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