From: Darrick J. Wong <djwong@xxxxxxxxxx> Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- tests/xfs/1213 | 73 ++++++++++++++++ tests/xfs/1213.out | 2 tests/xfs/1214 | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/1214.out | 2 4 files changed, 309 insertions(+) create mode 100755 tests/xfs/1213 create mode 100644 tests/xfs/1213.out create mode 100755 tests/xfs/1214 create mode 100644 tests/xfs/1214.out diff --git a/tests/xfs/1213 b/tests/xfs/1213 new file mode 100755 index 0000000000..40bf3838af --- /dev/null +++ b/tests/xfs/1213 @@ -0,0 +1,73 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2023-2024 Oracle. All Rights Reserved. +# +# FS QA Test No. 1213 +# +# Make sure that the XFS_EXCH_RANGE_FILE1_WRITTEN actually skips holes and +# unwritten extents on the data device and the rt device when the rextsize +# is 1 fsblock. +# +. ./common/preamble +_begin_fstest auto fiexchange swapext + +. ./common/filter + +# real QA test starts here + +# Modify as appropriate. +_supported_fs generic +_require_xfs_io_command "falloc" +_require_xfs_io_command swapext '-v exchrange -a' +_require_scratch + +_scratch_mkfs >> $seqres.full +_scratch_mount + +# This test doesn't deal with the unwritten extents that must be created when +# the realtime file allocation unit is larger than the fs blocksize. +file_blksz=$(_get_file_block_size $SCRATCH_MNT) +fs_blksz=$(_get_block_size $SCRATCH_MNT) +test "$file_blksz" -eq "$fs_blksz" || \ + _notrun "test requires file alloc unit ($file_blksz) == fs block size ($fs_blksz)" + +swap_and_check_contents() { + local a="$1" + local b="$2" + local tag="$3" + + local a_md5_before=$(md5sum $a | awk '{print $1}') + local b_md5_before=$(md5sum $b | awk '{print $1}') + + # Test swapext. -h means skip holes in /b, and -e means operate to EOF + echo "swap $tag" >> $seqres.full + $XFS_IO_PROG -c fsync -c 'bmap -elpvvvv' $a $b >> $seqres.full + $XFS_IO_PROG -c "swapext -v exchrange -f -u -h -e -a $b" $a >> $seqres.full + $XFS_IO_PROG -c 'bmap -elpvvvv' $a $b >> $seqres.full + _scratch_cycle_mount + + local a_md5_after=$(md5sum $a | awk '{print $1}') + local b_md5_after=$(md5sum $b | awk '{print $1}') + + test "$a_md5_before" != "$a_md5_after" && \ + echo "$a: md5 $a_md5_before -> $a_md5_after in $tag" + + test "$b_md5_before" != "$b_md5_after" && \ + echo "$b: md5 $b_md5_before -> $b_md5_after in $tag" +} + +# plain preallocations on the data device +$XFS_IO_PROG -c 'extsize 0' $SCRATCH_MNT +_pwrite_byte 0x58 0 1m $SCRATCH_MNT/dar >> $seqres.full +$XFS_IO_PROG -f -c 'truncate 1m' -c "falloc 640k 64k" $SCRATCH_MNT/dbr +swap_and_check_contents $SCRATCH_MNT/dar $SCRATCH_MNT/dbr "plain prealloc" + +# extent size hints on the data device +$XFS_IO_PROG -c 'extsize 1m' $SCRATCH_MNT +_pwrite_byte 0x58 0 1m $SCRATCH_MNT/dae >> $seqres.full +$XFS_IO_PROG -f -c 'truncate 1m' -c "falloc 640k 64k" $SCRATCH_MNT/dbe +swap_and_check_contents $SCRATCH_MNT/dae $SCRATCH_MNT/dbe "data dev extsize prealloc" + +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/1213.out b/tests/xfs/1213.out new file mode 100644 index 0000000000..5a28b8b45f --- /dev/null +++ b/tests/xfs/1213.out @@ -0,0 +1,2 @@ +QA output created by 1213 +Silence is golden diff --git a/tests/xfs/1214 b/tests/xfs/1214 new file mode 100755 index 0000000000..5b78b5e348 --- /dev/null +++ b/tests/xfs/1214 @@ -0,0 +1,232 @@ +#! /bin/bash +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2023-2024 Oracle. All Rights Reserved. +# +# FS QA Test No. 1214 +# +# Make sure that the XFS_EXCH_RANGE_FILE1_WRITTEN actually skips holes and +# unwritten extents on the realtime device when the rextsize is larger than 1 +# fs block. +# +. ./common/preamble +_begin_fstest auto fiexchange swapext + +. ./common/filter + +# real QA test starts here + +# Modify as appropriate. +_supported_fs generic +_require_xfs_io_command "falloc" +_require_xfs_io_command swapext '-v exchrange -a' +_require_realtime +_require_scratch + +_scratch_mkfs >> $seqres.full +_scratch_mount + +# This test only deals with the unwritten extents that must be created when +# the realtime file allocation unit is larger than the fs blocksize. +file_blksz=$(_get_file_block_size $SCRATCH_MNT) +fs_blksz=$(_get_block_size $SCRATCH_MNT) +test "$file_blksz" -ge "$((3 * fs_blksz))" || \ + _notrun "test requires file alloc unit ($file_blksz) >= 3 * fs block size ($fs_blksz)" + +swap_and_check_contents() { + local a="$1" + local b="$2" + local tag="$3" + + sync + + # Test swapext. -h means skip holes in /b, and -e means operate to EOF + echo "swap $tag" >> $seqres.full + $XFS_IO_PROG -c 'bmap -elpvvvv' $a $b >> $seqres.full + $XFS_IO_PROG -c "swapext -v exchrange -f -u -h -e -a $b" $a >> $seqres.full + $XFS_IO_PROG -c 'bmap -elpvvvv' $a $b >> $seqres.full + + local a_md5_before=$(md5sum $a | awk '{print $1}') + local b_md5_before=$(md5sum $b | awk '{print $1}') + + _scratch_cycle_mount + + local a_md5_check=$(md5sum $a.chk | awk '{print $1}') + local b_md5_check=$(md5sum $b.chk | awk '{print $1}') + + local a_md5_after=$(md5sum $a | awk '{print $1}') + local b_md5_after=$(md5sum $b | awk '{print $1}') + + test "$a_md5_before" != "$a_md5_after" && \ + echo "$a: md5 $a_md5_before -> $a_md5_after in $tag" + + test "$b_md5_before" != "$b_md5_after" && \ + echo "$b: md5 $b_md5_before -> $b_md5_after in $tag" + + if [ "$a_md5_check" != "$a_md5_after" ]; then + echo "$a: md5 $a_md5_after, expected $a_md5_check in $tag" | tee -a $seqres.full + echo "$a contents" >> $seqres.full + od -tx1 -Ad -c $a >> $seqres.full + echo "$a.chk contents" >> $seqres.full + od -tx1 -Ad -c $a.chk >> $seqres.full + fi + + if [ "$b_md5_check" != "$b_md5_after" ]; then + echo "$b: md5 $b_md5_after, expected $b_md5_check in $tag" | tee -a $seqres.full + echo "$b contents" >> $seqres.full + od -tx1 -Ad -c $b >> $seqres.full + echo "$b.chk contents" >> $seqres.full + od -tx1 -Ad -c $b.chk >> $seqres.full + fi +} + +filesz=$((5 * file_blksz)) + +# first rtblock of the second rtextent is unwritten +rm -f $SCRATCH_MNT/da $SCRATCH_MNT/db $SCRATCH_MNT/*.chk +_pwrite_byte 0x58 0 $filesz $SCRATCH_MNT/da >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x59 $((file_blksz + fs_blksz)) $((file_blksz - fs_blksz))" \ + $SCRATCH_MNT/db >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 0 $file_blksz" \ + -c "pwrite -S 0x00 $file_blksz $fs_blksz" \ + -c "pwrite -S 0x59 $((file_blksz + fs_blksz)) $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x58 $((file_blksz * 2)) $((filesz - (file_blksz * 2) ))" \ + $SCRATCH_MNT/da.chk >> /dev/null +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 $file_blksz $file_blksz" \ + $SCRATCH_MNT/db.chk >> /dev/null +swap_and_check_contents $SCRATCH_MNT/da $SCRATCH_MNT/db \ + "first rtb of second rtx" + +# second rtblock of the second rtextent is unwritten +rm -f $SCRATCH_MNT/da $SCRATCH_MNT/db $SCRATCH_MNT/*.chk +_pwrite_byte 0x58 0 $filesz $SCRATCH_MNT/da >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x59 $file_blksz $fs_blksz" \ + -c "pwrite -S 0x59 $((file_blksz + (2 * fs_blksz) )) $((file_blksz - (2 * fs_blksz) ))" \ + $SCRATCH_MNT/db >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 0 $file_blksz" \ + -c "pwrite -S 0x59 $file_blksz $fs_blksz" \ + -c "pwrite -S 0x00 $((file_blksz + fs_blksz)) $fs_blksz" \ + -c "pwrite -S 0x59 $((file_blksz + (2 * fs_blksz) )) $((file_blksz - (2 * fs_blksz) ))" \ + -c "pwrite -S 0x58 $((file_blksz * 2)) $((filesz - (file_blksz * 2) ))" \ + $SCRATCH_MNT/da.chk >> /dev/null +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 $file_blksz $file_blksz" \ + $SCRATCH_MNT/db.chk >> /dev/null +swap_and_check_contents $SCRATCH_MNT/da $SCRATCH_MNT/db \ + "second rtb of second rtx" + +# last rtblock of the second rtextent is unwritten +rm -f $SCRATCH_MNT/da $SCRATCH_MNT/db $SCRATCH_MNT/*.chk +_pwrite_byte 0x58 0 $filesz $SCRATCH_MNT/da >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x59 $file_blksz $((file_blksz - fs_blksz))" \ + $SCRATCH_MNT/db >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 0 $file_blksz" \ + -c "pwrite -S 0x59 $file_blksz $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x00 $(( (2 * file_blksz) - fs_blksz)) $fs_blksz" \ + -c "pwrite -S 0x58 $((file_blksz * 2)) $((filesz - (file_blksz * 2) ))" \ + $SCRATCH_MNT/da.chk >> /dev/null +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 $file_blksz $file_blksz" \ + $SCRATCH_MNT/db.chk >> /dev/null +swap_and_check_contents $SCRATCH_MNT/da $SCRATCH_MNT/db \ + "last rtb of second rtx" + +# last rtb of the 2nd rtx and first rtb of the 3rd rtx is unwritten +rm -f $SCRATCH_MNT/da $SCRATCH_MNT/db $SCRATCH_MNT/*.chk +_pwrite_byte 0x58 0 $filesz $SCRATCH_MNT/da >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "falloc $file_blksz $((2 * file_blksz))" \ + -c "pwrite -S 0x59 $file_blksz $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x59 $(( (2 * file_blksz) + fs_blksz)) $((file_blksz - fs_blksz))" \ + $SCRATCH_MNT/db >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 0 $file_blksz" \ + -c "pwrite -S 0x59 $file_blksz $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x00 $(( (2 * file_blksz) - fs_blksz)) $((2 * fs_blksz))" \ + -c "pwrite -S 0x59 $(( (2 * file_blksz) + fs_blksz)) $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x58 $((file_blksz * 3)) $((filesz - (file_blksz * 3) ))" \ + $SCRATCH_MNT/da.chk >> /dev/null +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 $file_blksz $((2 * file_blksz))" \ + $SCRATCH_MNT/db.chk >> /dev/null +swap_and_check_contents $SCRATCH_MNT/da $SCRATCH_MNT/db \ + "last rtb of 2nd rtx and first rtb of 3rd rtx" + +# last rtb of the 2nd rtx and first rtb of the 4th rtx is unwritten; 3rd rtx +# is a hole +rm -f $SCRATCH_MNT/da $SCRATCH_MNT/db $SCRATCH_MNT/*.chk +_pwrite_byte 0x58 0 $filesz $SCRATCH_MNT/da >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x59 $file_blksz $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x59 $(( (3 * file_blksz) + fs_blksz)) $((file_blksz - fs_blksz))" \ + -c "fpunch $((2 * file_blksz)) $file_blksz" \ + $SCRATCH_MNT/db >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 0 $file_blksz" \ + -c "pwrite -S 0x59 $file_blksz $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x00 $(( (2 * file_blksz) - fs_blksz)) $fs_blksz" \ + -c "pwrite -S 0x58 $((file_blksz * 2)) $file_blksz" \ + -c "pwrite -S 0x00 $((3 * file_blksz)) $fs_blksz" \ + -c "pwrite -S 0x59 $(( (3 * file_blksz) + fs_blksz)) $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x58 $((file_blksz * 4)) $((filesz - (file_blksz * 4) ))" \ + $SCRATCH_MNT/da.chk >> /dev/null +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 $file_blksz $file_blksz" \ + -c "pwrite -S 0x58 $((file_blksz * 3)) $file_blksz" \ + $SCRATCH_MNT/db.chk >> /dev/null +swap_and_check_contents $SCRATCH_MNT/da $SCRATCH_MNT/db \ + "last rtb of 2nd rtx and first rtb of 4th rtx; 3rd rtx is hole" + +# last rtb of the 2nd rtx and first rtb of the 4th rtx is unwritten; 3rd rtx +# is preallocated +rm -f $SCRATCH_MNT/da $SCRATCH_MNT/db $SCRATCH_MNT/*.chk +_pwrite_byte 0x58 0 $filesz $SCRATCH_MNT/da >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "falloc $file_blksz $((file_blksz * 3))" \ + -c "pwrite -S 0x59 $file_blksz $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x59 $(( (3 * file_blksz) + fs_blksz)) $((file_blksz - fs_blksz))" \ + $SCRATCH_MNT/db >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 0 $file_blksz" \ + -c "pwrite -S 0x59 $file_blksz $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x00 $(( (2 * file_blksz) - fs_blksz)) $fs_blksz" \ + -c "pwrite -S 0x58 $((file_blksz * 2)) $file_blksz" \ + -c "pwrite -S 0x00 $((3 * file_blksz)) $fs_blksz" \ + -c "pwrite -S 0x59 $(( (3 * file_blksz) + fs_blksz)) $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x58 $((file_blksz * 4)) $((filesz - (file_blksz * 4) ))" \ + $SCRATCH_MNT/da.chk >> /dev/null +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 $file_blksz $file_blksz" \ + -c "pwrite -S 0x58 $((file_blksz * 3)) $file_blksz" \ + $SCRATCH_MNT/db.chk >> /dev/null +swap_and_check_contents $SCRATCH_MNT/da $SCRATCH_MNT/db \ + "last rtb of 2nd rtx and first rtb of 4th rtx; 3rd rtx is prealloc" + +# 2nd rtx is preallocated and first rtb of 3rd rtx is unwritten +rm -f $SCRATCH_MNT/da $SCRATCH_MNT/db $SCRATCH_MNT/*.chk +_pwrite_byte 0x58 0 $filesz $SCRATCH_MNT/da >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "falloc $file_blksz $((file_blksz * 2))" \ + -c "pwrite -S 0x59 $(( (2 * file_blksz) + fs_blksz)) $((file_blksz - fs_blksz))" \ + $SCRATCH_MNT/db >> $seqres.full +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 0 $((2 * file_blksz))" \ + -c "pwrite -S 0x00 $((2 * file_blksz)) $fs_blksz" \ + -c "pwrite -S 0x59 $(( (2 * file_blksz) + fs_blksz)) $((file_blksz - fs_blksz))" \ + -c "pwrite -S 0x58 $((file_blksz * 3)) $((filesz - (file_blksz * 3) ))" \ + $SCRATCH_MNT/da.chk >> /dev/null +$XFS_IO_PROG -f -c "truncate $filesz" \ + -c "pwrite -S 0x58 $((2 * file_blksz)) $file_blksz" \ + $SCRATCH_MNT/db.chk >> /dev/null +swap_and_check_contents $SCRATCH_MNT/da $SCRATCH_MNT/db \ + "2nd rtx is prealloc and first rtb of 3rd rtx is unwritten" + +echo Silence is golden +status=0 +exit diff --git a/tests/xfs/1214.out b/tests/xfs/1214.out new file mode 100644 index 0000000000..a529e42333 --- /dev/null +++ b/tests/xfs/1214.out @@ -0,0 +1,2 @@ +QA output created by 1214 +Silence is golden