linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/3] atomic writes tests (part 2)
@ 2025-06-12  1:57 Catherine Hoang
  2025-06-12  1:57 ` [PATCH v4 1/3] common/atomicwrites: add helper for multi block atomic writes Catherine Hoang
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Catherine Hoang @ 2025-06-12  1:57 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/

v4 adds more descriptive commit messages. No functional changes since v3.
This series is based on for-next at the time of sending.

Catherine Hoang (3):
  common/atomicwrites: add helper for multi block atomic writes
  generic: various atomic write tests with hardware and scsi_debug
  xfs: more multi-block atomic writes tests

 common/atomicwrites    |  31 ++++++++++
 tests/generic/1222     |  89 ++++++++++++++++++++++++++++
 tests/generic/1222.out |  10 ++++
 tests/generic/1223     |  67 +++++++++++++++++++++
 tests/generic/1223.out |   9 +++
 tests/generic/1224     |  86 +++++++++++++++++++++++++++
 tests/generic/1224.out |  16 ++++++
 tests/generic/1225     | 128 +++++++++++++++++++++++++++++++++++++++++
 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, 683 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] 13+ messages in thread

* [PATCH v4 1/3] common/atomicwrites: add helper for multi block atomic writes
  2025-06-12  1:57 [PATCH v4 0/3] atomic writes tests (part 2) Catherine Hoang
@ 2025-06-12  1:57 ` Catherine Hoang
  2025-06-12  4:01   ` Darrick J. Wong
  2025-06-12  6:31   ` Ojaswin Mujoo
  2025-06-12  1:57 ` [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
  2025-06-12  1:57 ` [PATCH v4 3/3] xfs: more multi-block atomic writes tests Catherine Hoang
  2 siblings, 2 replies; 13+ messages in thread
From: Catherine Hoang @ 2025-06-12  1:57 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>
---
 common/atomicwrites | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/common/atomicwrites b/common/atomicwrites
index 391bb6f6..88f49a1a 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] 13+ messages in thread

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

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     |  89 ++++++++++++++++++++++++++++
 tests/generic/1222.out |  10 ++++
 tests/generic/1223     |  67 +++++++++++++++++++++
 tests/generic/1223.out |   9 +++
 tests/generic/1224     |  86 +++++++++++++++++++++++++++
 tests/generic/1224.out |  16 ++++++
 tests/generic/1225     | 128 +++++++++++++++++++++++++++++++++++++++++
 tests/generic/1225.out |  21 +++++++
 9 files changed, 436 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 88f49a1a..4ba945ec 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..d3665d0b
--- /dev/null
+++ b/tests/generic/1222
@@ -0,0 +1,89 @@
+#! /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
+	_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"
+_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..e0b6f0a1
--- /dev/null
+++ b/tests/generic/1223
@@ -0,0 +1,67 @@
+#! /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
+	_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/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..f2dea804
--- /dev/null
+++ b/tests/generic/1225
@@ -0,0 +1,128 @@
+#! /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
+_require_xfs_io_command pwrite -A
+
+_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"
+
+# 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=128K count=3 conv=fsync >>$seqres.full 2>&1
+$XFS_IO_PROG -dc "pwrite -A -D -V1 262144 262144" $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..92302597
--- /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
+75572c4929fde8faf131e84df4c6a764  SCRATCH_MNT/file1
+atomic write preallocated region
+27a248351cd540bc9ac2c2dc841abca2  SCRATCH_MNT/file1
+atomic write max size on fragmented fs
+27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
-- 
2.34.1


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

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

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] 13+ messages in thread

* Re: [PATCH v4 1/3] common/atomicwrites: add helper for multi block atomic writes
  2025-06-12  1:57 ` [PATCH v4 1/3] common/atomicwrites: add helper for multi block atomic writes Catherine Hoang
@ 2025-06-12  4:01   ` Darrick J. Wong
  2025-06-12  6:31   ` Ojaswin Mujoo
  1 sibling, 0 replies; 13+ messages in thread
From: Darrick J. Wong @ 2025-06-12  4:01 UTC (permalink / raw)
  To: Catherine Hoang; +Cc: linux-xfs, fstests, john.g.garry, ritesh.list, ojaswin

On Wed, Jun 11, 2025 at 06:57:06PM -0700, Catherine Hoang wrote:
> 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>
> ---
>  common/atomicwrites | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/common/atomicwrites b/common/atomicwrites
> index 391bb6f6..88f49a1a 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

Seems fine to me.  The indentation is a little odd (four spaces vs tabs)
but meh

Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>

--D

> +
> +    _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	[flat|nested] 13+ messages in thread

* Re: [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-12  1:57 ` [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
@ 2025-06-12  4:04   ` Darrick J. Wong
  2025-06-12 23:15     ` Catherine Hoang
  2025-06-12  6:59   ` Ojaswin Mujoo
  2025-06-12  7:06   ` Ojaswin Mujoo
  2 siblings, 1 reply; 13+ messages in thread
From: Darrick J. Wong @ 2025-06-12  4:04 UTC (permalink / raw)
  To: Catherine Hoang; +Cc: linux-xfs, fstests, john.g.garry, ritesh.list, ojaswin

On Wed, Jun 11, 2025 at 06:57:07PM -0700, Catherine Hoang wrote:
> 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>

Since this came from me originally, the first line of the commit message
should have a from header to make it explicit that I wrote it (and hence
have the first SOB):

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

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

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
<end of commit message>

> ---
>  common/atomicwrites    |  10 ++++
>  tests/generic/1222     |  89 ++++++++++++++++++++++++++++
>  tests/generic/1222.out |  10 ++++
>  tests/generic/1223     |  67 +++++++++++++++++++++
>  tests/generic/1223.out |   9 +++
>  tests/generic/1224     |  86 +++++++++++++++++++++++++++
>  tests/generic/1224.out |  16 ++++++
>  tests/generic/1225     | 128 +++++++++++++++++++++++++++++++++++++++++
>  tests/generic/1225.out |  21 +++++++

Zorro: Do you care about making people submit one test per patch?  IMO
it's easier on code authors to add similar tests in one big email
because then it's easier to add small changes across all the new tests
instead of looping in <push><edit><commit><repeat>.

--D

>  9 files changed, 436 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 88f49a1a..4ba945ec 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..d3665d0b
> --- /dev/null
> +++ b/tests/generic/1222
> @@ -0,0 +1,89 @@
> +#! /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
> +	_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"
> +_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..e0b6f0a1
> --- /dev/null
> +++ b/tests/generic/1223
> @@ -0,0 +1,67 @@
> +#! /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
> +	_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/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..f2dea804
> --- /dev/null
> +++ b/tests/generic/1225
> @@ -0,0 +1,128 @@
> +#! /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
> +_require_xfs_io_command pwrite -A
> +
> +_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"
> +
> +# 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=128K count=3 conv=fsync >>$seqres.full 2>&1
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 262144 262144" $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..92302597
> --- /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
> +75572c4929fde8faf131e84df4c6a764  SCRATCH_MNT/file1
> +atomic write preallocated region
> +27a248351cd540bc9ac2c2dc841abca2  SCRATCH_MNT/file1
> +atomic write max size on fragmented fs
> +27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
> -- 
> 2.34.1
> 
> 

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

* Re: [PATCH v4 1/3] common/atomicwrites: add helper for multi block atomic writes
  2025-06-12  1:57 ` [PATCH v4 1/3] common/atomicwrites: add helper for multi block atomic writes Catherine Hoang
  2025-06-12  4:01   ` Darrick J. Wong
@ 2025-06-12  6:31   ` Ojaswin Mujoo
  1 sibling, 0 replies; 13+ messages in thread
From: Ojaswin Mujoo @ 2025-06-12  6:31 UTC (permalink / raw)
  To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list

On Wed, Jun 11, 2025 at 06:57:06PM -0700, Catherine Hoang wrote:
> 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>
> ---
>  common/atomicwrites | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/common/atomicwrites b/common/atomicwrites
> index 391bb6f6..88f49a1a 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"
> +}
> +

Thanks for adding the helper. Looks good, feel free to add:

Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>

>  _require_scratch_write_atomic()
>  {
>  	_require_scratch
> -- 
> 2.34.1
> 

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

* Re: [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-12  1:57 ` [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
  2025-06-12  4:04   ` Darrick J. Wong
@ 2025-06-12  6:59   ` Ojaswin Mujoo
  2025-06-12 23:19     ` Catherine Hoang
  2025-06-12  7:06   ` Ojaswin Mujoo
  2 siblings, 1 reply; 13+ messages in thread
From: Ojaswin Mujoo @ 2025-06-12  6:59 UTC (permalink / raw)
  To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list

On Wed, Jun 11, 2025 at 06:57:07PM -0700, Catherine Hoang wrote:
> 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>

Hi Catherine, Darrick,

The tests looks mostly okay. Just a few minor comments I've added below:

> ---
>  common/atomicwrites    |  10 ++++
>  tests/generic/1222     |  89 ++++++++++++++++++++++++++++
>  tests/generic/1222.out |  10 ++++
>  tests/generic/1223     |  67 +++++++++++++++++++++
>  tests/generic/1223.out |   9 +++
>  tests/generic/1224     |  86 +++++++++++++++++++++++++++
>  tests/generic/1224.out |  16 ++++++
>  tests/generic/1225     | 128 +++++++++++++++++++++++++++++++++++++++++
>  tests/generic/1225.out |  21 +++++++
>  9 files changed, 436 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 88f49a1a..4ba945ec 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..d3665d0b
> --- /dev/null
> +++ b/tests/generic/1222
> @@ -0,0 +1,89 @@

<snip>

> +
> +$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
> +	_simple_atomic_write $i $i $testfile -d

I'm still not sure what extra thing this _simple_atomic_write is testing
here that is not already tested via _test_atomic_file_writes? (same
question for g/1223 as well)

> +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
> +

<snip>

> new file mode 100755
> index 00000000..f2dea804
> --- /dev/null
> +++ b/tests/generic/1225
> @@ -0,0 +1,128 @@
> +#! /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

I think we are not using reflink based helpers here so this can be
dropped.


<snip>

> +
> +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

Thanks for adding more unwritten based combinations :) 

Rest everything looks okay to me.

Regards,
ojaswin

<snip>

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

* Re: [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-12  1:57 ` [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
  2025-06-12  4:04   ` Darrick J. Wong
  2025-06-12  6:59   ` Ojaswin Mujoo
@ 2025-06-12  7:06   ` Ojaswin Mujoo
  2025-06-12 23:24     ` Catherine Hoang
  2 siblings, 1 reply; 13+ messages in thread
From: Ojaswin Mujoo @ 2025-06-12  7:06 UTC (permalink / raw)
  To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list

On Wed, Jun 11, 2025 at 06:57:07PM -0700, Catherine Hoang wrote:
> 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>
> ---

<snip>

Okay after running some of these tests on my setup, I have a few
more questions regarding g/1225.

> diff --git a/tests/generic/1225 b/tests/generic/1225
> new file mode 100755
> index 00000000..f2dea804
> --- /dev/null
> +++ b/tests/generic/1225
> @@ -0,0 +1,128 @@
> +#! /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
> +_require_xfs_io_command pwrite -A

I think this is already covered in _require_atomic_write_test_commands

> +
> +_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"

Is it possible to keep the max_awu requirement to maybe 64k? The reason
I'm asking is that in 4k bs ext4 with bigalloc, having cluster size more
than 64k is actually experimental so I don't think many people would be
formatting with 256k cluster size and would miss out on running this
test. Infact if i do set the cluster size to 256k I'm running into
enospc in the last enospc scenario of this test, whereas 64k works
correctly).

So just wondering if we can have an awu_max of 64k here so that more
people are easily able to run this in their setups?

Regards,
ojaswin

<snip>

> +
> +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..92302597
> --- /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
> +75572c4929fde8faf131e84df4c6a764  SCRATCH_MNT/file1
> +atomic write preallocated region
> +27a248351cd540bc9ac2c2dc841abca2  SCRATCH_MNT/file1
> +atomic write max size on fragmented fs
> +27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
> -- 
> 2.34.1
> 

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

* Re: [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-12  4:04   ` Darrick J. Wong
@ 2025-06-12 23:15     ` Catherine Hoang
  0 siblings, 0 replies; 13+ messages in thread
From: Catherine Hoang @ 2025-06-12 23:15 UTC (permalink / raw)
  To: Darrick J. Wong
  Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org, John Garry,
	ritesh.list@gmail.com, ojaswin@linux.ibm.com


> On Jun 11, 2025, at 9:04 PM, Darrick J. Wong <djwong@kernel.org> wrote:
> 
> On Wed, Jun 11, 2025 at 06:57:07PM -0700, Catherine Hoang wrote:
>> 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>
> 
> Since this came from me originally, the first line of the commit message
> should have a from header to make it explicit that I wrote it (and hence
> have the first SOB):

Ah I see, I didn’t realize the significance of that first line. I guess the
original author wasn’t preserved when I did a git reset so I could
separate the original patch into two separate commits. I’ll get that
fixed in the next version, thanks!
> 
> From: Darrick J. Wong <djwong@kernel.org>
> 
> Simple tests of various atomic write requests and a (simulated) hardware
> device.
> <snip>
> 
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> <end of commit message>
> 
>> ---
>> common/atomicwrites    |  10 ++++
>> tests/generic/1222     |  89 ++++++++++++++++++++++++++++
>> tests/generic/1222.out |  10 ++++
>> tests/generic/1223     |  67 +++++++++++++++++++++
>> tests/generic/1223.out |   9 +++
>> tests/generic/1224     |  86 +++++++++++++++++++++++++++
>> tests/generic/1224.out |  16 ++++++
>> tests/generic/1225     | 128 +++++++++++++++++++++++++++++++++++++++++
>> tests/generic/1225.out |  21 +++++++
> 
> Zorro: Do you care about making people submit one test per patch?  IMO
> it's easier on code authors to add similar tests in one big email
> because then it's easier to add small changes across all the new tests
> instead of looping in <push><edit><commit><repeat>.
> 
> --D
> 
>> 9 files changed, 436 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 88f49a1a..4ba945ec 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..d3665d0b
>> --- /dev/null
>> +++ b/tests/generic/1222
>> @@ -0,0 +1,89 @@
>> +#! /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
>> + _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"
>> +_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..e0b6f0a1
>> --- /dev/null
>> +++ b/tests/generic/1223
>> @@ -0,0 +1,67 @@
>> +#! /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
>> + _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/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..f2dea804
>> --- /dev/null
>> +++ b/tests/generic/1225
>> @@ -0,0 +1,128 @@
>> +#! /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
>> +_require_xfs_io_command pwrite -A
>> +
>> +_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"
>> +
>> +# 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=128K count=3 conv=fsync >>$seqres.full 2>&1
>> +$XFS_IO_PROG -dc "pwrite -A -D -V1 262144 262144" $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..92302597
>> --- /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
>> +75572c4929fde8faf131e84df4c6a764  SCRATCH_MNT/file1
>> +atomic write preallocated region
>> +27a248351cd540bc9ac2c2dc841abca2  SCRATCH_MNT/file1
>> +atomic write max size on fragmented fs
>> +27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
>> -- 
>> 2.34.1



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

* Re: [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-12  6:59   ` Ojaswin Mujoo
@ 2025-06-12 23:19     ` Catherine Hoang
  0 siblings, 0 replies; 13+ messages in thread
From: Catherine Hoang @ 2025-06-12 23:19 UTC (permalink / raw)
  To: Ojaswin Mujoo
  Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org,
	djwong@kernel.org, John Garry, ritesh.list@gmail.com

> On Jun 11, 2025, at 11:59 PM, Ojaswin Mujoo <ojaswin@linux.ibm.com> wrote:
> 
> On Wed, Jun 11, 2025 at 06:57:07PM -0700, Catherine Hoang wrote:
>> 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>
> 
> Hi Catherine, Darrick,
> 
> The tests looks mostly okay. Just a few minor comments I've added below:
> 
>> ---
>> common/atomicwrites    |  10 ++++
>> tests/generic/1222     |  89 ++++++++++++++++++++++++++++
>> tests/generic/1222.out |  10 ++++
>> tests/generic/1223     |  67 +++++++++++++++++++++
>> tests/generic/1223.out |   9 +++
>> tests/generic/1224     |  86 +++++++++++++++++++++++++++
>> tests/generic/1224.out |  16 ++++++
>> tests/generic/1225     | 128 +++++++++++++++++++++++++++++++++++++++++
>> tests/generic/1225.out |  21 +++++++
>> 9 files changed, 436 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 88f49a1a..4ba945ec 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..d3665d0b
>> --- /dev/null
>> +++ b/tests/generic/1222
>> @@ -0,0 +1,89 @@
> 
> <snip>
> 
>> +
>> +$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
>> + _simple_atomic_write $i $i $testfile -d
> 
> I'm still not sure what extra thing this _simple_atomic_write is testing
> here that is not already tested via _test_atomic_file_writes? (same
> question for g/1223 as well)

I think you’re right, the only difference I see is that _simple_atomic_write
accepts a pos argument while _test_atomic_file_writes doesn’t. But
since _test_atomic_file_writes already does a broader range of tests I
don’t think _simple_atomic_write is necessary, so I can remove that.
> 
>> +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
>> +
> 
> <snip>
> 
>> new file mode 100755
>> index 00000000..f2dea804
>> --- /dev/null
>> +++ b/tests/generic/1225
>> @@ -0,0 +1,128 @@
>> +#! /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
> 
> I think we are not using reflink based helpers here so this can be
> dropped.
> 
> 
> <snip>
> 
>> +
>> +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
> 
> Thanks for adding more unwritten based combinations :) 
> 
> Rest everything looks okay to me.
> 
> Regards,
> ojaswin
> 
> <snip>



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

* Re: [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-12  7:06   ` Ojaswin Mujoo
@ 2025-06-12 23:24     ` Catherine Hoang
  2025-06-13  5:17       ` Ojaswin Mujoo
  0 siblings, 1 reply; 13+ messages in thread
From: Catherine Hoang @ 2025-06-12 23:24 UTC (permalink / raw)
  To: Ojaswin Mujoo
  Cc: linux-xfs@vger.kernel.org, fstests@vger.kernel.org,
	djwong@kernel.org, John Garry, ritesh.list@gmail.com


> On Jun 12, 2025, at 12:06 AM, Ojaswin Mujoo <ojaswin@linux.ibm.com> wrote:
> 
> On Wed, Jun 11, 2025 at 06:57:07PM -0700, Catherine Hoang wrote:
>> 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>
>> ---
> 
> <snip>
> 
> Okay after running some of these tests on my setup, I have a few
> more questions regarding g/1225.
> 
>> diff --git a/tests/generic/1225 b/tests/generic/1225
>> new file mode 100755
>> index 00000000..f2dea804
>> --- /dev/null
>> +++ b/tests/generic/1225
>> @@ -0,0 +1,128 @@
>> +#! /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
>> +_require_xfs_io_command pwrite -A
> 
> I think this is already covered in _require_atomic_write_test_commands
> 
>> +
>> +_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"
> 
> Is it possible to keep the max_awu requirement to maybe 64k? The reason
> I'm asking is that in 4k bs ext4 with bigalloc, having cluster size more
> than 64k is actually experimental so I don't think many people would be
> formatting with 256k cluster size and would miss out on running this
> test. Infact if i do set the cluster size to 256k I'm running into
> enospc in the last enospc scenario of this test, whereas 64k works
> correctly).
> 
> So just wondering if we can have an awu_max of 64k here so that more
> people are easily able to run this in their setups?

Yes, this can be changed to 64k. I think only one of the tests need
256k writes, but it looks like that can be changed to 64k as well.
Thanks for the comments!
> 
> 
> 
> Regards,
> ojaswin
> 
> <snip>
> 
>> +
>> +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..92302597
>> --- /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
>> +75572c4929fde8faf131e84df4c6a764  SCRATCH_MNT/file1
>> +atomic write preallocated region
>> +27a248351cd540bc9ac2c2dc841abca2  SCRATCH_MNT/file1
>> +atomic write max size on fragmented fs
>> +27c9068d1b51da575a53ad34c57ca5cc  SCRATCH_MNT/file3
>> -- 
>> 2.34.1



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

* Re: [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug
  2025-06-12 23:24     ` Catherine Hoang
@ 2025-06-13  5:17       ` Ojaswin Mujoo
  0 siblings, 0 replies; 13+ messages in thread
From: Ojaswin Mujoo @ 2025-06-13  5:17 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

On Thu, Jun 12, 2025 at 11:24:34PM +0000, Catherine Hoang wrote:
> 
> > On Jun 12, 2025, at 12:06 AM, Ojaswin Mujoo <ojaswin@linux.ibm.com> wrote:
> > 
> > On Wed, Jun 11, 2025 at 06:57:07PM -0700, Catherine Hoang wrote:
> >> 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>
> >> ---
> > 
> > <snip>
> > 
> > Okay after running some of these tests on my setup, I have a few
> > more questions regarding g/1225.
> > 
> >> diff --git a/tests/generic/1225 b/tests/generic/1225
> >> new file mode 100755
> >> index 00000000..f2dea804
> >> --- /dev/null
> >> +++ b/tests/generic/1225
> >> @@ -0,0 +1,128 @@
> >> +#! /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
> >> +_require_xfs_io_command pwrite -A
> > 
> > I think this is already covered in _require_atomic_write_test_commands
> > 
> >> +
> >> +_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"
> > 
> > Is it possible to keep the max_awu requirement to maybe 64k? The reason
> > I'm asking is that in 4k bs ext4 with bigalloc, having cluster size more
> > than 64k is actually experimental so I don't think many people would be
> > formatting with 256k cluster size and would miss out on running this
> > test. Infact if i do set the cluster size to 256k I'm running into
> > enospc in the last enospc scenario of this test, whereas 64k works
> > correctly).
> > 
> > So just wondering if we can have an awu_max of 64k here so that more
> > people are easily able to run this in their setups?
> 
> Yes, this can be changed to 64k. I think only one of the tests need
> 256k writes, but it looks like that can be changed to 64k as well.
> Thanks for the comments!

Awesome, thanks!

Regards,
ojaswin

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

end of thread, other threads:[~2025-06-13  5:17 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-12  1:57 [PATCH v4 0/3] atomic writes tests (part 2) Catherine Hoang
2025-06-12  1:57 ` [PATCH v4 1/3] common/atomicwrites: add helper for multi block atomic writes Catherine Hoang
2025-06-12  4:01   ` Darrick J. Wong
2025-06-12  6:31   ` Ojaswin Mujoo
2025-06-12  1:57 ` [PATCH v4 2/3] generic: various atomic write tests with hardware and scsi_debug Catherine Hoang
2025-06-12  4:04   ` Darrick J. Wong
2025-06-12 23:15     ` Catherine Hoang
2025-06-12  6:59   ` Ojaswin Mujoo
2025-06-12 23:19     ` Catherine Hoang
2025-06-12  7:06   ` Ojaswin Mujoo
2025-06-12 23:24     ` Catherine Hoang
2025-06-13  5:17       ` Ojaswin Mujoo
2025-06-12  1:57 ` [PATCH v4 3/3] xfs: more multi-block atomic writes tests Catherine Hoang

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).