@@ -1763,3 +1763,22 @@ _scratch_xfs_find_agbtree_height() {
return 1
}
+
+_require_xfs_mkfs_atomicswap()
+{
+ # atomicswap can be activated on rmap or reflink filesystems.
+ # reflink is newer (4.9 for reflink vs. 4.8 for rmap) so test that.
+ _scratch_mkfs_xfs_supported -m reflink=1 >/dev/null 2>&1 || \
+ _notrun "mkfs.xfs doesn't have atomicswap dependent features"
+}
+
+_require_xfs_scratch_atomicswap()
+{
+ _require_xfs_mkfs_atomicswap
+ _require_scratch
+ _require_xfs_io_command swapext '-v vfs -a'
+ _scratch_mkfs -m reflink=1 > /dev/null
+ _try_scratch_mount || \
+ _notrun "atomicswap dependencies not supported by scratch filesystem type: $FSTYP"
+ _scratch_unmount
+}
new file mode 100755
@@ -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. 1216
+#
+# Test scatter-gather atomic file writes. We create a temporary file, write
+# sparsely to it, then use FILE_SWAP_RANGE_SKIP_FILE1_HOLES flag to swap
+# atomicallly only the ranges that we wrote.
+
+. ./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 -a'
+_require_scratch
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+_require_congruent_file_oplen $SCRATCH_MNT 65536
+
+# Create original file
+_pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
+
+# Create the donor file
+_pwrite_byte 0x59 64k 64k $SCRATCH_MNT/b >> $seqres.full
+_pwrite_byte 0x57 768k 64k $SCRATCH_MNT/b >> $seqres.full
+$XFS_IO_PROG -c 'truncate 1m' $SCRATCH_MNT/b
+
+md5sum $SCRATCH_MNT/a | _filter_scratch
+md5sum $SCRATCH_MNT/b | _filter_scratch
+
+# Test swapext. -h means skip holes in /b, and -e means operate to EOF
+echo swap | tee -a $seqres.full
+$XFS_IO_PROG -c "swapext -v vfs -f -u -h -e -a $SCRATCH_MNT/b" $SCRATCH_MNT/a
+_scratch_cycle_mount
+
+md5sum $SCRATCH_MNT/a | _filter_scratch
+md5sum $SCRATCH_MNT/b | _filter_scratch
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,6 @@
+QA output created by 1216
+310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a
+c9fb827e2e3e579dc2a733ddad486d1d SCRATCH_MNT/b
+swap
+e9cbfe8489a68efaa5fcf40cf3106118 SCRATCH_MNT/a
+faf8ed02a5b0638096a817abcc6c2127 SCRATCH_MNT/b
new file mode 100755
@@ -0,0 +1,56 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1217
+#
+# Test scatter-gather atomic file commits. Use the startupdate command to
+# create a temporary file, write sparsely to it, then commitupdate -h to
+# perform the scattered update.
+
+. ./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 -a'
+_require_xfs_io_command startupdate '-e'
+_require_scratch
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+_require_congruent_file_oplen $SCRATCH_MNT 65536
+
+# Create original file
+_pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
+sync
+md5sum $SCRATCH_MNT/a | _filter_scratch
+
+# Test atomic scatter-gather file commits.
+echo commit | tee -a $seqres.full
+$XFS_IO_PROG \
+ -c 'bmap -elpv' \
+ -c 'startupdate -e' \
+ -c 'truncate 1m' \
+ -c 'pwrite -S 0x59 64k 64k' \
+ -c 'pwrite -S 0x57 768k 64k' \
+ -c 'bmap -elpv' \
+ -c 'commitupdate -h -k' \
+ -c 'bmap -elpv' \
+ $SCRATCH_MNT/a >> $seqres.full
+_scratch_cycle_mount
+
+md5sum $SCRATCH_MNT/a | _filter_scratch
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,4 @@
+QA output created by 1217
+310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a
+commit
+e9cbfe8489a68efaa5fcf40cf3106118 SCRATCH_MNT/a
new file mode 100755
@@ -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. 1211
+#
+# Test scatter-gather atomic file writes. We create a temporary file, write
+# sparsely to it, then use FILE_SWAP_RANGE_SKIP_FILE1_HOLES flag to swap
+# atomicallly only the ranges that we wrote. Inject an error so that we can
+# test that log recovery finishes the swap.
+
+. ./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/inject
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_io_command swapext '-v vfs -a'
+_require_xfs_scratch_atomicswap
+_require_xfs_io_error_injection "bmap_finish_one"
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+_require_congruent_file_oplen $SCRATCH_MNT 65536
+
+# Create original file
+_pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
+
+# Create the donor file
+_pwrite_byte 0x59 64k 64k $SCRATCH_MNT/b >> $seqres.full
+_pwrite_byte 0x57 768k 64k $SCRATCH_MNT/b >> $seqres.full
+$XFS_IO_PROG -c 'truncate 1m' $SCRATCH_MNT/b
+sync
+
+md5sum $SCRATCH_MNT/a | _filter_scratch
+md5sum $SCRATCH_MNT/b | _filter_scratch
+
+# Test swapext. -h means skip holes in /b, and -e means operate to EOF
+echo swap | tee -a $seqres.full
+$XFS_IO_PROG -x -c 'inject bmap_finish_one' \
+ -c "swapext -v vfs -f -u -h -e -a $SCRATCH_MNT/b" $SCRATCH_MNT/a
+_scratch_cycle_mount
+
+md5sum $SCRATCH_MNT/a | _filter_scratch
+md5sum $SCRATCH_MNT/b | _filter_scratch
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,7 @@
+QA output created by 1211
+310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a
+c9fb827e2e3e579dc2a733ddad486d1d SCRATCH_MNT/b
+swap
+swapext: Input/output error
+e9cbfe8489a68efaa5fcf40cf3106118 SCRATCH_MNT/a
+faf8ed02a5b0638096a817abcc6c2127 SCRATCH_MNT/b
new file mode 100755
@@ -0,0 +1,61 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1212
+#
+# Test scatter-gather atomic file commits. Use the startupdate command to
+# create a temporary file, write sparsely to it, then commitupdate -h to
+# perform the scattered update. Inject an error so that we can test that log
+# recovery finishes the swap.
+
+. ./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/inject
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_io_command swapext '-v vfs -a'
+_require_xfs_io_command startupdate '-e'
+_require_xfs_scratch_atomicswap
+_require_xfs_io_error_injection "bmap_finish_one"
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+
+# Create original file
+_pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
+sync
+md5sum $SCRATCH_MNT/a | _filter_scratch
+
+# Test atomic scatter-gather file commits.
+echo commit | tee -a $seqres.full
+$XFS_IO_PROG -x \
+ -c 'bmap -elpv' \
+ -c 'startupdate -e' \
+ -c 'truncate 1m' \
+ -c 'pwrite -S 0x59 64k 64k' \
+ -c 'pwrite -S 0x57 768k 64k' \
+ -c 'sync' \
+ -c 'bmap -elpv' \
+ -c 'inject bmap_finish_one' \
+ -c 'commitupdate -h -k' \
+ $SCRATCH_MNT/a >> $seqres.full
+_scratch_cycle_mount
+
+$XFS_IO_PROG -c 'bmap -elpv' $SCRATCH_MNT/a >> $seqres.full
+md5sum $SCRATCH_MNT/a | _filter_scratch
+
+# success, all done
+status=0
+exit
new file mode 100644
@@ -0,0 +1,5 @@
+QA output created by 1212
+310f146ce52077fcd3308dcbe7632bb2 SCRATCH_MNT/a
+commit
+committing update: Input/output error
+e9cbfe8489a68efaa5fcf40cf3106118 SCRATCH_MNT/a