On Fri, Mar 21, 2025 at 02:27:07PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <djwong@xxxxxxxxxx> > > Test how well we can dump a fully populated filesystem's contents. > > Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> > Reviewed-by: Christoph Hellwig <hch@xxxxxx> > --- > tests/xfs/1895 | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > tests/xfs/1895.out | 6 ++ > 2 files changed, 159 insertions(+) > create mode 100755 tests/xfs/1895 > create mode 100644 tests/xfs/1895.out > > > diff --git a/tests/xfs/1895 b/tests/xfs/1895 > new file mode 100755 > index 00000000000000..18b534d328e9fd > --- /dev/null > +++ b/tests/xfs/1895 > @@ -0,0 +1,153 @@ > +#! /bin/bash > +# SPDX-License-Identifier: GPL-2.0 > +# Copyright (c) 2025 Oracle, Inc. All Rights Reserved. > +# > +# FS QA Test No. 1895 > +# > +# Populate a XFS filesystem, ensure that rdump can "recover" the contents to > +# another directory, and compare the contents. > +# > +. ./common/preamble > +_begin_fstest auto scrub > + > +_cleanup() > +{ > + command -v _kill_fsstress &>/dev/null && _kill_fsstress I'm wondering why you always do "command -v _kill_fsstress &>/dev/null" before _kill_fsstress, isn't _kill_fsstress a common helper in common/rc ? Thanks, Zorro > + cd / > + test -e "$testfiles" && rm -r -f $testfiles > +} > + > +_register_cleanup "_cleanup" BUS > + > +# Import common functions. > +. ./common/filter > +. ./common/populate > +. ./common/fuzzy > + > +_require_xfs_db_command "rdump" > +_require_test > +_require_scratch > +_require_scrub > +_require_populate_commands > + > +make_md5() > +{ > + (cd $1 ; find . -type f -print0 | xargs -0 md5sum) > $tmp.md5.$2 > +} > + > +cmp_md5() > +{ > + (cd $1 ; md5sum --quiet -c $tmp.md5.$2) > +} > + > +make_stat() > +{ > + # columns: raw mode in hex, > + # major rdev for special > + # minor rdev for special > + # uid of owner > + # gid of owner > + # file type > + # total size > + # mtime > + # name > + # We can't directly control directory sizes so filter them. > + # Too many things can bump (or not) atime so don't test that. > + (cd $1 ; find . -print0 | > + xargs -0 stat -c '%f %t:%T %u %g %F %s %Y %n' | > + sed -e 's/ directory [1-9][0-9]* / directory SIZE /g' | > + sort) > $tmp.stat.$2 > +} > + > +cmp_stat() > +{ > + diff -u $tmp.stat.$1 $tmp.stat.$2 > +} > + > +make_stat_files() { > + for file in "${FILES[@]}"; do > + find "$1/$file" -print0 | xargs -0 stat -c '%f %t:%T %u %g %F %s %Y %n' > + done | sed \ > + -e 's/ directory [1-9][0-9]* / directory SIZE /g' \ > + -e "s| $1| DUMPDIR|g" \ > + | sort > $tmp.stat.files.$2 > +} > + > +cmp_stat_files() > +{ > + diff -u $tmp.stat.files.$1 $tmp.stat.files.$2 > +} > + > +make_stat_dir() { > + find "$1" -print0 | \ > + xargs -0 stat -c '%f %t:%T %u %g %F %s %Y %n' | sed \ > + -e 's/ directory [1-9][0-9]* / directory SIZE /g' \ > + -e "s| $1| DUMPDIR|g" \ > + | sort > $tmp.stat.dir.$2 > +} > + > +cmp_stat_dir() > +{ > + diff -u $tmp.stat.dir.$1 $tmp.stat.dir.$2 > +} > + > +FILES=( > + "/S_IFDIR.FMT_INLINE" > + "/S_IFBLK" > + "/S_IFCHR" > + "/S_IFLNK.FMT_LOCAL" > + "/S_IFIFO" > + "/S_IFDIR.FMT_INLINE/00000001" > + "/ATTR.FMT_EXTENTS_REMOTE3K" > + "/S_IFREG.FMT_EXTENTS" > + "/S_IFREG.FMT_BTREE" > + "/BNOBT" > + "/S_IFDIR.FMT_BLOCK" > +) > +DIR="/S_IFDIR.FMT_LEAF" > + > +testfiles=$TEST_DIR/$seq > +mkdir -p $testfiles > + > +echo "Format and populate" > +_scratch_populate_cached nofill > $seqres.full 2>&1 > +_scratch_mount > + > +_run_fsstress -n 500 -d $SCRATCH_MNT/newfiles > + > +make_stat $SCRATCH_MNT before > +make_md5 $SCRATCH_MNT before > +make_stat_files $SCRATCH_MNT before > +make_stat_dir $SCRATCH_MNT/$DIR before > +_scratch_unmount > + > +echo "Recover filesystem" > +dumpdir1=$testfiles/rdump > +dumpdir2=$testfiles/sdump > +dumpdir3=$testfiles/tdump > +rm -r -f $dumpdir1 $dumpdir2 $dumpdir3 > + > +# as of linux 6.12 fchownat does not work on symlinks > +_scratch_xfs_db -c "rdump / $dumpdir1" | sed -e '/could not be set/d' > +_scratch_xfs_db -c "rdump ${FILES[*]} $dumpdir2" | sed -e '/could not be set/d' > +_scratch_xfs_db -c "rdump $DIR $dumpdir3" | sed -e '/could not be set/d' > + > +echo "Check file contents" > +make_stat $dumpdir1 after > +cmp_stat before after > +cmp_md5 $dumpdir1 before > + > +echo "Check selected files contents" > +make_stat_files $dumpdir2 after > +cmp_stat_files before after > + > +echo "Check single dir extraction contents" > +make_stat_dir $dumpdir3 after > +cmp_stat_dir before after > + > +# remount so we can check this fs > +_scratch_mount > + > +# success, all done > +status=0 > +exit > diff --git a/tests/xfs/1895.out b/tests/xfs/1895.out > new file mode 100644 > index 00000000000000..de639ed3fc7e38 > --- /dev/null > +++ b/tests/xfs/1895.out > @@ -0,0 +1,6 @@ > +QA output created by 1895 > +Format and populate > +Recover filesystem > +Check file contents > +Check selected files contents > +Check single dir extraction contents >