* [PATCH v2 0/6] atomic writes tests
@ 2025-05-20 1:33 Catherine Hoang
2025-05-20 1:33 ` [PATCH v2 1/6] generic/765: fix a few issues Catherine Hoang
` (5 more replies)
0 siblings, 6 replies; 19+ messages in thread
From: Catherine Hoang @ 2025-05-20 1:33 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list
Hi all,
Now that large atomic writes has been queued up, here's a series of tests
for this new feature. The first few patches make various adjustments to the
existing single block atomic writes test, as well as setup for additional
testing. The last patch adds several new tests for large atomic writes with
actual and simulated hardware.
This series is based on for-next at the time of sending.
Only patch 1 and 6 were changed since v1.
Darrick J. Wong (6):
generic/765: fix a few issues
generic/765: adjust various things
generic/765: move common atomic write code to a library file
common/atomicwrites: adjust a few more things
common/atomicwrites: fix _require_scratch_write_atomic
generic: various atomic write tests with scsi_debug
common/atomicwrites | 127 +++++++++++++++++++++++++++++++++++++
common/rc | 49 +--------------
doc/group-names.txt | 1 +
tests/generic/1222 | 86 +++++++++++++++++++++++++
tests/generic/1222.out | 10 +++
tests/generic/1223 | 66 +++++++++++++++++++
tests/generic/1223.out | 9 +++
tests/generic/1224 | 140 +++++++++++++++++++++++++++++++++++++++++
tests/generic/1224.out | 17 +++++
tests/generic/765 | 84 +++++++++----------------
tests/xfs/1216 | 67 ++++++++++++++++++++
tests/xfs/1216.out | 9 +++
tests/xfs/1217 | 70 +++++++++++++++++++++
tests/xfs/1217.out | 3 +
tests/xfs/1218 | 59 +++++++++++++++++
tests/xfs/1218.out | 15 +++++
16 files changed, 710 insertions(+), 102 deletions(-)
create mode 100644 common/atomicwrites
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 100644 tests/generic/1224
create mode 100644 tests/generic/1224.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 100644 tests/xfs/1218
create mode 100644 tests/xfs/1218.out
--
2.34.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v2 1/6] generic/765: fix a few issues
2025-05-20 1:33 [PATCH v2 0/6] atomic writes tests Catherine Hoang
@ 2025-05-20 1:33 ` Catherine Hoang
2025-05-20 2:10 ` Ritesh Harjani
2025-05-22 10:14 ` Ojaswin Mujoo
2025-05-20 1:33 ` [PATCH v2 2/6] generic/765: adjust various things Catherine Hoang
` (4 subsequent siblings)
5 siblings, 2 replies; 19+ messages in thread
From: Catherine Hoang @ 2025-05-20 1:33 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list
From: "Darrick J. Wong" <djwong@kernel.org>
Fix a few bugs in the single block atomic writes test, such as not requiring
directio, using the page size for the ext4 max bsize, and making sure we check
the max atomic write size.
Cc: ritesh.list@gmail.com
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
common/rc | 2 +-
tests/generic/765 | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/rc b/common/rc
index 657772e7..0ac90d3e 100644
--- a/common/rc
+++ b/common/rc
@@ -2989,7 +2989,7 @@ _require_xfs_io_command()
fi
if [ "$param" == "-A" ]; then
opts+=" -d"
- pwrite_opts+="-D -V 1 -b 4k"
+ pwrite_opts+="-V 1 -b 4k"
fi
testio=`$XFS_IO_PROG -f $opts -c \
"pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
diff --git a/tests/generic/765 b/tests/generic/765
index 9bab3b8a..8695a306 100755
--- a/tests/generic/765
+++ b/tests/generic/765
@@ -28,7 +28,7 @@ get_supported_bsize()
;;
"ext4")
min_bsize=1024
- max_bsize=4096
+ max_bsize=$(_get_page_size)
;;
*)
_notrun "$FSTYP does not support atomic writes"
@@ -73,7 +73,7 @@ test_atomic_writes()
# Check that atomic min/max = FS block size
test $file_min_write -eq $bsize || \
echo "atomic write min $file_min_write, should be fs block size $bsize"
- test $file_min_write -eq $bsize || \
+ test $file_max_write -eq $bsize || \
echo "atomic write max $file_max_write, should be fs block size $bsize"
test $file_max_segments -eq 1 || \
echo "atomic write max segments $file_max_segments, should be 1"
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 2/6] generic/765: adjust various things
2025-05-20 1:33 [PATCH v2 0/6] atomic writes tests Catherine Hoang
2025-05-20 1:33 ` [PATCH v2 1/6] generic/765: fix a few issues Catherine Hoang
@ 2025-05-20 1:33 ` Catherine Hoang
2025-05-22 10:14 ` Ojaswin Mujoo
2025-05-20 1:33 ` [PATCH v2 3/6] generic/765: move common atomic write code to a library file Catherine Hoang
` (3 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Catherine Hoang @ 2025-05-20 1:33 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list
From: "Darrick J. Wong" <djwong@kernel.org>
Fix some bugs when detecting the atomic write geometry, record what
atomic write geometry we're testing each time through the loop, and
create a group for atomic writes tests.
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>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
common/rc | 4 ++--
doc/group-names.txt | 1 +
tests/generic/765 | 25 ++++++++++++++++++++++++-
3 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/common/rc b/common/rc
index 0ac90d3e..261fa72a 100644
--- a/common/rc
+++ b/common/rc
@@ -5442,13 +5442,13 @@ _get_atomic_write_unit_min()
_get_atomic_write_unit_max()
{
$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep atomic_write_unit_max | grep -o '[0-9]\+'
+ grep -w atomic_write_unit_max | grep -o '[0-9]\+'
}
_get_atomic_write_segments_max()
{
$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep atomic_write_segments_max | grep -o '[0-9]\+'
+ grep -w atomic_write_segments_max | grep -o '[0-9]\+'
}
_require_scratch_write_atomic()
diff --git a/doc/group-names.txt b/doc/group-names.txt
index f510bb82..1b38f73b 100644
--- a/doc/group-names.txt
+++ b/doc/group-names.txt
@@ -12,6 +12,7 @@ acl Access Control Lists
admin xfs_admin functionality
aio general libaio async io tests
atime file access time
+atomicwrites RWF_ATOMIC testing
attr extended attributes
attr2 xfs v2 extended aributes
balance btrfs tree rebalance
diff --git a/tests/generic/765 b/tests/generic/765
index 8695a306..84381730 100755
--- a/tests/generic/765
+++ b/tests/generic/765
@@ -7,7 +7,7 @@
# Validate atomic write support
#
. ./common/preamble
-_begin_fstest auto quick rw
+_begin_fstest auto quick rw atomicwrites
_require_scratch_write_atomic
_require_xfs_io_command pwrite -A
@@ -34,6 +34,10 @@ get_supported_bsize()
_notrun "$FSTYP does not support atomic writes"
;;
esac
+
+ echo "fs config ------------" >> $seqres.full
+ echo "min_bsize $min_bsize" >> $seqres.full
+ echo "max_bsize $max_bsize" >> $seqres.full
}
get_mkfs_opts()
@@ -70,6 +74,11 @@ test_atomic_writes()
file_max_write=$(_get_atomic_write_unit_max $testfile)
file_max_segments=$(_get_atomic_write_segments_max $testfile)
+ echo "test $bsize --------------" >> $seqres.full
+ echo "file awu_min $file_min_write" >> $seqres.full
+ echo "file awu_max $file_max_write" >> $seqres.full
+ echo "file awu_segments $file_max_segments" >> $seqres.full
+
# Check that atomic min/max = FS block size
test $file_min_write -eq $bsize || \
echo "atomic write min $file_min_write, should be fs block size $bsize"
@@ -145,6 +154,15 @@ test_atomic_write_bounds()
testfile=$SCRATCH_MNT/testfile
touch $testfile
+ file_min_write=$(_get_atomic_write_unit_min $testfile)
+ file_max_write=$(_get_atomic_write_unit_max $testfile)
+ file_max_segments=$(_get_atomic_write_segments_max $testfile)
+
+ echo "test awb $bsize --------------" >> $seqres.full
+ echo "file awu_min $file_min_write" >> $seqres.full
+ echo "file awu_max $file_max_write" >> $seqres.full
+ echo "file awu_segments $file_max_segments" >> $seqres.full
+
$XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
echo "atomic write should fail when bsize is out of bounds"
@@ -157,6 +175,11 @@ sys_max_write=$(cat "/sys/block/$(_short_dev $SCRATCH_DEV)/queue/atomic_write_un
bdev_min_write=$(_get_atomic_write_unit_min $SCRATCH_DEV)
bdev_max_write=$(_get_atomic_write_unit_max $SCRATCH_DEV)
+echo "sysfs awu_min $sys_min_write" >> $seqres.full
+echo "sysfs awu_min $sys_max_write" >> $seqres.full
+echo "bdev awu_min $bdev_min_write" >> $seqres.full
+echo "bdev awu_min $bdev_max_write" >> $seqres.full
+
# Test that statx atomic values are the same as sysfs values
if [ "$sys_min_write" -ne "$bdev_min_write" ]; then
echo "bdev min write != sys min write"
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 3/6] generic/765: move common atomic write code to a library file
2025-05-20 1:33 [PATCH v2 0/6] atomic writes tests Catherine Hoang
2025-05-20 1:33 ` [PATCH v2 1/6] generic/765: fix a few issues Catherine Hoang
2025-05-20 1:33 ` [PATCH v2 2/6] generic/765: adjust various things Catherine Hoang
@ 2025-05-20 1:33 ` Catherine Hoang
2025-05-22 10:26 ` Ojaswin Mujoo
2025-05-20 1:33 ` [PATCH v2 4/6] common/atomicwrites: adjust a few more things Catherine Hoang
` (2 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Catherine Hoang @ 2025-05-20 1:33 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list
From: "Darrick J. Wong" <djwong@kernel.org>
Move the common atomic writes code to common/atomic so we can share
them.
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>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
common/atomicwrites | 111 ++++++++++++++++++++++++++++++++++++++++++++
common/rc | 47 -------------------
tests/generic/765 | 53 ++-------------------
3 files changed, 114 insertions(+), 97 deletions(-)
create mode 100644 common/atomicwrites
diff --git a/common/atomicwrites b/common/atomicwrites
new file mode 100644
index 00000000..fd3a9b71
--- /dev/null
+++ b/common/atomicwrites
@@ -0,0 +1,111 @@
+##/bin/bash
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# Routines for testing atomic writes.
+
+_get_atomic_write_unit_min()
+{
+ $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
+ grep atomic_write_unit_min | grep -o '[0-9]\+'
+}
+
+_get_atomic_write_unit_max()
+{
+ $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
+ grep -w atomic_write_unit_max | grep -o '[0-9]\+'
+}
+
+_get_atomic_write_segments_max()
+{
+ $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
+ grep -w atomic_write_segments_max | grep -o '[0-9]\+'
+}
+
+_require_scratch_write_atomic()
+{
+ _require_scratch
+
+ export STATX_WRITE_ATOMIC=0x10000
+
+ awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
+ awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
+
+ if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
+ _notrun "write atomic not supported by this block device"
+ fi
+
+ _scratch_mkfs > /dev/null 2>&1
+ _scratch_mount
+
+ testfile=$SCRATCH_MNT/testfile
+ touch $testfile
+
+ awu_min_fs=$(_get_atomic_write_unit_min $testfile)
+ awu_max_fs=$(_get_atomic_write_unit_max $testfile)
+
+ _scratch_unmount
+
+ if [ $awu_min_fs -eq 0 ] && [ $awu_max_fs -eq 0 ]; then
+ _notrun "write atomic not supported by this filesystem"
+ fi
+}
+
+_test_atomic_file_writes()
+{
+ local bsize="$1"
+ local testfile="$2"
+ local bytes_written
+ local testfile_cp="$testfile.copy"
+
+ # Check that we can perform an atomic write of len = FS block size
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
+
+ # Check that we can perform an atomic single-block cow write
+ if [ "$FSTYP" == "xfs" ]; then
+ testfile_cp=$SCRATCH_MNT/testfile_copy
+ if _xfs_has_feature $SCRATCH_MNT reflink; then
+ cp --reflink $testfile $testfile_cp
+ fi
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
+ fi
+
+ # Check that we can perform an atomic write on an unwritten block
+ $XFS_IO_PROG -c "falloc $bsize $bsize" $testfile
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize $bsize $bsize" $testfile | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write to unwritten block failed"
+
+ # Check that we can perform an atomic write on a sparse hole
+ $XFS_IO_PROG -c "fpunch 0 $bsize" $testfile
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write to sparse hole failed"
+
+ # Check that we can perform an atomic write on a fully mapped block
+ bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
+ grep wrote | awk -F'[/ ]' '{print $2}')
+ test $bytes_written -eq $bsize || echo "atomic write to mapped block failed"
+
+ # Reject atomic write if len is out of bounds
+ $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize - 1))" $testfile 2>> $seqres.full && \
+ echo "atomic write len=$((bsize - 1)) should fail"
+ $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize + 1))" $testfile 2>> $seqres.full && \
+ echo "atomic write len=$((bsize + 1)) should fail"
+
+ # Reject atomic write when iovecs > 1
+ $XFS_IO_PROG -dc "pwrite -A -D -V2 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
+ echo "atomic write only supports iovec count of 1"
+
+ # Reject atomic write when not using direct I/O
+ $XFS_IO_PROG -c "pwrite -A -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
+ echo "atomic write requires direct I/O"
+
+ # Reject atomic write when offset % bsize != 0
+ $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"
+}
diff --git a/common/rc b/common/rc
index 261fa72a..e5e53145 100644
--- a/common/rc
+++ b/common/rc
@@ -5433,53 +5433,6 @@ _require_scratch_btime()
_scratch_unmount
}
-_get_atomic_write_unit_min()
-{
- $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep atomic_write_unit_min | grep -o '[0-9]\+'
-}
-
-_get_atomic_write_unit_max()
-{
- $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep -w atomic_write_unit_max | grep -o '[0-9]\+'
-}
-
-_get_atomic_write_segments_max()
-{
- $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
- grep -w atomic_write_segments_max | grep -o '[0-9]\+'
-}
-
-_require_scratch_write_atomic()
-{
- _require_scratch
-
- export STATX_WRITE_ATOMIC=0x10000
-
- awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
- awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
-
- if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
- _notrun "write atomic not supported by this block device"
- fi
-
- _scratch_mkfs > /dev/null 2>&1
- _scratch_mount
-
- testfile=$SCRATCH_MNT/testfile
- touch $testfile
-
- awu_min_fs=$(_get_atomic_write_unit_min $testfile)
- awu_max_fs=$(_get_atomic_write_unit_max $testfile)
-
- _scratch_unmount
-
- if [ $awu_min_fs -eq 0 ] && [ $awu_max_fs -eq 0 ]; then
- _notrun "write atomic not supported by this filesystem"
- fi
-}
-
_require_inode_limits()
{
if [ $(_get_free_inode $TEST_DIR) -eq 0 ]; then
diff --git a/tests/generic/765 b/tests/generic/765
index 84381730..09e9fa38 100755
--- a/tests/generic/765
+++ b/tests/generic/765
@@ -9,6 +9,8 @@
. ./common/preamble
_begin_fstest auto quick rw atomicwrites
+. ./common/atomicwrites
+
_require_scratch_write_atomic
_require_xfs_io_command pwrite -A
@@ -87,56 +89,7 @@ test_atomic_writes()
test $file_max_segments -eq 1 || \
echo "atomic write max segments $file_max_segments, should be 1"
- # Check that we can perform an atomic write of len = FS block size
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
-
- # Check that we can perform an atomic single-block cow write
- if [ "$FSTYP" == "xfs" ]; then
- testfile_cp=$SCRATCH_MNT/testfile_copy
- if _xfs_has_feature $SCRATCH_MNT reflink; then
- cp --reflink $testfile $testfile_cp
- fi
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
- fi
-
- # Check that we can perform an atomic write on an unwritten block
- $XFS_IO_PROG -c "falloc $bsize $bsize" $testfile
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize $bsize $bsize" $testfile | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write to unwritten block failed"
-
- # Check that we can perform an atomic write on a sparse hole
- $XFS_IO_PROG -c "fpunch 0 $bsize" $testfile
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write to sparse hole failed"
-
- # Check that we can perform an atomic write on a fully mapped block
- bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
- grep wrote | awk -F'[/ ]' '{print $2}')
- test $bytes_written -eq $bsize || echo "atomic write to mapped block failed"
-
- # Reject atomic write if len is out of bounds
- $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize - 1))" $testfile 2>> $seqres.full && \
- echo "atomic write len=$((bsize - 1)) should fail"
- $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $((bsize + 1))" $testfile 2>> $seqres.full && \
- echo "atomic write len=$((bsize + 1)) should fail"
-
- # Reject atomic write when iovecs > 1
- $XFS_IO_PROG -dc "pwrite -A -D -V2 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
- echo "atomic write only supports iovec count of 1"
-
- # Reject atomic write when not using direct I/O
- $XFS_IO_PROG -c "pwrite -A -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
- echo "atomic write requires direct I/O"
-
- # Reject atomic write when offset % bsize != 0
- $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"
+ _test_atomic_file_writes "$bsize" "$testfile"
_scratch_unmount
}
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 4/6] common/atomicwrites: adjust a few more things
2025-05-20 1:33 [PATCH v2 0/6] atomic writes tests Catherine Hoang
` (2 preceding siblings ...)
2025-05-20 1:33 ` [PATCH v2 3/6] generic/765: move common atomic write code to a library file Catherine Hoang
@ 2025-05-20 1:33 ` Catherine Hoang
2025-05-22 10:37 ` Ojaswin Mujoo
2025-05-20 1:33 ` [PATCH v2 5/6] common/atomicwrites: fix _require_scratch_write_atomic Catherine Hoang
2025-05-20 1:34 ` [PATCH v2 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
5 siblings, 1 reply; 19+ messages in thread
From: Catherine Hoang @ 2025-05-20 1:33 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list
From: "Darrick J. Wong" <djwong@kernel.org>
Always export STATX_WRITE_ATOMIC so anyone can use it, make the "cp
reflink" logic work for any filesystem, not just xfs, and create a
separate helper to check that the necessary xfs_io support is present.
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>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
---
common/atomicwrites | 18 +++++++++++-------
tests/generic/765 | 2 +-
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/common/atomicwrites b/common/atomicwrites
index fd3a9b71..9ec1ca68 100644
--- a/common/atomicwrites
+++ b/common/atomicwrites
@@ -4,6 +4,8 @@
#
# Routines for testing atomic writes.
+export STATX_WRITE_ATOMIC=0x10000
+
_get_atomic_write_unit_min()
{
$XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
@@ -26,8 +28,6 @@ _require_scratch_write_atomic()
{
_require_scratch
- export STATX_WRITE_ATOMIC=0x10000
-
awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
@@ -51,6 +51,14 @@ _require_scratch_write_atomic()
fi
}
+# Check for xfs_io commands required to run _test_atomic_file_writes
+_require_atomic_write_test_commands()
+{
+ _require_xfs_io_command "falloc"
+ _require_xfs_io_command "fpunch"
+ _require_xfs_io_command pwrite -A
+}
+
_test_atomic_file_writes()
{
local bsize="$1"
@@ -64,11 +72,7 @@ _test_atomic_file_writes()
test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
# Check that we can perform an atomic single-block cow write
- if [ "$FSTYP" == "xfs" ]; then
- testfile_cp=$SCRATCH_MNT/testfile_copy
- if _xfs_has_feature $SCRATCH_MNT reflink; then
- cp --reflink $testfile $testfile_cp
- fi
+ if cp --reflink=always $testfile $testfile_cp 2>> $seqres.full; then
bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
grep wrote | awk -F'[/ ]' '{print $2}')
test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
diff --git a/tests/generic/765 b/tests/generic/765
index 09e9fa38..71604e5e 100755
--- a/tests/generic/765
+++ b/tests/generic/765
@@ -12,7 +12,7 @@ _begin_fstest auto quick rw atomicwrites
. ./common/atomicwrites
_require_scratch_write_atomic
-_require_xfs_io_command pwrite -A
+_require_atomic_write_test_commands
get_supported_bsize()
{
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 5/6] common/atomicwrites: fix _require_scratch_write_atomic
2025-05-20 1:33 [PATCH v2 0/6] atomic writes tests Catherine Hoang
` (3 preceding siblings ...)
2025-05-20 1:33 ` [PATCH v2 4/6] common/atomicwrites: adjust a few more things Catherine Hoang
@ 2025-05-20 1:33 ` Catherine Hoang
2025-05-20 2:14 ` Ritesh Harjani
2025-05-20 1:34 ` [PATCH v2 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
5 siblings, 1 reply; 19+ messages in thread
From: Catherine Hoang @ 2025-05-20 1:33 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list
From: "Darrick J. Wong" <djwong@kernel.org>
Fix this function to call _notrun whenever something fails. If we can't
figure out the atomic write geometry, then we haven't satisfied the
preconditions for the test.
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>
---
common/atomicwrites | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/common/atomicwrites b/common/atomicwrites
index 9ec1ca68..391bb6f6 100644
--- a/common/atomicwrites
+++ b/common/atomicwrites
@@ -28,21 +28,23 @@ _require_scratch_write_atomic()
{
_require_scratch
- awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
- awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
+ local awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
+ local awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
_notrun "write atomic not supported by this block device"
fi
- _scratch_mkfs > /dev/null 2>&1
- _scratch_mount
+ _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"
- testfile=$SCRATCH_MNT/testfile
+ local testfile=$SCRATCH_MNT/testfile
touch $testfile
- awu_min_fs=$(_get_atomic_write_unit_min $testfile)
- awu_max_fs=$(_get_atomic_write_unit_max $testfile)
+ local awu_min_fs=$(_get_atomic_write_unit_min $testfile)
+ local awu_max_fs=$(_get_atomic_write_unit_max $testfile)
_scratch_unmount
--
2.34.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH v2 6/6] generic: various atomic write tests with scsi_debug
2025-05-20 1:33 [PATCH v2 0/6] atomic writes tests Catherine Hoang
` (4 preceding siblings ...)
2025-05-20 1:33 ` [PATCH v2 5/6] common/atomicwrites: fix _require_scratch_write_atomic Catherine Hoang
@ 2025-05-20 1:34 ` Catherine Hoang
2025-05-20 12:05 ` Ritesh Harjani
` (2 more replies)
5 siblings, 3 replies; 19+ messages in thread
From: Catherine Hoang @ 2025-05-20 1:34 UTC (permalink / raw)
To: linux-xfs, fstests; +Cc: djwong, john.g.garry, ritesh.list
From: "Darrick J. Wong" <djwong@kernel.org>
Simple tests of various atomic write requests and a (simulated) hardware
device.
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
---
common/atomicwrites | 10 +++
tests/generic/1222 | 86 +++++++++++++++++++++++++
tests/generic/1222.out | 10 +++
tests/generic/1223 | 66 +++++++++++++++++++
tests/generic/1223.out | 9 +++
tests/generic/1224 | 140 +++++++++++++++++++++++++++++++++++++++++
tests/generic/1224.out | 17 +++++
tests/xfs/1216 | 67 ++++++++++++++++++++
tests/xfs/1216.out | 9 +++
tests/xfs/1217 | 70 +++++++++++++++++++++
tests/xfs/1217.out | 3 +
tests/xfs/1218 | 59 +++++++++++++++++
tests/xfs/1218.out | 15 +++++
13 files changed, 561 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 100644 tests/generic/1224
create mode 100644 tests/generic/1224.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 100644 tests/xfs/1218
create mode 100644 tests/xfs/1218.out
diff --git a/common/atomicwrites b/common/atomicwrites
index 391bb6f6..c75c3d39 100644
--- a/common/atomicwrites
+++ b/common/atomicwrites
@@ -115,3 +115,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..9d02bd70
--- /dev/null
+++ b/tests/generic/1222
@@ -0,0 +1,86 @@
+#! /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_atomic_write_test_commands
+
+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..8a77386e
--- /dev/null
+++ b/tests/generic/1223
@@ -0,0 +1,66 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1223
+#
+# Validate multi-fsblock atomic write support with or without hw support
+#
+. ./common/preamble
+_begin_fstest auto quick rw atomicwrites
+
+. ./common/atomicwrites
+
+_require_scratch
+_require_atomic_write_test_commands
+
+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 100644
index 00000000..fb178be4
--- /dev/null
+++ b/tests/generic/1224
@@ -0,0 +1,140 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2025 Oracle. All Rights Reserved.
+#
+# FS QA Test 1224
+#
+# test 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_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)
+
+# 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
+
+# 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
+
+# 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
+
+# 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
+
+# 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
+
+# non-reflink tests
+
+# 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
+
+# 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
+
+# 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
+
+# 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
+
+# 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 -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"
+#md5sum $file1 | _filter_scratch
+
+# 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/1224.out b/tests/generic/1224.out
new file mode 100644
index 00000000..1c788420
--- /dev/null
+++ b/tests/generic/1224.out
@@ -0,0 +1,17 @@
+QA output created by 1224
+111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
+111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
+111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
+111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
+f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
+4edfbc469bed9965219ea80c9ae54626 SCRATCH_MNT/file1
+93243a293a9f568903485b0b2a895815 SCRATCH_MNT/file2
+9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
+9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
+9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
+75572c4929fde8faf131e84df4c6a764 SCRATCH_MNT/file1
+27a248351cd540bc9ac2c2dc841abca2 SCRATCH_MNT/file1
+27c9068d1b51da575a53ad34c57ca5cc SCRATCH_MNT/file3
diff --git a/tests/xfs/1216 b/tests/xfs/1216
new file mode 100755
index 00000000..04aa77fe
--- /dev/null
+++ b/tests/xfs/1216
@@ -0,0 +1,67 @@
+#! /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
+
+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..0816d05f
--- /dev/null
+++ b/tests/xfs/1217
@@ -0,0 +1,70 @@
+#! /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_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 100644
index 00000000..f3682e42
--- /dev/null
+++ b/tests/xfs/1218
@@ -0,0 +1,59 @@
+#! /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_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 $testfile)
+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] 19+ messages in thread
* Re: [PATCH v2 1/6] generic/765: fix a few issues
2025-05-20 1:33 ` [PATCH v2 1/6] generic/765: fix a few issues Catherine Hoang
@ 2025-05-20 2:10 ` Ritesh Harjani
2025-05-22 10:14 ` Ojaswin Mujoo
1 sibling, 0 replies; 19+ messages in thread
From: Ritesh Harjani @ 2025-05-20 2:10 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, john.g.garry
Catherine Hoang <catherine.hoang@oracle.com> writes:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Fix a few bugs in the single block atomic writes test, such as not requiring
> directio, using the page size for the ext4 max bsize, and making sure we check
> the max atomic write size.
>
> Cc: ritesh.list@gmail.com
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> ---
> common/rc | 2 +-
> tests/generic/765 | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
Thanks for fixing this for 64k pagesize.
Looks good to me. Please feel free to add:
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
>
> diff --git a/common/rc b/common/rc
> index 657772e7..0ac90d3e 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
> fi
> if [ "$param" == "-A" ]; then
> opts+=" -d"
> - pwrite_opts+="-D -V 1 -b 4k"
> + pwrite_opts+="-V 1 -b 4k"
> fi
> testio=`$XFS_IO_PROG -f $opts -c \
> "pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
> diff --git a/tests/generic/765 b/tests/generic/765
> index 9bab3b8a..8695a306 100755
> --- a/tests/generic/765
> +++ b/tests/generic/765
> @@ -28,7 +28,7 @@ get_supported_bsize()
> ;;
> "ext4")
> min_bsize=1024
> - max_bsize=4096
> + max_bsize=$(_get_page_size)
> ;;
> *)
> _notrun "$FSTYP does not support atomic writes"
> @@ -73,7 +73,7 @@ test_atomic_writes()
> # Check that atomic min/max = FS block size
> test $file_min_write -eq $bsize || \
> echo "atomic write min $file_min_write, should be fs block size $bsize"
> - test $file_min_write -eq $bsize || \
> + test $file_max_write -eq $bsize || \
> echo "atomic write max $file_max_write, should be fs block size $bsize"
> test $file_max_segments -eq 1 || \
> echo "atomic write max segments $file_max_segments, should be 1"
> --
> 2.34.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 5/6] common/atomicwrites: fix _require_scratch_write_atomic
2025-05-20 1:33 ` [PATCH v2 5/6] common/atomicwrites: fix _require_scratch_write_atomic Catherine Hoang
@ 2025-05-20 2:14 ` Ritesh Harjani
0 siblings, 0 replies; 19+ messages in thread
From: Ritesh Harjani @ 2025-05-20 2:14 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, john.g.garry
Catherine Hoang <catherine.hoang@oracle.com> writes:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Fix this function to call _notrun whenever something fails. If we can't
> figure out the atomic write geometry, then we haven't satisfied the
> preconditions for the test.
>
> 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>
> ---
> common/atomicwrites | 16 +++++++++-------
> 1 file changed, 9 insertions(+), 7 deletions(-)
This make sense. Thanks for fixing it.
Please feel free to add:
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
>
> diff --git a/common/atomicwrites b/common/atomicwrites
> index 9ec1ca68..391bb6f6 100644
> --- a/common/atomicwrites
> +++ b/common/atomicwrites
> @@ -28,21 +28,23 @@ _require_scratch_write_atomic()
> {
> _require_scratch
>
> - awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> - awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
> + local awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> + local awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
>
> if [ $awu_min_bdev -eq 0 ] && [ $awu_max_bdev -eq 0 ]; then
> _notrun "write atomic not supported by this block device"
> fi
>
> - _scratch_mkfs > /dev/null 2>&1
> - _scratch_mount
> + _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"
>
> - testfile=$SCRATCH_MNT/testfile
> + local testfile=$SCRATCH_MNT/testfile
> touch $testfile
>
> - awu_min_fs=$(_get_atomic_write_unit_min $testfile)
> - awu_max_fs=$(_get_atomic_write_unit_max $testfile)
> + local awu_min_fs=$(_get_atomic_write_unit_min $testfile)
> + local awu_max_fs=$(_get_atomic_write_unit_max $testfile)
>
> _scratch_unmount
>
> --
> 2.34.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 6/6] generic: various atomic write tests with scsi_debug
2025-05-20 1:34 ` [PATCH v2 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
@ 2025-05-20 12:05 ` Ritesh Harjani
2025-05-21 2:30 ` Darrick J. Wong
2025-05-21 4:43 ` Ritesh Harjani
2025-05-22 10:53 ` Ojaswin Mujoo
2 siblings, 1 reply; 19+ messages in thread
From: Ritesh Harjani @ 2025-05-20 12:05 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, john.g.garry
Catherine Hoang <catherine.hoang@oracle.com> writes:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Simple tests of various atomic write requests and a (simulated) hardware
> device.
>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> ---
> common/atomicwrites | 10 +++
> tests/generic/1222 | 86 +++++++++++++++++++++++++
> tests/generic/1222.out | 10 +++
> tests/generic/1223 | 66 +++++++++++++++++++
> tests/generic/1223.out | 9 +++
> tests/generic/1224 | 140 +++++++++++++++++++++++++++++++++++++++++
> tests/generic/1224.out | 17 +++++
> tests/xfs/1216 | 67 ++++++++++++++++++++
> tests/xfs/1216.out | 9 +++
> tests/xfs/1217 | 70 +++++++++++++++++++++
> tests/xfs/1217.out | 3 +
> tests/xfs/1218 | 59 +++++++++++++++++
> tests/xfs/1218.out | 15 +++++
> 13 files changed, 561 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 100644 tests/generic/1224
> create mode 100644 tests/generic/1224.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 100644 tests/xfs/1218
> create mode 100644 tests/xfs/1218.out
>
> diff --git a/common/atomicwrites b/common/atomicwrites
> index 391bb6f6..c75c3d39 100644
> --- a/common/atomicwrites
> +++ b/common/atomicwrites
> @@ -115,3 +115,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..9d02bd70
> --- /dev/null
> +++ b/tests/generic/1222
> @@ -0,0 +1,86 @@
> +#! /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_atomic_write_test_commands
Is it possible to allow pwrite -A to be tested on $SCRATCH_MNT rather
than on TEST_MNT? For e.g.
What happens when TEST_DEV is not atomic write capable? Then this test
won't run even though we are passing scsi_debug which supports atomic writes.
> +
> +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..8a77386e
> --- /dev/null
> +++ b/tests/generic/1223
> @@ -0,0 +1,66 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1223
> +#
> +# Validate multi-fsblock atomic write support with or without hw support
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +
> +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
If the kernel we are testing on doesn't have SW XFS atomic write patches
and if the scratch device does not support HW atomic write, then this
could cause an infinite loop, right? Since both min_awu and max_awu can
come out to be 0?
> + $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
Will continue reviewing from g/1224 and will let you know if I
have any comments.
-ritesh
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 6/6] generic: various atomic write tests with scsi_debug
2025-05-20 12:05 ` Ritesh Harjani
@ 2025-05-21 2:30 ` Darrick J. Wong
2025-05-22 10:33 ` Ojaswin Mujoo
0 siblings, 1 reply; 19+ messages in thread
From: Darrick J. Wong @ 2025-05-21 2:30 UTC (permalink / raw)
To: Ritesh Harjani; +Cc: Catherine Hoang, linux-xfs, fstests, john.g.garry
On Tue, May 20, 2025 at 05:35:30PM +0530, Ritesh Harjani wrote:
> Catherine Hoang <catherine.hoang@oracle.com> writes:
>
> > From: "Darrick J. Wong" <djwong@kernel.org>
> >
> > Simple tests of various atomic write requests and a (simulated) hardware
> > device.
> >
> > Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> > Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> > ---
> > common/atomicwrites | 10 +++
> > tests/generic/1222 | 86 +++++++++++++++++++++++++
> > tests/generic/1222.out | 10 +++
> > tests/generic/1223 | 66 +++++++++++++++++++
> > tests/generic/1223.out | 9 +++
> > tests/generic/1224 | 140 +++++++++++++++++++++++++++++++++++++++++
> > tests/generic/1224.out | 17 +++++
> > tests/xfs/1216 | 67 ++++++++++++++++++++
> > tests/xfs/1216.out | 9 +++
> > tests/xfs/1217 | 70 +++++++++++++++++++++
> > tests/xfs/1217.out | 3 +
> > tests/xfs/1218 | 59 +++++++++++++++++
> > tests/xfs/1218.out | 15 +++++
> > 13 files changed, 561 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 100644 tests/generic/1224
> > create mode 100644 tests/generic/1224.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 100644 tests/xfs/1218
> > create mode 100644 tests/xfs/1218.out
> >
> > diff --git a/common/atomicwrites b/common/atomicwrites
> > index 391bb6f6..c75c3d39 100644
> > --- a/common/atomicwrites
> > +++ b/common/atomicwrites
> > @@ -115,3 +115,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..9d02bd70
> > --- /dev/null
> > +++ b/tests/generic/1222
> > @@ -0,0 +1,86 @@
> > +#! /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_atomic_write_test_commands
>
> Is it possible to allow pwrite -A to be tested on $SCRATCH_MNT rather
> than on TEST_MNT? For e.g.
>
> What happens when TEST_DEV is not atomic write capable? Then this test
> won't run even though we are passing scsi_debug which supports atomic writes.
Hrmmmm. Maybe we need an open-coded version of the "make sure the
xfs_io commands are present" checks without actually doing live testing
of the $TEST_DIR since we're creating a scsi-debug with atomic write
capability anyway.
> > +
> > +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..8a77386e
> > --- /dev/null
> > +++ b/tests/generic/1223
> > @@ -0,0 +1,66 @@
> > +#! /bin/bash
> > +# SPDX-License-Identifier: GPL-2.0
> > +# Copyright (c) 2025 Oracle. All Rights Reserved.
> > +#
> > +# FS QA Test 1223
> > +#
> > +# Validate multi-fsblock atomic write support with or without hw support
> > +#
> > +. ./common/preamble
> > +_begin_fstest auto quick rw atomicwrites
> > +
> > +. ./common/atomicwrites
> > +
> > +_require_scratch
> > +_require_atomic_write_test_commands
> > +
> > +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
>
> If the kernel we are testing on doesn't have SW XFS atomic write patches
> and if the scratch device does not support HW atomic write, then this
> could cause an infinite loop, right? Since both min_awu and max_awu can
> come out to be 0?
<nod> This should _notrun if max_awu is zero.
> > + $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
>
>
> Will continue reviewing from g/1224 and will let you know if I
> have any comments.
Ok. Thanks for reviewing! :)
--D
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 6/6] generic: various atomic write tests with scsi_debug
2025-05-20 1:34 ` [PATCH v2 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
2025-05-20 12:05 ` Ritesh Harjani
@ 2025-05-21 4:43 ` Ritesh Harjani
2025-05-22 10:53 ` Ojaswin Mujoo
2 siblings, 0 replies; 19+ messages in thread
From: Ritesh Harjani @ 2025-05-21 4:43 UTC (permalink / raw)
To: Catherine Hoang, linux-xfs, fstests; +Cc: djwong, john.g.garry
Catherine Hoang <catherine.hoang@oracle.com> writes:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Simple tests of various atomic write requests and a (simulated) hardware
> device.
>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
<...>
> diff --git a/tests/generic/1224 b/tests/generic/1224
> new file mode 100644
> index 00000000..fb178be4
> --- /dev/null
> +++ b/tests/generic/1224
> @@ -0,0 +1,140 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1224
> +#
> +# test 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_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)
> +
> +# 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
> +
> +# 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
> +
> +# 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
> +
> +# 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
> +
> +# 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
> +
> +# non-reflink tests
Can we split these non-reflink tests into a separate test, so that ext4
could use the same?
> +
> +# 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
> +
> +# 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
> +
> +# 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
> +
> +# 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
> +
> +# 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 -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"
> +#md5sum $file1 | _filter_scratch
I guess atomic write max size above is not really doing any atomic
writes. No -A options provided?
Also a left out comment of md5sum can be fixed.
> +
> +# 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
Nice :)
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/1224.out b/tests/generic/1224.out
> new file mode 100644
> index 00000000..1c788420
> --- /dev/null
> +++ b/tests/generic/1224.out
> @@ -0,0 +1,17 @@
> +QA output created by 1224
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +4edfbc469bed9965219ea80c9ae54626 SCRATCH_MNT/file1
> +93243a293a9f568903485b0b2a895815 SCRATCH_MNT/file2
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +75572c4929fde8faf131e84df4c6a764 SCRATCH_MNT/file1
> +27a248351cd540bc9ac2c2dc841abca2 SCRATCH_MNT/file1
> +27c9068d1b51da575a53ad34c57ca5cc SCRATCH_MNT/file3
Nit: Can we add the test name above each checksum to identify it easily?
e.g.
atomic write shared+unshared+shared data
f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
atomic write at EOF
75572c4929fde8faf131e84df4c6a764 SCRATCH_MNT/file1
> diff --git a/tests/xfs/1216 b/tests/xfs/1216
> new file mode 100755
> index 00000000..04aa77fe
> --- /dev/null
> +++ b/tests/xfs/1216
> @@ -0,0 +1,67 @@
> +#! /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
> +
> +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
Can we split tests/xfs/121{6,7,8} into a separate patch please?
Will be just easier to review XFS atomicwrites tests separately.
Thanks!
-ritesh
> diff --git a/tests/xfs/1216.out b/tests/xfs/1216.out
> ...
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 1/6] generic/765: fix a few issues
2025-05-20 1:33 ` [PATCH v2 1/6] generic/765: fix a few issues Catherine Hoang
2025-05-20 2:10 ` Ritesh Harjani
@ 2025-05-22 10:14 ` Ojaswin Mujoo
1 sibling, 0 replies; 19+ messages in thread
From: Ojaswin Mujoo @ 2025-05-22 10:14 UTC (permalink / raw)
To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list
On Mon, May 19, 2025 at 06:33:55PM -0700, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Fix a few bugs in the single block atomic writes test, such as not requiring
> directio, using the page size for the ext4 max bsize, and making sure we check
> the max atomic write size.
>
> Cc: ritesh.list@gmail.com
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Looks good, feel free to add:
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Regards,
ojaswin
> ---
> common/rc | 2 +-
> tests/generic/765 | 4 ++--
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/common/rc b/common/rc
> index 657772e7..0ac90d3e 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -2989,7 +2989,7 @@ _require_xfs_io_command()
> fi
> if [ "$param" == "-A" ]; then
> opts+=" -d"
> - pwrite_opts+="-D -V 1 -b 4k"
> + pwrite_opts+="-V 1 -b 4k"
> fi
> testio=`$XFS_IO_PROG -f $opts -c \
> "pwrite $pwrite_opts $param 0 4k" $testfile 2>&1`
> diff --git a/tests/generic/765 b/tests/generic/765
> index 9bab3b8a..8695a306 100755
> --- a/tests/generic/765
> +++ b/tests/generic/765
> @@ -28,7 +28,7 @@ get_supported_bsize()
> ;;
> "ext4")
> min_bsize=1024
> - max_bsize=4096
> + max_bsize=$(_get_page_size)
> ;;
> *)
> _notrun "$FSTYP does not support atomic writes"
> @@ -73,7 +73,7 @@ test_atomic_writes()
> # Check that atomic min/max = FS block size
> test $file_min_write -eq $bsize || \
> echo "atomic write min $file_min_write, should be fs block size $bsize"
> - test $file_min_write -eq $bsize || \
> + test $file_max_write -eq $bsize || \
> echo "atomic write max $file_max_write, should be fs block size $bsize"
> test $file_max_segments -eq 1 || \
> echo "atomic write max segments $file_max_segments, should be 1"
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 2/6] generic/765: adjust various things
2025-05-20 1:33 ` [PATCH v2 2/6] generic/765: adjust various things Catherine Hoang
@ 2025-05-22 10:14 ` Ojaswin Mujoo
0 siblings, 0 replies; 19+ messages in thread
From: Ojaswin Mujoo @ 2025-05-22 10:14 UTC (permalink / raw)
To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list
On Mon, May 19, 2025 at 06:33:56PM -0700, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Fix some bugs when detecting the atomic write geometry, record what
> atomic write geometry we're testing each time through the loop, and
> create a group for atomic writes tests.
>
> 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>
> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Looks good, feel free to add:
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Regards,
ojaswin
> ---
> common/rc | 4 ++--
> doc/group-names.txt | 1 +
> tests/generic/765 | 25 ++++++++++++++++++++++++-
> 3 files changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/common/rc b/common/rc
> index 0ac90d3e..261fa72a 100644
> --- a/common/rc
> +++ b/common/rc
> @@ -5442,13 +5442,13 @@ _get_atomic_write_unit_min()
> _get_atomic_write_unit_max()
> {
> $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> - grep atomic_write_unit_max | grep -o '[0-9]\+'
> + grep -w atomic_write_unit_max | grep -o '[0-9]\+'
> }
>
> _get_atomic_write_segments_max()
> {
> $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> - grep atomic_write_segments_max | grep -o '[0-9]\+'
> + grep -w atomic_write_segments_max | grep -o '[0-9]\+'
> }
>
> _require_scratch_write_atomic()
> diff --git a/doc/group-names.txt b/doc/group-names.txt
> index f510bb82..1b38f73b 100644
> --- a/doc/group-names.txt
> +++ b/doc/group-names.txt
> @@ -12,6 +12,7 @@ acl Access Control Lists
> admin xfs_admin functionality
> aio general libaio async io tests
> atime file access time
> +atomicwrites RWF_ATOMIC testing
> attr extended attributes
> attr2 xfs v2 extended aributes
> balance btrfs tree rebalance
> diff --git a/tests/generic/765 b/tests/generic/765
> index 8695a306..84381730 100755
> --- a/tests/generic/765
> +++ b/tests/generic/765
> @@ -7,7 +7,7 @@
> # Validate atomic write support
> #
> . ./common/preamble
> -_begin_fstest auto quick rw
> +_begin_fstest auto quick rw atomicwrites
>
> _require_scratch_write_atomic
> _require_xfs_io_command pwrite -A
> @@ -34,6 +34,10 @@ get_supported_bsize()
> _notrun "$FSTYP does not support atomic writes"
> ;;
> esac
> +
> + echo "fs config ------------" >> $seqres.full
> + echo "min_bsize $min_bsize" >> $seqres.full
> + echo "max_bsize $max_bsize" >> $seqres.full
> }
>
> get_mkfs_opts()
> @@ -70,6 +74,11 @@ test_atomic_writes()
> file_max_write=$(_get_atomic_write_unit_max $testfile)
> file_max_segments=$(_get_atomic_write_segments_max $testfile)
>
> + echo "test $bsize --------------" >> $seqres.full
> + echo "file awu_min $file_min_write" >> $seqres.full
> + echo "file awu_max $file_max_write" >> $seqres.full
> + echo "file awu_segments $file_max_segments" >> $seqres.full
> +
> # Check that atomic min/max = FS block size
> test $file_min_write -eq $bsize || \
> echo "atomic write min $file_min_write, should be fs block size $bsize"
> @@ -145,6 +154,15 @@ test_atomic_write_bounds()
> testfile=$SCRATCH_MNT/testfile
> touch $testfile
>
> + file_min_write=$(_get_atomic_write_unit_min $testfile)
> + file_max_write=$(_get_atomic_write_unit_max $testfile)
> + file_max_segments=$(_get_atomic_write_segments_max $testfile)
> +
> + echo "test awb $bsize --------------" >> $seqres.full
> + echo "file awu_min $file_min_write" >> $seqres.full
> + echo "file awu_max $file_max_write" >> $seqres.full
> + echo "file awu_segments $file_max_segments" >> $seqres.full
> +
> $XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile 2>> $seqres.full && \
> echo "atomic write should fail when bsize is out of bounds"
>
> @@ -157,6 +175,11 @@ sys_max_write=$(cat "/sys/block/$(_short_dev $SCRATCH_DEV)/queue/atomic_write_un
> bdev_min_write=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> bdev_max_write=$(_get_atomic_write_unit_max $SCRATCH_DEV)
>
> +echo "sysfs awu_min $sys_min_write" >> $seqres.full
> +echo "sysfs awu_min $sys_max_write" >> $seqres.full
> +echo "bdev awu_min $bdev_min_write" >> $seqres.full
> +echo "bdev awu_min $bdev_max_write" >> $seqres.full
> +
> # Test that statx atomic values are the same as sysfs values
> if [ "$sys_min_write" -ne "$bdev_min_write" ]; then
> echo "bdev min write != sys min write"
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 3/6] generic/765: move common atomic write code to a library file
2025-05-20 1:33 ` [PATCH v2 3/6] generic/765: move common atomic write code to a library file Catherine Hoang
@ 2025-05-22 10:26 ` Ojaswin Mujoo
0 siblings, 0 replies; 19+ messages in thread
From: Ojaswin Mujoo @ 2025-05-22 10:26 UTC (permalink / raw)
To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list
On Mon, May 19, 2025 at 06:33:57PM -0700, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Move the common atomic writes code to common/atomic so we can share
s/atomic/atomicwrites/
> them.
>
> 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>
> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Looks good:
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
just a minor comment below:
<snip>
> ---
> common/atomicwrites | 111 ++++++++++++++++++++++++++++++++++++++++++++
> common/rc | 47 -------------------
> tests/generic/765 | 53 ++-------------------
> 3 files changed, 114 insertions(+), 97 deletions(-)
> create mode 100644 common/atomicwrites
>
> +
> +_test_atomic_file_writes()
Since we use this for mostly bound checks and single mapping checks,
maybe we can name this as _test_atomic_file_writes_sanity() or something
along those lines? Im okay either ways, just thought its a bit confusing
to call _test_atomic_file_writes() and then doing more tests after that.
Regards,
ojaswin
> +{
> + local bsize="$1"
> + local testfile="$2"
> + local bytes_written
> + local testfile_cp="$testfile.copy"
> +
> + # Check that we can perform an atomic write of len = FS block size
> + bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile | \
> + grep wrote | awk -F'[/ ]' '{print $2}')
> + test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 6/6] generic: various atomic write tests with scsi_debug
2025-05-21 2:30 ` Darrick J. Wong
@ 2025-05-22 10:33 ` Ojaswin Mujoo
2025-05-28 22:00 ` Darrick J. Wong
0 siblings, 1 reply; 19+ messages in thread
From: Ojaswin Mujoo @ 2025-05-22 10:33 UTC (permalink / raw)
To: Darrick J. Wong
Cc: Ritesh Harjani, Catherine Hoang, linux-xfs, fstests, john.g.garry
On Tue, May 20, 2025 at 07:30:52PM -0700, Darrick J. Wong wrote:
> On Tue, May 20, 2025 at 05:35:30PM +0530, Ritesh Harjani wrote:
> > Catherine Hoang <catherine.hoang@oracle.com> writes:
> >
> > > From: "Darrick J. Wong" <djwong@kernel.org>
<snip>
> > > + 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_atomic_write_test_commands
> >
> > Is it possible to allow pwrite -A to be tested on $SCRATCH_MNT rather
> > than on TEST_MNT? For e.g.
> >
> > What happens when TEST_DEV is not atomic write capable? Then this test
> > won't run even though we are passing scsi_debug which supports atomic writes.
>
> Hrmmmm. Maybe we need an open-coded version of the "make sure the
> xfs_io commands are present" checks without actually doing live testing
> of the $TEST_DIR since we're creating a scsi-debug with atomic write
> capability anyway.
I think it might be better to finally have a _require_scratch_xfs_io_command()
and hence a _require_scratch_atomic_write_commands. This can avoid the
open coding as well as future proof it for similar features.
>
> > > +
> > > +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
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 4/6] common/atomicwrites: adjust a few more things
2025-05-20 1:33 ` [PATCH v2 4/6] common/atomicwrites: adjust a few more things Catherine Hoang
@ 2025-05-22 10:37 ` Ojaswin Mujoo
0 siblings, 0 replies; 19+ messages in thread
From: Ojaswin Mujoo @ 2025-05-22 10:37 UTC (permalink / raw)
To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list
On Mon, May 19, 2025 at 06:33:58PM -0700, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Always export STATX_WRITE_ATOMIC so anyone can use it, make the "cp
> reflink" logic work for any filesystem, not just xfs, and create a
> separate helper to check that the necessary xfs_io support is present.
Aside from the discussions of having a helper for
_requre_atomic_writes_test_commands for SCRATCH_DEV (in other thread),
rest of the changes look good.
Reviewed-by: Ojaswin Mujoo <ojaswin@linux.ibm.com>
Regards,
ojaswin
>
> 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>
> Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
> ---
> common/atomicwrites | 18 +++++++++++-------
> tests/generic/765 | 2 +-
> 2 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/common/atomicwrites b/common/atomicwrites
> index fd3a9b71..9ec1ca68 100644
> --- a/common/atomicwrites
> +++ b/common/atomicwrites
> @@ -4,6 +4,8 @@
> #
> # Routines for testing atomic writes.
>
> +export STATX_WRITE_ATOMIC=0x10000
> +
> _get_atomic_write_unit_min()
> {
> $XFS_IO_PROG -c "statx -r -m $STATX_WRITE_ATOMIC" $1 | \
> @@ -26,8 +28,6 @@ _require_scratch_write_atomic()
> {
> _require_scratch
>
> - export STATX_WRITE_ATOMIC=0x10000
> -
> awu_min_bdev=$(_get_atomic_write_unit_min $SCRATCH_DEV)
> awu_max_bdev=$(_get_atomic_write_unit_max $SCRATCH_DEV)
>
> @@ -51,6 +51,14 @@ _require_scratch_write_atomic()
> fi
> }
>
> +# Check for xfs_io commands required to run _test_atomic_file_writes
> +_require_atomic_write_test_commands()
> +{
> + _require_xfs_io_command "falloc"
> + _require_xfs_io_command "fpunch"
> + _require_xfs_io_command pwrite -A
> +}
> +
> _test_atomic_file_writes()
> {
> local bsize="$1"
> @@ -64,11 +72,7 @@ _test_atomic_file_writes()
> test $bytes_written -eq $bsize || echo "atomic write len=$bsize failed"
>
> # Check that we can perform an atomic single-block cow write
> - if [ "$FSTYP" == "xfs" ]; then
> - testfile_cp=$SCRATCH_MNT/testfile_copy
> - if _xfs_has_feature $SCRATCH_MNT reflink; then
> - cp --reflink $testfile $testfile_cp
> - fi
> + if cp --reflink=always $testfile $testfile_cp 2>> $seqres.full; then
> bytes_written=$($XFS_IO_PROG -dc "pwrite -A -D -V1 -b $bsize 0 $bsize" $testfile_cp | \
> grep wrote | awk -F'[/ ]' '{print $2}')
> test $bytes_written -eq $bsize || echo "atomic write on reflinked file failed"
> diff --git a/tests/generic/765 b/tests/generic/765
> index 09e9fa38..71604e5e 100755
> --- a/tests/generic/765
> +++ b/tests/generic/765
> @@ -12,7 +12,7 @@ _begin_fstest auto quick rw atomicwrites
> . ./common/atomicwrites
>
> _require_scratch_write_atomic
> -_require_xfs_io_command pwrite -A
> +_require_atomic_write_test_commands
>
> get_supported_bsize()
> {
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 6/6] generic: various atomic write tests with scsi_debug
2025-05-20 1:34 ` [PATCH v2 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
2025-05-20 12:05 ` Ritesh Harjani
2025-05-21 4:43 ` Ritesh Harjani
@ 2025-05-22 10:53 ` Ojaswin Mujoo
2 siblings, 0 replies; 19+ messages in thread
From: Ojaswin Mujoo @ 2025-05-22 10:53 UTC (permalink / raw)
To: Catherine Hoang; +Cc: linux-xfs, fstests, djwong, john.g.garry, ritesh.list
On Mon, May 19, 2025 at 06:34:00PM -0700, Catherine Hoang wrote:
> From: "Darrick J. Wong" <djwong@kernel.org>
>
> Simple tests of various atomic write requests and a (simulated) hardware
> device.
Hey Catherine, Darrick,
So while working on ext4 multi block we have also written some tests
which we plan to upstream soon. Ofcourse some were sort of identical to
the ones added here. So here and there while reviewing I might add a few
things we did differently, which we can think of incorporating.
>
> Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
> Signed-off-by: Catherine Hoang <catherine.hoang@oracle.com>
> ---
> common/atomicwrites | 10 +++
> tests/generic/1222 | 86 +++++++++++++++++++++++++
> tests/generic/1222.out | 10 +++
> tests/generic/1223 | 66 +++++++++++++++++++
> tests/generic/1223.out | 9 +++
> tests/generic/1224 | 140 +++++++++++++++++++++++++++++++++++++++++
> tests/generic/1224.out | 17 +++++
> tests/xfs/1216 | 67 ++++++++++++++++++++
> tests/xfs/1216.out | 9 +++
> tests/xfs/1217 | 70 +++++++++++++++++++++
> tests/xfs/1217.out | 3 +
> tests/xfs/1218 | 59 +++++++++++++++++
> tests/xfs/1218.out | 15 +++++
> 13 files changed, 561 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 100644 tests/generic/1224
> create mode 100644 tests/generic/1224.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 100644 tests/xfs/1218
> create mode 100644 tests/xfs/1218.out
>
> diff --git a/common/atomicwrites b/common/atomicwrites
> index 391bb6f6..c75c3d39 100644
> --- a/common/atomicwrites
> +++ b/common/atomicwrites
> @@ -115,3 +115,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..9d02bd70
> --- /dev/null
> +++ b/tests/generic/1222
> @@ -0,0 +1,86 @@
> +#! /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
How about using a _require_scratch_write_atomic_multi_fsblock() helper.
This will help _notrun tests which are not really relevant for kernels
with single block aw support, like mixed mapping tests.
> +_require_atomic_write_test_commands
> +
> +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
Why do we need the _simple_atomic_write here?
> +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..8a77386e
> --- /dev/null
> +++ b/tests/generic/1223
> @@ -0,0 +1,66 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1223
> +#
> +# Validate multi-fsblock atomic write support with or without hw support
> +#
> +. ./common/preamble
> +_begin_fstest auto quick rw atomicwrites
> +
> +. ./common/atomicwrites
> +
> +_require_scratch
> +_require_atomic_write_test_commands
> +
> +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 100644
> index 00000000..fb178be4
> --- /dev/null
> +++ b/tests/generic/1224
> @@ -0,0 +1,140 @@
> +#! /bin/bash
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (c) 2025 Oracle. All Rights Reserved.
> +#
> +# FS QA Test 1224
> +#
> +# test 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_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"
I usually use a scsi_debug disk with 64kb max awu. I can always use 256k
but any reason why we need to have it this high?
> +
> +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)
> +
> +# 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
> +
> +# 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
> +
> +# 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
> +
> +# 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
> +
> +# 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
> +
> +# non-reflink tests
> +
> +# 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
> +
> +# 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
> +
> +# 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
I think some combos for unwritten would be good as well.
> +
> +# 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
> +
> +# 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 -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"
> +#md5sum $file1 | _filter_scratch
> +
> +# 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
This will have a unwrit to hole sort of mapping. Maybe we should stress
with a more random layout. A rough snippet with multiple iterations to
stress this a bit more:
operations=("W" "H" "U")
for ((iteration=1; iteration<=10; iteration++)); do
echo "=== Mixed Mapping Test Iteration $iteration ===" >> $seqres.full
$XFS_IO_PROG -c "truncate 0" $testfile >> $seqres.full
# Create a random mixed mapping for all blocks in the 64K region
echo "Random block mapping pattern:" >> $seqres.full
off=0
mapping=""
for ((i=0; i<num_blocks; i++)); do
# Randomly select an operation (W, H, or U)
index=$((RANDOM % ${#operations[@]}))
map="${operations[$index]}"
mapping="${mapping}${map}"
echo "Block $i: Operation $map at offset $off" >> $seqres.full
case "$map" in
"W")
$XFS_IO_PROG -dc "pwrite -S 0x61 -b $blksz $off $blksz" $testfile >> $seqres.full
;;
"H")
# No operation needed for hole
;;
"U")
$XFS_IO_PROG -c "falloc $off $blksz" $testfile >> $seqres.full
;;
esac
off=$((off + blksz))
done
sync $testfile
echo "Full mapping pattern: $mapping" >> $seqres.full
# Now perform the atomic write over the entire region with O_SYNC
echo "Performing O_SYNC atomic write over the entire $awu_max region" >> $seqres.full
bytes_written=$($XFS_IO_PROG -dsc "pwrite -A -V1 -b $awu_max 0 $awu_max" $testfile | \
grep wrote | awk -F'[/ ]' '{print $2}')
# Check if the atomic write was successful
test $bytes_written -eq $awu_max || echo "atomic write len=$awu_max failed"
check_data_integrity
echo "Iteration $iteration completed: OK" >> $seqres.full
done
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/generic/1224.out b/tests/generic/1224.out
> new file mode 100644
> index 00000000..1c788420
> --- /dev/null
> +++ b/tests/generic/1224.out
> @@ -0,0 +1,17 @@
> +QA output created by 1224
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +111ce6bf29d5b1dbfb0e846c42719ece SCRATCH_MNT/file1
> +f1c9645dbc14efddc7d8a322685f26eb SCRATCH_MNT/file2
> +4edfbc469bed9965219ea80c9ae54626 SCRATCH_MNT/file1
> +93243a293a9f568903485b0b2a895815 SCRATCH_MNT/file2
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +9464b66461bc1d20229e1b71733539d0 SCRATCH_MNT/file1
> +75572c4929fde8faf131e84df4c6a764 SCRATCH_MNT/file1
> +27a248351cd540bc9ac2c2dc841abca2 SCRATCH_MNT/file1
> +27c9068d1b51da575a53ad34c57ca5cc SCRATCH_MNT/file3
> diff --git a/tests/xfs/1216 b/tests/xfs/1216
> new file mode 100755
> index 00000000..04aa77fe
> --- /dev/null
> +++ b/tests/xfs/1216
> @@ -0,0 +1,67 @@
> +#! /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
> +
> +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..0816d05f
> --- /dev/null
> +++ b/tests/xfs/1217
> @@ -0,0 +1,70 @@
> +#! /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_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 100644
> index 00000000..f3682e42
> --- /dev/null
> +++ b/tests/xfs/1218
> @@ -0,0 +1,59 @@
> +#! /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_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 $testfile)
> +test $max_awu -ge 4096 || _notrun "cannot perform 4k atomic writes"
> +
> +file2=$SCRATCH_MNT/file2
> +_pwrite_byte 0x66 0 64k $SCRATCH_MNT/file1 >> $seqres.full
> +cp --reflink=always $file1 $file2
> +
> +echo "Check files"
> +md5sum $SCRATCH_MNT/file1 | _filter_scratch
> +md5sum $SCRATCH_MNT/file2 | _filter_scratch
> +
> +echo "Inject error"
> +_scratch_inject_error "bmap_finish_one"
> +
> +echo "Atomic write to a reflinked file"
> +$XFS_IO_PROG -dc "pwrite -A -D -V1 -S 0x67 0 4096" $file1
> +
> +echo "FS should be shut down, touch will fail"
> +touch $SCRATCH_MNT/badfs 2>&1 | _filter_scratch
> +
> +echo "Remount to replay log"
> +_scratch_remount_dump_log >> $seqres.full
> +
> +echo "Check files"
> +md5sum $SCRATCH_MNT/file1 | _filter_scratch
> +md5sum $SCRATCH_MNT/file2 | _filter_scratch
> +
> +echo "FS should be online, touch should succeed"
> +touch $SCRATCH_MNT/goodfs 2>&1 | _filter_scratch
> +
> +# success, all done
> +status=0
> +exit
> diff --git a/tests/xfs/1218.out b/tests/xfs/1218.out
> new file mode 100644
> index 00000000..02800213
> --- /dev/null
> +++ b/tests/xfs/1218.out
> @@ -0,0 +1,15 @@
> +QA output created by 1218
> +Create files
> +Check files
> +77e3a730e3c75274c9ce310d7e39f938 SCRATCH_MNT/file1
> +77e3a730e3c75274c9ce310d7e39f938 SCRATCH_MNT/file2
> +Inject error
> +Atomic write to a reflinked file
> +pwrite: Input/output error
> +FS should be shut down, touch will fail
> +touch: cannot touch 'SCRATCH_MNT/badfs': Input/output error
> +Remount to replay log
> +Check files
> +0df1f61ed02a7e9bee2b8b7665066ddc SCRATCH_MNT/file1
> +77e3a730e3c75274c9ce310d7e39f938 SCRATCH_MNT/file2
> +FS should be online, touch should succeed
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v2 6/6] generic: various atomic write tests with scsi_debug
2025-05-22 10:33 ` Ojaswin Mujoo
@ 2025-05-28 22:00 ` Darrick J. Wong
0 siblings, 0 replies; 19+ messages in thread
From: Darrick J. Wong @ 2025-05-28 22:00 UTC (permalink / raw)
To: Ojaswin Mujoo
Cc: Ritesh Harjani, Catherine Hoang, linux-xfs, fstests, john.g.garry
On Thu, May 22, 2025 at 04:03:42PM +0530, Ojaswin Mujoo wrote:
> On Tue, May 20, 2025 at 07:30:52PM -0700, Darrick J. Wong wrote:
> > On Tue, May 20, 2025 at 05:35:30PM +0530, Ritesh Harjani wrote:
> > > Catherine Hoang <catherine.hoang@oracle.com> writes:
> > >
> > > > From: "Darrick J. Wong" <djwong@kernel.org>
>
> <snip>
> > > > + 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_atomic_write_test_commands
> > >
> > > Is it possible to allow pwrite -A to be tested on $SCRATCH_MNT rather
> > > than on TEST_MNT? For e.g.
> > >
> > > What happens when TEST_DEV is not atomic write capable? Then this test
> > > won't run even though we are passing scsi_debug which supports atomic writes.
> >
> > Hrmmmm. Maybe we need an open-coded version of the "make sure the
> > xfs_io commands are present" checks without actually doing live testing
> > of the $TEST_DIR since we're creating a scsi-debug with atomic write
> > capability anyway.
>
> I think it might be better to finally have a _require_scratch_xfs_io_command()
> and hence a _require_scratch_atomic_write_commands. This can avoid the
> open coding as well as future proof it for similar features.
<comes back from vacation>
/me looks at what _require_xfs_io_command actually does with the output:
echo $testio | grep -q "not found" && \
_notrun "xfs_io $command $param_checked support is missing"
echo $testio | grep -q "Operation not supported\|Inappropriate ioctl" && \
_notrun "xfs_io $command $param_checked failed (old kernel/wrong fs?)"
echo $testio | grep -q "Invalid" && \
_notrun "xfs_io $command $param_checked failed (old kernel/wrong fs/bad args?)"
echo $testio | grep -q "foreign file active" && \
_notrun "xfs_io $command $param_checked not supported on $FSTYP"
echo $testio | grep -q "Function not implemented" && \
_notrun "xfs_io $command $param_checked support is missing (missing syscall?)"
echo $testio | grep -q "unknown flag" && \
_notrun "xfs_io $command $param_checked support is missing (unknown flag)"
Aha, so it skips the test for EOPNOTSUPP and EINVAL after trying to
write 4k. Yay, an incohesive function that implies that it's looking to
see if xfs_io recognizes a (sub)command, but then does more than that
and actually requires that the kernel and the test filesystem support it
too.
<groan>
So I guess either the one test that uses scsi-debug has to do its own
grepping of the xfs_io -c 'help pwrite' output to look for atomic write
support, or turn on scsi_debug, mount it, and do something awful like:
TEST_DIR=/some/path _require_xfs_io_command pwrite -A
Any takers?
--D
> >
> > > > +
> > > > +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
>
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2025-05-28 22:00 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-20 1:33 [PATCH v2 0/6] atomic writes tests Catherine Hoang
2025-05-20 1:33 ` [PATCH v2 1/6] generic/765: fix a few issues Catherine Hoang
2025-05-20 2:10 ` Ritesh Harjani
2025-05-22 10:14 ` Ojaswin Mujoo
2025-05-20 1:33 ` [PATCH v2 2/6] generic/765: adjust various things Catherine Hoang
2025-05-22 10:14 ` Ojaswin Mujoo
2025-05-20 1:33 ` [PATCH v2 3/6] generic/765: move common atomic write code to a library file Catherine Hoang
2025-05-22 10:26 ` Ojaswin Mujoo
2025-05-20 1:33 ` [PATCH v2 4/6] common/atomicwrites: adjust a few more things Catherine Hoang
2025-05-22 10:37 ` Ojaswin Mujoo
2025-05-20 1:33 ` [PATCH v2 5/6] common/atomicwrites: fix _require_scratch_write_atomic Catherine Hoang
2025-05-20 2:14 ` Ritesh Harjani
2025-05-20 1:34 ` [PATCH v2 6/6] generic: various atomic write tests with scsi_debug Catherine Hoang
2025-05-20 12:05 ` Ritesh Harjani
2025-05-21 2:30 ` Darrick J. Wong
2025-05-22 10:33 ` Ojaswin Mujoo
2025-05-28 22:00 ` Darrick J. Wong
2025-05-21 4:43 ` Ritesh Harjani
2025-05-22 10:53 ` Ojaswin Mujoo
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).