From patchwork Mon Mar 18 17:22:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Foster X-Patchwork-Id: 10858263 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A0FB1139A for ; Mon, 18 Mar 2019 17:22:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 87327293A0 for ; Mon, 18 Mar 2019 17:22:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7B69329452; Mon, 18 Mar 2019 17:22:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 05E9B29448 for ; Mon, 18 Mar 2019 17:22:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726767AbfCRRWR (ORCPT ); Mon, 18 Mar 2019 13:22:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44642 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726720AbfCRRWR (ORCPT ); Mon, 18 Mar 2019 13:22:17 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E1C7AC049598; Mon, 18 Mar 2019 17:22:16 +0000 (UTC) Received: from bfoster.bos.redhat.com (dhcp-41-2.bos.redhat.com [10.18.41.2]) by smtp.corp.redhat.com (Postfix) with ESMTP id 888285D70E; Mon, 18 Mar 2019 17:22:16 +0000 (UTC) From: Brian Foster To: fstests@vger.kernel.org Cc: linux-xfs@vger.kernel.org Subject: [PATCH] generic: test stale data exposure after writeback crash Date: Mon, 18 Mar 2019 13:22:16 -0400 Message-Id: <20190318172216.20098-1-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Mon, 18 Mar 2019 17:22:16 +0000 (UTC) Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP XFS has historically had a stale data exposure window if a crash occurs after a delalloc->physical extent conversion but before writeback completes to the associated extent. While this should be a rare occurrence in production environments due to typical writeback ordering and such, it is not guaranteed in all cases until data extents are initialized as unwritten (or otherwise zeroed) before they are written. Add a test that performs selective writeback ordering to reproduce stale data exposure after a crash. Note that this test currently fails on XFS. Signed-off-by: Brian Foster --- As noted in the commit log, this test currently fails on XFS. I think it's worth considering regardless because we're pretty close to fixing this problem in the kernel. Darrick has posted a patch[1] that while apparently still needs a bit of work to accommodate performance concerns, does allow XFS to pass this test. Thoughts, reviews, flames appreciated. Brian [1] https://marc.info/?l=linux-xfs&m=155259894926863&w=2 tests/generic/999 | 70 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/999.out | 13 ++++++++ tests/generic/group | 1 + 3 files changed, 84 insertions(+) create mode 100755 tests/generic/999 create mode 100644 tests/generic/999.out diff --git a/tests/generic/999 b/tests/generic/999 new file mode 100755 index 00000000..46c85d07 --- /dev/null +++ b/tests/generic/999 @@ -0,0 +1,70 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2019 Red Hat, Inc. All Rights Reserved. +# +# FS QA Test 999 +# +# Test a some write patterns for stale data exposure after a crash. XFS is +# historically susceptible to this problem in the window between delalloc to +# physical extent conversion and writeback completion. +# +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc + +# remove previous $seqres.full before test +rm -f $seqres.full + +# real QA test starts here + +# Modify as appropriate. +_supported_fs generic +_supported_os Linux +_require_scratch +_require_scratch_shutdown + +# create a small fs and initialize free blocks with a unique pattern +_scratch_mkfs_sized $((1024 * 1024 * 100)) >> $seqres.full 2>&1 +_scratch_mount +$XFS_IO_PROG -f -c "pwrite -S 0xab 0 100m" -c fsync $SCRATCH_MNT/spc \ + >> $seqres.full 2>&1 +rm -f $SCRATCH_MNT/spc +$XFS_IO_PROG -c fsync $SCRATCH_MNT + +# Write a couple files with particular writeback sequences. The first writes a +# delalloc extent and triggers writeback on the last page. The second triggers +# post-eof preallocation (on XFS), write extends into the preallocation and +# triggers writeback of the last written page. +$XFS_IO_PROG -fc "pwrite 0 64k" -c "sync_range -w 60k 4k" \ + -c "sync_range -a 60k 4k" $SCRATCH_MNT/file.1 >> $seqres.full 2>&1 +$XFS_IO_PROG -fc "pwrite 0 68k" -c fsync -c "pwrite 96k 4k" \ + -c "sync_range -w 96k 4k" -c "sync_range -a 96k 4k" \ + $SCRATCH_MNT/file.2 >> $seqres.full 2>&1 + +# Shut down before any other writeback completes. Flush the log to persist inode +# size updates. +_scratch_shutdown -f + +# Now dump both files. The region prior to the last page in the first file +# should be zero filled. The region between the two writes to the second file +# should also be zero filled. +_scratch_cycle_mount +hexdump $SCRATCH_MNT/file.1 +hexdump $SCRATCH_MNT/file.2 + +status=0 +exit diff --git a/tests/generic/999.out b/tests/generic/999.out new file mode 100644 index 00000000..db3c5b7e --- /dev/null +++ b/tests/generic/999.out @@ -0,0 +1,13 @@ +QA output created by 999 +0000000 0000 0000 0000 0000 0000 0000 0000 0000 +* +000f000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd +* +0010000 +0000000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd +* +0011000 0000 0000 0000 0000 0000 0000 0000 0000 +* +0018000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd +* +0019000 diff --git a/tests/generic/group b/tests/generic/group index 78b9b45d..aa4734af 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -538,3 +538,4 @@ 533 auto quick attr 534 auto quick log 535 auto quick log +999 auto quick rw