From patchwork Fri Dec 30 22:19:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085292 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7B25C4332F for ; Sat, 31 Dec 2022 00:52:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235973AbiLaAwJ (ORCPT ); Fri, 30 Dec 2022 19:52:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37758 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235956AbiLaAv6 (ORCPT ); Fri, 30 Dec 2022 19:51:58 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 86737164AF; Fri, 30 Dec 2022 16:51:57 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 43C0AB81DF5; Sat, 31 Dec 2022 00:51:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E4BB9C433EF; Sat, 31 Dec 2022 00:51:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672447915; bh=2XUqCDN5obPTVw6gdUTST5T79HLXXgbtO6UGKb5NSBo=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=OXa4LTVZPzHjFpNbS0jNBMMUdSQpFOsPioWlDYZE1+UFeBS+a2SCcfuZCd6KpLt4t AYQQridvj8/l4VzNQhYkiXvY9f0WlcAsuJF8kIZiOkPc2i1FOfEi4RiEgX2C258KMV dhc0fp0AhwbyjG46H1f0hYKZgZD7h3ZdiVHJRioJGxQO9im0E91vWv1AgnUU/W8XEy 3mf8GMqsPUYy4BZbAXPkr6eUP8rjQEyB7xc/3t4cG4blI4QwAXNHko/m7DeeWM8sHa ljPxf0JBKE5QcoNZAsREnh4v9whBh94j35pUdKQ9bkO707bn7SlMKws5Y1+ZxaS3Mp ftSDgwWd9xl2Q== Subject: [PATCH 1/7] xfs/122: fix for swapext log items From: "Darrick J. Wong" To: zlang@redhat.com, djwong@kernel.org Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org, guan@eryu.me Date: Fri, 30 Dec 2022 14:19:48 -0800 Message-ID: <167243878834.732172.4501257239247928885.stgit@magnolia> In-Reply-To: <167243878818.732172.6392253687008406885.stgit@magnolia> References: <167243878818.732172.6392253687008406885.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Add entries for the extent swapping log items. Signed-off-by: Darrick J. Wong --- tests/xfs/122.out | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/xfs/122.out b/tests/xfs/122.out index 95e53c5081..21549db7fd 100644 --- a/tests/xfs/122.out +++ b/tests/xfs/122.out @@ -117,6 +117,9 @@ sizeof(struct xfs_rtrmap_root) = 4 sizeof(struct xfs_rud_log_format) = 16 sizeof(struct xfs_rui_log_format) = 16 sizeof(struct xfs_scrub_metadata) = 64 +sizeof(struct xfs_swap_extent) = 64 +sizeof(struct xfs_sxd_log_format) = 16 +sizeof(struct xfs_sxi_log_format) = 80 sizeof(struct xfs_unmount_log_format) = 8 sizeof(xfs_agf_t) = 224 sizeof(xfs_agfl_t) = 36 From patchwork Fri Dec 30 22:19:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085293 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B84E7C3DA7C for ; Sat, 31 Dec 2022 00:52:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235956AbiLaAwN (ORCPT ); Fri, 30 Dec 2022 19:52:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235930AbiLaAwM (ORCPT ); Fri, 30 Dec 2022 19:52:12 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 86CAD13F29; Fri, 30 Dec 2022 16:52:11 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 13C2B61D34; Sat, 31 Dec 2022 00:52:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73AEDC433D2; Sat, 31 Dec 2022 00:52:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672447930; bh=PteYv95dJjonUNLaZvijX26VuHDpWkVo6VJ7F5tcAVE=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=knmxfPYZZt7WQgXi8KWKnpAy7uyZU1TwlIJABhlbRIkQ3Ie5dS7G7yZhSoR38AeOL 8mVtgoqW2ywBBc2GsV8nl3iuz0a29aMbmp5hN0BBADltxZG8nCAHTTfeXk912rciwr h0Mdsp5T3XRrGNShHVMRt17cXh+hEl1XlId8zjul8rbVys+N3DhB4uVmR2SZoYug9C ryZ1qIuOAmcIEYXo66sGW9eaRTKlXG6HlIOuoFqntmYIfuLs7D05J2Q+Skn4O4QRWp HRaGIddO+9Uai6o3NdjMU9V8kx9G6GERMUyGXsJGjweZtKckzuX64Ko/wGy+MHuwWJ sDxou4cZZy47w== Subject: [PATCH 2/7] generic: test old xfs extent swapping ioctl From: "Darrick J. Wong" To: zlang@redhat.com, djwong@kernel.org Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org, guan@eryu.me Date: Fri, 30 Dec 2022 14:19:48 -0800 Message-ID: <167243878846.732172.11558501065157551188.stgit@magnolia> In-Reply-To: <167243878818.732172.6392253687008406885.stgit@magnolia> References: <167243878818.732172.6392253687008406885.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Add some tests to check the operation of the old xfs swapext ioctl. There aren't any xfs-specific pieces in here, so they're in generic/ Signed-off-by: Darrick J. Wong --- common/rc | 11 +++++++++ doc/group-names.txt | 2 ++ tests/generic/1200 | 55 +++++++++++++++++++++++++++++++++++++++++++++ tests/generic/1200.out | 3 ++ tests/generic/1201 | 53 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/1201.out | 4 +++ tests/generic/1202 | 47 ++++++++++++++++++++++++++++++++++++++ tests/generic/1202.out | 2 ++ tests/xfs/1202 | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/1202.out | 12 ++++++++++ tests/xfs/537 | 2 +- 11 files changed, 249 insertions(+), 1 deletion(-) create mode 100755 tests/generic/1200 create mode 100644 tests/generic/1200.out create mode 100755 tests/generic/1201 create mode 100644 tests/generic/1201.out create mode 100755 tests/generic/1202 create mode 100644 tests/generic/1202.out create mode 100755 tests/xfs/1202 create mode 100644 tests/xfs/1202.out diff --git a/common/rc b/common/rc index a1b65f0a7f..88ecc1837d 100644 --- a/common/rc +++ b/common/rc @@ -2575,6 +2575,17 @@ _require_xfs_io_command() echo $testio | grep -q "Inappropriate ioctl" && \ _notrun "xfs_io $command support is missing" ;; + "swapext") + $XFS_IO_PROG -f -c 'pwrite -S 0x58 0 128k -b 128k' $testfile > /dev/null + $XFS_IO_PROG -f -c 'truncate 128k' $testfile.1 > /dev/null + testio=`$XFS_IO_PROG -c "$command $param $testfile.1" $testfile 2>&1` + echo $testio | grep -q "bad argument count" && \ + _notrun "xfs_io $command $param support is missing" + echo $testio | grep -q "Inappropriate ioctl" && \ + _notrun "xfs_io $command $param ioctl support is missing" + rm -f $testfile.1 + param_checked="$param" + ;; "utimes" ) testio=`$XFS_IO_PROG -f -c "utimes 0 0 0 0" $testfile 2>&1` ;; diff --git a/doc/group-names.txt b/doc/group-names.txt index 771ce937ae..e88dcc0fdd 100644 --- a/doc/group-names.txt +++ b/doc/group-names.txt @@ -51,6 +51,7 @@ enospc ENOSPC error reporting exportfs file handles fiemap fiemap ioctl filestreams XFS filestreams allocator +fiexchange FIEXCHANGE_RANGE ioctl freeze filesystem freeze tests fsck general fsck tests fsmap FS_IOC_GETFSMAP ioctl @@ -121,6 +122,7 @@ splice splice system call stress fsstress filesystem exerciser subvol btrfs subvolumes swap swap files +swapext XFS_IOC_SWAPEXT ioctl symlink symbolic links tape dump and restore with a tape thin thin provisioning diff --git a/tests/generic/1200 b/tests/generic/1200 new file mode 100755 index 0000000000..58b93e2b6e --- /dev/null +++ b/tests/generic/1200 @@ -0,0 +1,55 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1200 +# +# Can we use swapext to make the quota accounting incorrect? + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext quota + +# Import common functions. +. ./common/filter +. ./common/quota + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_user +_require_nobody +_require_quota +_require_xfs_quota +_require_scratch + +# Format filesystem and set up quota limits +_scratch_mkfs > $seqres.full +_qmount_option "usrquota,grpquota" +_qmount >> $seqres.full + +# Set up initial files +$XFS_IO_PROG -f -c 'pwrite -S 0x58 0 256k -b 1m' $SCRATCH_MNT/a >> $seqres.full +chown $qa_user $SCRATCH_MNT/a +$XFS_IO_PROG -f -c 'pwrite -S 0x59 0 64k -b 64k' -c 'truncate 256k' $SCRATCH_MNT/b >> $seqres.full +chown nobody $SCRATCH_MNT/b + +echo before swapext >> $seqres.full +$XFS_QUOTA_PROG -x -c 'report -a' $SCRATCH_MNT >> $seqres.full +stat $SCRATCH_MNT/* >> $seqres.full + +# Now try to swap the extents of the two files. The command is allowed to +# fail with -EINVAL (since that's what the first kernel fix does) or succeed +# (because subsequent rewrites can handle quota). Whatever the outcome, the +# quota usage check at the end should never show a discrepancy. +$XFS_IO_PROG -c "swapext $SCRATCH_MNT/b" $SCRATCH_MNT/a &> $tmp.swap +cat $tmp.swap >> $seqres.full +grep -v 'Invalid argument' $tmp.swap + +echo after swapext >> $seqres.full +$XFS_QUOTA_PROG -x -c 'report -a' $SCRATCH_MNT >> $seqres.full +stat $SCRATCH_MNT/* >> $seqres.full + +_check_quota_usage + +# success, all done +status=0 +exit diff --git a/tests/generic/1200.out b/tests/generic/1200.out new file mode 100644 index 0000000000..b1a6357719 --- /dev/null +++ b/tests/generic/1200.out @@ -0,0 +1,3 @@ +QA output created by 1200 +Comparing user usage +Comparing group usage diff --git a/tests/generic/1201 b/tests/generic/1201 new file mode 100755 index 0000000000..91e3773eaa --- /dev/null +++ b/tests/generic/1201 @@ -0,0 +1,53 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1201 +# +# Can we use swapext to exceed the quota enforcement? + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext quota + +# Import common functions. +. ./common/filter +. ./common/quota + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_user +_require_nobody +_require_quota +_require_xfs_quota +_require_scratch + +# Format filesystem and set up quota limits +_scratch_mkfs > $seqres.full +_qmount_option "usrquota,grpquota" +_qmount >> $seqres.full + +# Set up initial files +$XFS_IO_PROG -f -c 'pwrite -S 0x58 0 256k -b 1m' $SCRATCH_MNT/a >> $seqres.full +chown $qa_user $SCRATCH_MNT/a +$XFS_IO_PROG -f -c 'pwrite -S 0x59 0 64k -b 64k' -c 'truncate 256k' $SCRATCH_MNT/b >> $seqres.full +chown nobody $SCRATCH_MNT/b + +# Set up a quota limit +$XFS_QUOTA_PROG -x -c "limit -u bhard=70k nobody" $SCRATCH_MNT + +echo before swapext >> $seqres.full +$XFS_QUOTA_PROG -x -c 'report -a' $SCRATCH_MNT >> $seqres.full +stat $SCRATCH_MNT/* >> $seqres.full + +# Now try to swapext +$XFS_IO_PROG -c "swapext $SCRATCH_MNT/b" $SCRATCH_MNT/a + +echo after swapext >> $seqres.full +$XFS_QUOTA_PROG -x -c 'report -a' $SCRATCH_MNT >> $seqres.full +stat $SCRATCH_MNT/* >> $seqres.full + +_check_quota_usage + +# success, all done +status=0 +exit diff --git a/tests/generic/1201.out b/tests/generic/1201.out new file mode 100644 index 0000000000..9001a59958 --- /dev/null +++ b/tests/generic/1201.out @@ -0,0 +1,4 @@ +QA output created by 1201 +swapext: Disk quota exceeded +Comparing user usage +Comparing group usage diff --git a/tests/generic/1202 b/tests/generic/1202 new file mode 100755 index 0000000000..2afa546f1f --- /dev/null +++ b/tests/generic/1202 @@ -0,0 +1,47 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1202 +# +# Make sure that swapext won't touch a swap file. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + test -e "$dir/a" && swapoff $dir/a + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_test + +dir=$TEST_DIR/test-$seq +mkdir -p $dir + +# Set up a fragmented swapfile and a dummy donor file. +$XFS_IO_PROG -f -c 'pwrite -S 0x58 0 32m -b 1m' -c fsync $dir/a >> $seqres.full +$here/src/punch-alternating $dir/a +$XFS_IO_PROG -f -c 'pwrite -S 0x58 0 32m -b 1m' -c fsync $dir/a >> $seqres.full +$MKSWAP_PROG $dir/a >> $seqres.full + +$XFS_IO_PROG -f -c 'pwrite -S 0x59 0 32m -b 1m' $dir/b >> $seqres.full + +swapon $dir/a || _notrun 'failed to swapon' + +# Now try to swapext. The old code would return EINVAL for swapfiles +# even though everything else in the VFS returns ETXTBSY. +$XFS_IO_PROG -c "swapext $dir/b" $dir/a 2>&1 | \ + sed -e 's/swapext: Invalid argument/swapext: Text file busy/g' + +# success, all done +status=0 +exit diff --git a/tests/generic/1202.out b/tests/generic/1202.out new file mode 100644 index 0000000000..029d65e4d0 --- /dev/null +++ b/tests/generic/1202.out @@ -0,0 +1,2 @@ +QA output created by 1202 +swapext: Text file busy diff --git a/tests/xfs/1202 b/tests/xfs/1202 new file mode 100755 index 0000000000..73e56641af --- /dev/null +++ b/tests/xfs/1202 @@ -0,0 +1,59 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1202 +# +# Simple tests of the old xfs swapext ioctl + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter + +# real QA test starts here +_supported_fs xfs +_require_xfs_io_command swapext '-v vfs' +_require_test + +# We can't do any reasonable swapping if the files we're going to create are +# realtime files, the rt extent size is greater than 1 block, and we can't use +# atomic extent swapping to make sure that partially written extents are fully +# swapped. +file_blksz=$(_get_file_block_size $TEST_DIR) +fs_blksz=$(_get_block_size $TEST_DIR) +if (( $file_blksz != $fs_blksz )); then + _xfs_has_feature $TEST_DIR reflink || \ + _notrun "test requires atomic extent swapping for rextsize=$((file_blksz / fs_blksz))" +fi + +dir=$TEST_DIR/test-$seq +mkdir -p $dir + +$XFS_IO_PROG -f -c 'pwrite -S 0x58 0 256k -b 1m' $dir/a >> $seqres.full +$XFS_IO_PROG -f -c 'pwrite -S 0x59 0 256k -b 1m' $dir/b >> $seqres.full +$XFS_IO_PROG -f -c 'pwrite -S 0x60 0 256k -b 1m' $dir/c >> $seqres.full +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 128k -b 1m' $dir/d >> $seqres.full +md5sum $dir/a $dir/b $dir/c $dir/d | _filter_test_dir + +# Swap two files that are the same length +echo swap +$XFS_IO_PROG -c "swapext $dir/b" $dir/a +md5sum $dir/a $dir/b | _filter_test_dir + +# Try to swap two files that are not the same length +echo fail swap +$XFS_IO_PROG -c "swapext $dir/c" $dir/d +md5sum $dir/c $dir/d | _filter_test_dir + +# success, all done +status=0 +exit diff --git a/tests/xfs/1202.out b/tests/xfs/1202.out new file mode 100644 index 0000000000..23127eb7b7 --- /dev/null +++ b/tests/xfs/1202.out @@ -0,0 +1,12 @@ +QA output created by 1202 +af5c6e2d6c297f3139a4e99df396c072 TEST_DIR/test-1202/a +fba5c83875b2ab054e06a0284346ebdf TEST_DIR/test-1202/b +40c08c6f2aca19bb0d2cf1dbd8bc1b1c TEST_DIR/test-1202/c +81615449a98aaaad8dc179b3bec87f38 TEST_DIR/test-1202/d +swap +fba5c83875b2ab054e06a0284346ebdf TEST_DIR/test-1202/a +af5c6e2d6c297f3139a4e99df396c072 TEST_DIR/test-1202/b +fail swap +swapext: Bad address +40c08c6f2aca19bb0d2cf1dbd8bc1b1c TEST_DIR/test-1202/c +81615449a98aaaad8dc179b3bec87f38 TEST_DIR/test-1202/d diff --git a/tests/xfs/537 b/tests/xfs/537 index 7e11488799..6364db9b5d 100755 --- a/tests/xfs/537 +++ b/tests/xfs/537 @@ -7,7 +7,7 @@ # Verify that XFS does not cause inode fork's extent count to overflow when # swapping forks between files . ./common/preamble -_begin_fstest auto quick collapse +_begin_fstest auto quick collapse swapext # Import common functions. . ./common/filter From patchwork Fri Dec 30 22:19:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085294 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 313E8C3DA7D for ; Sat, 31 Dec 2022 00:52:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235978AbiLaAwb (ORCPT ); Fri, 30 Dec 2022 19:52:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37842 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235930AbiLaAwa (ORCPT ); Fri, 30 Dec 2022 19:52:30 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 303B5186CF; Fri, 30 Dec 2022 16:52:27 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A49AC61D47; Sat, 31 Dec 2022 00:52:26 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F26B7C433EF; Sat, 31 Dec 2022 00:52:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672447946; bh=egWQGmh8TTruVN192dJq6s70SqU+sDgEYlue7CpnVmQ=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=o3fA5AX4CbuUYzswIvoR4Rzv1iAUv3iYPiy77RdI1GS3rbUWkXkX2Tk1jQxYAmAYa srAJkqgxO4NyfbD16Om4SSG2OClFu+GTd0uwfyueGEmRdl+7dFYWbtgX8wnGXI0/nE KFVUqT52hGzMGx3kCE3LoZsLS4DoBI+Xrvv7txhsN1bbkHty6InFMyK+4bOp4uN+4z czxhYh7K3j6xD0ZAkzITgHvKJVUpy247zN5Qym7bysYpdLBV0rUnXL6g2nfMrJiSfW qIVBGSQnn8VcfXJ2P7bhTz8rFUc0mDxzD/u7+a3x0BqZXTynAWf4VrFZsln80CjVnA fo+4sKeD3E4cw== Subject: [PATCH 3/7] generic: test new vfs swapext ioctl From: "Darrick J. Wong" To: zlang@redhat.com, djwong@kernel.org Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org, guan@eryu.me Date: Fri, 30 Dec 2022 14:19:48 -0800 Message-ID: <167243878860.732172.12480859111756252957.stgit@magnolia> In-Reply-To: <167243878818.732172.6392253687008406885.stgit@magnolia> References: <167243878818.732172.6392253687008406885.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Test the new vfs swapext ioctl. Signed-off-by: Darrick J. Wong --- common/rc | 13 +++++ common/reflink | 33 +++++++++++++ tests/generic/1203 | 58 ++++++++++++++++++++++ tests/generic/1203.out | 2 + tests/generic/1204 | 100 ++++++++++++++++++++++++++++++++++++++ tests/generic/1204.out | 86 +++++++++++++++++++++++++++++++++ tests/generic/1205 | 116 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/1205.out | 90 ++++++++++++++++++++++++++++++++++ tests/generic/1206 | 76 +++++++++++++++++++++++++++++ tests/generic/1206.out | 32 ++++++++++++ tests/generic/1207 | 122 ++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/1207.out | 48 ++++++++++++++++++ tests/generic/1209 | 101 ++++++++++++++++++++++++++++++++++++++ tests/generic/1209.out | 33 +++++++++++++ tests/generic/1210 | 48 ++++++++++++++++++ tests/generic/1210.out | 6 ++ tests/generic/1211 | 105 ++++++++++++++++++++++++++++++++++++++++ tests/generic/1211.out | 40 +++++++++++++++ tests/generic/1212 | 58 ++++++++++++++++++++++ tests/generic/1212.out | 2 + tests/generic/1213 | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/1213.out | 48 ++++++++++++++++++ tests/generic/1214 | 63 ++++++++++++++++++++++++ tests/generic/1214.out | 2 + tests/generic/1215 | 70 +++++++++++++++++++++++++++ tests/generic/1215.out | 2 + tests/xfs/1208 | 62 ++++++++++++++++++++++++ tests/xfs/1208.out | 10 ++++ 28 files changed, 1552 insertions(+) create mode 100755 tests/generic/1203 create mode 100644 tests/generic/1203.out create mode 100755 tests/generic/1204 create mode 100644 tests/generic/1204.out create mode 100755 tests/generic/1205 create mode 100644 tests/generic/1205.out create mode 100755 tests/generic/1206 create mode 100644 tests/generic/1206.out create mode 100755 tests/generic/1207 create mode 100644 tests/generic/1207.out create mode 100755 tests/generic/1209 create mode 100644 tests/generic/1209.out create mode 100755 tests/generic/1210 create mode 100644 tests/generic/1210.out create mode 100755 tests/generic/1211 create mode 100644 tests/generic/1211.out create mode 100755 tests/generic/1212 create mode 100644 tests/generic/1212.out create mode 100755 tests/generic/1213 create mode 100644 tests/generic/1213.out create mode 100755 tests/generic/1214 create mode 100644 tests/generic/1214.out create mode 100755 tests/generic/1215 create mode 100644 tests/generic/1215.out create mode 100755 tests/xfs/1208 create mode 100644 tests/xfs/1208.out diff --git a/common/rc b/common/rc index 88ecc1837d..cfe765de2e 100644 --- a/common/rc +++ b/common/rc @@ -2575,6 +2575,17 @@ _require_xfs_io_command() echo $testio | grep -q "Inappropriate ioctl" && \ _notrun "xfs_io $command support is missing" ;; + "startupdate"|"commitupdate"|"cancelupdate") + $XFS_IO_PROG -f -c 'pwrite -S 0x58 0 128k -b 128k' $testfile > /dev/null + testio=$($XFS_IO_PROG -c "startupdate $param" \ + -c 'pwrite -S 0x59 0 192k' \ + -c 'commitupdate' $testfile 2>&1) + echo $testio | grep -q "Inappropriate ioctl" && \ + _notrun "xfs_io $command $param support is missing" + echo $testio | grep -q "Operation not supported" && \ + _notrun "xfs_io $command $param kernel support is missing" + param_checked="$param" + ;; "swapext") $XFS_IO_PROG -f -c 'pwrite -S 0x58 0 128k -b 128k' $testfile > /dev/null $XFS_IO_PROG -f -c 'truncate 128k' $testfile.1 > /dev/null @@ -2583,6 +2594,8 @@ _require_xfs_io_command() _notrun "xfs_io $command $param support is missing" echo $testio | grep -q "Inappropriate ioctl" && \ _notrun "xfs_io $command $param ioctl support is missing" + echo $testio | grep -q "Operation not supported" && \ + _notrun "xfs_io $command $param kernel support is missing" rm -f $testfile.1 param_checked="$param" ;; diff --git a/common/reflink b/common/reflink index 76e9cb7d32..22adc4449b 100644 --- a/common/reflink +++ b/common/reflink @@ -325,6 +325,39 @@ _weave_reflink_regular() { done } +# Create a file of interleaved holes, unwritten blocks, and regular blocks. +_weave_file_rainbow() { + blksz=$1 + nr=$2 + dfile=$3 + + $XFS_IO_PROG -f -c "truncate $((blksz * nr))" $dfile + _pwrite_byte 0x00 0 $((blksz * nr)) $dfile.chk + # 0 blocks are unwritten + seq 1 5 $((nr - 1)) | while read i; do + $XFS_IO_PROG -f -c "falloc $((blksz * i)) $blksz" $dfile + _pwrite_byte 0x00 $((blksz * i)) $blksz $dfile.chk + done + # 1 blocks are holes + seq 2 5 $((nr - 1)) | while read i; do + _pwrite_byte 0x00 $((blksz * i)) $blksz $dfile.chk + done + # 2 blocks are regular + seq 3 5 $((nr - 1)) | while read i; do + _pwrite_byte 0x71 $((blksz * i)) $blksz $dfile + _pwrite_byte 0x71 $((blksz * i)) $blksz $dfile.chk + done + # 3 blocks are holes + seq 2 5 $((nr - 1)) | while read i; do + _pwrite_byte 0x00 $((blksz * i)) $blksz $dfile.chk + done + # 4 blocks are delalloc + seq 4 5 $((nr - 1)) | while read i; do + _pwrite_byte 0x62 $((blksz * i)) $blksz $dfile + _pwrite_byte 0x62 $((blksz * i)) $blksz $dfile.chk + done +} + # Create a file of interleaved holes, unwritten blocks, regular blocks, and # reflinked blocks _weave_reflink_rainbow() { diff --git a/tests/generic/1203 b/tests/generic/1203 new file mode 100755 index 0000000000..890b0b4c86 --- /dev/null +++ b/tests/generic/1203 @@ -0,0 +1,58 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1202 +# +# Make sure that swapext modifies ctime and not mtime of the file. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter + +# real QA test starts here +_require_test_program punch-alternating +_require_xfs_io_command swapext '-v vfs' +_require_test + +dir=$TEST_DIR/test-$seq +mkdir -p $dir + +# Set up initial files +$XFS_IO_PROG -f -c 'pwrite -S 0x58 0 256k -b 1m' $dir/a >> $seqres.full +$here/src/punch-alternating $dir/a +$XFS_IO_PROG -f -c 'pwrite -S 0x59 0 256k -b 1m' $dir/b >> $seqres.full + +# Snapshot the 'a' file before we swap +echo before >> $seqres.full +md5sum $dir/a $dir/b >> $seqres.full +old_mtime="$(echo $(stat -c '%y' $dir/a $dir/b))" +old_ctime="$(echo $(stat -c '%z' $dir/a $dir/b))" +stat -c '%y %Y %z %Z' $dir/a $dir/b >> $seqres.full + +# Now try to swapext +$XFS_IO_PROG -c "swapext $dir/b" $dir/a + +# Snapshot the 'a' file after we swap +echo after >> $seqres.full +md5sum $dir/a $dir/b >> $seqres.full +new_mtime="$(echo $(stat -c '%y' $dir/a $dir/b))" +new_ctime="$(echo $(stat -c '%z' $dir/a $dir/b))" +stat -c '%y %Y %z %Z' $dir/a $dir/b >> $seqres.full + +test "$new_mtime" = "$old_mtime" && echo "mtime: $new_mtime == $old_mtime" +test "$new_ctime" = "$old_ctime" && echo "ctime: $new_ctime == $old_ctime" + +# success, all done +echo Silence is golden. +status=0 +exit diff --git a/tests/generic/1203.out b/tests/generic/1203.out new file mode 100644 index 0000000000..904b25beb4 --- /dev/null +++ b/tests/generic/1203.out @@ -0,0 +1,2 @@ +QA output created by 1203 +Silence is golden. diff --git a/tests/generic/1204 b/tests/generic/1204 new file mode 100755 index 0000000000..5db3878520 --- /dev/null +++ b/tests/generic/1204 @@ -0,0 +1,100 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1204 +# +# Test swapext between ranges of two different files. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs -s 64k -l 64k' +_require_xfs_io_command "falloc" +_require_test + +filesnap() { + echo "$1" + if [ "$2" != "$3" ]; then + md5sum $2 $3 | _filter_test_dir + else + md5sum $2 | _filter_test_dir + fi +} + +test_swapext_once() { + filesnap "$1: before swapext" $dir/$3 $dir/$4 + $XFS_IO_PROG -c "swapext -v vfs $2 $dir/$3" $dir/$4 + filesnap "$1: after swapext" $dir/$3 $dir/$4 + _test_cycle_mount + filesnap "$1: after cycling mount" $dir/$3 $dir/$4 + echo +} + +test_swapext_two() { + # swapext the same range of two files + test_swapext_once "$@: samerange" \ + "-s $((blksz * 3)) -d $((blksz * 3)) -l $((blksz * 5))" b a + + # swapext different ranges of two files + test_swapext_once "$@: diffrange" \ + "-s $((blksz * 37)) -d $((blksz * 47)) -l $((blksz * 7))" b a + + # swapext overlapping ranges of two files + test_swapext_once "$@: overlap" \ + "-s $((blksz * 17)) -d $((blksz * 23)) -l $((blksz * 7))" b a +} + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 +nrblks=57 +_require_congruent_file_oplen $TEST_DIR $blksz + +# Set up some simple files for a first test. +rm -rf $dir/a $dir/b +_pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full +_pwrite_byte 0x59 0 $((blksz * nrblks)) $dir/b >> $seqres.full +test_swapext_two "simple" + +# Make some files that don't end an aligned offset. +rm -rf $dir/a $dir/b +_pwrite_byte 0x58 0 $(( (blksz * nrblks) + 37)) $dir/a >> $seqres.full +_pwrite_byte 0x59 0 $(( (blksz * nrblks) + 37)) $dir/b >> $seqres.full +test_swapext_once "unalignedeof" "" a b + +# Set up some crazy rainbow files +rm -rf $dir/a $dir/b +_weave_file_rainbow $blksz $nrblks $dir/a >> $seqres.full +_weave_file_rainbow $blksz $nrblks $dir/b >> $seqres.full +test_swapext_two "rainbow" + +# Now set up a simple file for testing within the same file +rm -rf $dir/c +$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((blksz * nrblks))" \ + -c "pwrite -S 0x59 $((blksz * nrblks)) $((blksz * nrblks))" \ + $dir/c >> $seqres.full + +# swapext the same offset into the 'X' and 'Y' regions of the file +test_swapext_once "single: sameXandY" \ + "-s $((blksz * 3)) -d $((blksz * (nrblks + 3))) -l $((blksz * 5))" c c + +# swapext the same offset into the 'X' and 'Y' regions of the file +test_swapext_once "single: overlap" \ + "-s $((blksz * 13)) -d $((blksz * 17)) -l $((blksz * 5))" c c + +# success, all done +status=0 +exit diff --git a/tests/generic/1204.out b/tests/generic/1204.out new file mode 100644 index 0000000000..cdf9f7315d --- /dev/null +++ b/tests/generic/1204.out @@ -0,0 +1,86 @@ +QA output created by 1204 +simple: samerange: before swapext +db85d578204631f2b4eb1e73974253c2 TEST_DIR/test-1204/b +d0425612f15c6071022cf7127620f63d TEST_DIR/test-1204/a +simple: samerange: after swapext +20beef1c9ed7de02e4229c69bd43bd8f TEST_DIR/test-1204/b +e7697fa99d08f7eb76fa3fb963fe916a TEST_DIR/test-1204/a +simple: samerange: after cycling mount +20beef1c9ed7de02e4229c69bd43bd8f TEST_DIR/test-1204/b +e7697fa99d08f7eb76fa3fb963fe916a TEST_DIR/test-1204/a + +simple: diffrange: before swapext +20beef1c9ed7de02e4229c69bd43bd8f TEST_DIR/test-1204/b +e7697fa99d08f7eb76fa3fb963fe916a TEST_DIR/test-1204/a +simple: diffrange: after swapext +cd32ce54c295fcdf571ce7f8220fac56 TEST_DIR/test-1204/b +d9771c5bb6d9db00b9abe65a4410e1a6 TEST_DIR/test-1204/a +simple: diffrange: after cycling mount +cd32ce54c295fcdf571ce7f8220fac56 TEST_DIR/test-1204/b +d9771c5bb6d9db00b9abe65a4410e1a6 TEST_DIR/test-1204/a + +simple: overlap: before swapext +cd32ce54c295fcdf571ce7f8220fac56 TEST_DIR/test-1204/b +d9771c5bb6d9db00b9abe65a4410e1a6 TEST_DIR/test-1204/a +simple: overlap: after swapext +e0fff655f6a08fc2f03ee01e4767060c TEST_DIR/test-1204/b +ec7d764c85e583e305028c9cba5b25b6 TEST_DIR/test-1204/a +simple: overlap: after cycling mount +e0fff655f6a08fc2f03ee01e4767060c TEST_DIR/test-1204/b +ec7d764c85e583e305028c9cba5b25b6 TEST_DIR/test-1204/a + +unalignedeof: before swapext +9f8c731a4f1946ffdda8c33e82417f2d TEST_DIR/test-1204/a +7a5d2ba7508226751c835292e28cd227 TEST_DIR/test-1204/b +unalignedeof: after swapext +7a5d2ba7508226751c835292e28cd227 TEST_DIR/test-1204/a +9f8c731a4f1946ffdda8c33e82417f2d TEST_DIR/test-1204/b +unalignedeof: after cycling mount +7a5d2ba7508226751c835292e28cd227 TEST_DIR/test-1204/a +9f8c731a4f1946ffdda8c33e82417f2d TEST_DIR/test-1204/b + +rainbow: samerange: before swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/a +rainbow: samerange: after swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/a +rainbow: samerange: after cycling mount +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/a + +rainbow: diffrange: before swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/a +rainbow: diffrange: after swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/a +rainbow: diffrange: after cycling mount +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/a + +rainbow: overlap: before swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1204/a +rainbow: overlap: after swapext +6753bc585e3c71d53bfaae11d2ffee99 TEST_DIR/test-1204/b +39597abd4d9d0c9ceac22b77eb00c373 TEST_DIR/test-1204/a +rainbow: overlap: after cycling mount +6753bc585e3c71d53bfaae11d2ffee99 TEST_DIR/test-1204/b +39597abd4d9d0c9ceac22b77eb00c373 TEST_DIR/test-1204/a + +single: sameXandY: before swapext +39e17753fa9e923a3b5928e13775e358 TEST_DIR/test-1204/c +single: sameXandY: after swapext +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1204/c +single: sameXandY: after cycling mount +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1204/c + +single: overlap: before swapext +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1204/c +swapext: Invalid argument +single: overlap: after swapext +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1204/c +single: overlap: after cycling mount +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1204/c + diff --git a/tests/generic/1205 b/tests/generic/1205 new file mode 100755 index 0000000000..dfa5adf0e1 --- /dev/null +++ b/tests/generic/1205 @@ -0,0 +1,116 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1205 +# +# Test swapext between ranges of two different files, when one of the files +# is shared. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_xfs_io_command "falloc" +_require_test_reflink + +filesnap() { + echo "$1" + if [ "$2" != "$3" ]; then + md5sum $2 $3 | _filter_test_dir + else + md5sum $2 | _filter_test_dir + fi +} + +test_swapext_once() { + filesnap "$1: before swapext" $dir/$3 $dir/$4 + $XFS_IO_PROG -c "swapext -v vfs $2 $dir/$3" $dir/$4 + filesnap "$1: after swapext" $dir/$3 $dir/$4 + _test_cycle_mount + filesnap "$1: after cycling mount" $dir/$3 $dir/$4 + echo +} + +test_swapext_two() { + # swapext the same range of two files + test_swapext_once "$@: samerange" \ + "-s $((blksz * 3)) -d $((blksz * 3)) -l $((blksz * 5))" b a + + # swapext different ranges of two files + test_swapext_once "$@: diffrange" \ + "-s $((blksz * 37)) -d $((blksz * 47)) -l $((blksz * 7))" b a + + # swapext overlapping ranges of two files + test_swapext_once "$@: overlap" \ + "-s $((blksz * 17)) -d $((blksz * 23)) -l $((blksz * 7))" b a + + # Now let's overwrite a entirely to make sure COW works + echo "overwrite A and B entirely" + md5sum $dir/sharea | _filter_test_dir + $XFS_IO_PROG -c "pwrite -S 0x60 0 $((blksz * nrblks))" $dir/a >> $seqres.full + $XFS_IO_PROG -c "pwrite -S 0x60 0 $((blksz * nrblks))" $dir/b >> $seqres.full + md5sum $dir/sharea | _filter_test_dir + _test_cycle_mount + md5sum $dir/sharea | _filter_test_dir + echo +} + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 +_require_congruent_file_oplen $TEST_DIR $blksz +nrblks=57 + +# Set up some simple files for a first test. +rm -f $dir/a $dir/b $dir/sharea +_pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full +_pwrite_byte 0x59 0 $((blksz * nrblks)) $dir/b >> $seqres.full +_cp_reflink $dir/a $dir/sharea +test_swapext_two "simple" + +# Set up some crazy rainbow files +rm -f $dir/a $dir/b $dir/sharea +_weave_file_rainbow $blksz $nrblks $dir/a >> $seqres.full +_weave_file_rainbow $blksz $nrblks $dir/b >> $seqres.full +_cp_reflink $dir/a $dir/sharea +test_swapext_two "rainbow" + +# Now set up a simple file for testing within the same file +rm -f $dir/c $dir/sharec +$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((blksz * nrblks))" \ + -c "pwrite -S 0x59 $((blksz * nrblks)) $((blksz * nrblks))" \ + $dir/c >> $seqres.full +_cp_reflink $dir/c $dir/sharec + +# swapext the same offset into the 'X' and 'Y' regions of the file +test_swapext_once "single: sameXandY" \ + "-s $((blksz * 3)) -d $((blksz * (nrblks + 3))) -l $((blksz * 5))" c c + +# swapext the same offset into the 'X' and 'Y' regions of the file +test_swapext_once "single: overlap" \ + "-s $((blksz * 13)) -d $((blksz * 17)) -l $((blksz * 5))" c c + +# Now let's overwrite a entirely to make sure COW works +echo "overwrite C entirely" +md5sum $dir/sharec | _filter_test_dir +$XFS_IO_PROG -c "pwrite -S 0x60 0 $((blksz * nrblks))" $dir/c >> $seqres.full +md5sum $dir/sharec | _filter_test_dir +_test_cycle_mount +md5sum $dir/sharec | _filter_test_dir + +# success, all done +status=0 +exit diff --git a/tests/generic/1205.out b/tests/generic/1205.out new file mode 100644 index 0000000000..9a95742e78 --- /dev/null +++ b/tests/generic/1205.out @@ -0,0 +1,90 @@ +QA output created by 1205 +simple: samerange: before swapext +db85d578204631f2b4eb1e73974253c2 TEST_DIR/test-1205/b +d0425612f15c6071022cf7127620f63d TEST_DIR/test-1205/a +simple: samerange: after swapext +20beef1c9ed7de02e4229c69bd43bd8f TEST_DIR/test-1205/b +e7697fa99d08f7eb76fa3fb963fe916a TEST_DIR/test-1205/a +simple: samerange: after cycling mount +20beef1c9ed7de02e4229c69bd43bd8f TEST_DIR/test-1205/b +e7697fa99d08f7eb76fa3fb963fe916a TEST_DIR/test-1205/a + +simple: diffrange: before swapext +20beef1c9ed7de02e4229c69bd43bd8f TEST_DIR/test-1205/b +e7697fa99d08f7eb76fa3fb963fe916a TEST_DIR/test-1205/a +simple: diffrange: after swapext +cd32ce54c295fcdf571ce7f8220fac56 TEST_DIR/test-1205/b +d9771c5bb6d9db00b9abe65a4410e1a6 TEST_DIR/test-1205/a +simple: diffrange: after cycling mount +cd32ce54c295fcdf571ce7f8220fac56 TEST_DIR/test-1205/b +d9771c5bb6d9db00b9abe65a4410e1a6 TEST_DIR/test-1205/a + +simple: overlap: before swapext +cd32ce54c295fcdf571ce7f8220fac56 TEST_DIR/test-1205/b +d9771c5bb6d9db00b9abe65a4410e1a6 TEST_DIR/test-1205/a +simple: overlap: after swapext +e0fff655f6a08fc2f03ee01e4767060c TEST_DIR/test-1205/b +ec7d764c85e583e305028c9cba5b25b6 TEST_DIR/test-1205/a +simple: overlap: after cycling mount +e0fff655f6a08fc2f03ee01e4767060c TEST_DIR/test-1205/b +ec7d764c85e583e305028c9cba5b25b6 TEST_DIR/test-1205/a + +overwrite A and B entirely +d0425612f15c6071022cf7127620f63d TEST_DIR/test-1205/sharea +d0425612f15c6071022cf7127620f63d TEST_DIR/test-1205/sharea +d0425612f15c6071022cf7127620f63d TEST_DIR/test-1205/sharea + +rainbow: samerange: before swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/a +rainbow: samerange: after swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/a +rainbow: samerange: after cycling mount +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/a + +rainbow: diffrange: before swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/a +rainbow: diffrange: after swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/a +rainbow: diffrange: after cycling mount +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/a + +rainbow: overlap: before swapext +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/b +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/a +rainbow: overlap: after swapext +6753bc585e3c71d53bfaae11d2ffee99 TEST_DIR/test-1205/b +39597abd4d9d0c9ceac22b77eb00c373 TEST_DIR/test-1205/a +rainbow: overlap: after cycling mount +6753bc585e3c71d53bfaae11d2ffee99 TEST_DIR/test-1205/b +39597abd4d9d0c9ceac22b77eb00c373 TEST_DIR/test-1205/a + +overwrite A and B entirely +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/sharea +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/sharea +48b41ee1970eb71064b77181f42634cf TEST_DIR/test-1205/sharea + +single: sameXandY: before swapext +39e17753fa9e923a3b5928e13775e358 TEST_DIR/test-1205/c +single: sameXandY: after swapext +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1205/c +single: sameXandY: after cycling mount +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1205/c + +single: overlap: before swapext +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1205/c +swapext: Invalid argument +single: overlap: after swapext +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1205/c +single: overlap: after cycling mount +8262c617070703fb0e2a28d8f05e3112 TEST_DIR/test-1205/c + +overwrite C entirely +39e17753fa9e923a3b5928e13775e358 TEST_DIR/test-1205/sharec +39e17753fa9e923a3b5928e13775e358 TEST_DIR/test-1205/sharec +39e17753fa9e923a3b5928e13775e358 TEST_DIR/test-1205/sharec diff --git a/tests/generic/1206 b/tests/generic/1206 new file mode 100755 index 0000000000..a4d9dd083e --- /dev/null +++ b/tests/generic/1206 @@ -0,0 +1,76 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1206 +# +# Test swapext between two files of unlike size. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs -s 64k -l 64k' +_require_test + +filesnap() { + echo "$1" + if [ "$2" != "$3" ]; then + md5sum $2 $3 | _filter_test_dir + else + md5sum $2 | _filter_test_dir + fi +} + +test_swapext_once() { + local tag=$1 + local a_len=$2 + local b_len=$3 + local a_off=$4 + local b_off=$5 + local len=$6 + + # len is either a block count or -e to swap to EOF + if [ "$len" != "-e" ]; then + len="-l $((blksz * len))" + fi + + rm -f $dir/a $dir/b + _pwrite_byte 0x58 0 $((blksz * a_len)) $dir/a >> $seqres.full + _pwrite_byte 0x59 0 $((blksz * b_len)) $dir/b >> $seqres.full + filesnap "$tag: before swapext" $dir/a $dir/b + + cmd="swapext -v vfs -s $((blksz * a_off)) -d $((blksz * b_off)) $len $dir/a" + echo "$cmd" >> $seqres.full + $XFS_IO_PROG -c "$cmd" $dir/b + filesnap "$tag: after swapext" $dir/a $dir/b + + _test_cycle_mount + filesnap "$tag: after cycling mount" $dir/a $dir/b + echo +} + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 + +test_swapext_once "last 5 blocks" 27 37 22 32 5 + +test_swapext_once "whole file to eof" 27 37 0 0 -e + +test_swapext_once "blocks 30-40" 27 37 30 30 10 + +# success, all done +status=0 +exit diff --git a/tests/generic/1206.out b/tests/generic/1206.out new file mode 100644 index 0000000000..82f4185684 --- /dev/null +++ b/tests/generic/1206.out @@ -0,0 +1,32 @@ +QA output created by 1206 +last 5 blocks: before swapext +207ea56e0ccbf50d38fd3a2d842aa170 TEST_DIR/test-1206/a +eb58941d31f5be1e4e22df8c536dd490 TEST_DIR/test-1206/b +last 5 blocks: after swapext +3f34470fe9feb8513d5f3a8538f2c5f3 TEST_DIR/test-1206/a +c3daca7dd9218371cd0dc64f11e4b0bf TEST_DIR/test-1206/b +last 5 blocks: after cycling mount +3f34470fe9feb8513d5f3a8538f2c5f3 TEST_DIR/test-1206/a +c3daca7dd9218371cd0dc64f11e4b0bf TEST_DIR/test-1206/b + +whole file to eof: before swapext +207ea56e0ccbf50d38fd3a2d842aa170 TEST_DIR/test-1206/a +eb58941d31f5be1e4e22df8c536dd490 TEST_DIR/test-1206/b +whole file to eof: after swapext +eb58941d31f5be1e4e22df8c536dd490 TEST_DIR/test-1206/a +207ea56e0ccbf50d38fd3a2d842aa170 TEST_DIR/test-1206/b +whole file to eof: after cycling mount +eb58941d31f5be1e4e22df8c536dd490 TEST_DIR/test-1206/a +207ea56e0ccbf50d38fd3a2d842aa170 TEST_DIR/test-1206/b + +blocks 30-40: before swapext +207ea56e0ccbf50d38fd3a2d842aa170 TEST_DIR/test-1206/a +eb58941d31f5be1e4e22df8c536dd490 TEST_DIR/test-1206/b +swapext: Invalid argument +blocks 30-40: after swapext +207ea56e0ccbf50d38fd3a2d842aa170 TEST_DIR/test-1206/a +eb58941d31f5be1e4e22df8c536dd490 TEST_DIR/test-1206/b +blocks 30-40: after cycling mount +207ea56e0ccbf50d38fd3a2d842aa170 TEST_DIR/test-1206/a +eb58941d31f5be1e4e22df8c536dd490 TEST_DIR/test-1206/b + diff --git a/tests/generic/1207 b/tests/generic/1207 new file mode 100755 index 0000000000..3a69a1ec57 --- /dev/null +++ b/tests/generic/1207 @@ -0,0 +1,122 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1207 +# +# Test atomic file updates when (a) the length is the same; (b) the length +# is different; and (c) someone modifies the original file and we need to +# cancel the update. The file contents are cloned into the staging file, +# and some of the contents are updated. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_xfs_io_command startupdate +_require_test_reflink +_require_test + +filesnap() { + echo "$1" + md5sum $2 | _filter_test_dir +} + +mkfile() { + rm -f $dir/a + _pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full + sync +} + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 +nrblks=64 + +# Use the atomic file update staging prototype in xfs_io to update a file. +mkfile +filesnap "before commit" $dir/a + +$XFS_IO_PROG \ + -c 'startupdate' \ + -c 'pwrite -S 0x60 44k 55k -b 1m' \ + -c 'commitupdate -q' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after commit" $dir/a +echo + +# Use the atomic file updates to replace a file with a shorter file. +mkfile +filesnap "before shorten commit" $dir/a + +$XFS_IO_PROG \ + -c 'startupdate' \ + -c 'truncate 55k' \ + -c 'pwrite -S 0x60 0 55k' \ + -c 'commitupdate -q' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after shorten commit" $dir/a +echo + +# Use the atomic file updates to replace a file with a longer file. +mkfile +filesnap "before lengthen commit" $dir/a + +$XFS_IO_PROG \ + -c 'startupdate' \ + -c "pwrite -S 0x60 0 $(( (blksz * nrblks) + 37373 ))" \ + -c 'commitupdate -q' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after lengthen commit" $dir/a +echo + +# Use the atomic file update staging prototype in xfs_io to cancel updating a +# file. +mkfile +filesnap "before cancel" $dir/a + +$XFS_IO_PROG \ + -c 'startupdate' \ + -c 'pwrite -S 0x60 44k 55k -b 1m' \ + -c 'cancelupdate' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after cancel" $dir/a +echo + +# Now try the update but with the A file open separately so that we clobber +# mtime and fail the update. +mkfile +filesnap "before fail commit" $dir/a + +$XFS_IO_PROG \ + -c "open $dir/a" \ + -c 'startupdate' \ + -c 'pwrite -S 0x58 44k 55k -b 1m' \ + -c 'file 0' \ + -c 'close' \ + -c 'pwrite -S 0x61 22k 11k -b 1m' \ + -c 'commitupdate -q' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after fail commit" $dir/a +echo + +# success, all done +status=0 +exit diff --git a/tests/generic/1207.out b/tests/generic/1207.out new file mode 100644 index 0000000000..ee33564067 --- /dev/null +++ b/tests/generic/1207.out @@ -0,0 +1,48 @@ +QA output created by 1207 +before commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1207/a +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1207/a'. +after commit +bedbd22b58a680219a1225353f6195fa TEST_DIR/test-1207/a + +before shorten commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1207/a +wrote 56320/56320 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1207/a'. +after shorten commit +52353039d89c5f2b76b9003464e5276a TEST_DIR/test-1207/a + +before lengthen commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1207/a +wrote 4231677/4231677 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1207/a'. +after lengthen commit +1839e7c6bf616160dc51b12179db2642 TEST_DIR/test-1207/a + +before cancel +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1207/a +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Cancelled updates to 'TEST_DIR/test-1207/a'. +after cancel +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1207/a + +before fail commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1207/a +committing update: Device or resource busy +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +[000] TEST_DIR/test-1207/a (xfs,non-sync,non-direct,read-write) + 001 TEST_DIR/test-1207/a (fileupdate) (xfs,non-sync,non-direct,read-write) +[000] TEST_DIR/test-1207/a (fileupdate) (xfs,non-sync,non-direct,read-write) +wrote 11264/11264 bytes at offset 22528 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +after fail commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1207/a + diff --git a/tests/generic/1209 b/tests/generic/1209 new file mode 100755 index 0000000000..6b287654ca --- /dev/null +++ b/tests/generic/1209 @@ -0,0 +1,101 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1209 +# +# Try invalid parameters to see if they fail. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_xfs_io_command startupdate +_require_test +_require_scratch +_require_chattr i + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 +nrblks=64 + +_scratch_mkfs >> $seqres.full +_scratch_mount + +_pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full +_pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/b >> $seqres.full + +echo Immutable files +$XFS_IO_PROG -c 'chattr +i' -c "swapext $dir/b" $dir/a +$CHATTR_PROG -i $dir/a + +echo Readonly files +$XFS_IO_PROG -r -c "swapext $dir/b" $dir/a + +echo Directories +$XFS_IO_PROG -c "swapext $dir/b" $dir + +echo Unaligned ranges +$XFS_IO_PROG -c "swapext -s 37 -d 61 -l 17 $dir/b" $dir/a + +echo file1 range entirely beyond EOF +$XFS_IO_PROG -c "swapext -s $(( blksz * (nrblks + 500) )) -d 0 -l $blksz $dir/b" $dir/a + +echo file2 range entirely beyond EOF +$XFS_IO_PROG -c "swapext -d $(( blksz * (nrblks + 500) )) -s 0 -l $blksz $dir/b" $dir/a + +echo Both ranges entirely beyond EOF +$XFS_IO_PROG -c "swapext -d $(( blksz * (nrblks + 500) )) -s $(( blksz * (nrblks + 500) )) -l $blksz $dir/b" $dir/a + +echo file1 range crossing EOF +$XFS_IO_PROG -c "swapext -s $(( blksz * (nrblks - 1) )) -d 0 -l $((2 * blksz)) $dir/b" $dir/a + +echo file2 range crossing EOF +$XFS_IO_PROG -c "swapext -d $(( blksz * (nrblks - 1) )) -s 0 -l $((2 * blksz)) $dir/b" $dir/a + +echo Both ranges crossing EOF +$XFS_IO_PROG -c "swapext -d $(( blksz * (nrblks - 1) )) -s $(( blksz * (nrblks - 1) )) -l $((blksz * 2)) $dir/b" $dir/a + +echo file1 unaligned EOF to file2 nowhere near EOF +_pwrite_byte 0x58 $((blksz * nrblks)) 37 $dir/a >> $seqres.full +_pwrite_byte 0x59 $((blksz * nrblks)) 37 $dir/b >> $seqres.full +$XFS_IO_PROG -c "swapext -d 0 -s $(( blksz * nrblks )) -l 37 $dir/b" $dir/a + +echo file2 unaligned EOF to file1 nowhere near EOF +$XFS_IO_PROG -c "swapext -s 0 -d $(( blksz * nrblks )) -l 37 $dir/b" $dir/a + +echo Files of unequal length +_pwrite_byte 0x58 $((blksz * nrblks)) $((blksz * 2)) $dir/a >> $seqres.full +_pwrite_byte 0x59 $((blksz * nrblks)) $blksz $dir/b >> $seqres.full +$XFS_IO_PROG -c "swapext $dir/b" $dir/a + +echo Files on different filesystems +_pwrite_byte 0x58 0 $((blksz * nrblks)) $SCRATCH_MNT/c >> $seqres.full +$XFS_IO_PROG -c "swapext $SCRATCH_MNT/c" $dir/a + +echo Files on different mounts +mkdir -p $SCRATCH_MNT/xyz +mount --bind $dir $SCRATCH_MNT/xyz --bind +_pwrite_byte 0x60 0 $((blksz * (nrblks + 2))) $dir/c >> $seqres.full +$XFS_IO_PROG -c "swapext $SCRATCH_MNT/xyz/c" $dir/a +umount $SCRATCH_MNT/xyz + +echo Swapping a file with itself +$XFS_IO_PROG -c "swapext $dir/a" $dir/a + +# success, all done +status=0 +exit diff --git a/tests/generic/1209.out b/tests/generic/1209.out new file mode 100644 index 0000000000..a051ed97d9 --- /dev/null +++ b/tests/generic/1209.out @@ -0,0 +1,33 @@ +QA output created by 1209 +Immutable files +swapext: Operation not permitted +Readonly files +swapext: Bad file descriptor +Directories +swapext: Is a directory +Unaligned ranges +swapext: Invalid argument +file1 range entirely beyond EOF +swapext: Invalid argument +file2 range entirely beyond EOF +swapext: Invalid argument +Both ranges entirely beyond EOF +swapext: Invalid argument +file1 range crossing EOF +swapext: Invalid argument +file2 range crossing EOF +swapext: Invalid argument +Both ranges crossing EOF +swapext: Invalid argument +file1 unaligned EOF to file2 nowhere near EOF +swapext: Invalid argument +file2 unaligned EOF to file1 nowhere near EOF +swapext: Invalid argument +Files of unequal length +swapext: Bad address +Files on different filesystems +swapext: Invalid cross-device link +Files on different mounts +swapext: Invalid cross-device link +Swapping a file with itself +swapext: Invalid argument diff --git a/tests/generic/1210 b/tests/generic/1210 new file mode 100755 index 0000000000..93a325ad7a --- /dev/null +++ b/tests/generic/1210 @@ -0,0 +1,48 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1210 +# +# Make sure swapext honors RLIMIT_FSIZE. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_test + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 +nrblks=64 + +# Create some 4M files to test swapext +_pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full +_pwrite_byte 0x59 0 $((blksz * nrblks)) $dir/b >> $seqres.full +sync +md5sum $dir/a $dir/b | _filter_test_dir + +# Set FSIZE to twice the blocksize (IOWs, 128k) +ulimit -f $(( (blksz * 2) / 512)) +ulimit -a >> $seqres.full + +# Now try to swapext +$XFS_IO_PROG -c "swapext $dir/b" $dir/a +md5sum $dir/a $dir/b | _filter_test_dir + +# success, all done +status=0 +exit diff --git a/tests/generic/1210.out b/tests/generic/1210.out new file mode 100644 index 0000000000..02d41b8838 --- /dev/null +++ b/tests/generic/1210.out @@ -0,0 +1,6 @@ +QA output created by 1210 +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1210/a +901e136269b8d283d311697b7c6dc1f2 TEST_DIR/test-1210/b +swapext: Invalid argument +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1210/a +901e136269b8d283d311697b7c6dc1f2 TEST_DIR/test-1210/b diff --git a/tests/generic/1211 b/tests/generic/1211 new file mode 100755 index 0000000000..f7b8a8d280 --- /dev/null +++ b/tests/generic/1211 @@ -0,0 +1,105 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1211 +# +# Test atomic file replacement when (a) the length is the same; (b) the length +# is different; and (c) someone modifies the original file and we need to +# cancel the update. The staging file is created empty, which implies that the +# caller wants a full file replacement. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_xfs_io_command startupdate '-e' +_require_test + +filesnap() { + echo "$1" + md5sum $2 | _filter_test_dir +} + +mkfile() { + rm -f $dir/a + _pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full + sync +} + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 +nrblks=64 + +# Use the atomic file update staging prototype in xfs_io to update a file. +mkfile +filesnap "before commit" $dir/a + +$XFS_IO_PROG \ + -c 'startupdate -e' \ + -c "pwrite -S 0x60 0 $((blksz * nrblks))" \ + -c 'commitupdate -q' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after commit" $dir/a +echo + +# Use the atomic file updates to replace a file with a shorter file. +mkfile +filesnap "before shorten commit" $dir/a + +$XFS_IO_PROG \ + -c 'startupdate -e' \ + -c 'pwrite -S 0x60 0 55k' \ + -c 'commitupdate -q' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after shorten commit" $dir/a +echo + +# Use the atomic file updates to replace a file with a longer file. +mkfile +filesnap "before lengthen commit" $dir/a + +$XFS_IO_PROG \ + -c 'startupdate -e' \ + -c "pwrite -S 0x60 0 $(( (blksz * nrblks) + 37373 ))" \ + -c 'commitupdate -q' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after lengthen commit" $dir/a +echo + +# Now try the update but with the A file open separately so that we clobber +# mtime and fail the update. +mkfile +filesnap "before fail commit" $dir/a + +$XFS_IO_PROG \ + -c "open $dir/a" \ + -c 'startupdate -e ' \ + -c 'pwrite -S 0x58 44k 55k -b 1m' \ + -c 'file 0' \ + -c 'close' \ + -c 'pwrite -S 0x61 22k 11k -b 1m' \ + -c 'commitupdate -q' \ + "$dir/a" 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after fail commit" $dir/a +echo + +# success, all done +status=0 +exit diff --git a/tests/generic/1211.out b/tests/generic/1211.out new file mode 100644 index 0000000000..a149de198f --- /dev/null +++ b/tests/generic/1211.out @@ -0,0 +1,40 @@ +QA output created by 1211 +before commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1211/a +wrote 4194304/4194304 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1211/a'. +after commit +0558063c531ca7c7864fc5a4923f7144 TEST_DIR/test-1211/a + +before shorten commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1211/a +wrote 56320/56320 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1211/a'. +after shorten commit +52353039d89c5f2b76b9003464e5276a TEST_DIR/test-1211/a + +before lengthen commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1211/a +wrote 4231677/4231677 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1211/a'. +after lengthen commit +1839e7c6bf616160dc51b12179db2642 TEST_DIR/test-1211/a + +before fail commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1211/a +committing update: Device or resource busy +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +[000] TEST_DIR/test-1211/a (xfs,non-sync,non-direct,read-write) + 001 TEST_DIR/test-1211/a (fileupdate) (xfs,non-sync,non-direct,read-write) +[000] TEST_DIR/test-1211/a (fileupdate) (xfs,non-sync,non-direct,read-write) +wrote 11264/11264 bytes at offset 22528 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +after fail commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1211/a + diff --git a/tests/generic/1212 b/tests/generic/1212 new file mode 100755 index 0000000000..c6599e3a35 --- /dev/null +++ b/tests/generic/1212 @@ -0,0 +1,58 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1212 +# +# Stress testing with a lot of extents. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter + +# real QA test starts here +_require_xfs_io_command swapext '-v vfs' +_require_test_program punch-alternating +_require_test + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=$(_get_file_block_size $TEST_DIR) +nrblks=$((LOAD_FACTOR * 100000)) + +_require_fs_space $TEST_DIR $(( (2 * blksz * nrblks) / 1024 )) + +# Create some big swiss cheese files to test swapext with a lot of extents +_pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full +$here/src/punch-alternating $dir/a +_pwrite_byte 0x59 0 $((blksz * nrblks)) $dir/b >> $seqres.full +$here/src/punch-alternating -o 1 $dir/b +filefrag -v $dir/a $dir/b >> $seqres.full + +# Now try to swapext +md5_a="$(md5sum < $dir/a)" +md5_b="$(md5sum < $dir/b)" +date >> $seqres.full +$XFS_IO_PROG -c "swapext $dir/b" $dir/a +date >> $seqres.full + +echo "md5_a=$md5_a" >> $seqres.full +echo "md5_b=$md5_b" >> $seqres.full +md5sum $dir/a $dir/b >> $seqres.full + +test "$(md5sum < $dir/b)" = "$md5_a" || echo "file b does not match former a" +test "$(md5sum < $dir/a)" = "$md5_b" || echo "file a does not match former b" + +echo "Silence is golden!" +# success, all done +status=0 +exit diff --git a/tests/generic/1212.out b/tests/generic/1212.out new file mode 100644 index 0000000000..fb775977ca --- /dev/null +++ b/tests/generic/1212.out @@ -0,0 +1,2 @@ +QA output created by 1212 +Silence is golden! diff --git a/tests/generic/1213 b/tests/generic/1213 new file mode 100755 index 0000000000..d466263a9d --- /dev/null +++ b/tests/generic/1213 @@ -0,0 +1,126 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1213 +# +# Test non-root atomic file updates when (a) the file contents are cloned into +# the staging file; and (b) when the staging file is created empty. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_xfs_io_command startupdate +_require_test_reflink +_require_test +_require_user + +filesnap() { + echo "$1" + md5sum $2 | _filter_test_dir +} + +mkfile() { + rm -f $dir/a + _pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full + chown $qa_user $dir/a $dir/ + sync +} + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 +nrblks=64 + +# Use the atomic file update staging prototype in xfs_io to update a file. +mkfile +filesnap "before commit" $dir/a + +cmd="$XFS_IO_PROG \ + -c 'startupdate' \ + -c 'pwrite -S 0x60 44k 55k -b 1m' \ + -c 'commitupdate -q' \ + \"$dir/a\"" +su -s /bin/bash -c "$cmd" $qa_user 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after commit" $dir/a +echo + +# Use the atomic file updates to replace a file with a shorter file. +mkfile +filesnap "before shorten commit" $dir/a + +cmd="$XFS_IO_PROG \ + -c 'startupdate' \ + -c 'truncate 55k' \ + -c 'pwrite -S 0x60 0 55k' \ + -c 'commitupdate -q' \ + \"$dir/a\"" +su -s /bin/bash -c "$cmd" $qa_user 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after shorten commit" $dir/a +echo + +# Use the atomic file updates to replace a file with a longer file. +mkfile +filesnap "before lengthen commit" $dir/a + +cmd="$XFS_IO_PROG \ + -c 'startupdate' \ + -c \"pwrite -S 0x60 0 $(( (blksz * nrblks) + 37373 ))\" \ + -c 'commitupdate -q' \ + \"$dir/a\"" +su -s /bin/bash -c "$cmd" $qa_user 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after lengthen commit" $dir/a +echo + +# Use the atomic file update staging prototype in xfs_io to cancel updating a +# file. +mkfile +filesnap "before cancel" $dir/a + +cmd="$XFS_IO_PROG \ + -c 'startupdate' \ + -c 'pwrite -S 0x60 44k 55k -b 1m' \ + -c 'cancelupdate' \ + \"$dir/a\"" +su -s /bin/bash -c "$cmd" $qa_user 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after cancel" $dir/a +echo + +# Now try the update but with the A file open separately so that we clobber +# mtime and fail the update. +mkfile +filesnap "before fail commit" $dir/a + +cmd="$XFS_IO_PROG \ + -c \"open $dir/a\" \ + -c 'startupdate' \ + -c 'pwrite -S 0x58 44k 55k -b 1m' \ + -c 'file 0' \ + -c 'close' \ + -c 'pwrite -S 0x61 22k 11k -b 1m' \ + -c 'commitupdate -q' \ + \"$dir/a\"" +su -s /bin/bash -c "$cmd" $qa_user 2>&1 | _filter_xfs_io | _filter_test_dir + +filesnap "after fail commit" $dir/a +echo + +# success, all done +status=0 +exit diff --git a/tests/generic/1213.out b/tests/generic/1213.out new file mode 100644 index 0000000000..b5a140560d --- /dev/null +++ b/tests/generic/1213.out @@ -0,0 +1,48 @@ +QA output created by 1213 +before commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1213/a +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1213/a'. +after commit +bedbd22b58a680219a1225353f6195fa TEST_DIR/test-1213/a + +before shorten commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1213/a +wrote 56320/56320 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1213/a'. +after shorten commit +52353039d89c5f2b76b9003464e5276a TEST_DIR/test-1213/a + +before lengthen commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1213/a +wrote 4231677/4231677 bytes at offset 0 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Committed updates to 'TEST_DIR/test-1213/a'. +after lengthen commit +1839e7c6bf616160dc51b12179db2642 TEST_DIR/test-1213/a + +before cancel +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1213/a +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Cancelled updates to 'TEST_DIR/test-1213/a'. +after cancel +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1213/a + +before fail commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1213/a +committing update: Device or resource busy +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 56320/56320 bytes at offset 45056 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +[000] TEST_DIR/test-1213/a (xfs,non-sync,non-direct,read-write) + 001 TEST_DIR/test-1213/a (fileupdate) (xfs,non-sync,non-direct,read-write) +[000] TEST_DIR/test-1213/a (fileupdate) (xfs,non-sync,non-direct,read-write) +wrote 11264/11264 bytes at offset 22528 +XXX Bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +after fail commit +d712f003e9d467e063cda1baf319b928 TEST_DIR/test-1213/a + diff --git a/tests/generic/1214 b/tests/generic/1214 new file mode 100755 index 0000000000..0cacc57e9c --- /dev/null +++ b/tests/generic/1214 @@ -0,0 +1,63 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1214 +# +# Test swapext with the fsync flag flushes everything to disk before the call +# returns. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_test_program "punch-alternating" +_require_xfs_io_command swapext '-v vfs -a' +_require_scratch +_require_scratch_shutdown + +_scratch_mkfs >> $seqres.full +_scratch_mount + +_pwrite_byte 0x58 0 2m $SCRATCH_MNT/a >> $seqres.full +_pwrite_byte 0x59 0 2m $SCRATCH_MNT/b >> $seqres.full +$here/src/punch-alternating $SCRATCH_MNT/a +$here/src/punch-alternating $SCRATCH_MNT/b + +old_a=$(md5sum $SCRATCH_MNT/a | awk '{print $1}') +old_b=$(md5sum $SCRATCH_MNT/b | awk '{print $1}') +echo "md5 a: $old_a md5 b: $old_b" >> $seqres.full + +od -tx1 -Ad -c $SCRATCH_MNT/a > /tmp/a0 +od -tx1 -Ad -c $SCRATCH_MNT/b > /tmp/b0 + +echo swap >> $seqres.full +$XFS_IO_PROG -c "swapext -v vfs -a -e -f -u $SCRATCH_MNT/a" $SCRATCH_MNT/b +_scratch_shutdown +_scratch_cycle_mount + +new_a=$(md5sum $SCRATCH_MNT/a | awk '{print $1}') +new_b=$(md5sum $SCRATCH_MNT/b | awk '{print $1}') +echo "md5 a: $new_a md5 b: $new_b" >> $seqres.full + +test $old_a = $new_b || echo "scratch file B doesn't match old file A" +test $old_b = $new_a || echo "scratch file A doesn't match old file B" + +od -tx1 -Ad -c $SCRATCH_MNT/a > /tmp/a1 +od -tx1 -Ad -c $SCRATCH_MNT/b > /tmp/b1 + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/generic/1214.out b/tests/generic/1214.out new file mode 100644 index 0000000000..a529e42333 --- /dev/null +++ b/tests/generic/1214.out @@ -0,0 +1,2 @@ +QA output created by 1214 +Silence is golden diff --git a/tests/generic/1215 b/tests/generic/1215 new file mode 100755 index 0000000000..28eb8356d8 --- /dev/null +++ b/tests/generic/1215 @@ -0,0 +1,70 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1215 +# +# Test swapext with the dry run flag doesn't change anything. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink + +# real QA test starts here +_require_test_program "punch-alternating" +_require_xfs_io_command swapext '-v vfs' +_require_scratch + +_scratch_mkfs >> $seqres.full +_scratch_mount + +_pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full +_pwrite_byte 0x59 0 2m $SCRATCH_MNT/b >> $seqres.full +$XFS_IO_PROG -c 'truncate 2m' $SCRATCH_MNT/a +$here/src/punch-alternating $SCRATCH_MNT/a +$here/src/punch-alternating $SCRATCH_MNT/b + +old_a=$(md5sum $SCRATCH_MNT/a | awk '{print $1}') +old_b=$(md5sum $SCRATCH_MNT/b | awk '{print $1}') +echo "md5 a: $old_a md5 b: $old_b" >> $seqres.full + +# Test swapext with the -n option, which will do all the input parameter +# checking and return 0 without changing anything. +echo dry run swap >> $seqres.full +$XFS_IO_PROG -c "swapext -v vfs -n -f -u $SCRATCH_MNT/a" $SCRATCH_MNT/b +_scratch_cycle_mount + +new_a=$(md5sum $SCRATCH_MNT/a | awk '{print $1}') +new_b=$(md5sum $SCRATCH_MNT/b | awk '{print $1}') +echo "md5 a: $new_a md5 b: $new_b" >> $seqres.full + +test $old_a = $new_a || echo "scratch file A should not have swapped" +test $old_b = $new_b || echo "scratch file B should not have swapped" + +# Do it again, but without the -n option, to prove that we can actually +# swap the file contents. +echo actual swap >> $seqres.full +$XFS_IO_PROG -c "swapext -v vfs -f -u $SCRATCH_MNT/a" $SCRATCH_MNT/b +_scratch_cycle_mount + +new_a=$(md5sum $SCRATCH_MNT/a | awk '{print $1}') +new_b=$(md5sum $SCRATCH_MNT/b | awk '{print $1}') +echo "md5 a: $new_a md5 b: $new_b" >> $seqres.full + +test $old_a = $new_b || echo "scratch file A should have swapped" +test $old_b = $new_a || echo "scratch file B should have swapped" + +# success, all done +echo Silence is golden +status=0 +exit diff --git a/tests/generic/1215.out b/tests/generic/1215.out new file mode 100644 index 0000000000..f68a8e6998 --- /dev/null +++ b/tests/generic/1215.out @@ -0,0 +1,2 @@ +QA output created by 1215 +Silence is golden diff --git a/tests/xfs/1208 b/tests/xfs/1208 new file mode 100755 index 0000000000..3106a4036c --- /dev/null +++ b/tests/xfs/1208 @@ -0,0 +1,62 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test No. 1208 +# +# Make sure an atomic swapext actually runs to completion even if we shut +# down the filesystem midway through. + +. ./common/preamble +_begin_fstest auto quick fiexchange swapext + +# Override the default cleanup function. +_cleanup() +{ + cd / + rm -r -f $tmp.* $dir +} + +# Import common functions. +. ./common/filter +. ./common/reflink +. ./common/inject + +# real QA test starts here +_supported_fs xfs +_require_xfs_io_command swapext '-v vfs -a' +_require_test_program "punch-alternating" +_require_xfs_io_command startupdate +_require_xfs_io_error_injection "bmap_finish_one" +_require_test + +filesnap() { + echo "$1" + md5sum $dir/a $dir/b $dir/c | _filter_test_dir +} + +dir=$TEST_DIR/test-$seq +mkdir -p $dir +blksz=65536 +nrblks=137 + +# Create two files to swap, and try to fragment the first file. +rm -f $dir/a +_pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full +$here/src/punch-alternating $dir/a +_pwrite_byte 0x59 0 $((blksz * nrblks)) $dir/b >> $seqres.full +_pwrite_byte 0x59 0 $((blksz * nrblks)) $dir/c >> $seqres.full +_pwrite_byte 0x58 0 $((blksz * nrblks)) $dir/a >> $seqres.full +sync + +# Inject a bmap error and trigger it via swapext. +filesnap "before commit" +$XFS_IO_PROG -x -c 'inject bmap_finish_one' -c "swapext $dir/b" $dir/a + +# Check the file afterwards. +_test_cycle_mount +filesnap "after commit" + +# success, all done +status=0 +exit diff --git a/tests/xfs/1208.out b/tests/xfs/1208.out new file mode 100644 index 0000000000..b6aa1b6231 --- /dev/null +++ b/tests/xfs/1208.out @@ -0,0 +1,10 @@ +QA output created by 1208 +before commit +c7221b1494117327570a0958b0abca51 TEST_DIR/test-1208/a +30cc2b6b307081e10972317013efb0f3 TEST_DIR/test-1208/b +30cc2b6b307081e10972317013efb0f3 TEST_DIR/test-1208/c +swapext: Input/output error +after commit +30cc2b6b307081e10972317013efb0f3 TEST_DIR/test-1208/a +c7221b1494117327570a0958b0abca51 TEST_DIR/test-1208/b +30cc2b6b307081e10972317013efb0f3 TEST_DIR/test-1208/c From patchwork Fri Dec 30 22:18:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 20A9AC4332F for ; Sat, 31 Dec 2022 00:33:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235666AbiLaAdC (ORCPT ); Fri, 30 Dec 2022 19:33:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33540 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235655AbiLaAdB (ORCPT ); Fri, 30 Dec 2022 19:33:01 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6CE814006 for ; Fri, 30 Dec 2022 16:33:00 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 71A1DB80883 for ; Sat, 31 Dec 2022 00:32:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36A20C433EF; Sat, 31 Dec 2022 00:32:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672446778; bh=paKWJ62A0KpEakAT5JYOS1fMjV1u+J0sCcJ9WFUVMnU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=LhrSpq8k36h/zF9b86IJDIDo0iJpuPLyIzshbCIDc27wkq1tNi1pbTTNYxk8zvhfV PlN+Z+d5s49T3VPZCqC8NYD3a74jXxdfNS5vZjgyQaSX0ZihHo+nZwL3qA9KS8ZdWz Bwoge1pkH9cuMJa/H+kSl9mai6xVBmYTweJLtZ29zh2QoCEYMjDYjIIWqdDYoQO5At Xb0JJOi6jBVLdWphThhDKZ4I+07JLAPBtm7lNfaEHYgq0kiye1jtpLDeXo+CabRjW+ /XsoCwDEL9RJ9wQb7AQWe/MRNDGUK1MYhks9t2Hruz/UW+70GPw1pSnDtnaxtQ5Kav qf1nvcnsEdwHA== Subject: [PATCH 4/7] xfs_scrub: fix the work estimation for phase 8 From: "Darrick J. Wong" To: cem@kernel.org, djwong@kernel.org Cc: linux-xfs@vger.kernel.org Date: Fri, 30 Dec 2022 14:18:28 -0800 Message-ID: <167243870802.716924.2818760920067531576.stgit@magnolia> In-Reply-To: <167243870748.716924.8460607901853339412.stgit@magnolia> References: <167243870748.716924.8460607901853339412.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong If there are latent errors on the filesystem, we aren't going to do any work during phase 8 and it makes no sense to add that into the work estimate for the progress bar. Signed-off-by: Darrick J. Wong --- scrub/phase8.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/scrub/phase8.c b/scrub/phase8.c index 80f86f9ecd9..789ef2b2b4e 100644 --- a/scrub/phase8.c +++ b/scrub/phase8.c @@ -21,23 +21,35 @@ /* Phase 8: Trim filesystem. */ -/* Trim the filesystem, if desired. */ -int -phase8_func( +static inline bool +fstrim_ok( struct scrub_ctx *ctx) { - if (action_list_empty(ctx->fs_repair_list) && - action_list_empty(ctx->file_repair_list)) - goto maybe_trim; - /* * If errors remain on the filesystem, do not trim anything. We don't * have any threads running, so it's ok to skip the ctx lock here. */ - if (ctx->corruptions_found || ctx->unfixable_errors != 0) + if (!action_list_empty(ctx->fs_repair_list)) + return false; + if (!action_list_empty(ctx->file_repair_list)) + return false; + + if (ctx->corruptions_found != 0) + return false; + if (ctx->unfixable_errors != 0) + return false; + + return true; +} + +/* Trim the filesystem, if desired. */ +int +phase8_func( + struct scrub_ctx *ctx) +{ + if (!fstrim_ok(ctx)) return 0; -maybe_trim: fstrim(ctx); progress_add(1); return 0; @@ -51,7 +63,11 @@ phase8_estimate( unsigned int *nr_threads, int *rshift) { - *items = 1; + *items = 0; + + if (fstrim_ok(ctx)) + *items = 1; + *nr_threads = 1; *rshift = 0; return 0; From patchwork Fri Dec 30 22:19:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085296 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A59BAC3DA7D for ; Sat, 31 Dec 2022 00:53:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235969AbiLaAxB (ORCPT ); Fri, 30 Dec 2022 19:53:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37882 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235930AbiLaAxB (ORCPT ); Fri, 30 Dec 2022 19:53:01 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D57A913F29; Fri, 30 Dec 2022 16:52:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 94A14B81DFA; Sat, 31 Dec 2022 00:52:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 43985C433EF; Sat, 31 Dec 2022 00:52:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672447977; bh=lcRbbT4hYzL+E4ZZlSfVwqApsVGMxkx0njhBLIOXB8g=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=ZseYNclfQj8hOtdVmtJWUxWtgEfFIC1L+W6U52nPJd4QiGfYJr3I8Zj9vlHuXqmL6 fCf21zGmsUCMzp2xKCf6jQ25G7vHPYrcE4gETC/w0JIMl5jGDGkzIUC4p+UXa3Nsj3 jJAglYSgx5CGBtTZBo/6MkyoVHkl2LpNZ8N1dJcDNvtU7rOV0puJwDnAxdF3TcSPfl yNlVrcIdjkOY3GNquebZHLegmfDH3HgCRFMy9TROdaI4iZBflYZOkfP9VoMZF3i1V/ TWm5Y1FJk2vQZWNpLCeff8mdzygBW5hK+mnNLK/z2ydLDRD94BEsJB4YdNNjGkiHED XpfCUxDT928+A== Subject: [PATCH 5/7] generic: test that file privilege gets dropped with FIEXCHANGE_RANGE From: "Darrick J. Wong" To: zlang@redhat.com, djwong@kernel.org Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org, guan@eryu.me Date: Fri, 30 Dec 2022 14:19:48 -0800 Message-ID: <167243878886.732172.11575927475610726999.stgit@magnolia> In-Reply-To: <167243878818.732172.6392253687008406885.stgit@magnolia> References: <167243878818.732172.6392253687008406885.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Make sure that we clear the suid and sgid bits and capabilities during a FIEXCHANGE_RANGE call just like we would for a regular file write. Signed-off-by: Darrick J. Wong --- tests/generic/1218 | 115 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/1218.out | 49 ++++++++++++++++++++ tests/generic/1219 | 83 +++++++++++++++++++++++++++++++++++ tests/generic/1219.out | 17 +++++++ 4 files changed, 264 insertions(+) create mode 100755 tests/generic/1218 create mode 100644 tests/generic/1218.out create mode 100755 tests/generic/1219 create mode 100755 tests/generic/1219.out diff --git a/tests/generic/1218 b/tests/generic/1218 new file mode 100755 index 0000000000..e6c170351e --- /dev/null +++ b/tests/generic/1218 @@ -0,0 +1,115 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test 1218 +# +# Functional test for dropping suid and sgid bits as part of an atomic file +# commit. +# +. ./common/preamble +_begin_fstest auto fiexchange swapext quick + +# Override the default cleanup function. +# _cleanup() +# { +# cd / +# rm -r -f $tmp.* +# } + +# Import common functions. +. ./common/filter + +# real QA test starts here + +# Modify as appropriate. +_supported_fs generic +_require_user +_require_xfs_io_command swapext '-v vfs -a' +_require_xfs_io_command startupdate +_require_scratch + +_scratch_mkfs >> $seqres.full +_scratch_mount +_require_congruent_file_oplen $SCRATCH_MNT 1048576 +chmod a+rw $SCRATCH_MNT/ + +setup_testfile() { + rm -f $SCRATCH_MNT/a + _pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full + sync +} + +commit_and_check() { + local user="$1" + + md5sum $SCRATCH_MNT/a | _filter_scratch + stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch + + local cmd="$XFS_IO_PROG -c 'startupdate' -c 'pwrite -S 0x57 0 1m' -c 'commitupdate' $SCRATCH_MNT/a" + if [ -n "$user" ]; then + su - "$user" -c "$cmd" >> $seqres.full + else + $SHELL -c "$cmd" >> $seqres.full + fi + + _scratch_cycle_mount + md5sum $SCRATCH_MNT/a | _filter_scratch + stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch + + # Blank line in output + echo +} + +# Commit to a non-exec file by an unprivileged user clears suid but leaves +# sgid. +echo "Test 1 - qa_user, non-exec file" +setup_testfile +chmod a+rws $SCRATCH_MNT/a +commit_and_check "$qa_user" + +# Commit to a group-exec file by an unprivileged user clears suid and sgid. +echo "Test 2 - qa_user, group-exec file" +setup_testfile +chmod g+x,a+rws $SCRATCH_MNT/a +commit_and_check "$qa_user" + +# Commit to a user-exec file by an unprivileged user clears suid but not sgid. +echo "Test 3 - qa_user, user-exec file" +setup_testfile +chmod u+x,a+rws,g-x $SCRATCH_MNT/a +commit_and_check "$qa_user" + +# Commit to a all-exec file by an unprivileged user clears suid and sgid. +echo "Test 4 - qa_user, all-exec file" +setup_testfile +chmod a+rwxs $SCRATCH_MNT/a +commit_and_check "$qa_user" + +# Commit to a non-exec file by root leaves suid and sgid. +echo "Test 5 - root, non-exec file" +setup_testfile +chmod a+rws $SCRATCH_MNT/a +commit_and_check + +# Commit to a group-exec file by root leaves suid and sgid. +echo "Test 6 - root, group-exec file" +setup_testfile +chmod g+x,a+rws $SCRATCH_MNT/a +commit_and_check + +# Commit to a user-exec file by root leaves suid and sgid. +echo "Test 7 - root, user-exec file" +setup_testfile +chmod u+x,a+rws,g-x $SCRATCH_MNT/a +commit_and_check + +# Commit to a all-exec file by root leaves suid and sgid. +echo "Test 8 - root, all-exec file" +setup_testfile +chmod a+rwxs $SCRATCH_MNT/a +commit_and_check + +# success, all done +status=0 +exit diff --git a/tests/generic/1218.out b/tests/generic/1218.out new file mode 100644 index 0000000000..8f4469aad4 --- /dev/null +++ b/tests/generic/1218.out @@ -0,0 +1,49 @@ +QA output created by 1218 +Test 1 - qa_user, non-exec file +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +6666 -rwSrwSrw- SCRATCH_MNT/a +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +666 -rw-rw-rw- SCRATCH_MNT/a + +Test 2 - qa_user, group-exec file +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +6676 -rwSrwsrw- SCRATCH_MNT/a +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +676 -rw-rwxrw- SCRATCH_MNT/a + +Test 3 - qa_user, user-exec file +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +6766 -rwsrwSrw- SCRATCH_MNT/a +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +766 -rwxrw-rw- SCRATCH_MNT/a + +Test 4 - qa_user, all-exec file +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +6777 -rwsrwsrwx SCRATCH_MNT/a +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +777 -rwxrwxrwx SCRATCH_MNT/a + +Test 5 - root, non-exec file +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +6666 -rwSrwSrw- SCRATCH_MNT/a +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +6666 -rwSrwSrw- SCRATCH_MNT/a + +Test 6 - root, group-exec file +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +6676 -rwSrwsrw- SCRATCH_MNT/a +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +6676 -rwSrwsrw- SCRATCH_MNT/a + +Test 7 - root, user-exec file +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +6766 -rwsrwSrw- SCRATCH_MNT/a +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +6766 -rwsrwSrw- SCRATCH_MNT/a + +Test 8 - root, all-exec file +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +6777 -rwsrwsrwx SCRATCH_MNT/a +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +6777 -rwsrwsrwx SCRATCH_MNT/a + diff --git a/tests/generic/1219 b/tests/generic/1219 new file mode 100755 index 0000000000..fe20475058 --- /dev/null +++ b/tests/generic/1219 @@ -0,0 +1,83 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2022 Oracle. All Rights Reserved. +# +# FS QA Test 1219 +# +# Functional test for dropping capability bits as part of an atomic file +# commit. +# +. ./common/preamble +_begin_fstest auto fiexchange swapext quick + +# Override the default cleanup function. +# _cleanup() +# { +# cd / +# rm -r -f $tmp.* +# } + +# Import common functions. +. ./common/filter + +# real QA test starts here + +# Modify as appropriate. +_supported_fs generic +_require_user +_require_command "$GETCAP_PROG" getcap +_require_command "$SETCAP_PROG" setcap +_require_xfs_io_command swapext '-v vfs -a' +_require_xfs_io_command startupdate +_require_scratch + +_scratch_mkfs >> $seqres.full +_scratch_mount +_require_congruent_file_oplen $SCRATCH_MNT 1048576 +chmod a+rw $SCRATCH_MNT/ + +setup_testfile() { + rm -f $SCRATCH_MNT/a $SCRATCH_MNT/b + _pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full + _pwrite_byte 0x57 0 1m $SCRATCH_MNT/b >> $seqres.full + chmod a+rw $SCRATCH_MNT/a $SCRATCH_MNT/b + $SETCAP_PROG cap_setgid,cap_setuid+ep $SCRATCH_MNT/a + sync +} + +commit_and_check() { + local user="$1" + + md5sum $SCRATCH_MNT/a | _filter_scratch + stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch + _getcap -v $SCRATCH_MNT/a | _filter_scratch + + local cmd="$XFS_IO_PROG -c 'startupdate' -c 'pwrite -S 0x57 0 1m' -c 'commitupdate' $SCRATCH_MNT/a" + if [ -n "$user" ]; then + su - "$user" -c "$cmd" >> $seqres.full + else + $SHELL -c "$cmd" >> $seqres.full + fi + + _scratch_cycle_mount + md5sum $SCRATCH_MNT/a | _filter_scratch + stat -c '%a %A %n' $SCRATCH_MNT/a | _filter_scratch + _getcap -v $SCRATCH_MNT/a | _filter_scratch + + # Blank line in output + echo +} + +# Commit by an unprivileged user clears capability bits. +echo "Test 1 - qa_user" +setup_testfile +commit_and_check "$qa_user" + +# Commit by root leaves capability bits. +echo "Test 2 - root" +setup_testfile +commit_and_check + +# success, all done +status=0 +exit diff --git a/tests/generic/1219.out b/tests/generic/1219.out new file mode 100755 index 0000000000..a925b4ec4f --- /dev/null +++ b/tests/generic/1219.out @@ -0,0 +1,17 @@ +QA output created by 1219 +Test 1 - qa_user +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +666 -rw-rw-rw- SCRATCH_MNT/a +SCRATCH_MNT/a cap_setgid,cap_setuid=ep +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +666 -rw-rw-rw- SCRATCH_MNT/a +SCRATCH_MNT/a + +Test 2 - root +310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a +666 -rw-rw-rw- SCRATCH_MNT/a +SCRATCH_MNT/a cap_setgid,cap_setuid=ep +3784de23efab7a2074c9ec66901e39e5 SCRATCH_MNT/a +666 -rw-rw-rw- SCRATCH_MNT/a +SCRATCH_MNT/a + From patchwork Fri Dec 30 22:19:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085297 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4CEEC4332F for ; Sat, 31 Dec 2022 00:53:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235985AbiLaAxP (ORCPT ); Fri, 30 Dec 2022 19:53:15 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235930AbiLaAxP (ORCPT ); Fri, 30 Dec 2022 19:53:15 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DC2FA186CF; Fri, 30 Dec 2022 16:53:13 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6B19561D47; Sat, 31 Dec 2022 00:53:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C9189C433EF; Sat, 31 Dec 2022 00:53:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672447992; bh=n4wj0sE2v3XC34dlrIeh+9bA37XaAGa4dS3eOB10hoM=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=OECNRTgXlu5Z2c0RiVHIMYNJ+dMYjtgXLxD2yNKvHVybB7DY2CIuhKHNOmjpLlG6c RzmF2AxC7l8qavpB1SGvcKpuT82VkHIq4nv3BnX6E4k2s+3odAdEQgN3qg38ijpP3l vVppu7h9h7VOihlbEk5A7M0mfV9wC6ihP0xWtomdSuHIxTbrTtT69HuKdGRvUeSvll PTlU9oKyqJO1QfmQPtu93xsaniUmXIN0I51CFY4NKC3+ceE/7ijM9GTFWmUJ0A3SPL 1rjICEaz+K7hV5UqI/5tK3Pl7KB+iLSDvlVVSR0wRCRYQ8d3QFGFjTl20LIpI+FKSe 5M7L1KEHLJJGg== Subject: [PATCH 6/7] fsx: support FIEXCHANGE_RANGE From: "Darrick J. Wong" To: zlang@redhat.com, djwong@kernel.org Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org, guan@eryu.me Date: Fri, 30 Dec 2022 14:19:49 -0800 Message-ID: <167243878899.732172.1539601356241657286.stgit@magnolia> In-Reply-To: <167243878818.732172.6392253687008406885.stgit@magnolia> References: <167243878818.732172.6392253687008406885.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Upgrade fsx to support exchanging file contents. Signed-off-by: Darrick J. Wong --- configure.ac | 1 include/builddefs.in | 1 ltp/Makefile | 4 + ltp/fsx.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++- m4/package_libcdev.m4 | 21 ++++++ src/fiexchange.h | 101 +++++++++++++++++++++++++++++++ src/global.h | 6 ++ 7 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 src/fiexchange.h diff --git a/configure.ac b/configure.ac index e92bd6b26d..4687d8a3c0 100644 --- a/configure.ac +++ b/configure.ac @@ -70,6 +70,7 @@ AC_HAVE_SEEK_DATA AC_HAVE_BMV_OF_SHARED AC_HAVE_NFTW AC_HAVE_RLIMIT_NOFILE +AC_HAVE_FIEXCHANGE AC_CHECK_FUNCS([renameat2]) AC_CHECK_FUNCS([reallocarray]) diff --git a/include/builddefs.in b/include/builddefs.in index dab10c968f..969acf0da2 100644 --- a/include/builddefs.in +++ b/include/builddefs.in @@ -72,6 +72,7 @@ HAVE_SEEK_DATA = @have_seek_data@ HAVE_NFTW = @have_nftw@ HAVE_BMV_OF_SHARED = @have_bmv_of_shared@ HAVE_RLIMIT_NOFILE = @have_rlimit_nofile@ +HAVE_FIEXCHANGE = @have_fiexchange@ GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall diff --git a/ltp/Makefile b/ltp/Makefile index 85f634145c..c2b70d896e 100644 --- a/ltp/Makefile +++ b/ltp/Makefile @@ -36,6 +36,10 @@ ifeq ($(HAVE_COPY_FILE_RANGE),yes) LCFLAGS += -DHAVE_COPY_FILE_RANGE endif +ifeq ($(HAVE_FIEXCHANGE),yes) +LCFLAGS += -DHAVE_FIEXCHANGE +endif + default: depend $(TARGETS) depend: .dep diff --git a/ltp/fsx.c b/ltp/fsx.c index 12c2cc33bf..ee4b8fe45d 100644 --- a/ltp/fsx.c +++ b/ltp/fsx.c @@ -111,6 +111,7 @@ enum { OP_CLONE_RANGE, OP_DEDUPE_RANGE, OP_COPY_RANGE, + OP_EXCHANGE_RANGE, OP_MAX_FULL, /* integrity operations */ @@ -175,6 +176,7 @@ int check_file = 0; /* -X flag enables */ int clone_range_calls = 1; /* -J flag disables */ int dedupe_range_calls = 1; /* -B flag disables */ int copy_range_calls = 1; /* -E flag disables */ +int xchg_range_calls = 1; /* -0 flag disables */ int integrity = 0; /* -i flag */ int fsxgoodfd = 0; int o_direct; /* -Z */ @@ -268,6 +270,7 @@ static const char *op_names[] = { [OP_DEDUPE_RANGE] = "dedupe_range", [OP_COPY_RANGE] = "copy_range", [OP_FSYNC] = "fsync", + [OP_EXCHANGE_RANGE] = "xchg_range", }; static const char *op_name(int operation) @@ -452,6 +455,20 @@ logdump(void) if (overlap) prt("\t******IIII"); break; + case OP_EXCHANGE_RANGE: + prt("XCHG 0x%x thru 0x%x\t(0x%x bytes) to 0x%x thru 0x%x", + lp->args[0], lp->args[0] + lp->args[1] - 1, + lp->args[1], + lp->args[2], lp->args[2] + lp->args[1] - 1); + overlap2 = badoff >= lp->args[2] && + badoff < lp->args[2] + lp->args[1]; + if (overlap && overlap2) + prt("\tXXXX**XXXX"); + else if (overlap) + prt("\tXXXX******"); + else if (overlap2) + prt("\t******XXXX"); + break; case OP_CLONE_RANGE: prt("CLONE 0x%x thru 0x%x\t(0x%x bytes) to 0x%x thru 0x%x", lp->args[0], lp->args[0] + lp->args[1] - 1, @@ -1369,6 +1386,116 @@ do_insert_range(unsigned offset, unsigned length) } #endif +#ifdef FIEXCHANGE_RANGE +static __u64 swap_flags = 0; + +int +test_xchg_range(void) +{ + struct file_xchg_range fsr = { + .file1_fd = fd, + .flags = FILE_XCHG_RANGE_DRY_RUN | swap_flags, + }; + int ret, e; + +retry: + ret = ioctl(fd, FIEXCHANGE_RANGE, &fsr); + e = ret < 0 ? errno : 0; + if (e == EOPNOTSUPP && !(swap_flags & FILE_XCHG_RANGE_NONATOMIC)) { + /* + * If the call fails with atomic mode, try again with non + * atomic mode. + */ + swap_flags = FILE_XCHG_RANGE_NONATOMIC; + fsr.flags |= swap_flags; + goto retry; + } + if (e == EOPNOTSUPP || errno == ENOTTY) { + if (!quiet) + fprintf(stderr, + "main: filesystem does not support " + "exchange range, disabling!\n"); + return 0; + } + + return 1; +} + +void +do_xchg_range(unsigned offset, unsigned length, unsigned dest) +{ + struct file_xchg_range fsr = { + .file1_fd = fd, + .file1_offset = offset, + .file2_offset = dest, + .length = length, + .flags = swap_flags, + }; + void *p; + + if (length == 0) { + if (!quiet && testcalls > simulatedopcount) + prt("skipping zero length exchange range\n"); + log5(OP_EXCHANGE_RANGE, offset, length, dest, FL_SKIPPED); + return; + } + + if ((loff_t)offset >= file_size || (loff_t)dest >= file_size) { + if (!quiet && testcalls > simulatedopcount) + prt("skipping exchange range behind EOF\n"); + log5(OP_EXCHANGE_RANGE, offset, length, dest, FL_SKIPPED); + return; + } + + p = malloc(length); + if (!p) { + if (!quiet && testcalls > simulatedopcount) + prt("skipping exchange range due to ENOMEM\n"); + log5(OP_EXCHANGE_RANGE, offset, length, dest, FL_SKIPPED); + return; + } + + log5(OP_EXCHANGE_RANGE, offset, length, dest, FL_NONE); + + if (testcalls <= simulatedopcount) + goto out_free; + + if ((progressinterval && testcalls % progressinterval == 0) || + (debug && (monitorstart == -1 || monitorend == -1 || + dest <= monitorstart || dest + length <= monitorend))) { + prt("%lu swap\tfrom 0x%x to 0x%x, (0x%x bytes) at 0x%x\n", + testcalls, offset, offset+length, length, dest); + } + + if (ioctl(fd, FIEXCHANGE_RANGE, &fsr) == -1) { + prt("exchange range: 0x%x to 0x%x at 0x%x\n", offset, + offset + length, dest); + prterr("do_xchg_range: FIEXCHANGE_RANGE"); + report_failure(161); + goto out_free; + } + + memcpy(p, good_buf + offset, length); + memcpy(good_buf + offset, good_buf + dest, length); + memcpy(good_buf + dest, p, length); +out_free: + free(p); +} + +#else +int +test_xchg_range(void) +{ + return 0; +} + +void +do_xchg_range(unsigned offset, unsigned length, unsigned dest) +{ + return; +} +#endif + #ifdef FICLONERANGE int test_clone_range(void) @@ -1856,6 +1983,7 @@ static int op_args_count(int operation) { switch (operation) { + case OP_EXCHANGE_RANGE: case OP_CLONE_RANGE: case OP_DEDUPE_RANGE: case OP_COPY_RANGE: @@ -2053,6 +2181,9 @@ test(void) case OP_COPY_RANGE: generate_dest_range(true, maxfilelen, &offset, &size, &offset2); break; + case OP_EXCHANGE_RANGE: + generate_dest_range(false, file_size, &offset, &size, &offset2); + break; } have_op: @@ -2096,6 +2227,12 @@ test(void) goto out; } break; + case OP_EXCHANGE_RANGE: + if (!xchg_range_calls) { + log5(op, offset, size, offset2, FL_SKIPPED); + goto out; + } + break; case OP_CLONE_RANGE: if (!clone_range_calls) { log5(op, offset, size, offset2, FL_SKIPPED); @@ -2180,6 +2317,18 @@ test(void) do_insert_range(offset, size); break; + case OP_EXCHANGE_RANGE: + if (size == 0) { + log5(OP_EXCHANGE_RANGE, offset, size, offset2, FL_SKIPPED); + goto out; + } + if (offset2 + size > maxfilelen) { + log5(OP_EXCHANGE_RANGE, offset, size, offset2, FL_SKIPPED); + goto out; + } + + do_xchg_range(offset, size, offset2); + break; case OP_CLONE_RANGE: if (size == 0) { log5(OP_CLONE_RANGE, offset, size, offset2, FL_SKIPPED); @@ -2294,6 +2443,9 @@ usage(void) #ifdef HAVE_COPY_FILE_RANGE " -E: Do not use copy range calls\n" #endif +#ifdef FIEXCHANGE_RANGE +" -0: Do not use exchange range calls\n" +#endif " -L: fsxLite - no file creations & no file size changes\n\ -N numops: total # operations to do (default infinity)\n\ -O: use oplen (see -o flag) for every op (default random)\n\ @@ -2608,12 +2760,11 @@ main(int argc, char **argv) page_size = getpagesize(); page_mask = page_size - 1; mmap_mask = page_mask; - setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */ while ((ch = getopt_long(argc, argv, - "b:c:dfg:i:j:kl:m:no:p:qr:s:t:w:xyABD:EFJKHzCILN:OP:RS:UWXZ", + "0b:c:dfg:i:j:kl:m:no:p:qr:s:t:w:xyABD:EFJKHzCILN:OP:RS:UWXZ", longopts, NULL)) != EOF) switch (ch) { case 'b': @@ -2747,6 +2898,9 @@ main(int argc, char **argv) case 'I': insert_range_calls = 0; break; + case '0': + xchg_range_calls = 0; + break; case 'J': clone_range_calls = 0; break; @@ -2988,6 +3142,8 @@ main(int argc, char **argv) dedupe_range_calls = test_dedupe_range(); if (copy_range_calls) copy_range_calls = test_copy_range(); + if (xchg_range_calls) + xchg_range_calls = test_xchg_range(); while (numops == -1 || numops--) if (!test()) diff --git a/m4/package_libcdev.m4 b/m4/package_libcdev.m4 index e1b381c16f..db663970c2 100644 --- a/m4/package_libcdev.m4 +++ b/m4/package_libcdev.m4 @@ -157,3 +157,24 @@ AC_DEFUN([AC_HAVE_RLIMIT_NOFILE], AC_MSG_RESULT(no)) AC_SUBST(have_rlimit_nofile) ]) + +# +# Check if we have a FIEXCHANGE_RANGE ioctl (Linux) +# +AC_DEFUN([AC_HAVE_FIEXCHANGE], + [ AC_MSG_CHECKING([for FIEXCHANGE_RANGE]) + AC_TRY_LINK([ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + ], [ + struct file_xchg_range fxr; + ioctl(-1, FIEXCHANGE_RANGE, &fxr); + ], have_fiexchange=yes + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + AC_SUBST(have_fiexchange) + ]) diff --git a/src/fiexchange.h b/src/fiexchange.h new file mode 100644 index 0000000000..29b3ac0ff5 --- /dev/null +++ b/src/fiexchange.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later WITH Linux-syscall-note */ +/* + * FIEXCHANGE ioctl definitions, to facilitate exchanging parts of files. + * + * Copyright (C) 2022 Oracle. All Rights Reserved. + * + * Author: Darrick J. Wong + */ +#ifndef _LINUX_FIEXCHANGE_H +#define _LINUX_FIEXCHANGE_H + +#include + +/* + * Exchange part of file1 with part of the file that this ioctl that is being + * called against (which we'll call file2). Filesystems must be able to + * restart and complete the operation even after the system goes down. + */ +struct file_xchg_range { + __s64 file1_fd; + __s64 file1_offset; /* file1 offset, bytes */ + __s64 file2_offset; /* file2 offset, bytes */ + __s64 length; /* bytes to exchange */ + + __u64 flags; /* see FILE_XCHG_RANGE_* below */ + + /* file2 metadata for optional freshness checks */ + __s64 file2_ino; /* inode number */ + __s64 file2_mtime; /* modification time */ + __s64 file2_ctime; /* change time */ + __s32 file2_mtime_nsec; /* mod time, nsec */ + __s32 file2_ctime_nsec; /* change time, nsec */ + + __u64 pad[6]; /* must be zeroes */ +}; + +/* + * Atomic exchange operations are not required. This relaxes the requirement + * that the filesystem must be able to complete the operation after a crash. + */ +#define FILE_XCHG_RANGE_NONATOMIC (1 << 0) + +/* + * Check that file2's inode number, mtime, and ctime against the values + * provided, and return -EBUSY if there isn't an exact match. + */ +#define FILE_XCHG_RANGE_FILE2_FRESH (1 << 1) + +/* + * Check that the file1's length is equal to file1_offset + length, and that + * file2's length is equal to file2_offset + length. Returns -EDOM if there + * isn't an exact match. + */ +#define FILE_XCHG_RANGE_FULL_FILES (1 << 2) + +/* + * Exchange file data all the way to the ends of both files, and then exchange + * the file sizes. This flag can be used to replace a file's contents with a + * different amount of data. length will be ignored. + */ +#define FILE_XCHG_RANGE_TO_EOF (1 << 3) + +/* Flush all changes in file data and file metadata to disk before returning. */ +#define FILE_XCHG_RANGE_FSYNC (1 << 4) + +/* Dry run; do all the parameter verification but do not change anything. */ +#define FILE_XCHG_RANGE_DRY_RUN (1 << 5) + +/* + * Do not exchange any part of the range where file1's mapping is a hole. This + * can be used to emulate scatter-gather atomic writes with a temp file. + */ +#define FILE_XCHG_RANGE_SKIP_FILE1_HOLES (1 << 6) + +/* + * Commit the contents of file1 into file2 if file2 has the same inode number, + * mtime, and ctime as the arguments provided to the call. The old contents of + * file2 will be moved to file1. + * + * With this flag, all committed information can be retrieved even if the + * system crashes or is rebooted. This includes writing through or flushing a + * disk cache if present. The call blocks until the device reports that the + * commit is complete. + * + * This flag should not be combined with NONATOMIC. It can be combined with + * SKIP_FILE1_HOLES. + */ +#define FILE_XCHG_RANGE_COMMIT (FILE_XCHG_RANGE_FILE2_FRESH | \ + FILE_XCHG_RANGE_FSYNC) + +#define FILE_XCHG_RANGE_ALL_FLAGS (FILE_XCHG_RANGE_NONATOMIC | \ + FILE_XCHG_RANGE_FILE2_FRESH | \ + FILE_XCHG_RANGE_FULL_FILES | \ + FILE_XCHG_RANGE_TO_EOF | \ + FILE_XCHG_RANGE_FSYNC | \ + FILE_XCHG_RANGE_DRY_RUN | \ + FILE_XCHG_RANGE_SKIP_FILE1_HOLES) + +#define FIEXCHANGE_RANGE _IOWR('X', 129, struct file_xchg_range) + +#endif /* _LINUX_FIEXCHANGE_H */ diff --git a/src/global.h b/src/global.h index b44070993c..49570ef117 100644 --- a/src/global.h +++ b/src/global.h @@ -171,6 +171,12 @@ #include #endif +#ifdef HAVE_FIEXCHANGE +# include +#else +# include "fiexchange.h" +#endif + static inline unsigned long long rounddown_64(unsigned long long x, unsigned int y) { From patchwork Fri Dec 30 22:19:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13085298 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 04B25C3DA7D for ; Sat, 31 Dec 2022 00:53:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235986AbiLaAxd (ORCPT ); Fri, 30 Dec 2022 19:53:33 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37938 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235930AbiLaAxc (ORCPT ); Fri, 30 Dec 2022 19:53:32 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1FD4D13F29; Fri, 30 Dec 2022 16:53:31 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id C4B44B81DF9; Sat, 31 Dec 2022 00:53:29 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 68937C433EF; Sat, 31 Dec 2022 00:53:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1672448008; bh=cWszxIJmhZ2jvP2wtTOB3XoOKrpxJBKvEuJtMu6hraA=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=szp7gNiZnirvYj4Q1KFEafp2ktJbb4bj2TVuf6g04Kc8ccBxGHIwQUqObJQCmzXlN kSSxBwyvmXda3XzwT6pLYx2wbiVYZkxre24VVF/bv+WL7ebXhGa+e1yLG0wcryoqSd AYzsJdvMRVDtcZiwIShJinUavtsV8kTaE8LZu3rBrRwUAZWSyKTeMTm0+WfgzXiFmV vu4mL/e6j91g2HYwxZbctcCtxJzVYauu4kEhgu6yiOPAmYfmsvYnH9aRbwzmXjx9m3 gkdvj4644vr9lOR8dEmSAK23U68I9z5qoP+/UIek0GEwGthwn0KVnHpfBDK7DK44WK QNwpzLwZ6FwHA== Subject: [PATCH 7/7] fsstress: update for FIEXCHANGE_RANGE From: "Darrick J. Wong" To: zlang@redhat.com, djwong@kernel.org Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org, guan@eryu.me Date: Fri, 30 Dec 2022 14:19:49 -0800 Message-ID: <167243878912.732172.17691109886906122211.stgit@magnolia> In-Reply-To: <167243878818.732172.6392253687008406885.stgit@magnolia> References: <167243878818.732172.6392253687008406885.stgit@magnolia> User-Agent: StGit/0.19 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Darrick J. Wong Teach this stress tool to be able to use the file content exchange ioctl. Signed-off-by: Darrick J. Wong --- ltp/fsstress.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/ltp/fsstress.c b/ltp/fsstress.c index 10608fb554..0fba3d92a0 100644 --- a/ltp/fsstress.c +++ b/ltp/fsstress.c @@ -143,6 +143,7 @@ typedef enum { OP_URING_WRITE, OP_WRITE, OP_WRITEV, + OP_XCHGRANGE, OP_LAST } opty_t; @@ -272,6 +273,8 @@ void uring_read_f(opnum_t, long); void uring_write_f(opnum_t, long); void write_f(opnum_t, long); void writev_f(opnum_t, long); +void xchgrange_f(opnum_t, long); + char *xattr_flag_to_string(int); struct opdesc ops[OP_LAST] = { @@ -340,6 +343,7 @@ struct opdesc ops[OP_LAST] = { [OP_URING_WRITE] = {"uring_write", uring_write_f, 1, 1 }, [OP_WRITE] = {"write", write_f, 4, 1 }, [OP_WRITEV] = {"writev", writev_f, 4, 1 }, + [OP_XCHGRANGE] = {"xchgrange", xchgrange_f, 4, 1 }, }, *ops_end; flist_t flist[FT_nft] = { @@ -2494,6 +2498,170 @@ chown_f(opnum_t opno, long r) free_pathname(&f); } +/* exchange some arbitrary range of f1 to f2...fn. */ +void +xchgrange_f( + opnum_t opno, + long r) +{ +#ifdef FIEXCHANGE_RANGE + struct file_xchg_range fxr = { 0 }; + static __u64 swap_flags = 0; + struct pathname fpath1; + struct pathname fpath2; + struct stat64 stat1; + struct stat64 stat2; + char inoinfo1[1024]; + char inoinfo2[1024]; + off64_t lr; + off64_t off1; + off64_t off2; + off64_t max_off2; + size_t len; + int v1; + int v2; + int fd1; + int fd2; + int ret; + int tries = 0; + int e; + + /* Load paths */ + init_pathname(&fpath1); + if (!get_fname(FT_REGm, r, &fpath1, NULL, NULL, &v1)) { + if (v1) + printf("%d/%lld: xchgrange read - no filename\n", + procid, opno); + goto out_fpath1; + } + + init_pathname(&fpath2); + if (!get_fname(FT_REGm, random(), &fpath2, NULL, NULL, &v2)) { + if (v2) + printf("%d/%lld: xchgrange write - no filename\n", + procid, opno); + goto out_fpath2; + } + + /* Open files */ + fd1 = open_path(&fpath1, O_RDONLY); + e = fd1 < 0 ? errno : 0; + check_cwd(); + if (fd1 < 0) { + if (v1) + printf("%d/%lld: xchgrange read - open %s failed %d\n", + procid, opno, fpath1.path, e); + goto out_fpath2; + } + + fd2 = open_path(&fpath2, O_WRONLY); + e = fd2 < 0 ? errno : 0; + check_cwd(); + if (fd2 < 0) { + if (v2) + printf("%d/%lld: xchgrange write - open %s failed %d\n", + procid, opno, fpath2.path, e); + goto out_fd1; + } + + /* Get file stats */ + if (fstat64(fd1, &stat1) < 0) { + if (v1) + printf("%d/%lld: xchgrange read - fstat64 %s failed %d\n", + procid, opno, fpath1.path, errno); + goto out_fd2; + } + inode_info(inoinfo1, sizeof(inoinfo1), &stat1, v1); + + if (fstat64(fd2, &stat2) < 0) { + if (v2) + printf("%d/%lld: xchgrange write - fstat64 %s failed %d\n", + procid, opno, fpath2.path, errno); + goto out_fd2; + } + inode_info(inoinfo2, sizeof(inoinfo2), &stat2, v2); + + if (stat1.st_size < (stat1.st_blksize * 2) || + stat2.st_size < (stat2.st_blksize * 2)) { + if (v2) + printf("%d/%lld: xchgrange - files are too small\n", + procid, opno); + goto out_fd2; + } + + /* Never let us swap more than 1/4 of the files. */ + len = (random() % FILELEN_MAX) + 1; + if (len > stat1.st_size / 4) + len = stat1.st_size / 4; + if (len > stat2.st_size / 4) + len = stat2.st_size / 4; + len = rounddown_64(len, stat1.st_blksize); + if (len == 0) + len = stat1.st_blksize; + + /* Calculate offsets */ + lr = ((int64_t)random() << 32) + random(); + if (stat1.st_size == len) + off1 = 0; + else + off1 = (off64_t)(lr % MIN(stat1.st_size - len, MAXFSIZE)); + off1 %= maxfsize; + off1 = rounddown_64(off1, stat1.st_blksize); + + /* + * If srcfile == destfile, randomly generate destination ranges + * until we find one that doesn't overlap the source range. + */ + max_off2 = MIN(stat2.st_size - len, MAXFSIZE); + do { + lr = ((int64_t)random() << 32) + random(); + if (stat2.st_size == len) + off2 = 0; + else + off2 = (off64_t)(lr % max_off2); + off2 %= maxfsize; + off2 = rounddown_64(off2, stat2.st_blksize); + } while (stat1.st_ino == stat2.st_ino && + llabs(off2 - off1) < len && + tries++ < 10); + + /* Swap data blocks */ + fxr.file1_fd = fd1; + fxr.file1_offset = off1; + fxr.length = len; + fxr.file2_offset = off2; + fxr.flags = swap_flags; + +retry: + ret = ioctl(fd2, FIEXCHANGE_RANGE, &fxr); + e = ret < 0 ? errno : 0; + if (e == EOPNOTSUPP && !(swap_flags & FILE_XCHG_RANGE_NONATOMIC)) { + swap_flags = FILE_XCHG_RANGE_NONATOMIC; + fxr.flags |= swap_flags; + goto retry; + } + if (v1 || v2) { + printf("%d/%lld: xchgrange %s%s [%lld,%lld] -> %s%s [%lld,%lld]", + procid, opno, + fpath1.path, inoinfo1, (long long)off1, (long long)len, + fpath2.path, inoinfo2, (long long)off2, (long long)len); + + if (ret < 0) + printf(" error %d", e); + printf("\n"); + } + +out_fd2: + close(fd2); +out_fd1: + close(fd1); +out_fpath2: + free_pathname(&fpath2); +out_fpath1: + free_pathname(&fpath1); +#endif +} + /* reflink some arbitrary range of f1 to f2. */ void clonerange_f(