linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 0/3] atomic writes tests (part 2)
@ 2025-06-16 21:52 Catherine Hoang
  2025-06-16 21:52 ` [PATCH v5 1/3] common/atomicwrites: add helper for multi block atomic writes Catherine Hoang
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Catherine Hoang @ 2025-06-16 21:52 UTC (permalink / raw)
  To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list, ojaswin

Hi all,

This series contains the tests from patch 6 of the previous atomic writes test series.
https://lore.kernel.org/linux-xfs/20250520013400.36830-1-catherine.hoang@oracle.com/

v5 includes minor updates to generic tests and picking up rvb tags. 
This series is based on for-next at the time of sending.

Catherine Hoang (1):
  common/atomicwrites: add helper for multi block atomic writes

Darrick J. Wong (2):
  generic: various atomic write tests with hardware and scsi_debug
  xfs: more multi-block atomic writes tests

 common/atomicwrites    |  31 ++++++++++
 tests/generic/1222     |  88 ++++++++++++++++++++++++++++
 tests/generic/1222.out |  10 ++++
 tests/generic/1223     |  66 +++++++++++++++++++++
 tests/generic/1223.out |   9 +++
 tests/generic/1224     |  86 ++++++++++++++++++++++++++++
 tests/generic/1224.out |  16 ++++++
 tests/generic/1225     | 127 +++++++++++++++++++++++++++++++++++++++++
 tests/generic/1225.out |  21 +++++++
 tests/xfs/1216         |  68 ++++++++++++++++++++++
 tests/xfs/1216.out     |   9 +++
 tests/xfs/1217         |  71 +++++++++++++++++++++++
 tests/xfs/1217.out     |   3 +
 tests/xfs/1218         |  60 +++++++++++++++++++
 tests/xfs/1218.out     |  15 +++++
 15 files changed, 680 insertions(+)
 create mode 100755 tests/generic/1222
 create mode 100644 tests/generic/1222.out
 create mode 100755 tests/generic/1223
 create mode 100644 tests/generic/1223.out
 create mode 100755 tests/generic/1224
 create mode 100644 tests/generic/1224.out
 create mode 100755 tests/generic/1225
 create mode 100644 tests/generic/1225.out
 create mode 100755 tests/xfs/1216
 create mode 100644 tests/xfs/1216.out
 create mode 100755 tests/xfs/1217
 create mode 100644 tests/xfs/1217.out
 create mode 100755 tests/xfs/1218
 create mode 100644 tests/xfs/1218.out

-- 
2.34.1


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v5 1/3] common/atomicwrites: add helper for multi block atomic writes
  2025-06-16 21:52 [PATCH v5 0/3] atomic writes tests (part 2) Catherine Hoang
@ 2025-06-16 21:52 ` Catherine Hoang
  2025-06-16 21:52 ` [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
  2025-06-16 21:52 ` [PATCH v5 3/3] xfs: more multi-block atomic writes tests Catherine Hoang
  2 siblings, 0 replies; 11+ messages in thread
From: Catherine Hoang @ 2025-06-16 21:52 UTC (permalink / raw)
  To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list, ojaswin

Add a helper to check that we can perform multi block atomic writes. We will
use this in the following patches that add testing for large atomic writes.
This helper will prevent these tests from running on kernels that only support
single block atomic writes.

Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
---
 common/atomicwrites | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/common/atomicwrites b/common/atomicwrites
index 391bb6f6..ac4facc3 100644
--- a/common/atomicwrites
+++ b/common/atomicwrites
@@ -24,6 +24,27 @@ _get_atomic_write_segments_max()
         grep -w atomic_write_segments_max | grep -o '[0-9]\+'
 }
 
+_require_scratch_write_atomic_multi_fsblock()
+{
+	_require_scratch
+
+	_scratch_mkfs > /dev/null 2>&1 || \
+		_notrun "cannot format scratch device for atomic write checks"
+	_try_scratch_mount || \
+		_notrun "cannot mount scratch device for atomic write checks"
+
+	local testfile=$SCRATCH_MNT/testfile
+	touch $testfile
+
+	local bsize=$(_get_file_block_size $SCRATCH_MNT)
+	local awu_max_fs=$(_get_atomic_write_unit_max $testfile)
+
+	_scratch_unmount
+
+	test $awu_max_fs -ge $((bsize * 2)) || \
+		_notrun "multi-block atomic writes not supported by this filesystem"
+}
+
 _require_scratch_write_atomic()
 {
 	_require_scratch
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-16 21:52 [PATCH v5 0/3] atomic writes tests (part 2) Catherine Hoang
  2025-06-16 21:52 ` [PATCH v5 1/3] common/atomicwrites: add helper for multi block atomic writes Catherine Hoang
@ 2025-06-16 21:52 ` Catherine Hoang
  2025-06-17 10:18   ` John Garry
                     ` (2 more replies)
  2025-06-16 21:52 ` [PATCH v5 3/3] xfs: more multi-block atomic writes tests Catherine Hoang
  2 siblings, 3 replies; 11+ messages in thread
From: Catherine Hoang @ 2025-06-16 21:52 UTC (permalink / raw)
  To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list, ojaswin

From: "Darrick J. Wong" <djwong@kernel.org>

Simple tests of various atomic write requests and a (simulated) hardware
device.

The first test performs basic multi-block atomic writes on a scsi_debug device
with atomic writes enabled. We test all advertised sizes between the atomic
write unit min and max. We also ensure that the write fails when expected, such
as when attempting buffered io or unaligned directio.

The second test is similar to the one above, except that it verifies multi-block
atomic writes on actual hardware instead of simulated hardware. The device used
in this test is not required to support atomic writes.

The final two tests ensure multi-block atomic writes can be performed on various
interweaved mappings, including written, mapped, hole, and unwritten. We also
test large atomic writes on a heavily fragmented filesystem. These tests are
separated into reflink (shared) and non-reflink tests.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
---
 common/atomicwrites    |  10 ++++
 tests/generic/1222     |  88 ++++++++++++++++++++++++++++
 tests/generic/1222.out |  10 ++++
 tests/generic/1223     |  66 +++++++++++++++++++++
 tests/generic/1223.out |   9 +++
 tests/generic/1224     |  86 ++++++++++++++++++++++++++++
 tests/generic/1224.out |  16 ++++++
 tests/generic/1225     | 127 +++++++++++++++++++++++++++++++++++++++++
 tests/generic/1225.out |  21 +++++++
 9 files changed, 433 insertions(+)
 create mode 100755 tests/generic/1222
 create mode 100644 tests/generic/1222.out
 create mode 100755 tests/generic/1223
 create mode 100644 tests/generic/1223.out
 create mode 100755 tests/generic/1224
 create mode 100644 tests/generic/1224.out
 create mode 100755 tests/generic/1225
 create mode 100644 tests/generic/1225.out

diff --git a/common/atomicwrites b/common/atomicwrites
index ac4facc3..95d545a6 100644
--- a/common/atomicwrites
+++ b/common/atomicwrites
@@ -136,3 +136,13 @@ _test_atomic_file_writes()
     $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
         echo "atomic write requires offset to be aligned to bsize"
 }
+
+_simple_atomic_write() {
+	local pos=$1
+	local count=$2
+	local file=$3
+	local directio=$4
+
+	echo "testing pos=$pos count=$count file=$file directio=$directio" >> $seqres.full
+	$XFS_IO_PROG $directio -c "pwrite -b $count -V 1 -A -D $pos $count" $file >> $seqres.full
+}
diff --git a/tests/generic/1222 b/tests/generic/1222
new file mode 100755
index 00000000..c718b244
--- /dev/null
+++ b/tests/generic/1222
@@ -0,0 +1,88 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1222
+#
+# Validate multi-fsblock atomic write support with simulated hardware support
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/scsi_debug
+. ./common/atomicwrites
+
+_cleanup()
+{
+	_scratch_unmount &>/dev/null
+	_put_scsi_debug_dev &>/dev/null
+	cd /
+	rm -r -f $tmp.*
+}
+
+_require_scsi_debug
+_require_scratch_nocheck
+# Format something so that ./check doesn't freak out
+_scratch_mkfs >> $seqres.full
+
+# 512b logical/physical sectors, 512M size, atomic writes enabled
+dev=$(_get_scsi_debug_dev 512 512 0 512 "atomic_wr=1")
+test -b "$dev" || _notrun "could not create atomic writes scsi_debug device"
+
+export SCRATCH_DEV=$dev
+unset USE_EXTERNAL
+
+_require_scratch_write_atomic
+_require_scratch_write_atomic_multi_fsblock
+
+xfs_io -c 'help pwrite' | grep -q RWF_ATOMIC || _notrun "xfs_io pwrite -A failed"
+xfs_io -c 'help falloc' | grep -q 'not found' && _notrun "xfs_io falloc failed"
+
+echo "scsi_debug atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
+
+testfile=$SCRATCH_MNT/testfile
+touch $testfile
+
+echo "filesystem atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
+
+sector_size=$(blockdev --getss $SCRATCH_DEV)
+min_awu=$(_get_atomic_write_unit_min $testfile)
+max_awu=$(_get_atomic_write_unit_max $testfile)
+
+$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+
+# try outside the advertised sizes
+echo "two EINVAL for unsupported sizes"
+min_i=$((min_awu / 2))
+_simple_atomic_write $min_i $min_i $testfile -d
+max_i=$((max_awu * 2))
+_simple_atomic_write $max_i $max_i $testfile -d
+
+# try all of the advertised sizes
+echo "all should work"
+for ((i = min_awu; i <= max_awu; i *= 2)); do
+	$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+	_test_atomic_file_writes $i $testfile
+done
+
+# does not support buffered io
+echo "one EOPNOTSUPP for buffered atomic"
+_simple_atomic_write 0 $min_awu $testfile
+
+# does not support unaligned directio
+echo "one EINVAL for unaligned directio"
+_simple_atomic_write $sector_size $min_awu $testfile -d
+
+_scratch_unmount
+_put_scsi_debug_dev
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/generic/1222.out b/tests/generic/1222.out
new file mode 100644
index 00000000..158b52fa
--- /dev/null
+++ b/tests/generic/1222.out
@@ -0,0 +1,10 @@
+QA output created by 1222
+two EINVAL for unsupported sizes
+pwrite: Invalid argument
+pwrite: Invalid argument
+all should work
+one EOPNOTSUPP for buffered atomic
+pwrite: Operation not supported
+one EINVAL for unaligned directio
+pwrite: Invalid argument
+Silence is golden
diff --git a/tests/generic/1223 b/tests/generic/1223
new file mode 100755
index 00000000..db242e7f
--- /dev/null
+++ b/tests/generic/1223
@@ -0,0 +1,66 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1223
+#
+# Validate multi-fsblock atomic write support with or without hw support
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+
+_require_scratch
+_require_atomic_write_test_commands
+_require_scratch_write_atomic_multi_fsblock
+
+echo "scratch device atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
+
+testfile=$SCRATCH_MNT/testfile
+touch $testfile
+
+echo "filesystem atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
+
+sector_size=$(blockdev --getss $SCRATCH_DEV)
+min_awu=$(_get_atomic_write_unit_min $testfile)
+max_awu=$(_get_atomic_write_unit_max $testfile)
+
+$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+
+# try outside the advertised sizes
+echo "two EINVAL for unsupported sizes"
+min_i=$((min_awu / 2))
+_simple_atomic_write $min_i $min_i $testfile -d
+max_i=$((max_awu * 2))
+_simple_atomic_write $max_i $max_i $testfile -d
+
+# try all of the advertised sizes
+for ((i = min_awu; i <= max_awu; i *= 2)); do
+	$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+	_test_atomic_file_writes $i $testfile
+done
+
+# does not support buffered io
+echo "one EOPNOTSUPP for buffered atomic"
+_simple_atomic_write 0 $min_awu $testfile
+
+# does not support unaligned directio
+echo "one EINVAL for unaligned directio"
+if [ $sector_size -lt $min_awu ]; then
+	_simple_atomic_write $sector_size $min_awu $testfile -d
+else
+	# not supported, so fake the output
+	echo "pwrite: Invalid argument"
+fi
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/generic/1223.out b/tests/generic/1223.out
new file mode 100644
index 00000000..edf5bd71
--- /dev/null
+++ b/tests/generic/1223.out
@@ -0,0 +1,9 @@
+QA output created by 1223
+two EINVAL for unsupported sizes
+pwrite: Invalid argument
+pwrite: Invalid argument
+one EOPNOTSUPP for buffered atomic
+pwrite: Operation not supported
+one EINVAL for unaligned directio
+pwrite: Invalid argument
+Silence is golden
diff --git a/tests/generic/1224 b/tests/generic/1224
new file mode 100755
index 00000000..3f83eebc
--- /dev/null
+++ b/tests/generic/1224
@@ -0,0 +1,86 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1224
+#
+# reflink tests for large atomic writes with mixed mappings
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+. ./common/filter
+. ./common/reflink
+
+_require_scratch
+_require_atomic_write_test_commands
+_require_scratch_write_atomic_multi_fsblock
+_require_xfs_io_command pwrite -A
+_require_cp_reflink
+
+_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
+_scratch_mount
+
+file1=$SCRATCH_MNT/file1
+file2=$SCRATCH_MNT/file2
+file3=$SCRATCH_MNT/file3
+
+touch $file1
+
+max_awu=$(_get_atomic_write_unit_max $file1)
+test $max_awu -ge 262144 || _notrun "test requires atomic writes up to 256k"
+
+min_awu=$(_get_atomic_write_unit_min $file1)
+test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
+
+bsize=$(_get_file_block_size $SCRATCH_MNT)
+test $max_awu -gt $((bsize * 2)) || \
+	_notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
+
+# reflink tests (files with shared extents)
+
+echo "atomic write shared data and unshared+shared data"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+cp --reflink=always $file1 $file2
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+echo "atomic write shared data and shared+unshared data"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+cp --reflink=always $file1 $file2
+$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+echo "atomic overwrite unshared data"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+cp --reflink=always $file1 $file2
+$XFS_IO_PROG -dc "pwrite -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+echo "atomic write shared+unshared+shared data"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+cp --reflink=always $file1 $file2
+$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+echo "atomic write interweaved hole+unwritten+written+reflinked"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+blksz=4096
+nr=32
+_weave_reflink_rainbow $blksz $nr $file1 $file2 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+md5sum $file2 | _filter_scratch
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/1224.out b/tests/generic/1224.out
new file mode 100644
index 00000000..89e5cd5a
--- /dev/null
+++ b/tests/generic/1224.out
@@ -0,0 +1,16 @@
+QA output created by 1224
+atomic write shared data and unshared+shared data
+111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
+atomic write shared data and shared+unshared data
+111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
+atomic overwrite unshared data
+111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
+atomic write shared+unshared+shared data
+111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
+atomic write interweaved hole+unwritten+written+reflinked
+4edfbc469bed9965219ea80c9ae54626  SCRATCH_MNT/file1
+93243a293a9f568903485b0b2a895815  SCRATCH_MNT/file2
diff --git a/tests/generic/1225 b/tests/generic/1225
new file mode 100755
index 00000000..b940afd3
--- /dev/null
+++ b/tests/generic/1225
@@ -0,0 +1,127 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1225
+#
+# basic tests for large atomic writes with mixed mappings
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+. ./common/filter
+. ./common/reflink
+
+_require_scratch
+_require_atomic_write_test_commands
+_require_scratch_write_atomic_multi_fsblock
+
+_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
+_scratch_mount
+
+file1=$SCRATCH_MNT/file1
+file2=$SCRATCH_MNT/file2
+file3=$SCRATCH_MNT/file3
+
+touch $file1
+
+max_awu=$(_get_atomic_write_unit_max $file1)
+test $max_awu -ge 65536 || _notrun "test requires atomic writes up to 64k"
+
+min_awu=$(_get_atomic_write_unit_min $file1)
+test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
+
+bsize=$(_get_file_block_size $SCRATCH_MNT)
+test $max_awu -gt $((bsize * 2)) || \
+	_notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
+
+# non-reflink tests
+
+echo "atomic write hole+mapped+hole"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+echo "atomic write adjacent mapped+hole and hole+mapped"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+echo "atomic write mapped+hole+mapped"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+echo "atomic write unwritten+mapped+unwritten"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+echo "atomic write adjacent mapped+unwritten and unwritten+mapped"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+echo "atomic write mapped+unwritten+mapped"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+echo "atomic write interweaved hole+unwritten+written"
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+blksz=4096
+nr=32
+_weave_file_rainbow $blksz $nr $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+echo "atomic write at EOF"
+dd if=/dev/zero of=$file1 bs=32K count=12 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 360448 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+echo "atomic write preallocated region"
+fallocate -l 10M $file1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
+md5sum $file1 | _filter_scratch
+
+# atomic write max size
+dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
+aw_max=$(_get_atomic_write_unit_max $file1)
+cp $file1 $file1.chk
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
+$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
+cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
+
+echo "atomic write max size on fragmented fs"
+avail=`_get_available_space $SCRATCH_MNT`
+filesizemb=$((avail / 1024 / 1024 - 1))
+fragmentedfile=$SCRATCH_MNT/fragmentedfile
+$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
+$here/src/punch-alternating $fragmentedfile
+touch $file3
+$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
+md5sum $file3 | _filter_scratch
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/1225.out b/tests/generic/1225.out
new file mode 100644
index 00000000..c5a6de04
--- /dev/null
+++ b/tests/generic/1225.out
@@ -0,0 +1,21 @@
+QA output created by 1225
+atomic write hole+mapped+hole
+9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
+atomic write adjacent mapped+hole and hole+mapped
+9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
+atomic write mapped+hole+mapped
+9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
+atomic write unwritten+mapped+unwritten
+111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
+atomic write adjacent mapped+unwritten and unwritten+mapped
+111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
+atomic write mapped+unwritten+mapped
+111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
+atomic write interweaved hole+unwritten+written
+5577e46f20631d76bbac73ab1b4ed208  SCRATCH_MNT/file1
+atomic write at EOF
+0e44615ab08f3e8585a374fca9a6f5eb  SCRATCH_MNT/file1
+atomic write preallocated region
+3acf1ace00273bc4e2bf4a8d016611ea  SCRATCH_MNT/file1
+atomic write max size on fragmented fs
+27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v5 3/3] xfs: more multi-block atomic writes tests
  2025-06-16 21:52 [PATCH v5 0/3] atomic writes tests (part 2) Catherine Hoang
  2025-06-16 21:52 ` [PATCH v5 1/3] common/atomicwrites: add helper for multi block atomic writes Catherine Hoang
  2025-06-16 21:52 ` [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
@ 2025-06-16 21:52 ` Catherine Hoang
  2025-06-18 18:13   ` Zorro Lang
  2 siblings, 1 reply; 11+ messages in thread
From: Catherine Hoang @ 2025-06-16 21:52 UTC (permalink / raw)
  To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list, ojaswin

From: "Darrick J. Wong" <djwong@kernel.org>

Add xfs specific tests for realtime volumes and error recovery.

The first test validates multi-block atomic writes on a realtime file. We
perform basic atomic writes operations within the advertised sizes and ensure
that atomic writes will fail outside of these bounds. The hardware used in this
test is not required to support atomic writes.

The second test verifies that a large atomic write can complete after a crash.
The error is injected while attempting to free an extent. We ensure that this
error occurs by first creating a heavily fragmented filesystem. After recovery,
we check that the write completes successfully.

The third test verifies that a large atomic write on a reflinked file can
complete after a crash. We start with two files that share the same data and
inject an error while attempting to perform a write on one of the files. After
recovery, we verify that these files now contain different data, indicating
that the write has succeeded.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
---
 tests/xfs/1216     | 68 ++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/1216.out |  9 ++++++
 tests/xfs/1217     | 71 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/xfs/1217.out |  3 ++
 tests/xfs/1218     | 60 +++++++++++++++++++++++++++++++++++++++
 tests/xfs/1218.out | 15 ++++++++++
 6 files changed, 226 insertions(+)
 create mode 100755 tests/xfs/1216
 create mode 100644 tests/xfs/1216.out
 create mode 100755 tests/xfs/1217
 create mode 100644 tests/xfs/1217.out
 create mode 100755 tests/xfs/1218
 create mode 100644 tests/xfs/1218.out

diff --git a/tests/xfs/1216 b/tests/xfs/1216
new file mode 100755
index 00000000..694e3a98
--- /dev/null
+++ b/tests/xfs/1216
@@ -0,0 +1,68 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1216
+#
+# Validate multi-fsblock realtime file atomic write support with or without hw
+# support
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+
+_require_realtime
+_require_scratch
+_require_atomic_write_test_commands
+_require_scratch_write_atomic_multi_fsblock
+
+echo "scratch device atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+
+testfile=$SCRATCH_MNT/testfile
+touch $testfile
+
+echo "filesystem atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
+
+sector_size=$(blockdev --getss $SCRATCH_RTDEV)
+min_awu=$(_get_atomic_write_unit_min $testfile)
+max_awu=$(_get_atomic_write_unit_max $testfile)
+
+$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+
+# try outside the advertised sizes
+echo "two EINVAL for unsupported sizes"
+min_i=$((min_awu / 2))
+_simple_atomic_write $min_i $min_i $testfile -d
+max_i=$((max_awu * 2))
+_simple_atomic_write $max_i $max_i $testfile -d
+
+# try all of the advertised sizes
+for ((i = min_awu; i <= max_awu; i *= 2)); do
+	$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
+	_test_atomic_file_writes $i $testfile
+	_simple_atomic_write $i $i $testfile -d
+done
+
+# does not support buffered io
+echo "one EOPNOTSUPP for buffered atomic"
+_simple_atomic_write 0 $min_awu $testfile
+
+# does not support unaligned directio
+echo "one EINVAL for unaligned directio"
+if [ $sector_size -lt $min_awu ]; then
+	_simple_atomic_write $sector_size $min_awu $testfile -d
+else
+	# not supported, so fake the output
+	echo "pwrite: Invalid argument"
+fi
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/xfs/1216.out b/tests/xfs/1216.out
new file mode 100644
index 00000000..51546082
--- /dev/null
+++ b/tests/xfs/1216.out
@@ -0,0 +1,9 @@
+QA output created by 1216
+two EINVAL for unsupported sizes
+pwrite: Invalid argument
+pwrite: Invalid argument
+one EOPNOTSUPP for buffered atomic
+pwrite: Operation not supported
+one EINVAL for unaligned directio
+pwrite: Invalid argument
+Silence is golden
diff --git a/tests/xfs/1217 b/tests/xfs/1217
new file mode 100755
index 00000000..f3f59ae4
--- /dev/null
+++ b/tests/xfs/1217
@@ -0,0 +1,71 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1217
+#
+# Check that software atomic writes can complete an operation after a crash.
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+. ./common/inject
+. ./common/filter
+
+_require_scratch
+_require_atomic_write_test_commands
+_require_scratch_write_atomic_multi_fsblock
+_require_xfs_io_error_injection "free_extent"
+_require_test_program "punch-alternating"
+
+echo "scratch device atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
+
+_scratch_mkfs >> $seqres.full
+_scratch_mount
+
+testfile=$SCRATCH_MNT/testfile
+touch $testfile
+
+echo "filesystem atomic write properties" >> $seqres.full
+$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
+
+bsize=$(_get_file_block_size $SCRATCH_MNT)
+max_awu=$(_get_atomic_write_unit_max $testfile)
+
+test $max_awu -gt $((bsize * 2)) || \
+	_notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
+
+# Create a fragmented file to force a software fallback
+$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((max_awu * 2))" $testfile >> $seqres.full
+$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((max_awu * 2))" $testfile.check >> $seqres.full
+$here/src/punch-alternating $testfile
+$here/src/punch-alternating $testfile.check
+$XFS_IO_PROG -c "pwrite -S 0xcd 0 $max_awu" $testfile.check >> $seqres.full
+$XFS_IO_PROG -c syncfs $SCRATCH_MNT
+
+# inject an error to force crash recovery on the second block
+_scratch_inject_error "free_extent"
+_simple_atomic_write 0 $max_awu $testfile -d >> $seqres.full
+
+# make sure we're shut down
+touch $SCRATCH_MNT/barf 2>&1 | _filter_scratch
+
+# check that recovery worked
+_scratch_cycle_mount
+
+test -e $SCRATCH_MNT/barf && \
+	echo "saw $SCRATCH_MNT/barf that should not exist"
+
+if ! cmp -s $testfile $testfile.check; then
+	echo "crash recovery did not work"
+	md5sum $testfile
+	md5sum $testfile.check
+
+	od -tx1 -Ad -c $testfile >> $seqres.full
+	od -tx1 -Ad -c $testfile.check >> $seqres.full
+fi
+
+status=0
+exit
diff --git a/tests/xfs/1217.out b/tests/xfs/1217.out
new file mode 100644
index 00000000..6e5b22be
--- /dev/null
+++ b/tests/xfs/1217.out
@@ -0,0 +1,3 @@
+QA output created by 1217
+pwrite: Input/output error
+touch: cannot touch 'SCRATCH_MNT/barf': Input/output error
diff --git a/tests/xfs/1218 b/tests/xfs/1218
new file mode 100755
index 00000000..799519b1
--- /dev/null
+++ b/tests/xfs/1218
@@ -0,0 +1,60 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle.  All Rights Reserved.
+#
+# FS QA Test 1218
+#
+# hardware large atomic writes error inject test
+#
+. ./common/preamble
+_begin_fstest auto rw quick atomicwrites
+
+. ./common/filter
+. ./common/inject
+. ./common/atomicwrites
+
+_require_scratch_write_atomic
+_require_scratch_write_atomic_multi_fsblock
+_require_xfs_io_command pwrite -A
+_require_xfs_io_error_injection "bmap_finish_one"
+
+_scratch_mkfs >> $seqres.full 2>&1
+_scratch_mount
+
+echo "Create files"
+file1=$SCRATCH_MNT/file1
+touch $file1
+
+max_awu=$(_get_atomic_write_unit_max $file1)
+test $max_awu -ge 4096 || _notrun "cannot perform 4k atomic writes"
+
+file2=$SCRATCH_MNT/file2
+_pwrite_byte 0x66 0 64k $SCRATCH_MNT/file1 >> $seqres.full
+cp --reflink=always $file1 $file2
+
+echo "Check files"
+md5sum $SCRATCH_MNT/file1 | _filter_scratch
+md5sum $SCRATCH_MNT/file2 | _filter_scratch
+
+echo "Inject error"
+_scratch_inject_error "bmap_finish_one"
+
+echo "Atomic write to a reflinked file"
+$XFS_IO_PROG -dc "pwrite -A -D -V1 -S 0x67 0 4096" $file1
+
+echo "FS should be shut down, touch will fail"
+touch $SCRATCH_MNT/badfs 2>&1 | _filter_scratch
+
+echo "Remount to replay log"
+_scratch_remount_dump_log >> $seqres.full
+
+echo "Check files"
+md5sum $SCRATCH_MNT/file1 | _filter_scratch
+md5sum $SCRATCH_MNT/file2 | _filter_scratch
+
+echo "FS should be online, touch should succeed"
+touch $SCRATCH_MNT/goodfs 2>&1 | _filter_scratch
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1218.out b/tests/xfs/1218.out
new file mode 100644
index 00000000..02800213
--- /dev/null
+++ b/tests/xfs/1218.out
@@ -0,0 +1,15 @@
+QA output created by 1218
+Create files
+Check files
+77e3a730e3c75274c9ce310d7e39f938  SCRATCH_MNT/file1
+77e3a730e3c75274c9ce310d7e39f938  SCRATCH_MNT/file2
+Inject error
+Atomic write to a reflinked file
+pwrite: Input/output error
+FS should be shut down, touch will fail
+touch: cannot touch 'SCRATCH_MNT/badfs': Input/output error
+Remount to replay log
+Check files
+0df1f61ed02a7e9bee2b8b7665066ddc  SCRATCH_MNT/file1
+77e3a730e3c75274c9ce310d7e39f938  SCRATCH_MNT/file2
+FS should be online, touch should succeed
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-16 21:52 ` [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
@ 2025-06-17 10:18   ` John Garry
  2025-06-18  9:25   ` Ojaswin Mujoo
  2025-06-18 18:09   ` Zorro Lang
  2 siblings, 0 replies; 11+ messages in thread
From: John Garry @ 2025-06-17 10:18 UTC (permalink / raw)
  To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, ritesh.list, ojaswin

On 16/06/2025 22:52, Catherine Hoang wrote:
> From: "Darrick J. Wong"<djwong@kernel.org>
> 
> Simple tests of various atomic write requests and a (simulated) hardware
> device.
> 
> The first test performs basic multi-block atomic writes on a scsi_debug device
> with atomic writes enabled. We test all advertised sizes between the atomic
> write unit min and max. We also ensure that the write fails when expected, such
> as when attempting buffered io or unaligned directio.
> 
> The second test is similar to the one above, except that it verifies multi-block
> atomic writes on actual hardware instead of simulated hardware. The device used
> in this test is not required to support atomic writes.
> 
> The final two tests ensure multi-block atomic writes can be performed on various
> interweaved mappings, including written, mapped, hole, and unwritten. We also
> test large atomic writes on a heavily fragmented filesystem. These tests are
> separated into reflink (shared) and non-reflink tests.
> 
> Signed-off-by: "Darrick J. Wong"<djwong@kernel.org>
> Signed-off-by: Catherine Hoang<catherine.hoang@oracle.com>
> ---

Nice

Reviewed-by: John Garry <john.g.garry@oracle.com>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-16 21:52 ` [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
  2025-06-17 10:18   ` John Garry
@ 2025-06-18  9:25   ` Ojaswin Mujoo
  2025-06-18 18:09   ` Zorro Lang
  2 siblings, 0 replies; 11+ messages in thread
From: Ojaswin Mujoo @ 2025-06-18  9:25 UTC (permalink / raw)
  To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list

On Mon, Jun 16, 2025 at 02:52:12PM -0700, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
> 
> Simple tests of various atomic write requests and a (simulated) hardware
> device.
> 
> The first test performs basic multi-block atomic writes on a scsi_debug device
> with atomic writes enabled. We test all advertised sizes between the atomic
> write unit min and max. We also ensure that the write fails when expected, such
> as when attempting buffered io or unaligned directio.
> 
> The second test is similar to the one above, except that it verifies multi-block
> atomic writes on actual hardware instead of simulated hardware. The device used
> in this test is not required to support atomic writes.
> 
> The final two tests ensure multi-block atomic writes can be performed on various
> interweaved mappings, including written, mapped, hole, and unwritten. We also
> test large atomic writes on a heavily fragmented filesystem. These tests are
> separated into reflink (shared) and non-reflink tests.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>

Looks good now, feel free to add:
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>

Regards,
ojaswin


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-16 21:52 ` [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
  2025-06-17 10:18   ` John Garry
  2025-06-18  9:25   ` Ojaswin Mujoo
@ 2025-06-18 18:09   ` Zorro Lang
  2025-06-20 23:02     ` Catherine Hoang
  2 siblings, 1 reply; 11+ messages in thread
From: Zorro Lang @ 2025-06-18 18:09 UTC (permalink / raw)
  To: Catherine Hoang
  Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list, ojaswin

On Mon, Jun 16, 2025 at 02:52:12PM -0700, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
> 
> Simple tests of various atomic write requests and a (simulated) hardware
> device.
> 
> The first test performs basic multi-block atomic writes on a scsi_debug device
> with atomic writes enabled. We test all advertised sizes between the atomic
> write unit min and max. We also ensure that the write fails when expected, such
> as when attempting buffered io or unaligned directio.
> 
> The second test is similar to the one above, except that it verifies multi-block
> atomic writes on actual hardware instead of simulated hardware. The device used
> in this test is not required to support atomic writes.
> 
> The final two tests ensure multi-block atomic writes can be performed on various
> interweaved mappings, including written, mapped, hole, and unwritten. We also
> test large atomic writes on a heavily fragmented filesystem. These tests are
> separated into reflink (shared) and non-reflink tests.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> ---
>  common/atomicwrites    |  10 ++++
>  tests/generic/1222     |  88 ++++++++++++++++++++++++++++
>  tests/generic/1222.out |  10 ++++
>  tests/generic/1223     |  66 +++++++++++++++++++++
>  tests/generic/1223.out |   9 +++
>  tests/generic/1224     |  86 ++++++++++++++++++++++++++++
>  tests/generic/1224.out |  16 ++++++
>  tests/generic/1225     | 127 +++++++++++++++++++++++++++++++++++++++++
>  tests/generic/1225.out |  21 +++++++
>  9 files changed, 433 insertions(+)
>  create mode 100755 tests/generic/1222
>  create mode 100644 tests/generic/1222.out
>  create mode 100755 tests/generic/1223
>  create mode 100644 tests/generic/1223.out
>  create mode 100755 tests/generic/1224
>  create mode 100644 tests/generic/1224.out
>  create mode 100755 tests/generic/1225
>  create mode 100644 tests/generic/1225.out
> 
> diff --git a/common/atomicwrites b/common/atomicwrites
> index ac4facc3..95d545a6 100644
> --- a/common/atomicwrites
> +++ b/common/atomicwrites
> @@ -136,3 +136,13 @@ _test_atomic_file_writes()
>      $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
>          echo "atomic write requires offset to be aligned to bsize"
>  }
> +
> +_simple_atomic_write() {
> +	local pos=$1
> +	local count=$2
> +	local file=$3
> +	local directio=$4
> +
> +	echo "testing pos=$pos count=$count file=$file directio=$directio" >> $seqres.full
> +	$XFS_IO_PROG $directio -c "pwrite -b $count -V 1 -A -D $pos $count" $file >> $seqres.full
> +}
> diff --git a/tests/generic/1222 b/tests/generic/1222
> new file mode 100755
> index 00000000..c718b244
> --- /dev/null
> +++ b/tests/generic/1222
> @@ -0,0 +1,88 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> +#
> +# FS QA Test 1222
> +#
> +# Validate multi-fsblock atomic write support with simulated hardware support
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/scsi_debug
> +. ./common/atomicwrites
> +
> +_cleanup()
> +{
> +	_scratch_unmount &>/dev/null
> +	_put_scsi_debug_dev &>/dev/null
> +	cd /
> +	rm -r -f $tmp.*
> +}
> +
> +_require_scsi_debug
> +_require_scratch_nocheck
> +# Format something so that ./check doesn't freak out
> +_scratch_mkfs >> $seqres.full
> +
> +# 512b logical/physical sectors, 512M size, atomic writes enabled
> +dev=$(_get_scsi_debug_dev 512 512 0 512 "atomic_wr=1")
> +test -b "$dev" || _notrun "could not create atomic writes scsi_debug device"
> +
> +export SCRATCH_DEV=$dev

These's a generic test case. As you use scsi_debug device. I'm wondering do we
need _require_block_device? Can this case works with FSTYP=nfs, cifs, tmpfs, overlayfs
and so on?

> +unset USE_EXTERNAL
> +
> +_require_scratch_write_atomic
> +_require_scratch_write_atomic_multi_fsblock
> +
> +xfs_io -c 'help pwrite' | grep -q RWF_ATOMIC || _notrun "xfs_io pwrite -A failed"
> +xfs_io -c 'help falloc' | grep -q 'not found' && _notrun "xfs_io falloc failed"

Can't these two lines be replaced by _require_xfs_io? e.g.
_require_xfs_io_command pwrite -A
_require_xfs_io_command falloc

> +
> +echo "scsi_debug atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full

_require_xfs_io_command statx -r ?

> +
> +_scratch_mkfs >> $seqres.full
> +_scratch_mount
> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
> +
> +testfile=$SCRATCH_MNT/testfile
> +touch $testfile
> +
> +echo "filesystem atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> +
> +sector_size=$(blockdev --getss $SCRATCH_DEV)
> +min_awu=$(_get_atomic_write_unit_min $testfile)
> +max_awu=$(_get_atomic_write_unit_max $testfile)
> +
> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +
> +# try outside the advertised sizes
> +echo "two EINVAL for unsupported sizes"
> +min_i=$((min_awu / 2))
> +_simple_atomic_write $min_i $min_i $testfile -d
> +max_i=$((max_awu * 2))
> +_simple_atomic_write $max_i $max_i $testfile -d
> +
> +# try all of the advertised sizes
> +echo "all should work"
> +for ((i = min_awu; i <= max_awu; i *= 2)); do
> +	$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +	_test_atomic_file_writes $i $testfile
> +done
> +
> +# does not support buffered io
> +echo "one EOPNOTSUPP for buffered atomic"
> +_simple_atomic_write 0 $min_awu $testfile
> +
> +# does not support unaligned directio
> +echo "one EINVAL for unaligned directio"
> +_simple_atomic_write $sector_size $min_awu $testfile -d
> +
> +_scratch_unmount
> +_put_scsi_debug_dev
> +
> +# success, all done
> +echo Silence is golden
> +status=0
> +exit
> diff --git a/tests/generic/1222.out b/tests/generic/1222.out
> new file mode 100644
> index 00000000..158b52fa
> --- /dev/null
> +++ b/tests/generic/1222.out
> @@ -0,0 +1,10 @@
> +QA output created by 1222
> +two EINVAL for unsupported sizes
> +pwrite: Invalid argument
> +pwrite: Invalid argument
> +all should work
> +one EOPNOTSUPP for buffered atomic
> +pwrite: Operation not supported
> +one EINVAL for unaligned directio
> +pwrite: Invalid argument
> +Silence is golden
> diff --git a/tests/generic/1223 b/tests/generic/1223
> new file mode 100755
> index 00000000..db242e7f
> --- /dev/null
> +++ b/tests/generic/1223
> @@ -0,0 +1,66 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> +#
> +# FS QA Test 1223
> +#
> +# Validate multi-fsblock atomic write support with or without hw support
> +#

Same review points with above case.

> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +_require_scratch_write_atomic_multi_fsblock
> +
> +echo "scratch device atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
> +
> +_scratch_mkfs >> $seqres.full
> +_scratch_mount
> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
> +
> +testfile=$SCRATCH_MNT/testfile
> +touch $testfile
> +
> +echo "filesystem atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> +
> +sector_size=$(blockdev --getss $SCRATCH_DEV)
> +min_awu=$(_get_atomic_write_unit_min $testfile)
> +max_awu=$(_get_atomic_write_unit_max $testfile)
> +
> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +
> +# try outside the advertised sizes
> +echo "two EINVAL for unsupported sizes"
> +min_i=$((min_awu / 2))
> +_simple_atomic_write $min_i $min_i $testfile -d
> +max_i=$((max_awu * 2))
> +_simple_atomic_write $max_i $max_i $testfile -d
> +
> +# try all of the advertised sizes
> +for ((i = min_awu; i <= max_awu; i *= 2)); do
> +	$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +	_test_atomic_file_writes $i $testfile
> +done
> +
> +# does not support buffered io
> +echo "one EOPNOTSUPP for buffered atomic"
> +_simple_atomic_write 0 $min_awu $testfile
> +
> +# does not support unaligned directio
> +echo "one EINVAL for unaligned directio"
> +if [ $sector_size -lt $min_awu ]; then
> +	_simple_atomic_write $sector_size $min_awu $testfile -d
> +else
> +	# not supported, so fake the output
> +	echo "pwrite: Invalid argument"
> +fi
> +
> +# success, all done
> +echo Silence is golden
> +status=0
> +exit
> diff --git a/tests/generic/1223.out b/tests/generic/1223.out
> new file mode 100644
> index 00000000..edf5bd71
> --- /dev/null
> +++ b/tests/generic/1223.out
> @@ -0,0 +1,9 @@
> +QA output created by 1223
> +two EINVAL for unsupported sizes
> +pwrite: Invalid argument
> +pwrite: Invalid argument
> +one EOPNOTSUPP for buffered atomic
> +pwrite: Operation not supported
> +one EINVAL for unaligned directio
> +pwrite: Invalid argument
> +Silence is golden
> diff --git a/tests/generic/1224 b/tests/generic/1224
> new file mode 100755
> index 00000000..3f83eebc
> --- /dev/null
> +++ b/tests/generic/1224
> @@ -0,0 +1,86 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> +#
> +# FS QA Test 1224
> +#
> +# reflink tests for large atomic writes with mixed mappings
> +#

Same review points as above case.

> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +. ./common/filter
> +. ./common/reflink
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +_require_scratch_write_atomic_multi_fsblock
> +_require_xfs_io_command pwrite -A
> +_require_cp_reflink

Do you just need _require_cp_reflink, or need _require_scratch_reflink too?

Thanks,
Zorro

> +
> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
> +_scratch_mount
> +
> +file1=$SCRATCH_MNT/file1
> +file2=$SCRATCH_MNT/file2
> +file3=$SCRATCH_MNT/file3
> +
> +touch $file1
> +
> +max_awu=$(_get_atomic_write_unit_max $file1)
> +test $max_awu -ge 262144 || _notrun "test requires atomic writes up to 256k"
> +
> +min_awu=$(_get_atomic_write_unit_min $file1)
> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
> +
> +bsize=$(_get_file_block_size $SCRATCH_MNT)
> +test $max_awu -gt $((bsize * 2)) || \
> +	_notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
> +
> +# reflink tests (files with shared extents)
> +
> +echo "atomic write shared data and unshared+shared data"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +cp --reflink=always $file1 $file2
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +echo "atomic write shared data and shared+unshared data"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +cp --reflink=always $file1 $file2
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +echo "atomic overwrite unshared data"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +cp --reflink=always $file1 $file2
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +echo "atomic write shared+unshared+shared data"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +cp --reflink=always $file1 $file2
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +echo "atomic write interweaved hole+unwritten+written+reflinked"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +blksz=4096
> +nr=32
> +_weave_reflink_rainbow $blksz $nr $file1 $file2 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +md5sum $file2 | _filter_scratch
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/1224.out b/tests/generic/1224.out
> new file mode 100644
> index 00000000..89e5cd5a
> --- /dev/null
> +++ b/tests/generic/1224.out
> @@ -0,0 +1,16 @@
> +QA output created by 1224
> +atomic write shared data and unshared+shared data
> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
> +atomic write shared data and shared+unshared data
> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
> +atomic overwrite unshared data
> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
> +atomic write shared+unshared+shared data
> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
> +atomic write interweaved hole+unwritten+written+reflinked
> +4edfbc469bed9965219ea80c9ae54626  SCRATCH_MNT/file1
> +93243a293a9f568903485b0b2a895815  SCRATCH_MNT/file2
> diff --git a/tests/generic/1225 b/tests/generic/1225
> new file mode 100755
> index 00000000..b940afd3
> --- /dev/null
> +++ b/tests/generic/1225
> @@ -0,0 +1,127 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> +#
> +# FS QA Test 1225
> +#
> +# basic tests for large atomic writes with mixed mappings
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +. ./common/filter
> +. ./common/reflink
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +_require_scratch_write_atomic_multi_fsblock
> +
> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
> +_scratch_mount
> +
> +file1=$SCRATCH_MNT/file1
> +file2=$SCRATCH_MNT/file2
> +file3=$SCRATCH_MNT/file3
> +
> +touch $file1
> +
> +max_awu=$(_get_atomic_write_unit_max $file1)
> +test $max_awu -ge 65536 || _notrun "test requires atomic writes up to 64k"
> +
> +min_awu=$(_get_atomic_write_unit_min $file1)
> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
> +
> +bsize=$(_get_file_block_size $SCRATCH_MNT)
> +test $max_awu -gt $((bsize * 2)) || \
> +	_notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
> +
> +# non-reflink tests
> +
> +echo "atomic write hole+mapped+hole"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +echo "atomic write adjacent mapped+hole and hole+mapped"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +echo "atomic write mapped+hole+mapped"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +echo "atomic write unwritten+mapped+unwritten"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +echo "atomic write adjacent mapped+unwritten and unwritten+mapped"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +echo "atomic write mapped+unwritten+mapped"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +echo "atomic write interweaved hole+unwritten+written"
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +blksz=4096
> +nr=32
> +_weave_file_rainbow $blksz $nr $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +echo "atomic write at EOF"
> +dd if=/dev/zero of=$file1 bs=32K count=12 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 360448 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +echo "atomic write preallocated region"
> +fallocate -l 10M $file1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> +md5sum $file1 | _filter_scratch
> +
> +# atomic write max size
> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> +aw_max=$(_get_atomic_write_unit_max $file1)
> +cp $file1 $file1.chk
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
> +$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
> +cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
> +
> +echo "atomic write max size on fragmented fs"
> +avail=`_get_available_space $SCRATCH_MNT`
> +filesizemb=$((avail / 1024 / 1024 - 1))
> +fragmentedfile=$SCRATCH_MNT/fragmentedfile
> +$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
> +$here/src/punch-alternating $fragmentedfile
> +touch $file3
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
> +md5sum $file3 | _filter_scratch
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/1225.out b/tests/generic/1225.out
> new file mode 100644
> index 00000000..c5a6de04
> --- /dev/null
> +++ b/tests/generic/1225.out
> @@ -0,0 +1,21 @@
> +QA output created by 1225
> +atomic write hole+mapped+hole
> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
> +atomic write adjacent mapped+hole and hole+mapped
> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
> +atomic write mapped+hole+mapped
> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
> +atomic write unwritten+mapped+unwritten
> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> +atomic write adjacent mapped+unwritten and unwritten+mapped
> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> +atomic write mapped+unwritten+mapped
> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> +atomic write interweaved hole+unwritten+written
> +5577e46f20631d76bbac73ab1b4ed208  SCRATCH_MNT/file1
> +atomic write at EOF
> +0e44615ab08f3e8585a374fca9a6f5eb  SCRATCH_MNT/file1
> +atomic write preallocated region
> +3acf1ace00273bc4e2bf4a8d016611ea  SCRATCH_MNT/file1
> +atomic write max size on fragmented fs
> +27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
> -- 
> 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 3/3] xfs: more multi-block atomic writes tests
  2025-06-16 21:52 ` [PATCH v5 3/3] xfs: more multi-block atomic writes tests Catherine Hoang
@ 2025-06-18 18:13   ` Zorro Lang
  0 siblings, 0 replies; 11+ messages in thread
From: Zorro Lang @ 2025-06-18 18:13 UTC (permalink / raw)
  To: Catherine Hoang
  Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list, ojaswin

On Mon, Jun 16, 2025 at 02:52:13PM -0700, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
> 
> Add xfs specific tests for realtime volumes and error recovery.
> 
> The first test validates multi-block atomic writes on a realtime file. We
> perform basic atomic writes operations within the advertised sizes and ensure
> that atomic writes will fail outside of these bounds. The hardware used in this
> test is not required to support atomic writes.
> 
> The second test verifies that a large atomic write can complete after a crash.
> The error is injected while attempting to free an extent. We ensure that this
> error occurs by first creating a heavily fragmented filesystem. After recovery,
> we check that the write completes successfully.
> 
> The third test verifies that a large atomic write on a reflinked file can
> complete after a crash. We start with two files that share the same data and
> inject an error while attempting to perform a write on one of the files. After
> recovery, we verify that these files now contain different data, indicating
> that the write has succeeded.
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> Reviewed-by: John Garry <john.g.garry@oracle.com>
> ---

Similar review points as patch 2/3, but as cases in this patch are xfs only, so
_require_block_device might not be necessary.

Thanks,
Zorro

>  tests/xfs/1216     | 68 ++++++++++++++++++++++++++++++++++++++++++++
>  tests/xfs/1216.out |  9 ++++++
>  tests/xfs/1217     | 71 ++++++++++++++++++++++++++++++++++++++++++++++
>  tests/xfs/1217.out |  3 ++
>  tests/xfs/1218     | 60 +++++++++++++++++++++++++++++++++++++++
>  tests/xfs/1218.out | 15 ++++++++++
>  6 files changed, 226 insertions(+)
>  create mode 100755 tests/xfs/1216
>  create mode 100644 tests/xfs/1216.out
>  create mode 100755 tests/xfs/1217
>  create mode 100644 tests/xfs/1217.out
>  create mode 100755 tests/xfs/1218
>  create mode 100644 tests/xfs/1218.out
> 
> diff --git a/tests/xfs/1216 b/tests/xfs/1216
> new file mode 100755
> index 00000000..694e3a98
> --- /dev/null
> +++ b/tests/xfs/1216
> @@ -0,0 +1,68 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> +#
> +# FS QA Test 1216
> +#
> +# Validate multi-fsblock realtime file atomic write support with or without hw
> +# support
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +
> +_require_realtime
> +_require_scratch
> +_require_atomic_write_test_commands
> +_require_scratch_write_atomic_multi_fsblock
> +
> +echo "scratch device atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
> +
> +_scratch_mkfs >> $seqres.full
> +_scratch_mount
> +
> +testfile=$SCRATCH_MNT/testfile
> +touch $testfile
> +
> +echo "filesystem atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> +
> +sector_size=$(blockdev --getss $SCRATCH_RTDEV)
> +min_awu=$(_get_atomic_write_unit_min $testfile)
> +max_awu=$(_get_atomic_write_unit_max $testfile)
> +
> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +
> +# try outside the advertised sizes
> +echo "two EINVAL for unsupported sizes"
> +min_i=$((min_awu / 2))
> +_simple_atomic_write $min_i $min_i $testfile -d
> +max_i=$((max_awu * 2))
> +_simple_atomic_write $max_i $max_i $testfile -d
> +
> +# try all of the advertised sizes
> +for ((i = min_awu; i <= max_awu; i *= 2)); do
> +	$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> +	_test_atomic_file_writes $i $testfile
> +	_simple_atomic_write $i $i $testfile -d
> +done
> +
> +# does not support buffered io
> +echo "one EOPNOTSUPP for buffered atomic"
> +_simple_atomic_write 0 $min_awu $testfile
> +
> +# does not support unaligned directio
> +echo "one EINVAL for unaligned directio"
> +if [ $sector_size -lt $min_awu ]; then
> +	_simple_atomic_write $sector_size $min_awu $testfile -d
> +else
> +	# not supported, so fake the output
> +	echo "pwrite: Invalid argument"
> +fi
> +
> +# success, all done
> +echo Silence is golden
> +status=0
> +exit
> diff --git a/tests/xfs/1216.out b/tests/xfs/1216.out
> new file mode 100644
> index 00000000..51546082
> --- /dev/null
> +++ b/tests/xfs/1216.out
> @@ -0,0 +1,9 @@
> +QA output created by 1216
> +two EINVAL for unsupported sizes
> +pwrite: Invalid argument
> +pwrite: Invalid argument
> +one EOPNOTSUPP for buffered atomic
> +pwrite: Operation not supported
> +one EINVAL for unaligned directio
> +pwrite: Invalid argument
> +Silence is golden
> diff --git a/tests/xfs/1217 b/tests/xfs/1217
> new file mode 100755
> index 00000000..f3f59ae4
> --- /dev/null
> +++ b/tests/xfs/1217
> @@ -0,0 +1,71 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> +#
> +# FS QA Test 1217
> +#
> +# Check that software atomic writes can complete an operation after a crash.
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +. ./common/inject
> +. ./common/filter
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +_require_scratch_write_atomic_multi_fsblock
> +_require_xfs_io_error_injection "free_extent"
> +_require_test_program "punch-alternating"
> +
> +echo "scratch device atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_RTDEV >> $seqres.full
> +
> +_scratch_mkfs >> $seqres.full
> +_scratch_mount
> +
> +testfile=$SCRATCH_MNT/testfile
> +touch $testfile
> +
> +echo "filesystem atomic write properties" >> $seqres.full
> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> +
> +bsize=$(_get_file_block_size $SCRATCH_MNT)
> +max_awu=$(_get_atomic_write_unit_max $testfile)
> +
> +test $max_awu -gt $((bsize * 2)) || \
> +	_notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
> +
> +# Create a fragmented file to force a software fallback
> +$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((max_awu * 2))" $testfile >> $seqres.full
> +$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((max_awu * 2))" $testfile.check >> $seqres.full
> +$here/src/punch-alternating $testfile
> +$here/src/punch-alternating $testfile.check
> +$XFS_IO_PROG -c "pwrite -S 0xcd 0 $max_awu" $testfile.check >> $seqres.full
> +$XFS_IO_PROG -c syncfs $SCRATCH_MNT
> +
> +# inject an error to force crash recovery on the second block
> +_scratch_inject_error "free_extent"
> +_simple_atomic_write 0 $max_awu $testfile -d >> $seqres.full
> +
> +# make sure we're shut down
> +touch $SCRATCH_MNT/barf 2>&1 | _filter_scratch
> +
> +# check that recovery worked
> +_scratch_cycle_mount
> +
> +test -e $SCRATCH_MNT/barf && \
> +	echo "saw $SCRATCH_MNT/barf that should not exist"
> +
> +if ! cmp -s $testfile $testfile.check; then
> +	echo "crash recovery did not work"
> +	md5sum $testfile
> +	md5sum $testfile.check
> +
> +	od -tx1 -Ad -c $testfile >> $seqres.full
> +	od -tx1 -Ad -c $testfile.check >> $seqres.full
> +fi
> +
> +status=0
> +exit
> diff --git a/tests/xfs/1217.out b/tests/xfs/1217.out
> new file mode 100644
> index 00000000..6e5b22be
> --- /dev/null
> +++ b/tests/xfs/1217.out
> @@ -0,0 +1,3 @@
> +QA output created by 1217
> +pwrite: Input/output error
> +touch: cannot touch 'SCRATCH_MNT/barf': Input/output error
> diff --git a/tests/xfs/1218 b/tests/xfs/1218
> new file mode 100755
> index 00000000..799519b1
> --- /dev/null
> +++ b/tests/xfs/1218
> @@ -0,0 +1,60 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> +#
> +# FS QA Test 1218
> +#
> +# hardware large atomic writes error inject test
> +#
> +. ./common/preamble
> +_begin_fstest auto rw quick atomicwrites
> +
> +. ./common/filter
> +. ./common/inject
> +. ./common/atomicwrites
> +
> +_require_scratch_write_atomic
> +_require_scratch_write_atomic_multi_fsblock
> +_require_xfs_io_command pwrite -A
> +_require_xfs_io_error_injection "bmap_finish_one"
> +
> +_scratch_mkfs >> $seqres.full 2>&1
> +_scratch_mount
> +
> +echo "Create files"
> +file1=$SCRATCH_MNT/file1
> +touch $file1
> +
> +max_awu=$(_get_atomic_write_unit_max $file1)
> +test $max_awu -ge 4096 || _notrun "cannot perform 4k atomic writes"
> +
> +file2=$SCRATCH_MNT/file2
> +_pwrite_byte 0x66 0 64k $SCRATCH_MNT/file1 >> $seqres.full
> +cp --reflink=always $file1 $file2
> +
> +echo "Check files"
> +md5sum $SCRATCH_MNT/file1 | _filter_scratch
> +md5sum $SCRATCH_MNT/file2 | _filter_scratch
> +
> +echo "Inject error"
> +_scratch_inject_error "bmap_finish_one"
> +
> +echo "Atomic write to a reflinked file"
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 -S 0x67 0 4096" $file1
> +
> +echo "FS should be shut down, touch will fail"
> +touch $SCRATCH_MNT/badfs 2>&1 | _filter_scratch
> +
> +echo "Remount to replay log"
> +_scratch_remount_dump_log >> $seqres.full
> +
> +echo "Check files"
> +md5sum $SCRATCH_MNT/file1 | _filter_scratch
> +md5sum $SCRATCH_MNT/file2 | _filter_scratch
> +
> +echo "FS should be online, touch should succeed"
> +touch $SCRATCH_MNT/goodfs 2>&1 | _filter_scratch
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/xfs/1218.out b/tests/xfs/1218.out
> new file mode 100644
> index 00000000..02800213
> --- /dev/null
> +++ b/tests/xfs/1218.out
> @@ -0,0 +1,15 @@
> +QA output created by 1218
> +Create files
> +Check files
> +77e3a730e3c75274c9ce310d7e39f938  SCRATCH_MNT/file1
> +77e3a730e3c75274c9ce310d7e39f938  SCRATCH_MNT/file2
> +Inject error
> +Atomic write to a reflinked file
> +pwrite: Input/output error
> +FS should be shut down, touch will fail
> +touch: cannot touch 'SCRATCH_MNT/badfs': Input/output error
> +Remount to replay log
> +Check files
> +0df1f61ed02a7e9bee2b8b7665066ddc  SCRATCH_MNT/file1
> +77e3a730e3c75274c9ce310d7e39f938  SCRATCH_MNT/file2
> +FS should be online, touch should succeed
> -- 
> 2.34.1
> 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-18 18:09   ` Zorro Lang
@ 2025-06-20 23:02     ` Catherine Hoang
  2025-06-21 12:20       ` Zorro Lang
  0 siblings, 1 reply; 11+ messages in thread
From: Catherine Hoang @ 2025-06-20 23:02 UTC (permalink / raw)
  To: Zorro Lang
  Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org,
	djwong@kernel.org, John Garry, ritesh.list@gmail.com,
	ojaswin@linux.ibm.com


> On Jun 18, 2025, at 11:09 AM, Zorro Lang <zlang@redhat.com> wrote:
> 
> On Mon, Jun 16, 2025 at 02:52:12PM -0700, Catherine Hoang wrote:
>> From: "Darrick J. Wong" <djwong@kernel.org>
>> 
>> Simple tests of various atomic write requests and a (simulated) hardware
>> device.
>> 
>> The first test performs basic multi-block atomic writes on a scsi_debug device
>> with atomic writes enabled. We test all advertised sizes between the atomic
>> write unit min and max. We also ensure that the write fails when expected, such
>> as when attempting buffered io or unaligned directio.
>> 
>> The second test is similar to the one above, except that it verifies multi-block
>> atomic writes on actual hardware instead of simulated hardware. The device used
>> in this test is not required to support atomic writes.
>> 
>> The final two tests ensure multi-block atomic writes can be performed on various
>> interweaved mappings, including written, mapped, hole, and unwritten. We also
>> test large atomic writes on a heavily fragmented filesystem. These tests are
>> separated into reflink (shared) and non-reflink tests.
>> 
>> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
>> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
>> ---
>> common/atomicwrites    |  10 ++++
>> tests/generic/1222     |  88 ++++++++++++++++++++++++++++
>> tests/generic/1222.out |  10 ++++
>> tests/generic/1223     |  66 +++++++++++++++++++++
>> tests/generic/1223.out |   9 +++
>> tests/generic/1224     |  86 ++++++++++++++++++++++++++++
>> tests/generic/1224.out |  16 ++++++
>> tests/generic/1225     | 127 +++++++++++++++++++++++++++++++++++++++++
>> tests/generic/1225.out |  21 +++++++
>> 9 files changed, 433 insertions(+)
>> create mode 100755 tests/generic/1222
>> create mode 100644 tests/generic/1222.out
>> create mode 100755 tests/generic/1223
>> create mode 100644 tests/generic/1223.out
>> create mode 100755 tests/generic/1224
>> create mode 100644 tests/generic/1224.out
>> create mode 100755 tests/generic/1225
>> create mode 100644 tests/generic/1225.out
>> 
>> diff --git a/common/atomicwrites b/common/atomicwrites
>> index ac4facc3..95d545a6 100644
>> --- a/common/atomicwrites
>> +++ b/common/atomicwrites
>> @@ -136,3 +136,13 @@ _test_atomic_file_writes()
>>     $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
>>         echo "atomic write requires offset to be aligned to bsize"
>> }
>> +
>> +_simple_atomic_write() {
>> + local pos=$1
>> + local count=$2
>> + local file=$3
>> + local directio=$4
>> +
>> + echo "testing pos=$pos count=$count file=$file directio=$directio" >> $seqres.full
>> + $XFS_IO_PROG $directio -c "pwrite -b $count -V 1 -A -D $pos $count" $file >> $seqres.full
>> +}
>> diff --git a/tests/generic/1222 b/tests/generic/1222
>> new file mode 100755
>> index 00000000..c718b244
>> --- /dev/null
>> +++ b/tests/generic/1222
>> @@ -0,0 +1,88 @@
>> +#! /bin/bash
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
>> +#
>> +# FS QA Test 1222
>> +#
>> +# Validate multi-fsblock atomic write support with simulated hardware support
>> +#
>> +. ./common/preamble
>> +_begin_fstest auto quick rw atomicwrites
>> +
>> +. ./common/scsi_debug
>> +. ./common/atomicwrites
>> +
>> +_cleanup()
>> +{
>> + _scratch_unmount &>/dev/null
>> + _put_scsi_debug_dev &>/dev/null
>> + cd /
>> + rm -r -f $tmp.*
>> +}
>> +
>> +_require_scsi_debug
>> +_require_scratch_nocheck
>> +# Format something so that ./check doesn't freak out
>> +_scratch_mkfs >> $seqres.full
>> +
>> +# 512b logical/physical sectors, 512M size, atomic writes enabled
>> +dev=$(_get_scsi_debug_dev 512 512 0 512 "atomic_wr=1")
>> +test -b "$dev" || _notrun "could not create atomic writes scsi_debug device"
>> +
>> +export SCRATCH_DEV=$dev
> 
> These's a generic test case. As you use scsi_debug device. I'm wondering do we
> need _require_block_device? Can this case works with FSTYP=nfs, cifs, tmpfs, overlayfs
> and so on?
> 
>> +unset USE_EXTERNAL
>> +
>> +_require_scratch_write_atomic
>> +_require_scratch_write_atomic_multi_fsblock
>> +
>> +xfs_io -c 'help pwrite' | grep -q RWF_ATOMIC || _notrun "xfs_io pwrite -A failed"
>> +xfs_io -c 'help falloc' | grep -q 'not found' && _notrun "xfs_io falloc failed"
> 
> Can't these two lines be replaced by _require_xfs_io? e.g.
> _require_xfs_io_command pwrite -A
> _require_xfs_io_command falloc

We can't use _require_xfs_io here because this checks $TEST_DIR, but we are
running these tests on a scsi_debug device located at $SCRATCH_MNT. Even
if $TEST_DIR doesn't support atomic writes, we still want to run this test as long
as the scsi_debug device has atomic writes enabled. So we need to manually
check that the scsi_debug device supports the commands we need.

I will address the other review comments in the next version. Thanks!
> 
>> +
>> +echo "scsi_debug atomic write properties" >> $seqres.full
>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
> 
> _require_xfs_io_command statx -r ?
> 
>> +
>> +_scratch_mkfs >> $seqres.full
>> +_scratch_mount
>> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
>> +
>> +testfile=$SCRATCH_MNT/testfile
>> +touch $testfile
>> +
>> +echo "filesystem atomic write properties" >> $seqres.full
>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
>> +
>> +sector_size=$(blockdev --getss $SCRATCH_DEV)
>> +min_awu=$(_get_atomic_write_unit_min $testfile)
>> +max_awu=$(_get_atomic_write_unit_max $testfile)
>> +
>> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>> +
>> +# try outside the advertised sizes
>> +echo "two EINVAL for unsupported sizes"
>> +min_i=$((min_awu / 2))
>> +_simple_atomic_write $min_i $min_i $testfile -d
>> +max_i=$((max_awu * 2))
>> +_simple_atomic_write $max_i $max_i $testfile -d
>> +
>> +# try all of the advertised sizes
>> +echo "all should work"
>> +for ((i = min_awu; i <= max_awu; i *= 2)); do
>> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>> + _test_atomic_file_writes $i $testfile
>> +done
>> +
>> +# does not support buffered io
>> +echo "one EOPNOTSUPP for buffered atomic"
>> +_simple_atomic_write 0 $min_awu $testfile
>> +
>> +# does not support unaligned directio
>> +echo "one EINVAL for unaligned directio"
>> +_simple_atomic_write $sector_size $min_awu $testfile -d
>> +
>> +_scratch_unmount
>> +_put_scsi_debug_dev
>> +
>> +# success, all done
>> +echo Silence is golden
>> +status=0
>> +exit
>> diff --git a/tests/generic/1222.out b/tests/generic/1222.out
>> new file mode 100644
>> index 00000000..158b52fa
>> --- /dev/null
>> +++ b/tests/generic/1222.out
>> @@ -0,0 +1,10 @@
>> +QA output created by 1222
>> +two EINVAL for unsupported sizes
>> +pwrite: Invalid argument
>> +pwrite: Invalid argument
>> +all should work
>> +one EOPNOTSUPP for buffered atomic
>> +pwrite: Operation not supported
>> +one EINVAL for unaligned directio
>> +pwrite: Invalid argument
>> +Silence is golden
>> diff --git a/tests/generic/1223 b/tests/generic/1223
>> new file mode 100755
>> index 00000000..db242e7f
>> --- /dev/null
>> +++ b/tests/generic/1223
>> @@ -0,0 +1,66 @@
>> +#! /bin/bash
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
>> +#
>> +# FS QA Test 1223
>> +#
>> +# Validate multi-fsblock atomic write support with or without hw support
>> +#
> 
> Same review points with above case.
> 
>> +. ./common/preamble
>> +_begin_fstest auto quick rw atomicwrites
>> +
>> +. ./common/atomicwrites
>> +
>> +_require_scratch
>> +_require_atomic_write_test_commands
>> +_require_scratch_write_atomic_multi_fsblock
>> +
>> +echo "scratch device atomic write properties" >> $seqres.full
>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
>> +
>> +_scratch_mkfs >> $seqres.full
>> +_scratch_mount
>> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
>> +
>> +testfile=$SCRATCH_MNT/testfile
>> +touch $testfile
>> +
>> +echo "filesystem atomic write properties" >> $seqres.full
>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
>> +
>> +sector_size=$(blockdev --getss $SCRATCH_DEV)
>> +min_awu=$(_get_atomic_write_unit_min $testfile)
>> +max_awu=$(_get_atomic_write_unit_max $testfile)
>> +
>> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>> +
>> +# try outside the advertised sizes
>> +echo "two EINVAL for unsupported sizes"
>> +min_i=$((min_awu / 2))
>> +_simple_atomic_write $min_i $min_i $testfile -d
>> +max_i=$((max_awu * 2))
>> +_simple_atomic_write $max_i $max_i $testfile -d
>> +
>> +# try all of the advertised sizes
>> +for ((i = min_awu; i <= max_awu; i *= 2)); do
>> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>> + _test_atomic_file_writes $i $testfile
>> +done
>> +
>> +# does not support buffered io
>> +echo "one EOPNOTSUPP for buffered atomic"
>> +_simple_atomic_write 0 $min_awu $testfile
>> +
>> +# does not support unaligned directio
>> +echo "one EINVAL for unaligned directio"
>> +if [ $sector_size -lt $min_awu ]; then
>> + _simple_atomic_write $sector_size $min_awu $testfile -d
>> +else
>> + # not supported, so fake the output
>> + echo "pwrite: Invalid argument"
>> +fi
>> +
>> +# success, all done
>> +echo Silence is golden
>> +status=0
>> +exit
>> diff --git a/tests/generic/1223.out b/tests/generic/1223.out
>> new file mode 100644
>> index 00000000..edf5bd71
>> --- /dev/null
>> +++ b/tests/generic/1223.out
>> @@ -0,0 +1,9 @@
>> +QA output created by 1223
>> +two EINVAL for unsupported sizes
>> +pwrite: Invalid argument
>> +pwrite: Invalid argument
>> +one EOPNOTSUPP for buffered atomic
>> +pwrite: Operation not supported
>> +one EINVAL for unaligned directio
>> +pwrite: Invalid argument
>> +Silence is golden
>> diff --git a/tests/generic/1224 b/tests/generic/1224
>> new file mode 100755
>> index 00000000..3f83eebc
>> --- /dev/null
>> +++ b/tests/generic/1224
>> @@ -0,0 +1,86 @@
>> +#! /bin/bash
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
>> +#
>> +# FS QA Test 1224
>> +#
>> +# reflink tests for large atomic writes with mixed mappings
>> +#
> 
> Same review points as above case.
> 
>> +. ./common/preamble
>> +_begin_fstest auto quick rw atomicwrites
>> +
>> +. ./common/atomicwrites
>> +. ./common/filter
>> +. ./common/reflink
>> +
>> +_require_scratch
>> +_require_atomic_write_test_commands
>> +_require_scratch_write_atomic_multi_fsblock
>> +_require_xfs_io_command pwrite -A
>> +_require_cp_reflink
> 
> Do you just need _require_cp_reflink, or need _require_scratch_reflink too?
> 
> Thanks,
> Zorro
> 
>> +
>> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
>> +_scratch_mount
>> +
>> +file1=$SCRATCH_MNT/file1
>> +file2=$SCRATCH_MNT/file2
>> +file3=$SCRATCH_MNT/file3
>> +
>> +touch $file1
>> +
>> +max_awu=$(_get_atomic_write_unit_max $file1)
>> +test $max_awu -ge 262144 || _notrun "test requires atomic writes up to 256k"
>> +
>> +min_awu=$(_get_atomic_write_unit_min $file1)
>> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
>> +
>> +bsize=$(_get_file_block_size $SCRATCH_MNT)
>> +test $max_awu -gt $((bsize * 2)) || \
>> + _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
>> +
>> +# reflink tests (files with shared extents)
>> +
>> +echo "atomic write shared data and unshared+shared data"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +cp --reflink=always $file1 $file2
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +md5sum $file2 | _filter_scratch
>> +
>> +echo "atomic write shared data and shared+unshared data"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +cp --reflink=always $file1 $file2
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +md5sum $file2 | _filter_scratch
>> +
>> +echo "atomic overwrite unshared data"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +cp --reflink=always $file1 $file2
>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +md5sum $file2 | _filter_scratch
>> +
>> +echo "atomic write shared+unshared+shared data"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +cp --reflink=always $file1 $file2
>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +md5sum $file2 | _filter_scratch
>> +
>> +echo "atomic write interweaved hole+unwritten+written+reflinked"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +blksz=4096
>> +nr=32
>> +_weave_reflink_rainbow $blksz $nr $file1 $file2 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +md5sum $file2 | _filter_scratch
>> +
>> +# success, all done
>> +status=0
>> +exit
>> diff --git a/tests/generic/1224.out b/tests/generic/1224.out
>> new file mode 100644
>> index 00000000..89e5cd5a
>> --- /dev/null
>> +++ b/tests/generic/1224.out
>> @@ -0,0 +1,16 @@
>> +QA output created by 1224
>> +atomic write shared data and unshared+shared data
>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
>> +atomic write shared data and shared+unshared data
>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
>> +atomic overwrite unshared data
>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
>> +atomic write shared+unshared+shared data
>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
>> +atomic write interweaved hole+unwritten+written+reflinked
>> +4edfbc469bed9965219ea80c9ae54626  SCRATCH_MNT/file1
>> +93243a293a9f568903485b0b2a895815  SCRATCH_MNT/file2
>> diff --git a/tests/generic/1225 b/tests/generic/1225
>> new file mode 100755
>> index 00000000..b940afd3
>> --- /dev/null
>> +++ b/tests/generic/1225
>> @@ -0,0 +1,127 @@
>> +#! /bin/bash
>> +# SPDX-License-Identifier: GPL-2.0
>> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
>> +#
>> +# FS QA Test 1225
>> +#
>> +# basic tests for large atomic writes with mixed mappings
>> +#
>> +. ./common/preamble
>> +_begin_fstest auto quick rw atomicwrites
>> +
>> +. ./common/atomicwrites
>> +. ./common/filter
>> +. ./common/reflink
>> +
>> +_require_scratch
>> +_require_atomic_write_test_commands
>> +_require_scratch_write_atomic_multi_fsblock
>> +
>> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
>> +_scratch_mount
>> +
>> +file1=$SCRATCH_MNT/file1
>> +file2=$SCRATCH_MNT/file2
>> +file3=$SCRATCH_MNT/file3
>> +
>> +touch $file1
>> +
>> +max_awu=$(_get_atomic_write_unit_max $file1)
>> +test $max_awu -ge 65536 || _notrun "test requires atomic writes up to 64k"
>> +
>> +min_awu=$(_get_atomic_write_unit_min $file1)
>> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
>> +
>> +bsize=$(_get_file_block_size $SCRATCH_MNT)
>> +test $max_awu -gt $((bsize * 2)) || \
>> + _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
>> +
>> +# non-reflink tests
>> +
>> +echo "atomic write hole+mapped+hole"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +echo "atomic write adjacent mapped+hole and hole+mapped"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +echo "atomic write mapped+hole+mapped"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +echo "atomic write unwritten+mapped+unwritten"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +echo "atomic write adjacent mapped+unwritten and unwritten+mapped"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +echo "atomic write mapped+unwritten+mapped"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +echo "atomic write interweaved hole+unwritten+written"
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +blksz=4096
>> +nr=32
>> +_weave_file_rainbow $blksz $nr $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +echo "atomic write at EOF"
>> +dd if=/dev/zero of=$file1 bs=32K count=12 conv=fsync >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 360448 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +echo "atomic write preallocated region"
>> +fallocate -l 10M $file1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>> +md5sum $file1 | _filter_scratch
>> +
>> +# atomic write max size
>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>> +aw_max=$(_get_atomic_write_unit_max $file1)
>> +cp $file1 $file1.chk
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
>> +$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
>> +cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
>> +
>> +echo "atomic write max size on fragmented fs"
>> +avail=`_get_available_space $SCRATCH_MNT`
>> +filesizemb=$((avail / 1024 / 1024 - 1))
>> +fragmentedfile=$SCRATCH_MNT/fragmentedfile
>> +$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
>> +$here/src/punch-alternating $fragmentedfile
>> +touch $file3
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
>> +md5sum $file3 | _filter_scratch
>> +
>> +# success, all done
>> +status=0
>> +exit
>> diff --git a/tests/generic/1225.out b/tests/generic/1225.out
>> new file mode 100644
>> index 00000000..c5a6de04
>> --- /dev/null
>> +++ b/tests/generic/1225.out
>> @@ -0,0 +1,21 @@
>> +QA output created by 1225
>> +atomic write hole+mapped+hole
>> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
>> +atomic write adjacent mapped+hole and hole+mapped
>> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
>> +atomic write mapped+hole+mapped
>> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
>> +atomic write unwritten+mapped+unwritten
>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>> +atomic write adjacent mapped+unwritten and unwritten+mapped
>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>> +atomic write mapped+unwritten+mapped
>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>> +atomic write interweaved hole+unwritten+written
>> +5577e46f20631d76bbac73ab1b4ed208  SCRATCH_MNT/file1
>> +atomic write at EOF
>> +0e44615ab08f3e8585a374fca9a6f5eb  SCRATCH_MNT/file1
>> +atomic write preallocated region
>> +3acf1ace00273bc4e2bf4a8d016611ea  SCRATCH_MNT/file1
>> +atomic write max size on fragmented fs
>> +27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
>> -- 
>> 2.34.1
>> 
>> 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-20 23:02     ` Catherine Hoang
@ 2025-06-21 12:20       ` Zorro Lang
  2025-06-26  0:00         ` Catherine Hoang
  0 siblings, 1 reply; 11+ messages in thread
From: Zorro Lang @ 2025-06-21 12:20 UTC (permalink / raw)
  To: Catherine Hoang
  Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org,
	djwong@kernel.org, John Garry, ritesh.list@gmail.com,
	ojaswin@linux.ibm.com

On Fri, Jun 20, 2025 at 11:02:05PM +0000, Catherine Hoang wrote:
> 
> > On Jun 18, 2025, at 11:09 AM, Zorro Lang <zlang@redhat.com> wrote:
> > 
> > On Mon, Jun 16, 2025 at 02:52:12PM -0700, Catherine Hoang wrote:
> >> From: "Darrick J. Wong" <djwong@kernel.org>
> >> 
> >> Simple tests of various atomic write requests and a (simulated) hardware
> >> device.
> >> 
> >> The first test performs basic multi-block atomic writes on a scsi_debug device
> >> with atomic writes enabled. We test all advertised sizes between the atomic
> >> write unit min and max. We also ensure that the write fails when expected, such
> >> as when attempting buffered io or unaligned directio.
> >> 
> >> The second test is similar to the one above, except that it verifies multi-block
> >> atomic writes on actual hardware instead of simulated hardware. The device used
> >> in this test is not required to support atomic writes.
> >> 
> >> The final two tests ensure multi-block atomic writes can be performed on various
> >> interweaved mappings, including written, mapped, hole, and unwritten. We also
> >> test large atomic writes on a heavily fragmented filesystem. These tests are
> >> separated into reflink (shared) and non-reflink tests.
> >> 
> >> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> >> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> >> ---
> >> common/atomicwrites    |  10 ++++
> >> tests/generic/1222     |  88 ++++++++++++++++++++++++++++
> >> tests/generic/1222.out |  10 ++++
> >> tests/generic/1223     |  66 +++++++++++++++++++++
> >> tests/generic/1223.out |   9 +++
> >> tests/generic/1224     |  86 ++++++++++++++++++++++++++++
> >> tests/generic/1224.out |  16 ++++++
> >> tests/generic/1225     | 127 +++++++++++++++++++++++++++++++++++++++++
> >> tests/generic/1225.out |  21 +++++++
> >> 9 files changed, 433 insertions(+)
> >> create mode 100755 tests/generic/1222
> >> create mode 100644 tests/generic/1222.out
> >> create mode 100755 tests/generic/1223
> >> create mode 100644 tests/generic/1223.out
> >> create mode 100755 tests/generic/1224
> >> create mode 100644 tests/generic/1224.out
> >> create mode 100755 tests/generic/1225
> >> create mode 100644 tests/generic/1225.out
> >> 
> >> diff --git a/common/atomicwrites b/common/atomicwrites
> >> index ac4facc3..95d545a6 100644
> >> --- a/common/atomicwrites
> >> +++ b/common/atomicwrites
> >> @@ -136,3 +136,13 @@ _test_atomic_file_writes()
> >>     $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
> >>         echo "atomic write requires offset to be aligned to bsize"
> >> }
> >> +
> >> +_simple_atomic_write() {
> >> + local pos=$1
> >> + local count=$2
> >> + local file=$3
> >> + local directio=$4
> >> +
> >> + echo "testing pos=$pos count=$count file=$file directio=$directio" >> $seqres.full
> >> + $XFS_IO_PROG $directio -c "pwrite -b $count -V 1 -A -D $pos $count" $file >> $seqres.full
> >> +}
> >> diff --git a/tests/generic/1222 b/tests/generic/1222
> >> new file mode 100755
> >> index 00000000..c718b244
> >> --- /dev/null
> >> +++ b/tests/generic/1222
> >> @@ -0,0 +1,88 @@
> >> +#! /bin/bash
> >> +# SPDX-License-Identifier: GPL-2.0
> >> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> >> +#
> >> +# FS QA Test 1222
> >> +#
> >> +# Validate multi-fsblock atomic write support with simulated hardware support
> >> +#
> >> +. ./common/preamble
> >> +_begin_fstest auto quick rw atomicwrites
> >> +
> >> +. ./common/scsi_debug
> >> +. ./common/atomicwrites
> >> +
> >> +_cleanup()
> >> +{
> >> + _scratch_unmount &>/dev/null
> >> + _put_scsi_debug_dev &>/dev/null
> >> + cd /
> >> + rm -r -f $tmp.*
> >> +}
> >> +
> >> +_require_scsi_debug
> >> +_require_scratch_nocheck
                       ^^^^^^^

> >> +# Format something so that ./check doesn't freak out
> >> +_scratch_mkfs >> $seqres.full
> >> +
> >> +# 512b logical/physical sectors, 512M size, atomic writes enabled
> >> +dev=$(_get_scsi_debug_dev 512 512 0 512 "atomic_wr=1")
> >> +test -b "$dev" || _notrun "could not create atomic writes scsi_debug device"
> >> +
> >> +export SCRATCH_DEV=$dev
> > 
> > These's a generic test case. As you use scsi_debug device. I'm wondering do we
> > need _require_block_device? Can this case works with FSTYP=nfs, cifs, tmpfs, overlayfs
> > and so on?

Did you make sure that this generic test case will _notrun on other fs, won't break
their fs testing?

> > 
> >> +unset USE_EXTERNAL
> >> +
> >> +_require_scratch_write_atomic

This function calls _require_scratch, that means the $SCRATCH_DEV still need to be
checked at the end of this test. So your above _require_scratch_nocheck isn't
real "nocheck".

> >> +_require_scratch_write_atomic_multi_fsblock
> >> +
> >> +xfs_io -c 'help pwrite' | grep -q RWF_ATOMIC || _notrun "xfs_io pwrite -A failed"
> >> +xfs_io -c 'help falloc' | grep -q 'not found' && _notrun "xfs_io falloc failed"
> > 
> > Can't these two lines be replaced by _require_xfs_io? e.g.
> > _require_xfs_io_command pwrite -A
> > _require_xfs_io_command falloc
> 
> We can't use _require_xfs_io here because this checks $TEST_DIR, but we are
> running these tests on a scsi_debug device located at $SCRATCH_MNT. Even
> if $TEST_DIR doesn't support atomic writes, we still want to run this test as long
> as the scsi_debug device has atomic writes enabled. So we need to manually
> check that the scsi_debug device supports the commands we need.

Oh, makes sense :) But that means you only check the command is supported by xfs_io,
not by the fs.

Please add a comment to explain that, and replace "xfs_io" with "$XFS_IO_PROG" at least.

> 
> I will address the other review comments in the next version. Thanks!
> > 
> >> +
> >> +echo "scsi_debug atomic write properties" >> $seqres.full
> >> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
> > 
> > _require_xfs_io_command statx -r ?
> > 
> >> +
> >> +_scratch_mkfs >> $seqres.full
> >> +_scratch_mount
> >> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
> >> +
> >> +testfile=$SCRATCH_MNT/testfile
> >> +touch $testfile
> >> +
> >> +echo "filesystem atomic write properties" >> $seqres.full
> >> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> >> +
> >> +sector_size=$(blockdev --getss $SCRATCH_DEV)
> >> +min_awu=$(_get_atomic_write_unit_min $testfile)
> >> +max_awu=$(_get_atomic_write_unit_max $testfile)
> >> +
> >> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> >> +
> >> +# try outside the advertised sizes
> >> +echo "two EINVAL for unsupported sizes"
> >> +min_i=$((min_awu / 2))
> >> +_simple_atomic_write $min_i $min_i $testfile -d
> >> +max_i=$((max_awu * 2))
> >> +_simple_atomic_write $max_i $max_i $testfile -d
> >> +
> >> +# try all of the advertised sizes
> >> +echo "all should work"
> >> +for ((i = min_awu; i <= max_awu; i *= 2)); do
> >> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> >> + _test_atomic_file_writes $i $testfile
> >> +done
> >> +
> >> +# does not support buffered io
> >> +echo "one EOPNOTSUPP for buffered atomic"
> >> +_simple_atomic_write 0 $min_awu $testfile
> >> +
> >> +# does not support unaligned directio
> >> +echo "one EINVAL for unaligned directio"
> >> +_simple_atomic_write $sector_size $min_awu $testfile -d
> >> +
> >> +_scratch_unmount
> >> +_put_scsi_debug_dev
> >> +
> >> +# success, all done
> >> +echo Silence is golden
> >> +status=0
> >> +exit
> >> diff --git a/tests/generic/1222.out b/tests/generic/1222.out
> >> new file mode 100644
> >> index 00000000..158b52fa
> >> --- /dev/null
> >> +++ b/tests/generic/1222.out
> >> @@ -0,0 +1,10 @@
> >> +QA output created by 1222
> >> +two EINVAL for unsupported sizes
> >> +pwrite: Invalid argument
> >> +pwrite: Invalid argument
> >> +all should work
> >> +one EOPNOTSUPP for buffered atomic
> >> +pwrite: Operation not supported
> >> +one EINVAL for unaligned directio
> >> +pwrite: Invalid argument
> >> +Silence is golden
> >> diff --git a/tests/generic/1223 b/tests/generic/1223
> >> new file mode 100755
> >> index 00000000..db242e7f
> >> --- /dev/null
> >> +++ b/tests/generic/1223
> >> @@ -0,0 +1,66 @@
> >> +#! /bin/bash
> >> +# SPDX-License-Identifier: GPL-2.0
> >> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> >> +#
> >> +# FS QA Test 1223
> >> +#
> >> +# Validate multi-fsblock atomic write support with or without hw support
> >> +#
> > 
> > Same review points with above case.
> > 
> >> +. ./common/preamble
> >> +_begin_fstest auto quick rw atomicwrites
> >> +
> >> +. ./common/atomicwrites
> >> +
> >> +_require_scratch
> >> +_require_atomic_write_test_commands
> >> +_require_scratch_write_atomic_multi_fsblock
> >> +
> >> +echo "scratch device atomic write properties" >> $seqres.full
> >> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
> >> +
> >> +_scratch_mkfs >> $seqres.full
> >> +_scratch_mount
> >> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
> >> +
> >> +testfile=$SCRATCH_MNT/testfile
> >> +touch $testfile
> >> +
> >> +echo "filesystem atomic write properties" >> $seqres.full
> >> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
> >> +
> >> +sector_size=$(blockdev --getss $SCRATCH_DEV)
> >> +min_awu=$(_get_atomic_write_unit_min $testfile)
> >> +max_awu=$(_get_atomic_write_unit_max $testfile)
> >> +
> >> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> >> +
> >> +# try outside the advertised sizes
> >> +echo "two EINVAL for unsupported sizes"
> >> +min_i=$((min_awu / 2))
> >> +_simple_atomic_write $min_i $min_i $testfile -d
> >> +max_i=$((max_awu * 2))
> >> +_simple_atomic_write $max_i $max_i $testfile -d
> >> +
> >> +# try all of the advertised sizes
> >> +for ((i = min_awu; i <= max_awu; i *= 2)); do
> >> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
> >> + _test_atomic_file_writes $i $testfile
> >> +done
> >> +
> >> +# does not support buffered io
> >> +echo "one EOPNOTSUPP for buffered atomic"
> >> +_simple_atomic_write 0 $min_awu $testfile
> >> +
> >> +# does not support unaligned directio
> >> +echo "one EINVAL for unaligned directio"
> >> +if [ $sector_size -lt $min_awu ]; then
> >> + _simple_atomic_write $sector_size $min_awu $testfile -d
> >> +else
> >> + # not supported, so fake the output
> >> + echo "pwrite: Invalid argument"
> >> +fi
> >> +
> >> +# success, all done
> >> +echo Silence is golden
> >> +status=0
> >> +exit
> >> diff --git a/tests/generic/1223.out b/tests/generic/1223.out
> >> new file mode 100644
> >> index 00000000..edf5bd71
> >> --- /dev/null
> >> +++ b/tests/generic/1223.out
> >> @@ -0,0 +1,9 @@
> >> +QA output created by 1223
> >> +two EINVAL for unsupported sizes
> >> +pwrite: Invalid argument
> >> +pwrite: Invalid argument
> >> +one EOPNOTSUPP for buffered atomic
> >> +pwrite: Operation not supported
> >> +one EINVAL for unaligned directio
> >> +pwrite: Invalid argument
> >> +Silence is golden
> >> diff --git a/tests/generic/1224 b/tests/generic/1224
> >> new file mode 100755
> >> index 00000000..3f83eebc
> >> --- /dev/null
> >> +++ b/tests/generic/1224
> >> @@ -0,0 +1,86 @@
> >> +#! /bin/bash
> >> +# SPDX-License-Identifier: GPL-2.0
> >> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> >> +#
> >> +# FS QA Test 1224
> >> +#
> >> +# reflink tests for large atomic writes with mixed mappings
> >> +#
> > 
> > Same review points as above case.
> > 
> >> +. ./common/preamble
> >> +_begin_fstest auto quick rw atomicwrites
> >> +
> >> +. ./common/atomicwrites
> >> +. ./common/filter
> >> +. ./common/reflink
> >> +
> >> +_require_scratch
> >> +_require_atomic_write_test_commands
> >> +_require_scratch_write_atomic_multi_fsblock
> >> +_require_xfs_io_command pwrite -A
> >> +_require_cp_reflink
> > 
> > Do you just need _require_cp_reflink, or need _require_scratch_reflink too?
> > 
> > Thanks,
> > Zorro
> > 
> >> +
> >> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
> >> +_scratch_mount
> >> +
> >> +file1=$SCRATCH_MNT/file1
> >> +file2=$SCRATCH_MNT/file2
> >> +file3=$SCRATCH_MNT/file3
> >> +
> >> +touch $file1
> >> +
> >> +max_awu=$(_get_atomic_write_unit_max $file1)
> >> +test $max_awu -ge 262144 || _notrun "test requires atomic writes up to 256k"
> >> +
> >> +min_awu=$(_get_atomic_write_unit_min $file1)
> >> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
> >> +
> >> +bsize=$(_get_file_block_size $SCRATCH_MNT)
> >> +test $max_awu -gt $((bsize * 2)) || \
> >> + _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
> >> +
> >> +# reflink tests (files with shared extents)
> >> +
> >> +echo "atomic write shared data and unshared+shared data"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +cp --reflink=always $file1 $file2
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +md5sum $file2 | _filter_scratch
> >> +
> >> +echo "atomic write shared data and shared+unshared data"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +cp --reflink=always $file1 $file2
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +md5sum $file2 | _filter_scratch
> >> +
> >> +echo "atomic overwrite unshared data"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +cp --reflink=always $file1 $file2
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +md5sum $file2 | _filter_scratch
> >> +
> >> +echo "atomic write shared+unshared+shared data"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +cp --reflink=always $file1 $file2
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +md5sum $file2 | _filter_scratch
> >> +
> >> +echo "atomic write interweaved hole+unwritten+written+reflinked"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +blksz=4096
> >> +nr=32
> >> +_weave_reflink_rainbow $blksz $nr $file1 $file2 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +md5sum $file2 | _filter_scratch
> >> +
> >> +# success, all done
> >> +status=0
> >> +exit
> >> diff --git a/tests/generic/1224.out b/tests/generic/1224.out
> >> new file mode 100644
> >> index 00000000..89e5cd5a
> >> --- /dev/null
> >> +++ b/tests/generic/1224.out
> >> @@ -0,0 +1,16 @@
> >> +QA output created by 1224
> >> +atomic write shared data and unshared+shared data
> >> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> >> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
> >> +atomic write shared data and shared+unshared data
> >> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> >> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
> >> +atomic overwrite unshared data
> >> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> >> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
> >> +atomic write shared+unshared+shared data
> >> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> >> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
> >> +atomic write interweaved hole+unwritten+written+reflinked
> >> +4edfbc469bed9965219ea80c9ae54626  SCRATCH_MNT/file1
> >> +93243a293a9f568903485b0b2a895815  SCRATCH_MNT/file2
> >> diff --git a/tests/generic/1225 b/tests/generic/1225
> >> new file mode 100755
> >> index 00000000..b940afd3
> >> --- /dev/null
> >> +++ b/tests/generic/1225
> >> @@ -0,0 +1,127 @@
> >> +#! /bin/bash
> >> +# SPDX-License-Identifier: GPL-2.0
> >> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
> >> +#
> >> +# FS QA Test 1225
> >> +#
> >> +# basic tests for large atomic writes with mixed mappings
> >> +#
> >> +. ./common/preamble
> >> +_begin_fstest auto quick rw atomicwrites
> >> +
> >> +. ./common/atomicwrites
> >> +. ./common/filter
> >> +. ./common/reflink
> >> +
> >> +_require_scratch
> >> +_require_atomic_write_test_commands
> >> +_require_scratch_write_atomic_multi_fsblock
> >> +
> >> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
> >> +_scratch_mount
> >> +
> >> +file1=$SCRATCH_MNT/file1
> >> +file2=$SCRATCH_MNT/file2
> >> +file3=$SCRATCH_MNT/file3
> >> +
> >> +touch $file1
> >> +
> >> +max_awu=$(_get_atomic_write_unit_max $file1)
> >> +test $max_awu -ge 65536 || _notrun "test requires atomic writes up to 64k"
> >> +
> >> +min_awu=$(_get_atomic_write_unit_min $file1)
> >> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
> >> +
> >> +bsize=$(_get_file_block_size $SCRATCH_MNT)
> >> +test $max_awu -gt $((bsize * 2)) || \
> >> + _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
> >> +
> >> +# non-reflink tests
> >> +
> >> +echo "atomic write hole+mapped+hole"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +echo "atomic write adjacent mapped+hole and hole+mapped"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +echo "atomic write mapped+hole+mapped"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +echo "atomic write unwritten+mapped+unwritten"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +echo "atomic write adjacent mapped+unwritten and unwritten+mapped"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +echo "atomic write mapped+unwritten+mapped"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +echo "atomic write interweaved hole+unwritten+written"
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +blksz=4096
> >> +nr=32
> >> +_weave_file_rainbow $blksz $nr $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +echo "atomic write at EOF"
> >> +dd if=/dev/zero of=$file1 bs=32K count=12 conv=fsync >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 360448 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +echo "atomic write preallocated region"
> >> +fallocate -l 10M $file1
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
> >> +md5sum $file1 | _filter_scratch
> >> +
> >> +# atomic write max size
> >> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
> >> +aw_max=$(_get_atomic_write_unit_max $file1)
> >> +cp $file1 $file1.chk
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
> >> +$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
> >> +cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
> >> +
> >> +echo "atomic write max size on fragmented fs"
> >> +avail=`_get_available_space $SCRATCH_MNT`
> >> +filesizemb=$((avail / 1024 / 1024 - 1))
> >> +fragmentedfile=$SCRATCH_MNT/fragmentedfile
> >> +$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
> >> +$here/src/punch-alternating $fragmentedfile
> >> +touch $file3
> >> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
> >> +md5sum $file3 | _filter_scratch
> >> +
> >> +# success, all done
> >> +status=0
> >> +exit
> >> diff --git a/tests/generic/1225.out b/tests/generic/1225.out
> >> new file mode 100644
> >> index 00000000..c5a6de04
> >> --- /dev/null
> >> +++ b/tests/generic/1225.out
> >> @@ -0,0 +1,21 @@
> >> +QA output created by 1225
> >> +atomic write hole+mapped+hole
> >> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
> >> +atomic write adjacent mapped+hole and hole+mapped
> >> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
> >> +atomic write mapped+hole+mapped
> >> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
> >> +atomic write unwritten+mapped+unwritten
> >> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> >> +atomic write adjacent mapped+unwritten and unwritten+mapped
> >> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> >> +atomic write mapped+unwritten+mapped
> >> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
> >> +atomic write interweaved hole+unwritten+written
> >> +5577e46f20631d76bbac73ab1b4ed208  SCRATCH_MNT/file1
> >> +atomic write at EOF
> >> +0e44615ab08f3e8585a374fca9a6f5eb  SCRATCH_MNT/file1
> >> +atomic write preallocated region
> >> +3acf1ace00273bc4e2bf4a8d016611ea  SCRATCH_MNT/file1
> >> +atomic write max size on fragmented fs
> >> +27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
> >> -- 
> >> 2.34.1
> >> 
> >> 
> > 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-21 12:20       ` Zorro Lang
@ 2025-06-26  0:00         ` Catherine Hoang
  0 siblings, 0 replies; 11+ messages in thread
From: Catherine Hoang @ 2025-06-26  0:00 UTC (permalink / raw)
  To: Zorro Lang
  Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org,
	djwong@kernel.org, John Garry, ritesh.list@gmail.com,
	ojaswin@linux.ibm.com



> On Jun 21, 2025, at 5:20 AM, Zorro Lang <zlang@redhat.com> wrote:
> 
> On Fri, Jun 20, 2025 at 11:02:05PM +0000, Catherine Hoang wrote:
>> 
>>> On Jun 18, 2025, at 11:09 AM, Zorro Lang <zlang@redhat.com> wrote:
>>> 
>>> On Mon, Jun 16, 2025 at 02:52:12PM -0700, Catherine Hoang wrote:
>>>> From: "Darrick J. Wong" <djwong@kernel.org>
>>>> 
>>>> Simple tests of various atomic write requests and a (simulated) hardware
>>>> device.
>>>> 
>>>> The first test performs basic multi-block atomic writes on a scsi_debug device
>>>> with atomic writes enabled. We test all advertised sizes between the atomic
>>>> write unit min and max. We also ensure that the write fails when expected, such
>>>> as when attempting buffered io or unaligned directio.
>>>> 
>>>> The second test is similar to the one above, except that it verifies multi-block
>>>> atomic writes on actual hardware instead of simulated hardware. The device used
>>>> in this test is not required to support atomic writes.
>>>> 
>>>> The final two tests ensure multi-block atomic writes can be performed on various
>>>> interweaved mappings, including written, mapped, hole, and unwritten. We also
>>>> test large atomic writes on a heavily fragmented filesystem. These tests are
>>>> separated into reflink (shared) and non-reflink tests.
>>>> 
>>>> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
>>>> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
>>>> ---
>>>> common/atomicwrites    |  10 ++++
>>>> tests/generic/1222     |  88 ++++++++++++++++++++++++++++
>>>> tests/generic/1222.out |  10 ++++
>>>> tests/generic/1223     |  66 +++++++++++++++++++++
>>>> tests/generic/1223.out |   9 +++
>>>> tests/generic/1224     |  86 ++++++++++++++++++++++++++++
>>>> tests/generic/1224.out |  16 ++++++
>>>> tests/generic/1225     | 127 +++++++++++++++++++++++++++++++++++++++++
>>>> tests/generic/1225.out |  21 +++++++
>>>> 9 files changed, 433 insertions(+)
>>>> create mode 100755 tests/generic/1222
>>>> create mode 100644 tests/generic/1222.out
>>>> create mode 100755 tests/generic/1223
>>>> create mode 100644 tests/generic/1223.out
>>>> create mode 100755 tests/generic/1224
>>>> create mode 100644 tests/generic/1224.out
>>>> create mode 100755 tests/generic/1225
>>>> create mode 100644 tests/generic/1225.out
>>>> 
>>>> diff --git a/common/atomicwrites b/common/atomicwrites
>>>> index ac4facc3..95d545a6 100644
>>>> --- a/common/atomicwrites
>>>> +++ b/common/atomicwrites
>>>> @@ -136,3 +136,13 @@ _test_atomic_file_writes()
>>>>    $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 1 $bsize" $testfile 2>> $seqres.full && \
>>>>        echo "atomic write requires offset to be aligned to bsize"
>>>> }
>>>> +
>>>> +_simple_atomic_write() {
>>>> + local pos=$1
>>>> + local count=$2
>>>> + local file=$3
>>>> + local directio=$4
>>>> +
>>>> + echo "testing pos=$pos count=$count file=$file directio=$directio" >> $seqres.full
>>>> + $XFS_IO_PROG $directio -c "pwrite -b $count -V 1 -A -D $pos $count" $file >> $seqres.full
>>>> +}
>>>> diff --git a/tests/generic/1222 b/tests/generic/1222
>>>> new file mode 100755
>>>> index 00000000..c718b244
>>>> --- /dev/null
>>>> +++ b/tests/generic/1222
>>>> @@ -0,0 +1,88 @@
>>>> +#! /bin/bash
>>>> +# SPDX-License-Identifier: GPL-2.0
>>>> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
>>>> +#
>>>> +# FS QA Test 1222
>>>> +#
>>>> +# Validate multi-fsblock atomic write support with simulated hardware support
>>>> +#
>>>> +. ./common/preamble
>>>> +_begin_fstest auto quick rw atomicwrites
>>>> +
>>>> +. ./common/scsi_debug
>>>> +. ./common/atomicwrites
>>>> +
>>>> +_cleanup()
>>>> +{
>>>> + _scratch_unmount &>/dev/null
>>>> + _put_scsi_debug_dev &>/dev/null
>>>> + cd /
>>>> + rm -r -f $tmp.*
>>>> +}
>>>> +
>>>> +_require_scsi_debug
>>>> +_require_scratch_nocheck
>                       ^^^^^^^
> 
>>>> +# Format something so that ./check doesn't freak out
>>>> +_scratch_mkfs >> $seqres.full
>>>> +
>>>> +# 512b logical/physical sectors, 512M size, atomic writes enabled
>>>> +dev=$(_get_scsi_debug_dev 512 512 0 512 "atomic_wr=1")
>>>> +test -b "$dev" || _notrun "could not create atomic writes scsi_debug device"
>>>> +
>>>> +export SCRATCH_DEV=$dev
>>> 
>>> These's a generic test case. As you use scsi_debug device. I'm wondering do we
>>> need _require_block_device? Can this case works with FSTYP=nfs, cifs, tmpfs, overlayfs
>>> and so on?
> 
> Did you make sure that this generic test case will _notrun on other fs, won't break
> their fs testing?

I’m not familiar with those filesystems, but I will add _require_block_device
to the generic tests so that they won’t run on these filesystems.
> 
>>> 
>>>> +unset USE_EXTERNAL
>>>> +
>>>> +_require_scratch_write_atomic
> 
> This function calls _require_scratch, that means the $SCRATCH_DEV still need to be
> checked at the end of this test. So your above _require_scratch_nocheck isn't
> real "nocheck".

Ok, looks like we can change this to just _require_scratch. Thanks!
> 
>>>> +_require_scratch_write_atomic_multi_fsblock
>>>> +
>>>> +xfs_io -c 'help pwrite' | grep -q RWF_ATOMIC || _notrun "xfs_io pwrite -A failed"
>>>> +xfs_io -c 'help falloc' | grep -q 'not found' && _notrun "xfs_io falloc failed"
>>> 
>>> Can't these two lines be replaced by _require_xfs_io? e.g.
>>> _require_xfs_io_command pwrite -A
>>> _require_xfs_io_command falloc
>> 
>> We can't use _require_xfs_io here because this checks $TEST_DIR, but we are
>> running these tests on a scsi_debug device located at $SCRATCH_MNT. Even
>> if $TEST_DIR doesn't support atomic writes, we still want to run this test as long
>> as the scsi_debug device has atomic writes enabled. So we need to manually
>> check that the scsi_debug device supports the commands we need.
> 
> Oh, makes sense :) But that means you only check the command is supported by xfs_io,
> not by the fs.
> 
> Please add a comment to explain that, and replace "xfs_io" with "$XFS_IO_PROG" at least.
> 
>> 
>> I will address the other review comments in the next version. Thanks!
>>> 
>>>> +
>>>> +echo "scsi_debug atomic write properties" >> $seqres.full
>>>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
>>> 
>>> _require_xfs_io_command statx -r ?
>>> 
>>>> +
>>>> +_scratch_mkfs >> $seqres.full
>>>> +_scratch_mount
>>>> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
>>>> +
>>>> +testfile=$SCRATCH_MNT/testfile
>>>> +touch $testfile
>>>> +
>>>> +echo "filesystem atomic write properties" >> $seqres.full
>>>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
>>>> +
>>>> +sector_size=$(blockdev --getss $SCRATCH_DEV)
>>>> +min_awu=$(_get_atomic_write_unit_min $testfile)
>>>> +max_awu=$(_get_atomic_write_unit_max $testfile)
>>>> +
>>>> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>>>> +
>>>> +# try outside the advertised sizes
>>>> +echo "two EINVAL for unsupported sizes"
>>>> +min_i=$((min_awu / 2))
>>>> +_simple_atomic_write $min_i $min_i $testfile -d
>>>> +max_i=$((max_awu * 2))
>>>> +_simple_atomic_write $max_i $max_i $testfile -d
>>>> +
>>>> +# try all of the advertised sizes
>>>> +echo "all should work"
>>>> +for ((i = min_awu; i <= max_awu; i *= 2)); do
>>>> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>>>> + _test_atomic_file_writes $i $testfile
>>>> +done
>>>> +
>>>> +# does not support buffered io
>>>> +echo "one EOPNOTSUPP for buffered atomic"
>>>> +_simple_atomic_write 0 $min_awu $testfile
>>>> +
>>>> +# does not support unaligned directio
>>>> +echo "one EINVAL for unaligned directio"
>>>> +_simple_atomic_write $sector_size $min_awu $testfile -d
>>>> +
>>>> +_scratch_unmount
>>>> +_put_scsi_debug_dev
>>>> +
>>>> +# success, all done
>>>> +echo Silence is golden
>>>> +status=0
>>>> +exit
>>>> diff --git a/tests/generic/1222.out b/tests/generic/1222.out
>>>> new file mode 100644
>>>> index 00000000..158b52fa
>>>> --- /dev/null
>>>> +++ b/tests/generic/1222.out
>>>> @@ -0,0 +1,10 @@
>>>> +QA output created by 1222
>>>> +two EINVAL for unsupported sizes
>>>> +pwrite: Invalid argument
>>>> +pwrite: Invalid argument
>>>> +all should work
>>>> +one EOPNOTSUPP for buffered atomic
>>>> +pwrite: Operation not supported
>>>> +one EINVAL for unaligned directio
>>>> +pwrite: Invalid argument
>>>> +Silence is golden
>>>> diff --git a/tests/generic/1223 b/tests/generic/1223
>>>> new file mode 100755
>>>> index 00000000..db242e7f
>>>> --- /dev/null
>>>> +++ b/tests/generic/1223
>>>> @@ -0,0 +1,66 @@
>>>> +#! /bin/bash
>>>> +# SPDX-License-Identifier: GPL-2.0
>>>> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
>>>> +#
>>>> +# FS QA Test 1223
>>>> +#
>>>> +# Validate multi-fsblock atomic write support with or without hw support
>>>> +#
>>> 
>>> Same review points with above case.
>>> 
>>>> +. ./common/preamble
>>>> +_begin_fstest auto quick rw atomicwrites
>>>> +
>>>> +. ./common/atomicwrites
>>>> +
>>>> +_require_scratch
>>>> +_require_atomic_write_test_commands
>>>> +_require_scratch_write_atomic_multi_fsblock
>>>> +
>>>> +echo "scratch device atomic write properties" >> $seqres.full
>>>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $SCRATCH_DEV >> $seqres.full
>>>> +
>>>> +_scratch_mkfs >> $seqres.full
>>>> +_scratch_mount
>>>> +test "$FSTYP" = "xfs" && _xfs_force_bdev data $SCRATCH_MNT
>>>> +
>>>> +testfile=$SCRATCH_MNT/testfile
>>>> +touch $testfile
>>>> +
>>>> +echo "filesystem atomic write properties" >> $seqres.full
>>>> +$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $testfile >> $seqres.full
>>>> +
>>>> +sector_size=$(blockdev --getss $SCRATCH_DEV)
>>>> +min_awu=$(_get_atomic_write_unit_min $testfile)
>>>> +max_awu=$(_get_atomic_write_unit_max $testfile)
>>>> +
>>>> +$XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>>>> +
>>>> +# try outside the advertised sizes
>>>> +echo "two EINVAL for unsupported sizes"
>>>> +min_i=$((min_awu / 2))
>>>> +_simple_atomic_write $min_i $min_i $testfile -d
>>>> +max_i=$((max_awu * 2))
>>>> +_simple_atomic_write $max_i $max_i $testfile -d
>>>> +
>>>> +# try all of the advertised sizes
>>>> +for ((i = min_awu; i <= max_awu; i *= 2)); do
>>>> + $XFS_IO_PROG -f -c "falloc 0 $((max_awu * 2))" -c fsync $testfile
>>>> + _test_atomic_file_writes $i $testfile
>>>> +done
>>>> +
>>>> +# does not support buffered io
>>>> +echo "one EOPNOTSUPP for buffered atomic"
>>>> +_simple_atomic_write 0 $min_awu $testfile
>>>> +
>>>> +# does not support unaligned directio
>>>> +echo "one EINVAL for unaligned directio"
>>>> +if [ $sector_size -lt $min_awu ]; then
>>>> + _simple_atomic_write $sector_size $min_awu $testfile -d
>>>> +else
>>>> + # not supported, so fake the output
>>>> + echo "pwrite: Invalid argument"
>>>> +fi
>>>> +
>>>> +# success, all done
>>>> +echo Silence is golden
>>>> +status=0
>>>> +exit
>>>> diff --git a/tests/generic/1223.out b/tests/generic/1223.out
>>>> new file mode 100644
>>>> index 00000000..edf5bd71
>>>> --- /dev/null
>>>> +++ b/tests/generic/1223.out
>>>> @@ -0,0 +1,9 @@
>>>> +QA output created by 1223
>>>> +two EINVAL for unsupported sizes
>>>> +pwrite: Invalid argument
>>>> +pwrite: Invalid argument
>>>> +one EOPNOTSUPP for buffered atomic
>>>> +pwrite: Operation not supported
>>>> +one EINVAL for unaligned directio
>>>> +pwrite: Invalid argument
>>>> +Silence is golden
>>>> diff --git a/tests/generic/1224 b/tests/generic/1224
>>>> new file mode 100755
>>>> index 00000000..3f83eebc
>>>> --- /dev/null
>>>> +++ b/tests/generic/1224
>>>> @@ -0,0 +1,86 @@
>>>> +#! /bin/bash
>>>> +# SPDX-License-Identifier: GPL-2.0
>>>> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
>>>> +#
>>>> +# FS QA Test 1224
>>>> +#
>>>> +# reflink tests for large atomic writes with mixed mappings
>>>> +#
>>> 
>>> Same review points as above case.
>>> 
>>>> +. ./common/preamble
>>>> +_begin_fstest auto quick rw atomicwrites
>>>> +
>>>> +. ./common/atomicwrites
>>>> +. ./common/filter
>>>> +. ./common/reflink
>>>> +
>>>> +_require_scratch
>>>> +_require_atomic_write_test_commands
>>>> +_require_scratch_write_atomic_multi_fsblock
>>>> +_require_xfs_io_command pwrite -A
>>>> +_require_cp_reflink
>>> 
>>> Do you just need _require_cp_reflink, or need _require_scratch_reflink too?
>>> 
>>> Thanks,
>>> Zorro
>>> 
>>>> +
>>>> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
>>>> +_scratch_mount
>>>> +
>>>> +file1=$SCRATCH_MNT/file1
>>>> +file2=$SCRATCH_MNT/file2
>>>> +file3=$SCRATCH_MNT/file3
>>>> +
>>>> +touch $file1
>>>> +
>>>> +max_awu=$(_get_atomic_write_unit_max $file1)
>>>> +test $max_awu -ge 262144 || _notrun "test requires atomic writes up to 256k"
>>>> +
>>>> +min_awu=$(_get_atomic_write_unit_min $file1)
>>>> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
>>>> +
>>>> +bsize=$(_get_file_block_size $SCRATCH_MNT)
>>>> +test $max_awu -gt $((bsize * 2)) || \
>>>> + _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
>>>> +
>>>> +# reflink tests (files with shared extents)
>>>> +
>>>> +echo "atomic write shared data and unshared+shared data"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +cp --reflink=always $file1 $file2
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +md5sum $file2 | _filter_scratch
>>>> +
>>>> +echo "atomic write shared data and shared+unshared data"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +cp --reflink=always $file1 $file2
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +md5sum $file2 | _filter_scratch
>>>> +
>>>> +echo "atomic overwrite unshared data"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +cp --reflink=always $file1 $file2
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +md5sum $file2 | _filter_scratch
>>>> +
>>>> +echo "atomic write shared+unshared+shared data"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +cp --reflink=always $file1 $file2
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +md5sum $file2 | _filter_scratch
>>>> +
>>>> +echo "atomic write interweaved hole+unwritten+written+reflinked"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +blksz=4096
>>>> +nr=32
>>>> +_weave_reflink_rainbow $blksz $nr $file1 $file2 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +md5sum $file2 | _filter_scratch
>>>> +
>>>> +# success, all done
>>>> +status=0
>>>> +exit
>>>> diff --git a/tests/generic/1224.out b/tests/generic/1224.out
>>>> new file mode 100644
>>>> index 00000000..89e5cd5a
>>>> --- /dev/null
>>>> +++ b/tests/generic/1224.out
>>>> @@ -0,0 +1,16 @@
>>>> +QA output created by 1224
>>>> +atomic write shared data and unshared+shared data
>>>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>>>> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
>>>> +atomic write shared data and shared+unshared data
>>>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>>>> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
>>>> +atomic overwrite unshared data
>>>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>>>> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
>>>> +atomic write shared+unshared+shared data
>>>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>>>> +f1c9645dbc14efddc7d8a322685f26eb  SCRATCH_MNT/file2
>>>> +atomic write interweaved hole+unwritten+written+reflinked
>>>> +4edfbc469bed9965219ea80c9ae54626  SCRATCH_MNT/file1
>>>> +93243a293a9f568903485b0b2a895815  SCRATCH_MNT/file2
>>>> diff --git a/tests/generic/1225 b/tests/generic/1225
>>>> new file mode 100755
>>>> index 00000000..b940afd3
>>>> --- /dev/null
>>>> +++ b/tests/generic/1225
>>>> @@ -0,0 +1,127 @@
>>>> +#! /bin/bash
>>>> +# SPDX-License-Identifier: GPL-2.0
>>>> +# Copyright (c) 2025 Oracle.  All Rights Reserved.
>>>> +#
>>>> +# FS QA Test 1225
>>>> +#
>>>> +# basic tests for large atomic writes with mixed mappings
>>>> +#
>>>> +. ./common/preamble
>>>> +_begin_fstest auto quick rw atomicwrites
>>>> +
>>>> +. ./common/atomicwrites
>>>> +. ./common/filter
>>>> +. ./common/reflink
>>>> +
>>>> +_require_scratch
>>>> +_require_atomic_write_test_commands
>>>> +_require_scratch_write_atomic_multi_fsblock
>>>> +
>>>> +_scratch_mkfs_sized $((500 * 1048576)) >> $seqres.full 2>&1
>>>> +_scratch_mount
>>>> +
>>>> +file1=$SCRATCH_MNT/file1
>>>> +file2=$SCRATCH_MNT/file2
>>>> +file3=$SCRATCH_MNT/file3
>>>> +
>>>> +touch $file1
>>>> +
>>>> +max_awu=$(_get_atomic_write_unit_max $file1)
>>>> +test $max_awu -ge 65536 || _notrun "test requires atomic writes up to 64k"
>>>> +
>>>> +min_awu=$(_get_atomic_write_unit_min $file1)
>>>> +test $min_awu -le 4096 || _notrun "test requires atomic writes down to 4k"
>>>> +
>>>> +bsize=$(_get_file_block_size $SCRATCH_MNT)
>>>> +test $max_awu -gt $((bsize * 2)) || \
>>>> + _notrun "max atomic write $max_awu less than 2 fsblocks $bsize"
>>>> +
>>>> +# non-reflink tests
>>>> +
>>>> +echo "atomic write hole+mapped+hole"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +echo "atomic write adjacent mapped+hole and hole+mapped"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +echo "atomic write mapped+hole+mapped"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096000 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +echo "atomic write unwritten+mapped+unwritten"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 4096 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +echo "atomic write adjacent mapped+unwritten and unwritten+mapped"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 32768" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 32768 32768" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +echo "atomic write mapped+unwritten+mapped"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -fc "falloc 0 4096000" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 0 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -D -V1 61440 4096" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +echo "atomic write interweaved hole+unwritten+written"
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +blksz=4096
>>>> +nr=32
>>>> +_weave_file_rainbow $blksz $nr $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +echo "atomic write at EOF"
>>>> +dd if=/dev/zero of=$file1 bs=32K count=12 conv=fsync >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 360448 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +echo "atomic write preallocated region"
>>>> +fallocate -l 10M $file1
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file1 >>$seqres.full 2>&1
>>>> +md5sum $file1 | _filter_scratch
>>>> +
>>>> +# atomic write max size
>>>> +dd if=/dev/zero of=$file1 bs=1M count=10 conv=fsync >>$seqres.full 2>&1
>>>> +aw_max=$(_get_atomic_write_unit_max $file1)
>>>> +cp $file1 $file1.chk
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 $aw_max" $file1 >>$seqres.full 2>&1
>>>> +$XFS_IO_PROG -c "pwrite 0 $aw_max" $file1.chk >>$seqres.full 2>&1
>>>> +cmp -s $file1 $file1.chk || echo "file1 doesnt match file1.chk"
>>>> +
>>>> +echo "atomic write max size on fragmented fs"
>>>> +avail=`_get_available_space $SCRATCH_MNT`
>>>> +filesizemb=$((avail / 1024 / 1024 - 1))
>>>> +fragmentedfile=$SCRATCH_MNT/fragmentedfile
>>>> +$XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $fragmentedfile
>>>> +$here/src/punch-alternating $fragmentedfile
>>>> +touch $file3
>>>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 0 65536" $file3 >>$seqres.full 2>&1
>>>> +md5sum $file3 | _filter_scratch
>>>> +
>>>> +# success, all done
>>>> +status=0
>>>> +exit
>>>> diff --git a/tests/generic/1225.out b/tests/generic/1225.out
>>>> new file mode 100644
>>>> index 00000000..c5a6de04
>>>> --- /dev/null
>>>> +++ b/tests/generic/1225.out
>>>> @@ -0,0 +1,21 @@
>>>> +QA output created by 1225
>>>> +atomic write hole+mapped+hole
>>>> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
>>>> +atomic write adjacent mapped+hole and hole+mapped
>>>> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
>>>> +atomic write mapped+hole+mapped
>>>> +9464b66461bc1d20229e1b71733539d0  SCRATCH_MNT/file1
>>>> +atomic write unwritten+mapped+unwritten
>>>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>>>> +atomic write adjacent mapped+unwritten and unwritten+mapped
>>>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>>>> +atomic write mapped+unwritten+mapped
>>>> +111ce6bf29d5b1dbfb0e846c42719ece  SCRATCH_MNT/file1
>>>> +atomic write interweaved hole+unwritten+written
>>>> +5577e46f20631d76bbac73ab1b4ed208  SCRATCH_MNT/file1
>>>> +atomic write at EOF
>>>> +0e44615ab08f3e8585a374fca9a6f5eb  SCRATCH_MNT/file1
>>>> +atomic write preallocated region
>>>> +3acf1ace00273bc4e2bf4a8d016611ea  SCRATCH_MNT/file1
>>>> +atomic write max size on fragmented fs
>>>> +27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
>>>> -- 
>>>> 2.34.1
>>>> 
>>>> 
>>> 
>> 
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2025-06-26  0:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-16 21:52 [PATCH v5 0/3] atomic writes tests (part 2) Catherine Hoang
2025-06-16 21:52 ` [PATCH v5 1/3] common/atomicwrites: add helper for multi block atomic writes Catherine Hoang
2025-06-16 21:52 ` [PATCH v5 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
2025-06-17 10:18   ` John Garry
2025-06-18  9:25   ` Ojaswin Mujoo
2025-06-18 18:09   ` Zorro Lang
2025-06-20 23:02     ` Catherine Hoang
2025-06-21 12:20       ` Zorro Lang
2025-06-26  0:00         ` Catherine Hoang
2025-06-16 21:52 ` [PATCH v5 3/3] xfs: more multi-block atomic writes tests Catherine Hoang
2025-06-18 18:13   ` Zorro Lang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).