* [PATCH 01/11] xfs/122: fix metadirino
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
@ 2023-12-27 13:50 ` Darrick J. Wong
2023-12-27 13:50 ` [PATCH 02/11] various: fix finding metadata inode numbers when metadir is enabled Darrick J. Wong
` (9 subsequent siblings)
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:50 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Fix xfs/122 to work properly with metadirino.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/122.out | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/xfs/122.out b/tests/xfs/122.out
index 5d14386518..430b805792 100644
--- a/tests/xfs/122.out
+++ b/tests/xfs/122.out
@@ -35,6 +35,7 @@ offsetof(xfs_sb_t, sb_logsunit) = 196
offsetof(xfs_sb_t, sb_lsn) = 240
offsetof(xfs_sb_t, sb_magicnum) = 0
offsetof(xfs_sb_t, sb_meta_uuid) = 248
+offsetof(xfs_sb_t, sb_metadirino) = 264
offsetof(xfs_sb_t, sb_pquotino) = 232
offsetof(xfs_sb_t, sb_qflags) = 176
offsetof(xfs_sb_t, sb_rblocks) = 16
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 02/11] various: fix finding metadata inode numbers when metadir is enabled
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
2023-12-27 13:50 ` [PATCH 01/11] xfs/122: fix metadirino Darrick J. Wong
@ 2023-12-27 13:50 ` Darrick J. Wong
2023-12-27 13:50 ` [PATCH 03/11] xfs/{030,033,178}: forcibly disable metadata directory trees Darrick J. Wong
` (8 subsequent siblings)
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:50 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
There are a number of tests that use xfs_db to examine the contents of
metadata inodes to check correct functioning. The logic is scattered
everywhere and won't work with metadata directory trees, so make a
shared helper to find these inodes.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 32 ++++++++++++++++++++++++++++++--
tests/xfs/007 | 16 +++++++++-------
tests/xfs/529 | 5 ++---
tests/xfs/530 | 6 ++----
tests/xfs/739 | 9 ++-------
tests/xfs/740 | 9 ++-------
tests/xfs/741 | 9 ++-------
tests/xfs/742 | 9 ++-------
tests/xfs/743 | 9 ++-------
tests/xfs/744 | 9 ++-------
tests/xfs/745 | 9 ++-------
tests/xfs/746 | 9 ++-------
12 files changed, 59 insertions(+), 72 deletions(-)
diff --git a/common/xfs b/common/xfs
index f77d4639b9..48643b7c18 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1422,7 +1422,7 @@ _scratch_get_bmx_prefix() {
_scratch_get_iext_count()
{
- local ino=$1
+ local selector=$1
local whichfork=$2
local field=""
@@ -1437,7 +1437,7 @@ _scratch_get_iext_count()
return 1
esac
- _scratch_xfs_get_metadata_field $field "inode $ino"
+ _scratch_xfs_get_metadata_field $field "$selector"
}
#
@@ -1843,3 +1843,31 @@ _require_xfs_parent()
|| _notrun "kernel does not support parent pointers"
_scratch_unmount
}
+
+# Find a metadata file within an xfs filesystem. The sole argument is the
+# name of the field within the superblock.
+_scratch_xfs_find_metafile()
+{
+ local metafile="$1"
+ local selector=
+
+ if ! _check_scratch_xfs_features METADIR > /dev/null; then
+ sb_field="$(_scratch_xfs_get_sb_field "$metafile")"
+ if echo "$sb_field" | grep -q -w 'not found'; then
+ return 1
+ fi
+ selector="inode $sb_field"
+ else
+ case "${metafile}" in
+ "rootino") selector="path /";;
+ "uquotino") selector="path -m /quota/user";;
+ "gquotino") selector="path -m /quota/group";;
+ "pquotino") selector="path -m /quota/project";;
+ "rbmino") selector="path -m /realtime/bitmap";;
+ "rsumino") selector="path -m /realtime/summary";;
+ esac
+ fi
+
+ echo "${selector}"
+ return 0
+}
diff --git a/tests/xfs/007 b/tests/xfs/007
index 4f864100fd..6d6d828b13 100755
--- a/tests/xfs/007
+++ b/tests/xfs/007
@@ -22,6 +22,11 @@ _require_xfs_quota
_scratch_mkfs_xfs | _filter_mkfs > /dev/null 2> $tmp.mkfs
. $tmp.mkfs
+get_qfile_nblocks() {
+ local selector="$(_scratch_xfs_find_metafile "$1")"
+ _scratch_xfs_db -c "$selector" -c "p core.nblocks"
+}
+
do_test()
{
qino_1=$1
@@ -31,12 +36,9 @@ do_test()
echo "*** umount"
_scratch_unmount
- QINO_1=`_scratch_xfs_get_sb_field $qino_1`
- QINO_2=`_scratch_xfs_get_sb_field $qino_2`
-
echo "*** Usage before quotarm ***"
- _scratch_xfs_db -c "inode $QINO_1" -c "p core.nblocks"
- _scratch_xfs_db -c "inode $QINO_2" -c "p core.nblocks"
+ get_qfile_nblocks $qino_1
+ get_qfile_nblocks $qino_2
_qmount
echo "*** turn off $off_opts quotas"
@@ -66,8 +68,8 @@ do_test()
_scratch_unmount
echo "*** Usage after quotarm ***"
- _scratch_xfs_db -c "inode $QINO_1" -c "p core.nblocks"
- _scratch_xfs_db -c "inode $QINO_2" -c "p core.nblocks"
+ get_qfile_nblocks $qino_1
+ get_qfile_nblocks $qino_2
}
# Test user and group first
diff --git a/tests/xfs/529 b/tests/xfs/529
index cd176877f5..43199a37ff 100755
--- a/tests/xfs/529
+++ b/tests/xfs/529
@@ -163,9 +163,8 @@ done
_scratch_unmount >> $seqres.full
echo "Verify uquota inode's extent count"
-uquotino=$(_scratch_xfs_get_metadata_field 'uquotino' 'sb 0')
-
-nextents=$(_scratch_get_iext_count $uquotino data || \
+selector="$(_scratch_xfs_find_metafile uquotino)"
+nextents=$(_scratch_get_iext_count "$selector" data || \
_fail "Unable to obtain inode fork's extent count")
if (( $nextents > 10 )); then
echo "Extent count overflow check failed: nextents = $nextents"
diff --git a/tests/xfs/530 b/tests/xfs/530
index 56f5e7ebdb..cb8c2e3978 100755
--- a/tests/xfs/530
+++ b/tests/xfs/530
@@ -104,10 +104,8 @@ _scratch_unmount >> $seqres.full
echo "Verify rbmino's and rsumino's extent count"
for rtino in rbmino rsumino; do
- ino=$(_scratch_xfs_get_metadata_field $rtino "sb 0")
- echo "$rtino = $ino" >> $seqres.full
-
- nextents=$(_scratch_get_iext_count $ino data || \
+ selector="$(_scratch_xfs_find_metafile "$rtino")"
+ nextents=$(_scratch_get_iext_count "$selector" data || \
_fail "Unable to obtain inode fork's extent count")
if (( $nextents > 10 )); then
echo "Extent count overflow check failed: nextents = $nextents"
diff --git a/tests/xfs/739 b/tests/xfs/739
index fb7fe2e643..b6bbaf7c1d 100755
--- a/tests/xfs/739
+++ b/tests/xfs/739
@@ -27,13 +27,8 @@ echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
echo "Fuzz rtbitmap"
-is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
-if [ -n "$is_metadir" ]; then
- path=('path -m /realtime/0.bitmap')
-else
- path=('sb' 'addr rbmino')
-fi
-_scratch_xfs_fuzz_metadata '' 'online' "${path[@]}" 'dblock 0' >> $seqres.full
+path="$(_scratch_xfs_find_metafile rbmino)"
+_scratch_xfs_fuzz_metadata '' 'online' "$path" 'dblock 0' >> $seqres.full
echo "Done fuzzing rtbitmap"
# success, all done
diff --git a/tests/xfs/740 b/tests/xfs/740
index a59fa37ecf..7cee2b110f 100755
--- a/tests/xfs/740
+++ b/tests/xfs/740
@@ -27,13 +27,8 @@ echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
echo "Fuzz rtsummary"
-is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
-if [ -n "$is_metadir" ]; then
- path=('path -m /realtime/0.summary')
-else
- path=('sb' 'addr rsumino')
-fi
-_scratch_xfs_fuzz_metadata '' 'online' "${path[@]}" 'dblock 0' >> $seqres.full
+path="$(_scratch_xfs_find_metafile rsumino)"
+_scratch_xfs_fuzz_metadata '' 'online' "$path" 'dblock 0' >> $seqres.full
echo "Done fuzzing rtsummary"
# success, all done
diff --git a/tests/xfs/741 b/tests/xfs/741
index 957bed791b..1d18f4d9e4 100755
--- a/tests/xfs/741
+++ b/tests/xfs/741
@@ -27,13 +27,8 @@ echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
echo "Fuzz rtbitmap"
-is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
-if [ -n "$is_metadir" ]; then
- path=('path -m /realtime/0.bitmap')
-else
- path=('sb' 'addr rbmino')
-fi
-_scratch_xfs_fuzz_metadata '' 'offline' "${path[@]}" 'dblock 0' >> $seqres.full
+path="$(_scratch_xfs_find_metafile rbmino)"
+_scratch_xfs_fuzz_metadata '' 'offline' "$path" 'dblock 0' >> $seqres.full
echo "Done fuzzing rtbitmap"
# success, all done
diff --git a/tests/xfs/742 b/tests/xfs/742
index d911748443..96ef89275c 100755
--- a/tests/xfs/742
+++ b/tests/xfs/742
@@ -27,13 +27,8 @@ echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
echo "Fuzz rtsummary"
-is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
-if [ -n "$is_metadir" ]; then
- path=('path -m /realtime/0.summary')
-else
- path=('sb' 'addr rsumino')
-fi
-_scratch_xfs_fuzz_metadata '' 'offline' "${path[@]}" 'dblock 0' >> $seqres.full
+path="$(_scratch_xfs_find_metafile rsumino)"
+_scratch_xfs_fuzz_metadata '' 'offline' "$path" 'dblock 0' >> $seqres.full
echo "Done fuzzing rtsummary"
# success, all done
diff --git a/tests/xfs/743 b/tests/xfs/743
index 69e865a438..29f21e32c6 100755
--- a/tests/xfs/743
+++ b/tests/xfs/743
@@ -28,13 +28,8 @@ echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
echo "Fuzz rtbitmap"
-is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
-if [ -n "$is_metadir" ]; then
- path=('path -m /realtime/0.bitmap')
-else
- path=('sb' 'addr rbmino')
-fi
-_scratch_xfs_fuzz_metadata '' 'both' "${path[@]}" 'dblock 0' >> $seqres.full
+path="$(_scratch_xfs_find_metafile rbmino)"
+_scratch_xfs_fuzz_metadata '' 'both' "$path" 'dblock 0' >> $seqres.full
echo "Done fuzzing rtbitmap"
# success, all done
diff --git a/tests/xfs/744 b/tests/xfs/744
index ea490b524e..72ae8f8593 100755
--- a/tests/xfs/744
+++ b/tests/xfs/744
@@ -28,13 +28,8 @@ echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
echo "Fuzz rtsummary"
-is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
-if [ -n "$is_metadir" ]; then
- path=('path -m /realtime/0.summary')
-else
- path=('sb' 'addr rsumino')
-fi
-_scratch_xfs_fuzz_metadata '' 'both' "${path[@]}" 'dblock 0' >> $seqres.full
+path="$(_scratch_xfs_find_metafile rsumino)"
+_scratch_xfs_fuzz_metadata '' 'both' "$path" 'dblock 0' >> $seqres.full
echo "Done fuzzing rtsummary"
# success, all done
diff --git a/tests/xfs/745 b/tests/xfs/745
index 7621d45744..caecaa4edd 100755
--- a/tests/xfs/745
+++ b/tests/xfs/745
@@ -27,13 +27,8 @@ echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
echo "Fuzz rtbitmap"
-is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.bitmap')
-if [ -n "$is_metadir" ]; then
- path=('path -m /realtime/0.bitmap')
-else
- path=('sb' 'addr rbmino')
-fi
-_scratch_xfs_fuzz_metadata '' 'none' "${path[@]}" 'dblock 0' >> $seqres.full
+path="$(_scratch_xfs_find_metafile rbmino)"
+_scratch_xfs_fuzz_metadata '' 'none' "$path" 'dblock 0' >> $seqres.full
echo "Done fuzzing rtbitmap"
# success, all done
diff --git a/tests/xfs/746 b/tests/xfs/746
index 401233162c..f005893965 100755
--- a/tests/xfs/746
+++ b/tests/xfs/746
@@ -27,13 +27,8 @@ echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
echo "Fuzz rtsummary"
-is_metadir=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime/0.summary')
-if [ -n "$is_metadir" ]; then
- path=('path -m /realtime/0.summary')
-else
- path=('sb' 'addr rsumino')
-fi
-_scratch_xfs_fuzz_metadata '' 'none' "${path[@]}" 'dblock 0' >> $seqres.full
+path="$(_scratch_xfs_find_metafile rsumino)"
+_scratch_xfs_fuzz_metadata '' 'none' "$path" 'dblock 0' >> $seqres.full
echo "Done fuzzing rtsummary"
# success, all done
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 03/11] xfs/{030,033,178}: forcibly disable metadata directory trees
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
2023-12-27 13:50 ` [PATCH 01/11] xfs/122: fix metadirino Darrick J. Wong
2023-12-27 13:50 ` [PATCH 02/11] various: fix finding metadata inode numbers when metadir is enabled Darrick J. Wong
@ 2023-12-27 13:50 ` Darrick J. Wong
2023-12-27 13:50 ` [PATCH 04/11] common/repair: patch up repair sb inode value complaints Darrick J. Wong
` (7 subsequent siblings)
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:50 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The golden output for thests tests encode the xfs_repair output when we
fuzz various parts of the filesystem. With metadata directory trees
enabled, however, the golden output changes dramatically to reflect
reconstruction of the metadata directory tree.
To avoid regressions, add a helper to force metadata directories off via
MKFS_OPTIONS.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 13 +++++++++++++
tests/xfs/030 | 1 +
tests/xfs/033 | 1 +
tests/xfs/178 | 1 +
4 files changed, 16 insertions(+)
diff --git a/common/xfs b/common/xfs
index 48643b7c18..007c8704ce 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1871,3 +1871,16 @@ _scratch_xfs_find_metafile()
echo "${selector}"
return 0
}
+
+# Force metadata directories off.
+_scratch_xfs_force_no_metadir()
+{
+ if echo "$MKFS_OPTIONS" | grep -q 'metadir='; then
+ MKFS_OPTIONS="$(echo "$MKFS_OPTIONS" | sed -e 's/metadir=\([01]\)/metadir=0/g')"
+ return
+ fi
+
+ if grep -q 'metadir=' $MKFS_XFS_PROG; then
+ MKFS_OPTIONS="-m metadir=0 $MKFS_OPTIONS"
+ fi
+}
diff --git a/tests/xfs/030 b/tests/xfs/030
index 201a901579..a62ea4fab3 100755
--- a/tests/xfs/030
+++ b/tests/xfs/030
@@ -50,6 +50,7 @@ _supported_fs xfs
_require_scratch
_require_no_large_scratch_dev
+_scratch_xfs_force_no_metadir
DSIZE="-dsize=100m,agcount=6"
diff --git a/tests/xfs/033 b/tests/xfs/033
index ef5dc4fa36..e886c15082 100755
--- a/tests/xfs/033
+++ b/tests/xfs/033
@@ -53,6 +53,7 @@ _supported_fs xfs
_require_scratch
_require_no_large_scratch_dev
+_scratch_xfs_force_no_metadir
# devzero blows away 512byte blocks, so make 512byte inodes (at least)
_scratch_mkfs_xfs | _filter_mkfs 2>$tmp.mkfs >/dev/null
diff --git a/tests/xfs/178 b/tests/xfs/178
index fee1e92bf3..4e39cc364c 100755
--- a/tests/xfs/178
+++ b/tests/xfs/178
@@ -52,6 +52,7 @@ _supported_fs xfs
# fix filesystem, new mkfs.xfs will be fine.
_require_scratch
+_scratch_xfs_force_no_metadir
_scratch_mkfs_xfs | _filter_mkfs 2>$tmp.mkfs
test "${PIPESTATUS[0]}" -eq 0 || _fail "mkfs failed!"
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 04/11] common/repair: patch up repair sb inode value complaints
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (2 preceding siblings ...)
2023-12-27 13:50 ` [PATCH 03/11] xfs/{030,033,178}: forcibly disable metadata directory trees Darrick J. Wong
@ 2023-12-27 13:50 ` Darrick J. Wong
2023-12-27 13:51 ` [PATCH 05/11] xfs/206: update for metadata directory support Darrick J. Wong
` (6 subsequent siblings)
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:50 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Now that we've refactored xfs_repair to be more consistent in how it
reports unexpected superblock inode pointer values, we have to fix up
the fstests repair filters to emulate the old golden output.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/repair | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/common/repair b/common/repair
index 8945d0028c..c3afcfb3e6 100644
--- a/common/repair
+++ b/common/repair
@@ -28,6 +28,10 @@ _filter_repair()
perl -ne '
# for sb
/- agno = / && next; # remove each AG line (variable number)
+s/realtime bitmap inode pointer/realtime bitmap ino pointer/;
+s/sb realtime bitmap inode value/sb realtime bitmap inode/;
+s/realtime summary inode pointer/realtime summary ino pointer/;
+s/sb realtime summary inode value/sb realtime summary inode/;
s/(pointer to) (\d+)/\1 INO/;
# Changed inode output in 5.5.0
s/sb root inode value /sb root inode /;
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 05/11] xfs/206: update for metadata directory support
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (3 preceding siblings ...)
2023-12-27 13:50 ` [PATCH 04/11] common/repair: patch up repair sb inode value complaints Darrick J. Wong
@ 2023-12-27 13:51 ` Darrick J. Wong
2023-12-27 13:51 ` [PATCH 06/11] xfs/{050,144,153,299,330}: update quota reports to handle metadir trees Darrick J. Wong
` (5 subsequent siblings)
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:51 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Filter 'metadir=' out of the golden output so that metadata directories
don't cause this test to regress.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/206 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/xfs/206 b/tests/xfs/206
index f7f12ff1f9..9fd9400daf 100755
--- a/tests/xfs/206
+++ b/tests/xfs/206
@@ -65,7 +65,8 @@ mkfs_filter()
-e "s/, lazy-count=[0-9]//" \
-e "/.*crc=/d" \
-e "/^Default configuration/d" \
- -e 's/, parent=[01]//'
+ -e 's/, parent=[01]//' \
+ -e '/metadir=.*/d'
}
# mkfs slightly smaller than that, small log for speed.
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 06/11] xfs/{050,144,153,299,330}: update quota reports to handle metadir trees
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (4 preceding siblings ...)
2023-12-27 13:51 ` [PATCH 05/11] xfs/206: update for metadata directory support Darrick J. Wong
@ 2023-12-27 13:51 ` Darrick J. Wong
2023-12-27 13:51 ` [PATCH 07/11] xfs/856: add metadir upgrade to test matrix Darrick J. Wong
` (4 subsequent siblings)
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:51 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Prior to the new metadir feature in XFS, the rtbitmap and rtsummary
files were included in icount, though their bcount contribution is zero
due to rt and quota not being supported together. With the new metadir
feature in XFS, no files in the metadata directory tree are counted in
quota.
Hence we must adjust the icount of any quota report down by two to avoid
breaking golden outputs.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/filter | 7 +++++--
common/xfs | 29 +++++++++++++++++++++++++++++
tests/xfs/050 | 5 +++++
tests/xfs/153 | 5 +++++
tests/xfs/299 | 1 +
tests/xfs/330 | 6 +++++-
6 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/common/filter b/common/filter
index 509ee95039..904263b3e7 100644
--- a/common/filter
+++ b/common/filter
@@ -618,11 +618,14 @@ _filter_getcap()
# Filter user/group/project id numbers out of quota reports, and standardize
# the block counts to use filesystem block size. Callers must set the id and
-# bsize variables before calling this function.
+# bsize variables before calling this function. The HIDDEN_QUOTA_FILES variable
+# (by default zero) is the number of root files to filter out of the inode
+# count part of the quota report.
_filter_quota_report()
{
test -n "$id" || echo "id must be set"
test -n "$bsize" || echo "block size must be set"
+ test -n "$HIDDEN_QUOTA_FILES" || HIDDEN_QUOTA_FILES=0
tr -s '[:space:]' | \
perl -npe '
@@ -630,7 +633,7 @@ _filter_quota_report()
s/^\#0 \d+ /[ROOT] 0 /g;
s/6 days/7 days/g' |
perl -npe '
- $val = 0;
+ $val = '"$HIDDEN_QUOTA_FILES"';
if ($ENV{'LARGE_SCRATCH_DEV'}) {
$val = $ENV{'NUM_SPACE_FILES'};
}
diff --git a/common/xfs b/common/xfs
index 007c8704ce..c6a60119f9 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1884,3 +1884,32 @@ _scratch_xfs_force_no_metadir()
MKFS_OPTIONS="-m metadir=0 $MKFS_OPTIONS"
fi
}
+
+# Decide if a mount filesystem has metadata directory trees.
+_xfs_mount_has_metadir() {
+ local mount="$1"
+
+ # spaceman (and its info command) predate metadir
+ test ! -e "$XFS_SPACEMAN_PROG" && return 1
+ $XFS_SPACEMAN_PROG -c "info" "$mount" | grep -q 'metadir=1'
+}
+
+# Compute the number of files that are not counted in quotas.
+_xfs_calc_hidden_quota_files() {
+ local mount="$1"
+
+ if _xfs_mount_has_metadir "$mount"; then
+ # Prior to the metadir feature, the realtime bitmap and summary
+ # file were "owned" by root and hence accounted to the root
+ # dquots. The metadata directory feature stopped accounting
+ # metadata files to quotas, so we must subtract 2 inodes from
+ # the repquota golden outputs to keep the tests going.
+ #
+ # We needn't adjust the block counts because the kernel doesn't
+ # support rt quota and hence the rt metadata files will always
+ # be zero length.
+ echo -2
+ else
+ echo 0
+ fi
+}
diff --git a/tests/xfs/050 b/tests/xfs/050
index 2220e47016..10294e3f6d 100755
--- a/tests/xfs/050
+++ b/tests/xfs/050
@@ -32,9 +32,14 @@ _require_scratch
_require_xfs_quota
_scratch_mkfs >/dev/null 2>&1
+orig_mntopts="$MOUNT_OPTIONS"
+_qmount_option "uquota"
_scratch_mount
bsize=$(_get_file_block_size $SCRATCH_MNT)
+# needs quota enabled to compute the number of metadata dir files
+HIDDEN_QUOTA_FILES=$(_xfs_calc_hidden_quota_files $SCRATCH_MNT)
_scratch_unmount
+MOUNT_OPTIONS="$orig_mntopts"
bsoft=$(( 200 * $bsize ))
bhard=$(( 1000 * $bsize ))
diff --git a/tests/xfs/153 b/tests/xfs/153
index dbe26b6803..9def579bba 100755
--- a/tests/xfs/153
+++ b/tests/xfs/153
@@ -37,9 +37,14 @@ _require_idmapped_mounts
_require_test_program "vfs/mount-idmapped"
_scratch_mkfs >/dev/null 2>&1
+orig_mntopts="$MOUNT_OPTIONS"
+_qmount_option "uquota"
_scratch_mount
bsize=$(_get_file_block_size $SCRATCH_MNT)
+# needs quota enabled to compute the number of metadata dir files
+HIDDEN_QUOTA_FILES=$(_xfs_calc_hidden_quota_files $SCRATCH_MNT)
_scratch_unmount
+MOUNT_OPTIONS="$orig_mntopts"
bsoft=$(( 200 * $bsize ))
bhard=$(( 1000 * $bsize ))
diff --git a/tests/xfs/299 b/tests/xfs/299
index 4b9df3c6aa..49a6527255 100755
--- a/tests/xfs/299
+++ b/tests/xfs/299
@@ -159,6 +159,7 @@ _qmount_option "uquota,gquota,pquota"
_qmount
bsize=$(_get_file_block_size $SCRATCH_MNT)
+HIDDEN_QUOTA_FILES=$(_xfs_calc_hidden_quota_files $SCRATCH_MNT)
bsoft=$(( 100 * $bsize ))
bhard=$(( 500 * $bsize ))
diff --git a/tests/xfs/330 b/tests/xfs/330
index c6e74e67e8..7ebbffff2a 100755
--- a/tests/xfs/330
+++ b/tests/xfs/330
@@ -26,7 +26,10 @@ _require_nobody
do_repquota()
{
- repquota $SCRATCH_MNT | grep -E '^(fsgqa|root|nobody)' | sort -r
+ repquota $SCRATCH_MNT | grep -E '^(fsgqa|root|nobody)' | sort -r | \
+ perl -npe '
+ $val = '"$HIDDEN_QUOTA_FILES"';
+ s/(^root\s+--\s+\S+\s+\S+\s+\S+\s+)(\S+)/$1@{[$2 - $val]}/g'
}
rm -f "$seqres.full"
@@ -35,6 +38,7 @@ echo "Format and mount"
_scratch_mkfs > "$seqres.full" 2>&1
export MOUNT_OPTIONS="-o usrquota,grpquota $MOUNT_OPTIONS"
_scratch_mount >> "$seqres.full" 2>&1
+HIDDEN_QUOTA_FILES=$(_xfs_calc_hidden_quota_files $SCRATCH_MNT)
quotacheck -u -g $SCRATCH_MNT 2> /dev/null
quotaon $SCRATCH_MNT 2> /dev/null
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 07/11] xfs/856: add metadir upgrade to test matrix
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (5 preceding siblings ...)
2023-12-27 13:51 ` [PATCH 06/11] xfs/{050,144,153,299,330}: update quota reports to handle metadir trees Darrick J. Wong
@ 2023-12-27 13:51 ` Darrick J. Wong
2023-12-27 13:51 ` [PATCH 08/11] xfs/509: adjust inumbers accounting for metadata directories Darrick J. Wong
` (3 subsequent siblings)
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:51 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Add metadata directory trees to the features that this test will try to
upgrade.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1856 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/xfs/1856 b/tests/xfs/1856
index 84e72d7c81..93bdbaa531 100755
--- a/tests/xfs/1856
+++ b/tests/xfs/1856
@@ -173,12 +173,14 @@ if rt_configured; then
check_repair_upgrade finobt && FEATURES+=("finobt")
check_repair_upgrade inobtcount && FEATURES+=("inobtcount")
check_repair_upgrade bigtime && FEATURES+=("bigtime")
+ check_repair_upgrade metadir && FEATURES+=("metadir")
else
check_repair_upgrade finobt && FEATURES+=("finobt")
check_repair_upgrade rmapbt && FEATURES+=("rmapbt")
check_repair_upgrade reflink && FEATURES+=("reflink")
check_repair_upgrade inobtcount && FEATURES+=("inobtcount")
check_repair_upgrade bigtime && FEATURES+=("bigtime")
+ check_repair_upgrade metadir && FEATURES+=("metadir")
fi
test "${#FEATURES[@]}" -eq 0 && \
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 08/11] xfs/509: adjust inumbers accounting for metadata directories
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (6 preceding siblings ...)
2023-12-27 13:51 ` [PATCH 07/11] xfs/856: add metadir upgrade to test matrix Darrick J. Wong
@ 2023-12-27 13:51 ` Darrick J. Wong
2023-12-27 13:52 ` [PATCH 09/11] xfs: create fuzz tests " Darrick J. Wong
` (2 subsequent siblings)
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:51 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The INUMBERS ioctl exports data from the inode btree directly -- the
number of inodes it reports is taken from ir_freemask and includes all
the files in the metadata directory tree. BULKSTAT, on the other hand,
only reports non-metadata files. When metadir is enabled, this will
(eventually) cause a discrepancy in the inode counts that is large
enough to exceed the tolerances, thereby causing a test failure.
Correct this by counting the files in the metadata directory and
subtracting that from the INUMBERS totals.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/509 | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/tests/xfs/509 b/tests/xfs/509
index d04dfbbfba..b87abef964 100755
--- a/tests/xfs/509
+++ b/tests/xfs/509
@@ -91,13 +91,13 @@ inumbers_count()
bstat_versions | while read v_tag v_flag; do
echo -n "inumbers all($v_tag): "
nr=$(inumbers_fs $SCRATCH_MNT $v_flag)
- _within_tolerance "inumbers" $nr $expect $tolerance -v
+ _within_tolerance "inumbers" $((nr - METADATA_FILES)) $expect $tolerance -v
local agcount=$(_xfs_mount_agcount $SCRATCH_MNT)
for batchsize in 71 2 1; do
echo -n "inumbers $batchsize($v_tag): "
nr=$(inumbers_ag $agcount $batchsize $SCRATCH_MNT $v_flag)
- _within_tolerance "inumbers" $nr $expect $tolerance -v
+ _within_tolerance "inumbers" $((nr - METADATA_FILES)) $expect $tolerance -v
done
done
}
@@ -143,9 +143,26 @@ _supported_fs xfs
DIRCOUNT=8
INOCOUNT=$((2048 / DIRCOUNT))
+# Count everything in the metadata directory tree.
+count_metadir_files() {
+ local metadirs=('/realtime' '/quota')
+ local db_args=('-f')
+
+ for m in "${metadirs[@]}"; do
+ db_args+=('-c' "ls -m $m")
+ done
+
+ local ret=$(_scratch_xfs_db "${db_args[@]}" 2>/dev/null | grep regular | wc -l)
+ test -z "$ret" && ret=0
+ echo $ret
+}
+
_scratch_mkfs "-d agcount=$DIRCOUNT" >> $seqres.full 2>&1 || _fail "mkfs failed"
_scratch_mount
+METADATA_FILES=$(count_metadir_files)
+echo "found $METADATA_FILES metadata files" >> $seqres.full
+
# Figure out if we have v5 bulkstat/inumbers ioctls.
has_v5=
bs_root_out="$($XFS_IO_PROG -c 'bulkstat_single root' $SCRATCH_MNT 2>>$seqres.full)"
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 09/11] xfs: create fuzz tests for metadata directories
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (7 preceding siblings ...)
2023-12-27 13:51 ` [PATCH 08/11] xfs/509: adjust inumbers accounting for metadata directories Darrick J. Wong
@ 2023-12-27 13:52 ` Darrick J. Wong
2023-12-27 13:52 ` [PATCH 10/11] xfs: baseline golden output for metadata directory fuzz tests Darrick J. Wong
2023-12-27 13:52 ` [PATCH 11/11] xfs: test metapath repairs Darrick J. Wong
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:52 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Create fuzz tests to make sure that all the validation works for
metadata directories and subdirectories.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 22 ++++++++++++++++++++++
tests/xfs/1546 | 37 +++++++++++++++++++++++++++++++++++++
tests/xfs/1546.out | 4 ++++
tests/xfs/1547 | 37 +++++++++++++++++++++++++++++++++++++
tests/xfs/1547.out | 4 ++++
tests/xfs/1548 | 37 +++++++++++++++++++++++++++++++++++++
tests/xfs/1548.out | 4 ++++
tests/xfs/1549 | 38 ++++++++++++++++++++++++++++++++++++++
tests/xfs/1549.out | 4 ++++
tests/xfs/1550 | 37 +++++++++++++++++++++++++++++++++++++
tests/xfs/1550.out | 4 ++++
tests/xfs/1551 | 37 +++++++++++++++++++++++++++++++++++++
tests/xfs/1551.out | 4 ++++
tests/xfs/1552 | 37 +++++++++++++++++++++++++++++++++++++
tests/xfs/1552.out | 4 ++++
tests/xfs/1553 | 38 ++++++++++++++++++++++++++++++++++++++
tests/xfs/1553.out | 4 ++++
17 files changed, 352 insertions(+)
create mode 100755 tests/xfs/1546
create mode 100644 tests/xfs/1546.out
create mode 100755 tests/xfs/1547
create mode 100644 tests/xfs/1547.out
create mode 100755 tests/xfs/1548
create mode 100644 tests/xfs/1548.out
create mode 100755 tests/xfs/1549
create mode 100644 tests/xfs/1549.out
create mode 100755 tests/xfs/1550
create mode 100644 tests/xfs/1550.out
create mode 100755 tests/xfs/1551
create mode 100644 tests/xfs/1551.out
create mode 100755 tests/xfs/1552
create mode 100644 tests/xfs/1552.out
create mode 100755 tests/xfs/1553
create mode 100644 tests/xfs/1553.out
diff --git a/common/xfs b/common/xfs
index c6a60119f9..b88491666d 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1913,3 +1913,25 @@ _xfs_calc_hidden_quota_files() {
echo 0
fi
}
+
+_require_xfs_mkfs_metadir()
+{
+ _scratch_mkfs_xfs_supported -m metadir=1 >/dev/null 2>&1 || \
+ _notrun "mkfs.xfs doesn't have metadir features"
+}
+
+_require_xfs_scratch_metadir()
+{
+ _require_xfs_mkfs_metadir
+ _require_scratch
+
+ _scratch_mkfs -m metadir=1 &> /dev/null
+ _require_scratch_xfs_features METADIR
+ _try_scratch_mount
+ res=$?
+ if [ $res -ne 0 ]; then
+ _notrun "mounting with metadir not supported by filesystem type: $FSTYP"
+ else
+ _scratch_unmount
+ fi
+}
diff --git a/tests/xfs/1546 b/tests/xfs/1546
new file mode 100755
index 0000000000..a370eb7abf
--- /dev/null
+++ b/tests/xfs/1546
@@ -0,0 +1,37 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1546
+#
+# Populate a XFS filesystem and fuzz every metadir root field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_scratch_metadir
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /')
+
+echo "Fuzz metadir root"
+_scratch_xfs_fuzz_metadata '' 'online' 'path -m /' >> $seqres.full
+echo "Done fuzzing metadir root"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1546.out b/tests/xfs/1546.out
new file mode 100644
index 0000000000..b72891a758
--- /dev/null
+++ b/tests/xfs/1546.out
@@ -0,0 +1,4 @@
+QA output created by 1546
+Format and populate
+Fuzz metadir root
+Done fuzzing metadir root
diff --git a/tests/xfs/1547 b/tests/xfs/1547
new file mode 100755
index 0000000000..0083924b7b
--- /dev/null
+++ b/tests/xfs/1547
@@ -0,0 +1,37 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1547
+#
+# Populate a XFS filesystem and fuzz every metadir root field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_scratch_metadir
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /')
+
+echo "Fuzz metadir root"
+_scratch_xfs_fuzz_metadata '' 'offline' 'path -m /' >> $seqres.full
+echo "Done fuzzing metadir root"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1547.out b/tests/xfs/1547.out
new file mode 100644
index 0000000000..983cc01343
--- /dev/null
+++ b/tests/xfs/1547.out
@@ -0,0 +1,4 @@
+QA output created by 1547
+Format and populate
+Fuzz metadir root
+Done fuzzing metadir root
diff --git a/tests/xfs/1548 b/tests/xfs/1548
new file mode 100755
index 0000000000..d81c524b07
--- /dev/null
+++ b/tests/xfs/1548
@@ -0,0 +1,37 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1548
+#
+# Populate a XFS filesystem and fuzz every metadir root field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_norepair
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_scratch_metadir
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /')
+
+echo "Fuzz metadir root"
+_scratch_xfs_fuzz_metadata '' 'none' 'path -m /' >> $seqres.full
+echo "Done fuzzing metadir root"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1548.out b/tests/xfs/1548.out
new file mode 100644
index 0000000000..9e395bb059
--- /dev/null
+++ b/tests/xfs/1548.out
@@ -0,0 +1,4 @@
+QA output created by 1548
+Format and populate
+Fuzz metadir root
+Done fuzzing metadir root
diff --git a/tests/xfs/1549 b/tests/xfs/1549
new file mode 100755
index 0000000000..487c73e9e9
--- /dev/null
+++ b/tests/xfs/1549
@@ -0,0 +1,38 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1549
+#
+# Populate a XFS filesystem and fuzz every metadir root field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_bothrepair
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_scratch_metadir
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /')
+
+echo "Fuzz metadir root"
+_scratch_xfs_fuzz_metadata '' 'both' 'path -m /' >> $seqres.full
+echo "Done fuzzing metadir root"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1549.out b/tests/xfs/1549.out
new file mode 100644
index 0000000000..22b3d215e3
--- /dev/null
+++ b/tests/xfs/1549.out
@@ -0,0 +1,4 @@
+QA output created by 1549
+Format and populate
+Fuzz metadir root
+Done fuzzing metadir root
diff --git a/tests/xfs/1550 b/tests/xfs/1550
new file mode 100755
index 0000000000..8b5b42710c
--- /dev/null
+++ b/tests/xfs/1550
@@ -0,0 +1,37 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1550
+#
+# Populate a XFS filesystem and fuzz every metadir subdir field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_scratch_metadir
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime')
+
+echo "Fuzz metadir subdir"
+_scratch_xfs_fuzz_metadata '' 'online' 'path -m /realtime' >> $seqres.full
+echo "Done fuzzing metadir subdir"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1550.out b/tests/xfs/1550.out
new file mode 100644
index 0000000000..7694cd670b
--- /dev/null
+++ b/tests/xfs/1550.out
@@ -0,0 +1,4 @@
+QA output created by 1550
+Format and populate
+Fuzz metadir subdir
+Done fuzzing metadir subdir
diff --git a/tests/xfs/1551 b/tests/xfs/1551
new file mode 100755
index 0000000000..05b0328ef0
--- /dev/null
+++ b/tests/xfs/1551
@@ -0,0 +1,37 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1551
+#
+# Populate a XFS filesystem and fuzz every metadir subdir field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_scratch_metadir
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime')
+
+echo "Fuzz metadir subdir"
+_scratch_xfs_fuzz_metadata '' 'offline' 'path -m /realtime' >> $seqres.full
+echo "Done fuzzing metadir subdir"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1551.out b/tests/xfs/1551.out
new file mode 100644
index 0000000000..4c3360d08b
--- /dev/null
+++ b/tests/xfs/1551.out
@@ -0,0 +1,4 @@
+QA output created by 1551
+Format and populate
+Fuzz metadir subdir
+Done fuzzing metadir subdir
diff --git a/tests/xfs/1552 b/tests/xfs/1552
new file mode 100755
index 0000000000..0870837f9c
--- /dev/null
+++ b/tests/xfs/1552
@@ -0,0 +1,37 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1552
+#
+# Populate a XFS filesystem and fuzz every metadir subdir field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_norepair
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_scratch_metadir
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime')
+
+echo "Fuzz metadir subdir"
+_scratch_xfs_fuzz_metadata '' 'none' 'path -m /realtime' >> $seqres.full
+echo "Done fuzzing metadir subdir"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1552.out b/tests/xfs/1552.out
new file mode 100644
index 0000000000..6636b1b656
--- /dev/null
+++ b/tests/xfs/1552.out
@@ -0,0 +1,4 @@
+QA output created by 1552
+Format and populate
+Fuzz metadir subdir
+Done fuzzing metadir subdir
diff --git a/tests/xfs/1553 b/tests/xfs/1553
new file mode 100755
index 0000000000..ab15e53e27
--- /dev/null
+++ b/tests/xfs/1553
@@ -0,0 +1,38 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1553
+#
+# Populate a XFS filesystem and fuzz every metadir subdir field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_bothrepair
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_scratch_metadir
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'path -m /realtime')
+
+echo "Fuzz metadir subdir"
+_scratch_xfs_fuzz_metadata '' 'both' 'path -m /realtime' >> $seqres.full
+echo "Done fuzzing metadir subdir"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1553.out b/tests/xfs/1553.out
new file mode 100644
index 0000000000..0298fcfddb
--- /dev/null
+++ b/tests/xfs/1553.out
@@ -0,0 +1,4 @@
+QA output created by 1553
+Format and populate
+Fuzz metadir subdir
+Done fuzzing metadir subdir
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 10/11] xfs: baseline golden output for metadata directory fuzz tests
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (8 preceding siblings ...)
2023-12-27 13:52 ` [PATCH 09/11] xfs: create fuzz tests " Darrick J. Wong
@ 2023-12-27 13:52 ` Darrick J. Wong
2023-12-27 13:52 ` [PATCH 11/11] xfs: test metapath repairs Darrick J. Wong
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:52 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Record all the currently known failures of the xfs_scrub check and
repair code for the metadata directory fuzz tests.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1546.out | 312 ++++++++++++++++++++++++++++++++++++++
tests/xfs/1547.out | 32 ++++
tests/xfs/1548.out | 314 ++++++++++++++++++++++++++++++++++++++
tests/xfs/1549.out | 326 +++++++++++++++++++++++++++++++++++++++
tests/xfs/1550.out | 430 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1551.out | 31 ++++
tests/xfs/1552.out | 339 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/1553.out | 366 ++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 2150 insertions(+)
diff --git a/tests/xfs/1546.out b/tests/xfs/1546.out
index b72891a758..cdfffd1609 100644
--- a/tests/xfs/1546.out
+++ b/tests/xfs/1546.out
@@ -1,4 +1,316 @@
QA output created by 1546
Format and populate
Fuzz metadir root
+core.magic = zeroes: mount failed (32).
+core.magic = ones: mount failed (32).
+core.magic = firstbit: mount failed (32).
+core.magic = middlebit: mount failed (32).
+core.magic = lastbit: mount failed (32).
+core.magic = add: mount failed (32).
+core.magic = sub: mount failed (32).
+core.mode = zeroes: mount failed (32).
+core.mode = ones: mount failed (32).
+core.mode = firstbit: mount failed (32).
+core.mode = middlebit: mount failed (32).
+core.mode = lastbit: mount failed (32).
+core.mode = add: mount failed (32).
+core.mode = sub: mount failed (32).
+core.version = zeroes: mount failed (32).
+core.version = ones: mount failed (32).
+core.version = firstbit: mount failed (32).
+core.version = middlebit: mount failed (32).
+core.version = lastbit: mount failed (32).
+core.version = add: mount failed (32).
+core.version = sub: mount failed (32).
+core.format = zeroes: mount failed (32).
+core.format = ones: mount failed (32).
+core.format = firstbit: mount failed (32).
+core.format = middlebit: mount failed (32).
+core.format = lastbit: mount failed (32).
+core.format = add: mount failed (32).
+core.format = sub: mount failed (32).
+core.onlink = ones: mount failed (32).
+core.onlink = firstbit: mount failed (32).
+core.onlink = middlebit: mount failed (32).
+core.onlink = lastbit: mount failed (32).
+core.onlink = add: mount failed (32).
+core.onlink = sub: mount failed (32).
+core.uid = ones: mount failed (32).
+core.uid = firstbit: mount failed (32).
+core.uid = middlebit: mount failed (32).
+core.uid = lastbit: mount failed (32).
+core.uid = add: mount failed (32).
+core.uid = sub: mount failed (32).
+core.gid = ones: mount failed (32).
+core.gid = firstbit: mount failed (32).
+core.gid = middlebit: mount failed (32).
+core.gid = lastbit: mount failed (32).
+core.gid = add: mount failed (32).
+core.gid = sub: mount failed (32).
+core.nlinkv2 = zeroes: mount failed (32).
+core.projid_lo = ones: mount failed (32).
+core.projid_lo = firstbit: mount failed (32).
+core.projid_lo = middlebit: mount failed (32).
+core.projid_lo = lastbit: mount failed (32).
+core.projid_lo = add: mount failed (32).
+core.projid_lo = sub: mount failed (32).
+core.projid_hi = ones: mount failed (32).
+core.projid_hi = firstbit: mount failed (32).
+core.projid_hi = middlebit: mount failed (32).
+core.projid_hi = lastbit: mount failed (32).
+core.projid_hi = add: mount failed (32).
+core.projid_hi = sub: mount failed (32).
+core.nextents = ones: mount failed (32).
+core.nextents = firstbit: mount failed (32).
+core.nextents = middlebit: mount failed (32).
+core.nextents = lastbit: mount failed (32).
+core.nextents = add: mount failed (32).
+core.nextents = sub: mount failed (32).
+core.size = zeroes: mount failed (32).
+core.size = ones: mount failed (32).
+core.size = firstbit: mount failed (32).
+core.size = middlebit: mount failed (32).
+core.size = lastbit: mount failed (32).
+core.size = add: mount failed (32).
+core.size = sub: mount failed (32).
+core.extsize = ones: mount failed (32).
+core.extsize = firstbit: mount failed (32).
+core.extsize = middlebit: mount failed (32).
+core.extsize = lastbit: mount failed (32).
+core.extsize = add: mount failed (32).
+core.extsize = sub: mount failed (32).
+core.naextents = ones: mount failed (32).
+core.naextents = firstbit: mount failed (32).
+core.naextents = middlebit: mount failed (32).
+core.naextents = lastbit: mount failed (32).
+core.naextents = add: mount failed (32).
+core.naextents = sub: mount failed (32).
+core.forkoff = ones: mount failed (32).
+core.forkoff = firstbit: mount failed (32).
+core.forkoff = middlebit: online scrub didn't fail.
+core.forkoff = lastbit: mount failed (32).
+core.forkoff = add: mount failed (32).
+core.forkoff = sub: mount failed (32).
+core.aformat = zeroes: online scrub didn't fail.
+core.aformat = zeroes: offline re-scrub failed (1).
+core.aformat = zeroes: offline post-mod scrub failed (1).
+core.aformat = ones: mount failed (32).
+core.aformat = firstbit: mount failed (32).
+core.aformat = middlebit: mount failed (32).
+core.aformat = lastbit: mount failed (32).
+core.aformat = add: mount failed (32).
+core.aformat = sub: mount failed (32).
+core.realtime = ones: mount failed (32).
+core.realtime = firstbit: mount failed (32).
+core.realtime = middlebit: mount failed (32).
+core.realtime = lastbit: mount failed (32).
+core.realtime = add: mount failed (32).
+core.realtime = sub: mount failed (32).
+core.rtinherit = ones: online scrub didn't fail.
+core.rtinherit = firstbit: online scrub didn't fail.
+core.rtinherit = middlebit: online scrub didn't fail.
+core.rtinherit = lastbit: online scrub didn't fail.
+core.rtinherit = add: online scrub didn't fail.
+core.rtinherit = sub: online scrub didn't fail.
+core.projinherit = ones: online scrub didn't fail.
+core.projinherit = firstbit: online scrub didn't fail.
+core.projinherit = middlebit: online scrub didn't fail.
+core.projinherit = lastbit: online scrub didn't fail.
+core.projinherit = add: online scrub didn't fail.
+core.projinherit = sub: online scrub didn't fail.
+core.nosymlinks = zeroes: mount failed (32).
+core.nosymlinks = firstbit: mount failed (32).
+core.nosymlinks = middlebit: mount failed (32).
+core.nosymlinks = lastbit: mount failed (32).
+core.nosymlinks = add: mount failed (32).
+core.nosymlinks = sub: mount failed (32).
+core.extsz = ones: mount failed (32).
+core.extsz = firstbit: mount failed (32).
+core.extsz = middlebit: mount failed (32).
+core.extsz = lastbit: mount failed (32).
+core.extsz = add: mount failed (32).
+core.extsz = sub: mount failed (32).
+core.extszinherit = ones: mount failed (32).
+core.extszinherit = firstbit: mount failed (32).
+core.extszinherit = middlebit: mount failed (32).
+core.extszinherit = lastbit: mount failed (32).
+core.extszinherit = add: mount failed (32).
+core.extszinherit = sub: mount failed (32).
+next_unlinked = zeroes: mount failed (32).
+next_unlinked = firstbit: mount failed (32).
+next_unlinked = middlebit: mount failed (32).
+next_unlinked = lastbit: mount failed (32).
+next_unlinked = add: online scrub didn't fail.
+next_unlinked = add: offline re-scrub failed (1).
+next_unlinked = add: offline post-mod scrub failed (1).
+next_unlinked = sub: mount failed (32).
+v3.crc = zeroes: mount failed (32).
+v3.crc = ones: mount failed (32).
+v3.crc = firstbit: mount failed (32).
+v3.crc = middlebit: mount failed (32).
+v3.crc = lastbit: mount failed (32).
+v3.crc = add: mount failed (32).
+v3.crc = sub: mount failed (32).
+v3.change_count = zeroes: online scrub didn't fail.
+v3.change_count = ones: online scrub didn't fail.
+v3.change_count = firstbit: online scrub didn't fail.
+v3.change_count = middlebit: online scrub didn't fail.
+v3.change_count = lastbit: online scrub didn't fail.
+v3.change_count = add: online scrub didn't fail.
+v3.change_count = sub: online scrub didn't fail.
+v3.flags2 = zeroes: mount failed (32).
+v3.flags2 = ones: mount failed (32).
+v3.flags2 = firstbit: mount failed (32).
+v3.flags2 = middlebit: online scrub didn't fail.
+v3.flags2 = middlebit: offline re-scrub failed (1).
+v3.flags2 = middlebit: offline post-mod scrub failed (1).
+v3.flags2 = lastbit: mount failed (32).
+v3.flags2 = add: mount failed (32).
+v3.flags2 = sub: mount failed (32).
+v3.cowextsize = ones: mount failed (32).
+v3.cowextsize = firstbit: mount failed (32).
+v3.cowextsize = middlebit: mount failed (32).
+v3.cowextsize = lastbit: mount failed (32).
+v3.cowextsize = add: mount failed (32).
+v3.cowextsize = sub: mount failed (32).
+v3.inumber = zeroes: mount failed (32).
+v3.inumber = ones: mount failed (32).
+v3.inumber = firstbit: mount failed (32).
+v3.inumber = middlebit: mount failed (32).
+v3.inumber = lastbit: mount failed (32).
+v3.inumber = add: mount failed (32).
+v3.inumber = sub: mount failed (32).
+v3.uuid = zeroes: mount failed (32).
+v3.uuid = ones: mount failed (32).
+v3.uuid = firstbit: mount failed (32).
+v3.uuid = middlebit: mount failed (32).
+v3.uuid = lastbit: mount failed (32).
+v3.reflink = ones: mount failed (32).
+v3.reflink = firstbit: mount failed (32).
+v3.reflink = middlebit: mount failed (32).
+v3.reflink = lastbit: mount failed (32).
+v3.reflink = add: mount failed (32).
+v3.reflink = sub: mount failed (32).
+v3.cowextsz = ones: mount failed (32).
+v3.cowextsz = firstbit: mount failed (32).
+v3.cowextsz = middlebit: mount failed (32).
+v3.cowextsz = lastbit: mount failed (32).
+v3.cowextsz = add: mount failed (32).
+v3.cowextsz = sub: mount failed (32).
+v3.nrext64 = zeroes: online scrub didn't fail.
+v3.nrext64 = firstbit: online scrub didn't fail.
+v3.nrext64 = middlebit: online scrub didn't fail.
+v3.nrext64 = lastbit: online scrub didn't fail.
+v3.nrext64 = add: online scrub didn't fail.
+v3.nrext64 = sub: online scrub didn't fail.
+v3.metadir = zeroes: mount failed (32).
+v3.metadir = firstbit: mount failed (32).
+v3.metadir = middlebit: mount failed (32).
+v3.metadir = lastbit: mount failed (32).
+v3.metadir = add: mount failed (32).
+v3.metadir = sub: mount failed (32).
+u3.sfdir3.hdr.count = zeroes: mount failed (32).
+u3.sfdir3.hdr.count = ones: mount failed (32).
+u3.sfdir3.hdr.count = firstbit: mount failed (32).
+u3.sfdir3.hdr.count = middlebit: mount failed (32).
+u3.sfdir3.hdr.count = lastbit: mount failed (32).
+u3.sfdir3.hdr.count = add: mount failed (32).
+u3.sfdir3.hdr.count = sub: mount failed (32).
+u3.sfdir3.hdr.i8count = ones: mount failed (32).
+u3.sfdir3.hdr.i8count = firstbit: mount failed (32).
+u3.sfdir3.hdr.i8count = middlebit: mount failed (32).
+u3.sfdir3.hdr.i8count = lastbit: mount failed (32).
+u3.sfdir3.hdr.i8count = add: mount failed (32).
+u3.sfdir3.hdr.i8count = sub: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = zeroes: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = ones: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = firstbit: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[0].namelen = ones: mount failed (32).
+u3.sfdir3.list[0].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[0].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[0].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[0].namelen = add: mount failed (32).
+u3.sfdir3.list[0].namelen = sub: mount failed (32).
+u3.sfdir3.list[0].offset = zeroes: mount failed (32).
+u3.sfdir3.list[0].offset = ones: mount failed (32).
+u3.sfdir3.list[0].offset = firstbit: mount failed (32).
+u3.sfdir3.list[0].offset = middlebit: mount failed (32).
+u3.sfdir3.list[0].offset = lastbit: mount failed (32).
+u3.sfdir3.list[0].offset = add: mount failed (32).
+u3.sfdir3.list[0].offset = sub: mount failed (32).
+u3.sfdir3.list[0].name = zeroes: mount failed (32).
+u3.sfdir3.list[0].name = ones: mount failed (32).
+u3.sfdir3.list[0].name = firstbit: mount failed (32).
+u3.sfdir3.list[0].name = middlebit: mount failed (32).
+u3.sfdir3.list[0].name = lastbit: mount failed (32).
+u3.sfdir3.list[0].name = add: mount failed (32).
+u3.sfdir3.list[0].name = sub: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[0].filetype = ones: mount failed (32).
+u3.sfdir3.list[0].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[0].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[0].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[0].filetype = add: mount failed (32).
+u3.sfdir3.list[0].filetype = sub: mount failed (32).
+u3.sfdir3.list[1].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[1].namelen = ones: mount failed (32).
+u3.sfdir3.list[1].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[1].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[1].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[1].namelen = add: mount failed (32).
+u3.sfdir3.list[1].namelen = sub: mount failed (32).
+u3.sfdir3.list[1].offset = zeroes: mount failed (32).
+u3.sfdir3.list[1].offset = ones: mount failed (32).
+u3.sfdir3.list[1].offset = firstbit: mount failed (32).
+u3.sfdir3.list[1].offset = middlebit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = add: online scrub didn't fail.
+u3.sfdir3.list[1].offset = sub: mount failed (32).
+u3.sfdir3.list[1].name = zeroes: online repair failed (4).
+u3.sfdir3.list[1].name = zeroes: online re-scrub failed (4).
+u3.sfdir3.list[1].name = zeroes: offline re-scrub failed (1).
+u3.sfdir3.list[1].name = zeroes: pre-mod mount failed (32).
+u3.sfdir3.list[1].name = ones: online repair failed (4).
+u3.sfdir3.list[1].name = ones: online re-scrub failed (4).
+u3.sfdir3.list[1].name = ones: offline re-scrub failed (1).
+u3.sfdir3.list[1].name = ones: pre-mod mount failed (32).
+u3.sfdir3.list[1].name = firstbit: online repair failed (4).
+u3.sfdir3.list[1].name = firstbit: online re-scrub failed (4).
+u3.sfdir3.list[1].name = firstbit: offline re-scrub failed (1).
+u3.sfdir3.list[1].name = firstbit: pre-mod mount failed (32).
+u3.sfdir3.list[1].name = lastbit: online repair failed (4).
+u3.sfdir3.list[1].name = lastbit: online re-scrub failed (4).
+u3.sfdir3.list[1].name = lastbit: offline re-scrub failed (1).
+u3.sfdir3.list[1].name = lastbit: pre-mod mount failed (32).
+u3.sfdir3.list[1].name = add: online repair failed (4).
+u3.sfdir3.list[1].name = add: online re-scrub failed (4).
+u3.sfdir3.list[1].name = add: offline re-scrub failed (1).
+u3.sfdir3.list[1].name = add: pre-mod mount failed (32).
+u3.sfdir3.list[1].name = sub: online repair failed (4).
+u3.sfdir3.list[1].name = sub: online re-scrub failed (4).
+u3.sfdir3.list[1].name = sub: offline re-scrub failed (1).
+u3.sfdir3.list[1].name = sub: pre-mod mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[1].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[1].filetype = ones: mount failed (32).
+u3.sfdir3.list[1].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[1].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[1].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[1].filetype = add: mount failed (32).
+u3.sfdir3.list[1].filetype = sub: mount failed (32).
Done fuzzing metadir root
diff --git a/tests/xfs/1547.out b/tests/xfs/1547.out
index 983cc01343..662d04321f 100644
--- a/tests/xfs/1547.out
+++ b/tests/xfs/1547.out
@@ -1,4 +1,36 @@
QA output created by 1547
Format and populate
Fuzz metadir root
+core.forkoff = middlebit: offline scrub didn't fail.
+core.rtinherit = ones: offline scrub didn't fail.
+core.rtinherit = firstbit: offline scrub didn't fail.
+core.rtinherit = middlebit: offline scrub didn't fail.
+core.rtinherit = lastbit: offline scrub didn't fail.
+core.rtinherit = add: offline scrub didn't fail.
+core.rtinherit = sub: offline scrub didn't fail.
+core.projinherit = ones: offline scrub didn't fail.
+core.projinherit = firstbit: offline scrub didn't fail.
+core.projinherit = middlebit: offline scrub didn't fail.
+core.projinherit = lastbit: offline scrub didn't fail.
+core.projinherit = add: offline scrub didn't fail.
+core.projinherit = sub: offline scrub didn't fail.
+v3.change_count = zeroes: offline scrub didn't fail.
+v3.change_count = ones: offline scrub didn't fail.
+v3.change_count = firstbit: offline scrub didn't fail.
+v3.change_count = middlebit: offline scrub didn't fail.
+v3.change_count = lastbit: offline scrub didn't fail.
+v3.change_count = add: offline scrub didn't fail.
+v3.change_count = sub: offline scrub didn't fail.
+v3.nrext64 = zeroes: offline scrub didn't fail.
+v3.nrext64 = firstbit: offline scrub didn't fail.
+v3.nrext64 = middlebit: offline scrub didn't fail.
+v3.nrext64 = lastbit: offline scrub didn't fail.
+v3.nrext64 = add: offline scrub didn't fail.
+v3.nrext64 = sub: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = middlebit: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = lastbit: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = add: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = middlebit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = add: offline scrub didn't fail.
Done fuzzing metadir root
diff --git a/tests/xfs/1548.out b/tests/xfs/1548.out
index 9e395bb059..48ee6c02fb 100644
--- a/tests/xfs/1548.out
+++ b/tests/xfs/1548.out
@@ -1,4 +1,318 @@
QA output created by 1548
Format and populate
Fuzz metadir root
+core.magic = zeroes: mount failed (32).
+core.magic = ones: mount failed (32).
+core.magic = firstbit: mount failed (32).
+core.magic = middlebit: mount failed (32).
+core.magic = lastbit: mount failed (32).
+core.magic = add: mount failed (32).
+core.magic = sub: mount failed (32).
+core.mode = zeroes: mount failed (32).
+core.mode = ones: mount failed (32).
+core.mode = firstbit: mount failed (32).
+core.mode = middlebit: mount failed (32).
+core.mode = lastbit: mount failed (32).
+core.mode = add: mount failed (32).
+core.mode = sub: mount failed (32).
+core.version = zeroes: mount failed (32).
+core.version = ones: mount failed (32).
+core.version = firstbit: mount failed (32).
+core.version = middlebit: mount failed (32).
+core.version = lastbit: mount failed (32).
+core.version = add: mount failed (32).
+core.version = sub: mount failed (32).
+core.format = zeroes: mount failed (32).
+core.format = ones: mount failed (32).
+core.format = firstbit: mount failed (32).
+core.format = middlebit: mount failed (32).
+core.format = lastbit: mount failed (32).
+core.format = add: mount failed (32).
+core.format = sub: mount failed (32).
+core.onlink = ones: mount failed (32).
+core.onlink = firstbit: mount failed (32).
+core.onlink = middlebit: mount failed (32).
+core.onlink = lastbit: mount failed (32).
+core.onlink = add: mount failed (32).
+core.onlink = sub: mount failed (32).
+core.uid = ones: mount failed (32).
+core.uid = firstbit: mount failed (32).
+core.uid = middlebit: mount failed (32).
+core.uid = lastbit: mount failed (32).
+core.uid = add: mount failed (32).
+core.uid = sub: mount failed (32).
+core.gid = ones: mount failed (32).
+core.gid = firstbit: mount failed (32).
+core.gid = middlebit: mount failed (32).
+core.gid = lastbit: mount failed (32).
+core.gid = add: mount failed (32).
+core.gid = sub: mount failed (32).
+core.nlinkv2 = zeroes: mount failed (32).
+core.projid_lo = ones: mount failed (32).
+core.projid_lo = firstbit: mount failed (32).
+core.projid_lo = middlebit: mount failed (32).
+core.projid_lo = lastbit: mount failed (32).
+core.projid_lo = add: mount failed (32).
+core.projid_lo = sub: mount failed (32).
+core.projid_hi = ones: mount failed (32).
+core.projid_hi = firstbit: mount failed (32).
+core.projid_hi = middlebit: mount failed (32).
+core.projid_hi = lastbit: mount failed (32).
+core.projid_hi = add: mount failed (32).
+core.projid_hi = sub: mount failed (32).
+core.nextents = ones: mount failed (32).
+core.nextents = firstbit: mount failed (32).
+core.nextents = middlebit: mount failed (32).
+core.nextents = lastbit: mount failed (32).
+core.nextents = add: mount failed (32).
+core.nextents = sub: mount failed (32).
+core.size = zeroes: mount failed (32).
+core.size = ones: mount failed (32).
+core.size = firstbit: mount failed (32).
+core.size = middlebit: mount failed (32).
+core.size = lastbit: mount failed (32).
+core.size = add: mount failed (32).
+core.size = sub: mount failed (32).
+core.extsize = ones: mount failed (32).
+core.extsize = firstbit: mount failed (32).
+core.extsize = middlebit: mount failed (32).
+core.extsize = lastbit: mount failed (32).
+core.extsize = add: mount failed (32).
+core.extsize = sub: mount failed (32).
+core.naextents = ones: mount failed (32).
+core.naextents = firstbit: mount failed (32).
+core.naextents = middlebit: mount failed (32).
+core.naextents = lastbit: mount failed (32).
+core.naextents = add: mount failed (32).
+core.naextents = sub: mount failed (32).
+core.forkoff = ones: mount failed (32).
+core.forkoff = firstbit: mount failed (32).
+core.forkoff = middlebit: offline scrub didn't fail.
+core.forkoff = middlebit: online scrub didn't fail.
+core.forkoff = lastbit: mount failed (32).
+core.forkoff = add: mount failed (32).
+core.forkoff = sub: mount failed (32).
+core.aformat = zeroes: online scrub didn't fail.
+core.aformat = ones: mount failed (32).
+core.aformat = firstbit: mount failed (32).
+core.aformat = middlebit: mount failed (32).
+core.aformat = lastbit: mount failed (32).
+core.aformat = add: mount failed (32).
+core.aformat = sub: mount failed (32).
+core.realtime = ones: mount failed (32).
+core.realtime = firstbit: mount failed (32).
+core.realtime = middlebit: mount failed (32).
+core.realtime = lastbit: mount failed (32).
+core.realtime = add: mount failed (32).
+core.realtime = sub: mount failed (32).
+core.rtinherit = ones: offline scrub didn't fail.
+core.rtinherit = ones: online scrub didn't fail.
+core.rtinherit = firstbit: offline scrub didn't fail.
+core.rtinherit = firstbit: online scrub didn't fail.
+core.rtinherit = middlebit: offline scrub didn't fail.
+core.rtinherit = middlebit: online scrub didn't fail.
+core.rtinherit = lastbit: offline scrub didn't fail.
+core.rtinherit = lastbit: online scrub didn't fail.
+core.rtinherit = add: offline scrub didn't fail.
+core.rtinherit = add: online scrub didn't fail.
+core.rtinherit = sub: offline scrub didn't fail.
+core.rtinherit = sub: online scrub didn't fail.
+core.projinherit = ones: offline scrub didn't fail.
+core.projinherit = ones: online scrub didn't fail.
+core.projinherit = firstbit: offline scrub didn't fail.
+core.projinherit = firstbit: online scrub didn't fail.
+core.projinherit = middlebit: offline scrub didn't fail.
+core.projinherit = middlebit: online scrub didn't fail.
+core.projinherit = lastbit: offline scrub didn't fail.
+core.projinherit = lastbit: online scrub didn't fail.
+core.projinherit = add: offline scrub didn't fail.
+core.projinherit = add: online scrub didn't fail.
+core.projinherit = sub: offline scrub didn't fail.
+core.projinherit = sub: online scrub didn't fail.
+core.nosymlinks = zeroes: mount failed (32).
+core.nosymlinks = firstbit: mount failed (32).
+core.nosymlinks = middlebit: mount failed (32).
+core.nosymlinks = lastbit: mount failed (32).
+core.nosymlinks = add: mount failed (32).
+core.nosymlinks = sub: mount failed (32).
+core.extsz = ones: mount failed (32).
+core.extsz = firstbit: mount failed (32).
+core.extsz = middlebit: mount failed (32).
+core.extsz = lastbit: mount failed (32).
+core.extsz = add: mount failed (32).
+core.extsz = sub: mount failed (32).
+core.extszinherit = ones: mount failed (32).
+core.extszinherit = firstbit: mount failed (32).
+core.extszinherit = middlebit: mount failed (32).
+core.extszinherit = lastbit: mount failed (32).
+core.extszinherit = add: mount failed (32).
+core.extszinherit = sub: mount failed (32).
+next_unlinked = zeroes: mount failed (32).
+next_unlinked = firstbit: mount failed (32).
+next_unlinked = middlebit: mount failed (32).
+next_unlinked = lastbit: mount failed (32).
+next_unlinked = add: online scrub didn't fail.
+next_unlinked = sub: mount failed (32).
+v3.crc = zeroes: mount failed (32).
+v3.crc = ones: mount failed (32).
+v3.crc = firstbit: mount failed (32).
+v3.crc = middlebit: mount failed (32).
+v3.crc = lastbit: mount failed (32).
+v3.crc = add: mount failed (32).
+v3.crc = sub: mount failed (32).
+v3.change_count = zeroes: offline scrub didn't fail.
+v3.change_count = zeroes: online scrub didn't fail.
+v3.change_count = ones: offline scrub didn't fail.
+v3.change_count = ones: online scrub didn't fail.
+v3.change_count = firstbit: offline scrub didn't fail.
+v3.change_count = firstbit: online scrub didn't fail.
+v3.change_count = middlebit: offline scrub didn't fail.
+v3.change_count = middlebit: online scrub didn't fail.
+v3.change_count = lastbit: offline scrub didn't fail.
+v3.change_count = lastbit: online scrub didn't fail.
+v3.change_count = add: offline scrub didn't fail.
+v3.change_count = add: online scrub didn't fail.
+v3.change_count = sub: offline scrub didn't fail.
+v3.change_count = sub: online scrub didn't fail.
+v3.flags2 = zeroes: mount failed (32).
+v3.flags2 = ones: mount failed (32).
+v3.flags2 = firstbit: mount failed (32).
+v3.flags2 = middlebit: online scrub didn't fail.
+v3.flags2 = lastbit: mount failed (32).
+v3.flags2 = add: mount failed (32).
+v3.flags2 = sub: mount failed (32).
+v3.cowextsize = ones: mount failed (32).
+v3.cowextsize = firstbit: mount failed (32).
+v3.cowextsize = middlebit: mount failed (32).
+v3.cowextsize = lastbit: mount failed (32).
+v3.cowextsize = add: mount failed (32).
+v3.cowextsize = sub: mount failed (32).
+v3.inumber = zeroes: mount failed (32).
+v3.inumber = ones: mount failed (32).
+v3.inumber = firstbit: mount failed (32).
+v3.inumber = middlebit: mount failed (32).
+v3.inumber = lastbit: mount failed (32).
+v3.inumber = add: mount failed (32).
+v3.inumber = sub: mount failed (32).
+v3.uuid = zeroes: mount failed (32).
+v3.uuid = ones: mount failed (32).
+v3.uuid = firstbit: mount failed (32).
+v3.uuid = middlebit: mount failed (32).
+v3.uuid = lastbit: mount failed (32).
+v3.reflink = ones: mount failed (32).
+v3.reflink = firstbit: mount failed (32).
+v3.reflink = middlebit: mount failed (32).
+v3.reflink = lastbit: mount failed (32).
+v3.reflink = add: mount failed (32).
+v3.reflink = sub: mount failed (32).
+v3.cowextsz = ones: mount failed (32).
+v3.cowextsz = firstbit: mount failed (32).
+v3.cowextsz = middlebit: mount failed (32).
+v3.cowextsz = lastbit: mount failed (32).
+v3.cowextsz = add: mount failed (32).
+v3.cowextsz = sub: mount failed (32).
+v3.nrext64 = zeroes: offline scrub didn't fail.
+v3.nrext64 = zeroes: online scrub didn't fail.
+v3.nrext64 = firstbit: offline scrub didn't fail.
+v3.nrext64 = firstbit: online scrub didn't fail.
+v3.nrext64 = middlebit: offline scrub didn't fail.
+v3.nrext64 = middlebit: online scrub didn't fail.
+v3.nrext64 = lastbit: offline scrub didn't fail.
+v3.nrext64 = lastbit: online scrub didn't fail.
+v3.nrext64 = add: offline scrub didn't fail.
+v3.nrext64 = add: online scrub didn't fail.
+v3.nrext64 = sub: offline scrub didn't fail.
+v3.nrext64 = sub: online scrub didn't fail.
+v3.metadir = zeroes: mount failed (32).
+v3.metadir = firstbit: mount failed (32).
+v3.metadir = middlebit: mount failed (32).
+v3.metadir = lastbit: mount failed (32).
+v3.metadir = add: mount failed (32).
+v3.metadir = sub: mount failed (32).
+u3.sfdir3.hdr.count = zeroes: mount failed (32).
+u3.sfdir3.hdr.count = ones: mount failed (32).
+u3.sfdir3.hdr.count = firstbit: mount failed (32).
+u3.sfdir3.hdr.count = middlebit: mount failed (32).
+u3.sfdir3.hdr.count = lastbit: mount failed (32).
+u3.sfdir3.hdr.count = add: mount failed (32).
+u3.sfdir3.hdr.count = sub: mount failed (32).
+u3.sfdir3.hdr.i8count = ones: mount failed (32).
+u3.sfdir3.hdr.i8count = firstbit: mount failed (32).
+u3.sfdir3.hdr.i8count = middlebit: mount failed (32).
+u3.sfdir3.hdr.i8count = lastbit: mount failed (32).
+u3.sfdir3.hdr.i8count = add: mount failed (32).
+u3.sfdir3.hdr.i8count = sub: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = zeroes: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = ones: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = firstbit: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = middlebit: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = lastbit: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = add: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[0].namelen = ones: mount failed (32).
+u3.sfdir3.list[0].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[0].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[0].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[0].namelen = add: mount failed (32).
+u3.sfdir3.list[0].namelen = sub: mount failed (32).
+u3.sfdir3.list[0].offset = zeroes: mount failed (32).
+u3.sfdir3.list[0].offset = ones: mount failed (32).
+u3.sfdir3.list[0].offset = firstbit: mount failed (32).
+u3.sfdir3.list[0].offset = middlebit: mount failed (32).
+u3.sfdir3.list[0].offset = lastbit: mount failed (32).
+u3.sfdir3.list[0].offset = add: mount failed (32).
+u3.sfdir3.list[0].offset = sub: mount failed (32).
+u3.sfdir3.list[0].name = zeroes: mount failed (32).
+u3.sfdir3.list[0].name = ones: mount failed (32).
+u3.sfdir3.list[0].name = firstbit: mount failed (32).
+u3.sfdir3.list[0].name = middlebit: mount failed (32).
+u3.sfdir3.list[0].name = lastbit: mount failed (32).
+u3.sfdir3.list[0].name = add: mount failed (32).
+u3.sfdir3.list[0].name = sub: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[0].filetype = ones: mount failed (32).
+u3.sfdir3.list[0].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[0].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[0].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[0].filetype = add: mount failed (32).
+u3.sfdir3.list[0].filetype = sub: mount failed (32).
+u3.sfdir3.list[1].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[1].namelen = ones: mount failed (32).
+u3.sfdir3.list[1].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[1].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[1].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[1].namelen = add: mount failed (32).
+u3.sfdir3.list[1].namelen = sub: mount failed (32).
+u3.sfdir3.list[1].offset = zeroes: mount failed (32).
+u3.sfdir3.list[1].offset = ones: mount failed (32).
+u3.sfdir3.list[1].offset = firstbit: mount failed (32).
+u3.sfdir3.list[1].offset = middlebit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = middlebit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = add: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = add: online scrub didn't fail.
+u3.sfdir3.list[1].offset = sub: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[1].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[1].filetype = ones: mount failed (32).
+u3.sfdir3.list[1].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[1].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[1].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[1].filetype = add: mount failed (32).
+u3.sfdir3.list[1].filetype = sub: mount failed (32).
Done fuzzing metadir root
diff --git a/tests/xfs/1549.out b/tests/xfs/1549.out
index 22b3d215e3..c35f47c31a 100644
--- a/tests/xfs/1549.out
+++ b/tests/xfs/1549.out
@@ -1,4 +1,330 @@
QA output created by 1549
Format and populate
Fuzz metadir root
+core.magic = zeroes: mount failed (32).
+core.magic = ones: mount failed (32).
+core.magic = firstbit: mount failed (32).
+core.magic = middlebit: mount failed (32).
+core.magic = lastbit: mount failed (32).
+core.magic = add: mount failed (32).
+core.magic = sub: mount failed (32).
+core.mode = zeroes: mount failed (32).
+core.mode = ones: mount failed (32).
+core.mode = firstbit: mount failed (32).
+core.mode = middlebit: mount failed (32).
+core.mode = lastbit: mount failed (32).
+core.mode = add: mount failed (32).
+core.mode = sub: mount failed (32).
+core.version = zeroes: mount failed (32).
+core.version = ones: mount failed (32).
+core.version = firstbit: mount failed (32).
+core.version = middlebit: mount failed (32).
+core.version = lastbit: mount failed (32).
+core.version = add: mount failed (32).
+core.version = sub: mount failed (32).
+core.format = zeroes: mount failed (32).
+core.format = ones: mount failed (32).
+core.format = firstbit: mount failed (32).
+core.format = middlebit: mount failed (32).
+core.format = lastbit: mount failed (32).
+core.format = add: mount failed (32).
+core.format = sub: mount failed (32).
+core.onlink = ones: mount failed (32).
+core.onlink = firstbit: mount failed (32).
+core.onlink = middlebit: mount failed (32).
+core.onlink = lastbit: mount failed (32).
+core.onlink = add: mount failed (32).
+core.onlink = sub: mount failed (32).
+core.uid = ones: mount failed (32).
+core.uid = firstbit: mount failed (32).
+core.uid = middlebit: mount failed (32).
+core.uid = lastbit: mount failed (32).
+core.uid = add: mount failed (32).
+core.uid = sub: mount failed (32).
+core.gid = ones: mount failed (32).
+core.gid = firstbit: mount failed (32).
+core.gid = middlebit: mount failed (32).
+core.gid = lastbit: mount failed (32).
+core.gid = add: mount failed (32).
+core.gid = sub: mount failed (32).
+core.nlinkv2 = zeroes: mount failed (32).
+core.projid_lo = ones: mount failed (32).
+core.projid_lo = firstbit: mount failed (32).
+core.projid_lo = middlebit: mount failed (32).
+core.projid_lo = lastbit: mount failed (32).
+core.projid_lo = add: mount failed (32).
+core.projid_lo = sub: mount failed (32).
+core.projid_hi = ones: mount failed (32).
+core.projid_hi = firstbit: mount failed (32).
+core.projid_hi = middlebit: mount failed (32).
+core.projid_hi = lastbit: mount failed (32).
+core.projid_hi = add: mount failed (32).
+core.projid_hi = sub: mount failed (32).
+core.nextents = ones: mount failed (32).
+core.nextents = firstbit: mount failed (32).
+core.nextents = middlebit: mount failed (32).
+core.nextents = lastbit: mount failed (32).
+core.nextents = add: mount failed (32).
+core.nextents = sub: mount failed (32).
+core.size = zeroes: mount failed (32).
+core.size = ones: mount failed (32).
+core.size = firstbit: mount failed (32).
+core.size = middlebit: mount failed (32).
+core.size = lastbit: mount failed (32).
+core.size = add: mount failed (32).
+core.size = sub: mount failed (32).
+core.extsize = ones: mount failed (32).
+core.extsize = firstbit: mount failed (32).
+core.extsize = middlebit: mount failed (32).
+core.extsize = lastbit: mount failed (32).
+core.extsize = add: mount failed (32).
+core.extsize = sub: mount failed (32).
+core.naextents = ones: mount failed (32).
+core.naextents = firstbit: mount failed (32).
+core.naextents = middlebit: mount failed (32).
+core.naextents = lastbit: mount failed (32).
+core.naextents = add: mount failed (32).
+core.naextents = sub: mount failed (32).
+core.forkoff = ones: mount failed (32).
+core.forkoff = firstbit: mount failed (32).
+core.forkoff = middlebit: offline scrub didn't fail.
+core.forkoff = middlebit: online scrub didn't fail.
+core.forkoff = lastbit: mount failed (32).
+core.forkoff = add: mount failed (32).
+core.forkoff = sub: mount failed (32).
+core.aformat = zeroes: online scrub didn't fail.
+core.aformat = zeroes: offline re-scrub failed (1).
+core.aformat = zeroes: offline post-mod scrub failed (1).
+core.aformat = ones: mount failed (32).
+core.aformat = firstbit: mount failed (32).
+core.aformat = middlebit: mount failed (32).
+core.aformat = lastbit: mount failed (32).
+core.aformat = add: mount failed (32).
+core.aformat = sub: mount failed (32).
+core.realtime = ones: mount failed (32).
+core.realtime = firstbit: mount failed (32).
+core.realtime = middlebit: mount failed (32).
+core.realtime = lastbit: mount failed (32).
+core.realtime = add: mount failed (32).
+core.realtime = sub: mount failed (32).
+core.rtinherit = ones: offline scrub didn't fail.
+core.rtinherit = ones: online scrub didn't fail.
+core.rtinherit = firstbit: offline scrub didn't fail.
+core.rtinherit = firstbit: online scrub didn't fail.
+core.rtinherit = middlebit: offline scrub didn't fail.
+core.rtinherit = middlebit: online scrub didn't fail.
+core.rtinherit = lastbit: offline scrub didn't fail.
+core.rtinherit = lastbit: online scrub didn't fail.
+core.rtinherit = add: offline scrub didn't fail.
+core.rtinherit = add: online scrub didn't fail.
+core.rtinherit = sub: offline scrub didn't fail.
+core.rtinherit = sub: online scrub didn't fail.
+core.projinherit = ones: offline scrub didn't fail.
+core.projinherit = ones: online scrub didn't fail.
+core.projinherit = firstbit: offline scrub didn't fail.
+core.projinherit = firstbit: online scrub didn't fail.
+core.projinherit = middlebit: offline scrub didn't fail.
+core.projinherit = middlebit: online scrub didn't fail.
+core.projinherit = lastbit: offline scrub didn't fail.
+core.projinherit = lastbit: online scrub didn't fail.
+core.projinherit = add: offline scrub didn't fail.
+core.projinherit = add: online scrub didn't fail.
+core.projinherit = sub: offline scrub didn't fail.
+core.projinherit = sub: online scrub didn't fail.
+core.nosymlinks = zeroes: mount failed (32).
+core.nosymlinks = firstbit: mount failed (32).
+core.nosymlinks = middlebit: mount failed (32).
+core.nosymlinks = lastbit: mount failed (32).
+core.nosymlinks = add: mount failed (32).
+core.nosymlinks = sub: mount failed (32).
+core.extsz = ones: mount failed (32).
+core.extsz = firstbit: mount failed (32).
+core.extsz = middlebit: mount failed (32).
+core.extsz = lastbit: mount failed (32).
+core.extsz = add: mount failed (32).
+core.extsz = sub: mount failed (32).
+core.extszinherit = ones: mount failed (32).
+core.extszinherit = firstbit: mount failed (32).
+core.extszinherit = middlebit: mount failed (32).
+core.extszinherit = lastbit: mount failed (32).
+core.extszinherit = add: mount failed (32).
+core.extszinherit = sub: mount failed (32).
+next_unlinked = zeroes: mount failed (32).
+next_unlinked = firstbit: mount failed (32).
+next_unlinked = middlebit: mount failed (32).
+next_unlinked = lastbit: mount failed (32).
+next_unlinked = add: online scrub didn't fail.
+next_unlinked = add: offline re-scrub failed (1).
+next_unlinked = add: offline post-mod scrub failed (1).
+next_unlinked = sub: mount failed (32).
+v3.crc = zeroes: mount failed (32).
+v3.crc = ones: mount failed (32).
+v3.crc = firstbit: mount failed (32).
+v3.crc = middlebit: mount failed (32).
+v3.crc = lastbit: mount failed (32).
+v3.crc = add: mount failed (32).
+v3.crc = sub: mount failed (32).
+v3.change_count = zeroes: offline scrub didn't fail.
+v3.change_count = zeroes: online scrub didn't fail.
+v3.change_count = ones: offline scrub didn't fail.
+v3.change_count = ones: online scrub didn't fail.
+v3.change_count = firstbit: offline scrub didn't fail.
+v3.change_count = firstbit: online scrub didn't fail.
+v3.change_count = middlebit: offline scrub didn't fail.
+v3.change_count = middlebit: online scrub didn't fail.
+v3.change_count = lastbit: offline scrub didn't fail.
+v3.change_count = lastbit: online scrub didn't fail.
+v3.change_count = add: offline scrub didn't fail.
+v3.change_count = add: online scrub didn't fail.
+v3.change_count = sub: offline scrub didn't fail.
+v3.change_count = sub: online scrub didn't fail.
+v3.flags2 = zeroes: mount failed (32).
+v3.flags2 = ones: mount failed (32).
+v3.flags2 = firstbit: mount failed (32).
+v3.flags2 = middlebit: online scrub didn't fail.
+v3.flags2 = middlebit: offline re-scrub failed (1).
+v3.flags2 = middlebit: offline post-mod scrub failed (1).
+v3.flags2 = lastbit: mount failed (32).
+v3.flags2 = add: mount failed (32).
+v3.flags2 = sub: mount failed (32).
+v3.cowextsize = ones: mount failed (32).
+v3.cowextsize = firstbit: mount failed (32).
+v3.cowextsize = middlebit: mount failed (32).
+v3.cowextsize = lastbit: mount failed (32).
+v3.cowextsize = add: mount failed (32).
+v3.cowextsize = sub: mount failed (32).
+v3.inumber = zeroes: mount failed (32).
+v3.inumber = ones: mount failed (32).
+v3.inumber = firstbit: mount failed (32).
+v3.inumber = middlebit: mount failed (32).
+v3.inumber = lastbit: mount failed (32).
+v3.inumber = add: mount failed (32).
+v3.inumber = sub: mount failed (32).
+v3.uuid = zeroes: mount failed (32).
+v3.uuid = ones: mount failed (32).
+v3.uuid = firstbit: mount failed (32).
+v3.uuid = middlebit: mount failed (32).
+v3.uuid = lastbit: mount failed (32).
+v3.reflink = ones: mount failed (32).
+v3.reflink = firstbit: mount failed (32).
+v3.reflink = middlebit: mount failed (32).
+v3.reflink = lastbit: mount failed (32).
+v3.reflink = add: mount failed (32).
+v3.reflink = sub: mount failed (32).
+v3.cowextsz = ones: mount failed (32).
+v3.cowextsz = firstbit: mount failed (32).
+v3.cowextsz = middlebit: mount failed (32).
+v3.cowextsz = lastbit: mount failed (32).
+v3.cowextsz = add: mount failed (32).
+v3.cowextsz = sub: mount failed (32).
+v3.nrext64 = zeroes: offline scrub didn't fail.
+v3.nrext64 = zeroes: online scrub didn't fail.
+v3.nrext64 = firstbit: offline scrub didn't fail.
+v3.nrext64 = firstbit: online scrub didn't fail.
+v3.nrext64 = middlebit: offline scrub didn't fail.
+v3.nrext64 = middlebit: online scrub didn't fail.
+v3.nrext64 = lastbit: offline scrub didn't fail.
+v3.nrext64 = lastbit: online scrub didn't fail.
+v3.nrext64 = add: offline scrub didn't fail.
+v3.nrext64 = add: online scrub didn't fail.
+v3.nrext64 = sub: offline scrub didn't fail.
+v3.nrext64 = sub: online scrub didn't fail.
+v3.metadir = zeroes: mount failed (32).
+v3.metadir = firstbit: mount failed (32).
+v3.metadir = middlebit: mount failed (32).
+v3.metadir = lastbit: mount failed (32).
+v3.metadir = add: mount failed (32).
+v3.metadir = sub: mount failed (32).
+u3.sfdir3.hdr.count = zeroes: mount failed (32).
+u3.sfdir3.hdr.count = ones: mount failed (32).
+u3.sfdir3.hdr.count = firstbit: mount failed (32).
+u3.sfdir3.hdr.count = middlebit: mount failed (32).
+u3.sfdir3.hdr.count = lastbit: mount failed (32).
+u3.sfdir3.hdr.count = add: mount failed (32).
+u3.sfdir3.hdr.count = sub: mount failed (32).
+u3.sfdir3.hdr.i8count = ones: mount failed (32).
+u3.sfdir3.hdr.i8count = firstbit: mount failed (32).
+u3.sfdir3.hdr.i8count = middlebit: mount failed (32).
+u3.sfdir3.hdr.i8count = lastbit: mount failed (32).
+u3.sfdir3.hdr.i8count = add: mount failed (32).
+u3.sfdir3.hdr.i8count = sub: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = zeroes: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = ones: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = firstbit: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = middlebit: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = lastbit: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = add: offline scrub didn't fail.
+u3.sfdir3.hdr.parent.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[0].namelen = ones: mount failed (32).
+u3.sfdir3.list[0].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[0].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[0].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[0].namelen = add: mount failed (32).
+u3.sfdir3.list[0].namelen = sub: mount failed (32).
+u3.sfdir3.list[0].offset = zeroes: mount failed (32).
+u3.sfdir3.list[0].offset = ones: mount failed (32).
+u3.sfdir3.list[0].offset = firstbit: mount failed (32).
+u3.sfdir3.list[0].offset = middlebit: mount failed (32).
+u3.sfdir3.list[0].offset = lastbit: mount failed (32).
+u3.sfdir3.list[0].offset = add: mount failed (32).
+u3.sfdir3.list[0].offset = sub: mount failed (32).
+u3.sfdir3.list[0].name = zeroes: mount failed (32).
+u3.sfdir3.list[0].name = ones: mount failed (32).
+u3.sfdir3.list[0].name = firstbit: mount failed (32).
+u3.sfdir3.list[0].name = middlebit: mount failed (32).
+u3.sfdir3.list[0].name = lastbit: mount failed (32).
+u3.sfdir3.list[0].name = add: mount failed (32).
+u3.sfdir3.list[0].name = sub: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[0].filetype = ones: mount failed (32).
+u3.sfdir3.list[0].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[0].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[0].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[0].filetype = add: mount failed (32).
+u3.sfdir3.list[0].filetype = sub: mount failed (32).
+u3.sfdir3.list[1].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[1].namelen = ones: mount failed (32).
+u3.sfdir3.list[1].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[1].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[1].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[1].namelen = add: mount failed (32).
+u3.sfdir3.list[1].namelen = sub: mount failed (32).
+u3.sfdir3.list[1].offset = zeroes: mount failed (32).
+u3.sfdir3.list[1].offset = ones: mount failed (32).
+u3.sfdir3.list[1].offset = firstbit: mount failed (32).
+u3.sfdir3.list[1].offset = middlebit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = middlebit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = add: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = add: online scrub didn't fail.
+u3.sfdir3.list[1].offset = sub: mount failed (32).
+u3.sfdir3.list[1].name = zeroes: online repair failed (4).
+u3.sfdir3.list[1].name = firstbit: online repair failed (4).
+u3.sfdir3.list[1].name = middlebit: online repair failed (4).
+u3.sfdir3.list[1].name = lastbit: online repair failed (4).
+u3.sfdir3.list[1].name = add: online repair failed (4).
+u3.sfdir3.list[1].name = sub: online repair failed (4).
+u3.sfdir3.list[1].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[1].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[1].filetype = ones: mount failed (32).
+u3.sfdir3.list[1].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[1].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[1].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[1].filetype = add: mount failed (32).
+u3.sfdir3.list[1].filetype = sub: mount failed (32).
Done fuzzing metadir root
diff --git a/tests/xfs/1550.out b/tests/xfs/1550.out
index 7694cd670b..166e165538 100644
--- a/tests/xfs/1550.out
+++ b/tests/xfs/1550.out
@@ -1,4 +1,434 @@
QA output created by 1550
Format and populate
Fuzz metadir subdir
+core.magic = zeroes: mount failed (32).
+core.magic = ones: mount failed (32).
+core.magic = firstbit: mount failed (32).
+core.magic = middlebit: mount failed (32).
+core.magic = lastbit: mount failed (32).
+core.magic = add: mount failed (32).
+core.magic = sub: mount failed (32).
+core.mode = zeroes: mount failed (32).
+core.mode = ones: mount failed (32).
+core.mode = firstbit: mount failed (32).
+core.mode = middlebit: mount failed (32).
+core.mode = lastbit: mount failed (32).
+core.mode = add: mount failed (32).
+core.mode = sub: mount failed (32).
+core.version = zeroes: mount failed (32).
+core.version = ones: mount failed (32).
+core.version = firstbit: mount failed (32).
+core.version = middlebit: mount failed (32).
+core.version = lastbit: mount failed (32).
+core.version = add: mount failed (32).
+core.version = sub: mount failed (32).
+core.format = zeroes: mount failed (32).
+core.format = ones: mount failed (32).
+core.format = firstbit: mount failed (32).
+core.format = middlebit: mount failed (32).
+core.format = lastbit: mount failed (32).
+core.format = add: mount failed (32).
+core.format = sub: mount failed (32).
+core.onlink = ones: mount failed (32).
+core.onlink = firstbit: mount failed (32).
+core.onlink = middlebit: mount failed (32).
+core.onlink = lastbit: mount failed (32).
+core.onlink = add: mount failed (32).
+core.onlink = sub: mount failed (32).
+core.uid = ones: mount failed (32).
+core.uid = firstbit: mount failed (32).
+core.uid = middlebit: mount failed (32).
+core.uid = lastbit: mount failed (32).
+core.uid = add: mount failed (32).
+core.uid = sub: mount failed (32).
+core.gid = ones: mount failed (32).
+core.gid = firstbit: mount failed (32).
+core.gid = middlebit: mount failed (32).
+core.gid = lastbit: mount failed (32).
+core.gid = add: mount failed (32).
+core.gid = sub: mount failed (32).
+core.nlinkv2 = zeroes: mount failed (32).
+core.projid_lo = ones: mount failed (32).
+core.projid_lo = firstbit: mount failed (32).
+core.projid_lo = middlebit: mount failed (32).
+core.projid_lo = lastbit: mount failed (32).
+core.projid_lo = add: mount failed (32).
+core.projid_lo = sub: mount failed (32).
+core.projid_hi = ones: mount failed (32).
+core.projid_hi = firstbit: mount failed (32).
+core.projid_hi = middlebit: mount failed (32).
+core.projid_hi = lastbit: mount failed (32).
+core.projid_hi = add: mount failed (32).
+core.projid_hi = sub: mount failed (32).
+core.nextents = ones: mount failed (32).
+core.nextents = firstbit: mount failed (32).
+core.nextents = middlebit: mount failed (32).
+core.nextents = lastbit: mount failed (32).
+core.nextents = add: mount failed (32).
+core.nextents = sub: mount failed (32).
+core.size = zeroes: mount failed (32).
+core.size = ones: mount failed (32).
+core.size = firstbit: mount failed (32).
+core.size = middlebit: mount failed (32).
+core.size = lastbit: mount failed (32).
+core.size = add: mount failed (32).
+core.size = sub: mount failed (32).
+core.extsize = ones: mount failed (32).
+core.extsize = firstbit: mount failed (32).
+core.extsize = middlebit: mount failed (32).
+core.extsize = lastbit: mount failed (32).
+core.extsize = add: mount failed (32).
+core.extsize = sub: mount failed (32).
+core.naextents = ones: mount failed (32).
+core.naextents = firstbit: mount failed (32).
+core.naextents = middlebit: mount failed (32).
+core.naextents = lastbit: mount failed (32).
+core.naextents = add: mount failed (32).
+core.naextents = sub: mount failed (32).
+core.forkoff = zeroes: mount failed (32).
+core.forkoff = ones: mount failed (32).
+core.forkoff = firstbit: mount failed (32).
+core.forkoff = middlebit: mount failed (32).
+core.forkoff = lastbit: mount failed (32).
+core.forkoff = add: mount failed (32).
+core.forkoff = sub: mount failed (32).
+core.aformat = zeroes: mount failed (32).
+core.aformat = ones: mount failed (32).
+core.aformat = firstbit: mount failed (32).
+core.aformat = middlebit: mount failed (32).
+core.aformat = lastbit: mount failed (32).
+core.aformat = add: mount failed (32).
+core.aformat = sub: mount failed (32).
+core.realtime = ones: mount failed (32).
+core.realtime = firstbit: mount failed (32).
+core.realtime = middlebit: mount failed (32).
+core.realtime = lastbit: mount failed (32).
+core.realtime = add: mount failed (32).
+core.realtime = sub: mount failed (32).
+core.rtinherit = ones: online scrub didn't fail.
+core.rtinherit = firstbit: online scrub didn't fail.
+core.rtinherit = middlebit: online scrub didn't fail.
+core.rtinherit = lastbit: online scrub didn't fail.
+core.rtinherit = add: online scrub didn't fail.
+core.rtinherit = sub: online scrub didn't fail.
+core.projinherit = ones: online scrub didn't fail.
+core.projinherit = firstbit: online scrub didn't fail.
+core.projinherit = middlebit: online scrub didn't fail.
+core.projinherit = lastbit: online scrub didn't fail.
+core.projinherit = add: online scrub didn't fail.
+core.projinherit = sub: online scrub didn't fail.
+core.nosymlinks = zeroes: mount failed (32).
+core.nosymlinks = firstbit: mount failed (32).
+core.nosymlinks = middlebit: mount failed (32).
+core.nosymlinks = lastbit: mount failed (32).
+core.nosymlinks = add: mount failed (32).
+core.nosymlinks = sub: mount failed (32).
+core.extsz = ones: mount failed (32).
+core.extsz = firstbit: mount failed (32).
+core.extsz = middlebit: mount failed (32).
+core.extsz = lastbit: mount failed (32).
+core.extsz = add: mount failed (32).
+core.extsz = sub: mount failed (32).
+core.extszinherit = ones: mount failed (32).
+core.extszinherit = firstbit: mount failed (32).
+core.extszinherit = middlebit: mount failed (32).
+core.extszinherit = lastbit: mount failed (32).
+core.extszinherit = add: mount failed (32).
+core.extszinherit = sub: mount failed (32).
+next_unlinked = zeroes: mount failed (32).
+next_unlinked = firstbit: mount failed (32).
+next_unlinked = middlebit: mount failed (32).
+next_unlinked = lastbit: mount failed (32).
+next_unlinked = add: online scrub didn't fail.
+next_unlinked = add: offline re-scrub failed (1).
+next_unlinked = add: offline post-mod scrub failed (1).
+next_unlinked = sub: mount failed (32).
+v3.crc = zeroes: mount failed (32).
+v3.crc = ones: mount failed (32).
+v3.crc = firstbit: mount failed (32).
+v3.crc = middlebit: mount failed (32).
+v3.crc = lastbit: mount failed (32).
+v3.crc = add: mount failed (32).
+v3.crc = sub: mount failed (32).
+v3.change_count = zeroes: online scrub didn't fail.
+v3.change_count = ones: online scrub didn't fail.
+v3.change_count = firstbit: online scrub didn't fail.
+v3.change_count = middlebit: online scrub didn't fail.
+v3.change_count = lastbit: online scrub didn't fail.
+v3.change_count = add: online scrub didn't fail.
+v3.change_count = sub: online scrub didn't fail.
+v3.flags2 = zeroes: mount failed (32).
+v3.flags2 = ones: mount failed (32).
+v3.flags2 = firstbit: mount failed (32).
+v3.flags2 = middlebit: online scrub didn't fail.
+v3.flags2 = middlebit: offline re-scrub failed (1).
+v3.flags2 = middlebit: offline post-mod scrub failed (1).
+v3.flags2 = lastbit: mount failed (32).
+v3.flags2 = add: mount failed (32).
+v3.flags2 = sub: mount failed (32).
+v3.cowextsize = ones: mount failed (32).
+v3.cowextsize = firstbit: mount failed (32).
+v3.cowextsize = middlebit: mount failed (32).
+v3.cowextsize = lastbit: mount failed (32).
+v3.cowextsize = add: mount failed (32).
+v3.cowextsize = sub: mount failed (32).
+v3.inumber = zeroes: mount failed (32).
+v3.inumber = ones: mount failed (32).
+v3.inumber = firstbit: mount failed (32).
+v3.inumber = middlebit: mount failed (32).
+v3.inumber = lastbit: mount failed (32).
+v3.inumber = add: mount failed (32).
+v3.inumber = sub: mount failed (32).
+v3.uuid = zeroes: mount failed (32).
+v3.uuid = ones: mount failed (32).
+v3.uuid = firstbit: mount failed (32).
+v3.uuid = middlebit: mount failed (32).
+v3.uuid = lastbit: mount failed (32).
+v3.reflink = ones: mount failed (32).
+v3.reflink = firstbit: mount failed (32).
+v3.reflink = middlebit: mount failed (32).
+v3.reflink = lastbit: mount failed (32).
+v3.reflink = add: mount failed (32).
+v3.reflink = sub: mount failed (32).
+v3.cowextsz = ones: mount failed (32).
+v3.cowextsz = firstbit: mount failed (32).
+v3.cowextsz = middlebit: mount failed (32).
+v3.cowextsz = lastbit: mount failed (32).
+v3.cowextsz = add: mount failed (32).
+v3.cowextsz = sub: mount failed (32).
+v3.nrext64 = zeroes: online scrub didn't fail.
+v3.nrext64 = firstbit: online scrub didn't fail.
+v3.nrext64 = middlebit: online scrub didn't fail.
+v3.nrext64 = lastbit: online scrub didn't fail.
+v3.nrext64 = add: online scrub didn't fail.
+v3.nrext64 = sub: online scrub didn't fail.
+v3.metadir = zeroes: mount failed (32).
+v3.metadir = firstbit: mount failed (32).
+v3.metadir = middlebit: mount failed (32).
+v3.metadir = lastbit: mount failed (32).
+v3.metadir = add: mount failed (32).
+v3.metadir = sub: mount failed (32).
+u3.sfdir3.hdr.count = zeroes: mount failed (32).
+u3.sfdir3.hdr.count = ones: mount failed (32).
+u3.sfdir3.hdr.count = firstbit: mount failed (32).
+u3.sfdir3.hdr.count = middlebit: mount failed (32).
+u3.sfdir3.hdr.count = lastbit: mount failed (32).
+u3.sfdir3.hdr.count = add: mount failed (32).
+u3.sfdir3.hdr.count = sub: mount failed (32).
+u3.sfdir3.hdr.i8count = ones: mount failed (32).
+u3.sfdir3.hdr.i8count = firstbit: mount failed (32).
+u3.sfdir3.hdr.i8count = middlebit: mount failed (32).
+u3.sfdir3.hdr.i8count = lastbit: mount failed (32).
+u3.sfdir3.hdr.i8count = add: mount failed (32).
+u3.sfdir3.hdr.i8count = sub: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = zeroes: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = ones: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = firstbit: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[0].namelen = ones: mount failed (32).
+u3.sfdir3.list[0].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[0].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[0].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[0].namelen = add: mount failed (32).
+u3.sfdir3.list[0].namelen = sub: mount failed (32).
+u3.sfdir3.list[0].offset = zeroes: mount failed (32).
+u3.sfdir3.list[0].offset = ones: mount failed (32).
+u3.sfdir3.list[0].offset = firstbit: mount failed (32).
+u3.sfdir3.list[0].offset = middlebit: mount failed (32).
+u3.sfdir3.list[0].offset = lastbit: mount failed (32).
+u3.sfdir3.list[0].offset = add: mount failed (32).
+u3.sfdir3.list[0].offset = sub: mount failed (32).
+u3.sfdir3.list[0].name = zeroes: mount failed (32).
+u3.sfdir3.list[0].name = ones: mount failed (32).
+u3.sfdir3.list[0].name = firstbit: mount failed (32).
+u3.sfdir3.list[0].name = middlebit: mount failed (32).
+u3.sfdir3.list[0].name = lastbit: mount failed (32).
+u3.sfdir3.list[0].name = add: mount failed (32).
+u3.sfdir3.list[0].name = sub: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[0].filetype = ones: mount failed (32).
+u3.sfdir3.list[0].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[0].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[0].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[0].filetype = add: mount failed (32).
+u3.sfdir3.list[0].filetype = sub: mount failed (32).
+u3.sfdir3.list[1].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[1].namelen = ones: mount failed (32).
+u3.sfdir3.list[1].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[1].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[1].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[1].namelen = add: mount failed (32).
+u3.sfdir3.list[1].namelen = sub: mount failed (32).
+u3.sfdir3.list[1].offset = zeroes: mount failed (32).
+u3.sfdir3.list[1].offset = ones: mount failed (32).
+u3.sfdir3.list[1].offset = firstbit: mount failed (32).
+u3.sfdir3.list[1].offset = middlebit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = add: online scrub didn't fail.
+u3.sfdir3.list[1].offset = sub: mount failed (32).
+u3.sfdir3.list[1].name = zeroes: mount failed (32).
+u3.sfdir3.list[1].name = ones: mount failed (32).
+u3.sfdir3.list[1].name = firstbit: mount failed (32).
+u3.sfdir3.list[1].name = middlebit: mount failed (32).
+u3.sfdir3.list[1].name = lastbit: mount failed (32).
+u3.sfdir3.list[1].name = add: mount failed (32).
+u3.sfdir3.list[1].name = sub: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[1].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[1].filetype = ones: mount failed (32).
+u3.sfdir3.list[1].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[1].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[1].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[1].filetype = add: mount failed (32).
+u3.sfdir3.list[1].filetype = sub: mount failed (32).
+a.sfattr.hdr.totsize = zeroes: mount failed (32).
+a.sfattr.hdr.totsize = ones: mount failed (32).
+a.sfattr.hdr.totsize = firstbit: mount failed (32).
+a.sfattr.hdr.totsize = middlebit: mount failed (32).
+a.sfattr.hdr.totsize = lastbit: mount failed (32).
+a.sfattr.hdr.totsize = add: mount failed (32).
+a.sfattr.hdr.totsize = sub: mount failed (32).
+a.sfattr.hdr.count = zeroes: mount failed (32).
+a.sfattr.hdr.count = ones: mount failed (32).
+a.sfattr.hdr.count = firstbit: mount failed (32).
+a.sfattr.hdr.count = middlebit: mount failed (32).
+a.sfattr.hdr.count = lastbit: mount failed (32).
+a.sfattr.hdr.count = add: mount failed (32).
+a.sfattr.hdr.count = sub: mount failed (32).
+a.sfattr.list[0].namelen = zeroes: mount failed (32).
+a.sfattr.list[0].namelen = ones: mount failed (32).
+a.sfattr.list[0].namelen = firstbit: mount failed (32).
+a.sfattr.list[0].namelen = middlebit: mount failed (32).
+a.sfattr.list[0].namelen = lastbit: mount failed (32).
+a.sfattr.list[0].namelen = add: mount failed (32).
+a.sfattr.list[0].namelen = sub: mount failed (32).
+a.sfattr.list[0].parent = zeroes: online repair failed (1).
+a.sfattr.list[0].parent = zeroes: online re-scrub failed (5).
+a.sfattr.list[0].parent = zeroes: offline re-scrub failed (1).
+a.sfattr.list[0].parent = zeroes: online post-mod scrub failed (1).
+a.sfattr.list[0].parent = zeroes: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent = lastbit: online repair failed (1).
+a.sfattr.list[0].parent = lastbit: online re-scrub failed (5).
+a.sfattr.list[0].parent = lastbit: offline re-scrub failed (1).
+a.sfattr.list[0].parent = lastbit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent = lastbit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent = sub: online repair failed (1).
+a.sfattr.list[0].parent = sub: online re-scrub failed (5).
+a.sfattr.list[0].parent = sub: offline re-scrub failed (1).
+a.sfattr.list[0].parent = sub: online post-mod scrub failed (1).
+a.sfattr.list[0].parent = sub: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_ino = lastbit: online repair failed (1).
+a.sfattr.list[0].parent_ino = lastbit: online re-scrub failed (5).
+a.sfattr.list[0].parent_ino = lastbit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_ino = lastbit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_ino = lastbit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_ino = add: online repair failed (1).
+a.sfattr.list[0].parent_ino = add: online re-scrub failed (5).
+a.sfattr.list[0].parent_ino = add: offline re-scrub failed (1).
+a.sfattr.list[0].parent_ino = add: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_ino = add: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_ino = sub: online repair failed (1).
+a.sfattr.list[0].parent_ino = sub: online re-scrub failed (5).
+a.sfattr.list[0].parent_ino = sub: offline re-scrub failed (1).
+a.sfattr.list[0].parent_ino = sub: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_ino = sub: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = ones: online repair failed (1).
+a.sfattr.list[0].parent_gen = ones: online re-scrub failed (5).
+a.sfattr.list[0].parent_gen = ones: offline re-scrub failed (1).
+a.sfattr.list[0].parent_gen = ones: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = ones: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = firstbit: online repair failed (1).
+a.sfattr.list[0].parent_gen = firstbit: online re-scrub failed (5).
+a.sfattr.list[0].parent_gen = firstbit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_gen = firstbit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = firstbit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = middlebit: online repair failed (1).
+a.sfattr.list[0].parent_gen = middlebit: online re-scrub failed (5).
+a.sfattr.list[0].parent_gen = middlebit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_gen = middlebit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = middlebit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = lastbit: online repair failed (1).
+a.sfattr.list[0].parent_gen = lastbit: online re-scrub failed (5).
+a.sfattr.list[0].parent_gen = lastbit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_gen = lastbit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = lastbit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = add: online repair failed (1).
+a.sfattr.list[0].parent_gen = add: online re-scrub failed (5).
+a.sfattr.list[0].parent_gen = add: offline re-scrub failed (1).
+a.sfattr.list[0].parent_gen = add: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = add: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = sub: online repair failed (1).
+a.sfattr.list[0].parent_gen = sub: online re-scrub failed (5).
+a.sfattr.list[0].parent_gen = sub: offline re-scrub failed (1).
+a.sfattr.list[0].parent_gen = sub: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_gen = sub: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = zeroes: online repair failed (1).
+a.sfattr.list[0].parent_namehash = zeroes: online re-scrub failed (5).
+a.sfattr.list[0].parent_namehash = zeroes: offline re-scrub failed (1).
+a.sfattr.list[0].parent_namehash = zeroes: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = zeroes: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = firstbit: online repair failed (1).
+a.sfattr.list[0].parent_namehash = firstbit: online re-scrub failed (5).
+a.sfattr.list[0].parent_namehash = firstbit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_namehash = firstbit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = firstbit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = lastbit: online repair failed (1).
+a.sfattr.list[0].parent_namehash = lastbit: online re-scrub failed (5).
+a.sfattr.list[0].parent_namehash = lastbit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_namehash = lastbit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = lastbit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = add: online repair failed (1).
+a.sfattr.list[0].parent_namehash = add: online re-scrub failed (5).
+a.sfattr.list[0].parent_namehash = add: offline re-scrub failed (1).
+a.sfattr.list[0].parent_namehash = add: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = add: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = sub: online repair failed (1).
+a.sfattr.list[0].parent_namehash = sub: online re-scrub failed (5).
+a.sfattr.list[0].parent_namehash = sub: offline re-scrub failed (1).
+a.sfattr.list[0].parent_namehash = sub: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_namehash = sub: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = ones: online repair failed (1).
+a.sfattr.list[0].parent_name = ones: online re-scrub failed (5).
+a.sfattr.list[0].parent_name = ones: offline re-scrub failed (1).
+a.sfattr.list[0].parent_name = ones: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = ones: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = firstbit: online repair failed (1).
+a.sfattr.list[0].parent_name = firstbit: online re-scrub failed (5).
+a.sfattr.list[0].parent_name = firstbit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_name = firstbit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = firstbit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = middlebit: online repair failed (1).
+a.sfattr.list[0].parent_name = middlebit: online re-scrub failed (5).
+a.sfattr.list[0].parent_name = middlebit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_name = middlebit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = middlebit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = lastbit: online repair failed (1).
+a.sfattr.list[0].parent_name = lastbit: online re-scrub failed (5).
+a.sfattr.list[0].parent_name = lastbit: offline re-scrub failed (1).
+a.sfattr.list[0].parent_name = lastbit: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = lastbit: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = add: online repair failed (1).
+a.sfattr.list[0].parent_name = add: online re-scrub failed (5).
+a.sfattr.list[0].parent_name = add: offline re-scrub failed (1).
+a.sfattr.list[0].parent_name = add: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = add: offline post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = sub: online repair failed (1).
+a.sfattr.list[0].parent_name = sub: online re-scrub failed (5).
+a.sfattr.list[0].parent_name = sub: offline re-scrub failed (1).
+a.sfattr.list[0].parent_name = sub: online post-mod scrub failed (1).
+a.sfattr.list[0].parent_name = sub: offline post-mod scrub failed (1).
Done fuzzing metadir subdir
diff --git a/tests/xfs/1551.out b/tests/xfs/1551.out
index 4c3360d08b..fedbe7ad69 100644
--- a/tests/xfs/1551.out
+++ b/tests/xfs/1551.out
@@ -1,4 +1,35 @@
QA output created by 1551
Format and populate
Fuzz metadir subdir
+core.rtinherit = ones: offline scrub didn't fail.
+core.rtinherit = firstbit: offline scrub didn't fail.
+core.rtinherit = middlebit: offline scrub didn't fail.
+core.rtinherit = lastbit: offline scrub didn't fail.
+core.rtinherit = add: offline scrub didn't fail.
+core.rtinherit = sub: offline scrub didn't fail.
+core.projinherit = ones: offline scrub didn't fail.
+core.projinherit = firstbit: offline scrub didn't fail.
+core.projinherit = middlebit: offline scrub didn't fail.
+core.projinherit = lastbit: offline scrub didn't fail.
+core.projinherit = add: offline scrub didn't fail.
+core.projinherit = sub: offline scrub didn't fail.
+v3.change_count = zeroes: offline scrub didn't fail.
+v3.change_count = ones: offline scrub didn't fail.
+v3.change_count = firstbit: offline scrub didn't fail.
+v3.change_count = middlebit: offline scrub didn't fail.
+v3.change_count = lastbit: offline scrub didn't fail.
+v3.change_count = add: offline scrub didn't fail.
+v3.change_count = sub: offline scrub didn't fail.
+v3.nrext64 = zeroes: offline scrub didn't fail.
+v3.nrext64 = firstbit: offline scrub didn't fail.
+v3.nrext64 = middlebit: offline scrub didn't fail.
+v3.nrext64 = lastbit: offline scrub didn't fail.
+v3.nrext64 = add: offline scrub didn't fail.
+v3.nrext64 = sub: offline scrub didn't fail.
+u3.sfdir3.list[0].inumber.i4 = lastbit: offline repair failed (1).
+u3.sfdir3.list[0].inumber.i4 = lastbit: offline re-scrub failed (1).
+u3.sfdir3.list[0].inumber.i4 = lastbit: pre-mod mount failed (32).
+u3.sfdir3.list[1].offset = middlebit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = add: offline scrub didn't fail.
Done fuzzing metadir subdir
diff --git a/tests/xfs/1552.out b/tests/xfs/1552.out
index 6636b1b656..35cc60d261 100644
--- a/tests/xfs/1552.out
+++ b/tests/xfs/1552.out
@@ -1,4 +1,343 @@
QA output created by 1552
Format and populate
Fuzz metadir subdir
+core.magic = zeroes: mount failed (32).
+core.magic = ones: mount failed (32).
+core.magic = firstbit: mount failed (32).
+core.magic = middlebit: mount failed (32).
+core.magic = lastbit: mount failed (32).
+core.magic = add: mount failed (32).
+core.magic = sub: mount failed (32).
+core.mode = zeroes: mount failed (32).
+core.mode = ones: mount failed (32).
+core.mode = firstbit: mount failed (32).
+core.mode = middlebit: mount failed (32).
+core.mode = lastbit: mount failed (32).
+core.mode = add: mount failed (32).
+core.mode = sub: mount failed (32).
+core.version = zeroes: mount failed (32).
+core.version = ones: mount failed (32).
+core.version = firstbit: mount failed (32).
+core.version = middlebit: mount failed (32).
+core.version = lastbit: mount failed (32).
+core.version = add: mount failed (32).
+core.version = sub: mount failed (32).
+core.format = zeroes: mount failed (32).
+core.format = ones: mount failed (32).
+core.format = firstbit: mount failed (32).
+core.format = middlebit: mount failed (32).
+core.format = lastbit: mount failed (32).
+core.format = add: mount failed (32).
+core.format = sub: mount failed (32).
+core.onlink = ones: mount failed (32).
+core.onlink = firstbit: mount failed (32).
+core.onlink = middlebit: mount failed (32).
+core.onlink = lastbit: mount failed (32).
+core.onlink = add: mount failed (32).
+core.onlink = sub: mount failed (32).
+core.uid = ones: mount failed (32).
+core.uid = firstbit: mount failed (32).
+core.uid = middlebit: mount failed (32).
+core.uid = lastbit: mount failed (32).
+core.uid = add: mount failed (32).
+core.uid = sub: mount failed (32).
+core.gid = ones: mount failed (32).
+core.gid = firstbit: mount failed (32).
+core.gid = middlebit: mount failed (32).
+core.gid = lastbit: mount failed (32).
+core.gid = add: mount failed (32).
+core.gid = sub: mount failed (32).
+core.nlinkv2 = zeroes: mount failed (32).
+core.projid_lo = ones: mount failed (32).
+core.projid_lo = firstbit: mount failed (32).
+core.projid_lo = middlebit: mount failed (32).
+core.projid_lo = lastbit: mount failed (32).
+core.projid_lo = add: mount failed (32).
+core.projid_lo = sub: mount failed (32).
+core.projid_hi = ones: mount failed (32).
+core.projid_hi = firstbit: mount failed (32).
+core.projid_hi = middlebit: mount failed (32).
+core.projid_hi = lastbit: mount failed (32).
+core.projid_hi = add: mount failed (32).
+core.projid_hi = sub: mount failed (32).
+core.nextents = ones: mount failed (32).
+core.nextents = firstbit: mount failed (32).
+core.nextents = middlebit: mount failed (32).
+core.nextents = lastbit: mount failed (32).
+core.nextents = add: mount failed (32).
+core.nextents = sub: mount failed (32).
+core.size = zeroes: mount failed (32).
+core.size = ones: mount failed (32).
+core.size = firstbit: mount failed (32).
+core.size = middlebit: mount failed (32).
+core.size = lastbit: mount failed (32).
+core.size = add: mount failed (32).
+core.size = sub: mount failed (32).
+core.extsize = ones: mount failed (32).
+core.extsize = firstbit: mount failed (32).
+core.extsize = middlebit: mount failed (32).
+core.extsize = lastbit: mount failed (32).
+core.extsize = add: mount failed (32).
+core.extsize = sub: mount failed (32).
+core.naextents = ones: mount failed (32).
+core.naextents = firstbit: mount failed (32).
+core.naextents = middlebit: mount failed (32).
+core.naextents = lastbit: mount failed (32).
+core.naextents = add: mount failed (32).
+core.naextents = sub: mount failed (32).
+core.forkoff = zeroes: mount failed (32).
+core.forkoff = ones: mount failed (32).
+core.forkoff = firstbit: mount failed (32).
+core.forkoff = middlebit: mount failed (32).
+core.forkoff = lastbit: mount failed (32).
+core.forkoff = add: mount failed (32).
+core.forkoff = sub: mount failed (32).
+core.aformat = zeroes: mount failed (32).
+core.aformat = ones: mount failed (32).
+core.aformat = firstbit: mount failed (32).
+core.aformat = middlebit: mount failed (32).
+core.aformat = lastbit: mount failed (32).
+core.aformat = add: mount failed (32).
+core.aformat = sub: mount failed (32).
+core.realtime = ones: mount failed (32).
+core.realtime = firstbit: mount failed (32).
+core.realtime = middlebit: mount failed (32).
+core.realtime = lastbit: mount failed (32).
+core.realtime = add: mount failed (32).
+core.realtime = sub: mount failed (32).
+core.rtinherit = ones: offline scrub didn't fail.
+core.rtinherit = ones: online scrub didn't fail.
+core.rtinherit = firstbit: offline scrub didn't fail.
+core.rtinherit = firstbit: online scrub didn't fail.
+core.rtinherit = middlebit: offline scrub didn't fail.
+core.rtinherit = middlebit: online scrub didn't fail.
+core.rtinherit = lastbit: offline scrub didn't fail.
+core.rtinherit = lastbit: online scrub didn't fail.
+core.rtinherit = add: offline scrub didn't fail.
+core.rtinherit = add: online scrub didn't fail.
+core.rtinherit = sub: offline scrub didn't fail.
+core.rtinherit = sub: online scrub didn't fail.
+core.projinherit = ones: offline scrub didn't fail.
+core.projinherit = ones: online scrub didn't fail.
+core.projinherit = firstbit: offline scrub didn't fail.
+core.projinherit = firstbit: online scrub didn't fail.
+core.projinherit = middlebit: offline scrub didn't fail.
+core.projinherit = middlebit: online scrub didn't fail.
+core.projinherit = lastbit: offline scrub didn't fail.
+core.projinherit = lastbit: online scrub didn't fail.
+core.projinherit = add: offline scrub didn't fail.
+core.projinherit = add: online scrub didn't fail.
+core.projinherit = sub: offline scrub didn't fail.
+core.projinherit = sub: online scrub didn't fail.
+core.nosymlinks = zeroes: mount failed (32).
+core.nosymlinks = firstbit: mount failed (32).
+core.nosymlinks = middlebit: mount failed (32).
+core.nosymlinks = lastbit: mount failed (32).
+core.nosymlinks = add: mount failed (32).
+core.nosymlinks = sub: mount failed (32).
+core.extsz = ones: mount failed (32).
+core.extsz = firstbit: mount failed (32).
+core.extsz = middlebit: mount failed (32).
+core.extsz = lastbit: mount failed (32).
+core.extsz = add: mount failed (32).
+core.extsz = sub: mount failed (32).
+core.extszinherit = ones: mount failed (32).
+core.extszinherit = firstbit: mount failed (32).
+core.extszinherit = middlebit: mount failed (32).
+core.extszinherit = lastbit: mount failed (32).
+core.extszinherit = add: mount failed (32).
+core.extszinherit = sub: mount failed (32).
+next_unlinked = zeroes: mount failed (32).
+next_unlinked = firstbit: mount failed (32).
+next_unlinked = middlebit: mount failed (32).
+next_unlinked = lastbit: mount failed (32).
+next_unlinked = add: online scrub didn't fail.
+next_unlinked = sub: mount failed (32).
+v3.crc = zeroes: mount failed (32).
+v3.crc = ones: mount failed (32).
+v3.crc = firstbit: mount failed (32).
+v3.crc = middlebit: mount failed (32).
+v3.crc = lastbit: mount failed (32).
+v3.crc = add: mount failed (32).
+v3.crc = sub: mount failed (32).
+v3.change_count = zeroes: offline scrub didn't fail.
+v3.change_count = zeroes: online scrub didn't fail.
+v3.change_count = ones: offline scrub didn't fail.
+v3.change_count = ones: online scrub didn't fail.
+v3.change_count = firstbit: offline scrub didn't fail.
+v3.change_count = firstbit: online scrub didn't fail.
+v3.change_count = middlebit: offline scrub didn't fail.
+v3.change_count = middlebit: online scrub didn't fail.
+v3.change_count = lastbit: offline scrub didn't fail.
+v3.change_count = lastbit: online scrub didn't fail.
+v3.change_count = add: offline scrub didn't fail.
+v3.change_count = add: online scrub didn't fail.
+v3.change_count = sub: offline scrub didn't fail.
+v3.change_count = sub: online scrub didn't fail.
+v3.flags2 = zeroes: mount failed (32).
+v3.flags2 = ones: mount failed (32).
+v3.flags2 = firstbit: mount failed (32).
+v3.flags2 = middlebit: online scrub didn't fail.
+v3.flags2 = lastbit: mount failed (32).
+v3.flags2 = add: mount failed (32).
+v3.flags2 = sub: mount failed (32).
+v3.cowextsize = ones: mount failed (32).
+v3.cowextsize = firstbit: mount failed (32).
+v3.cowextsize = middlebit: mount failed (32).
+v3.cowextsize = lastbit: mount failed (32).
+v3.cowextsize = add: mount failed (32).
+v3.cowextsize = sub: mount failed (32).
+v3.inumber = zeroes: mount failed (32).
+v3.inumber = ones: mount failed (32).
+v3.inumber = firstbit: mount failed (32).
+v3.inumber = middlebit: mount failed (32).
+v3.inumber = lastbit: mount failed (32).
+v3.inumber = add: mount failed (32).
+v3.inumber = sub: mount failed (32).
+v3.uuid = zeroes: mount failed (32).
+v3.uuid = ones: mount failed (32).
+v3.uuid = firstbit: mount failed (32).
+v3.uuid = middlebit: mount failed (32).
+v3.uuid = lastbit: mount failed (32).
+v3.reflink = ones: mount failed (32).
+v3.reflink = firstbit: mount failed (32).
+v3.reflink = middlebit: mount failed (32).
+v3.reflink = lastbit: mount failed (32).
+v3.reflink = add: mount failed (32).
+v3.reflink = sub: mount failed (32).
+v3.cowextsz = ones: mount failed (32).
+v3.cowextsz = firstbit: mount failed (32).
+v3.cowextsz = middlebit: mount failed (32).
+v3.cowextsz = lastbit: mount failed (32).
+v3.cowextsz = add: mount failed (32).
+v3.cowextsz = sub: mount failed (32).
+v3.nrext64 = zeroes: offline scrub didn't fail.
+v3.nrext64 = zeroes: online scrub didn't fail.
+v3.nrext64 = firstbit: offline scrub didn't fail.
+v3.nrext64 = firstbit: online scrub didn't fail.
+v3.nrext64 = middlebit: offline scrub didn't fail.
+v3.nrext64 = middlebit: online scrub didn't fail.
+v3.nrext64 = lastbit: offline scrub didn't fail.
+v3.nrext64 = lastbit: online scrub didn't fail.
+v3.nrext64 = add: offline scrub didn't fail.
+v3.nrext64 = add: online scrub didn't fail.
+v3.nrext64 = sub: offline scrub didn't fail.
+v3.nrext64 = sub: online scrub didn't fail.
+v3.metadir = zeroes: mount failed (32).
+v3.metadir = firstbit: mount failed (32).
+v3.metadir = middlebit: mount failed (32).
+v3.metadir = lastbit: mount failed (32).
+v3.metadir = add: mount failed (32).
+v3.metadir = sub: mount failed (32).
+u3.sfdir3.hdr.count = zeroes: mount failed (32).
+u3.sfdir3.hdr.count = ones: mount failed (32).
+u3.sfdir3.hdr.count = firstbit: mount failed (32).
+u3.sfdir3.hdr.count = middlebit: mount failed (32).
+u3.sfdir3.hdr.count = lastbit: mount failed (32).
+u3.sfdir3.hdr.count = add: mount failed (32).
+u3.sfdir3.hdr.count = sub: mount failed (32).
+u3.sfdir3.hdr.i8count = ones: mount failed (32).
+u3.sfdir3.hdr.i8count = firstbit: mount failed (32).
+u3.sfdir3.hdr.i8count = middlebit: mount failed (32).
+u3.sfdir3.hdr.i8count = lastbit: mount failed (32).
+u3.sfdir3.hdr.i8count = add: mount failed (32).
+u3.sfdir3.hdr.i8count = sub: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = zeroes: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = ones: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = firstbit: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[0].namelen = ones: mount failed (32).
+u3.sfdir3.list[0].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[0].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[0].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[0].namelen = add: mount failed (32).
+u3.sfdir3.list[0].namelen = sub: mount failed (32).
+u3.sfdir3.list[0].offset = zeroes: mount failed (32).
+u3.sfdir3.list[0].offset = ones: mount failed (32).
+u3.sfdir3.list[0].offset = firstbit: mount failed (32).
+u3.sfdir3.list[0].offset = middlebit: mount failed (32).
+u3.sfdir3.list[0].offset = lastbit: mount failed (32).
+u3.sfdir3.list[0].offset = add: mount failed (32).
+u3.sfdir3.list[0].offset = sub: mount failed (32).
+u3.sfdir3.list[0].name = zeroes: mount failed (32).
+u3.sfdir3.list[0].name = ones: mount failed (32).
+u3.sfdir3.list[0].name = firstbit: mount failed (32).
+u3.sfdir3.list[0].name = middlebit: mount failed (32).
+u3.sfdir3.list[0].name = lastbit: mount failed (32).
+u3.sfdir3.list[0].name = add: mount failed (32).
+u3.sfdir3.list[0].name = sub: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[0].filetype = ones: mount failed (32).
+u3.sfdir3.list[0].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[0].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[0].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[0].filetype = add: mount failed (32).
+u3.sfdir3.list[0].filetype = sub: mount failed (32).
+u3.sfdir3.list[1].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[1].namelen = ones: mount failed (32).
+u3.sfdir3.list[1].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[1].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[1].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[1].namelen = add: mount failed (32).
+u3.sfdir3.list[1].namelen = sub: mount failed (32).
+u3.sfdir3.list[1].offset = zeroes: mount failed (32).
+u3.sfdir3.list[1].offset = ones: mount failed (32).
+u3.sfdir3.list[1].offset = firstbit: mount failed (32).
+u3.sfdir3.list[1].offset = middlebit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = middlebit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = add: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = add: online scrub didn't fail.
+u3.sfdir3.list[1].offset = sub: mount failed (32).
+u3.sfdir3.list[1].name = zeroes: mount failed (32).
+u3.sfdir3.list[1].name = ones: mount failed (32).
+u3.sfdir3.list[1].name = firstbit: mount failed (32).
+u3.sfdir3.list[1].name = middlebit: mount failed (32).
+u3.sfdir3.list[1].name = lastbit: mount failed (32).
+u3.sfdir3.list[1].name = add: mount failed (32).
+u3.sfdir3.list[1].name = sub: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[1].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[1].filetype = ones: mount failed (32).
+u3.sfdir3.list[1].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[1].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[1].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[1].filetype = add: mount failed (32).
+u3.sfdir3.list[1].filetype = sub: mount failed (32).
+a.sfattr.hdr.totsize = zeroes: mount failed (32).
+a.sfattr.hdr.totsize = ones: mount failed (32).
+a.sfattr.hdr.totsize = firstbit: mount failed (32).
+a.sfattr.hdr.totsize = middlebit: mount failed (32).
+a.sfattr.hdr.totsize = lastbit: mount failed (32).
+a.sfattr.hdr.totsize = add: mount failed (32).
+a.sfattr.hdr.totsize = sub: mount failed (32).
+a.sfattr.hdr.count = zeroes: mount failed (32).
+a.sfattr.hdr.count = ones: mount failed (32).
+a.sfattr.hdr.count = firstbit: mount failed (32).
+a.sfattr.hdr.count = middlebit: mount failed (32).
+a.sfattr.hdr.count = lastbit: mount failed (32).
+a.sfattr.hdr.count = add: mount failed (32).
+a.sfattr.hdr.count = sub: mount failed (32).
+a.sfattr.list[0].namelen = zeroes: mount failed (32).
+a.sfattr.list[0].namelen = ones: mount failed (32).
+a.sfattr.list[0].namelen = firstbit: mount failed (32).
+a.sfattr.list[0].namelen = middlebit: mount failed (32).
+a.sfattr.list[0].namelen = lastbit: mount failed (32).
+a.sfattr.list[0].namelen = add: mount failed (32).
+a.sfattr.list[0].namelen = sub: mount failed (32).
Done fuzzing metadir subdir
diff --git a/tests/xfs/1553.out b/tests/xfs/1553.out
index 0298fcfddb..e406b598b9 100644
--- a/tests/xfs/1553.out
+++ b/tests/xfs/1553.out
@@ -1,4 +1,370 @@
QA output created by 1553
Format and populate
Fuzz metadir subdir
+core.magic = zeroes: mount failed (32).
+core.magic = ones: mount failed (32).
+core.magic = firstbit: mount failed (32).
+core.magic = middlebit: mount failed (32).
+core.magic = lastbit: mount failed (32).
+core.magic = add: mount failed (32).
+core.magic = sub: mount failed (32).
+core.mode = zeroes: mount failed (32).
+core.mode = ones: mount failed (32).
+core.mode = firstbit: mount failed (32).
+core.mode = middlebit: mount failed (32).
+core.mode = lastbit: mount failed (32).
+core.mode = add: mount failed (32).
+core.mode = sub: mount failed (32).
+core.version = zeroes: mount failed (32).
+core.version = ones: mount failed (32).
+core.version = firstbit: mount failed (32).
+core.version = middlebit: mount failed (32).
+core.version = lastbit: mount failed (32).
+core.version = add: mount failed (32).
+core.version = sub: mount failed (32).
+core.format = zeroes: mount failed (32).
+core.format = ones: mount failed (32).
+core.format = firstbit: mount failed (32).
+core.format = middlebit: mount failed (32).
+core.format = lastbit: mount failed (32).
+core.format = add: mount failed (32).
+core.format = sub: mount failed (32).
+core.onlink = ones: mount failed (32).
+core.onlink = firstbit: mount failed (32).
+core.onlink = middlebit: mount failed (32).
+core.onlink = lastbit: mount failed (32).
+core.onlink = add: mount failed (32).
+core.onlink = sub: mount failed (32).
+core.uid = ones: mount failed (32).
+core.uid = firstbit: mount failed (32).
+core.uid = middlebit: mount failed (32).
+core.uid = lastbit: mount failed (32).
+core.uid = add: mount failed (32).
+core.uid = sub: mount failed (32).
+core.gid = ones: mount failed (32).
+core.gid = firstbit: mount failed (32).
+core.gid = middlebit: mount failed (32).
+core.gid = lastbit: mount failed (32).
+core.gid = add: mount failed (32).
+core.gid = sub: mount failed (32).
+core.nlinkv2 = zeroes: mount failed (32).
+core.projid_lo = ones: mount failed (32).
+core.projid_lo = firstbit: mount failed (32).
+core.projid_lo = middlebit: mount failed (32).
+core.projid_lo = lastbit: mount failed (32).
+core.projid_lo = add: mount failed (32).
+core.projid_lo = sub: mount failed (32).
+core.projid_hi = ones: mount failed (32).
+core.projid_hi = firstbit: mount failed (32).
+core.projid_hi = middlebit: mount failed (32).
+core.projid_hi = lastbit: mount failed (32).
+core.projid_hi = add: mount failed (32).
+core.projid_hi = sub: mount failed (32).
+core.nextents = ones: mount failed (32).
+core.nextents = firstbit: mount failed (32).
+core.nextents = middlebit: mount failed (32).
+core.nextents = lastbit: mount failed (32).
+core.nextents = add: mount failed (32).
+core.nextents = sub: mount failed (32).
+core.size = zeroes: mount failed (32).
+core.size = ones: mount failed (32).
+core.size = firstbit: mount failed (32).
+core.size = middlebit: mount failed (32).
+core.size = lastbit: mount failed (32).
+core.size = add: mount failed (32).
+core.size = sub: mount failed (32).
+core.extsize = ones: mount failed (32).
+core.extsize = firstbit: mount failed (32).
+core.extsize = middlebit: mount failed (32).
+core.extsize = lastbit: mount failed (32).
+core.extsize = add: mount failed (32).
+core.extsize = sub: mount failed (32).
+core.naextents = ones: mount failed (32).
+core.naextents = firstbit: mount failed (32).
+core.naextents = middlebit: mount failed (32).
+core.naextents = lastbit: mount failed (32).
+core.naextents = add: mount failed (32).
+core.naextents = sub: mount failed (32).
+core.forkoff = zeroes: mount failed (32).
+core.forkoff = ones: mount failed (32).
+core.forkoff = firstbit: mount failed (32).
+core.forkoff = middlebit: mount failed (32).
+core.forkoff = lastbit: mount failed (32).
+core.forkoff = add: mount failed (32).
+core.forkoff = sub: mount failed (32).
+core.aformat = zeroes: mount failed (32).
+core.aformat = ones: mount failed (32).
+core.aformat = firstbit: mount failed (32).
+core.aformat = middlebit: mount failed (32).
+core.aformat = lastbit: mount failed (32).
+core.aformat = add: mount failed (32).
+core.aformat = sub: mount failed (32).
+core.realtime = ones: mount failed (32).
+core.realtime = firstbit: mount failed (32).
+core.realtime = middlebit: mount failed (32).
+core.realtime = lastbit: mount failed (32).
+core.realtime = add: mount failed (32).
+core.realtime = sub: mount failed (32).
+core.rtinherit = ones: offline scrub didn't fail.
+core.rtinherit = ones: online scrub didn't fail.
+core.rtinherit = firstbit: offline scrub didn't fail.
+core.rtinherit = firstbit: online scrub didn't fail.
+core.rtinherit = middlebit: offline scrub didn't fail.
+core.rtinherit = middlebit: online scrub didn't fail.
+core.rtinherit = lastbit: offline scrub didn't fail.
+core.rtinherit = lastbit: online scrub didn't fail.
+core.rtinherit = add: offline scrub didn't fail.
+core.rtinherit = add: online scrub didn't fail.
+core.rtinherit = sub: offline scrub didn't fail.
+core.rtinherit = sub: online scrub didn't fail.
+core.projinherit = ones: offline scrub didn't fail.
+core.projinherit = ones: online scrub didn't fail.
+core.projinherit = firstbit: offline scrub didn't fail.
+core.projinherit = firstbit: online scrub didn't fail.
+core.projinherit = middlebit: offline scrub didn't fail.
+core.projinherit = middlebit: online scrub didn't fail.
+core.projinherit = lastbit: offline scrub didn't fail.
+core.projinherit = lastbit: online scrub didn't fail.
+core.projinherit = add: offline scrub didn't fail.
+core.projinherit = add: online scrub didn't fail.
+core.projinherit = sub: offline scrub didn't fail.
+core.projinherit = sub: online scrub didn't fail.
+core.nosymlinks = zeroes: mount failed (32).
+core.nosymlinks = firstbit: mount failed (32).
+core.nosymlinks = middlebit: mount failed (32).
+core.nosymlinks = lastbit: mount failed (32).
+core.nosymlinks = add: mount failed (32).
+core.nosymlinks = sub: mount failed (32).
+core.extsz = ones: mount failed (32).
+core.extsz = firstbit: mount failed (32).
+core.extsz = middlebit: mount failed (32).
+core.extsz = lastbit: mount failed (32).
+core.extsz = add: mount failed (32).
+core.extsz = sub: mount failed (32).
+core.extszinherit = ones: mount failed (32).
+core.extszinherit = firstbit: mount failed (32).
+core.extszinherit = middlebit: mount failed (32).
+core.extszinherit = lastbit: mount failed (32).
+core.extszinherit = add: mount failed (32).
+core.extszinherit = sub: mount failed (32).
+next_unlinked = zeroes: mount failed (32).
+next_unlinked = firstbit: mount failed (32).
+next_unlinked = middlebit: mount failed (32).
+next_unlinked = lastbit: mount failed (32).
+next_unlinked = add: online scrub didn't fail.
+next_unlinked = add: offline re-scrub failed (1).
+next_unlinked = add: offline post-mod scrub failed (1).
+next_unlinked = sub: mount failed (32).
+v3.crc = zeroes: mount failed (32).
+v3.crc = ones: mount failed (32).
+v3.crc = firstbit: mount failed (32).
+v3.crc = middlebit: mount failed (32).
+v3.crc = lastbit: mount failed (32).
+v3.crc = add: mount failed (32).
+v3.crc = sub: mount failed (32).
+v3.change_count = zeroes: offline scrub didn't fail.
+v3.change_count = zeroes: online scrub didn't fail.
+v3.change_count = ones: offline scrub didn't fail.
+v3.change_count = ones: online scrub didn't fail.
+v3.change_count = firstbit: offline scrub didn't fail.
+v3.change_count = firstbit: online scrub didn't fail.
+v3.change_count = middlebit: offline scrub didn't fail.
+v3.change_count = middlebit: online scrub didn't fail.
+v3.change_count = lastbit: offline scrub didn't fail.
+v3.change_count = lastbit: online scrub didn't fail.
+v3.change_count = add: offline scrub didn't fail.
+v3.change_count = add: online scrub didn't fail.
+v3.change_count = sub: offline scrub didn't fail.
+v3.change_count = sub: online scrub didn't fail.
+v3.flags2 = zeroes: mount failed (32).
+v3.flags2 = ones: mount failed (32).
+v3.flags2 = firstbit: mount failed (32).
+v3.flags2 = middlebit: online scrub didn't fail.
+v3.flags2 = middlebit: offline re-scrub failed (1).
+v3.flags2 = middlebit: offline post-mod scrub failed (1).
+v3.flags2 = lastbit: mount failed (32).
+v3.flags2 = add: mount failed (32).
+v3.flags2 = sub: mount failed (32).
+v3.cowextsize = ones: mount failed (32).
+v3.cowextsize = firstbit: mount failed (32).
+v3.cowextsize = middlebit: mount failed (32).
+v3.cowextsize = lastbit: mount failed (32).
+v3.cowextsize = add: mount failed (32).
+v3.cowextsize = sub: mount failed (32).
+v3.inumber = zeroes: mount failed (32).
+v3.inumber = ones: mount failed (32).
+v3.inumber = firstbit: mount failed (32).
+v3.inumber = middlebit: mount failed (32).
+v3.inumber = lastbit: mount failed (32).
+v3.inumber = add: mount failed (32).
+v3.inumber = sub: mount failed (32).
+v3.uuid = zeroes: mount failed (32).
+v3.uuid = ones: mount failed (32).
+v3.uuid = firstbit: mount failed (32).
+v3.uuid = middlebit: mount failed (32).
+v3.uuid = lastbit: mount failed (32).
+v3.reflink = ones: mount failed (32).
+v3.reflink = firstbit: mount failed (32).
+v3.reflink = middlebit: mount failed (32).
+v3.reflink = lastbit: mount failed (32).
+v3.reflink = add: mount failed (32).
+v3.reflink = sub: mount failed (32).
+v3.cowextsz = ones: mount failed (32).
+v3.cowextsz = firstbit: mount failed (32).
+v3.cowextsz = middlebit: mount failed (32).
+v3.cowextsz = lastbit: mount failed (32).
+v3.cowextsz = add: mount failed (32).
+v3.cowextsz = sub: mount failed (32).
+v3.nrext64 = zeroes: offline scrub didn't fail.
+v3.nrext64 = zeroes: online scrub didn't fail.
+v3.nrext64 = firstbit: offline scrub didn't fail.
+v3.nrext64 = firstbit: online scrub didn't fail.
+v3.nrext64 = middlebit: offline scrub didn't fail.
+v3.nrext64 = middlebit: online scrub didn't fail.
+v3.nrext64 = lastbit: offline scrub didn't fail.
+v3.nrext64 = lastbit: online scrub didn't fail.
+v3.nrext64 = add: offline scrub didn't fail.
+v3.nrext64 = add: online scrub didn't fail.
+v3.nrext64 = sub: offline scrub didn't fail.
+v3.nrext64 = sub: online scrub didn't fail.
+v3.metadir = zeroes: mount failed (32).
+v3.metadir = firstbit: mount failed (32).
+v3.metadir = middlebit: mount failed (32).
+v3.metadir = lastbit: mount failed (32).
+v3.metadir = add: mount failed (32).
+v3.metadir = sub: mount failed (32).
+u3.sfdir3.hdr.count = zeroes: mount failed (32).
+u3.sfdir3.hdr.count = ones: mount failed (32).
+u3.sfdir3.hdr.count = firstbit: mount failed (32).
+u3.sfdir3.hdr.count = middlebit: mount failed (32).
+u3.sfdir3.hdr.count = lastbit: mount failed (32).
+u3.sfdir3.hdr.count = add: mount failed (32).
+u3.sfdir3.hdr.count = sub: mount failed (32).
+u3.sfdir3.hdr.i8count = ones: mount failed (32).
+u3.sfdir3.hdr.i8count = firstbit: mount failed (32).
+u3.sfdir3.hdr.i8count = middlebit: mount failed (32).
+u3.sfdir3.hdr.i8count = lastbit: mount failed (32).
+u3.sfdir3.hdr.i8count = add: mount failed (32).
+u3.sfdir3.hdr.i8count = sub: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = zeroes: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = ones: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = firstbit: mount failed (32).
+u3.sfdir3.hdr.parent.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[0].namelen = ones: mount failed (32).
+u3.sfdir3.list[0].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[0].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[0].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[0].namelen = add: mount failed (32).
+u3.sfdir3.list[0].namelen = sub: mount failed (32).
+u3.sfdir3.list[0].offset = zeroes: mount failed (32).
+u3.sfdir3.list[0].offset = ones: mount failed (32).
+u3.sfdir3.list[0].offset = firstbit: mount failed (32).
+u3.sfdir3.list[0].offset = middlebit: mount failed (32).
+u3.sfdir3.list[0].offset = lastbit: mount failed (32).
+u3.sfdir3.list[0].offset = add: mount failed (32).
+u3.sfdir3.list[0].offset = sub: mount failed (32).
+u3.sfdir3.list[0].name = zeroes: mount failed (32).
+u3.sfdir3.list[0].name = ones: mount failed (32).
+u3.sfdir3.list[0].name = firstbit: mount failed (32).
+u3.sfdir3.list[0].name = middlebit: mount failed (32).
+u3.sfdir3.list[0].name = lastbit: mount failed (32).
+u3.sfdir3.list[0].name = add: mount failed (32).
+u3.sfdir3.list[0].name = sub: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = lastbit: offline repair failed (1).
+u3.sfdir3.list[0].inumber.i4 = lastbit: offline re-scrub failed (1).
+u3.sfdir3.list[0].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[0].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[0].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[0].filetype = ones: mount failed (32).
+u3.sfdir3.list[0].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[0].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[0].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[0].filetype = add: mount failed (32).
+u3.sfdir3.list[0].filetype = sub: mount failed (32).
+u3.sfdir3.list[1].namelen = zeroes: mount failed (32).
+u3.sfdir3.list[1].namelen = ones: mount failed (32).
+u3.sfdir3.list[1].namelen = firstbit: mount failed (32).
+u3.sfdir3.list[1].namelen = middlebit: mount failed (32).
+u3.sfdir3.list[1].namelen = lastbit: mount failed (32).
+u3.sfdir3.list[1].namelen = add: mount failed (32).
+u3.sfdir3.list[1].namelen = sub: mount failed (32).
+u3.sfdir3.list[1].offset = zeroes: mount failed (32).
+u3.sfdir3.list[1].offset = ones: mount failed (32).
+u3.sfdir3.list[1].offset = firstbit: mount failed (32).
+u3.sfdir3.list[1].offset = middlebit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = middlebit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = lastbit: online scrub didn't fail.
+u3.sfdir3.list[1].offset = add: offline scrub didn't fail.
+u3.sfdir3.list[1].offset = add: online scrub didn't fail.
+u3.sfdir3.list[1].offset = sub: mount failed (32).
+u3.sfdir3.list[1].name = zeroes: mount failed (32).
+u3.sfdir3.list[1].name = ones: mount failed (32).
+u3.sfdir3.list[1].name = firstbit: mount failed (32).
+u3.sfdir3.list[1].name = middlebit: mount failed (32).
+u3.sfdir3.list[1].name = lastbit: mount failed (32).
+u3.sfdir3.list[1].name = add: mount failed (32).
+u3.sfdir3.list[1].name = sub: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = zeroes: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = ones: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = firstbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = middlebit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = lastbit: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = add: mount failed (32).
+u3.sfdir3.list[1].inumber.i4 = sub: mount failed (32).
+u3.sfdir3.list[1].filetype = zeroes: mount failed (32).
+u3.sfdir3.list[1].filetype = ones: mount failed (32).
+u3.sfdir3.list[1].filetype = firstbit: mount failed (32).
+u3.sfdir3.list[1].filetype = middlebit: mount failed (32).
+u3.sfdir3.list[1].filetype = lastbit: mount failed (32).
+u3.sfdir3.list[1].filetype = add: mount failed (32).
+u3.sfdir3.list[1].filetype = sub: mount failed (32).
+a.sfattr.hdr.totsize = zeroes: mount failed (32).
+a.sfattr.hdr.totsize = ones: mount failed (32).
+a.sfattr.hdr.totsize = firstbit: mount failed (32).
+a.sfattr.hdr.totsize = middlebit: mount failed (32).
+a.sfattr.hdr.totsize = lastbit: mount failed (32).
+a.sfattr.hdr.totsize = add: mount failed (32).
+a.sfattr.hdr.totsize = sub: mount failed (32).
+a.sfattr.hdr.count = zeroes: mount failed (32).
+a.sfattr.hdr.count = ones: mount failed (32).
+a.sfattr.hdr.count = firstbit: mount failed (32).
+a.sfattr.hdr.count = middlebit: mount failed (32).
+a.sfattr.hdr.count = lastbit: mount failed (32).
+a.sfattr.hdr.count = add: mount failed (32).
+a.sfattr.hdr.count = sub: mount failed (32).
+a.sfattr.list[0].namelen = zeroes: mount failed (32).
+a.sfattr.list[0].namelen = ones: mount failed (32).
+a.sfattr.list[0].namelen = firstbit: mount failed (32).
+a.sfattr.list[0].namelen = middlebit: mount failed (32).
+a.sfattr.list[0].namelen = lastbit: mount failed (32).
+a.sfattr.list[0].namelen = add: mount failed (32).
+a.sfattr.list[0].namelen = sub: mount failed (32).
+a.sfattr.list[0].parent = zeroes: online repair failed (1).
+a.sfattr.list[0].parent = add: online repair failed (1).
+a.sfattr.list[0].parent_ino = zeroes: online repair failed (1).
+a.sfattr.list[0].parent_ino = firstbit: online repair failed (1).
+a.sfattr.list[0].parent_ino = middlebit: online repair failed (1).
+a.sfattr.list[0].parent_ino = lastbit: online repair failed (1).
+a.sfattr.list[0].parent_ino = add: online repair failed (1).
+a.sfattr.list[0].parent_gen = ones: online repair failed (1).
+a.sfattr.list[0].parent_gen = firstbit: online repair failed (1).
+a.sfattr.list[0].parent_gen = middlebit: online repair failed (1).
+a.sfattr.list[0].parent_gen = lastbit: online repair failed (1).
+a.sfattr.list[0].parent_gen = add: online repair failed (1).
+a.sfattr.list[0].parent_namehash = zeroes: online repair failed (1).
+a.sfattr.list[0].parent_namehash = firstbit: online repair failed (1).
+a.sfattr.list[0].parent_namehash = middlebit: online repair failed (1).
+a.sfattr.list[0].parent_namehash = lastbit: online repair failed (1).
+a.sfattr.list[0].parent_name = firstbit: online repair failed (1).
+a.sfattr.list[0].parent_name = middlebit: online repair failed (1).
+a.sfattr.list[0].parent_name = add: online repair failed (1).
+a.sfattr.list[0].parent_name = sub: online repair failed (1).
Done fuzzing metadir subdir
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 11/11] xfs: test metapath repairs
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (9 preceding siblings ...)
2023-12-27 13:52 ` [PATCH 10/11] xfs: baseline golden output for metadata directory fuzz tests Darrick J. Wong
@ 2023-12-27 13:52 ` Darrick J. Wong
10 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:52 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Functional testing for metadir path checking and repairs.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1874 | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1874.out | 16 ++++++
2 files changed, 148 insertions(+)
create mode 100755 tests/xfs/1874
create mode 100644 tests/xfs/1874.out
diff --git a/tests/xfs/1874 b/tests/xfs/1874
new file mode 100755
index 0000000000..a00b58773f
--- /dev/null
+++ b/tests/xfs/1874
@@ -0,0 +1,132 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2023-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test 1874
+#
+# Functional test of using online repair to fix metadir paths.
+#
+. ./common/preamble
+_begin_fstest auto online_repair
+
+# Override the default cleanup function.
+# _cleanup()
+# {
+# cd /
+# rm -r -f $tmp.*
+# }
+
+# Import common functions.
+source ./common/filter
+source ./common/inject
+source ./common/fuzzy
+source ./common/quota
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs xfs
+_require_xfs_db_command "link"
+_require_xfs_db_command "unlink"
+_require_scratch
+_require_xfs_stress_online_repair
+
+prepare_fs() {
+ # Format filesystem
+ _scratch_mkfs | _filter_mkfs 2> $tmp.mkfs >> $seqres.full
+ _scratch_mount
+
+ $XFS_INFO_PROG $SCRATCH_MNT | grep -q 'metadir=1' || \
+ _notrun "metadata directories must be enabled"
+
+ $XFS_INFO_PROG $SCRATCH_MNT | grep -q 'parent=1' || \
+ _notrun "parent pointers must be enabled"
+
+ root_inum="$(stat -c '%i' $SCRATCH_MNT)"
+ __stress_scrub_check_commands "%dir%" '' '' 'scrub metapath'
+ _scratch_unmount
+
+ # Stash the /realtime inode number and gen
+ rt_metadir_inum=$(_scratch_xfs_get_metadata_field v3.inumber 'path -m /realtime')
+ rt_metadir_gen=$(_scratch_xfs_get_metadata_field core.gen 'path -m /realtime')
+
+ # Stash the /realtime/bitmap inode number and gen
+ rbm_inum=$(_scratch_xfs_get_metadata_field v3.inumber 'path -m /realtime/bitmap')
+ rbm_gen=$(_scratch_xfs_get_metadata_field core.gen 'path -m /realtime/bitmap')
+
+ # Fuzz parent pointer in rtbitmap file
+ _scratch_xfs_db -x \
+ -c 'path -m /realtime/bitmap' \
+ -c "write -d a.sfattr.list[0].parent_ino $root_inum" >> $seqres.full.
+}
+
+simple_online_repair() {
+ echo "check /realtime dir" | _tee_kernlog
+ $XFS_IO_PROG -c "scrub directory $rt_metadir_inum $rt_metadir_gen" $SCRATCH_MNT
+
+ echo "check /realtime/bitmap pptr" | _tee_kernlog
+ $XFS_IO_PROG -c "scrub parent $rbm_inum $rbm_gen" $SCRATCH_MNT
+
+ echo "check /realtime/bitmap metapath" | _tee_kernlog
+ $XFS_IO_PROG -c "scrub metapath rtbitmap" $SCRATCH_MNT
+
+ echo "check nlinks" | _tee_kernlog
+ $XFS_IO_PROG -c "scrub nlinks" $SCRATCH_MNT
+
+ # Destroying a metadir path (e.g. /realtime/bitmap) cannot be done
+ # offline because then the mount will fail. Hence we must use a
+ # specific sequence of online repairs to remove the metadir path link.
+ # Only then can we use the metapath scrubber to restore the link.
+
+ # Force repair the parent directory. Since /realtime/bitmap has a bad
+ # parent pointer, the "bitmap" entry in /realtime will not be created.
+ echo "fix /realtime dir" | _tee_kernlog
+ $XFS_IO_PROG -x -c "repair -R directory $rt_metadir_inum $rt_metadir_gen" $SCRATCH_MNT
+
+ # Force repair the parent pointer. Since the "bitmap" entry in
+ # /realtime no longer exists and no other directories count the
+ # rtbitmap as a parent, this will fail cross-referencing after the
+ # repair.
+ echo "fix /realtime/bitmap pptr" | _tee_kernlog
+ $XFS_IO_PROG -x -c "repair -R parent $rbm_inum $rbm_gen" $SCRATCH_MNT
+
+ # Now that we've completely erased the /realtime/bitmap path, check
+ # that the link is indeed lost, and restore the link.
+ echo "fix /realtime/bitmap metapath" | _tee_kernlog
+ $XFS_IO_PROG -x -c "repair metapath rtbitmap" $SCRATCH_MNT
+
+ # Make sure we're not missing any link count
+ echo "fix nlinks" | _tee_kernlog
+ $XFS_IO_PROG -x -c "repair nlinks" $SCRATCH_MNT
+}
+
+# Part 1: Use raw ioctls to detect the error and fix it.
+prepare_fs
+_scratch_mount
+simple_online_repair
+_check_scratch_fs
+_scratch_unmount
+
+# Part 2: Use xfs_scrub to detect the error and fix it.
+prepare_fs
+_scratch_mount
+echo "fix with xfs_scrub" | _tee_kernlog
+_scratch_scrub &>> $seqres.full
+echo "xfs_scrub returned $?" >> $seqres.full
+_check_scratch_fs
+_scratch_unmount
+
+# Part 3: Use xfs_repair to detect the error and fix it.
+prepare_fs
+echo "fix with xfs_repair" | _tee_kernlog
+echo repair?? >> $seqres.full
+_scratch_xfs_repair &>> $seqres.full
+echo "xfs_repair returned $?" >> $seqres.full
+_scratch_mount
+_check_scratch_fs
+_scratch_unmount
+
+echo "done with test" | _tee_kernlog
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1874.out b/tests/xfs/1874.out
new file mode 100644
index 0000000000..1c29698283
--- /dev/null
+++ b/tests/xfs/1874.out
@@ -0,0 +1,16 @@
+QA output created by 1874
+check /realtime dir
+Corruption detected during cross-referencing.
+check /realtime/bitmap pptr
+Corruption detected during cross-referencing.
+check /realtime/bitmap metapath
+check nlinks
+fix /realtime dir
+fix /realtime/bitmap pptr
+Corruption remains.
+Corruption still detected during cross-referencing.
+fix /realtime/bitmap metapath
+fix nlinks
+fix with xfs_scrub
+fix with xfs_repair
+done with test
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 01/17] common/populate: refactor caching of metadumps to a helper
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
@ 2023-12-27 13:53 ` Darrick J. Wong
2023-12-27 13:53 ` [PATCH 02/17] common/xfs: wipe external logs during mdrestore operations Darrick J. Wong
` (15 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:53 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Hoist out of _scratch_populate_cached all the code that we use to save a
metadump of the populated filesystem. We're going to make this more
involved for XFS in the next few patches so that we can take advantage
of the new support for external devices in metadump/mdrestore.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/populate | 37 ++++++++++++++++++++++++++++---------
1 file changed, 28 insertions(+), 9 deletions(-)
diff --git a/common/populate b/common/populate
index 83cd0eb5db..72c88e0651 100644
--- a/common/populate
+++ b/common/populate
@@ -1047,6 +1047,31 @@ _scratch_populate_restore_cached() {
return 1
}
+# Take a metadump of the scratch filesystem and cache it for later.
+_scratch_populate_save_metadump()
+{
+ local metadump_file="$1"
+
+ case "${FSTYP}" in
+ "xfs")
+ local logdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
+ logdev=$SCRATCH_LOGDEV
+
+ _xfs_metadump "$metadump_file" "$SCRATCH_DEV" "$logdev" \
+ compress
+ res=$?
+ ;;
+ "ext2"|"ext3"|"ext4")
+ _ext4_metadump "${SCRATCH_DEV}" "${metadump_file}" compress
+ res=$?
+ ;;
+ *)
+ _fail "Don't know how to save a ${FSTYP} filesystem."
+ esac
+ return $res
+}
+
# Populate a scratch FS from scratch or from a cached image.
_scratch_populate_cached() {
local meta_descr="$(_scratch_populate_cache_tag "$@")"
@@ -1070,26 +1095,20 @@ _scratch_populate_cached() {
# Oh well, just create one from scratch
_scratch_mkfs
- echo "${meta_descr}" > "${populate_metadump_descr}"
case "${FSTYP}" in
"xfs")
_scratch_xfs_populate $@
_scratch_xfs_populate_check
-
- local logdev=none
- [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
- logdev=$SCRATCH_LOGDEV
-
- _xfs_metadump "$POPULATE_METADUMP" "$SCRATCH_DEV" "$logdev" \
- compress
;;
"ext2"|"ext3"|"ext4")
_scratch_ext4_populate $@
_scratch_ext4_populate_check
- _ext4_metadump "${SCRATCH_DEV}" "${POPULATE_METADUMP}" compress
;;
*)
_fail "Don't know how to populate a ${FSTYP} filesystem."
;;
esac
+
+ _scratch_populate_save_metadump "${POPULATE_METADUMP}" && \
+ echo "${meta_descr}" > "${populate_metadump_descr}"
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 02/17] common/xfs: wipe external logs during mdrestore operations
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
2023-12-27 13:53 ` [PATCH 01/17] common/populate: refactor caching of metadumps to a helper Darrick J. Wong
@ 2023-12-27 13:53 ` Darrick J. Wong
2023-12-27 13:53 ` [PATCH 03/17] common/ext4: reformat " Darrick J. Wong
` (14 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:53 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The XFS metadump file format doesn't support the capture of external log
devices, which means that mdrestore ought to wipe the external log and
run xfs_repair to rewrite the log device as needed to get the restored
filesystem to work again. The common/populate code could already do
this, so push it to the common xfs helper.
While we're at it, fix the uncareful usage of SCRATCH_LOGDEV in the
populate code.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/fuzzy | 7 ++++++-
common/populate | 19 ++++++-------------
common/xfs | 21 +++++++++++++++++++--
3 files changed, 31 insertions(+), 16 deletions(-)
diff --git a/common/fuzzy b/common/fuzzy
index b72b4a9fe7..b72ee3f67f 100644
--- a/common/fuzzy
+++ b/common/fuzzy
@@ -304,7 +304,12 @@ __scratch_xfs_fuzz_unmount()
__scratch_xfs_fuzz_mdrestore()
{
__scratch_xfs_fuzz_unmount
- _xfs_mdrestore "${POPULATE_METADUMP}" "${SCRATCH_DEV}" || \
+
+ local logdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
+ logdev=$SCRATCH_LOGDEV
+
+ _xfs_mdrestore "${POPULATE_METADUMP}" "${SCRATCH_DEV}" "${logdev}" || \
_fail "${POPULATE_METADUMP}: Could not find metadump to restore?"
}
diff --git a/common/populate b/common/populate
index 72c88e0651..92a3c5e354 100644
--- a/common/populate
+++ b/common/populate
@@ -1011,21 +1011,14 @@ _scratch_populate_cache_tag() {
_scratch_populate_restore_cached() {
local metadump="$1"
+ local logdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
+ logdev=$SCRATCH_LOGDEV
+
case "${FSTYP}" in
"xfs")
- _xfs_mdrestore "${metadump}" "${SCRATCH_DEV}"
- res=$?
- test $res -ne 0 && return $res
-
- # Cached images should have been unmounted cleanly, so if
- # there's an external log we need to wipe it and run repair to
- # format it to match this filesystem.
- if [ -n "${SCRATCH_LOGDEV}" ]; then
- $WIPEFS_PROG -a "${SCRATCH_LOGDEV}"
- _scratch_xfs_repair
- res=$?
- fi
- return $res
+ _xfs_mdrestore "${metadump}" "${SCRATCH_DEV}" "${logdev}"
+ return $?
;;
"ext2"|"ext3"|"ext4")
_ext4_mdrestore "${metadump}" "${SCRATCH_DEV}"
diff --git a/common/xfs b/common/xfs
index b88491666d..77ba786ece 100644
--- a/common/xfs
+++ b/common/xfs
@@ -683,7 +683,8 @@ _xfs_metadump() {
_xfs_mdrestore() {
local metadump="$1"
local device="$2"
- shift; shift
+ local logdev="$3"
+ shift; shift; shift
local options="$@"
# If we're configured for compressed dumps and there isn't already an
@@ -697,6 +698,18 @@ _xfs_mdrestore() {
test -r "$metadump" || return 1
$XFS_MDRESTORE_PROG $options "${metadump}" "${device}"
+ res=$?
+ test $res -ne 0 && return $res
+
+ # mdrestore does not know how to restore an external log. If there is
+ # one, we need to erase the log header and run xfs_repair to format a
+ # new log header onto the log device.
+ if [ "$logdev" != "none" ]; then
+ $XFS_IO_PROG -d -c 'pwrite -S 0 -q 0 1m' "$logdev"
+ _scratch_xfs_repair >> $seqres.full 2>&1
+ res=$?
+ fi
+ return $res
}
# Snapshot the metadata on the scratch device
@@ -718,7 +731,11 @@ _scratch_xfs_mdrestore()
local metadump=$1
shift
- _xfs_mdrestore "$metadump" "$SCRATCH_DEV" "$@"
+ local logdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
+ logdev=$SCRATCH_LOGDEV
+
+ _xfs_mdrestore "$metadump" "$SCRATCH_DEV" "$logdev" "$@"
}
# Do not use xfs_repair (offline fsck) to rebuild the filesystem
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 03/17] common/ext4: reformat external logs during mdrestore operations
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
2023-12-27 13:53 ` [PATCH 01/17] common/populate: refactor caching of metadumps to a helper Darrick J. Wong
2023-12-27 13:53 ` [PATCH 02/17] common/xfs: wipe external logs during mdrestore operations Darrick J. Wong
@ 2023-12-27 13:53 ` Darrick J. Wong
2023-12-27 13:53 ` [PATCH 04/17] xfs: use metadump v2 format by default Darrick J. Wong
` (13 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:53 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The e2image file format doesn't support the capture of external log
devices, which means that mdrestore ought to reformat the external log
to get the restored filesystem to work again. The common/populate code
could already do this, so push it to the common ext4 helper.
While we're at it, fix the uncareful usage of SCRATCH_LOGDEV in the
populate code.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/ext4 | 17 ++++++++++++++++-
common/populate | 16 ++--------------
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/common/ext4 b/common/ext4
index 3dcbfe17c9..5171b8df68 100644
--- a/common/ext4
+++ b/common/ext4
@@ -134,7 +134,8 @@ _ext4_mdrestore()
{
local metadump="$1"
local device="$2"
- shift; shift
+ local logdev="$3"
+ shift; shift; shift
local options="$@"
# If we're configured for compressed dumps and there isn't already an
@@ -148,6 +149,20 @@ _ext4_mdrestore()
test -r "$metadump" || return 1
$E2IMAGE_PROG $options -r "${metadump}" "${SCRATCH_DEV}"
+ res=$?
+ test $res -ne 0 && return $res
+
+ # ext4 cannot e2image external logs, so we have to reformat the log
+ # device to match the restored fs
+ if [ "${logdev}" != "none" ]; then
+ local fsuuid="$($DUMPE2FS_PROG -h "${SCRATCH_DEV}" 2>/dev/null | \
+ grep 'Journal UUID:' | \
+ sed -e 's/Journal UUID:[[:space:]]*//g')"
+ $MKFS_EXT4_PROG -O journal_dev "${logdev}" \
+ -F -U "${fsuuid}"
+ res=$?
+ fi
+ return $res
}
# this test requires the ext4 kernel support crc feature on scratch device
diff --git a/common/populate b/common/populate
index 92a3c5e354..450b024bfc 100644
--- a/common/populate
+++ b/common/populate
@@ -1021,20 +1021,8 @@ _scratch_populate_restore_cached() {
return $?
;;
"ext2"|"ext3"|"ext4")
- _ext4_mdrestore "${metadump}" "${SCRATCH_DEV}"
- ret=$?
- test $ret -ne 0 && return $ret
-
- # ext4 cannot e2image external logs, so we have to reformat
- # the scratch device to match the restored fs
- if [ -n "${SCRATCH_LOGDEV}" ]; then
- local fsuuid="$($DUMPE2FS_PROG -h "${SCRATCH_DEV}" 2>/dev/null | \
- grep 'Journal UUID:' | \
- sed -e 's/Journal UUID:[[:space:]]*//g')"
- $MKFS_EXT4_PROG -O journal_dev "${SCRATCH_LOGDEV}" \
- -F -U "${fsuuid}"
- fi
- return 0
+ _ext4_mdrestore "${metadump}" "${SCRATCH_DEV}" "${logdev}"
+ return $?
;;
esac
return 1
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 04/17] xfs: use metadump v2 format by default
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (2 preceding siblings ...)
2023-12-27 13:53 ` [PATCH 03/17] common/ext4: reformat " Darrick J. Wong
@ 2023-12-27 13:53 ` Darrick J. Wong
2023-12-27 13:54 ` [PATCH 05/17] common/xfs: capture external logs during metadump/mdrestore Darrick J. Wong
` (12 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:53 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Create metadump v2 files by default.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/common/xfs b/common/xfs
index 77ba786ece..4e8630b3ab 100644
--- a/common/xfs
+++ b/common/xfs
@@ -669,6 +669,14 @@ _xfs_metadump() {
local options="$@"
test -z "$options" && options="-a -o"
+ # Use metadump v2 format unless the user gave us a specific version
+ $XFS_METADUMP_PROG --help 2>&1 | grep -q -- '-v version' && \
+ metadump_has_v2=1
+
+ if ! echo "$options" | grep -q -- '-v' && [ -n "$metadump_has_v2" ]; then
+ options="$options -v 2"
+ fi
+
if [ "$logdev" != "none" ]; then
options="$options -l $logdev"
fi
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 05/17] common/xfs: capture external logs during metadump/mdrestore
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (3 preceding siblings ...)
2023-12-27 13:53 ` [PATCH 04/17] xfs: use metadump v2 format by default Darrick J. Wong
@ 2023-12-27 13:54 ` Darrick J. Wong
2023-12-27 13:54 ` [PATCH 06/17] xfs/122: update for rtgroups Darrick J. Wong
` (11 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:54 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
If xfs_mdrestore supports the -l switch and there's an external scratch
log, pass the option so that we can restore log contents.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 40 +++++++++++++++++++++++++++++++++-------
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/common/xfs b/common/xfs
index 4e8630b3ab..175de69c63 100644
--- a/common/xfs
+++ b/common/xfs
@@ -668,6 +668,7 @@ _xfs_metadump() {
shift; shift; shift; shift
local options="$@"
test -z "$options" && options="-a -o"
+ local metadump_has_dash_x
# Use metadump v2 format unless the user gave us a specific version
$XFS_METADUMP_PROG --help 2>&1 | grep -q -- '-v version' && \
@@ -694,6 +695,12 @@ _xfs_mdrestore() {
local logdev="$3"
shift; shift; shift
local options="$@"
+ local need_repair
+ local mdrestore_has_dash_l
+
+ # Does mdrestore support restoring to external devices?
+ $XFS_MDRESTORE_PROG --help 2>&1 | grep -q -- '-l logdev' &&
+ mdrestore_has_dash_l=1
# If we're configured for compressed dumps and there isn't already an
# uncompressed dump, see if we can use DUMP_COMPRESSOR to decompress
@@ -705,19 +712,38 @@ _xfs_mdrestore() {
fi
test -r "$metadump" || return 1
+ if [ "$logdev" != "none" ]; then
+ # We have an external log device. If mdrestore supports
+ # restoring to it, configure ourselves to do that.
+ if [ -n "$mdrestore_has_dash_l" ]; then
+ options="$options -l $logdev"
+ fi
+
+ # Wipe the log device. If mdrestore doesn't support restoring
+ # to external log devices or the metadump file doesn't capture
+ # the log contents, this is our only chance to signal that the
+ # log header needs to be rewritten.
+ $XFS_IO_PROG -d -c 'pwrite -S 0 -q 0 1m' "$logdev"
+ fi
+
$XFS_MDRESTORE_PROG $options "${metadump}" "${device}"
res=$?
test $res -ne 0 && return $res
- # mdrestore does not know how to restore an external log. If there is
- # one, we need to erase the log header and run xfs_repair to format a
- # new log header onto the log device.
+ # If there's an external log, check to see if the restore rewrote the
+ # log header. If not, we need to run xfs_repair to format a new log
+ # header onto the log device.
if [ "$logdev" != "none" ]; then
- $XFS_IO_PROG -d -c 'pwrite -S 0 -q 0 1m' "$logdev"
- _scratch_xfs_repair >> $seqres.full 2>&1
- res=$?
+ magic="$($XFS_IO_PROG -c 'pread -q -v 0 4' "$logdev")"
+ if [ "$magic" = "00000000: 00 00 00 00 ...." ]; then
+ need_repair=1
+ fi
fi
- return $res
+
+ test -z "$need_repair" && return 0
+
+ echo "repairing fs to fix uncaptured parts of fs." >> $seqres.full
+ _scratch_xfs_repair >> $seqres.full 2>&1
}
# Snapshot the metadata on the scratch device
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 06/17] xfs/122: update for rtgroups
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (4 preceding siblings ...)
2023-12-27 13:54 ` [PATCH 05/17] common/xfs: capture external logs during metadump/mdrestore Darrick J. Wong
@ 2023-12-27 13:54 ` Darrick J. Wong
2023-12-27 13:54 ` [PATCH 07/17] punch-alternating: detect xfs realtime files with large allocation units Darrick J. Wong
` (10 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:54 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Add our new metadata for realtime allocation groups to the ondisk checking.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/122.out | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/xfs/122.out b/tests/xfs/122.out
index 430b805792..21b139d838 100644
--- a/tests/xfs/122.out
+++ b/tests/xfs/122.out
@@ -44,6 +44,9 @@ offsetof(xfs_sb_t, sb_rbmino) = 64
offsetof(xfs_sb_t, sb_rextents) = 24
offsetof(xfs_sb_t, sb_rextsize) = 80
offsetof(xfs_sb_t, sb_rextslog) = 125
+offsetof(xfs_sb_t, sb_rgblklog) = 280
+offsetof(xfs_sb_t, sb_rgblocks) = 272
+offsetof(xfs_sb_t, sb_rgcount) = 276
offsetof(xfs_sb_t, sb_rootino) = 56
offsetof(xfs_sb_t, sb_rrmapino) = 264
offsetof(xfs_sb_t, sb_rsumino) = 72
@@ -116,9 +119,11 @@ sizeof(struct xfs_refcount_key) = 4
sizeof(struct xfs_refcount_rec) = 12
sizeof(struct xfs_rmap_key) = 20
sizeof(struct xfs_rmap_rec) = 24
+sizeof(struct xfs_rtgroup_geometry) = 128
sizeof(struct xfs_rtrmap_key) = 24
sizeof(struct xfs_rtrmap_rec) = 32
sizeof(struct xfs_rtrmap_root) = 4
+sizeof(struct xfs_rtsb) = 104
sizeof(struct xfs_rud_log_format) = 16
sizeof(struct xfs_rui_log_format) = 16
sizeof(struct xfs_scrub_metadata) = 64
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 07/17] punch-alternating: detect xfs realtime files with large allocation units
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (5 preceding siblings ...)
2023-12-27 13:54 ` [PATCH 06/17] xfs/122: update for rtgroups Darrick J. Wong
@ 2023-12-27 13:54 ` Darrick J. Wong
2023-12-27 13:54 ` [PATCH 08/17] xfs/206: update mkfs filtering for rt groups feature Darrick J. Wong
` (9 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:54 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
For files on the XFS realtime volume, it's possible that the file
allocation unit (aka the minimum size we have to punch to deallocate
file blocks) could be greater than a single fs block. This utility
assumed that it's always possible to punch a single fs block, but for
these types of files, all that does is zeroes the page cache. While
that's what most *user applications* want, fstests uses punching to
fragment file mapping metadata and/or fragment free space, so adapt this
test for that purpose by detecting realtime files.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
src/punch-alternating.c | 28 +++++++++++++++++++++++++++-
tests/xfs/114 | 4 ++++
tests/xfs/146 | 2 +-
tests/xfs/187 | 3 ++-
tests/xfs/341 | 4 ++--
5 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/src/punch-alternating.c b/src/punch-alternating.c
index 18dd215197..d2bb4b6a22 100644
--- a/src/punch-alternating.c
+++ b/src/punch-alternating.c
@@ -20,6 +20,28 @@ void usage(char *cmd)
exit(1);
}
+/* Compute the file allocation unit size for an XFS file. */
+static int detect_xfs_alloc_unit(int fd)
+{
+ struct fsxattr fsx;
+ struct xfs_fsop_geom fsgeom;
+ int ret;
+
+ ret = ioctl(fd, XFS_IOC_FSGEOMETRY, &fsgeom);
+ if (ret)
+ return -1;
+
+ ret = ioctl(fd, XFS_IOC_FSGETXATTR, &fsx);
+ if (ret)
+ return -1;
+
+ ret = fsgeom.blocksize;
+ if (fsx.fsx_xflags & XFS_XFLAG_REALTIME)
+ ret *= fsgeom.rtextsize;
+
+ return ret;
+}
+
int main(int argc, char *argv[])
{
struct stat s;
@@ -82,7 +104,11 @@ int main(int argc, char *argv[])
goto err;
sz = s.st_size;
- blksz = sf.f_bsize;
+ c = detect_xfs_alloc_unit(fd);
+ if (c > 0)
+ blksz = c;
+ else
+ blksz = sf.f_bsize;
mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
for (offset = start_offset * blksz;
diff --git a/tests/xfs/114 b/tests/xfs/114
index 0e8a0529ab..7ecb4d217c 100755
--- a/tests/xfs/114
+++ b/tests/xfs/114
@@ -49,6 +49,10 @@ $XFS_IO_PROG -f \
-c "pwrite -S 0x68 -b 1048576 0 $len2" \
$SCRATCH_MNT/f2 >> $seqres.full
+# The arguments to punch-alternating must be specified in units of file
+# allocation units, so we divide the argument by $file_blksz. We already
+# verified that $blksz is congruent with $file_blksz, so the fpunch parameters
+# will always align with the file allocation unit.
$here/src/punch-alternating -o $((16 * blksz / file_blksz)) \
-s $((blksz / file_blksz)) \
-i $((blksz * 2 / file_blksz)) \
diff --git a/tests/xfs/146 b/tests/xfs/146
index 5090435976..5d30cd8123 100755
--- a/tests/xfs/146
+++ b/tests/xfs/146
@@ -69,7 +69,7 @@ _xfs_force_bdev realtime $SCRATCH_MNT
# Allocate some stuff at the start, to force the first falloc of the ouch file
# to happen somewhere in the middle of the rt volume
$XFS_IO_PROG -f -c 'falloc 0 64m' "$SCRATCH_MNT/b"
-$here/src/punch-alternating -i $((rextblks * 2)) -s $((rextblks)) "$SCRATCH_MNT/b"
+$here/src/punch-alternating "$SCRATCH_MNT/b"
avail="$(df -P "$SCRATCH_MNT" | awk 'END {print $4}')"1
toobig="$((avail * 2))"
diff --git a/tests/xfs/187 b/tests/xfs/187
index 7c34d8e630..14c3b37670 100755
--- a/tests/xfs/187
+++ b/tests/xfs/187
@@ -132,7 +132,8 @@ $XFS_IO_PROG -f -c "truncate $required_sz" -c "falloc 0 $remap_sz" $SCRATCH_MNT/
# Punch out every other extent of the last two sections, to fragment free space.
frag_sz=$((remap_sz * 3))
punch_off=$((bigfile_sz - frag_sz))
-$here/src/punch-alternating $SCRATCH_MNT/bigfile -o $((punch_off / fsbsize)) -i $((rtextsize_blks * 2)) -s $rtextsize_blks
+rtextsize_bytes=$((fsbsize * rtextsize_blks))
+$here/src/punch-alternating $SCRATCH_MNT/bigfile -o $((punch_off / rtextsize_bytes))
# Make sure we have some free rtextents.
free_rtx=$($XFS_IO_PROG -c 'statfs' $SCRATCH_MNT | grep statfs.f_bavail | awk '{print $3}')
diff --git a/tests/xfs/341 b/tests/xfs/341
index 1f734c9015..7d2842b579 100755
--- a/tests/xfs/341
+++ b/tests/xfs/341
@@ -43,8 +43,8 @@ len=$((blocks * rtextsz))
echo "Create some files"
$XFS_IO_PROG -f -R -c "falloc 0 $len" -c "pwrite -S 0x68 -b 1048576 0 $len" $SCRATCH_MNT/f1 >> $seqres.full
$XFS_IO_PROG -f -R -c "falloc 0 $len" -c "pwrite -S 0x68 -b 1048576 0 $len" $SCRATCH_MNT/f2 >> $seqres.full
-$here/src/punch-alternating -i $((2 * rtextsz_blks)) -s $rtextsz_blks $SCRATCH_MNT/f1 >> "$seqres.full"
-$here/src/punch-alternating -i $((2 * rtextsz_blks)) -s $rtextsz_blks $SCRATCH_MNT/f2 >> "$seqres.full"
+$here/src/punch-alternating $SCRATCH_MNT/f1 >> "$seqres.full"
+$here/src/punch-alternating $SCRATCH_MNT/f2 >> "$seqres.full"
echo garbage > $SCRATCH_MNT/f3
ino=$(stat -c '%i' $SCRATCH_MNT/f3)
_scratch_unmount
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 08/17] xfs/206: update mkfs filtering for rt groups feature
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (6 preceding siblings ...)
2023-12-27 13:54 ` [PATCH 07/17] punch-alternating: detect xfs realtime files with large allocation units Darrick J. Wong
@ 2023-12-27 13:54 ` Darrick J. Wong
2023-12-27 13:55 ` [PATCH 09/17] common: pass the realtime device to xfs_db when possible Darrick J. Wong
` (8 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:54 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Filter out the new mkfs lines that show the rtgroup information, since
this test is heavily dependent on old mkfs output.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/206 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/xfs/206 b/tests/xfs/206
index 9fd9400daf..4aceb12715 100755
--- a/tests/xfs/206
+++ b/tests/xfs/206
@@ -66,7 +66,8 @@ mkfs_filter()
-e "/.*crc=/d" \
-e "/^Default configuration/d" \
-e 's/, parent=[01]//' \
- -e '/metadir=.*/d'
+ -e '/metadir=.*/d' \
+ -e '/rgcount=/d'
}
# mkfs slightly smaller than that, small log for speed.
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 09/17] common: pass the realtime device to xfs_db when possible
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (7 preceding siblings ...)
2023-12-27 13:54 ` [PATCH 08/17] xfs/206: update mkfs filtering for rt groups feature Darrick J. Wong
@ 2023-12-27 13:55 ` Darrick J. Wong
2023-12-27 13:55 ` [PATCH 10/17] common: filter rtgroups when we're disabling metadir Darrick J. Wong
` (7 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:55 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Teach xfstests to pass the realtime device to xfs_db when it supports
that option.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/common/xfs b/common/xfs
index 175de69c63..aa1c23dd54 100644
--- a/common/xfs
+++ b/common/xfs
@@ -282,10 +282,10 @@ _xfs_check()
{
OPTS=" "
DBOPTS=" "
- USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special"
+ USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-r rtdev] [-i ino]... [-b bno]... special"
OPTIND=1
- while getopts "b:fi:l:stvV" c; do
+ while getopts "b:fi:l:stvVR:" c; do
case $c in
s) OPTS=$OPTS"-s ";;
t) OPTS=$OPTS"-t ";;
@@ -297,6 +297,7 @@ _xfs_check()
V) $XFS_DB_PROG -p xfs_check -V
return $?
;;
+ r) DBOPTS="$DBOPTS -R $OPTARG";;
esac
done
set -- extra $@
@@ -340,6 +341,10 @@ _scratch_xfs_db_options()
SCRATCH_OPTIONS=""
[ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV"
+ if [ "$USE_EXTERNAL" = yes ] && [ ! -z "$SCRATCH_RTDEV" ]; then
+ $XFS_DB_PROG --help 2>&1 | grep -q -- '-R rtdev' && \
+ SCRATCH_OPTIONS="$SCRATCH_OPTIONS -R$SCRATCH_RTDEV"
+ fi
echo $SCRATCH_OPTIONS $* $SCRATCH_DEV
}
@@ -404,6 +409,11 @@ _scratch_xfs_check()
SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV"
[ "$LARGE_SCRATCH_DEV" = yes ] && \
SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t"
+ if [ "$USE_EXTERNAL" = yes ] && [ ! -z "$SCRATCH_RTDEV" ]; then
+ $XFS_DB_PROG --help 2>&1 | grep -q -- '-R rtdev' || \
+ _notrun 'xfs_db does not support rt devices'
+ SCRATCH_OPTIONS="$SCRATCH_OPTIONS -R$SCRATCH_RTDEV"
+ fi
_xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 10/17] common: filter rtgroups when we're disabling metadir
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (8 preceding siblings ...)
2023-12-27 13:55 ` [PATCH 09/17] common: pass the realtime device to xfs_db when possible Darrick J. Wong
@ 2023-12-27 13:55 ` Darrick J. Wong
2023-12-27 13:55 ` [PATCH 11/17] xfs/185: update for rtgroups Darrick J. Wong
` (6 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:55 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
If we're forcing a filesystem to be created without the metadir feature,
we should forcibly disable rtgroups as well.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/common/xfs b/common/xfs
index aa1c23dd54..e66e11f15d 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1936,6 +1936,10 @@ _scratch_xfs_find_metafile()
# Force metadata directories off.
_scratch_xfs_force_no_metadir()
{
+ if echo "$MKFS_OPTIONS" | grep -q 'rtgroups='; then
+ MKFS_OPTIONS="$(echo "$MKFS_OPTIONS" | sed -e 's/rtgroups=\([01]\)/rtgroups=0/g')"
+ fi
+
if echo "$MKFS_OPTIONS" | grep -q 'metadir='; then
MKFS_OPTIONS="$(echo "$MKFS_OPTIONS" | sed -e 's/metadir=\([01]\)/metadir=0/g')"
return
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 11/17] xfs/185: update for rtgroups
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (9 preceding siblings ...)
2023-12-27 13:55 ` [PATCH 10/17] common: filter rtgroups when we're disabling metadir Darrick J. Wong
@ 2023-12-27 13:55 ` Darrick J. Wong
2023-12-27 13:55 ` [PATCH 12/17] xfs/449: update test to know about xfs_db -R Darrick J. Wong
` (5 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:55 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Send the fallocate results to seqres.full, since it doesn't matter if
the call fails as long as we get the layout that we wanted. This test
already has code to check the layout, so there's no point in failing on
random ENOSPC errors.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/185 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/xfs/185 b/tests/xfs/185
index abeb052580..04770fd6c9 100755
--- a/tests/xfs/185
+++ b/tests/xfs/185
@@ -100,7 +100,7 @@ test "$ddbytes" -lt "$((rtbytes + (10 * rtextsize) ))" || \
# easy because fallocate for the first rt file always starts allocating at
# physical offset zero.
alloc_rtx="$((rtbytes / rtextsize))"
-$XFS_IO_PROG -c "falloc 0 $((alloc_rtx * rtextsize))" $rtfile
+$XFS_IO_PROG -c "falloc 0 $((alloc_rtx * rtextsize))" $rtfile &>> $seqres.full
expected_end="$(( (alloc_rtx * rtextsize - 1) / 512 ))"
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 12/17] xfs/449: update test to know about xfs_db -R
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (10 preceding siblings ...)
2023-12-27 13:55 ` [PATCH 11/17] xfs/185: update for rtgroups Darrick J. Wong
@ 2023-12-27 13:55 ` Darrick J. Wong
2023-12-27 13:56 ` [PATCH 13/17] xfs/122: update for rtbitmap headers Darrick J. Wong
` (4 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:55 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The realtime groups feature added a -R flag to xfs_db so that users can
pass in the realtime device. Since we've now modified the
_scratch_xfs_db to use this facility, we can update the test to do exact
comparisons of the xfs_db info command against the mkfs output.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/449 | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/xfs/449 b/tests/xfs/449
index 5374bf2f85..66c443e994 100755
--- a/tests/xfs/449
+++ b/tests/xfs/449
@@ -32,7 +32,11 @@ echo DB >> $seqres.full
cat $tmp.dbinfo >> $seqres.full
# xfs_db doesn't take a rtdev argument, so it reports "realtime=external".
# mkfs does, so make a quick substitution
-diff -u <(cat $tmp.mkfs | sed -e 's/realtime =\/.*extsz=/realtime =external extsz=/g') $tmp.dbinfo
+if $XFS_DB_PROG --help 2>&1 | grep -q -- '-R rtdev'; then
+ diff -u $tmp.mkfs $tmp.dbinfo
+else
+ diff -u <(cat $tmp.mkfs | sed -e 's/realtime =\/.*extsz=/realtime =external extsz=/g') $tmp.dbinfo
+fi
_scratch_mount
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 13/17] xfs/122: update for rtbitmap headers
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (11 preceding siblings ...)
2023-12-27 13:55 ` [PATCH 12/17] xfs/449: update test to know about xfs_db -R Darrick J. Wong
@ 2023-12-27 13:56 ` Darrick J. Wong
2023-12-27 13:56 ` [PATCH 14/17] xfs/122: udpate test to pick up rtword/suminfo ondisk unions Darrick J. Wong
` (3 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:56 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/122.out | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/xfs/122.out b/tests/xfs/122.out
index 21b139d838..8bb79ba959 100644
--- a/tests/xfs/122.out
+++ b/tests/xfs/122.out
@@ -119,6 +119,7 @@ sizeof(struct xfs_refcount_key) = 4
sizeof(struct xfs_refcount_rec) = 12
sizeof(struct xfs_rmap_key) = 20
sizeof(struct xfs_rmap_rec) = 24
+sizeof(struct xfs_rtbuf_blkinfo) = 48
sizeof(struct xfs_rtgroup_geometry) = 128
sizeof(struct xfs_rtrmap_key) = 24
sizeof(struct xfs_rtrmap_rec) = 32
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 14/17] xfs/122: udpate test to pick up rtword/suminfo ondisk unions
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (12 preceding siblings ...)
2023-12-27 13:56 ` [PATCH 13/17] xfs/122: update for rtbitmap headers Darrick J. Wong
@ 2023-12-27 13:56 ` Darrick J. Wong
2023-12-27 13:56 ` [PATCH 15/17] xfs/27[46],xfs/556: fix tests to deal with rtgroups output in bmap/fsmap commands Darrick J. Wong
` (2 subsequent siblings)
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:56 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Update this test to check that the ondisk unions for rt bitmap word and
rt summary counts are always the correct size.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/122 | 2 +-
tests/xfs/122.out | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/xfs/122 b/tests/xfs/122
index ba927c77c4..4e5ba1dfee 100755
--- a/tests/xfs/122
+++ b/tests/xfs/122
@@ -195,7 +195,7 @@ echo 'int main(int argc, char *argv[]) {' >>$cprog
#
cat /usr/include/xfs/xfs*.h | indent |\
_attribute_filter |\
-grep -E '(} *xfs_.*_t|^struct xfs_[a-z0-9_]*$)' |\
+grep -E '(} *xfs_.*_t|^(union|struct) xfs_[a-z0-9_]*$)' |\
grep -E -v -f $tmp.ignore |\
sed -e 's/^.*}[[:space:]]*//g' -e 's/;.*$//g' -e 's/_t, /_t\n/g' |\
sort | uniq |\
diff --git a/tests/xfs/122.out b/tests/xfs/122.out
index 8bb79ba959..6b03b90c2d 100644
--- a/tests/xfs/122.out
+++ b/tests/xfs/122.out
@@ -134,6 +134,8 @@ sizeof(struct xfs_swap_extent) = 64
sizeof(struct xfs_sxd_log_format) = 16
sizeof(struct xfs_sxi_log_format) = 80
sizeof(struct xfs_unmount_log_format) = 8
+sizeof(union xfs_rtword_raw) = 4
+sizeof(union xfs_suminfo_raw) = 4
sizeof(xfs_agf_t) = 224
sizeof(xfs_agfl_t) = 36
sizeof(xfs_agi_t) = 344
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 15/17] xfs/27[46],xfs/556: fix tests to deal with rtgroups output in bmap/fsmap commands
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (13 preceding siblings ...)
2023-12-27 13:56 ` [PATCH 14/17] xfs/122: udpate test to pick up rtword/suminfo ondisk unions Darrick J. Wong
@ 2023-12-27 13:56 ` Darrick J. Wong
2023-12-27 13:56 ` [PATCH 16/17] common/xfs: capture realtime devices during metadump/mdrestore Darrick J. Wong
2023-12-27 13:57 ` [PATCH 17/17] common/fuzzy: adapt the scrub stress tests to support rtgroups Darrick J. Wong
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:56 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Fix these tests to deal with the xfs_io bmap and fsmap commands printing
out realtime group numbers if the feature is enabled.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 7 +++++++
tests/xfs/271 | 3 ++-
tests/xfs/556 | 16 ++++++++++------
3 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/common/xfs b/common/xfs
index e66e11f15d..1136d685e7 100644
--- a/common/xfs
+++ b/common/xfs
@@ -485,6 +485,13 @@ _xfs_has_feature()
feat="rtextents"
feat_regex="[1-9][0-9]*"
;;
+ "rtgroups")
+ # any fs with rtgroups enabled will have a nonzero rt group
+ # size, even if there is no rt device (and hence zero actual
+ # groups)
+ feat="rgsize"
+ feat_regex="[1-9][0-9]*"
+ ;;
esac
local answer="$($XFS_INFO_PROG "$fs" 2>&1 | grep -E -w -c "$feat=$feat_regex")"
diff --git a/tests/xfs/271 b/tests/xfs/271
index d67ac4d6c1..74e2c822c1 100755
--- a/tests/xfs/271
+++ b/tests/xfs/271
@@ -31,6 +31,7 @@ _scratch_mkfs > "$seqres.full" 2>&1
_scratch_mount
agcount=$(_xfs_mount_agcount $SCRATCH_MNT)
+rgcount=$(_xfs_mount_rgcount $SCRATCH_MNT)
# mkfs lays out btree root blocks in the order bnobt, cntbt, inobt, finobt,
# rmapbt, refcountbt, and then allocates AGFL blocks. Since GETFSMAP has the
@@ -48,7 +49,7 @@ cat $TEST_DIR/fsmap >> $seqres.full
echo "Check AG header" | tee -a $seqres.full
grep 'static fs metadata[[:space:]]*[0-9]*[[:space:]]*(0\.\.' $TEST_DIR/fsmap | tee -a $seqres.full > $TEST_DIR/testout
-_within_tolerance "AG header count" $(wc -l < $TEST_DIR/testout) $agcount 0 -v
+_within_tolerance "AG header count" $(wc -l < $TEST_DIR/testout) $((agcount + rgcount)) 0 -v
echo "Check freesp/rmap btrees" | tee -a $seqres.full
grep 'per-AG metadata[[:space:]]*[0-9]*[[:space:]]*([0-9]*\.\.' $TEST_DIR/fsmap | tee -a $seqres.full > $TEST_DIR/testout
diff --git a/tests/xfs/556 b/tests/xfs/556
index 061d8d5723..5940226223 100755
--- a/tests/xfs/556
+++ b/tests/xfs/556
@@ -47,16 +47,20 @@ victim=$SCRATCH_MNT/a
file_blksz=$(_get_file_block_size $SCRATCH_MNT)
$XFS_IO_PROG -f -c "pwrite -S 0x58 0 $((4 * file_blksz))" -c "fsync" $victim >> $seqres.full
unset errordev
-_xfs_is_realtime_file $victim && errordev="RT"
+
+awk_len_prog='{print $6}'
+if _xfs_is_realtime_file $victim; then
+ if ! _xfs_has_feature $SCRATCH_MNT rtgroups; then
+ awk_len_prog='{print $4}'
+ fi
+ errordev="RT"
+fi
bmap_str="$($XFS_IO_PROG -c "bmap -elpv" $victim | grep "^[[:space:]]*0:")"
echo "$errordev:$bmap_str" >> $seqres.full
phys="$(echo "$bmap_str" | $AWK_PROG '{print $3}')"
-if [ "$errordev" = "RT" ]; then
- len="$(echo "$bmap_str" | $AWK_PROG '{print $4}')"
-else
- len="$(echo "$bmap_str" | $AWK_PROG '{print $6}')"
-fi
+len="$(echo "$bmap_str" | $AWK_PROG "$awk_len_prog")"
+
fs_blksz=$(_get_block_size $SCRATCH_MNT)
echo "file_blksz:$file_blksz:fs_blksz:$fs_blksz" >> $seqres.full
kernel_sectors_per_fs_block=$((fs_blksz / 512))
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 16/17] common/xfs: capture realtime devices during metadump/mdrestore
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (14 preceding siblings ...)
2023-12-27 13:56 ` [PATCH 15/17] xfs/27[46],xfs/556: fix tests to deal with rtgroups output in bmap/fsmap commands Darrick J. Wong
@ 2023-12-27 13:56 ` Darrick J. Wong
2023-12-27 13:57 ` [PATCH 17/17] common/fuzzy: adapt the scrub stress tests to support rtgroups Darrick J. Wong
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:56 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
If xfs_metadump supports the -r switch to capture the contents of
realtime devices and there is a realtime device, add the option to the
command line to enable preservation.
Similarly, if xfs_mdrestore supports the -r switch and there's an
external scratch rtdev, pass the option so that we can restore rtdev
contents.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/fuzzy | 6 ++++-
common/populate | 12 ++++++++--
common/xfs | 65 +++++++++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/common/fuzzy b/common/fuzzy
index b72ee3f67f..d504f0854e 100644
--- a/common/fuzzy
+++ b/common/fuzzy
@@ -309,7 +309,11 @@ __scratch_xfs_fuzz_mdrestore()
[ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
logdev=$SCRATCH_LOGDEV
- _xfs_mdrestore "${POPULATE_METADUMP}" "${SCRATCH_DEV}" "${logdev}" || \
+ local rtdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
+ rtdev=$SCRATCH_RTDEV
+
+ _xfs_mdrestore "${POPULATE_METADUMP}" "${SCRATCH_DEV}" "${logdev}" "${rtdev}" || \
_fail "${POPULATE_METADUMP}: Could not find metadump to restore?"
}
diff --git a/common/populate b/common/populate
index 450b024bfc..dc89eee70e 100644
--- a/common/populate
+++ b/common/populate
@@ -1017,7 +1017,11 @@ _scratch_populate_restore_cached() {
case "${FSTYP}" in
"xfs")
- _xfs_mdrestore "${metadump}" "${SCRATCH_DEV}" "${logdev}"
+ local rtdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
+ rtdev=$SCRATCH_RTDEV
+
+ _xfs_mdrestore "${metadump}" "${SCRATCH_DEV}" "${logdev}" "${rtdev}"
return $?
;;
"ext2"|"ext3"|"ext4")
@@ -1039,8 +1043,12 @@ _scratch_populate_save_metadump()
[ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
logdev=$SCRATCH_LOGDEV
+ local rtdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
+ rtdev=$SCRATCH_RTDEV
+
_xfs_metadump "$metadump_file" "$SCRATCH_DEV" "$logdev" \
- compress
+ "$rtdev" compress
res=$?
;;
"ext2"|"ext3"|"ext4")
diff --git a/common/xfs b/common/xfs
index 1136d685e7..1ff81f4cc2 100644
--- a/common/xfs
+++ b/common/xfs
@@ -681,11 +681,17 @@ _xfs_metadump() {
local metadump="$1"
local device="$2"
local logdev="$3"
- local compressopt="$4"
- shift; shift; shift; shift
+ local rtdev="$4"
+ local compressopt="$5"
+ shift; shift; shift; shift; shift
local options="$@"
test -z "$options" && options="-a -o"
local metadump_has_dash_x
+ local metadump_has_dash_r
+
+ # Does metadump support capturing realtime devices?
+ $XFS_METADUMP_PROG --help 2>&1 | grep -q -- '-r rtdev' && \
+ metadump_has_dash_r=1
# Use metadump v2 format unless the user gave us a specific version
$XFS_METADUMP_PROG --help 2>&1 | grep -q -- '-v version' && \
@@ -699,6 +705,10 @@ _xfs_metadump() {
options="$options -l $logdev"
fi
+ if [ "$rtdev" != "none" ] && [ -n "$metadump_has_dash_r" ]; then
+ options="$options -r $rtdev"
+ fi
+
$XFS_METADUMP_PROG $options "$device" "$metadump"
res=$?
[ "$compressopt" = "compress" ] && [ -n "$DUMP_COMPRESSOR" ] &&
@@ -710,14 +720,19 @@ _xfs_mdrestore() {
local metadump="$1"
local device="$2"
local logdev="$3"
- shift; shift; shift
+ local rtdev="$4"
+ shift; shift; shift; shift
local options="$@"
local need_repair
local mdrestore_has_dash_l
+ local mdrestore_has_dash_r
# Does mdrestore support restoring to external devices?
$XFS_MDRESTORE_PROG --help 2>&1 | grep -q -- '-l logdev' &&
mdrestore_has_dash_l=1
+ # Does mdrestore support restoring to realtime devices?
+ $XFS_MDRESTORE_PROG --help 2>&1 | grep -q -- '-r rtdev' &&
+ mdrestore_has_dash_r=1
# If we're configured for compressed dumps and there isn't already an
# uncompressed dump, see if we can use DUMP_COMPRESSOR to decompress
@@ -743,6 +758,20 @@ _xfs_mdrestore() {
$XFS_IO_PROG -d -c 'pwrite -S 0 -q 0 1m' "$logdev"
fi
+ if [ "$rtdev" != "none" ]; then
+ # We have a realtime device. If mdrestore supports restoring
+ # to it, configure ourselves to do that.
+ if [ -n "$mdrestore_has_dash_r" ]; then
+ options="$options -r $rtdev"
+ fi
+
+ # Wipe the realtime device. If mdrestore doesn't support
+ # restoring to realtime devices or the metadump file doesn't
+ # capture the realtime group headers, this is our only chance
+ # to signal that the log header needs to be rewritten.
+ $XFS_IO_PROG -d -c 'pwrite -S 0 -q 0 1m' "$rtdev"
+ fi
+
$XFS_MDRESTORE_PROG $options "${metadump}" "${device}"
res=$?
test $res -ne 0 && return $res
@@ -757,6 +786,16 @@ _xfs_mdrestore() {
fi
fi
+ # If there's a realtime device, check to see if the restore rewrote the
+ # rt group headers. If not, we need to run xfs_repair to format new
+ # group headers onto the realtime device.
+ if [ "$rtdev" != "none" ] && [ -z "$need_repair" ]; then
+ magic="$($XFS_IO_PROG -c 'pread -q -v 0 4' "$rtdev")"
+ if [ "$magic" = "00000000: 00 00 00 00 ...." ]; then
+ need_repair=1
+ fi
+ fi
+
test -z "$need_repair" && return 0
echo "repairing fs to fix uncaptured parts of fs." >> $seqres.full
@@ -768,12 +807,16 @@ _scratch_xfs_metadump()
{
local metadump=$1
shift
+
local logdev=none
-
[ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
logdev=$SCRATCH_LOGDEV
- _xfs_metadump "$metadump" "$SCRATCH_DEV" "$logdev" nocompress "$@"
+ local rtdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
+ rtdev=$SCRATCH_RTDEV
+
+ _xfs_metadump "$metadump" "$SCRATCH_DEV" "$logdev" "$rtdev" nocompress "$@"
}
# Restore snapshotted metadata on the scratch device
@@ -786,7 +829,11 @@ _scratch_xfs_mdrestore()
[ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \
logdev=$SCRATCH_LOGDEV
- _xfs_mdrestore "$metadump" "$SCRATCH_DEV" "$logdev" "$@"
+ local rtdev=none
+ [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \
+ rtdev=$SCRATCH_RTDEV
+
+ _xfs_mdrestore "$metadump" "$SCRATCH_DEV" "$logdev" "$rtdev" "$@"
}
# Do not use xfs_repair (offline fsck) to rebuild the filesystem
@@ -923,7 +970,7 @@ _check_xfs_filesystem()
if [ "$ok" -ne 1 ] && [ "$DUMP_CORRUPT_FS" = "1" ]; then
local flatdev="$(basename "$device")"
_xfs_metadump "$seqres.$flatdev.check.md" "$device" "$logdev" \
- compress >> $seqres.full
+ "$rtdev" compress >> $seqres.full
fi
# Optionally test the index rebuilding behavior.
@@ -956,7 +1003,7 @@ _check_xfs_filesystem()
if [ "$rebuild_ok" -ne 1 ] && [ "$DUMP_CORRUPT_FS" = "1" ]; then
local flatdev="$(basename "$device")"
_xfs_metadump "$seqres.$flatdev.rebuild.md" "$device" \
- "$logdev" compress >> $seqres.full
+ "$logdev" "$rtdev" compress >> $seqres.full
fi
fi
@@ -1040,7 +1087,7 @@ _check_xfs_filesystem()
if [ "$orebuild_ok" -ne 1 ] && [ "$DUMP_CORRUPT_FS" = "1" ]; then
local flatdev="$(basename "$device")"
_xfs_metadump "$seqres.$flatdev.orebuild.md" "$device" \
- "$logdev" compress >> $seqres.full
+ "$logdev" "$rtdev" compress >> $seqres.full
fi
fi
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 17/17] common/fuzzy: adapt the scrub stress tests to support rtgroups
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (15 preceding siblings ...)
2023-12-27 13:56 ` [PATCH 16/17] common/xfs: capture realtime devices during metadump/mdrestore Darrick J. Wong
@ 2023-12-27 13:57 ` Darrick J. Wong
16 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:57 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Adapt the scrub stress testing framework to support checking realtime
group metadata.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/fuzzy | 27 ++++++++++++++++++++++-----
common/xfs | 9 +++++++++
tests/xfs/581 | 2 +-
tests/xfs/720 | 2 +-
tests/xfs/795 | 2 +-
5 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/common/fuzzy b/common/fuzzy
index d504f0854e..2de06622e5 100644
--- a/common/fuzzy
+++ b/common/fuzzy
@@ -847,8 +847,10 @@ __stress_one_scrub_loop() {
local scrub_tgt="$3"
local scrub_startat="$4"
local start_agno="$5"
- shift; shift; shift; shift; shift
+ local start_rgno="$6"
+ shift; shift; shift; shift; shift; shift
local agcount="$(_xfs_mount_agcount $SCRATCH_MNT)"
+ local rgcount="$(_xfs_mount_rgcount $SCRATCH_MNT)"
local xfs_io_args=()
for arg in "$@"; do
@@ -861,6 +863,12 @@ __stress_one_scrub_loop() {
local ag_arg="$(echo "$arg" | sed -e "s|%agno%|$agno|g")"
xfs_io_args+=('-c' "$ag_arg")
done
+ elif echo "$arg" | grep -q -w '%rgno%'; then
+ # Substitute the rtgroup number
+ for ((rgno = start_rgno; rgno < rgcount; rgno++)); do
+ local rg_arg="$(echo "$arg" | sed -e "s|%rgno%|$rgno|g")"
+ xfs_io_args+=('-c' "$rg_arg")
+ done
else
xfs_io_args+=('-c' "$arg")
fi
@@ -1245,7 +1253,9 @@ _scratch_xfs_stress_scrub_cleanup() {
__stress_scrub_check_commands() {
local scrub_tgt="$1"
local start_agno="$2"
- shift; shift
+ local start_rgno="$3"
+ shift; shift; shift
+ local rgcount="$(_xfs_mount_rgcount $SCRATCH_MNT)"
local cooked_tgt="$scrub_tgt"
case "$scrub_tgt" in
@@ -1275,6 +1285,10 @@ __stress_scrub_check_commands() {
cooked_arg="$(echo "$cooked_arg" | sed -e 's/^repair/repair -R/g')"
fi
cooked_arg="$(echo "$cooked_arg" | sed -e "s/%agno%/$start_agno/g")"
+ if echo "$cooked_arg" | grep -q -w '%rgno%'; then
+ test "$rgcount" -eq 0 && continue
+ cooked_arg="$(echo "$cooked_arg" | sed -e "s/%rgno%/$start_rgno/g")"
+ fi
testio=`$XFS_IO_PROG -x -c "$cooked_arg" "$cooked_tgt" 2>&1`
echo $testio | grep -q "Unknown type" && \
_notrun "xfs_io scrub subcommand support is missing"
@@ -1300,6 +1314,7 @@ __stress_scrub_check_commands() {
# in a separate loop. If zero -i options are specified, do not run.
# Callers must check each of these commands (via _require_xfs_io_command)
# before calling here.
+# -R For %rgno% substitution, start with this rtgroup instead of rtgroup 0.
# -r Run fsstress for this amount of time, then remount the fs ro or rw.
# The default is to run fsstress continuously with no remount, unless
# XFS_SCRUB_STRESS_REMOUNT_PERIOD is set.
@@ -1346,6 +1361,7 @@ _scratch_xfs_stress_scrub() {
local remount_period="${XFS_SCRUB_STRESS_REMOUNT_PERIOD}"
local stress_tgt="${XFS_SCRUB_STRESS_TARGET:-default}"
local start_agno=0
+ local start_rgno=0
__SCRUB_STRESS_FREEZE_PID=""
__SCRUB_STRESS_REMOUNT_LOOP=""
@@ -1353,12 +1369,13 @@ _scratch_xfs_stress_scrub() {
touch "$runningfile"
OPTIND=1
- while getopts "a:fi:r:s:S:t:w:x:X:" c; do
+ while getopts "a:fi:r:R:s:S:t:w:x:X:" c; do
case "$c" in
a) start_agno="$OPTARG";;
f) freeze=yes;;
i) io_args+=("$OPTARG");;
r) remount_period="$OPTARG";;
+ R) start_rgno="$OPTARG";;
s) one_scrub_args+=("$OPTARG");;
S) xfs_scrub_args+=("$OPTARG");;
t) scrub_tgt="$OPTARG";;
@@ -1369,7 +1386,7 @@ _scratch_xfs_stress_scrub() {
esac
done
- __stress_scrub_check_commands "$scrub_tgt" "$start_agno" \
+ __stress_scrub_check_commands "$scrub_tgt" "$start_agno" "$start_rgno" \
"${one_scrub_args[@]}"
if ! command -v "__stress_scrub_${exerciser}_loop" &>/dev/null; then
@@ -1425,7 +1442,7 @@ _scratch_xfs_stress_scrub() {
if [ "${#one_scrub_args[@]}" -gt 0 ]; then
__stress_one_scrub_loop "$end" "$runningfile" "$scrub_tgt" \
- "$scrub_startat" "$start_agno" \
+ "$scrub_startat" "$start_agno" "$start_rgno" \
"${one_scrub_args[@]}" &
fi
diff --git a/common/xfs b/common/xfs
index 1ff81f4cc2..313b7045bd 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1584,6 +1584,15 @@ _xfs_mount_agcount()
$XFS_INFO_PROG "$1" | sed -n "s/^.*agcount=\([[:digit:]]*\).*/\1/p"
}
+# Find rtgroup count of mounted filesystem
+_xfs_mount_rgcount()
+{
+ local rtgroups="$($XFS_INFO_PROG "$1" | grep rgcount= | sed -e 's/^.*rgcount=\([0-9]*\).*$/\1/g')"
+
+ test -z "$rtgroups" && rtgroups=0
+ echo "$rtgroups"
+}
+
# Wipe the superblock of each XFS AGs
_try_wipe_scratch_xfs()
{
diff --git a/tests/xfs/581 b/tests/xfs/581
index 1d08bc7df3..353421130e 100755
--- a/tests/xfs/581
+++ b/tests/xfs/581
@@ -32,7 +32,7 @@ _require_xfs_stress_scrub
_scratch_mkfs > "$seqres.full" 2>&1
_scratch_mount
_require_xfs_has_feature "$SCRATCH_MNT" realtime
-_scratch_xfs_stress_scrub -s "scrub rtbitmap"
+_scratch_xfs_stress_scrub -s "scrub rtbitmap" -s "scrub rgbitmap %rgno%"
# success, all done
echo Silence is golden
diff --git a/tests/xfs/720 b/tests/xfs/720
index 2b6406da6e..3242a19b02 100755
--- a/tests/xfs/720
+++ b/tests/xfs/720
@@ -39,7 +39,7 @@ alloc_unit=$(_get_file_block_size $SCRATCH_MNT)
scratchfile=$SCRATCH_MNT/file
touch $scratchfile
$XFS_IO_PROG -x -c 'inject force_repair' $SCRATCH_MNT
-__stress_scrub_check_commands "$scratchfile" "" 'repair bmapbtd'
+__stress_scrub_check_commands "$scratchfile" "" "" 'repair bmapbtd'
# Compute the number of extent records needed to guarantee btree format,
# assuming 16 bytes for each ondisk extent record
diff --git a/tests/xfs/795 b/tests/xfs/795
index a381db320f..2ce2ec5365 100755
--- a/tests/xfs/795
+++ b/tests/xfs/795
@@ -39,7 +39,7 @@ scratchfile=$SCRATCH_MNT/file
mkdir $scratchdir
touch $scratchfile
$XFS_IO_PROG -x -c 'inject force_repair' $SCRATCH_MNT
-__stress_scrub_check_commands "$scratchdir" "" 'repair directory'
+__stress_scrub_check_commands "$scratchdir" "" "" 'repair directory'
# Create a 2-dirblock directory
total_size=$((alloc_unit * 2))
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 1/2] xfs: refactor statfs field extraction
2023-12-31 20:00 ` [PATCHSET v2.0 3/9] fstests: enable FITRIM for the realtime section Darrick J. Wong
@ 2023-12-27 13:57 ` Darrick J. Wong
2023-12-27 13:57 ` [PATCH 2/2] common/xfs: FITRIM now supports realtime volumes Darrick J. Wong
1 sibling, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:57 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Prepare for the next patch by refactoring the open-coded bits that call
statfs on a mounted xfs filesystem to extract a status field.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 6 ++++++
tests/xfs/176 | 4 ++--
tests/xfs/187 | 6 +++---
tests/xfs/541 | 6 ++----
4 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/common/xfs b/common/xfs
index 313b7045bd..d9aa242ec7 100644
--- a/common/xfs
+++ b/common/xfs
@@ -2063,3 +2063,9 @@ _require_xfs_scratch_metadir()
_scratch_unmount
fi
}
+
+# Extract a statfs attribute of the given mounted XFS filesystem.
+_xfs_statfs_field()
+{
+ $XFS_IO_PROG -c 'statfs' "$1" | grep -E "$2" | cut -d ' ' -f 3
+}
diff --git a/tests/xfs/176 b/tests/xfs/176
index 5231b888ba..0af81fcce3 100755
--- a/tests/xfs/176
+++ b/tests/xfs/176
@@ -49,7 +49,7 @@ fi
_scratch_mount
_xfs_force_bdev data $SCRATCH_MNT
-old_dblocks=$($XFS_IO_PROG -c 'statfs' $SCRATCH_MNT | grep geom.datablocks)
+old_dblocks=$(_xfs_statfs_field "$SCRATCH_MNT" geom.datablocks)
mkdir $SCRATCH_MNT/save/
sino=$(stat -c '%i' $SCRATCH_MNT/save)
@@ -172,7 +172,7 @@ for ((ino = target_ino; ino >= icluster_ino; ino--)); do
res=$?
# Make sure shrink did not work
- new_dblocks=$($XFS_IO_PROG -c 'statfs' $SCRATCH_MNT | grep geom.datablocks)
+ new_dblocks=$(_xfs_statfs_field "$SCRATCH_MNT" geom.datablocks)
if [ "$new_dblocks" != "$old_dblocks" ]; then
echo "should not have shrank $old_dblocks -> $new_dblocks"
break
diff --git a/tests/xfs/187 b/tests/xfs/187
index 14c3b37670..03d92d0890 100755
--- a/tests/xfs/187
+++ b/tests/xfs/187
@@ -79,8 +79,8 @@ _xfs_force_bdev realtime $SCRATCH_MNT
# Set the extent size hint larger than the realtime extent size. This is
# necessary to exercise the minlen constraints on the realtime allocator.
-fsbsize=$($XFS_IO_PROG -c 'statfs' $SCRATCH_MNT | grep geom.bsize | awk '{print $3}')
-rtextsize_blks=$($XFS_IO_PROG -c 'statfs' $SCRATCH_MNT | grep geom.rtextsize | awk '{print $3}')
+fsbsize=$(_xfs_statfs_field "$SCRATCH_MNT" geom.bsize)
+rtextsize_blks=$(_xfs_statfs_field "$SCRATCH_MNT" geom.rtextsize)
extsize=$((2 * rtextsize_blks * fsbsize))
echo "rtextsize_blks=$rtextsize_blks extsize=$extsize" >> $seqres.full
@@ -136,7 +136,7 @@ rtextsize_bytes=$((fsbsize * rtextsize_blks))
$here/src/punch-alternating $SCRATCH_MNT/bigfile -o $((punch_off / rtextsize_bytes))
# Make sure we have some free rtextents.
-free_rtx=$($XFS_IO_PROG -c 'statfs' $SCRATCH_MNT | grep statfs.f_bavail | awk '{print $3}')
+free_rtx=$(_xfs_statfs_field "$SCRATCH_MNT" statfs.f_bavail)
if [ $free_rtx -eq 0 ]; then
echo "Expected fragmented free rt space, found none."
fi
diff --git a/tests/xfs/541 b/tests/xfs/541
index ae2fd819d5..3a0a9d5390 100755
--- a/tests/xfs/541
+++ b/tests/xfs/541
@@ -83,13 +83,11 @@ test $grow_extszhint -eq 0 || \
echo "expected post-grow extszhint 0, got $grow_extszhint"
# Check that we now have rt extents.
-rtextents=$($XFS_IO_PROG -c 'statfs' $SCRATCH_MNT | \
- grep 'geom.rtextents' | cut -d ' ' -f 3)
+rtextents=$(_xfs_statfs_field "$SCRATCH_MNT" geom.rtextents)
test $rtextents -gt 0 || echo "expected rtextents > 0"
# Check the new rt extent size.
-after_rtextsz_blocks=$($XFS_IO_PROG -c 'statfs' $SCRATCH_MNT | \
- grep 'geom.rtextsize' | cut -d ' ' -f 3)
+after_rtextsz_blocks=$(_xfs_statfs_field "$SCRATCH_MNT" geom.rtextsize)
test $after_rtextsz_blocks -eq $new_rtextsz_blocks || \
echo "expected rtextsize $new_rtextsz_blocks, got $after_rtextsz_blocks"
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 2/2] common/xfs: FITRIM now supports realtime volumes
2023-12-31 20:00 ` [PATCHSET v2.0 3/9] fstests: enable FITRIM for the realtime section Darrick J. Wong
2023-12-27 13:57 ` [PATCH 1/2] xfs: refactor statfs field extraction Darrick J. Wong
@ 2023-12-27 13:57 ` Darrick J. Wong
1 sibling, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:57 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
XFS now supports FITRIM to the realtime volume. Detect this support and
enable it.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 40 ++++++++++++++++++++++++++++++++++++++--
1 file changed, 38 insertions(+), 2 deletions(-)
diff --git a/common/xfs b/common/xfs
index d9aa242ec7..75f1bbcc3d 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1937,8 +1937,44 @@ _require_xfs_scratch_atomicswap()
# of 1024 byte blocks.
_xfs_discard_max_offset_kb()
{
- $XFS_IO_PROG -c 'statfs' "$1" | \
- awk '{g[$1] = $3} END {print (g["geom.bsize"] * g["geom.datablocks"] / 1024)}'
+ local statfs
+
+ # Use awk to read the statfs output for the XFS filesystem, compute
+ # the two possible FITRIM offset maximums, and then use some horrid
+ # bash magic to import the five numbers as an indexed array. There's
+ # no better way to do this in bash since you can't readarray to build
+ # an associative array. Elements are as follows:
+ #
+ # 0: fsblock size in bytes
+ # 1: Data volume size in fsblocks.
+ # 2: Realtime volume size in fsblocks.
+ # 3: Max FITRIM offset if we can only trim the data volume
+ # 4: Max FITRIM offset if we can trim the data and rt volumes
+ readarray -t statfs < <($XFS_IO_PROG -c 'statfs' "$1" | \
+ awk '{g[$1] = $3} END {printf("%d\n%d\n%d\n%d\n%d\n",
+ g["geom.bsize"],
+ g["geom.datablocks"],
+ g["geom.rtblocks"],
+ g["geom.bsize"] * g["geom.datablocks"] / 1024,
+ g["geom.bsize"] * (g["geom.datablocks"] + g["geom.rtblocks"]) / 1024);}')
+
+ # If the kernel supports discarding the realtime volume, then it will
+ # not reject a FITRIM for fsblock dblks+1, even if the len/minlen
+ # arguments are absurd.
+ if [ "${statfs[2]}" -gt 0 ]; then
+ if $FSTRIM_PROG -o "$((statfs[0] * statfs[1]))" \
+ -l "${statfs[0]}" \
+ -m "$((statfs[0] * 2))" "$1" &>/dev/null; then
+ # The kernel supports discarding the rt volume, so
+ # print out the second answer from above.
+ echo "${statfs[4]}"
+ return
+ fi
+ fi
+
+ # The kernel does not support discarding the rt volume or there is no
+ # rt volume. Print out the first answer from above.
+ echo "${statfs[3]}"
}
# Adjust MKFS_OPTIONS as necessary to avoid having parent pointers formatted
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 01/13] xfs: fix tests that try to access the realtime rmap inode
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
@ 2023-12-27 13:57 ` Darrick J. Wong
2023-12-27 13:58 ` [PATCH 02/13] fuzz: for fuzzing the rtrmapbt, find the path to the rt rmap btree file Darrick J. Wong
` (11 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:57 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The realtime rmap tests were added to fstests a long time ago. Since
they were added, we decided to create a metadata file directory
structure instead of adding more fields to the superblock. Therefore,
fix all the tests that try to access these paths.
While we're at it, fix xfs/409 to run the *online* scrub program like
it's supposed to. xfs/408 is the fuzzer for xfs_repair testing.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 41 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/122.out | 1 -
tests/xfs/333 | 45 ---------------------------------------------
tests/xfs/333.out | 6 ------
tests/xfs/337 | 2 +-
tests/xfs/338 | 30 +++++++++++++++++++++++++-----
tests/xfs/339 | 5 +++--
tests/xfs/340 | 25 ++++++++++++++++++++-----
tests/xfs/341 | 2 +-
tests/xfs/342 | 4 ++--
10 files changed, 93 insertions(+), 68 deletions(-)
delete mode 100755 tests/xfs/333
delete mode 100644 tests/xfs/333.out
diff --git a/common/xfs b/common/xfs
index 75f1bbcc3d..d3baa7a7c3 100644
--- a/common/xfs
+++ b/common/xfs
@@ -2105,3 +2105,44 @@ _xfs_statfs_field()
{
$XFS_IO_PROG -c 'statfs' "$1" | grep -E "$2" | cut -d ' ' -f 3
}
+
+# Resolve a metadata directory tree path and return the inode number.
+_scratch_metadir_lookup() {
+ local res="$(_scratch_xfs_db -c "ls -i -m $1")"
+ test "${PIPESTATUS[0]}" -eq 0 && echo "$res"
+}
+
+# Figure out which directory entry we have to change to update the rtrmap
+# inode pointer. The last line of output is inumber field within a metadata
+# object; any previous lines are the accessor commands that must be fed to
+# xfs_db to get to the correct directory block.
+_scratch_find_rt_metadir_entry() {
+ local sfkey="$(_scratch_xfs_db -c 'path -m /realtime' -c print | \
+ grep "\"$1\"" | \
+ sed -e 's/.name.*$//g' -e 's/\[/\\[/g' -e 's/\]/\\]/g' )"
+ if [ -n "$sfkey" ]; then
+ echo 'path -m /realtime'
+ _scratch_xfs_db -c 'path -m /realtime' -c print | \
+ grep "${sfkey}.inumber" | awk '{print $1}'
+ return 0
+ fi
+
+ local size=$(_scratch_xfs_db -c 'path -m /realtime' -c 'print core.size' | awk '{print $3}')
+ local blksz=$(_scratch_xfs_db -c 'sb 0' -c 'print blocksize' | awk '{print $3}')
+ local dirblklog=$(_scratch_xfs_db -c 'sb 0' -c 'print dirblklog' | awk '{print $3}')
+ local dirblksz=$((blksz << dirblklog ))
+ for ((fileoff = 0; fileoff < (size / dirblksz); fileoff++)); do
+ local dbkey="$(_scratch_xfs_db -c 'path -m /realtime' -c "dblock $fileoff" -c 'print' | \
+ grep "\"$1\"" | \
+ sed -e 's/.name.*$//g' -e 's/\[/\\[/g' -e 's/\]/\\]/g' )"
+ if [ -n "$dbkey" ]; then
+ echo 'path -m /realtime'
+ echo "dblock $fileoff"
+ _scratch_xfs_db -c 'path -m /realtime' -c "dblock $fileoff" -c print | \
+ grep "${dbkey}.inumber" | awk '{print $1}'
+ return 0
+ fi
+ done
+
+ return 1
+}
diff --git a/tests/xfs/122.out b/tests/xfs/122.out
index 6b03b90c2d..837286a9d3 100644
--- a/tests/xfs/122.out
+++ b/tests/xfs/122.out
@@ -48,7 +48,6 @@ offsetof(xfs_sb_t, sb_rgblklog) = 280
offsetof(xfs_sb_t, sb_rgblocks) = 272
offsetof(xfs_sb_t, sb_rgcount) = 276
offsetof(xfs_sb_t, sb_rootino) = 56
-offsetof(xfs_sb_t, sb_rrmapino) = 264
offsetof(xfs_sb_t, sb_rsumino) = 72
offsetof(xfs_sb_t, sb_sectlog) = 121
offsetof(xfs_sb_t, sb_sectsize) = 102
diff --git a/tests/xfs/333 b/tests/xfs/333
deleted file mode 100755
index 728c518402..0000000000
--- a/tests/xfs/333
+++ /dev/null
@@ -1,45 +0,0 @@
-#! /bin/bash
-# SPDX-License-Identifier: GPL-2.0
-# Copyright (c) 2016, Oracle and/or its affiliates. All Rights Reserved.
-#
-# FS QA Test No. 333
-#
-# Set rrmapino to another inode on an non-rt rmap fs and see if repair fixes it.
-#
-. ./common/preamble
-_begin_fstest auto quick rmap realtime
-
-# Import common functions.
-. ./common/filter
-
-# real QA test starts here
-_supported_fs xfs
-_require_xfs_scratch_rmapbt
-_disable_dmesg_check
-
-rm -f "$seqres.full"
-
-unset SCRATCH_RTDEV
-
-echo "Format and mount"
-_scratch_mkfs > "$seqres.full" 2>&1
-rrmapino="$(_scratch_xfs_db -c 'sb 0' -c 'p rrmapino' 2>&1)"
-test "${rrmapino}" = "field rrmapino not found" && _notrun "realtime rmapbt not supported"
-_scratch_mount
-
-echo "Create some files"
-$XFS_IO_PROG -f -c "pwrite -S 0x68 0 9999" $SCRATCH_MNT/f1 >> $seqres.full
-$XFS_IO_PROG -f -c "pwrite -S 0x68 0 9999" $SCRATCH_MNT/f2 >> $seqres.full
-echo garbage > $SCRATCH_MNT/f3
-ino=$(stat -c '%i' $SCRATCH_MNT/f3)
-_scratch_unmount
-
-echo "Corrupt fs"
-_scratch_xfs_db -x -c 'sb 0' -c "write rrmapino $ino" >> $seqres.full
-_try_scratch_mount 2>&1 | _filter_error_mount
-
-echo "Test done, mount should have failed"
-
-# success, all done
-status=0
-exit
diff --git a/tests/xfs/333.out b/tests/xfs/333.out
deleted file mode 100644
index b3c698750f..0000000000
--- a/tests/xfs/333.out
+++ /dev/null
@@ -1,6 +0,0 @@
-QA output created by 333
-Format and mount
-Create some files
-Corrupt fs
-mount: Structure needs cleaning
-Test done, mount should have failed
diff --git a/tests/xfs/337 b/tests/xfs/337
index f74baae9b0..9ea8587b27 100755
--- a/tests/xfs/337
+++ b/tests/xfs/337
@@ -53,7 +53,7 @@ echo "+ check fs"
_scratch_xfs_repair -n >> $seqres.full 2>&1 || echo "xfs_repair should not fail"
echo "+ corrupt image"
-_scratch_xfs_db -x -c "sb" -c "addr rrmapino" -c "addr u3.rtrmapbt.ptrs[1]" \
+_scratch_xfs_db -x -c "path -m /realtime/0.rmap" -c "addr u3.rtrmapbt.ptrs[1]" \
-c "stack" -c "blocktrash -x 4096 -y 4096 -n 8 -3 -z" \
>> $seqres.full 2>&1
diff --git a/tests/xfs/338 b/tests/xfs/338
index 9f36150c7e..babadc4e1b 100755
--- a/tests/xfs/338
+++ b/tests/xfs/338
@@ -29,13 +29,33 @@ $XFS_IO_PROG -f -R -c "pwrite -S 0x68 0 9999" $SCRATCH_MNT/f2 >> $seqres.full
_scratch_unmount
echo "Corrupt fs"
-_scratch_xfs_db -x -c 'sb 0' -c 'addr rrmapino' \
- -c 'write core.nlinkv2 0' -c 'write core.mode 0' -c 'sb 0' \
- -c 'write rrmapino 0' >> $seqres.full
-_try_scratch_mount >> $seqres.full 2>&1 && echo "mount should have failed"
+readarray -t rtrmap_path < <(_scratch_find_rt_metadir_entry 0.rmap)
+
+rtrmap_accessors=()
+rtrmap_path_len="${#rtrmap_path[@]}"
+for ((i = 0; i < rtrmap_path_len - 1; i++)); do
+ rtrmap_accessors+=(-c "${rtrmap_path[i]}")
+done
+rtrmap_entry="${rtrmap_path[rtrmap_path_len - 1]}"
+test -n "$rtrmap_entry" || _fail "Could not find rtrmap metadir entry?"
+
+_scratch_xfs_db -x -c 'path -m /realtime/0.rmap' \
+ -c 'write core.nlinkv2 0' -c 'write core.mode 0' \
+ "${rtrmap_accessors[@]}" \
+ -c "print $rtrmap_entry" \
+ -c "write -d $rtrmap_entry 0" >> $seqres.full
+if _try_scratch_mount >> $seqres.full 2>&1; then
+ echo "mount should have failed"
+ _scratch_unmount
+else
+ # If the verifiers are working properly, the mount will fail because
+ # we fuzzed the metadata root directory. This causes loud complaints
+ # to dmesg, so we want to ignore those.
+ _disable_dmesg_check
+fi
echo "Repair fs"
-_scratch_unmount 2>&1 | _filter_scratch
+_scratch_unmount 2>&1 | _filter_scratch | _filter_ending_dot
_repair_scratch_fs >> $seqres.full 2>&1
echo "Try to create more files (again)"
diff --git a/tests/xfs/339 b/tests/xfs/339
index 3e0b4d97ab..24a90d0ba3 100755
--- a/tests/xfs/339
+++ b/tests/xfs/339
@@ -31,7 +31,8 @@ ln $SCRATCH_MNT/f3 $SCRATCH_MNT/f4
_scratch_unmount
echo "Corrupt fs"
-rrmapino=`_scratch_xfs_get_sb_field rrmapino`
+rrmapino=$(_scratch_metadir_lookup /realtime/0.rmap)
+test -n "$rrmapino" || _fail "Could not find rtrmap inode?"
_scratch_xfs_set_metadata_field "u3.sfdir3.list[3].inumber.i4" $rrmapino \
'sb 0' 'addr rootino' >> $seqres.full
_scratch_mount
@@ -43,7 +44,7 @@ echo "Try to create more files"
$XFS_IO_PROG -f -R -c "pwrite -S 0x68 0 9999" $SCRATCH_MNT/f5 >> $seqres.full 2>&1
echo "Repair fs"
-_scratch_unmount 2>&1 | _filter_scratch
+_scratch_unmount 2>&1 | _filter_scratch | _filter_ending_dot
_repair_scratch_fs >> $seqres.full 2>&1
echo "Try to create more files (again)"
diff --git a/tests/xfs/340 b/tests/xfs/340
index 2c0014513e..6ee818becb 100755
--- a/tests/xfs/340
+++ b/tests/xfs/340
@@ -31,16 +31,31 @@ ino=$(stat -c '%i' $SCRATCH_MNT/f3)
_scratch_unmount
echo "Corrupt fs"
-rrmapino=$(_scratch_xfs_get_sb_field rrmapino)
-_scratch_xfs_db -x -c "inode $rrmapino" \
+readarray -t rtrmap_path < <(_scratch_find_rt_metadir_entry 0.rmap)
+
+rtrmap_accessors=()
+rtrmap_path_len="${#rtrmap_path[@]}"
+for ((i = 0; i < rtrmap_path_len - 1; i++)); do
+ rtrmap_accessors+=(-c "${rtrmap_path[i]}")
+done
+rtrmap_entry="${rtrmap_path[rtrmap_path_len - 1]}"
+test -n "$rtrmap_entry" || _fail "Could not find rtrmap metadir entry?"
+
+rrmapino=$(_scratch_metadir_lookup /realtime/0.rmap)
+test -n "$rrmapino" || _fail "Could not find rtrmap inode?"
+_scratch_xfs_db -x -c "path -m /realtime/0.rmap" \
-c 'write core.format 2' -c 'write core.size 0' \
- -c 'write core.nblocks 0' -c 'sb 0' -c 'addr rootino' \
+ -c 'write core.nblocks 0' \
+ -c 'sb 0' -c 'addr rootino' \
+ -c "print u3.sfdir3.list[2].inumber" \
-c "write u3.sfdir3.list[2].inumber.i4 $rrmapino" \
- -c 'sb 0' -c "write rrmapino $ino" >> $seqres.full
+ "${rtrmap_accessors[@]}" \
+ -c "print $rtrmap_entry" \
+ -c "write $rtrmap_entry $ino" >> $seqres.full
_try_scratch_mount >> $seqres.full 2>&1 && echo "mount should have failed"
echo "Repair fs"
-_scratch_unmount 2>&1 | _filter_scratch
+_scratch_unmount 2>&1 | _filter_scratch | _filter_ending_dot
_repair_scratch_fs >> $seqres.full 2>&1
echo "Try to create more files (again)"
diff --git a/tests/xfs/341 b/tests/xfs/341
index 7d2842b579..8861e751a9 100755
--- a/tests/xfs/341
+++ b/tests/xfs/341
@@ -53,7 +53,7 @@ echo "Corrupt fs"
fsbno=$(_scratch_xfs_db -c "inode $ino" -c 'bmap' | grep 'flag 0' | head -n 1 | \
sed -e 's/^.*startblock \([0-9]*\) .*$/\1/g')
-_scratch_xfs_db -x -c 'sb 0' -c 'addr rrmapino' \
+_scratch_xfs_db -x -c 'path -m /realtime/0.rmap' \
-c "write u3.rtrmapbt.ptrs[1] $fsbno" -c 'p' >> $seqres.full
_scratch_mount
diff --git a/tests/xfs/342 b/tests/xfs/342
index 538c8987ef..f29bd874e9 100755
--- a/tests/xfs/342
+++ b/tests/xfs/342
@@ -47,9 +47,9 @@ ino=$(stat -c '%i' $SCRATCH_MNT/f3)
_scratch_unmount
echo "Corrupt fs"
-_scratch_xfs_db -c 'sb 0' -c 'addr rrmapino' -c 'p u3.rtrmapbt.ptrs[1]' >> $seqres.full
+_scratch_xfs_db -c 'path -m /realtime/0.rmap' -c 'p u3.rtrmapbt.ptrs[1]' >> $seqres.full
-fsbno=$(_scratch_xfs_db -c 'sb 0' -c 'addr rrmapino' \
+fsbno=$(_scratch_xfs_db -c 'path -m /realtime/0.rmap' \
-c 'p u3.rtrmapbt.ptrs[1]' | sed -e 's/^.*://g')
_scratch_xfs_db -x -c "inode $ino" -c "write u3.bmx[0].startblock $fsbno" >> $seqres.full
_scratch_mount
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 02/13] fuzz: for fuzzing the rtrmapbt, find the path to the rt rmap btree file
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
2023-12-27 13:57 ` [PATCH 01/13] xfs: fix tests that try to access the realtime rmap inode Darrick J. Wong
@ 2023-12-27 13:58 ` Darrick J. Wong
2023-12-27 13:58 ` [PATCH 03/13] xfs: race fsstress with realtime rmap btree scrub and repair Darrick J. Wong
` (10 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:58 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The fs population code creates a realtime rmap btree in /some/ realtime
group with at least two levels. This rmapbt file isn't necessarily the
one for group 0, so we need to find it programmatically.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 33 +++++++++++++++++++++++++++++++++
tests/xfs/406 | 6 ++++--
tests/xfs/407 | 6 ++++--
tests/xfs/408 | 7 +++++--
tests/xfs/409 | 7 +++++--
tests/xfs/481 | 6 ++++--
tests/xfs/482 | 7 +++++--
7 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/common/xfs b/common/xfs
index d3baa7a7c3..b8dd8d4a40 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1914,6 +1914,39 @@ _scratch_xfs_find_agbtree_height() {
return 1
}
+# Find us the path to the inode containing a realtime btree with a specific
+# height.
+_scratch_xfs_find_rgbtree_height() {
+ local bt_type="$1"
+ local bt_height="$2"
+ local rgcount=$(_xfs_mount_rgcount $SCRATCH_DEV)
+ local path
+ local path_format
+ local bt_prefix
+
+ case "${bt_type}" in
+ "rmap")
+ path_format="/realtime/%u.rmap"
+ bt_prefix="u3.rtrmapbt"
+ ;;
+ *)
+ _fail "Don't know about rt btree ${bt_type}"
+ ;;
+ esac
+
+ for ((rgno = 0; rgno < rgcount; rgno++)); do
+ path="$(printf "${path_format}" "${rgno}")"
+ bt_level=$(_scratch_xfs_db -c "path -m ${path}" -c "p ${bt_prefix}.level" | awk '{print $3}')
+ # "level" is the actual level within the btree
+ if [ "${bt_level}" -eq "$((bt_height - 1))" ]; then
+ echo "${path}"
+ return 0
+ fi
+ done
+
+ return 1
+}
+
_require_xfs_mkfs_atomicswap()
{
# atomicswap can be activated on rmap or reflink filesystems.
diff --git a/tests/xfs/406 b/tests/xfs/406
index 78db18077c..8c5570886b 100755
--- a/tests/xfs/406
+++ b/tests/xfs/406
@@ -26,10 +26,12 @@ _require_scratch_xfs_fuzz_fields
echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
-inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'sb 0' 'addr rrmapino')
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 2)" || \
+ _fail "could not find two-level rtrmapbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
echo "Fuzz rtrmapbt recs"
-_scratch_xfs_fuzz_metadata '' 'offline' 'sb 0' 'addr rrmapino' "addr u${inode_ver}.rtrmapbt.ptrs[1]" >> $seqres.full
+_scratch_xfs_fuzz_metadata '' 'offline' "path -m $path" "addr u${inode_ver}.rtrmapbt.ptrs[1]" >> $seqres.full
echo "Done fuzzing rtrmapbt recs"
# success, all done
diff --git a/tests/xfs/407 b/tests/xfs/407
index 5a43775b55..2460ea336c 100755
--- a/tests/xfs/407
+++ b/tests/xfs/407
@@ -26,10 +26,12 @@ _require_scratch_xfs_fuzz_fields
echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
-inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'sb 0' 'addr rrmapino')
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 1)" || \
+ _fail "could not find two-level rtrmapbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
echo "Fuzz rtrmapbt recs"
-_scratch_xfs_fuzz_metadata '' 'online' 'sb 0' 'addr rrmapino' "addr u${inode_ver}.rtrmapbt.ptrs[1]" >> $seqres.full
+_scratch_xfs_fuzz_metadata '' 'online' "path -m $path" "addr u${inode_ver}.rtrmapbt.ptrs[1]" >> $seqres.full
echo "Done fuzzing rtrmapbt recs"
# success, all done
diff --git a/tests/xfs/408 b/tests/xfs/408
index 8049d6bead..3bed3824e8 100755
--- a/tests/xfs/408
+++ b/tests/xfs/408
@@ -4,7 +4,7 @@
#
# FS QA Test No. 408
#
-# Populate a XFS filesystem and fuzz every rtrmapbt keyptr field.
+# Populate a XFS filesystem and fuzz every rtrmapbt key/pointer field.
# Use xfs_repair to fix the corruption.
#
. ./common/preamble
@@ -26,8 +26,11 @@ _require_scratch_xfs_fuzz_fields
echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 2)" || \
+ _fail "could not find two-level rtrmapbt"
+
echo "Fuzz rtrmapbt keyptrs"
-_scratch_xfs_fuzz_metadata '(rtrmapbt)' 'offline' 'sb 0' 'addr rrmapino' >> $seqres.full
+_scratch_xfs_fuzz_metadata '(rtrmapbt)' 'offline' "path -m $path" >> $seqres.full
echo "Done fuzzing rtrmapbt keyptrs"
# success, all done
diff --git a/tests/xfs/409 b/tests/xfs/409
index adac95fea8..ce66175c6e 100755
--- a/tests/xfs/409
+++ b/tests/xfs/409
@@ -4,7 +4,7 @@
#
# FS QA Test No. 409
#
-# Populate a XFS filesystem and fuzz every rtrmapbt keyptr field.
+# Populate a XFS filesystem and fuzz every rtrmapbt key/pointer field.
# Use xfs_scrub to fix the corruption.
#
. ./common/preamble
@@ -26,8 +26,11 @@ _require_scratch_xfs_fuzz_fields
echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 2)" || \
+ _fail "could not find two-level rtrmapbt"
+
echo "Fuzz rtrmapbt keyptrs"
-_scratch_xfs_fuzz_metadata '(rtrmapbt)' 'offline' 'sb 0' 'addr rrmapino' >> $seqres.full
+_scratch_xfs_fuzz_metadata '(rtrmapbt)' 'online' "path -m $path" >> $seqres.full
echo "Done fuzzing rtrmapbt keyptrs"
# success, all done
diff --git a/tests/xfs/481 b/tests/xfs/481
index 48c7580ccb..d303f2c27d 100755
--- a/tests/xfs/481
+++ b/tests/xfs/481
@@ -27,10 +27,12 @@ _disable_dmesg_check
echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
-inode_ver=$(_scratch_xfs_get_metadata_field "core.version" 'sb 0' 'addr rrmapino')
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 2)" || \
+ _fail "could not find two-level rtrmapbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
echo "Fuzz rtrmapbt recs"
-_scratch_xfs_fuzz_metadata '' 'none' 'sb 0' 'addr rrmapino' "addr u${inode_ver}.rtrmapbt.ptrs[1]" >> $seqres.full
+_scratch_xfs_fuzz_metadata '' 'none' "path -m $path" "addr u${inode_ver}.rtrmapbt.ptrs[1]" >> $seqres.full
echo "Done fuzzing rtrmapbt recs"
# success, all done
diff --git a/tests/xfs/482 b/tests/xfs/482
index 0192b94cc0..32a3012154 100755
--- a/tests/xfs/482
+++ b/tests/xfs/482
@@ -4,7 +4,7 @@
#
# FS QA Test No. 482
#
-# Populate a XFS filesystem and fuzz every rtrmapbt keyptr field.
+# Populate a XFS filesystem and fuzz every rtrmapbt key/pointer field.
# Do not fix the filesystem, to test metadata verifiers.
. ./common/preamble
@@ -27,8 +27,11 @@ _disable_dmesg_check
echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 2)" || \
+ _fail "could not find two-level rtrmapbt"
+
echo "Fuzz rtrmapbt keyptrs"
-_scratch_xfs_fuzz_metadata '(rtrmapbt)' 'offline' 'sb 0' 'addr rrmapino' >> $seqres.full
+_scratch_xfs_fuzz_metadata '(rtrmapbt)' 'offline' "path -m $path" >> $seqres.full
echo "Done fuzzing rtrmapbt keyptrs"
# success, all done
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 03/13] xfs: race fsstress with realtime rmap btree scrub and repair
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
2023-12-27 13:57 ` [PATCH 01/13] xfs: fix tests that try to access the realtime rmap inode Darrick J. Wong
2023-12-27 13:58 ` [PATCH 02/13] fuzz: for fuzzing the rtrmapbt, find the path to the rt rmap btree file Darrick J. Wong
@ 2023-12-27 13:58 ` Darrick J. Wong
2023-12-27 13:58 ` [PATCH 04/13] xfs/856: add rtrmapbt upgrade to test matrix Darrick J. Wong
` (9 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:58 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Race checking and rebuilding realtime rmap btrees with fsstress.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1817 | 42 ++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1817.out | 2 ++
tests/xfs/1821 | 42 ++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1821.out | 2 ++
tests/xfs/1857 | 42 ++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1857.out | 2 ++
6 files changed, 132 insertions(+)
create mode 100755 tests/xfs/1817
create mode 100644 tests/xfs/1817.out
create mode 100755 tests/xfs/1821
create mode 100644 tests/xfs/1821.out
create mode 100755 tests/xfs/1857
create mode 100644 tests/xfs/1857.out
diff --git a/tests/xfs/1817 b/tests/xfs/1817
new file mode 100755
index 0000000000..56ce63e005
--- /dev/null
+++ b/tests/xfs/1817
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1817
+#
+# Race fsstress and rtrmapbt scrub for a while to see if we crash or livelock.
+#
+. ./common/preamble
+_begin_fstest scrub dangerous_fsstress_scrub
+
+_cleanup() {
+ _scratch_xfs_stress_scrub_cleanup &> /dev/null
+ cd /
+ rm -r -f $tmp.*
+}
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/fuzzy
+. ./common/inject
+. ./common/xfs
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch
+_require_xfs_stress_scrub
+
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount
+_require_xfs_has_feature "$SCRATCH_MNT" realtime
+_require_xfs_has_feature "$SCRATCH_MNT" rmapbt
+_xfs_force_bdev realtime $SCRATCH_MNT
+
+_scratch_xfs_stress_scrub -s "scrub rtrmapbt %rgno%"
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/xfs/1817.out b/tests/xfs/1817.out
new file mode 100644
index 0000000000..525ec14ed0
--- /dev/null
+++ b/tests/xfs/1817.out
@@ -0,0 +1,2 @@
+QA output created by 1817
+Silence is golden
diff --git a/tests/xfs/1821 b/tests/xfs/1821
new file mode 100755
index 0000000000..7dbac04f52
--- /dev/null
+++ b/tests/xfs/1821
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1821
+#
+# Race fsstress and realtime bitmap repair for a while to see if we crash or
+# livelock.
+#
+. ./common/preamble
+_begin_fstest online_repair dangerous_fsstress_repair
+
+_cleanup() {
+ _scratch_xfs_stress_scrub_cleanup &> /dev/null
+ cd /
+ rm -r -f $tmp.*
+}
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/fuzzy
+. ./common/inject
+. ./common/xfs
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch
+_require_xfs_stress_online_repair
+
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount
+_require_xfs_has_feature "$SCRATCH_MNT" realtime
+_xfs_force_bdev realtime $SCRATCH_MNT
+
+_scratch_xfs_stress_online_repair -s "repair rtbitmap" -s "repair rgbitmap %rgno%"
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/xfs/1821.out b/tests/xfs/1821.out
new file mode 100644
index 0000000000..0f18ad5d88
--- /dev/null
+++ b/tests/xfs/1821.out
@@ -0,0 +1,2 @@
+QA output created by 1821
+Silence is golden
diff --git a/tests/xfs/1857 b/tests/xfs/1857
new file mode 100755
index 0000000000..de10bbb5c4
--- /dev/null
+++ b/tests/xfs/1857
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1857
+#
+# Race fsstress and rtrmapbt repair for a while to see if we crash or livelock.
+#
+. ./common/preamble
+_begin_fstest online_repair dangerous_fsstress_repair
+
+_cleanup() {
+ _scratch_xfs_stress_scrub_cleanup &> /dev/null
+ cd /
+ rm -r -f $tmp.*
+}
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/fuzzy
+. ./common/inject
+. ./common/xfs
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch
+_require_xfs_stress_online_repair
+
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount
+_require_xfs_has_feature "$SCRATCH_MNT" realtime
+_require_xfs_has_feature "$SCRATCH_MNT" rmapbt
+_xfs_force_bdev realtime $SCRATCH_MNT
+
+_scratch_xfs_stress_online_repair -s "repair rtrmapbt %rgno%"
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/xfs/1857.out b/tests/xfs/1857.out
new file mode 100644
index 0000000000..b51ffd3f6c
--- /dev/null
+++ b/tests/xfs/1857.out
@@ -0,0 +1,2 @@
+QA output created by 1857
+Silence is golden
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 04/13] xfs/856: add rtrmapbt upgrade to test matrix
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (2 preceding siblings ...)
2023-12-27 13:58 ` [PATCH 03/13] xfs: race fsstress with realtime rmap btree scrub and repair Darrick J. Wong
@ 2023-12-27 13:58 ` Darrick J. Wong
2023-12-27 13:59 ` [PATCH 05/13] xfs/122: update for rtgroups-based realtime rmap btrees Darrick J. Wong
` (8 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:58 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Add realtime reverse mapping btrees to the features that this test will
try to upgrade.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1856 | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/tests/xfs/1856 b/tests/xfs/1856
index 93bdbaa531..8453d9bff2 100755
--- a/tests/xfs/1856
+++ b/tests/xfs/1856
@@ -34,11 +34,46 @@ rt_configured()
test "$USE_EXTERNAL" = "yes" && test -n "$SCRATCH_RTDEV"
}
+# Does mkfs support rtgroups?
+supports_rtgroups()
+{
+ $MKFS_XFS_PROG 2>&1 | grep -q 'rtgroups='
+}
+
+# Do we need to enable rtgroups at mkfs time to support a feature upgrade test?
+need_rtgroups()
+{
+ local feat="$1"
+
+ # if realtime isn't configured, we don't need rt groups
+ rt_configured || return 1
+
+ # If we don't even know what realtime rmap is, we don't need rt groups
+ test -z "${FEATURE_STATE["rmapbt"]}" && return 1
+
+ # rt rmap btrees require rt groups but rt groups cannot be added to
+ # an existing filesystem, so we must force it on at mkfs time
+ test "${FEATURE_STATE["rmapbt"]}" -eq 1 && return 0
+ test "$feat" = "rmapbt" && return 0
+
+ return 1
+}
+
# Compute the MKFS_OPTIONS string for a particular feature upgrade test
compute_mkfs_options()
{
+ local feat="$1"
local m_opts=""
local caller_options="$MKFS_OPTIONS"
+ local rtgroups
+
+ need_rtgroups "$feat" && rtgroups=1
+ if echo "$caller_options" | grep -q 'rtgroups='; then
+ test -z "$rtgroups" && rtgroups=0
+ caller_options="$(echo "$caller_options" | sed -e 's/rtgroups=*[0-9]*/rtgroups='$rtgroups'/g')"
+ elif [ -n "$rtgroups" ]; then
+ caller_options="$caller_options -r rtgroups=$rtgroups"
+ fi
for feat in "${FEATURES[@]}"; do
local feat_state="${FEATURE_STATE["${feat}"]}"
@@ -170,10 +205,12 @@ post_exercise()
# upgrade don't spread failure to the rest of the tests.
FEATURES=()
if rt_configured; then
+ # rmap wasn't added to rt devices until after metadir and rtgroups
check_repair_upgrade finobt && FEATURES+=("finobt")
check_repair_upgrade inobtcount && FEATURES+=("inobtcount")
check_repair_upgrade bigtime && FEATURES+=("bigtime")
check_repair_upgrade metadir && FEATURES+=("metadir")
+ supports_rtgroups && check_repair_upgrade rmapbt && FEATURES+=("rmapbt")
else
check_repair_upgrade finobt && FEATURES+=("finobt")
check_repair_upgrade rmapbt && FEATURES+=("rmapbt")
@@ -196,7 +233,7 @@ for feat in "${FEATURES[@]}"; do
upgrade_start_message "$feat" | _tee_kernlog $seqres.full > /dev/null
- opts="$(compute_mkfs_options)"
+ opts="$(compute_mkfs_options "$feat")"
echo "mkfs.xfs $opts" >> $seqres.full
# Format filesystem
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 05/13] xfs/122: update for rtgroups-based realtime rmap btrees
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (3 preceding siblings ...)
2023-12-27 13:58 ` [PATCH 04/13] xfs/856: add rtrmapbt upgrade to test matrix Darrick J. Wong
@ 2023-12-27 13:59 ` Darrick J. Wong
2023-12-27 13:59 ` [PATCH 06/13] xfs: fix various problems with fsmap detecting the data device Darrick J. Wong
` (7 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:59 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Now that we've redesigned realtime rmap to require that the rt section
be sharded into allocation groups of no more than 2^31 blocks, we've
reduced the size of the ondisk structures and therefore need to update
this test.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/122.out | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/xfs/122.out b/tests/xfs/122.out
index 837286a9d3..f5621cac12 100644
--- a/tests/xfs/122.out
+++ b/tests/xfs/122.out
@@ -120,8 +120,8 @@ sizeof(struct xfs_rmap_key) = 20
sizeof(struct xfs_rmap_rec) = 24
sizeof(struct xfs_rtbuf_blkinfo) = 48
sizeof(struct xfs_rtgroup_geometry) = 128
-sizeof(struct xfs_rtrmap_key) = 24
-sizeof(struct xfs_rtrmap_rec) = 32
+sizeof(struct xfs_rtrmap_key) = 20
+sizeof(struct xfs_rtrmap_rec) = 24
sizeof(struct xfs_rtrmap_root) = 4
sizeof(struct xfs_rtsb) = 104
sizeof(struct xfs_rud_log_format) = 16
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 06/13] xfs: fix various problems with fsmap detecting the data device
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (4 preceding siblings ...)
2023-12-27 13:59 ` [PATCH 05/13] xfs/122: update for rtgroups-based realtime rmap btrees Darrick J. Wong
@ 2023-12-27 13:59 ` Darrick J. Wong
2023-12-27 13:59 ` [PATCH 07/13] xfs/341: update test for rtgroup-based rmap Darrick J. Wong
` (6 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:59 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Various tests of realtime rmap functionality assumed that the data
device could be picked out from the GETFSMAP output by looking for
static fs metadata. This is no longer true, since rtgroups have a
static superblock header at the start, so update these tests.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/272 | 2 +-
tests/xfs/276 | 2 +-
tests/xfs/277 | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/xfs/272 b/tests/xfs/272
index c68fa9d614..d5f3a74177 100755
--- a/tests/xfs/272
+++ b/tests/xfs/272
@@ -57,7 +57,7 @@ cat $TEST_DIR/bmap | while read ext offrange colon blockrange ag agrange total c
done
echo "Check device field of FS metadata and regular file"
-data_dev=$(grep 'static fs metadata' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
+data_dev=$(grep 'inode btree' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
rt_dev=$(grep "${ino}[[:space:]]*[0-9]*\.\.[0-9]*" $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
test "${data_dev}" = "${rt_dev}" || echo "data ${data_dev} realtime ${rt_dev}?"
diff --git a/tests/xfs/276 b/tests/xfs/276
index 8cc486752a..a05ca1961d 100755
--- a/tests/xfs/276
+++ b/tests/xfs/276
@@ -61,7 +61,7 @@ cat $TEST_DIR/bmap | while read ext offrange colon blockrange ag agrange total c
done
echo "Check device field of FS metadata and realtime file"
-data_dev=$(grep 'static fs metadata' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
+data_dev=$(grep 'inode btree' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
rt_dev=$(grep "${ino}[[:space:]]*[0-9]*\.\.[0-9]*[[:space:]]*[0-9]*$" $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
test "${data_dev}" != "${rt_dev}" || echo "data ${data_dev} realtime ${rt_dev}?"
diff --git a/tests/xfs/277 b/tests/xfs/277
index 03208ef233..eff54a2a50 100755
--- a/tests/xfs/277
+++ b/tests/xfs/277
@@ -38,7 +38,7 @@ $XFS_IO_PROG -c 'fsmap -v' $SCRATCH_MNT >> $seqres.full
$XFS_IO_PROG -c 'fsmap -v' $SCRATCH_MNT | tr '[]()' ' ' > $TEST_DIR/fsmap
echo "Check device field of FS metadata and journalling log"
-data_dev=$(grep 'static fs metadata' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
+data_dev=$(grep 'inode btree' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
journal_dev=$(grep 'journalling log' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
test "${data_dev}" = "${journal_dev}" || echo "data ${data_dev} journal ${journal_dev}?"
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 07/13] xfs/341: update test for rtgroup-based rmap
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (5 preceding siblings ...)
2023-12-27 13:59 ` [PATCH 06/13] xfs: fix various problems with fsmap detecting the data device Darrick J. Wong
@ 2023-12-27 13:59 ` Darrick J. Wong
2023-12-27 13:59 ` [PATCH 08/13] xfs/3{43,32}: adapt tests for rt extent size greater than 1 Darrick J. Wong
` (5 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:59 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Now that we're sharding the realtime volume into multiple allocation
groups, update this test to reflect the new reality. The realtime rmap
btree record and key sizes have shrunk, and we can't guarantee that a
quick file write actually hits the same rt group as the one we fuzzed,
so eliminate the file write test since we're really only curious if
xfs_repair will fix the problem.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/341 | 10 +++-------
tests/xfs/341.out | 1 -
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/tests/xfs/341 b/tests/xfs/341
index 8861e751a9..561054f0bd 100755
--- a/tests/xfs/341
+++ b/tests/xfs/341
@@ -32,10 +32,10 @@ blksz="$(_get_block_size $SCRATCH_MNT)"
rtextsz_blks=$((rtextsz / blksz))
# inode core size is at least 176 bytes; btree header is 56 bytes;
-# rtrmap record is 32 bytes; and rtrmap key/pointer are 56 bytes.
+# rtrmap record is 24 bytes; and rtrmap key/pointer are 48 bytes.
i_core_size="$(_xfs_get_inode_core_bytes $SCRATCH_MNT)"
-i_ptrs=$(( (isize - i_core_size) / 56 ))
-bt_recs=$(( (blksz - 56) / 32 ))
+i_ptrs=$(( (isize - i_core_size) / 48 ))
+bt_recs=$(( (blksz - 56) / 24 ))
blocks=$((i_ptrs * bt_recs + 1))
len=$((blocks * rtextsz))
@@ -57,10 +57,6 @@ _scratch_xfs_db -x -c 'path -m /realtime/0.rmap' \
-c "write u3.rtrmapbt.ptrs[1] $fsbno" -c 'p' >> $seqres.full
_scratch_mount
-echo "Try to create more files"
-$XFS_IO_PROG -f -R -c "pwrite -S 0x68 0 9999" $SCRATCH_MNT/f5 >> $seqres.full 2>&1
-test -e $SCRATCH_MNT/f5 && echo "should not have been able to write f5"
-
echo "Repair fs"
_scratch_unmount 2>&1 | _filter_scratch
_repair_scratch_fs >> $seqres.full 2>&1
diff --git a/tests/xfs/341.out b/tests/xfs/341.out
index 75a5bc6c61..580d788954 100644
--- a/tests/xfs/341.out
+++ b/tests/xfs/341.out
@@ -2,6 +2,5 @@ QA output created by 341
Format and mount
Create some files
Corrupt fs
-Try to create more files
Repair fs
Try to create more files (again)
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 08/13] xfs/3{43,32}: adapt tests for rt extent size greater than 1
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (6 preceding siblings ...)
2023-12-27 13:59 ` [PATCH 07/13] xfs/341: update test for rtgroup-based rmap Darrick J. Wong
@ 2023-12-27 13:59 ` Darrick J. Wong
2023-12-27 14:00 ` [PATCH 09/13] xfs: skip tests if formatting small filesystem fails Darrick J. Wong
` (4 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 13:59 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Both of these tests for the realtime volume can fail when the rt extent
size is larger than a single block.
332 is a read-write functionality test that encodes md5sum in the
output, so we need to skip it if $blksz isn't congruent with the extent
size, because the fcollapse call will fail.
343 is a test of the rmap btree, so the fix here is simpler -- make
$blksz the file allocation unit, and get rid of the md5sum in the
golden output.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/332 | 6 +-----
tests/xfs/332.out | 2 --
tests/xfs/343 | 2 ++
3 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/tests/xfs/332 b/tests/xfs/332
index a2d37ee905..c1ac87adcb 100755
--- a/tests/xfs/332
+++ b/tests/xfs/332
@@ -28,7 +28,7 @@ rm -f "$seqres.full"
echo "Format and mount"
_scratch_mkfs > "$seqres.full" 2>&1
_scratch_mount
-blksz=65536
+blksz=$(_get_file_block_size $SCRATCH_MNT) # 65536
blocks=16
len=$((blocks * blksz))
@@ -45,10 +45,6 @@ $XFS_IO_PROG -c "fpunch $blksz $blksz" \
-c "fcollapse $((9 * blksz)) $blksz" \
-c "finsert $((10 * blksz)) $blksz" $SCRATCH_MNT/f1 >> $seqres.full
-echo "Check file"
-md5sum $SCRATCH_MNT/f1 | _filter_scratch
-od -tx1 -Ad -c $SCRATCH_MNT/f1 >> $seqres.full
-
echo "Unmount"
_scratch_unmount
diff --git a/tests/xfs/332.out b/tests/xfs/332.out
index 9beff7cc37..3a7ca95b40 100644
--- a/tests/xfs/332.out
+++ b/tests/xfs/332.out
@@ -2,8 +2,6 @@ QA output created by 332
Format and mount
Create some files
Manipulate file
-Check file
-e45c5707fcf6817e914ffb6ce37a0ac7 SCRATCH_MNT/f1
Unmount
Try a regular fsmap
Try a bad fsmap
diff --git a/tests/xfs/343 b/tests/xfs/343
index bffcc7d9ac..fe461847ed 100755
--- a/tests/xfs/343
+++ b/tests/xfs/343
@@ -31,6 +31,8 @@ blksz=65536
blocks=16
len=$((blocks * blksz))
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
+
echo "Create some files"
$XFS_IO_PROG -f -R -c "falloc 0 $len" -c "pwrite -S 0x68 -b 1048576 0 $len" $SCRATCH_MNT/f1 >> $seqres.full
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 09/13] xfs: skip tests if formatting small filesystem fails
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (7 preceding siblings ...)
2023-12-27 13:59 ` [PATCH 08/13] xfs/3{43,32}: adapt tests for rt extent size greater than 1 Darrick J. Wong
@ 2023-12-27 14:00 ` Darrick J. Wong
2023-12-27 14:00 ` [PATCH 10/13] xfs/443: use file allocation unit, not dbsize Darrick J. Wong
` (3 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:00 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
There are a few tests that try to exercise XFS functionality with an
unusually small (< 500MB) filesystem. Formatting can fail if the test
configuration also specifies a very large realtime device because mkfs
hits ENOSPC when allocating the realtime metadata. The test proceeds
anyway (which causes an immediate mount failure) so we might as well
skip these.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/104 | 1 +
tests/xfs/291 | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/xfs/104 b/tests/xfs/104
index d16f46d8e4..c3d1d18a58 100755
--- a/tests/xfs/104
+++ b/tests/xfs/104
@@ -16,6 +16,7 @@ _create_scratch()
{
echo "*** mkfs"
_scratch_mkfs_xfs $@ | tee -a $seqres.full | _filter_mkfs 2>$tmp.mkfs
+ test "${PIPESTATUS[0]}" -eq 0 || _notrun "formatting small scratch fs failed"
. $tmp.mkfs
echo "*** mount"
diff --git a/tests/xfs/291 b/tests/xfs/291
index 600dcb2eba..70e5f51cee 100755
--- a/tests/xfs/291
+++ b/tests/xfs/291
@@ -18,7 +18,8 @@ _require_command "$XFS_MDRESTORE_PROG" "xfs_mdrestore"
# real QA test starts here
_require_scratch
logblks=$(_scratch_find_xfs_min_logblocks -n size=16k -d size=133m)
-_scratch_mkfs_xfs -n size=16k -l size=${logblks}b -d size=133m >> $seqres.full 2>&1
+_scratch_mkfs_xfs -n size=16k -l size=${logblks}b -d size=133m >> $seqres.full 2>&1 || \
+ _notrun "formatting small scratch fs failed"
_scratch_mount
# First we cause very badly fragmented freespace, then
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 10/13] xfs/443: use file allocation unit, not dbsize
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (8 preceding siblings ...)
2023-12-27 14:00 ` [PATCH 09/13] xfs: skip tests if formatting small filesystem fails Darrick J. Wong
@ 2023-12-27 14:00 ` Darrick J. Wong
2023-12-27 14:00 ` [PATCH 11/13] populate: adjust rtrmap calculations for rtgroups Darrick J. Wong
` (2 subsequent siblings)
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:00 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
We can only punch in units of file allocation boundaries, so update this
test to use that instead of the fs blocksize.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/443 | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/tests/xfs/443 b/tests/xfs/443
index 56828decae..ab3cda59f3 100755
--- a/tests/xfs/443
+++ b/tests/xfs/443
@@ -40,14 +40,15 @@ _scratch_mount
file1=$SCRATCH_MNT/file1
file2=$SCRATCH_MNT/file2
+file_blksz=$(_get_file_block_size $SCRATCH_MNT)
# The goal is run an extent swap where one of the associated files has the
# minimum number of extents to remain in btree format. First, create a couple
# files with large enough extent counts (200 or so should be plenty) to ensure
# btree format on the largest possible inode size filesystems.
-$XFS_IO_PROG -fc "falloc 0 $((400 * dbsize))" $file1
+$XFS_IO_PROG -fc "falloc 0 $((400 * file_blksz))" $file1
$here/src/punch-alternating $file1
-$XFS_IO_PROG -fc "falloc 0 $((400 * dbsize))" $file2
+$XFS_IO_PROG -fc "falloc 0 $((400 * file_blksz))" $file2
$here/src/punch-alternating $file2
# Now run an extent swap at every possible extent count down to 0. Depending on
@@ -55,12 +56,12 @@ $here/src/punch-alternating $file2
# btree format.
for i in $(seq 1 2 399); do
# punch one extent from the tmpfile and swap
- $XFS_IO_PROG -c "fpunch $((i * dbsize)) $dbsize" $file2
+ $XFS_IO_PROG -c "fpunch $((i * file_blksz)) $file_blksz" $file2
$XFS_IO_PROG -c "swapext $file2" $file1
# punch the same extent from the old fork (now in file2) to resync the
# extent counts and repeat
- $XFS_IO_PROG -c "fpunch $((i * dbsize)) $dbsize" $file2
+ $XFS_IO_PROG -c "fpunch $((i * file_blksz)) $file_blksz" $file2
done
# sanity check that no extents are left over
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 11/13] populate: adjust rtrmap calculations for rtgroups
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (9 preceding siblings ...)
2023-12-27 14:00 ` [PATCH 10/13] xfs/443: use file allocation unit, not dbsize Darrick J. Wong
@ 2023-12-27 14:00 ` Darrick J. Wong
2023-12-27 14:00 ` [PATCH 12/13] populate: check that we created a realtime rmap btree of the given height Darrick J. Wong
2023-12-27 14:01 ` [PATCH 13/13] fuzzy: create missing fuzz tests for rt rmap btrees Darrick J. Wong
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:00 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Now that we've sharded the realtime volume and created per-group rmap
btrees, we need to adjust downward the size of rtrmapbt records since
the block counts are now 32-bit instead of 64-bit.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/populate | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/populate b/common/populate
index dc89eee70e..d8d19bf782 100644
--- a/common/populate
+++ b/common/populate
@@ -450,7 +450,7 @@ _scratch_xfs_populate() {
is_rt="$(_xfs_get_rtextents "$SCRATCH_MNT")"
if [ $is_rmapbt -gt 0 ] && [ $is_rt -gt 0 ]; then
echo "+ rtrmapbt btree"
- nr="$((blksz * 2 / 32))"
+ nr="$((blksz * 2 / 24))"
$XFS_IO_PROG -R -f -c 'truncate 0' "${SCRATCH_MNT}/RTRMAPBT"
__populate_create_file $((blksz * nr)) "${SCRATCH_MNT}/RTRMAPBT"
fi
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 12/13] populate: check that we created a realtime rmap btree of the given height
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (10 preceding siblings ...)
2023-12-27 14:00 ` [PATCH 11/13] populate: adjust rtrmap calculations for rtgroups Darrick J. Wong
@ 2023-12-27 14:00 ` Darrick J. Wong
2023-12-27 14:01 ` [PATCH 13/13] fuzzy: create missing fuzz tests for rt rmap btrees Darrick J. Wong
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:00 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Make sure that we actually create an rt rmap btree of the desired height
somewhere in the filesystem.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/populate | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/common/populate b/common/populate
index d8d19bf782..84ff9304e3 100644
--- a/common/populate
+++ b/common/populate
@@ -740,6 +740,37 @@ __populate_check_xfs_agbtree_height() {
return 1
}
+# Check that there's at least one rt btree with multiple levels
+__populate_check_xfs_rgbtree_height() {
+ local bt_type="$1"
+ local rgcount=$(_scratch_xfs_db -c 'sb 0' -c 'p rgcount' | awk '{print $3}')
+ local path
+ local path_format
+ local bt_prefix
+
+ case "${bt_type}" in
+ "rmap")
+ path_format="/realtime/%u.rmap"
+ bt_prefix="u3.rtrmapbt"
+ ;;
+ *)
+ _fail "Don't know about rt btree ${bt_type}"
+ ;;
+ esac
+
+ for ((rgno = 0; rgno < rgcount; rgno++)); do
+ path="$(printf "${path_format}" "${rgno}")"
+ bt_level=$(_scratch_xfs_db -c "path -m ${path}" -c "p ${bt_prefix}.level" | awk '{print $3}')
+ # "level" is the actual level within the btree
+ if [ "${bt_level}" -gt 0 ]; then
+ return 0
+ fi
+ done
+
+ __populate_fail "Failed to create rt ${bt_type} of sufficient height!"
+ return 1
+}
+
# Check that populate created all the types of files we wanted
_scratch_xfs_populate_check() {
_scratch_mount
@@ -763,6 +794,7 @@ _scratch_xfs_populate_check() {
is_finobt=$(_xfs_has_feature "$SCRATCH_MNT" finobt -v)
is_rmapbt=$(_xfs_has_feature "$SCRATCH_MNT" rmapbt -v)
is_reflink=$(_xfs_has_feature "$SCRATCH_MNT" reflink -v)
+ is_rt="$(_xfs_get_rtextents "$SCRATCH_MNT")"
blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")"
dblksz="$(_xfs_get_dir_blocksize "$SCRATCH_MNT")"
@@ -793,6 +825,8 @@ _scratch_xfs_populate_check() {
test $is_finobt -ne 0 && __populate_check_xfs_agbtree_height "fino"
test $is_rmapbt -ne 0 && __populate_check_xfs_agbtree_height "rmap"
test $is_reflink -ne 0 && __populate_check_xfs_agbtree_height "refcnt"
+ test $is_rmapbt -ne 0 && test $is_rt -gt 0 && \
+ __populate_check_xfs_rgbtree_height "rmap"
}
# Check data fork format of ext4 file
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 13/13] fuzzy: create missing fuzz tests for rt rmap btrees
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (11 preceding siblings ...)
2023-12-27 14:00 ` [PATCH 12/13] populate: check that we created a realtime rmap btree of the given height Darrick J. Wong
@ 2023-12-27 14:01 ` Darrick J. Wong
12 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:01 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Back when I first created the fuzz tests for the realtime rmap btree, I
forgot a couple of things. Add tests to fuzz rtrmap btree leaf records,
and node keys.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1528 | 41 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/1528.out | 4 ++++
tests/xfs/1529 | 40 ++++++++++++++++++++++++++++++++++++++++
tests/xfs/1529.out | 4 ++++
tests/xfs/407 | 2 +-
5 files changed, 90 insertions(+), 1 deletion(-)
create mode 100755 tests/xfs/1528
create mode 100644 tests/xfs/1528.out
create mode 100755 tests/xfs/1529
create mode 100644 tests/xfs/1529.out
diff --git a/tests/xfs/1528 b/tests/xfs/1528
new file mode 100755
index 0000000000..24cbb55c23
--- /dev/null
+++ b/tests/xfs/1528
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1528
+#
+# Populate a XFS filesystem and fuzz every rtrmapbt record field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_xfs_scratch_rmapbt
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 2)" || \
+ _fail "could not find two-level rtrmapbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
+
+echo "Fuzz rtrmapbt recs"
+_scratch_xfs_fuzz_metadata '' 'both' "path -m $path" "addr u${inode_ver}.rtrmapbt.ptrs[1]" >> $seqres.full
+echo "Done fuzzing rtrmapbt recs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1528.out b/tests/xfs/1528.out
new file mode 100644
index 0000000000..b51b640c40
--- /dev/null
+++ b/tests/xfs/1528.out
@@ -0,0 +1,4 @@
+QA output created by 1528
+Format and populate
+Fuzz rtrmapbt recs
+Done fuzzing rtrmapbt recs
diff --git a/tests/xfs/1529 b/tests/xfs/1529
new file mode 100755
index 0000000000..3930edad47
--- /dev/null
+++ b/tests/xfs/1529
@@ -0,0 +1,40 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1529
+#
+# Populate a XFS filesystem and fuzz every rtrmapbt keyptr field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_xfs_scratch_rmapbt
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 2)" || \
+ _fail "could not find two-level rtrmapbt"
+
+echo "Fuzz rtrmapbt keyptrs"
+_scratch_xfs_fuzz_metadata '(rtrmapbt)' 'offline' "path -m $path" >> $seqres.full
+echo "Done fuzzing rtrmapbt keyptrs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1529.out b/tests/xfs/1529.out
new file mode 100644
index 0000000000..808fcc957f
--- /dev/null
+++ b/tests/xfs/1529.out
@@ -0,0 +1,4 @@
+QA output created by 1529
+Format and populate
+Fuzz rtrmapbt keyptrs
+Done fuzzing rtrmapbt keyptrs
diff --git a/tests/xfs/407 b/tests/xfs/407
index 2460ea336c..bd439105e2 100755
--- a/tests/xfs/407
+++ b/tests/xfs/407
@@ -26,7 +26,7 @@ _require_scratch_xfs_fuzz_fields
echo "Format and populate"
_scratch_populate_cached nofill > $seqres.full 2>&1
-path="$(_scratch_xfs_find_rgbtree_height 'rmap' 1)" || \
+path="$(_scratch_xfs_find_rgbtree_height 'rmap' 2)" || \
_fail "could not find two-level rtrmapbt"
inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 1/1] fuzzy: create known output for rt rmap btree fuzz tests
2023-12-31 20:01 ` [PATCHSET v2.0 5/9] fstests: establish baseline for realtime rmap fuzz tests Darrick J. Wong
@ 2023-12-27 14:01 ` Darrick J. Wong
0 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:01 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1528.out | 22 ++++++++
tests/xfs/1529.out | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/406.out | 22 ++++++++
tests/xfs/408.out | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/409.out | 15 ++++++
tests/xfs/481.out | 22 ++++++++
tests/xfs/482.out | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 495 insertions(+)
diff --git a/tests/xfs/1528.out b/tests/xfs/1528.out
index b51b640c40..efa31b604e 100644
--- a/tests/xfs/1528.out
+++ b/tests/xfs/1528.out
@@ -1,4 +1,26 @@
QA output created by 1528
Format and populate
Fuzz rtrmapbt recs
+leftsib = add: offline scrub didn't fail.
+rightsib = ones: offline scrub didn't fail.
+rightsib = firstbit: offline scrub didn't fail.
+rightsib = lastbit: offline scrub didn't fail.
+rightsib = add: offline scrub didn't fail.
+recs[2].blockcount = middlebit: offline scrub didn't fail.
+recs[2].blockcount = lastbit: offline scrub didn't fail.
+recs[2].blockcount = add: offline scrub didn't fail.
+recs[3].blockcount = middlebit: offline scrub didn't fail.
+recs[3].blockcount = add: offline scrub didn't fail.
+recs[4].blockcount = middlebit: offline scrub didn't fail.
+recs[4].blockcount = add: offline scrub didn't fail.
+recs[5].blockcount = middlebit: offline scrub didn't fail.
+recs[5].blockcount = add: offline scrub didn't fail.
+recs[6].blockcount = middlebit: offline scrub didn't fail.
+recs[6].blockcount = add: offline scrub didn't fail.
+recs[7].blockcount = middlebit: offline scrub didn't fail.
+recs[7].blockcount = add: offline scrub didn't fail.
+recs[8].blockcount = middlebit: offline scrub didn't fail.
+recs[8].blockcount = add: offline scrub didn't fail.
+recs[9].blockcount = middlebit: offline scrub didn't fail.
+recs[9].blockcount = add: offline scrub didn't fail.
Done fuzzing rtrmapbt recs
diff --git a/tests/xfs/1529.out b/tests/xfs/1529.out
index 808fcc957f..0810094a43 100644
--- a/tests/xfs/1529.out
+++ b/tests/xfs/1529.out
@@ -1,4 +1,142 @@
QA output created by 1529
Format and populate
Fuzz rtrmapbt keyptrs
+u3.rtrmapbt.keys[1].startblock = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[1] = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[2] = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[3] = firstbit: offline scrub didn't fail.
Done fuzzing rtrmapbt keyptrs
diff --git a/tests/xfs/406.out b/tests/xfs/406.out
index 6615533e6c..e95ac52fed 100644
--- a/tests/xfs/406.out
+++ b/tests/xfs/406.out
@@ -1,4 +1,26 @@
QA output created by 406
Format and populate
Fuzz rtrmapbt recs
+leftsib = add: offline scrub didn't fail.
+rightsib = ones: offline scrub didn't fail.
+rightsib = firstbit: offline scrub didn't fail.
+rightsib = lastbit: offline scrub didn't fail.
+rightsib = add: offline scrub didn't fail.
+recs[2].blockcount = middlebit: offline scrub didn't fail.
+recs[2].blockcount = lastbit: offline scrub didn't fail.
+recs[2].blockcount = add: offline scrub didn't fail.
+recs[3].blockcount = middlebit: offline scrub didn't fail.
+recs[3].blockcount = add: offline scrub didn't fail.
+recs[4].blockcount = middlebit: offline scrub didn't fail.
+recs[4].blockcount = add: offline scrub didn't fail.
+recs[5].blockcount = middlebit: offline scrub didn't fail.
+recs[5].blockcount = add: offline scrub didn't fail.
+recs[6].blockcount = middlebit: offline scrub didn't fail.
+recs[6].blockcount = add: offline scrub didn't fail.
+recs[7].blockcount = middlebit: offline scrub didn't fail.
+recs[7].blockcount = add: offline scrub didn't fail.
+recs[8].blockcount = middlebit: offline scrub didn't fail.
+recs[8].blockcount = add: offline scrub didn't fail.
+recs[9].blockcount = middlebit: offline scrub didn't fail.
+recs[9].blockcount = add: offline scrub didn't fail.
Done fuzzing rtrmapbt recs
diff --git a/tests/xfs/408.out b/tests/xfs/408.out
index c01b2e26ae..5626c59560 100644
--- a/tests/xfs/408.out
+++ b/tests/xfs/408.out
@@ -1,4 +1,142 @@
QA output created by 408
Format and populate
Fuzz rtrmapbt keyptrs
+u3.rtrmapbt.keys[1].startblock = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[1] = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[2] = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[3] = firstbit: offline scrub didn't fail.
Done fuzzing rtrmapbt keyptrs
diff --git a/tests/xfs/409.out b/tests/xfs/409.out
index 690ac99b10..3d0a67afa8 100644
--- a/tests/xfs/409.out
+++ b/tests/xfs/409.out
@@ -1,4 +1,19 @@
QA output created by 409
Format and populate
Fuzz rtrmapbt keyptrs
+u3.rtrmapbt.level = ones: mount failed (32).
+u3.rtrmapbt.level = firstbit: mount failed (32).
+u3.rtrmapbt.level = middlebit: mount failed (32).
+u3.rtrmapbt.level = add: mount failed (32).
+u3.rtrmapbt.level = sub: mount failed (32).
+u3.rtrmapbt.numrecs = zeroes: online repair failed (1).
+u3.rtrmapbt.numrecs = zeroes: online re-scrub failed (5).
+u3.rtrmapbt.numrecs = zeroes: offline re-scrub failed (1).
+u3.rtrmapbt.numrecs = zeroes: online post-mod scrub failed (4).
+u3.rtrmapbt.numrecs = zeroes: offline post-mod scrub failed (1).
+u3.rtrmapbt.numrecs = ones: mount failed (32).
+u3.rtrmapbt.numrecs = firstbit: mount failed (32).
+u3.rtrmapbt.numrecs = middlebit: mount failed (32).
+u3.rtrmapbt.numrecs = add: mount failed (32).
+u3.rtrmapbt.numrecs = sub: mount failed (32).
Done fuzzing rtrmapbt keyptrs
diff --git a/tests/xfs/481.out b/tests/xfs/481.out
index d570dc8f21..1e080de148 100644
--- a/tests/xfs/481.out
+++ b/tests/xfs/481.out
@@ -1,4 +1,26 @@
QA output created by 481
Format and populate
Fuzz rtrmapbt recs
+leftsib = add: offline scrub didn't fail.
+rightsib = ones: offline scrub didn't fail.
+rightsib = firstbit: offline scrub didn't fail.
+rightsib = lastbit: offline scrub didn't fail.
+rightsib = add: offline scrub didn't fail.
+recs[2].blockcount = middlebit: offline scrub didn't fail.
+recs[2].blockcount = lastbit: offline scrub didn't fail.
+recs[2].blockcount = add: offline scrub didn't fail.
+recs[3].blockcount = middlebit: offline scrub didn't fail.
+recs[3].blockcount = add: offline scrub didn't fail.
+recs[4].blockcount = middlebit: offline scrub didn't fail.
+recs[4].blockcount = add: offline scrub didn't fail.
+recs[5].blockcount = middlebit: offline scrub didn't fail.
+recs[5].blockcount = add: offline scrub didn't fail.
+recs[6].blockcount = middlebit: offline scrub didn't fail.
+recs[6].blockcount = add: offline scrub didn't fail.
+recs[7].blockcount = middlebit: offline scrub didn't fail.
+recs[7].blockcount = add: offline scrub didn't fail.
+recs[8].blockcount = middlebit: offline scrub didn't fail.
+recs[8].blockcount = add: offline scrub didn't fail.
+recs[9].blockcount = middlebit: offline scrub didn't fail.
+recs[9].blockcount = add: offline scrub didn't fail.
Done fuzzing rtrmapbt recs
diff --git a/tests/xfs/482.out b/tests/xfs/482.out
index 6bdf7a9fc1..c945b7aaf8 100644
--- a/tests/xfs/482.out
+++ b/tests/xfs/482.out
@@ -1,4 +1,142 @@
QA output created by 482
Format and populate
Fuzz rtrmapbt keyptrs
+u3.rtrmapbt.keys[1].startblock = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[1].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[2].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].startblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].owner_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = zeroes: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].offset_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].attrfork_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = ones: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = middlebit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = lastbit: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = add: offline scrub didn't fail.
+u3.rtrmapbt.keys[3].bmbtblock_hi = sub: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[1] = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[2] = firstbit: offline scrub didn't fail.
+u3.rtrmapbt.ptrs[3] = firstbit: offline scrub didn't fail.
Done fuzzing rtrmapbt keyptrs
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 1/9] xfs/122: update fields for realtime reflink
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
@ 2023-12-27 14:01 ` Darrick J. Wong
2023-12-27 14:01 ` [PATCH 2/9] common/populate: create realtime refcount btree Darrick J. Wong
` (7 subsequent siblings)
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:01 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Add a few more ondisk structures for realtime reflink.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/122.out | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/xfs/122.out b/tests/xfs/122.out
index f5621cac12..9c2d2fffb4 100644
--- a/tests/xfs/122.out
+++ b/tests/xfs/122.out
@@ -120,6 +120,9 @@ sizeof(struct xfs_rmap_key) = 20
sizeof(struct xfs_rmap_rec) = 24
sizeof(struct xfs_rtbuf_blkinfo) = 48
sizeof(struct xfs_rtgroup_geometry) = 128
+sizeof(struct xfs_rtrefcount_key) = 4
+sizeof(struct xfs_rtrefcount_rec) = 12
+sizeof(struct xfs_rtrefcount_root) = 4
sizeof(struct xfs_rtrmap_key) = 20
sizeof(struct xfs_rtrmap_rec) = 24
sizeof(struct xfs_rtrmap_root) = 4
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 2/9] common/populate: create realtime refcount btree
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
2023-12-27 14:01 ` [PATCH 1/9] xfs/122: update fields for realtime reflink Darrick J. Wong
@ 2023-12-27 14:01 ` Darrick J. Wong
2023-12-27 14:02 ` [PATCH 3/9] xfs: create fuzz tests for the " Darrick J. Wong
` (6 subsequent siblings)
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:01 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Populate a realtime refcount btree when we're creating a sample fs.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/populate | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/common/populate b/common/populate
index 84ff9304e3..1e51eedddc 100644
--- a/common/populate
+++ b/common/populate
@@ -438,16 +438,30 @@ _scratch_xfs_populate() {
local dir="${SCRATCH_MNT}/INOBT"
__populate_create_dir "${dir}" "${nr}" true --file-pct 100
- # Reverse-mapping btree
+ is_rt="$(_xfs_get_rtextents "$SCRATCH_MNT")"
is_rmapbt="$(_xfs_has_feature "$SCRATCH_MNT" rmapbt -v)"
+ is_reflink="$(_xfs_has_feature "$SCRATCH_MNT" reflink -v)"
+
+ # Reverse-mapping btree
if [ $is_rmapbt -gt 0 ]; then
echo "+ rmapbt btree"
nr="$((blksz * 2 / 24))"
__populate_create_file $((blksz * nr)) "${SCRATCH_MNT}/RMAPBT"
fi
+ # Realtime Reference-count btree comes before the rtrmapbt so that
+ # the refcount entries are created in rtgroup 0.
+ if [ $is_reflink -gt 0 ] && [ $is_rt -gt 0 ]; then
+ echo "+ rtreflink btree"
+ rt_blksz=$(_xfs_get_rtextsize "$SCRATCH_MNT")
+ nr="$((rt_blksz * 2 / 12))"
+ $XFS_IO_PROG -R -f -c 'truncate 0' "${SCRATCH_MNT}/RTREFCOUNTBT"
+ __populate_create_file $((blksz * nr)) "${SCRATCH_MNT}/RTREFCOUNTBT"
+ $XFS_IO_PROG -R -f -c 'truncate 0' "${SCRATCH_MNT}/RTREFCOUNTBT2"
+ cp --reflink=always "${SCRATCH_MNT}/RTREFCOUNTBT" "${SCRATCH_MNT}/RTREFCOUNTBT2"
+ fi
+
# Realtime Reverse-mapping btree
- is_rt="$(_xfs_get_rtextents "$SCRATCH_MNT")"
if [ $is_rmapbt -gt 0 ] && [ $is_rt -gt 0 ]; then
echo "+ rtrmapbt btree"
nr="$((blksz * 2 / 24))"
@@ -456,7 +470,6 @@ _scratch_xfs_populate() {
fi
# Reference-count btree
- is_reflink="$(_xfs_has_feature "$SCRATCH_MNT" reflink -v)"
if [ $is_reflink -gt 0 ]; then
echo "+ reflink btree"
nr="$((blksz * 2 / 12))"
@@ -512,6 +525,7 @@ _scratch_xfs_populate() {
__populate_fragment_file "${SCRATCH_MNT}/RMAPBT"
__populate_fragment_file "${SCRATCH_MNT}/RTRMAPBT"
__populate_fragment_file "${SCRATCH_MNT}/REFCOUNTBT"
+ __populate_fragment_file "${SCRATCH_MNT}/RTREFCOUNTBT"
umount "${SCRATCH_MNT}"
}
@@ -753,6 +767,10 @@ __populate_check_xfs_rgbtree_height() {
path_format="/realtime/%u.rmap"
bt_prefix="u3.rtrmapbt"
;;
+ "refcnt")
+ path_format="/realtime/%u.refcount"
+ bt_prefix="u3.rtrefcbt"
+ ;;
*)
_fail "Don't know about rt btree ${bt_type}"
;;
@@ -827,6 +845,8 @@ _scratch_xfs_populate_check() {
test $is_reflink -ne 0 && __populate_check_xfs_agbtree_height "refcnt"
test $is_rmapbt -ne 0 && test $is_rt -gt 0 && \
__populate_check_xfs_rgbtree_height "rmap"
+ test $is_reflink -ne 0 && test $is_rt -gt 0 && \
+ __populate_check_xfs_rgbtree_height "refcnt"
}
# Check data fork format of ext4 file
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 3/9] xfs: create fuzz tests for the realtime refcount btree
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
2023-12-27 14:01 ` [PATCH 1/9] xfs/122: update fields for realtime reflink Darrick J. Wong
2023-12-27 14:01 ` [PATCH 2/9] common/populate: create realtime refcount btree Darrick J. Wong
@ 2023-12-27 14:02 ` Darrick J. Wong
2023-12-27 14:02 ` [PATCH 4/9] xfs/27[24]: adapt for checking files on the realtime volume Darrick J. Wong
` (5 subsequent siblings)
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:02 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Create fuzz tests for the realtime refcount btree record and key/ptr
blocks.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 4 ++++
tests/xfs/1538 | 41 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/1538.out | 4 ++++
tests/xfs/1539 | 41 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/1539.out | 4 ++++
tests/xfs/1540 | 41 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/1540.out | 4 ++++
tests/xfs/1541 | 42 ++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1541.out | 4 ++++
tests/xfs/1542 | 41 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/1542.out | 4 ++++
tests/xfs/1543 | 40 ++++++++++++++++++++++++++++++++++++++++
tests/xfs/1543.out | 4 ++++
tests/xfs/1544 | 40 ++++++++++++++++++++++++++++++++++++++++
tests/xfs/1544.out | 4 ++++
tests/xfs/1545 | 41 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/1545.out | 4 ++++
17 files changed, 363 insertions(+)
create mode 100755 tests/xfs/1538
create mode 100644 tests/xfs/1538.out
create mode 100755 tests/xfs/1539
create mode 100644 tests/xfs/1539.out
create mode 100755 tests/xfs/1540
create mode 100644 tests/xfs/1540.out
create mode 100755 tests/xfs/1541
create mode 100644 tests/xfs/1541.out
create mode 100755 tests/xfs/1542
create mode 100644 tests/xfs/1542.out
create mode 100755 tests/xfs/1543
create mode 100644 tests/xfs/1543.out
create mode 100755 tests/xfs/1544
create mode 100644 tests/xfs/1544.out
create mode 100755 tests/xfs/1545
create mode 100644 tests/xfs/1545.out
diff --git a/common/xfs b/common/xfs
index b8dd8d4a40..aab04bfb18 100644
--- a/common/xfs
+++ b/common/xfs
@@ -1929,6 +1929,10 @@ _scratch_xfs_find_rgbtree_height() {
path_format="/realtime/%u.rmap"
bt_prefix="u3.rtrmapbt"
;;
+ "refcnt")
+ path_format="/realtime/%u.refcount"
+ bt_prefix="u3.rtrefcbt"
+ ;;
*)
_fail "Don't know about rt btree ${bt_type}"
;;
diff --git a/tests/xfs/1538 b/tests/xfs/1538
new file mode 100755
index 0000000000..2bd630fdf1
--- /dev/null
+++ b/tests/xfs/1538
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1538
+#
+# Populate a XFS filesystem and fuzz every rtrefcountbt record field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'refcnt' 2)" || \
+ _fail "could not find two-level rtrefcountbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
+
+echo "Fuzz rtrefcountbt recs"
+_scratch_xfs_fuzz_metadata '' 'online' "path -m $path" "addr u${inode_ver}.rtrefcbt.ptrs[1]" >> $seqres.full
+echo "Done fuzzing rtrefcountbt recs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1538.out b/tests/xfs/1538.out
new file mode 100644
index 0000000000..968cfd6ef9
--- /dev/null
+++ b/tests/xfs/1538.out
@@ -0,0 +1,4 @@
+QA output created by 1538
+Format and populate
+Fuzz rtrefcountbt recs
+Done fuzzing rtrefcountbt recs
diff --git a/tests/xfs/1539 b/tests/xfs/1539
new file mode 100755
index 0000000000..8086943211
--- /dev/null
+++ b/tests/xfs/1539
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1539
+#
+# Populate a XFS filesystem and fuzz every rtrefcountbt record field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'refcnt' 2)" || \
+ _fail "could not find two-level rtrefcountbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
+
+echo "Fuzz rtrefcountbt recs"
+_scratch_xfs_fuzz_metadata '' 'offline' "path -m $path" "addr u${inode_ver}.rtrefcbt.ptrs[1]" >> $seqres.full
+echo "Done fuzzing rtrefcountbt recs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1539.out b/tests/xfs/1539.out
new file mode 100644
index 0000000000..aa3a963dc2
--- /dev/null
+++ b/tests/xfs/1539.out
@@ -0,0 +1,4 @@
+QA output created by 1539
+Format and populate
+Fuzz rtrefcountbt recs
+Done fuzzing rtrefcountbt recs
diff --git a/tests/xfs/1540 b/tests/xfs/1540
new file mode 100755
index 0000000000..ab8dee2a02
--- /dev/null
+++ b/tests/xfs/1540
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1540
+#
+# Populate a XFS filesystem and fuzz every rtrefcountbt record field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_norepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'refcnt' 2)" || \
+ _fail "could not find two-level rtrefcountbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
+
+echo "Fuzz rtrefcountbt recs"
+_scratch_xfs_fuzz_metadata '' 'none' "path -m $path" "addr u${inode_ver}.rtrefcbt.ptrs[1]" >> $seqres.full
+echo "Done fuzzing rtrefcountbt recs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1540.out b/tests/xfs/1540.out
new file mode 100644
index 0000000000..37f3311837
--- /dev/null
+++ b/tests/xfs/1540.out
@@ -0,0 +1,4 @@
+QA output created by 1540
+Format and populate
+Fuzz rtrefcountbt recs
+Done fuzzing rtrefcountbt recs
diff --git a/tests/xfs/1541 b/tests/xfs/1541
new file mode 100755
index 0000000000..18312456f4
--- /dev/null
+++ b/tests/xfs/1541
@@ -0,0 +1,42 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1541
+#
+# Populate a XFS filesystem and fuzz every rtrefcountbt record field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'refcnt' 2)" || \
+ _fail "could not find two-level rtrefcountbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
+
+echo "Fuzz rtrefcountbt recs"
+_scratch_xfs_fuzz_metadata '' 'both' "path -m $path" "addr u${inode_ver}.rtrefcbt.ptrs[1]" >> $seqres.full
+echo "Done fuzzing rtrefcountbt recs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1541.out b/tests/xfs/1541.out
new file mode 100644
index 0000000000..35a9b73471
--- /dev/null
+++ b/tests/xfs/1541.out
@@ -0,0 +1,4 @@
+QA output created by 1541
+Format and populate
+Fuzz rtrefcountbt recs
+Done fuzzing rtrefcountbt recs
diff --git a/tests/xfs/1542 b/tests/xfs/1542
new file mode 100755
index 0000000000..9246a31a31
--- /dev/null
+++ b/tests/xfs/1542
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1542
+#
+# Populate a XFS filesystem and fuzz every rtrefcountbt key/ptr field.
+# Use xfs_scrub to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_online_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'refcnt' 2)" || \
+ _fail "could not find two-level rtrefcountbt"
+inode_ver=$(_scratch_xfs_get_metadata_field "core.version" "path -m $path")
+
+echo "Fuzz rtrefcountbt keyptrs"
+_scratch_xfs_fuzz_metadata '(rtrefcbt)' 'online' "path -m $path" >> $seqres.full
+echo "Done fuzzing rtrefcountbt keyptrs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1542.out b/tests/xfs/1542.out
new file mode 100644
index 0000000000..55d820b4b1
--- /dev/null
+++ b/tests/xfs/1542.out
@@ -0,0 +1,4 @@
+QA output created by 1542
+Format and populate
+Fuzz rtrefcountbt keyptrs
+Done fuzzing rtrefcountbt keyptrs
diff --git a/tests/xfs/1543 b/tests/xfs/1543
new file mode 100755
index 0000000000..38afae106a
--- /dev/null
+++ b/tests/xfs/1543
@@ -0,0 +1,40 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1543
+#
+# Populate a XFS filesystem and fuzz every rtrefcountbt key/ptr field.
+# Use xfs_repair to fix the corruption.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_scrub dangerous_repair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'refcnt' 2)" || \
+ _fail "could not find two-level rtrefcountbt"
+
+echo "Fuzz rtrefcountbt keyptrs"
+_scratch_xfs_fuzz_metadata '(rtrefcbt)' 'offline' "path -m $path" >> $seqres.full
+echo "Done fuzzing rtrefcountbt keyptrs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1543.out b/tests/xfs/1543.out
new file mode 100644
index 0000000000..e7afa10744
--- /dev/null
+++ b/tests/xfs/1543.out
@@ -0,0 +1,4 @@
+QA output created by 1543
+Format and populate
+Fuzz rtrefcountbt keyptrs
+Done fuzzing rtrefcountbt keyptrs
diff --git a/tests/xfs/1544 b/tests/xfs/1544
new file mode 100755
index 0000000000..86b11b1955
--- /dev/null
+++ b/tests/xfs/1544
@@ -0,0 +1,40 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1544
+#
+# Populate a XFS filesystem and fuzz every rtrefcountbt key/ptr field.
+# Do not fix the filesystem, to test metadata verifiers.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_norepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'refcnt' 2)" || \
+ _fail "could not find two-level rtrefcountbt"
+
+echo "Fuzz rtrefcountbt keyptrs"
+_scratch_xfs_fuzz_metadata '(rtrefcbt)' 'none' "path -m $path" >> $seqres.full
+echo "Done fuzzing rtrefcountbt keyptrs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1544.out b/tests/xfs/1544.out
new file mode 100644
index 0000000000..b39532c160
--- /dev/null
+++ b/tests/xfs/1544.out
@@ -0,0 +1,4 @@
+QA output created by 1544
+Format and populate
+Fuzz rtrefcountbt keyptrs
+Done fuzzing rtrefcountbt keyptrs
diff --git a/tests/xfs/1545 b/tests/xfs/1545
new file mode 100755
index 0000000000..1dbe03506b
--- /dev/null
+++ b/tests/xfs/1545
@@ -0,0 +1,41 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1545
+#
+# Populate a XFS filesystem and fuzz every rtrefcountbt key/ptr field.
+# Try online repair and, if necessary, offline repair,
+# to test the most likely usage pattern.
+
+. ./common/preamble
+_begin_fstest dangerous_fuzzers dangerous_bothrepair realtime
+
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/populate
+. ./common/fuzzy
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch_reflink
+_require_scratch_xfs_fuzz_fields
+_disable_dmesg_check
+
+echo "Format and populate"
+_scratch_populate_cached nofill > $seqres.full 2>&1
+
+path="$(_scratch_xfs_find_rgbtree_height 'refcnt' 2)" || \
+ _fail "could not find two-level rtrefcountbt"
+
+echo "Fuzz rtrefcountbt keyptrs"
+_scratch_xfs_fuzz_metadata '(rtrefcbt)' 'both' "path -m $path" >> $seqres.full
+echo "Done fuzzing rtrefcountbt keyptrs"
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1545.out b/tests/xfs/1545.out
new file mode 100644
index 0000000000..982a0d64df
--- /dev/null
+++ b/tests/xfs/1545.out
@@ -0,0 +1,4 @@
+QA output created by 1545
+Format and populate
+Fuzz rtrefcountbt keyptrs
+Done fuzzing rtrefcountbt keyptrs
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 4/9] xfs/27[24]: adapt for checking files on the realtime volume
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
` (2 preceding siblings ...)
2023-12-27 14:02 ` [PATCH 3/9] xfs: create fuzz tests for the " Darrick J. Wong
@ 2023-12-27 14:02 ` Darrick J. Wong
2023-12-27 14:02 ` [PATCH 5/9] xfs: race fsstress with realtime refcount btree scrub and repair Darrick J. Wong
` (4 subsequent siblings)
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:02 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Adapt both tests to behave properly if the two files being tested are on
the realtime volume.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/272 | 40 +++++++++++++++++++++++++------------
tests/xfs/274 | 62 ++++++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 70 insertions(+), 32 deletions(-)
diff --git a/tests/xfs/272 b/tests/xfs/272
index d5f3a74177..edc5b16967 100755
--- a/tests/xfs/272
+++ b/tests/xfs/272
@@ -40,26 +40,40 @@ $here/src/punch-alternating $SCRATCH_MNT/urk >> $seqres.full
ino=$(stat -c '%i' $SCRATCH_MNT/urk)
echo "Get fsmap" | tee -a $seqres.full
-$XFS_IO_PROG -c 'fsmap -v' $SCRATCH_MNT >> $seqres.full
$XFS_IO_PROG -c 'fsmap -v' $SCRATCH_MNT | tr '[]()' ' ' > $TEST_DIR/fsmap
+cat $TEST_DIR/fsmap >> $seqres.full
echo "Get bmap" | tee -a $seqres.full
-$XFS_IO_PROG -c 'bmap -v' $SCRATCH_MNT/urk >> $seqres.full
$XFS_IO_PROG -c 'bmap -v' $SCRATCH_MNT/urk | grep '^[[:space:]]*[0-9]*:' | grep -v 'hole' | tr '[]()' ' ' > $TEST_DIR/bmap
+cat $TEST_DIR/bmap >> $seqres.full
echo "Check bmap and fsmap" | tee -a $seqres.full
-cat $TEST_DIR/bmap | while read ext offrange colon blockrange ag agrange total crap; do
- qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${blockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${ag}[[:space:]]*${agrange}[[:space:]]*${total}(| [01]*)$"
- echo "${qstr}" >> $seqres.full
- grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
- found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
- test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
-done
+if $XFS_IO_PROG -c 'stat -v' $SCRATCH_MNT/urk | grep -q realtime; then
+ # file on rt volume
+ cat $TEST_DIR/bmap | while read ext offrange colon rtblockrange total crap; do
+ qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${rtblockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${total}(| [01]*)$"
+ echo "${qstr}" >> $seqres.full
+ grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
+ found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
+ test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
+ done
-echo "Check device field of FS metadata and regular file"
-data_dev=$(grep 'inode btree' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
-rt_dev=$(grep "${ino}[[:space:]]*[0-9]*\.\.[0-9]*" $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
-test "${data_dev}" = "${rt_dev}" || echo "data ${data_dev} realtime ${rt_dev}?"
+ echo "Check device field of FS metadata and regular file"
+else
+ # file on data volume
+ cat $TEST_DIR/bmap | while read ext offrange colon blockrange ag agrange total crap; do
+ qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${blockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${ag}[[:space:]]*${agrange}[[:space:]]*${total}(| [01]*)$"
+ echo "${qstr}" >> $seqres.full
+ grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
+ found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
+ test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
+ done
+
+ echo "Check device field of FS metadata and regular file"
+ data_dev=$(grep 'inode btree' $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
+ rt_dev=$(grep "${ino}[[:space:]]*[0-9]*\.\.[0-9]*" $TEST_DIR/fsmap | head -n 1 | awk '{print $2}')
+ test "${data_dev}" = "${rt_dev}" || echo "data ${data_dev} realtime ${rt_dev}?"
+fi
# success, all done
status=0
diff --git a/tests/xfs/274 b/tests/xfs/274
index cd483d77bc..f16b49fc1c 100755
--- a/tests/xfs/274
+++ b/tests/xfs/274
@@ -40,34 +40,58 @@ _cp_reflink $SCRATCH_MNT/f1 $SCRATCH_MNT/f2
ino=$(stat -c '%i' $SCRATCH_MNT/f1)
echo "Get fsmap" | tee -a $seqres.full
-$XFS_IO_PROG -c 'fsmap -v' $SCRATCH_MNT >> $seqres.full
$XFS_IO_PROG -c 'fsmap -v' $SCRATCH_MNT | tr '[]()' ' ' > $TEST_DIR/fsmap
+cat $TEST_DIR/fsmap >> $seqres.full
echo "Get f1 bmap" | tee -a $seqres.full
-$XFS_IO_PROG -c 'bmap -v' $SCRATCH_MNT/f1 >> $seqres.full
$XFS_IO_PROG -c 'bmap -v' $SCRATCH_MNT/f1 | grep '^[[:space:]]*[0-9]*:' | grep -v 'hole' | tr '[]()' ' ' > $TEST_DIR/bmap
+cat $TEST_DIR/bmap >> $seqres.full
-echo "Check f1 bmap and fsmap" | tee -a $seqres.full
-cat $TEST_DIR/bmap | while read ext offrange colon blockrange ag agrange total crap; do
- qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${blockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${ag}[[:space:]]*${agrange}[[:space:]]*${total} 010[01]{4}$"
- echo "${qstr}" >> $seqres.full
- grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
- found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
- test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
-done
+if _xfs_is_realtime_file $SCRATCH_MNT/f1 && ! _xfs_has_feature $SCRATCH_MNT rtgroups; then
+ # file on rt volume
+ echo "Check f1 bmap and fsmap" | tee -a $seqres.full
+ cat $TEST_DIR/bmap | while read ext offrange colon rtblockrange total crap; do
+ qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${rtblockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${total} 010[01]{4}$"
+ echo "${qstr}" >> $seqres.full
+ grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
+ found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
+ test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
+ done
+else
+ # file on data volume
+ echo "Check f1 bmap and fsmap" | tee -a $seqres.full
+ cat $TEST_DIR/bmap | while read ext offrange colon blockrange ag agrange total crap; do
+ qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${blockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${ag}[[:space:]]*${agrange}[[:space:]]*${total} 010[01]{4}$"
+ echo "${qstr}" >> $seqres.full
+ grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
+ found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
+ test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
+ done
+fi
echo "Get f2 bmap" | tee -a $seqres.full
-$XFS_IO_PROG -c 'bmap -v' $SCRATCH_MNT/f2 >> $seqres.full
$XFS_IO_PROG -c 'bmap -v' $SCRATCH_MNT/f2 | grep '^[[:space:]]*[0-9]*:' | grep -v 'hole' | tr '[]()' ' ' > $TEST_DIR/bmap
+cat $TEST_DIR/bmap >> $seqres.full
-echo "Check f2 bmap and fsmap" | tee -a $seqres.full
-cat $TEST_DIR/bmap | while read ext offrange colon blockrange ag agrange total crap; do
- qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${blockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${ag}[[:space:]]*${agrange}[[:space:]]*${total} 010[01]{4}$"
- echo "${qstr}" >> $seqres.full
- grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
- found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
- test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
-done
+if _xfs_is_realtime_file $SCRATCH_MNT/f2 && ! _xfs_has_feature $SCRATCH_MNT rtgroups; then
+ echo "Check f2 bmap and fsmap" | tee -a $seqres.full
+ cat $TEST_DIR/bmap | while read ext offrange colon rtblockrange total crap; do
+ qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${rtblockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${total} 010[01]{4}$"
+ echo "${qstr}" >> $seqres.full
+ grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
+ found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
+ test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
+ done
+else
+ echo "Check f2 bmap and fsmap" | tee -a $seqres.full
+ cat $TEST_DIR/bmap | while read ext offrange colon blockrange ag agrange total crap; do
+ qstr="^[[:space:]]*[0-9]*:[[:space:]]*[0-9]*:[0-9]*[[:space:]]*${blockrange} :[[:space:]]*${ino}[[:space:]]*${offrange}[[:space:]]*${ag}[[:space:]]*${agrange}[[:space:]]*${total} 010[01]{4}$"
+ echo "${qstr}" >> $seqres.full
+ grep "${qstr}" $TEST_DIR/fsmap >> $seqres.full
+ found=$(grep -E -c "${qstr}" $TEST_DIR/fsmap)
+ test $found -eq 1 || echo "Unexpected output for offset ${offrange}."
+ done
+fi
# success, all done
status=0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 5/9] xfs: race fsstress with realtime refcount btree scrub and repair
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
` (3 preceding siblings ...)
2023-12-27 14:02 ` [PATCH 4/9] xfs/27[24]: adapt for checking files on the realtime volume Darrick J. Wong
@ 2023-12-27 14:02 ` Darrick J. Wong
2023-12-27 14:02 ` [PATCH 6/9] xfs: remove xfs/131 now that we allow reflink on realtime volumes Darrick J. Wong
` (3 subsequent siblings)
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:02 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Race checking and rebuilding realtime refcount btrees with fsstress.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1818 | 43 +++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1818.out | 2 ++
tests/xfs/1819 | 43 +++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1819.out | 2 ++
4 files changed, 90 insertions(+)
create mode 100755 tests/xfs/1818
create mode 100644 tests/xfs/1818.out
create mode 100755 tests/xfs/1819
create mode 100644 tests/xfs/1819.out
diff --git a/tests/xfs/1818 b/tests/xfs/1818
new file mode 100755
index 0000000000..674fff25fa
--- /dev/null
+++ b/tests/xfs/1818
@@ -0,0 +1,43 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1818
+#
+# Race fsstress and rt refcount btree scrub for a while to see if we crash or
+# livelock.
+#
+. ./common/preamble
+_begin_fstest scrub dangerous_fsstress_scrub
+
+_cleanup() {
+ _scratch_xfs_stress_scrub_cleanup &> /dev/null
+ cd /
+ rm -r -f $tmp.*
+}
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/fuzzy
+. ./common/inject
+. ./common/xfs
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch
+_require_xfs_stress_scrub
+
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount
+_require_xfs_has_feature "$SCRATCH_MNT" realtime
+_require_xfs_has_feature "$SCRATCH_MNT" reflink
+_xfs_force_bdev realtime $SCRATCH_MNT
+
+_scratch_xfs_stress_scrub -s "scrub rtrefcountbt %rgno%"
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/xfs/1818.out b/tests/xfs/1818.out
new file mode 100644
index 0000000000..700d301da1
--- /dev/null
+++ b/tests/xfs/1818.out
@@ -0,0 +1,2 @@
+QA output created by 1818
+Silence is golden
diff --git a/tests/xfs/1819 b/tests/xfs/1819
new file mode 100755
index 0000000000..e27a29271f
--- /dev/null
+++ b/tests/xfs/1819
@@ -0,0 +1,43 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1819
+#
+# Race fsstress and rt refcount btree scrub for a while to see if we crash or
+# livelock.
+#
+. ./common/preamble
+_begin_fstest online_repair dangerous_fsstress_repair
+
+_cleanup() {
+ _scratch_xfs_stress_scrub_cleanup &> /dev/null
+ cd /
+ rm -r -f $tmp.*
+}
+_register_cleanup "_cleanup" BUS
+
+# Import common functions.
+. ./common/filter
+. ./common/fuzzy
+. ./common/inject
+. ./common/xfs
+
+# real QA test starts here
+_supported_fs xfs
+_require_realtime
+_require_scratch
+_require_xfs_stress_online_repair
+
+_scratch_mkfs > "$seqres.full" 2>&1
+_scratch_mount
+_require_xfs_has_feature "$SCRATCH_MNT" realtime
+_require_xfs_has_feature "$SCRATCH_MNT" reflink
+_xfs_force_bdev realtime $SCRATCH_MNT
+
+_scratch_xfs_stress_online_repair -s "repair rtrefcountbt %rgno%"
+
+# success, all done
+echo Silence is golden
+status=0
+exit
diff --git a/tests/xfs/1819.out b/tests/xfs/1819.out
new file mode 100644
index 0000000000..041e17ab61
--- /dev/null
+++ b/tests/xfs/1819.out
@@ -0,0 +1,2 @@
+QA output created by 1819
+Silence is golden
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 6/9] xfs: remove xfs/131 now that we allow reflink on realtime volumes
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
` (4 preceding siblings ...)
2023-12-27 14:02 ` [PATCH 5/9] xfs: race fsstress with realtime refcount btree scrub and repair Darrick J. Wong
@ 2023-12-27 14:02 ` Darrick J. Wong
2023-12-27 14:03 ` [PATCH 7/9] xfs/856: add rtreflink upgrade to test matrix Darrick J. Wong
` (2 subsequent siblings)
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:02 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Remove this test, since we now support reflink on the rt volume.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/131 | 48 ------------------------------------------------
tests/xfs/131.out | 5 -----
2 files changed, 53 deletions(-)
delete mode 100755 tests/xfs/131
delete mode 100644 tests/xfs/131.out
diff --git a/tests/xfs/131 b/tests/xfs/131
deleted file mode 100755
index 879e2dc6e8..0000000000
--- a/tests/xfs/131
+++ /dev/null
@@ -1,48 +0,0 @@
-#! /bin/bash
-# SPDX-License-Identifier: GPL-2.0
-# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved.
-#
-# FS QA Test No. 131
-#
-# Ensure that we can't reflink realtime files.
-#
-. ./common/preamble
-_begin_fstest auto quick clone realtime
-
-# Override the default cleanup function.
-_cleanup()
-{
- cd /
- umount $SCRATCH_MNT > /dev/null 2>&1
- rm -rf $tmp.* $testdir $metadump_file
-}
-
-# Import common functions.
-. ./common/filter
-. ./common/reflink
-
-# real QA test starts here
-_supported_fs xfs
-_require_realtime
-_require_scratch_reflink
-_require_cp_reflink
-
-echo "Format and mount scratch device"
-_scratch_mkfs >> $seqres.full
-_scratch_mount
-
-testdir=$SCRATCH_MNT/test-$seq
-mkdir $testdir
-
-echo "Create the original file blocks"
-blksz=65536
-$XFS_IO_PROG -R -f -c "truncate $blksz" $testdir/file1
-
-echo "Reflink every block"
-_cp_reflink $testdir/file1 $testdir/file2 2>&1 | _filter_scratch
-
-test -s $testdir/file2 && _fail "Should not be able to reflink a realtime file."
-
-# success, all done
-status=0
-exit
diff --git a/tests/xfs/131.out b/tests/xfs/131.out
deleted file mode 100644
index 3c0186f0c7..0000000000
--- a/tests/xfs/131.out
+++ /dev/null
@@ -1,5 +0,0 @@
-QA output created by 131
-Format and mount scratch device
-Create the original file blocks
-Reflink every block
-cp: failed to clone 'SCRATCH_MNT/test-131/file2' from 'SCRATCH_MNT/test-131/file1': Invalid argument
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 7/9] xfs/856: add rtreflink upgrade to test matrix
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
` (5 preceding siblings ...)
2023-12-27 14:02 ` [PATCH 6/9] xfs: remove xfs/131 now that we allow reflink on realtime volumes Darrick J. Wong
@ 2023-12-27 14:03 ` Darrick J. Wong
2023-12-27 14:03 ` [PATCH 8/9] generic/331,xfs/240: support files that skip delayed allocation Darrick J. Wong
2023-12-27 14:03 ` [PATCH 9/9] common/xfs: fix _xfs_get_file_block_size when rtinherit is set and no rt section Darrick J. Wong
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:03 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Add realtime reflink to the features that this test will try to
upgrade.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1856 | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/xfs/1856 b/tests/xfs/1856
index 8453d9bff2..4126c28e5d 100755
--- a/tests/xfs/1856
+++ b/tests/xfs/1856
@@ -205,12 +205,13 @@ post_exercise()
# upgrade don't spread failure to the rest of the tests.
FEATURES=()
if rt_configured; then
- # rmap wasn't added to rt devices until after metadir and rtgroups
+ # reflink & rmap weren't added to rt devices until after metadir and rtgroups
check_repair_upgrade finobt && FEATURES+=("finobt")
check_repair_upgrade inobtcount && FEATURES+=("inobtcount")
check_repair_upgrade bigtime && FEATURES+=("bigtime")
check_repair_upgrade metadir && FEATURES+=("metadir")
supports_rtgroups && check_repair_upgrade rmapbt && FEATURES+=("rmapbt")
+ supports_rtgroups && check_repair_upgrade reflink && FEATURES+=("reflink")
else
check_repair_upgrade finobt && FEATURES+=("finobt")
check_repair_upgrade rmapbt && FEATURES+=("rmapbt")
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 8/9] generic/331,xfs/240: support files that skip delayed allocation
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
` (6 preceding siblings ...)
2023-12-27 14:03 ` [PATCH 7/9] xfs/856: add rtreflink upgrade to test matrix Darrick J. Wong
@ 2023-12-27 14:03 ` Darrick J. Wong
2023-12-27 14:03 ` [PATCH 9/9] common/xfs: fix _xfs_get_file_block_size when rtinherit is set and no rt section Darrick J. Wong
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:03 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The goal of this test is to ensure that log recovery finishes a copy on
write operation in the event of temporary media errors. It's important
that the test observe some sort of IO error once we switch the scratch
device to fail all IOs, but regrettably the test encoded the specific
behavior of XFS and btrfs when the test was written -- the aio write
to the page cache doesn't have to touch the disk and succeeds, and the
fdatasync flushes things to disk and hits the IO error.
However, this is not how things work on the XFS realtime device. There
is no delalloc on realtime, so the aio write allocates an unwritten
extent to stage the write. The allocation fails due to EIO, so it's the
write call that fails. Therefore, all we need to do is to detect an IO
error at any point between the write and the fdatasync call to be
satisfied that the test does what we want to do.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/generic/331 | 12 ++++++++++--
tests/generic/331.out | 2 +-
tests/xfs/240 | 13 +++++++++++--
tests/xfs/240.out | 2 +-
4 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/tests/generic/331 b/tests/generic/331
index 492abedf76..8c665ce4fc 100755
--- a/tests/generic/331
+++ b/tests/generic/331
@@ -59,9 +59,17 @@ echo "CoW and unmount"
$XFS_IO_PROG -f -c "pwrite -S 0x63 $bufsize 1" $testdir/file2 >> $seqres.full
$XFS_IO_PROG -f -c "pwrite -S 0x63 -b $bufsize 0 $filesize" $TEST_DIR/moo >> $seqres.full
sync
+
+# If the filesystem supports delalloc, then the fdatasync will report an IO
+# error. If the write goes directly to disk, then aiocp will return nonzero.
+unset write_failed
_dmerror_load_error_table
-$AIO_TEST -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full
-$XFS_IO_PROG -c "fdatasync" $testdir/file2
+$AIO_TEST -b $bufsize $TEST_DIR/moo $testdir/file2 &>> $seqres.full || \
+ write_failed=1
+$XFS_IO_PROG -c "fdatasync" $testdir/file2 2>&1 | grep -q 'Input.output error' && \
+ write_failed=1
+test -n $write_failed && echo "write failed"
+
_dmerror_load_working_table
_dmerror_unmount
_dmerror_mount
diff --git a/tests/generic/331.out b/tests/generic/331.out
index adbf841d00..d8ccea704b 100644
--- a/tests/generic/331.out
+++ b/tests/generic/331.out
@@ -5,7 +5,7 @@ Compare files
1886e67cf8783e89ce6ddc5bb09a3944 SCRATCH_MNT/test-331/file1
1886e67cf8783e89ce6ddc5bb09a3944 SCRATCH_MNT/test-331/file2
CoW and unmount
-fdatasync: Input/output error
+write failed
Compare files
1886e67cf8783e89ce6ddc5bb09a3944 SCRATCH_MNT/test-331/file1
d94b0ab13385aba594411c174b1cc13c SCRATCH_MNT/test-331/file2
diff --git a/tests/xfs/240 b/tests/xfs/240
index a65c270d23..cabe309201 100755
--- a/tests/xfs/240
+++ b/tests/xfs/240
@@ -66,8 +66,17 @@ $XFS_IO_PROG -f -c "pwrite -S 0x63 $bufsize 1" $testdir/file2 >> $seqres.full
$XFS_IO_PROG -f -c "pwrite -S 0x63 -b $bufsize 0 $filesize" $TEST_DIR/moo >> $seqres.full
sync
_dmerror_load_error_table
-$AIO_TEST -b $bufsize $TEST_DIR/moo $testdir/file2 >> $seqres.full
-$XFS_IO_PROG -c "fdatasync" $testdir/file2
+
+# If the filesystem supports delalloc, then the fdatasync will report an IO
+# error. If the write goes directly to disk, then aiocp will return nonzero.
+unset write_failed
+_dmerror_load_error_table
+$AIO_TEST -b $bufsize $TEST_DIR/moo $testdir/file2 &>> $seqres.full || \
+ write_failed=1
+$XFS_IO_PROG -c "fdatasync" $testdir/file2 2>&1 | grep -q 'Input.output error' && \
+ write_failed=1
+test -n $write_failed && echo "write failed"
+
_dmerror_load_working_table
_dmerror_unmount
_dmerror_mount
diff --git a/tests/xfs/240.out b/tests/xfs/240.out
index 1a22e8a389..00bb116e5c 100644
--- a/tests/xfs/240.out
+++ b/tests/xfs/240.out
@@ -5,7 +5,7 @@ Compare files
1886e67cf8783e89ce6ddc5bb09a3944 SCRATCH_MNT/test-240/file1
1886e67cf8783e89ce6ddc5bb09a3944 SCRATCH_MNT/test-240/file2
CoW and unmount
-fdatasync: Input/output error
+write failed
Compare files
1886e67cf8783e89ce6ddc5bb09a3944 SCRATCH_MNT/test-240/file1
d94b0ab13385aba594411c174b1cc13c SCRATCH_MNT/test-240/file2
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 9/9] common/xfs: fix _xfs_get_file_block_size when rtinherit is set and no rt section
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
` (7 preceding siblings ...)
2023-12-27 14:03 ` [PATCH 8/9] generic/331,xfs/240: support files that skip delayed allocation Darrick J. Wong
@ 2023-12-27 14:03 ` Darrick J. Wong
8 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:03 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
It's possible for the sysadmin to set rtinherit on the directory tree
even if there isn't a realtime section attached to the filesystem. When
this is the case, the realtime flag is /not/ passed to new files, and
file data is written to the data device. The file allocation unit for
the file is the fs blocksize, and it is not correct to use the rt
extent.
fstests can be fooled into doing the incorrect thing if test runner puts
'-d rtinherit=1 -r extsize=28k' into MKFS_OPTIONS without configuring a
realtime device. This causes many tests to do the wrong thing because
they think they must operate on units of 28k (and not 4k). Fix this.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/xfs | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/common/xfs b/common/xfs
index aab04bfb18..69a0eb620c 100644
--- a/common/xfs
+++ b/common/xfs
@@ -208,6 +208,8 @@ _xfs_get_file_block_size()
{
local path="$1"
+ # If rtinherit or realtime are not set on the path, then all files
+ # will be created on the data device.
if ! ($XFS_IO_PROG -c "stat -v" "$path" 2>&1 | grep -E -q '(rt-inherit|realtime)'); then
_get_block_size "$path"
return
@@ -218,6 +220,15 @@ _xfs_get_file_block_size()
while ! $XFS_INFO_PROG "$path" &>/dev/null && [ "$path" != "/" ]; do
path="$(dirname "$path")"
done
+
+ # If there's no realtime section, the rtinherit and rextsize settings
+ # are irrelevant -- all files are created on the data device.
+ if $XFS_INFO_PROG "$path" | grep -q 'realtime =none'; then
+ _get_block_size "$path"
+ return
+ fi
+
+ # Otherwise, report the rt extent size.
_xfs_get_rtextsize "$path"
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 1/1] xfs: baseline golden output for rt refcount btree fuzz tests
2023-12-31 20:01 ` [PATCHSET v2.0 7/9] fstests: establish baseline for realtime reflink fuzz tests Darrick J. Wong
@ 2023-12-27 14:03 ` Darrick J. Wong
0 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:03 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Record all the currently known failures of the xfs_scrub check and
repair code for the rt refcount btree fuzz tests.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1539.out | 6 ++++++
tests/xfs/1540.out | 6 ++++++
tests/xfs/1541.out | 6 ++++++
tests/xfs/1542.out | 10 ++++++++++
tests/xfs/1543.out | 2 ++
tests/xfs/1544.out | 12 ++++++++++++
tests/xfs/1545.out | 12 ++++++++++++
7 files changed, 54 insertions(+)
diff --git a/tests/xfs/1539.out b/tests/xfs/1539.out
index aa3a963dc2..9f90912f2c 100644
--- a/tests/xfs/1539.out
+++ b/tests/xfs/1539.out
@@ -1,4 +1,10 @@
QA output created by 1539
Format and populate
Fuzz rtrefcountbt recs
+numrecs = lastbit: offline scrub didn't fail.
+leftsib = add: offline scrub didn't fail.
+rightsib = ones: offline scrub didn't fail.
+rightsib = firstbit: offline scrub didn't fail.
+rightsib = lastbit: offline scrub didn't fail.
+rightsib = add: offline scrub didn't fail.
Done fuzzing rtrefcountbt recs
diff --git a/tests/xfs/1540.out b/tests/xfs/1540.out
index 37f3311837..368dbace0f 100644
--- a/tests/xfs/1540.out
+++ b/tests/xfs/1540.out
@@ -1,4 +1,10 @@
QA output created by 1540
Format and populate
Fuzz rtrefcountbt recs
+numrecs = lastbit: offline scrub didn't fail.
+leftsib = add: offline scrub didn't fail.
+rightsib = ones: offline scrub didn't fail.
+rightsib = firstbit: offline scrub didn't fail.
+rightsib = lastbit: offline scrub didn't fail.
+rightsib = add: offline scrub didn't fail.
Done fuzzing rtrefcountbt recs
diff --git a/tests/xfs/1541.out b/tests/xfs/1541.out
index 35a9b73471..4af739233a 100644
--- a/tests/xfs/1541.out
+++ b/tests/xfs/1541.out
@@ -1,4 +1,10 @@
QA output created by 1541
Format and populate
Fuzz rtrefcountbt recs
+numrecs = lastbit: offline scrub didn't fail.
+leftsib = add: offline scrub didn't fail.
+rightsib = ones: offline scrub didn't fail.
+rightsib = firstbit: offline scrub didn't fail.
+rightsib = lastbit: offline scrub didn't fail.
+rightsib = add: offline scrub didn't fail.
Done fuzzing rtrefcountbt recs
diff --git a/tests/xfs/1542.out b/tests/xfs/1542.out
index 55d820b4b1..d6acd5257c 100644
--- a/tests/xfs/1542.out
+++ b/tests/xfs/1542.out
@@ -1,4 +1,14 @@
QA output created by 1542
Format and populate
Fuzz rtrefcountbt keyptrs
+u3.rtrefcbt.level = ones: mount failed (32).
+u3.rtrefcbt.level = firstbit: mount failed (32).
+u3.rtrefcbt.level = middlebit: mount failed (32).
+u3.rtrefcbt.level = add: mount failed (32).
+u3.rtrefcbt.level = sub: mount failed (32).
+u3.rtrefcbt.numrecs = ones: mount failed (32).
+u3.rtrefcbt.numrecs = firstbit: mount failed (32).
+u3.rtrefcbt.numrecs = middlebit: mount failed (32).
+u3.rtrefcbt.numrecs = add: mount failed (32).
+u3.rtrefcbt.numrecs = sub: mount failed (32).
Done fuzzing rtrefcountbt keyptrs
diff --git a/tests/xfs/1543.out b/tests/xfs/1543.out
index e7afa10744..59eb5ad149 100644
--- a/tests/xfs/1543.out
+++ b/tests/xfs/1543.out
@@ -1,4 +1,6 @@
QA output created by 1543
Format and populate
Fuzz rtrefcountbt keyptrs
+u3.rtrefcbt.keys[1].startblock = zeroes: offline scrub didn't fail.
+u3.rtrefcbt.keys[1].startblock = lastbit: offline scrub didn't fail.
Done fuzzing rtrefcountbt keyptrs
diff --git a/tests/xfs/1544.out b/tests/xfs/1544.out
index b39532c160..717f901bb4 100644
--- a/tests/xfs/1544.out
+++ b/tests/xfs/1544.out
@@ -1,4 +1,16 @@
QA output created by 1544
Format and populate
Fuzz rtrefcountbt keyptrs
+u3.rtrefcbt.level = ones: mount failed (32).
+u3.rtrefcbt.level = firstbit: mount failed (32).
+u3.rtrefcbt.level = middlebit: mount failed (32).
+u3.rtrefcbt.level = add: mount failed (32).
+u3.rtrefcbt.level = sub: mount failed (32).
+u3.rtrefcbt.numrecs = ones: mount failed (32).
+u3.rtrefcbt.numrecs = firstbit: mount failed (32).
+u3.rtrefcbt.numrecs = middlebit: mount failed (32).
+u3.rtrefcbt.numrecs = add: mount failed (32).
+u3.rtrefcbt.numrecs = sub: mount failed (32).
+u3.rtrefcbt.keys[1].startblock = zeroes: offline scrub didn't fail.
+u3.rtrefcbt.keys[1].startblock = lastbit: offline scrub didn't fail.
Done fuzzing rtrefcountbt keyptrs
diff --git a/tests/xfs/1545.out b/tests/xfs/1545.out
index 982a0d64df..d279dc0db8 100644
--- a/tests/xfs/1545.out
+++ b/tests/xfs/1545.out
@@ -1,4 +1,16 @@
QA output created by 1545
Format and populate
Fuzz rtrefcountbt keyptrs
+u3.rtrefcbt.level = ones: mount failed (32).
+u3.rtrefcbt.level = firstbit: mount failed (32).
+u3.rtrefcbt.level = middlebit: mount failed (32).
+u3.rtrefcbt.level = add: mount failed (32).
+u3.rtrefcbt.level = sub: mount failed (32).
+u3.rtrefcbt.numrecs = ones: mount failed (32).
+u3.rtrefcbt.numrecs = firstbit: mount failed (32).
+u3.rtrefcbt.numrecs = middlebit: mount failed (32).
+u3.rtrefcbt.numrecs = add: mount failed (32).
+u3.rtrefcbt.numrecs = sub: mount failed (32).
+u3.rtrefcbt.keys[1].startblock = zeroes: offline scrub didn't fail.
+u3.rtrefcbt.keys[1].startblock = lastbit: offline scrub didn't fail.
Done fuzzing rtrefcountbt keyptrs
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 1/5] xfs: make sure that CoW will write around when rextsize > 1
2023-12-31 20:01 ` [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents Darrick J. Wong
@ 2023-12-27 14:04 ` Darrick J. Wong
2023-12-27 14:04 ` [PATCH 2/5] xfs: skip cowextsize hint fragmentation tests on realtime volumes Darrick J. Wong
` (3 subsequent siblings)
4 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:04 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Make sure that CoW triggers the intended copy-around behavior when we
write a tiny amount to the middle of a large rt extent.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1919 | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1919.out | 84 +++++++++++++++++++++++++++
2 files changed, 247 insertions(+)
create mode 100755 tests/xfs/1919
create mode 100644 tests/xfs/1919.out
diff --git a/tests/xfs/1919 b/tests/xfs/1919
new file mode 100755
index 0000000000..00b16737e7
--- /dev/null
+++ b/tests/xfs/1919
@@ -0,0 +1,163 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1919
+#
+# Make sure that copy on write actually does the intended write-around when we
+# stage a tiny modification to a large shared realtime extent. We should never
+# end up with multiple rt extents mapped to the same region.
+#
+. ./common/preamble
+_begin_fstest auto quick clone realtime
+
+# Import common functions.
+. ./common/filter
+. ./common/reflink
+
+# real QA test starts here
+_supported_fs xfs
+_require_xfs_io_command "fpunch"
+_require_xfs_io_command "fzero"
+_require_xfs_io_command "fcollapse"
+_require_xfs_io_command "finsert"
+_require_xfs_io_command "funshare"
+_require_realtime
+_require_scratch_reflink
+
+rtextsz=262144
+filesz=$((rtextsz * 3))
+
+echo "Format filesystem and populate"
+_scratch_mkfs -m reflink=1 -r extsize=$rtextsz > $seqres.full
+_scratch_mount >> $seqres.full
+
+# Force all our files to be on the realtime device
+_xfs_force_bdev realtime $SCRATCH_MNT
+
+check_file() {
+ $XFS_IO_PROG -c fsync -c 'bmap -elpv' $1 >> $seqres.full
+ md5sum $SCRATCH_MNT/a | _filter_scratch
+ md5sum $1 | _filter_scratch
+}
+
+rtextsz_got=$(_xfs_get_rtextsize "$SCRATCH_MNT")
+test $rtextsz_got -eq $rtextsz || \
+ _notrun "got rtextsize $rtextsz_got, wanted $rtextsz"
+
+_pwrite_byte 0x59 0 $filesz $SCRATCH_MNT/a >> $seqres.full
+sync
+md5sum $SCRATCH_MNT/a | _filter_scratch
+$XFS_IO_PROG -c 'bmap -elpv' $SCRATCH_MNT/a >> $seqres.full
+
+echo "pwrite 1 byte in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/b
+_pwrite_byte 0x00 345678 1 $SCRATCH_MNT/b >> $seqres.full
+check_file $SCRATCH_MNT/b
+
+echo "mwrite 1 byte in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/c
+$XFS_IO_PROG -c "mmap -rw 0 $filesz" -c "mwrite -S 0x00 345678 1" -c msync $SCRATCH_MNT/c
+check_file $SCRATCH_MNT/c
+
+echo "fzero 1 byte in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/d
+$XFS_IO_PROG -c "fzero 345678 1" $SCRATCH_MNT/d
+check_file $SCRATCH_MNT/d
+
+echo "fpunch 1 byte in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/e
+$XFS_IO_PROG -c "fpunch 345678 1" $SCRATCH_MNT/e
+check_file $SCRATCH_MNT/e
+
+echo "funshare 1 byte in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/f
+$XFS_IO_PROG -c "funshare 345678 1" $SCRATCH_MNT/f
+check_file $SCRATCH_MNT/f
+
+echo "pwrite 1 block in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/g
+_pwrite_byte 0x00 327680 65536 $SCRATCH_MNT/g >> $seqres.full
+check_file $SCRATCH_MNT/g
+
+echo "mwrite 1 block in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/h
+$XFS_IO_PROG -c "mmap -rw 0 $filesz" -c "mwrite -S 0x00 327680 65536" -c msync $SCRATCH_MNT/h
+check_file $SCRATCH_MNT/h
+
+echo "fzero 1 block in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/i
+$XFS_IO_PROG -c "fzero 327680 65536" $SCRATCH_MNT/i
+check_file $SCRATCH_MNT/i
+
+echo "fpunch 1 block in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/j
+$XFS_IO_PROG -c "fpunch 327680 65536" $SCRATCH_MNT/j
+check_file $SCRATCH_MNT/j
+
+echo "funshare 1 block in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/k
+$XFS_IO_PROG -c "funshare 327680 65536" $SCRATCH_MNT/k
+check_file $SCRATCH_MNT/k
+
+echo "pwrite 1 extent in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/l
+_pwrite_byte 0x00 262144 262144 $SCRATCH_MNT/l >> $seqres.full
+check_file $SCRATCH_MNT/l
+
+echo "mwrite 1 extent in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/m
+$XFS_IO_PROG -c "mmap -rw 0 $filesz" -c "mwrite -S 0x00 262144 262144" -c msync $SCRATCH_MNT/m
+check_file $SCRATCH_MNT/m
+
+echo "fzero 1 extent in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/n
+$XFS_IO_PROG -c "fzero 262144 262144" $SCRATCH_MNT/n
+check_file $SCRATCH_MNT/n
+
+echo "fpunch 1 extent in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/o
+$XFS_IO_PROG -c "fpunch 262144 262144" $SCRATCH_MNT/o
+check_file $SCRATCH_MNT/o
+
+echo "funshare 1 extent in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/p
+$XFS_IO_PROG -c "funshare 262144 262144" $SCRATCH_MNT/p
+check_file $SCRATCH_MNT/p
+
+echo "fcollapse 1 extent in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/q
+$XFS_IO_PROG -c "fcollapse 262144 262144" $SCRATCH_MNT/q
+check_file $SCRATCH_MNT/q
+
+echo "finsert 1 extent in the middle" | tee -a $seqres.full
+_cp_reflink $SCRATCH_MNT/a $SCRATCH_MNT/r
+$XFS_IO_PROG -c "finsert 262144 262144" $SCRATCH_MNT/r
+check_file $SCRATCH_MNT/r
+
+echo "copy unwritten blocks in large rtext" | tee -a $seqres.full
+$XFS_IO_PROG -f -c "falloc 0 $filesz" -c 'pwrite -S 0x59 345678 1' $SCRATCH_MNT/s >> $seqres.full
+$XFS_IO_PROG -c 'bmap -elpv' $SCRATCH_MNT/s >> $seqres.full
+_cp_reflink $SCRATCH_MNT/s $SCRATCH_MNT/t
+$XFS_IO_PROG -c 'bmap -elpv' $SCRATCH_MNT/s >> $seqres.full
+$XFS_IO_PROG -f -c 'pwrite -S 0x59 1048576 1' $SCRATCH_MNT/s >> $seqres.full
+$XFS_IO_PROG -f -c 'pwrite -S 0x59 1048576 1' $SCRATCH_MNT/t >> $seqres.full
+check_file $SCRATCH_MNT/s
+check_file $SCRATCH_MNT/t
+
+echo "test writing to shared unwritten extent" | tee -a $seqres.full
+$XFS_IO_PROG -c 'bmap -elpv' $SCRATCH_MNT/s >> $seqres.full
+_cp_reflink $SCRATCH_MNT/s $SCRATCH_MNT/u
+$XFS_IO_PROG -c 'bmap -elpv' $SCRATCH_MNT/s >> $seqres.full
+$XFS_IO_PROG -f -c 'pwrite -S 0x59 345678 1' $SCRATCH_MNT/u >> $seqres.full
+check_file $SCRATCH_MNT/u
+
+echo "Remount and recheck" | tee -a $seqres.full
+md5sum $SCRATCH_MNT/a | _filter_scratch
+for i in b c d e f g h i j k l m n o p q r s t u; do
+ check_file $SCRATCH_MNT/$i | grep -v SCRATCH_MNT.a
+done
+
+# success, all done
+status=0
+exit
diff --git a/tests/xfs/1919.out b/tests/xfs/1919.out
new file mode 100644
index 0000000000..40cf5092a5
--- /dev/null
+++ b/tests/xfs/1919.out
@@ -0,0 +1,84 @@
+QA output created by 1919
+Format filesystem and populate
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+pwrite 1 byte in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+ea0b05f13c8cce703accaffe56d59bd3 SCRATCH_MNT/b
+mwrite 1 byte in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+ea0b05f13c8cce703accaffe56d59bd3 SCRATCH_MNT/c
+fzero 1 byte in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+ea0b05f13c8cce703accaffe56d59bd3 SCRATCH_MNT/d
+fpunch 1 byte in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+ea0b05f13c8cce703accaffe56d59bd3 SCRATCH_MNT/e
+funshare 1 byte in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/f
+pwrite 1 block in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+2a508e23efc80e468efa7004fd8a1839 SCRATCH_MNT/g
+mwrite 1 block in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+2a508e23efc80e468efa7004fd8a1839 SCRATCH_MNT/h
+fzero 1 block in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+2a508e23efc80e468efa7004fd8a1839 SCRATCH_MNT/i
+fpunch 1 block in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+2a508e23efc80e468efa7004fd8a1839 SCRATCH_MNT/j
+funshare 1 block in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/k
+pwrite 1 extent in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+352abe71b0d40f194b9d701750b0d7f3 SCRATCH_MNT/l
+mwrite 1 extent in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+352abe71b0d40f194b9d701750b0d7f3 SCRATCH_MNT/m
+fzero 1 extent in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+352abe71b0d40f194b9d701750b0d7f3 SCRATCH_MNT/n
+fpunch 1 extent in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+352abe71b0d40f194b9d701750b0d7f3 SCRATCH_MNT/o
+funshare 1 extent in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/p
+fcollapse 1 extent in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+b0581637c15320958874ef3f082111da SCRATCH_MNT/q
+finsert 1 extent in the middle
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+a7359d0c100367c2cd430be334dffbd3 SCRATCH_MNT/r
+copy unwritten blocks in large rtext
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+bff4e0a70430429c92d6139065e6949b SCRATCH_MNT/s
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+bff4e0a70430429c92d6139065e6949b SCRATCH_MNT/t
+test writing to shared unwritten extent
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+bff4e0a70430429c92d6139065e6949b SCRATCH_MNT/u
+Remount and recheck
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/a
+ea0b05f13c8cce703accaffe56d59bd3 SCRATCH_MNT/b
+ea0b05f13c8cce703accaffe56d59bd3 SCRATCH_MNT/c
+ea0b05f13c8cce703accaffe56d59bd3 SCRATCH_MNT/d
+ea0b05f13c8cce703accaffe56d59bd3 SCRATCH_MNT/e
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/f
+2a508e23efc80e468efa7004fd8a1839 SCRATCH_MNT/g
+2a508e23efc80e468efa7004fd8a1839 SCRATCH_MNT/h
+2a508e23efc80e468efa7004fd8a1839 SCRATCH_MNT/i
+2a508e23efc80e468efa7004fd8a1839 SCRATCH_MNT/j
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/k
+352abe71b0d40f194b9d701750b0d7f3 SCRATCH_MNT/l
+352abe71b0d40f194b9d701750b0d7f3 SCRATCH_MNT/m
+352abe71b0d40f194b9d701750b0d7f3 SCRATCH_MNT/n
+352abe71b0d40f194b9d701750b0d7f3 SCRATCH_MNT/o
+924a97fdaa2ab30e2768081469e728a7 SCRATCH_MNT/p
+b0581637c15320958874ef3f082111da SCRATCH_MNT/q
+a7359d0c100367c2cd430be334dffbd3 SCRATCH_MNT/r
+bff4e0a70430429c92d6139065e6949b SCRATCH_MNT/s
+bff4e0a70430429c92d6139065e6949b SCRATCH_MNT/t
+bff4e0a70430429c92d6139065e6949b SCRATCH_MNT/u
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 2/5] xfs: skip cowextsize hint fragmentation tests on realtime volumes
2023-12-31 20:01 ` [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents Darrick J. Wong
2023-12-27 14:04 ` [PATCH 1/5] xfs: make sure that CoW will write around when rextsize > 1 Darrick J. Wong
@ 2023-12-27 14:04 ` Darrick J. Wong
2023-12-27 14:04 ` [PATCH 3/5] misc: add more congruent oplen testing Darrick J. Wong
` (2 subsequent siblings)
4 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:04 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
The XFS CoW extent size hint is ignored on realtime filesystems when the
rt extent size set to a unit larger than a single filesystem block
because it is assumed that the larger allocation unit is the
administrator's sole and mandatory anti-fragmentation strategy. As
such, we can skip these tests.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/reflink | 27 +++++++++++++++++++++++++++
tests/xfs/180 | 1 +
tests/xfs/182 | 1 +
tests/xfs/184 | 1 +
tests/xfs/192 | 1 +
tests/xfs/200 | 1 +
tests/xfs/204 | 1 +
tests/xfs/208 | 1 +
tests/xfs/315 | 1 +
tests/xfs/326 | 6 ++++++
10 files changed, 41 insertions(+)
diff --git a/common/reflink b/common/reflink
index 22adc4449b..1082642e4e 100644
--- a/common/reflink
+++ b/common/reflink
@@ -521,3 +521,30 @@ _sweave_reflink_rainbow_delalloc() {
_pwrite_byte 0x62 $((blksz * i)) $blksz $dfile.chk
done
}
+
+# Require that the COW extent size hint can actually be used to combat
+# fragmentation on the scratch filesystem. This is (so far) true for any
+# filesystem except for the ones where the realtime extent size is larger
+# than one fs block, for it is assumed that setting a rt extent size is the
+# preferred fragmentation avoidance strategy.
+_require_scratch_cowextsize_useful() {
+ local testfile=$SCRATCH_MNT/hascowextsize
+ local param="${1:-1m}"
+
+ rm -f $testfile
+ touch $testfile
+ local before="$($XFS_IO_PROG -c 'cowextsize' $testfile)"
+
+ $XFS_IO_PROG -c "cowextsize $param" $testfile
+ local after="$($XFS_IO_PROG -c 'cowextsize' $testfile)"
+ rm -f $testfile
+
+ test "$before" != "$after" || \
+ _notrun "setting cowextsize to $param had no effect"
+
+ local fileblocksize=$(_get_file_block_size $SCRATCH_MNT)
+ local fsblocksize=$(_get_block_size $SCRATCH_MNT)
+
+ test $fsblocksize -eq $fileblocksize || \
+ _notrun "XFS does not support cowextsize when rt extsize ($fileblocksize) > 1FSB ($fsblocksize)"
+}
diff --git a/tests/xfs/180 b/tests/xfs/180
index d2fac03a9e..e8e04062a8 100755
--- a/tests/xfs/180
+++ b/tests/xfs/180
@@ -38,6 +38,7 @@ nr=128
filesize=$((blksz * nr))
bufnr=16
bufsize=$((blksz * bufnr))
+_require_scratch_cowextsize_useful $bufsize
_require_fs_space $SCRATCH_MNT $((filesize / 1024 * 3 * 5 / 4))
real_blksz=$(_get_block_size $testdir)
diff --git a/tests/xfs/182 b/tests/xfs/182
index 511aca6f2d..7c0713b248 100755
--- a/tests/xfs/182
+++ b/tests/xfs/182
@@ -39,6 +39,7 @@ nr=128
filesize=$((blksz * nr))
bufnr=16
bufsize=$((blksz * bufnr))
+_require_scratch_cowextsize_useful $bufsize
_require_fs_space $SCRATCH_MNT $((filesize / 1024 * 3 * 5 / 4))
real_blksz=$(_get_block_size $testdir)
diff --git a/tests/xfs/184 b/tests/xfs/184
index 97f529f666..b2b4da6024 100755
--- a/tests/xfs/184
+++ b/tests/xfs/184
@@ -40,6 +40,7 @@ nr=128
filesize=$((blksz * nr))
bufnr=16
bufsize=$((blksz * bufnr))
+_require_scratch_cowextsize_useful $bufsize
_require_fs_space $SCRATCH_MNT $((filesize / 1024 * 3 * 5 / 4))
real_blksz=$(_get_block_size $testdir)
diff --git a/tests/xfs/192 b/tests/xfs/192
index ef7da55be5..0017597280 100755
--- a/tests/xfs/192
+++ b/tests/xfs/192
@@ -42,6 +42,7 @@ nr=128
filesize=$((blksz * nr))
bufnr=16
bufsize=$((blksz * bufnr))
+_require_scratch_cowextsize_useful $bufsize
_require_fs_space $SCRATCH_MNT $((filesize / 1024 * 3 * 5 / 4))
real_blksz=$(_get_block_size $testdir)
diff --git a/tests/xfs/200 b/tests/xfs/200
index a9d6ce1bb6..500564d9a8 100755
--- a/tests/xfs/200
+++ b/tests/xfs/200
@@ -42,6 +42,7 @@ nr=128
filesize=$((blksz * nr))
bufnr=16
bufsize=$((blksz * bufnr))
+_require_scratch_cowextsize_useful $bufsize
_require_fs_space $SCRATCH_MNT $((filesize / 1024 * 3 * 5 / 4))
real_blksz=$(_get_block_size $testdir)
diff --git a/tests/xfs/204 b/tests/xfs/204
index 7dacfa2de7..8cbdd6513f 100755
--- a/tests/xfs/204
+++ b/tests/xfs/204
@@ -44,6 +44,7 @@ nr=128
filesize=$((blksz * nr))
bufnr=16
bufsize=$((blksz * bufnr))
+_require_scratch_cowextsize_useful $bufsize
_require_fs_space $SCRATCH_MNT $((filesize / 1024 * 3 * 5 / 4))
real_blksz=$(_get_block_size $testdir)
diff --git a/tests/xfs/208 b/tests/xfs/208
index 1e7734b822..0d2401b908 100755
--- a/tests/xfs/208
+++ b/tests/xfs/208
@@ -41,6 +41,7 @@ nr=128
filesize=$((blksz * nr))
bufnr=16
bufsize=$((blksz * bufnr))
+_require_scratch_cowextsize_useful $bufsize
_require_fs_space $SCRATCH_MNT $((filesize / 1024 * 3 * 5 / 4))
real_blksz=$(_get_file_block_size $testdir)
diff --git a/tests/xfs/315 b/tests/xfs/315
index 9f6b39c8cc..3a618a3680 100755
--- a/tests/xfs/315
+++ b/tests/xfs/315
@@ -38,6 +38,7 @@ echo "Format filesystem"
_scratch_mkfs >/dev/null 2>&1
_scratch_mount >> $seqres.full
_require_congruent_file_oplen $SCRATCH_MNT $blksz
+_require_scratch_cowextsize_useful $sz
$XFS_IO_PROG -c "cowextsize $sz" $SCRATCH_MNT
diff --git a/tests/xfs/326 b/tests/xfs/326
index ac620fc433..a3fed8b6ac 100755
--- a/tests/xfs/326
+++ b/tests/xfs/326
@@ -55,6 +55,12 @@ $XFS_IO_PROG -c "cowextsize $sz" $SCRATCH_MNT
# staging extent for an unshared extent and trips over the injected error.
_require_no_xfs_always_cow
+# This test uses a very large cowextszhint to manipulate the COW fork to
+# contain a large unwritten extent before injecting the error. XFS ignores
+# cowextsize when the realtime extent size is greater than 1FSB, so this test
+# cannot set up the preconditions for the test.
+_require_scratch_cowextsize_useful $sz
+
echo "Create files"
_pwrite_byte 0x66 0 $sz $SCRATCH_MNT/file1 >> $seqres.full
_cp_reflink $SCRATCH_MNT/file1 $SCRATCH_MNT/file2
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 3/5] misc: add more congruent oplen testing
2023-12-31 20:01 ` [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents Darrick J. Wong
2023-12-27 14:04 ` [PATCH 1/5] xfs: make sure that CoW will write around when rextsize > 1 Darrick J. Wong
2023-12-27 14:04 ` [PATCH 2/5] xfs: skip cowextsize hint fragmentation tests on realtime volumes Darrick J. Wong
@ 2023-12-27 14:04 ` Darrick J. Wong
2023-12-27 14:05 ` [PATCH 4/5] xfs: test COWing entire rt extents Darrick J. Wong
2023-12-27 14:05 ` [PATCH 5/5] generic/303: avoid test failures on weird rt extent sizes Darrick J. Wong
4 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:04 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Do more checking for file allocation operation op length congruency.
This prevents tests from failing with EINVAL when the realtime extent
size is something weird like 28k or 1GB.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/generic/145 | 1 +
tests/generic/147 | 1 +
tests/generic/261 | 1 +
tests/generic/262 | 1 +
tests/generic/331 | 1 +
tests/generic/353 | 2 +-
tests/generic/517 | 1 +
tests/generic/657 | 1 +
tests/generic/658 | 1 +
tests/generic/659 | 1 +
tests/generic/660 | 1 +
tests/generic/663 | 1 +
tests/generic/664 | 1 +
tests/generic/665 | 1 +
tests/generic/670 | 1 +
tests/generic/672 | 1 +
tests/xfs/420 | 3 +++
tests/xfs/421 | 3 +++
tests/xfs/792 | 1 +
19 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/tests/generic/145 b/tests/generic/145
index f213f53be8..81fc5f6c2f 100755
--- a/tests/generic/145
+++ b/tests/generic/145
@@ -36,6 +36,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $TEST_DIR $blksz
_pwrite_byte 0x61 0 $blksz $testdir/file1 >> $seqres.full
_pwrite_byte 0x62 $blksz $blksz $testdir/file1 >> $seqres.full
_pwrite_byte 0x63 $((blksz * 2)) $blksz $testdir/file1 >> $seqres.full
diff --git a/tests/generic/147 b/tests/generic/147
index 113800944b..bb17bb1c0b 100755
--- a/tests/generic/147
+++ b/tests/generic/147
@@ -35,6 +35,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $TEST_DIR $blksz
_pwrite_byte 0x61 0 $blksz $testdir/file1 >> $seqres.full
_pwrite_byte 0x62 $blksz $blksz $testdir/file1 >> $seqres.full
_pwrite_byte 0x63 $((blksz * 2)) $blksz $testdir/file1 >> $seqres.full
diff --git a/tests/generic/261 b/tests/generic/261
index 93c1c349b1..deb360288e 100755
--- a/tests/generic/261
+++ b/tests/generic/261
@@ -29,6 +29,7 @@ testdir=$SCRATCH_MNT/test-$seq
mkdir $testdir
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=5
filesize=$((blksz * nr))
diff --git a/tests/generic/262 b/tests/generic/262
index 46e88f8731..f296e37e02 100755
--- a/tests/generic/262
+++ b/tests/generic/262
@@ -29,6 +29,7 @@ testdir=$SCRATCH_MNT/test-$seq
mkdir $testdir
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=4
filesize=$((blksz * nr))
diff --git a/tests/generic/331 b/tests/generic/331
index 8c665ce4fc..9b6801e16f 100755
--- a/tests/generic/331
+++ b/tests/generic/331
@@ -38,6 +38,7 @@ testdir=$SCRATCH_MNT/test-$seq
mkdir $testdir
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=640
bufnr=128
filesize=$((blksz * nr))
diff --git a/tests/generic/353 b/tests/generic/353
index c563972510..6dbb0d4c24 100755
--- a/tests/generic/353
+++ b/tests/generic/353
@@ -30,7 +30,7 @@ _scratch_mkfs > /dev/null 2>&1
_scratch_mount
blocksize=$(_get_file_block_size $SCRATCH_MNT)
-
+_require_congruent_file_oplen $SCRATCH_MNT $blocksize
file1="$SCRATCH_MNT/file1"
file2="$SCRATCH_MNT/file2"
extmap1="$SCRATCH_MNT/extmap1"
diff --git a/tests/generic/517 b/tests/generic/517
index cf3031ed2d..229358d06b 100755
--- a/tests/generic/517
+++ b/tests/generic/517
@@ -21,6 +21,7 @@ _require_scratch_dedupe
_scratch_mkfs >>$seqres.full 2>&1
_scratch_mount
+_require_congruent_file_oplen $SCRATCH_MNT 65536
# The first byte with a value of 0xae starts at an offset (512Kb + 100) which is
# not a multiple of the block size.
diff --git a/tests/generic/657 b/tests/generic/657
index e0fecd544c..9f4673dda3 100755
--- a/tests/generic/657
+++ b/tests/generic/657
@@ -30,6 +30,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=64
filesize=$((blksz * nr))
_pwrite_byte 0x61 0 $filesize $testdir/file1 >> $seqres.full
diff --git a/tests/generic/658 b/tests/generic/658
index a5cbadaaa5..e9519c25e2 100755
--- a/tests/generic/658
+++ b/tests/generic/658
@@ -31,6 +31,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=64
filesize=$((blksz * nr))
_weave_reflink_regular $blksz $nr $testdir/file1 $testdir/file3 >> $seqres.full
diff --git a/tests/generic/659 b/tests/generic/659
index ccc2d7950d..05436edfab 100755
--- a/tests/generic/659
+++ b/tests/generic/659
@@ -31,6 +31,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=64
filesize=$((blksz * nr))
_weave_reflink_unwritten $blksz $nr $testdir/file1 $testdir/file3 >> $seqres.full
diff --git a/tests/generic/660 b/tests/generic/660
index bc17dc5e59..52b0d1ea9e 100755
--- a/tests/generic/660
+++ b/tests/generic/660
@@ -31,6 +31,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=64
filesize=$((blksz * nr))
_weave_reflink_holes $blksz $nr $testdir/file1 $testdir/file3 >> $seqres.full
diff --git a/tests/generic/663 b/tests/generic/663
index 658a5b7004..692c77b745 100755
--- a/tests/generic/663
+++ b/tests/generic/663
@@ -32,6 +32,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=64
filesize=$((blksz * nr))
_sweave_reflink_regular $blksz $nr $testdir/file1 $testdir/file3 >> $seqres.full
diff --git a/tests/generic/664 b/tests/generic/664
index 3009101fdc..40fb8c6d92 100755
--- a/tests/generic/664
+++ b/tests/generic/664
@@ -34,6 +34,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=64
filesize=$((blksz * nr))
_sweave_reflink_unwritten $blksz $nr $testdir/file1 $testdir/file3 >> $seqres.full
diff --git a/tests/generic/665 b/tests/generic/665
index 86ba578720..ee511755e6 100755
--- a/tests/generic/665
+++ b/tests/generic/665
@@ -34,6 +34,7 @@ mkdir $testdir
echo "Create the original files"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=64
filesize=$((blksz * nr))
_sweave_reflink_holes $blksz $nr $testdir/file1 $testdir/file3 >> $seqres.full
diff --git a/tests/generic/670 b/tests/generic/670
index 67de167405..80f9fe6d4f 100755
--- a/tests/generic/670
+++ b/tests/generic/670
@@ -31,6 +31,7 @@ mkdir $testdir
loops=512
nr_loops=$((loops - 1))
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
echo "Initialize files"
echo >> $seqres.full
diff --git a/tests/generic/672 b/tests/generic/672
index 9e3a97ec5e..0710a04294 100755
--- a/tests/generic/672
+++ b/tests/generic/672
@@ -30,6 +30,7 @@ mkdir $testdir
loops=1024
nr_loops=$((loops - 1))
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
echo "Initialize files"
echo >> $seqres.full
diff --git a/tests/xfs/420 b/tests/xfs/420
index d38772c9d9..51f87bc304 100755
--- a/tests/xfs/420
+++ b/tests/xfs/420
@@ -69,6 +69,9 @@ exercise_lseek() {
}
blksz=65536
+# Golden output encodes SEEK_HOLE/DATA output, which depends on COW only
+# happening on $blksz granularity
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=8
filesize=$((blksz * nr))
diff --git a/tests/xfs/421 b/tests/xfs/421
index 027ae47c21..429333e349 100755
--- a/tests/xfs/421
+++ b/tests/xfs/421
@@ -51,6 +51,9 @@ testdir=$SCRATCH_MNT/test-$seq
mkdir $testdir
blksz=65536
+# Golden output encodes SEEK_HOLE/DATA output, which depends on COW only
+# happening on $blksz granularity
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
nr=8
filesize=$((blksz * nr))
diff --git a/tests/xfs/792 b/tests/xfs/792
index bfbfbce4aa..bfbfd8bfbc 100755
--- a/tests/xfs/792
+++ b/tests/xfs/792
@@ -32,6 +32,7 @@ _require_xfs_io_error_injection "bmap_finish_one"
_scratch_mkfs >> $seqres.full
_scratch_mount
+_require_congruent_file_oplen $SCRATCH_MNT 65536
# Create original file
_pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 4/5] xfs: test COWing entire rt extents
2023-12-31 20:01 ` [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents Darrick J. Wong
` (2 preceding siblings ...)
2023-12-27 14:04 ` [PATCH 3/5] misc: add more congruent oplen testing Darrick J. Wong
@ 2023-12-27 14:05 ` Darrick J. Wong
2023-12-27 14:05 ` [PATCH 5/5] generic/303: avoid test failures on weird rt extent sizes Darrick J. Wong
4 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:05 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
For XFS filesystems with a realtime volume, an extent size larger than
1FSB, and reflink enabled, we use a "COW around" strategy that detects
file writes that are not aligned to the rt extent size and enlarges
those writes to dirty enough page cache so that the entire rt extent can
be COWed all at once. This is a functional test to make sure that all
works properly.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
tests/xfs/1926 | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1926.out | 2 +
2 files changed, 179 insertions(+)
create mode 100755 tests/xfs/1926
create mode 100644 tests/xfs/1926.out
diff --git a/tests/xfs/1926 b/tests/xfs/1926
new file mode 100755
index 0000000000..91b611f59d
--- /dev/null
+++ b/tests/xfs/1926
@@ -0,0 +1,177 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2023-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1926
+#
+# Functional testing for COWing around realtime extents.
+#
+. ./common/preamble
+_begin_fstest auto clone realtime rw
+
+_cleanup()
+{
+ cd /
+ rm -r -f $tmp.* $testdir
+}
+
+. ./common/reflink
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_require_test
+_require_test_reflink
+_require_cp_reflink
+
+alloc_unit=$(_get_file_block_size $TEST_DIR)
+blksz=$(_get_block_size $TEST_DIR)
+
+testdir="$TEST_DIR/test-$seq"
+mkdir "$testdir"
+
+filesize="$(( (alloc_unit * 5 / 2) + 512))"
+origfile="$testdir/a"
+testfile0="$testdir/a0"
+testfile1="$testdir/a1"
+testfile2="$testdir/a2"
+testfile3="$testdir/a3"
+testfile4="$testdir/a4"
+testfile5="$testdir/a5"
+testfile6="$testdir/a6"
+testfile7="$testdir/a7"
+testfile8="$testdir/a8"
+testfile9="$testdir/a9"
+testfileA="$testdir/aA"
+testfileB="$testdir/aB"
+
+goldfile0="$testdir/g0"
+goldfile1="$testdir/g1"
+goldfile2="$testdir/g2"
+goldfile3="$testdir/g3"
+goldfile4="$testdir/g4"
+goldfile5="$testdir/g5"
+
+orig_cmd="pwrite -S 0x58 -b 1m 0 $filesize"
+$XFS_IO_PROG -f -c "$orig_cmd" -c fsync "$origfile" >> $seqres.full
+
+_cp_reflink "$origfile" "$testfile0"
+_cp_reflink "$origfile" "$testfile1"
+_cp_reflink "$origfile" "$testfile2"
+_cp_reflink "$origfile" "$testfile3"
+_cp_reflink "$origfile" "$testfile4"
+_cp_reflink "$origfile" "$testfile5"
+_cp_reflink "$origfile" "$testfile6"
+_cp_reflink "$origfile" "$testfile7"
+_cp_reflink "$origfile" "$testfile8"
+_cp_reflink "$origfile" "$testfile9"
+_cp_reflink "$origfile" "$testfileA"
+_cp_reflink "$origfile" "$testfileB"
+
+# First we try a partial ovewrite below EOF
+cmd="pwrite -S 0x59 -b 1m -W 512 512"
+_kernlog "********** buffered write below eof goldfile0"
+$XFS_IO_PROG -c "$cmd" "$testfile0" >> $seqres.full
+_kernlog "********** direct write below eof goldfile0"
+$XFS_IO_PROG -d -c "$cmd" "$testfile1" >> $seqres.full
+_kernlog "********** goldfile0"
+$XFS_IO_PROG -f -c "$orig_cmd" -c "$cmd" -c fsync "$goldfile0" >> $seqres.full
+
+# Next we try an appending write at EOF
+_kernlog "********** appending buffered write goldfile1"
+cmd="pwrite -S 0x5a -b 1m -W $filesize 512"
+$XFS_IO_PROG -c "$cmd" "$testfile2" >> $seqres.full
+_kernlog "********** appending direct write goldfile1"
+$XFS_IO_PROG -d -c "$cmd" "$testfile3" >> $seqres.full
+_kernlog "********** goldfile1"
+$XFS_IO_PROG -f -c "$orig_cmd" -c "$cmd" -c fsync "$goldfile1" >> $seqres.full
+
+# Third we try a pure overwrite of the second block
+_kernlog "********** buffered overwrite second block goldfile2"
+cmd="pwrite -S 0x5b -b 1m -W $alloc_unit $alloc_unit"
+$XFS_IO_PROG -c "$cmd" "$testfile4" >> $seqres.full
+_kernlog "********** direct overwrite second block goldfile2"
+$XFS_IO_PROG -d -c "$cmd" "$testfile5" >> $seqres.full
+_kernlog "********** goldfile2"
+$XFS_IO_PROG -f -c "$orig_cmd" -c "$cmd" -c fsync "$goldfile2" >> $seqres.full
+
+# Fourth we try a small write well beyond EOF
+_kernlog "********** buffered write beyond eof block goldfile3"
+cmd="pwrite -S 0x5c -b 1m -W $(( (filesize * 2) + 512)) 512"
+$XFS_IO_PROG -c "$cmd" "$testfile6" >> $seqres.full
+_kernlog "********** direct write beyond eof block goldfile3"
+$XFS_IO_PROG -d -c "$cmd" "$testfile7" >> $seqres.full
+_kernlog "********** goldfile3"
+$XFS_IO_PROG -f -c "$orig_cmd" -c "$cmd" -c fsync "$goldfile3" >> $seqres.full
+
+# Fifth we try a large write well beyond EOF
+_kernlog "********** buffered write beyond eof block goldfile4"
+cmd="pwrite -S 0x5d -b 1m -W $(( ((filesize * 2) + 512) & ~(alloc_unit - 1) )) $alloc_unit"
+$XFS_IO_PROG -c "$cmd" "$testfile8" >> $seqres.full
+_kernlog "********** direct write beyond eof block goldfile4"
+$XFS_IO_PROG -d -c "$cmd" "$testfile9" >> $seqres.full
+_kernlog "********** goldfile3"
+$XFS_IO_PROG -f -c "$orig_cmd" -c "$cmd" -c fsync "$goldfile4" >> $seqres.full
+
+# Sixth we try a pure overwrite of the second fsblock
+_kernlog "********** buffered overwrite second fsblock goldfile5"
+cmd="pwrite -S 0x5b -b 1m -W $blksz $alloc_unit"
+$XFS_IO_PROG -c "$cmd" "$testfileA" >> $seqres.full
+_kernlog "********** direct overwrite second fsblock goldfile5"
+$XFS_IO_PROG -d -c "$cmd" "$testfileB" >> $seqres.full
+_kernlog "********** goldfile5"
+$XFS_IO_PROG -f -c "$orig_cmd" -c "$cmd" -c fsync "$goldfile5" >> $seqres.full
+
+_kernlog "********** done"
+
+corruption_noted=
+
+note_corruption() {
+ local fname="$1"
+
+ echo "$fname is bad"
+
+ if [ -z "$corruption_noted" ]; then
+ corruption_noted=1
+ echo "origfile" >> $seqres.full
+ od -tx1 -Ad -c "$origfile" >> $seqres.full
+ fi
+
+ echo "$fname" >> $seqres.full
+ od -tx1 -Ad -c "$testfile1" >> $seqres.full
+}
+
+echo "before remount" >> $seqres.full
+cmp -s "$goldfile0" "$testfile0" || note_corruption "$testfile0"
+cmp -s "$goldfile0" "$testfile1" || note_corruption "$testfile1"
+cmp -s "$goldfile1" "$testfile2" || note_corruption "$testfile2"
+cmp -s "$goldfile1" "$testfile3" || note_corruption "$testfile3"
+cmp -s "$goldfile2" "$testfile4" || note_corruption "$testfile4"
+cmp -s "$goldfile2" "$testfile5" || note_corruption "$testfile5"
+cmp -s "$goldfile3" "$testfile6" || note_corruption "$testfile6"
+cmp -s "$goldfile3" "$testfile7" || note_corruption "$testfile7"
+cmp -s "$goldfile4" "$testfile8" || note_corruption "$testfile8"
+cmp -s "$goldfile4" "$testfile9" || note_corruption "$testfile9"
+cmp -s "$goldfile5" "$testfileA" || note_corruption "$testfileA"
+cmp -s "$goldfile5" "$testfileB" || note_corruption "$testfileB"
+
+_test_cycle_mount
+
+echo "after remount" >> $seqres.full
+cmp -s "$goldfile0" "$testfile0" || note_corruption "$testfile0"
+cmp -s "$goldfile0" "$testfile1" || note_corruption "$testfile1"
+cmp -s "$goldfile1" "$testfile2" || note_corruption "$testfile2"
+cmp -s "$goldfile1" "$testfile3" || note_corruption "$testfile3"
+cmp -s "$goldfile2" "$testfile4" || note_corruption "$testfile4"
+cmp -s "$goldfile2" "$testfile5" || note_corruption "$testfile5"
+cmp -s "$goldfile3" "$testfile6" || note_corruption "$testfile6"
+cmp -s "$goldfile3" "$testfile7" || note_corruption "$testfile7"
+cmp -s "$goldfile4" "$testfile8" || note_corruption "$testfile8"
+cmp -s "$goldfile4" "$testfile9" || note_corruption "$testfile9"
+cmp -s "$goldfile5" "$testfileA" || note_corruption "$testfileA"
+cmp -s "$goldfile5" "$testfileB" || note_corruption "$testfileB"
+
+echo Silence is golden
+status=0
+exit
diff --git a/tests/xfs/1926.out b/tests/xfs/1926.out
new file mode 100644
index 0000000000..a56601b969
--- /dev/null
+++ b/tests/xfs/1926.out
@@ -0,0 +1,2 @@
+QA output created by 1926
+Silence is golden
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 5/5] generic/303: avoid test failures on weird rt extent sizes
2023-12-31 20:01 ` [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents Darrick J. Wong
` (3 preceding siblings ...)
2023-12-27 14:05 ` [PATCH 4/5] xfs: test COWing entire rt extents Darrick J. Wong
@ 2023-12-27 14:05 ` Darrick J. Wong
4 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:05 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Fix this test to skip the high offset reflink test if (on XFS) the rt
extent size isn't congruent with the chosen target offset.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/rc | 23 +++++++++++++++++++++++
tests/generic/303 | 8 +++++++-
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/common/rc b/common/rc
index f760eedc26..2d67f7dff1 100644
--- a/common/rc
+++ b/common/rc
@@ -4690,6 +4690,29 @@ _get_file_block_size()
esac
}
+_test_congruent_file_oplen()
+{
+ local file="$1"
+ local alloc_unit=$(_get_file_block_size "$file")
+ local oplen="$2"
+
+ case $FSTYP in
+ nfs*|cifs|9p|virtiofs|ceph|glusterfs|overlay|pvfs2)
+ # Network filesystems don't know about (or tell the client
+ # about) the underlying file allocation unit and they generally
+ # pass the file IO request to the underlying filesystem, so we
+ # don't have anything to check here.
+ return
+ ;;
+ esac
+
+ if [ $alloc_unit -gt $oplen ]; then
+ return 1
+ fi
+ test $((oplen % alloc_unit)) -eq 0 || return 1
+ return 0
+}
+
# Given a file path and a byte length of a file operation under test, ensure
# that the length is an integer multiple of the file's allocation unit size.
# In other words, skip the test unless (oplen ≡ alloc_unit mod 0). This is
diff --git a/tests/generic/303 b/tests/generic/303
index 95679569e4..ef88d2357b 100755
--- a/tests/generic/303
+++ b/tests/generic/303
@@ -48,7 +48,13 @@ echo "Reflink past maximum file size in dest file (should fail)"
_reflink_range $testdir/file1 0 $testdir/file5 4611686018427322368 $len >> $seqres.full
echo "Reflink high offset to low offset"
-_reflink_range $testdir/file1 $bigoff_64k $testdir/file6 1048576 65535 >> $seqres.full
+oplen=1048576
+if _test_congruent_file_oplen $testdir $oplen; then
+ _reflink_range $testdir/file1 $bigoff_64k $testdir/file6 $oplen 65535 >> $seqres.full
+else
+ # If we can't do the ficlonerange test, fake it in the output file
+ $XFS_IO_PROG -f -c 'pwrite -S 0x61 1114110 1' $testdir/file6 >> $seqres.full
+fi
echo "Reflink past source file EOF (should fail)"
_reflink_range $testdir/file2 524288 $testdir/file7 0 1048576 >> $seqres.full
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 1/3] common: enable testing of realtime quota when supported
2023-12-31 20:02 ` [PATCHSET v2.0 9/9] fstests: functional tests for rt quota Darrick J. Wong
@ 2023-12-27 14:05 ` Darrick J. Wong
2023-12-27 14:05 ` [PATCH 2/3] xfs: fix quota tests to adapt to realtime quota Darrick J. Wong
2023-12-27 14:06 ` [PATCH 3/3] xfs: regression testing of quota on the realtime device Darrick J. Wong
2 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:05 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
If the kernel advertises realtime quota support, test it.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/populate | 2 +-
common/quota | 12 ++++++------
common/xfs | 12 ++++++++++++
3 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/common/populate b/common/populate
index 1e51eedddc..538cbc86fc 100644
--- a/common/populate
+++ b/common/populate
@@ -240,7 +240,7 @@ _populate_xfs_qmount_option()
if [ ! -f /proc/fs/xfs/xqmstat ]; then
# No quota support
return
- elif [ "${USE_EXTERNAL}" = "yes" ] && [ ! -z "${SCRATCH_RTDEV}" ]; then
+ elif [ "${USE_EXTERNAL}" = "yes" ] && [ ! -z "${SCRATCH_RTDEV}" ] && ! _xfs_supports_rtquota; then
# Quotas not supported on rt filesystems
return
elif [ -z "${XFS_QUOTA_PROG}" ]; then
diff --git a/common/quota b/common/quota
index 6b529bf4b4..565057d932 100644
--- a/common/quota
+++ b/common/quota
@@ -23,10 +23,10 @@ _require_quota()
if [ ! -f /proc/fs/xfs/xqmstat ]; then
_notrun "Installed kernel does not support XFS quotas"
fi
- if [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ]; then
+ if [ "$USE_EXTERNAL" = yes ] && [ -n "$TEST_RTDEV" ] && ! _xfs_supports_rtquota; then
_notrun "Quotas not supported on realtime test device"
fi
- if [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ]; then
+ if [ "$USE_EXTERNAL" = yes ] && [ -n "$SCRATCH_RTDEV" ] && ! _xfs_supports_rtquota; then
_notrun "Quotas not supported on realtime scratch device"
fi
;;
@@ -44,10 +44,10 @@ _require_xfs_quota()
{
$here/src/feature -q $TEST_DEV
[ $? -ne 0 ] && _notrun "Installed kernel does not support XFS quota"
- if [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ]; then
+ if [ "$USE_EXTERNAL" = yes ] && [ -n "$TEST_RTDEV" ] && ! _xfs_supports_rtquota; then
_notrun "Quotas not supported on realtime test device"
fi
- if [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ]; then
+ if [ "$USE_EXTERNAL" = yes ] && [ -n "$SCRATCH_RTDEV" ] && ! _xfs_supports_rtquota; then
_notrun "Quotas not supported on realtime scratch device"
fi
[ -n "$XFS_QUOTA_PROG" ] || _notrun "XFS quota user tools not installed"
@@ -153,8 +153,8 @@ _require_prjquota()
fi
$here/src/feature -P $_dev
[ $? -ne 0 ] && _notrun "Installed kernel does not support project quotas"
- if [ "$USE_EXTERNAL" = yes ]; then
- if [ -n "$TEST_RTDEV" -o -n "$SCRATCH_RTDEV" ]; then
+ if [ "$FSTYP" = "xfs" ] && [ "$USE_EXTERNAL" = yes ]; then
+ if [ -n "$TEST_RTDEV" -o -n "$SCRATCH_RTDEV" ] && ! _xfs_supports_rtquota; then
_notrun "Project quotas not supported on realtime filesystem"
fi
fi
diff --git a/common/xfs b/common/xfs
index 69a0eb620c..56c4b20889 100644
--- a/common/xfs
+++ b/common/xfs
@@ -2194,3 +2194,15 @@ _scratch_find_rt_metadir_entry() {
return 1
}
+
+_xfs_supports_rtquota() {
+ test "$FSTYP" = "xfs" || return 1
+
+ local xqmfile="/proc/fs/xfs/xqm"
+
+ test -e "$xqmfile" || modprobe xfs
+ test -e "$xqmfile" || return 1
+
+ local rtquota="$(cat "$xqmfile" | awk '{print $5}')"
+ test "$rtquota" = "1"
+}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 2/3] xfs: fix quota tests to adapt to realtime quota
2023-12-31 20:02 ` [PATCHSET v2.0 9/9] fstests: functional tests for rt quota Darrick J. Wong
2023-12-27 14:05 ` [PATCH 1/3] common: enable testing of realtime quota when supported Darrick J. Wong
@ 2023-12-27 14:05 ` Darrick J. Wong
2023-12-27 14:06 ` [PATCH 3/3] xfs: regression testing of quota on the realtime device Darrick J. Wong
2 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:05 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Fix or limit the scope of tests so that we can turn on testing for
realtime quotas.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/quota | 22 ++++++++++++++++++++++
tests/generic/219 | 1 +
tests/generic/230 | 1 +
tests/generic/305 | 1 +
tests/generic/326 | 1 +
tests/generic/327 | 1 +
tests/generic/328 | 1 +
tests/generic/566 | 4 +++-
tests/generic/587 | 1 +
tests/generic/603 | 1 +
tests/generic/691 | 2 ++
tests/generic/710 | 4 +++-
tests/xfs/050 | 2 ++
tests/xfs/106 | 1 +
tests/xfs/108 | 2 ++
tests/xfs/152 | 1 +
tests/xfs/153 | 2 ++
tests/xfs/161 | 2 ++
tests/xfs/213 | 1 +
tests/xfs/214 | 1 +
tests/xfs/220 | 2 ++
tests/xfs/299 | 2 ++
tests/xfs/330 | 1 +
tests/xfs/434 | 1 +
tests/xfs/435 | 1 +
tests/xfs/441 | 1 +
tests/xfs/442 | 1 +
tests/xfs/508 | 2 ++
tests/xfs/511 | 10 +++++++++-
tests/xfs/720 | 5 +++++
30 files changed, 75 insertions(+), 3 deletions(-)
diff --git a/common/quota b/common/quota
index 565057d932..06179eb8c8 100644
--- a/common/quota
+++ b/common/quota
@@ -467,5 +467,27 @@ _restore_project_quota()
fi
}
+# Reconfigure the mounted fs as needed so that we can test the VFS quota
+# utilities. They do not support realtime block limits or reporting, so
+# we forcibly inhibit rtinherit on XFS filesystems.
+_force_vfs_quota_testing()
+{
+ local mount="${1:-$TEST_DIR}"
+
+ test "$FSTYP" = "xfs" && _xfs_force_bdev data "$mount"
+}
+
+# Does the scratch filesystem have a realtime volume wherein quota works?
+_scratch_supports_rtquota()
+{
+ if [ "$FSTYP" = "xfs" ]; then
+ test "$USE_EXTERNAL" = yes && \
+ test -n "$SCRATCH_RTDEV" && \
+ _xfs_supports_rtquota
+ else
+ return 1
+ fi
+}
+
# make sure this script returns success
/bin/true
diff --git a/tests/generic/219 b/tests/generic/219
index 71da25e352..a38dc7d84a 100755
--- a/tests/generic/219
+++ b/tests/generic/219
@@ -83,6 +83,7 @@ test_accounting()
_scratch_unmount 2>/dev/null
_scratch_mkfs >> $seqres.full 2>&1
_scratch_mount "-o usrquota,grpquota"
+_force_vfs_quota_testing $SCRATCH_MNT
quotacheck -u -g $SCRATCH_MNT 2>/dev/null
quotaon $SCRATCH_MNT 2>/dev/null
_scratch_unmount
diff --git a/tests/generic/230 b/tests/generic/230
index e49e0da25c..8a0aac1e7b 100755
--- a/tests/generic/230
+++ b/tests/generic/230
@@ -103,6 +103,7 @@ _qmount_option 'defaults'
_scratch_mkfs >> $seqres.full 2>&1
_scratch_mount "-o usrquota,grpquota"
+_force_vfs_quota_testing $SCRATCH_MNT
BLOCK_SIZE=$(_get_file_block_size $SCRATCH_MNT)
quotacheck -u -g $SCRATCH_MNT 2>/dev/null
quotaon $SCRATCH_MNT 2>/dev/null
diff --git a/tests/generic/305 b/tests/generic/305
index b46d512742..7c8f7692c1 100755
--- a/tests/generic/305
+++ b/tests/generic/305
@@ -27,6 +27,7 @@ echo "Format and mount"
_scratch_mkfs > $seqres.full 2>&1
export MOUNT_OPTIONS="-o usrquota,grpquota $MOUNT_OPTIONS"
_scratch_mount >> $seqres.full 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT
quotacheck -u -g $SCRATCH_MNT 2> /dev/null
quotaon $SCRATCH_MNT 2> /dev/null
diff --git a/tests/generic/326 b/tests/generic/326
index f5c557b3a0..b5e4100f4a 100755
--- a/tests/generic/326
+++ b/tests/generic/326
@@ -28,6 +28,7 @@ echo "Format and mount"
_scratch_mkfs > $seqres.full 2>&1
export MOUNT_OPTIONS="-o usrquota,grpquota $MOUNT_OPTIONS"
_scratch_mount >> $seqres.full 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT
quotacheck -u -g $SCRATCH_MNT 2> /dev/null
quotaon $SCRATCH_MNT 2> /dev/null
diff --git a/tests/generic/327 b/tests/generic/327
index 92540b19dd..dcdf2b3130 100755
--- a/tests/generic/327
+++ b/tests/generic/327
@@ -26,6 +26,7 @@ echo "Format and mount"
_scratch_mkfs > $seqres.full 2>&1
export MOUNT_OPTIONS="-o usrquota,grpquota $MOUNT_OPTIONS"
_scratch_mount >> $seqres.full 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT
quotacheck -u -g $SCRATCH_MNT 2> /dev/null
quotaon $SCRATCH_MNT 2> /dev/null
diff --git a/tests/generic/328 b/tests/generic/328
index db7fd3db41..26c89fff62 100755
--- a/tests/generic/328
+++ b/tests/generic/328
@@ -27,6 +27,7 @@ echo "Format and mount"
_scratch_mkfs > $seqres.full 2>&1
export MOUNT_OPTIONS="-o usrquota,grpquota $MOUNT_OPTIONS"
_scratch_mount >> $seqres.full 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT
quotacheck -u -g $SCRATCH_MNT 2> /dev/null
quotaon $SCRATCH_MNT 2> /dev/null
diff --git a/tests/generic/566 b/tests/generic/566
index 52b01f6d9e..052fabeb0e 100755
--- a/tests/generic/566
+++ b/tests/generic/566
@@ -37,7 +37,9 @@ _qmount
dir="$SCRATCH_MNT/dummy"
mkdir -p $dir
chown $qa_user $dir
-$XFS_QUOTA_PROG -x -c "limit -g bsoft=100k bhard=100k $qa_user" $SCRATCH_MNT
+_scratch_supports_rtquota && \
+ extra_limits="rtbsoft=100k rtbhard=100k"
+$XFS_QUOTA_PROG -x -c "limit -g bsoft=100k bhard=100k $extra_limits $qa_user" $SCRATCH_MNT
$XFS_IO_PROG -f -c 'pwrite -S 0x58 0 1m' $dir/foo >> $seqres.full
chown $qa_user "${dir}/foo"
diff --git a/tests/generic/587 b/tests/generic/587
index ebfeea1d17..183ec1cad7 100755
--- a/tests/generic/587
+++ b/tests/generic/587
@@ -58,6 +58,7 @@ _scratch_mkfs > $seqres.full
# This test must have user quota enabled
_qmount_option usrquota
_qmount >> $seqres.full
+_force_vfs_quota_testing $SCRATCH_MNT
testfile=$SCRATCH_MNT/test-$seq
touch $testfile
diff --git a/tests/generic/603 b/tests/generic/603
index 08ddcbf2ec..15dc2293a1 100755
--- a/tests/generic/603
+++ b/tests/generic/603
@@ -120,6 +120,7 @@ _scratch_mkfs >$seqres.full 2>&1
_scratch_enable_pquota
_qmount_option "usrquota,grpquota,prjquota"
_qmount
+_force_vfs_quota_testing $SCRATCH_MNT
_require_prjquota $SCRATCH_DEV
BLOCK_SIZE=$(_get_file_block_size $SCRATCH_MNT)
rm -rf $SCRATCH_MNT/t
diff --git a/tests/generic/691 b/tests/generic/691
index 6432834f9f..3d43ea5b04 100755
--- a/tests/generic/691
+++ b/tests/generic/691
@@ -39,6 +39,7 @@ _scratch_mkfs >$seqres.full 2>&1
_scratch_enable_pquota
_qmount_option "prjquota"
_qmount
+_force_vfs_quota_testing $SCRATCH_MNT
_require_prjquota $SCRATCH_DEV
filter_quota()
@@ -66,6 +67,7 @@ exercise()
_scratch_enable_pquota
fi
_qmount
+ _force_vfs_quota_testing $SCRATCH_MNT
if [ "$type" = "P" ];then
_create_project_quota $SCRATCH_MNT/t 100 $qa_user
file=$SCRATCH_MNT/t/testfile
diff --git a/tests/generic/710 b/tests/generic/710
index c7fca05d4c..2f793e03fb 100755
--- a/tests/generic/710
+++ b/tests/generic/710
@@ -33,7 +33,9 @@ $XFS_IO_PROG -f -c 'pwrite -S 0x59 0 64k -b 64k' -c 'truncate 256k' $SCRATCH_MNT
chown nobody $SCRATCH_MNT/b
# Set up a quota limit
-$XFS_QUOTA_PROG -x -c "limit -u bhard=70k nobody" $SCRATCH_MNT
+_scratch_supports_rtquota && \
+ extra_limits="rtbhard=70k"
+$XFS_QUOTA_PROG -x -c "limit -u bhard=70k $extra_limits nobody" $SCRATCH_MNT
echo before swapext >> $seqres.full
$XFS_QUOTA_PROG -x -c 'report -a' $SCRATCH_MNT >> $seqres.full
diff --git a/tests/xfs/050 b/tests/xfs/050
index 10294e3f6d..03cc534bc7 100755
--- a/tests/xfs/050
+++ b/tests/xfs/050
@@ -35,6 +35,7 @@ _scratch_mkfs >/dev/null 2>&1
orig_mntopts="$MOUNT_OPTIONS"
_qmount_option "uquota"
_scratch_mount
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
bsize=$(_get_file_block_size $SCRATCH_MNT)
# needs quota enabled to compute the number of metadata dir files
HIDDEN_QUOTA_FILES=$(_xfs_calc_hidden_quota_files $SCRATCH_MNT)
@@ -77,6 +78,7 @@ _exercise()
. $tmp.mkfs
_qmount
+ _force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
# Figure out whether we're doing large allocations
# (bail out if they're so large they stuff the test up)
diff --git a/tests/xfs/106 b/tests/xfs/106
index 388873bdee..9f00b3adb5 100755
--- a/tests/xfs/106
+++ b/tests/xfs/106
@@ -197,6 +197,7 @@ test_xfs_quota()
{
_qmount_option $1
_qmount
+ _force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
if [ $type == "p" ]; then
_require_prjquota $SCRATCH_DEV
diff --git a/tests/xfs/108 b/tests/xfs/108
index 8593edbdd2..7f2578aa28 100755
--- a/tests/xfs/108
+++ b/tests/xfs/108
@@ -65,6 +65,7 @@ test_accounting()
export MOUNT_OPTIONS="-opquota"
_scratch_mkfs_xfs >> $seqres.full
_qmount
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
_require_prjquota $SCRATCH_DEV
# real QA test starts here
@@ -73,6 +74,7 @@ _scratch_unmount 2>/dev/null
_scratch_mkfs_xfs | _filter_mkfs 2>$tmp.mkfs
cat $tmp.mkfs >>$seqres.full
_scratch_mount
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
uid=1
gid=2
diff --git a/tests/xfs/152 b/tests/xfs/152
index 325a05c141..f9a0bee12f 100755
--- a/tests/xfs/152
+++ b/tests/xfs/152
@@ -242,6 +242,7 @@ qmount_idmapped()
{
wipe_mounts
_try_scratch_mount || _fail "qmount failed"
+ _force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
mkdir -p "${SCRATCH_MNT}/unmapped"
mkdir -p "${SCRATCH_MNT}/idmapped"
diff --git a/tests/xfs/153 b/tests/xfs/153
index 9def579bba..304e0f11cc 100755
--- a/tests/xfs/153
+++ b/tests/xfs/153
@@ -40,6 +40,7 @@ _scratch_mkfs >/dev/null 2>&1
orig_mntopts="$MOUNT_OPTIONS"
_qmount_option "uquota"
_scratch_mount
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
bsize=$(_get_file_block_size $SCRATCH_MNT)
# needs quota enabled to compute the number of metadata dir files
HIDDEN_QUOTA_FILES=$(_xfs_calc_hidden_quota_files $SCRATCH_MNT)
@@ -82,6 +83,7 @@ run_tests()
. $tmp.mkfs
_qmount
+ _force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
# Figure out whether we're doing large allocations
# (bail out if they're so large they stuff the test up)
diff --git a/tests/xfs/161 b/tests/xfs/161
index 486fa6ca0e..57cfe5b003 100755
--- a/tests/xfs/161
+++ b/tests/xfs/161
@@ -38,6 +38,8 @@ _qmount_option "usrquota"
_scratch_xfs_db -c 'version' -c 'sb 0' -c 'p' >> $seqres.full
_scratch_mount >> $seqres.full
+_xfs_force_bdev data $SCRATCH_MNT
+
# Force the block counters for uid 1 and 2 above zero
_pwrite_byte 0x61 0 64k $SCRATCH_MNT/a >> $seqres.full
_pwrite_byte 0x61 0 64k $SCRATCH_MNT/b >> $seqres.full
diff --git a/tests/xfs/213 b/tests/xfs/213
index e184962452..7f3b1b4f4a 100755
--- a/tests/xfs/213
+++ b/tests/xfs/213
@@ -30,6 +30,7 @@ echo "Format and mount"
_scratch_mkfs > $seqres.full 2>&1
export MOUNT_OPTIONS="-o usrquota,grpquota $MOUNT_OPTIONS"
_scratch_mount >> $seqres.full 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT # repquota
quotacheck -u -g $SCRATCH_MNT 2> /dev/null
quotaon $SCRATCH_MNT 2> /dev/null
diff --git a/tests/xfs/214 b/tests/xfs/214
index 84ba838f3a..858ac7ea4b 100755
--- a/tests/xfs/214
+++ b/tests/xfs/214
@@ -31,6 +31,7 @@ echo "Format and mount"
_scratch_mkfs > $seqres.full 2>&1
export MOUNT_OPTIONS="-o usrquota,grpquota $MOUNT_OPTIONS"
_scratch_mount >> $seqres.full 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT # repquota
quotacheck -u -g $SCRATCH_MNT 2> /dev/null
quotaon $SCRATCH_MNT 2> /dev/null
diff --git a/tests/xfs/220 b/tests/xfs/220
index 88eedf5161..77008bf80b 100755
--- a/tests/xfs/220
+++ b/tests/xfs/220
@@ -39,6 +39,7 @@ _scratch_mkfs_xfs >/dev/null 2>&1
# mount with quotas enabled
_scratch_mount -o uquota
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
# turn off quota
$XFS_QUOTA_PROG -x -c off $SCRATCH_DEV
@@ -51,6 +52,7 @@ _scratch_mkfs_xfs >/dev/null 2>&1
# mount with quotas enabled
_scratch_mount -o uquota
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
# turn off quota accounting...
$XFS_QUOTA_PROG -x -c off $SCRATCH_DEV
diff --git a/tests/xfs/299 b/tests/xfs/299
index 49a6527255..84fb76120d 100755
--- a/tests/xfs/299
+++ b/tests/xfs/299
@@ -157,6 +157,7 @@ projid_file="$tmp.projid"
echo "*** user, group, and project"
_qmount_option "uquota,gquota,pquota"
_qmount
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
bsize=$(_get_file_block_size $SCRATCH_MNT)
HIDDEN_QUOTA_FILES=$(_xfs_calc_hidden_quota_files $SCRATCH_MNT)
@@ -184,6 +185,7 @@ cat $tmp.mkfs >>$seqres.full
echo "*** uqnoenforce, gqnoenforce, and pqnoenforce"
_qmount_option "uqnoenforce,gqnoenforce,pqnoenforce"
_qmount
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
_exercise uno
_exercise gno
_exercise pno
diff --git a/tests/xfs/330 b/tests/xfs/330
index 7ebbffff2a..7c18514923 100755
--- a/tests/xfs/330
+++ b/tests/xfs/330
@@ -38,6 +38,7 @@ echo "Format and mount"
_scratch_mkfs > "$seqres.full" 2>&1
export MOUNT_OPTIONS="-o usrquota,grpquota $MOUNT_OPTIONS"
_scratch_mount >> "$seqres.full" 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT # golden output encodes block usage
HIDDEN_QUOTA_FILES=$(_xfs_calc_hidden_quota_files $SCRATCH_MNT)
quotacheck -u -g $SCRATCH_MNT 2> /dev/null
quotaon $SCRATCH_MNT 2> /dev/null
diff --git a/tests/xfs/434 b/tests/xfs/434
index 12d1a0c9da..ef7652f7f3 100755
--- a/tests/xfs/434
+++ b/tests/xfs/434
@@ -47,6 +47,7 @@ _scratch_mount -o noquota >> "$seqres.full" 2>&1
testdir="$SCRATCH_MNT/test-$seq"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
blks=3
mkdir "$testdir"
diff --git a/tests/xfs/435 b/tests/xfs/435
index 44135c7653..c68d7a126a 100755
--- a/tests/xfs/435
+++ b/tests/xfs/435
@@ -38,6 +38,7 @@ _scratch_mount -o quota >> "$seqres.full" 2>&1
testdir="$SCRATCH_MNT/test-$seq"
blksz=65536
+_require_congruent_file_oplen $SCRATCH_MNT $blksz
blks=3
mkdir "$testdir"
diff --git a/tests/xfs/441 b/tests/xfs/441
index 82654bf332..04682796b5 100755
--- a/tests/xfs/441
+++ b/tests/xfs/441
@@ -32,6 +32,7 @@ check_quota() {
echo "Format and mount (noquota)"
_scratch_mkfs > "$seqres.full" 2>&1
_scratch_mount "-o noquota" >> $seqres.full 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT # _check_quota_usage uses repquota
echo "Create files"
_pwrite_byte 0x58 0 1m $SCRATCH_MNT/a >> $seqres.full
diff --git a/tests/xfs/442 b/tests/xfs/442
index b04b1c8349..4a0608a095 100755
--- a/tests/xfs/442
+++ b/tests/xfs/442
@@ -70,6 +70,7 @@ _qmount_option "usrquota,grpquota,prjquota"
# tests now have separate faster-running regression tests.
_scratch_mkfs_sized $((1600 * 1048576)) > $seqres.full 2>&1
_scratch_mount >> $seqres.full 2>&1
+_force_vfs_quota_testing $SCRATCH_MNT # _check_quota_usage uses repquota
nr_cpus=$((LOAD_FACTOR * 4))
nr_ops=$((25000 * nr_cpus * TIME_FACTOR))
diff --git a/tests/xfs/508 b/tests/xfs/508
index 47c04f89de..28d5be484c 100755
--- a/tests/xfs/508
+++ b/tests/xfs/508
@@ -59,6 +59,8 @@ _require_prjquota $SCRATCH_DEV
mkdir $SCRATCH_MNT/dir
$QUOTA_CMD -x -c 'project -s test' $SCRATCH_MNT >>$seqres.full 2>&1
$QUOTA_CMD -x -c 'limit -p bsoft=1m bhard=2m test' $SCRATCH_MNT
+_scratch_supports_rtquota && \
+ $QUOTA_CMD -x -c 'limit -p rtbsoft=1m rtbhard=2m test' $SCRATCH_MNT
# test the Project inheritance bit is a directory only flag, and it's set on
# directory by default. Expect no complain about "project inheritance flag is
diff --git a/tests/xfs/511 b/tests/xfs/511
index d2550404b0..ce7d40300c 100755
--- a/tests/xfs/511
+++ b/tests/xfs/511
@@ -40,11 +40,19 @@ $XFS_IO_PROG -f -c "pwrite 0 65536" -c sync $SCRATCH_MNT/t/file >>$seqres.full
quota_cmd="$XFS_QUOTA_PROG -x"
$quota_cmd -c "project -s -p $SCRATCH_MNT/t 42" $SCRATCH_MNT >/dev/null 2>&1
$quota_cmd -c 'limit -p isoft=53 bsoft=100m 42' $SCRATCH_MNT
+_scratch_supports_rtquota && \
+ $quota_cmd -c 'limit -p rtbsoft=100m 42' $SCRATCH_MNT
+
+# The golden output for this test was written with the assumption that the file
+# allocation unit divides 64k evenly, so the file block usage would be exactly
+# 64k. On realtime filesystems this isn't always true (e.g. -rextsize=28k) so
+# we'll accept the space usage being the same as what du reports for the file.
+file_nblocks=$(du -B 1024 $SCRATCH_MNT/t/file | awk '{print $1}')
# The itotal and size should be 53 and 102400(k), as above project quota limit.
# The isued and used should be 2 and 64(k), as this case takes.
df -k --output=file,itotal,iused,size,used $SCRATCH_MNT/t | \
- _filter_scratch | _filter_spaces
+ _filter_scratch | _filter_spaces | sed -e "s|$file_nblocks$|64|"
# success, all done
status=0
diff --git a/tests/xfs/720 b/tests/xfs/720
index 3242a19b02..e36dc23948 100755
--- a/tests/xfs/720
+++ b/tests/xfs/720
@@ -32,6 +32,11 @@ _scratch_mkfs > "$seqres.full" 2>&1
_qmount_option usrquota
_qmount
+# This test tries to exceed quota limits by creating an N>2 block bmbt, setting
+# the block limit to 2N, and rebuilding the bmbt. Hence we must force the
+# files to be created on the data device.
+_xfs_force_bdev data $SCRATCH_MNT
+
blocksize=$(_get_block_size $SCRATCH_MNT)
alloc_unit=$(_get_file_block_size $SCRATCH_MNT)
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 3/3] xfs: regression testing of quota on the realtime device
2023-12-31 20:02 ` [PATCHSET v2.0 9/9] fstests: functional tests for rt quota Darrick J. Wong
2023-12-27 14:05 ` [PATCH 1/3] common: enable testing of realtime quota when supported Darrick J. Wong
2023-12-27 14:05 ` [PATCH 2/3] xfs: fix quota tests to adapt to realtime quota Darrick J. Wong
@ 2023-12-27 14:06 ` Darrick J. Wong
2 siblings, 0 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-27 14:06 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
From: Darrick J. Wong <djwong@kernel.org>
Make sure that quota accounting and enforcement work correctly for
realtime volumes on XFS.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
common/quota | 30 +++++++++
tests/xfs/1858 | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1858.out | 41 +++++++++++++
3 files changed, 239 insertions(+)
create mode 100755 tests/xfs/1858
create mode 100644 tests/xfs/1858.out
diff --git a/common/quota b/common/quota
index 06179eb8c8..da016896ac 100644
--- a/common/quota
+++ b/common/quota
@@ -117,6 +117,36 @@ _require_xfs_quota_acct_enabled()
_notrun "$qtype: accounting not enabled on $fsname filesystem."
}
+# Decide if the mounted filesystem supports realtime quotas.
+_require_rtquota()
+{
+ local dev="$1"
+ test -z "$dev" && dev="$TEST_DEV"
+ local rtdev="$2"
+ test -z "$rtdev" && rtdev="$TEST_RTDEV"
+
+ test "$FSTYP" = "xfs" || \
+ _notrun "Realtime quota only supported on xfs"
+
+ [ -n "$XFS_QUOTA_PROG" ] || \
+ _notrun "xfs_quota user tool not installed"
+
+ $here/src/feature -q $dev || \
+ _notrun "Installed kernel does not support XFS quotas"
+
+ test -b "$rtdev" || \
+ _notrun "No realtime device supplied?"
+
+ test "$USE_EXTERNAL" = "yes" || \
+ _notrun "Realtime requires USE_EXTERNAL='yes'"
+
+ $here/src/feature -U $dev || \
+ $here/src/feature -G $dev || \
+ $here/src/feature -P $dev || \
+ _notrun "Mounted rt filesystem does not have quotas enabled"
+
+}
+
#
# checks that xfs_quota can operate on foreign (non-xfs) filesystems
# Skips check on xfs filesystems, old xfs_quota is fine there.
diff --git a/tests/xfs/1858 b/tests/xfs/1858
new file mode 100755
index 0000000000..12c9cb392a
--- /dev/null
+++ b/tests/xfs/1858
@@ -0,0 +1,168 @@
+#! /bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2022-2024 Oracle. All Rights Reserved.
+#
+# FS QA Test No. 1858
+#
+# Functional testing for realtime quotas.
+
+. ./common/preamble
+_begin_fstest auto quick quota realtime
+
+# Import common functions.
+. ./common/quota
+. ./common/filter
+
+# real QA test starts here
+_supported_fs xfs
+_require_test_program "punch-alternating"
+_require_scratch
+_require_user
+
+echo "Format filesystem" | tee -a $seqres.full
+_scratch_mkfs > $seqres.full
+_qmount_option 'usrquota'
+_qmount
+_require_rtquota $SCRATCH_DEV $SCRATCH_RTDEV
+
+# Make sure all our files are on the rt device
+_xfs_force_bdev realtime $SCRATCH_MNT
+chmod a+rwx $SCRATCH_MNT
+
+# Record rt geometry
+bmbt_blksz=$(_get_block_size $SCRATCH_MNT)
+file_blksz=$(_get_file_block_size $SCRATCH_MNT)
+rextsize=$((file_blksz / bmbt_blksz))
+echo "bmbt_blksz $bmbt_blksz" >> $seqres.full
+echo "file_blksz $file_blksz" >> $seqres.full
+echo "rextsize $rextsize" >> $seqres.full
+
+note() {
+ echo -e "\n$*" | tee -a $seqres.full
+}
+
+# Report on the user's block and rt block usage, soft limit, hard limit, and
+# warning count for rt volumes
+report_rtusage() {
+ local user="$1"
+ local timeout_arg="$2"
+ local print_timeout=0
+
+ test -z "$user" && user=$qa_user
+ test -n "$timeout_arg" && print_timeout=1
+
+ $XFS_QUOTA_PROG -c "quota -u -r -n -N $user" $SCRATCH_MNT | \
+ sed -e 's/ days/_days/g' >> $seqres.full
+
+ $XFS_QUOTA_PROG -c "quota -u -r -n -N $user" $SCRATCH_MNT | \
+ sed -e 's/ days/_days/g' | \
+ awk -v user=$user -v print_timeout=$print_timeout -v file_blksz=$file_blksz \
+ '{printf("%s[real] %d %d %d %d %s\n", user, $2 * 1024 / file_blksz, $3 * 1024 / file_blksz, $4 * 1024 / file_blksz, $5, print_timeout ? $6 : "---");}'
+}
+
+note "Write 128rx to root"
+$XFS_IO_PROG -f -c "pwrite 0 $((128 * file_blksz))" $SCRATCH_MNT/file1 > /dev/null
+chmod a+r $SCRATCH_MNT/file1
+sync
+report_rtusage 0
+
+note "Write 64rx to root, 4444, and 5555."
+$XFS_IO_PROG -f -c "pwrite 0 $((64 * file_blksz))" $SCRATCH_MNT/file3.5555 > /dev/null
+chown 5555 $SCRATCH_MNT/file3.5555
+$XFS_IO_PROG -f -c "pwrite 0 $((64 * file_blksz))" $SCRATCH_MNT/file3.4444 > /dev/null
+chown 4444 $SCRATCH_MNT/file3.4444
+$XFS_IO_PROG -f -c "pwrite 0 $((64 * file_blksz))" $SCRATCH_MNT/file3 > /dev/null
+sync
+report_rtusage 0
+report_rtusage 4444
+report_rtusage 5555
+
+note "Move 64rx from root to 5555"
+chown 5555 $SCRATCH_MNT/file3
+report_rtusage 0
+report_rtusage 4444
+report_rtusage 5555
+
+note "Move 64rx from 5555 to 4444"
+chown 4444 $SCRATCH_MNT/file3
+report_rtusage 0
+report_rtusage 4444
+report_rtusage 5555
+
+note "Set hard limit of 1024rx and check enforcement"
+$XFS_QUOTA_PROG -x -c "limit -u rtbhard=$((1024 * file_blksz)) $qa_user" $SCRATCH_MNT
+su $qa_user -c "$XFS_IO_PROG -f -c 'pwrite 0 $((2048 * file_blksz))' $SCRATCH_MNT/file2"
+report_rtusage
+
+note "Set soft limit of 512rx and check timelimit enforcement"
+rm -f $SCRATCH_MNT/file2 $SCRATCH_MNT/file2.1
+period=6 # seconds
+$XFS_QUOTA_PROG -x -c "limit -u rtbsoft=$((512 * file_blksz)) rtbhard=0 $qa_user" $SCRATCH_MNT
+$XFS_QUOTA_PROG -x -c "timer -u -r -d $period" $SCRATCH_MNT
+$XFS_QUOTA_PROG -x -c 'state -u' $SCRATCH_MNT >> $seqres.full
+
+su $qa_user -c "$XFS_IO_PROG -f -c 'pwrite 0 $((512 * file_blksz))' $SCRATCH_MNT/file2" > /dev/null
+report_rtusage
+
+overflow=$(date +%s)
+su $qa_user -c "$XFS_IO_PROG -f -c 'pwrite -b $file_blksz 0 $file_blksz' $SCRATCH_MNT/file2.1" > /dev/null
+report_rtusage
+sleep $((period / 2))
+echo "Try again after $((period / 2))s"
+su $qa_user -c "$XFS_IO_PROG -f -c 'pwrite -b $file_blksz $file_blksz $file_blksz' $SCRATCH_MNT/file2.1" > /dev/null
+report_rtusage
+sleep $period
+echo "Try again after another ${period}s"
+su $qa_user -c "$XFS_IO_PROG -f -c 'pwrite -b $file_blksz $((2 * file_blksz)) $file_blksz' $SCRATCH_MNT/file2.1" > /dev/null
+report_rtusage
+
+note "Extend time limits and warnings"
+rm -f $SCRATCH_MNT/file2 $SCRATCH_MNT/file2.1
+$XFS_QUOTA_PROG -x -c "limit -u rtbsoft=$((512 * file_blksz)) rtbhard=0 $qa_user" $SCRATCH_MNT
+$XFS_QUOTA_PROG -x -c "timer -u -r -d 49h" $SCRATCH_MNT
+$XFS_QUOTA_PROG -x -c 'state -u' $SCRATCH_MNT >> $seqres.full
+
+su $qa_user -c "$XFS_IO_PROG -f -c 'pwrite 0 $((512 * file_blksz))' $SCRATCH_MNT/file2" > /dev/null
+report_rtusage $qa_user want_timeout
+
+su $qa_user -c "$XFS_IO_PROG -f -c 'pwrite -b $file_blksz 0 $file_blksz' $SCRATCH_MNT/file2.1" > /dev/null
+report_rtusage $qa_user want_timeout
+
+$XFS_QUOTA_PROG -x -c "timer -u -r 73h $qa_user" $SCRATCH_MNT
+
+su $qa_user -c "$XFS_IO_PROG -f -c 'pwrite -b $file_blksz $file_blksz $file_blksz' $SCRATCH_MNT/file2.1" > /dev/null
+report_rtusage $qa_user want_timeout
+
+note "Test quota applied to bmbt"
+
+# Testing quota enforcement for bmbt shape changes is tricky. The block
+# reservation will be for enough blocks to handle the maximal btree split.
+# This is (approximately) 9 blocks no matter the size of the existing extent
+# map structure, so we set the hard limit to one more than this quantity.
+#
+# However, that means that we need to make a file of at least twice that size
+# to ensure that we create enough extent records even in the rextsize==1 case
+# where punching doesn't just create unwritten records.
+#
+# Unfortunately, it's very difficult to predict when exactly the EDQUOT will
+# come down, so we just look for the error message.
+extent_records=$(( (25 * bmbt_blksz) / 16))
+echo "extent_records $extent_records" >> $seqres.full
+
+rm -f $SCRATCH_MNT/file2
+$XFS_QUOTA_PROG -x -c "limit -u rtbsoft=0 rtbhard=0 $qa_user" $SCRATCH_MNT
+$XFS_QUOTA_PROG -x -c "limit -u bhard=$((bmbt_blksz * 10)) bsoft=0 $qa_user" $SCRATCH_MNT
+$XFS_QUOTA_PROG -x -c 'state -u' $SCRATCH_MNT >> $seqres.full
+$XFS_IO_PROG -f -c "pwrite -S 0x58 -b 64m 0 $((extent_records * file_blksz))" $SCRATCH_MNT/file2 > /dev/null
+sync
+chown $qa_user $SCRATCH_MNT/file2
+$here/src/punch-alternating $SCRATCH_MNT/file2 2>&1 | _filter_scratch
+
+$XFS_QUOTA_PROG -c "quota -u -r -n -N $qa_user" -c "quota -u -b -n -N $qa_user" $SCRATCH_MNT >> $seqres.full
+$XFS_IO_PROG -c "bmap -e -l -p -v" $SCRATCH_MNT/file2 >> $seqres.full
+
+# success, all done
+$XFS_QUOTA_PROG -x -c 'report -a -u' -c 'report -a -u -r' $SCRATCH_MNT >> $seqres.full
+ls -latr $SCRATCH_MNT >> $seqres.full
+status=0
+exit
diff --git a/tests/xfs/1858.out b/tests/xfs/1858.out
new file mode 100644
index 0000000000..1edee3f422
--- /dev/null
+++ b/tests/xfs/1858.out
@@ -0,0 +1,41 @@
+QA output created by 1858
+Format filesystem
+
+Write 128rx to root
+0[real] 128 0 0 0 ---
+
+Write 64rx to root, 4444, and 5555.
+0[real] 192 0 0 0 ---
+4444[real] 64 0 0 0 ---
+5555[real] 64 0 0 0 ---
+
+Move 64rx from root to 5555
+0[real] 128 0 0 0 ---
+4444[real] 64 0 0 0 ---
+5555[real] 128 0 0 0 ---
+
+Move 64rx from 5555 to 4444
+0[real] 128 0 0 0 ---
+4444[real] 128 0 0 0 ---
+5555[real] 64 0 0 0 ---
+
+Set hard limit of 1024rx and check enforcement
+pwrite: Disk quota exceeded
+fsgqa[real] 1024 0 1024 0 ---
+
+Set soft limit of 512rx and check timelimit enforcement
+fsgqa[real] 512 512 0 0 ---
+fsgqa[real] 513 512 0 0 ---
+Try again after 3s
+fsgqa[real] 514 512 0 0 ---
+Try again after another 6s
+pwrite: Disk quota exceeded
+fsgqa[real] 514 512 0 0 ---
+
+Extend time limits and warnings
+fsgqa[real] 512 512 0 0 [--------]
+fsgqa[real] 513 512 0 0 [2_days]
+fsgqa[real] 514 512 0 0 [3_days]
+
+Test quota applied to bmbt
+SCRATCH_MNT/file2: Disk quota exceeded
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume
@ 2023-12-31 18:23 Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
` (8 more replies)
0 siblings, 9 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 18:23 UTC (permalink / raw)
To: xfs, fstests; +Cc: Christoph Hellwig
Hi everyone,
This third patchriver contains for the realtime modernization project.
There are five main parts to this effort -- adding a metadata directory
tree; sharding the realtime volume into allocation groups to reduce
metadata lock contention; adding reverse mapping; adding reflink; and
adding the one piece needed to make quotas work on realtime. This
brings the robustness of the realtime volume up to par with the data
volume.
Christoph Hellwig has recently taken an interest in getting this feature
merged to better support zoned storage and garbage collection. This
river is much smaller than last year's, as we've recently collaborated
to get a bunch of the typedef abuses and casting problems corrected.
In theory this can also be used to support things like pmem and cxl.mem
via multi-volume XFSes where the fs metadata lives on cheap(er) flash
storage so that the pmem can be the exclusive backing of file data on
the rt volume.
--D
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 1/9] fstests: test XFS metadata directories
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
@ 2023-12-31 20:00 ` Darrick J. Wong
2023-12-27 13:50 ` [PATCH 01/11] xfs/122: fix metadirino Darrick J. Wong
` (10 more replies)
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
` (7 subsequent siblings)
8 siblings, 11 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:00 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
Adjust fstests as needed to support the XFS metadata directory feature,
and add some new tests for online fsck and fuzz testing of the ondisk
metadata.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=metadir
xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=metadir
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=metadir
xfsdocs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-documentation.git/log/?h=metadir
---
common/filter | 7 +
common/repair | 4
common/xfs | 96 +++++++++++-
tests/xfs/007 | 16 +-
tests/xfs/030 | 1
tests/xfs/033 | 1
tests/xfs/050 | 5 +
tests/xfs/122.out | 1
tests/xfs/153 | 5 +
tests/xfs/1546 | 37 ++++
tests/xfs/1546.out | 316 ++++++++++++++++++++++++++++++++++++++
tests/xfs/1547 | 37 ++++
tests/xfs/1547.out | 36 ++++
tests/xfs/1548 | 37 ++++
tests/xfs/1548.out | 318 ++++++++++++++++++++++++++++++++++++++
tests/xfs/1549 | 38 +++++
tests/xfs/1549.out | 330 ++++++++++++++++++++++++++++++++++++++++
tests/xfs/1550 | 37 ++++
tests/xfs/1550.out | 434 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1551 | 37 ++++
tests/xfs/1551.out | 35 ++++
tests/xfs/1552 | 37 ++++
tests/xfs/1552.out | 343 +++++++++++++++++++++++++++++++++++++++++
tests/xfs/1553 | 38 +++++
tests/xfs/1553.out | 370 ++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/178 | 1
tests/xfs/1856 | 2
tests/xfs/1874 | 132 ++++++++++++++++
tests/xfs/1874.out | 16 ++
tests/xfs/206 | 3
tests/xfs/299 | 1
tests/xfs/330 | 6 +
tests/xfs/509 | 21 ++-
tests/xfs/529 | 5 -
tests/xfs/530 | 6 -
tests/xfs/739 | 9 -
tests/xfs/740 | 9 -
tests/xfs/741 | 9 -
tests/xfs/742 | 9 -
tests/xfs/743 | 9 -
tests/xfs/744 | 9 -
tests/xfs/745 | 9 -
tests/xfs/746 | 9 -
43 files changed, 2803 insertions(+), 78 deletions(-)
create mode 100755 tests/xfs/1546
create mode 100644 tests/xfs/1546.out
create mode 100755 tests/xfs/1547
create mode 100644 tests/xfs/1547.out
create mode 100755 tests/xfs/1548
create mode 100644 tests/xfs/1548.out
create mode 100755 tests/xfs/1549
create mode 100644 tests/xfs/1549.out
create mode 100755 tests/xfs/1550
create mode 100644 tests/xfs/1550.out
create mode 100755 tests/xfs/1551
create mode 100644 tests/xfs/1551.out
create mode 100755 tests/xfs/1552
create mode 100644 tests/xfs/1552.out
create mode 100755 tests/xfs/1553
create mode 100644 tests/xfs/1553.out
create mode 100755 tests/xfs/1874
create mode 100644 tests/xfs/1874.out
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
@ 2023-12-31 20:00 ` Darrick J. Wong
2023-12-27 13:53 ` [PATCH 01/17] common/populate: refactor caching of metadumps to a helper Darrick J. Wong
` (16 more replies)
2023-12-31 20:00 ` [PATCHSET v2.0 3/9] fstests: enable FITRIM for the realtime section Darrick J. Wong
` (6 subsequent siblings)
8 siblings, 17 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:00 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
Right now, the realtime section uses a single pair of metadata inodes to
store the free space information. This presents a scalability problem
since every thread trying to allocate or free rt extents have to lock
these files. It would be very useful if we could begin to tackle these
problems by sharding the realtime section, so create the notion of
realtime groups, which are similar to allocation groups on the data
section.
While we're at it, define a superblock to be stamped into the start of
each rt section. This enables utilities such as blkid to identify block
devices containing realtime sections, and helpfully avoids the situation
where a file extent can cross an rtgroup boundary.
The best advantage for rtgroups will become evident later when we get to
adding rmap and reflink to the realtime volume, since the geometry
constraints are the same for rt groups and AGs. Hence we can reuse all
that code directly.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=realtime-groups
xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=realtime-groups
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=realtime-groups
xfsdocs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-documentation.git/log/?h=realtime-groups
---
common/ext4 | 17 +++++
common/fuzzy | 38 ++++++++++--
common/populate | 78 +++++++++++++-----------
common/xfs | 150 ++++++++++++++++++++++++++++++++++++++++++++---
src/punch-alternating.c | 28 ++++++++-
tests/xfs/114 | 4 +
tests/xfs/122 | 2 -
tests/xfs/122.out | 8 +++
tests/xfs/146 | 2 -
tests/xfs/185 | 2 -
tests/xfs/187 | 3 +
tests/xfs/206 | 3 +
tests/xfs/271 | 3 +
tests/xfs/341 | 4 +
tests/xfs/449 | 6 ++
tests/xfs/556 | 16 +++--
tests/xfs/581 | 2 -
tests/xfs/720 | 2 -
tests/xfs/795 | 2 -
19 files changed, 298 insertions(+), 72 deletions(-)
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 3/9] fstests: enable FITRIM for the realtime section
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
@ 2023-12-31 20:00 ` Darrick J. Wong
2023-12-27 13:57 ` [PATCH 1/2] xfs: refactor statfs field extraction Darrick J. Wong
2023-12-27 13:57 ` [PATCH 2/2] common/xfs: FITRIM now supports realtime volumes Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
` (5 subsequent siblings)
8 siblings, 2 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:00 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
One thing that's been missing for a long time is the ability to tell
underlying storage that it can unmap the unused space on the realtime
device. This short series exposes this functionality through FITRIM.
Callers that want ranged FITRIM should be aware that the realtime space
exists in the offset range after the data device. However, it is
anticipated that most callers pass in offset=0 len=-1ULL and will not
notice or care.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=realtime-discard
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=realtime-discard
---
common/xfs | 46 ++++++++++++++++++++++++++++++++++++++++++++--
tests/xfs/176 | 4 ++--
tests/xfs/187 | 6 +++---
tests/xfs/541 | 6 ++----
4 files changed, 51 insertions(+), 11 deletions(-)
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
` (2 preceding siblings ...)
2023-12-31 20:00 ` [PATCHSET v2.0 3/9] fstests: enable FITRIM for the realtime section Darrick J. Wong
@ 2023-12-31 20:00 ` Darrick J. Wong
2023-12-27 13:57 ` [PATCH 01/13] xfs: fix tests that try to access the realtime rmap inode Darrick J. Wong
` (12 more replies)
2023-12-31 20:01 ` [PATCHSET v2.0 5/9] fstests: establish baseline for realtime rmap fuzz tests Darrick J. Wong
` (4 subsequent siblings)
8 siblings, 13 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:00 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
Fix a few regressions in fstests when rmap is enabled on the realtime
volume.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=realtime-rmap
xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=realtime-rmap
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=realtime-rmap
xfsdocs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-documentation.git/log/?h=realtime-rmap
---
common/populate | 36 +++++++++++++++++++++++++
common/xfs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/104 | 1 +
tests/xfs/122.out | 5 +---
tests/xfs/1528 | 41 +++++++++++++++++++++++++++++
tests/xfs/1528.out | 4 +++
tests/xfs/1529 | 40 ++++++++++++++++++++++++++++
tests/xfs/1529.out | 4 +++
tests/xfs/1817 | 42 ++++++++++++++++++++++++++++++
tests/xfs/1817.out | 2 +
tests/xfs/1821 | 42 ++++++++++++++++++++++++++++++
tests/xfs/1821.out | 2 +
tests/xfs/1856 | 39 +++++++++++++++++++++++++++
tests/xfs/1857 | 42 ++++++++++++++++++++++++++++++
tests/xfs/1857.out | 2 +
tests/xfs/272 | 2 +
tests/xfs/276 | 2 +
tests/xfs/277 | 2 +
tests/xfs/291 | 3 +-
tests/xfs/332 | 6 +---
tests/xfs/332.out | 2 -
tests/xfs/333 | 45 --------------------------------
tests/xfs/333.out | 6 ----
tests/xfs/337 | 2 +
tests/xfs/338 | 30 ++++++++++++++++++---
tests/xfs/339 | 5 ++--
tests/xfs/340 | 25 ++++++++++++++----
tests/xfs/341 | 12 +++-----
tests/xfs/341.out | 1 -
tests/xfs/342 | 4 +--
tests/xfs/343 | 2 +
tests/xfs/406 | 6 +++-
tests/xfs/407 | 6 +++-
tests/xfs/408 | 7 ++++-
tests/xfs/409 | 7 ++++-
tests/xfs/443 | 9 ++++--
tests/xfs/481 | 6 +++-
tests/xfs/482 | 7 ++++-
38 files changed, 466 insertions(+), 107 deletions(-)
create mode 100755 tests/xfs/1528
create mode 100644 tests/xfs/1528.out
create mode 100755 tests/xfs/1529
create mode 100644 tests/xfs/1529.out
create mode 100755 tests/xfs/1817
create mode 100644 tests/xfs/1817.out
create mode 100755 tests/xfs/1821
create mode 100644 tests/xfs/1821.out
create mode 100755 tests/xfs/1857
create mode 100644 tests/xfs/1857.out
delete mode 100755 tests/xfs/333
delete mode 100644 tests/xfs/333.out
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 5/9] fstests: establish baseline for realtime rmap fuzz tests
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
` (3 preceding siblings ...)
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
@ 2023-12-31 20:01 ` Darrick J. Wong
2023-12-27 14:01 ` [PATCH 1/1] fuzzy: create known output for rt rmap btree " Darrick J. Wong
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
` (3 subsequent siblings)
8 siblings, 1 reply; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:01 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
Establish a baseline golden output for the realtime rmap fuzz tests.
This shouldn't be merged upstream because the output is very dependent
on the geometry of the filesystem that is created.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=realtime-rmap-baseline
---
tests/xfs/1528.out | 22 ++++++++
tests/xfs/1529.out | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/406.out | 22 ++++++++
tests/xfs/408.out | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/409.out | 15 ++++++
tests/xfs/481.out | 22 ++++++++
tests/xfs/482.out | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 495 insertions(+)
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 6/9] fstests: reflink on the realtime device
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
` (4 preceding siblings ...)
2023-12-31 20:01 ` [PATCHSET v2.0 5/9] fstests: establish baseline for realtime rmap fuzz tests Darrick J. Wong
@ 2023-12-31 20:01 ` Darrick J. Wong
2023-12-27 14:01 ` [PATCH 1/9] xfs/122: update fields for realtime reflink Darrick J. Wong
` (8 more replies)
2023-12-31 20:01 ` [PATCHSET v2.0 7/9] fstests: establish baseline for realtime reflink fuzz tests Darrick J. Wong
` (2 subsequent siblings)
8 siblings, 9 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:01 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
This patchset enables use of the file data block sharing feature (i.e.
reflink) on the realtime device. It follows the same basic sequence as
the realtime rmap series -- first a few cleanups; then widening of the
API parameters; and introduction of the new btree format and inode fork
format. Next comes enabling CoW and remapping for the rt device; new
scrub, repair, and health reporting code; and at the end we implement
some code to lengthen write requests so that rt extents are always CoWed
fully.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=realtime-reflink
xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=realtime-reflink
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=realtime-reflink
xfsdocs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-documentation.git/log/?h=realtime-reflink
---
common/populate | 26 ++++++++++++++++++---
common/xfs | 15 ++++++++++++
tests/generic/331 | 12 ++++++++-
tests/generic/331.out | 2 +-
tests/xfs/122.out | 3 ++
tests/xfs/131 | 48 --------------------------------------
tests/xfs/131.out | 5 ----
tests/xfs/1538 | 41 ++++++++++++++++++++++++++++++++
tests/xfs/1538.out | 4 +++
tests/xfs/1539 | 41 ++++++++++++++++++++++++++++++++
tests/xfs/1539.out | 4 +++
tests/xfs/1540 | 41 ++++++++++++++++++++++++++++++++
tests/xfs/1540.out | 4 +++
tests/xfs/1541 | 42 +++++++++++++++++++++++++++++++++
tests/xfs/1541.out | 4 +++
tests/xfs/1542 | 41 ++++++++++++++++++++++++++++++++
tests/xfs/1542.out | 4 +++
tests/xfs/1543 | 40 ++++++++++++++++++++++++++++++++
tests/xfs/1543.out | 4 +++
tests/xfs/1544 | 40 ++++++++++++++++++++++++++++++++
tests/xfs/1544.out | 4 +++
tests/xfs/1545 | 41 ++++++++++++++++++++++++++++++++
tests/xfs/1545.out | 4 +++
tests/xfs/1818 | 43 ++++++++++++++++++++++++++++++++++
tests/xfs/1818.out | 2 ++
tests/xfs/1819 | 43 ++++++++++++++++++++++++++++++++++
tests/xfs/1819.out | 2 ++
tests/xfs/1856 | 3 ++
tests/xfs/240 | 13 +++++++++-
tests/xfs/240.out | 2 +-
tests/xfs/272 | 40 +++++++++++++++++++++-----------
tests/xfs/274 | 62 ++++++++++++++++++++++++++++++++++---------------
32 files changed, 585 insertions(+), 95 deletions(-)
delete mode 100755 tests/xfs/131
delete mode 100644 tests/xfs/131.out
create mode 100755 tests/xfs/1538
create mode 100644 tests/xfs/1538.out
create mode 100755 tests/xfs/1539
create mode 100644 tests/xfs/1539.out
create mode 100755 tests/xfs/1540
create mode 100644 tests/xfs/1540.out
create mode 100755 tests/xfs/1541
create mode 100644 tests/xfs/1541.out
create mode 100755 tests/xfs/1542
create mode 100644 tests/xfs/1542.out
create mode 100755 tests/xfs/1543
create mode 100644 tests/xfs/1543.out
create mode 100755 tests/xfs/1544
create mode 100644 tests/xfs/1544.out
create mode 100755 tests/xfs/1545
create mode 100644 tests/xfs/1545.out
create mode 100755 tests/xfs/1818
create mode 100644 tests/xfs/1818.out
create mode 100755 tests/xfs/1819
create mode 100644 tests/xfs/1819.out
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 7/9] fstests: establish baseline for realtime reflink fuzz tests
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
` (5 preceding siblings ...)
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
@ 2023-12-31 20:01 ` Darrick J. Wong
2023-12-27 14:03 ` [PATCH 1/1] xfs: baseline golden output for rt refcount btree " Darrick J. Wong
2023-12-31 20:01 ` [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents Darrick J. Wong
2023-12-31 20:02 ` [PATCHSET v2.0 9/9] fstests: functional tests for rt quota Darrick J. Wong
8 siblings, 1 reply; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:01 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
Establish a baseline golden output for the realtime reflink fuzz tests.
This shouldn't be merged upstream because the output is very dependent
on the geometry of the filesystem that is created.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=realtime-reflink-baseline
---
tests/xfs/1539.out | 6 ++++++
tests/xfs/1540.out | 6 ++++++
tests/xfs/1541.out | 6 ++++++
tests/xfs/1542.out | 10 ++++++++++
tests/xfs/1543.out | 2 ++
tests/xfs/1544.out | 12 ++++++++++++
tests/xfs/1545.out | 12 ++++++++++++
7 files changed, 54 insertions(+)
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
` (6 preceding siblings ...)
2023-12-31 20:01 ` [PATCHSET v2.0 7/9] fstests: establish baseline for realtime reflink fuzz tests Darrick J. Wong
@ 2023-12-31 20:01 ` Darrick J. Wong
2023-12-27 14:04 ` [PATCH 1/5] xfs: make sure that CoW will write around when rextsize > 1 Darrick J. Wong
` (4 more replies)
2023-12-31 20:02 ` [PATCHSET v2.0 9/9] fstests: functional tests for rt quota Darrick J. Wong
8 siblings, 5 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:01 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
Now that we've landed support for reflink on the realtime device for
cases where the rt extent size is the same as the fs block size, enhance
the reflink code further to support cases where the rt extent size is a
power-of-two multiple of the fs block size. This enables us to do data
block sharing (for example) for much larger allocation units by dirtying
pagecache around shared extents and expanding writeback to write back
shared extents fully.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=realtime-reflink-extsize
xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=realtime-reflink-extsize
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=realtime-reflink-extsize
---
common/rc | 23 +++++++
common/reflink | 27 ++++++++
tests/generic/145 | 1
tests/generic/147 | 1
tests/generic/261 | 1
tests/generic/262 | 1
tests/generic/303 | 8 ++
tests/generic/331 | 1
tests/generic/353 | 2 -
tests/generic/517 | 1
tests/generic/657 | 1
tests/generic/658 | 1
tests/generic/659 | 1
tests/generic/660 | 1
tests/generic/663 | 1
tests/generic/664 | 1
tests/generic/665 | 1
tests/generic/670 | 1
tests/generic/672 | 1
tests/xfs/180 | 1
tests/xfs/182 | 1
tests/xfs/184 | 1
tests/xfs/1919 | 163 ++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1919.out | 84 +++++++++++++++++++++++++
tests/xfs/192 | 1
tests/xfs/1926 | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1926.out | 2 +
tests/xfs/200 | 1
tests/xfs/204 | 1
tests/xfs/208 | 1
tests/xfs/315 | 1
tests/xfs/326 | 6 ++
tests/xfs/420 | 3 +
tests/xfs/421 | 3 +
tests/xfs/792 | 1
35 files changed, 520 insertions(+), 2 deletions(-)
create mode 100755 tests/xfs/1919
create mode 100644 tests/xfs/1919.out
create mode 100755 tests/xfs/1926
create mode 100644 tests/xfs/1926.out
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCHSET v2.0 9/9] fstests: functional tests for rt quota
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
` (7 preceding siblings ...)
2023-12-31 20:01 ` [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents Darrick J. Wong
@ 2023-12-31 20:02 ` Darrick J. Wong
2023-12-27 14:05 ` [PATCH 1/3] common: enable testing of realtime quota when supported Darrick J. Wong
` (2 more replies)
8 siblings, 3 replies; 72+ messages in thread
From: Darrick J. Wong @ 2023-12-31 20:02 UTC (permalink / raw)
To: djwong, zlang; +Cc: guan, linux-xfs, fstests
Hi all,
The sole patch in this series sets up functional testing for quota on
the xfs realtime device.
If you're going to start using this code, I strongly recommend pulling
from my git trees, which are linked below.
This has been running on the djcloud for months with no problems. Enjoy!
Comments and questions are, as always, welcome.
--D
kernel git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=realtime-quotas
xfsprogs git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfsprogs-dev.git/log/?h=realtime-quotas
fstests git tree:
https://git.kernel.org/cgit/linux/kernel/git/djwong/xfstests-dev.git/log/?h=realtime-quotas
---
common/populate | 2 -
common/quota | 64 ++++++++++++++++++--
common/xfs | 12 ++++
tests/generic/219 | 1
tests/generic/230 | 1
tests/generic/305 | 1
tests/generic/326 | 1
tests/generic/327 | 1
tests/generic/328 | 1
tests/generic/566 | 4 +
tests/generic/587 | 1
tests/generic/603 | 1
tests/generic/691 | 2 +
tests/generic/710 | 4 +
tests/xfs/050 | 2 +
tests/xfs/106 | 1
tests/xfs/108 | 2 +
tests/xfs/152 | 1
tests/xfs/153 | 2 +
tests/xfs/161 | 2 +
tests/xfs/1858 | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/xfs/1858.out | 41 +++++++++++++
tests/xfs/213 | 1
tests/xfs/214 | 1
tests/xfs/220 | 2 +
tests/xfs/299 | 2 +
tests/xfs/330 | 1
tests/xfs/434 | 1
tests/xfs/435 | 1
tests/xfs/441 | 1
tests/xfs/442 | 1
tests/xfs/508 | 2 +
tests/xfs/511 | 10 +++
tests/xfs/720 | 5 ++
34 files changed, 333 insertions(+), 10 deletions(-)
create mode 100755 tests/xfs/1858
create mode 100644 tests/xfs/1858.out
^ permalink raw reply [flat|nested] 72+ messages in thread
end of thread, other threads:[~2024-01-01 1:06 UTC | newest]
Thread overview: 72+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-31 18:23 [NYE PATCHRIVER 3/4] xfs: modernize the realtime volume Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 1/9] fstests: test XFS metadata directories Darrick J. Wong
2023-12-27 13:50 ` [PATCH 01/11] xfs/122: fix metadirino Darrick J. Wong
2023-12-27 13:50 ` [PATCH 02/11] various: fix finding metadata inode numbers when metadir is enabled Darrick J. Wong
2023-12-27 13:50 ` [PATCH 03/11] xfs/{030,033,178}: forcibly disable metadata directory trees Darrick J. Wong
2023-12-27 13:50 ` [PATCH 04/11] common/repair: patch up repair sb inode value complaints Darrick J. Wong
2023-12-27 13:51 ` [PATCH 05/11] xfs/206: update for metadata directory support Darrick J. Wong
2023-12-27 13:51 ` [PATCH 06/11] xfs/{050,144,153,299,330}: update quota reports to handle metadir trees Darrick J. Wong
2023-12-27 13:51 ` [PATCH 07/11] xfs/856: add metadir upgrade to test matrix Darrick J. Wong
2023-12-27 13:51 ` [PATCH 08/11] xfs/509: adjust inumbers accounting for metadata directories Darrick J. Wong
2023-12-27 13:52 ` [PATCH 09/11] xfs: create fuzz tests " Darrick J. Wong
2023-12-27 13:52 ` [PATCH 10/11] xfs: baseline golden output for metadata directory fuzz tests Darrick J. Wong
2023-12-27 13:52 ` [PATCH 11/11] xfs: test metapath repairs Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 2/9] xfsprogs: shard the realtime section Darrick J. Wong
2023-12-27 13:53 ` [PATCH 01/17] common/populate: refactor caching of metadumps to a helper Darrick J. Wong
2023-12-27 13:53 ` [PATCH 02/17] common/xfs: wipe external logs during mdrestore operations Darrick J. Wong
2023-12-27 13:53 ` [PATCH 03/17] common/ext4: reformat " Darrick J. Wong
2023-12-27 13:53 ` [PATCH 04/17] xfs: use metadump v2 format by default Darrick J. Wong
2023-12-27 13:54 ` [PATCH 05/17] common/xfs: capture external logs during metadump/mdrestore Darrick J. Wong
2023-12-27 13:54 ` [PATCH 06/17] xfs/122: update for rtgroups Darrick J. Wong
2023-12-27 13:54 ` [PATCH 07/17] punch-alternating: detect xfs realtime files with large allocation units Darrick J. Wong
2023-12-27 13:54 ` [PATCH 08/17] xfs/206: update mkfs filtering for rt groups feature Darrick J. Wong
2023-12-27 13:55 ` [PATCH 09/17] common: pass the realtime device to xfs_db when possible Darrick J. Wong
2023-12-27 13:55 ` [PATCH 10/17] common: filter rtgroups when we're disabling metadir Darrick J. Wong
2023-12-27 13:55 ` [PATCH 11/17] xfs/185: update for rtgroups Darrick J. Wong
2023-12-27 13:55 ` [PATCH 12/17] xfs/449: update test to know about xfs_db -R Darrick J. Wong
2023-12-27 13:56 ` [PATCH 13/17] xfs/122: update for rtbitmap headers Darrick J. Wong
2023-12-27 13:56 ` [PATCH 14/17] xfs/122: udpate test to pick up rtword/suminfo ondisk unions Darrick J. Wong
2023-12-27 13:56 ` [PATCH 15/17] xfs/27[46],xfs/556: fix tests to deal with rtgroups output in bmap/fsmap commands Darrick J. Wong
2023-12-27 13:56 ` [PATCH 16/17] common/xfs: capture realtime devices during metadump/mdrestore Darrick J. Wong
2023-12-27 13:57 ` [PATCH 17/17] common/fuzzy: adapt the scrub stress tests to support rtgroups Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 3/9] fstests: enable FITRIM for the realtime section Darrick J. Wong
2023-12-27 13:57 ` [PATCH 1/2] xfs: refactor statfs field extraction Darrick J. Wong
2023-12-27 13:57 ` [PATCH 2/2] common/xfs: FITRIM now supports realtime volumes Darrick J. Wong
2023-12-31 20:00 ` [PATCHSET v2.0 4/9] fstests: fixes for realtime rmap Darrick J. Wong
2023-12-27 13:57 ` [PATCH 01/13] xfs: fix tests that try to access the realtime rmap inode Darrick J. Wong
2023-12-27 13:58 ` [PATCH 02/13] fuzz: for fuzzing the rtrmapbt, find the path to the rt rmap btree file Darrick J. Wong
2023-12-27 13:58 ` [PATCH 03/13] xfs: race fsstress with realtime rmap btree scrub and repair Darrick J. Wong
2023-12-27 13:58 ` [PATCH 04/13] xfs/856: add rtrmapbt upgrade to test matrix Darrick J. Wong
2023-12-27 13:59 ` [PATCH 05/13] xfs/122: update for rtgroups-based realtime rmap btrees Darrick J. Wong
2023-12-27 13:59 ` [PATCH 06/13] xfs: fix various problems with fsmap detecting the data device Darrick J. Wong
2023-12-27 13:59 ` [PATCH 07/13] xfs/341: update test for rtgroup-based rmap Darrick J. Wong
2023-12-27 13:59 ` [PATCH 08/13] xfs/3{43,32}: adapt tests for rt extent size greater than 1 Darrick J. Wong
2023-12-27 14:00 ` [PATCH 09/13] xfs: skip tests if formatting small filesystem fails Darrick J. Wong
2023-12-27 14:00 ` [PATCH 10/13] xfs/443: use file allocation unit, not dbsize Darrick J. Wong
2023-12-27 14:00 ` [PATCH 11/13] populate: adjust rtrmap calculations for rtgroups Darrick J. Wong
2023-12-27 14:00 ` [PATCH 12/13] populate: check that we created a realtime rmap btree of the given height Darrick J. Wong
2023-12-27 14:01 ` [PATCH 13/13] fuzzy: create missing fuzz tests for rt rmap btrees Darrick J. Wong
2023-12-31 20:01 ` [PATCHSET v2.0 5/9] fstests: establish baseline for realtime rmap fuzz tests Darrick J. Wong
2023-12-27 14:01 ` [PATCH 1/1] fuzzy: create known output for rt rmap btree " Darrick J. Wong
2023-12-31 20:01 ` [PATCHSET v2.0 6/9] fstests: reflink on the realtime device Darrick J. Wong
2023-12-27 14:01 ` [PATCH 1/9] xfs/122: update fields for realtime reflink Darrick J. Wong
2023-12-27 14:01 ` [PATCH 2/9] common/populate: create realtime refcount btree Darrick J. Wong
2023-12-27 14:02 ` [PATCH 3/9] xfs: create fuzz tests for the " Darrick J. Wong
2023-12-27 14:02 ` [PATCH 4/9] xfs/27[24]: adapt for checking files on the realtime volume Darrick J. Wong
2023-12-27 14:02 ` [PATCH 5/9] xfs: race fsstress with realtime refcount btree scrub and repair Darrick J. Wong
2023-12-27 14:02 ` [PATCH 6/9] xfs: remove xfs/131 now that we allow reflink on realtime volumes Darrick J. Wong
2023-12-27 14:03 ` [PATCH 7/9] xfs/856: add rtreflink upgrade to test matrix Darrick J. Wong
2023-12-27 14:03 ` [PATCH 8/9] generic/331,xfs/240: support files that skip delayed allocation Darrick J. Wong
2023-12-27 14:03 ` [PATCH 9/9] common/xfs: fix _xfs_get_file_block_size when rtinherit is set and no rt section Darrick J. Wong
2023-12-31 20:01 ` [PATCHSET v2.0 7/9] fstests: establish baseline for realtime reflink fuzz tests Darrick J. Wong
2023-12-27 14:03 ` [PATCH 1/1] xfs: baseline golden output for rt refcount btree " Darrick J. Wong
2023-12-31 20:01 ` [PATCHSET v2.0 8/9] fstests: reflink with large realtime extents Darrick J. Wong
2023-12-27 14:04 ` [PATCH 1/5] xfs: make sure that CoW will write around when rextsize > 1 Darrick J. Wong
2023-12-27 14:04 ` [PATCH 2/5] xfs: skip cowextsize hint fragmentation tests on realtime volumes Darrick J. Wong
2023-12-27 14:04 ` [PATCH 3/5] misc: add more congruent oplen testing Darrick J. Wong
2023-12-27 14:05 ` [PATCH 4/5] xfs: test COWing entire rt extents Darrick J. Wong
2023-12-27 14:05 ` [PATCH 5/5] generic/303: avoid test failures on weird rt extent sizes Darrick J. Wong
2023-12-31 20:02 ` [PATCHSET v2.0 9/9] fstests: functional tests for rt quota Darrick J. Wong
2023-12-27 14:05 ` [PATCH 1/3] common: enable testing of realtime quota when supported Darrick J. Wong
2023-12-27 14:05 ` [PATCH 2/3] xfs: fix quota tests to adapt to realtime quota Darrick J. Wong
2023-12-27 14:06 ` [PATCH 3/3] xfs: regression testing of quota on the realtime device Darrick J. Wong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox