On Mon, Jan 30, 2023 at 05:56:42PM -0500, Hironori Shiina wrote: > xfsdump used to cause a problem when there is an inode whose number is > lower than the root inode number. This patch adds a helper function to > reproduce such a situation for regression tests. > > Signed-off-by: Hironori Shiina <shiina.hironori@xxxxxxxxxxx> > --- This version looks good to me, Reviewed-by: Zorro Lang <zlang@xxxxxxxxxx> > common/xfs | 40 ++++++++++++++++++++++++++++++++++++++++ > tests/xfs/545 | 31 ++++--------------------------- > tests/xfs/554 | 35 ++++++----------------------------- > tests/xfs/557 | 31 ++++--------------------------- > 4 files changed, 54 insertions(+), 83 deletions(-) > > diff --git a/common/xfs b/common/xfs > index a00d90a4..ba59889c 100644 > --- a/common/xfs > +++ b/common/xfs > @@ -1556,3 +1556,43 @@ _xfs_get_inode_core_bytes() > echo 96 > fi > } > + > +# Create a file with a lower inode number than the root inode number. For this > +# creation, this function runs mkfs and mount on the scratch device with > +# options. This function prints the root inode number and the created inode > +# number. > +_scratch_xfs_create_fake_root() > +{ > + local root_inum > + local inum > + > + # A large stripe unit will put the root inode out quite far > + # due to alignment, leaving free blocks ahead of it. > + _scratch_mkfs_xfs -d sunit=1024,swidth=1024 > $seqres.full 2>&1 || _fail "mkfs failed" > + > + # Mounting /without/ a stripe should allow inodes to be allocated > + # in lower free blocks, without the stripe alignment. > + _scratch_mount -o sunit=0,swidth=0 > + > + local root_inum=$(stat -c %i $SCRATCH_MNT) > + > + # Consume space after the root inode so that the blocks before > + # root look "close" for the next inode chunk allocation > + $XFS_IO_PROG -f -c "falloc 0 16m" $SCRATCH_MNT/fillfile > + > + # And make a bunch of inodes until we (hopefully) get one lower > + # than root, in a new inode chunk. > + echo "root_inum: $root_inum" >> $seqres.full > + for i in $(seq 0 4096) ; do > + fname=$SCRATCH_MNT/$(printf "FILE_%03d" $i) > + touch $fname > + inum=$(stat -c "%i" $fname) > + [[ $inum -lt $root_inum ]] && break > + done > + > + echo "created: $inum" >> $seqres.full > + > + [[ $inum -lt $root_inum ]] || _notrun "Could not set up test" > + > + echo "$root_inum $inum" > +} > diff --git a/tests/xfs/545 b/tests/xfs/545 > index ccb0dd6c..57a650ac 100755 > --- a/tests/xfs/545 > +++ b/tests/xfs/545 > @@ -17,33 +17,10 @@ _supported_fs xfs > _require_xfs_io_command "falloc" > _require_scratch > > -# A large stripe unit will put the root inode out quite far > -# due to alignment, leaving free blocks ahead of it. > -_scratch_mkfs_xfs -d sunit=1024,swidth=1024 > $seqres.full 2>&1 > - > -# Mounting /without/ a stripe should allow inodes to be allocated > -# in lower free blocks, without the stripe alignment. > -_scratch_mount -o sunit=0,swidth=0 > - > -root_inum=$(stat -c %i $SCRATCH_MNT) > - > -# Consume space after the root inode so that the blocks before > -# root look "close" for the next inode chunk allocation > -$XFS_IO_PROG -f -c "falloc 0 16m" $SCRATCH_MNT/fillfile > - > -# And make a bunch of inodes until we (hopefully) get one lower > -# than root, in a new inode chunk. > -echo "root_inum: $root_inum" >> $seqres.full > -for i in $(seq 0 4096) ; do > - fname=$SCRATCH_MNT/$(printf "FILE_%03d" $i) > - touch $fname > - inum=$(stat -c "%i" $fname) > - [[ $inum -lt $root_inum ]] && break > -done > - > -echo "created: $inum" >> $seqres.full > - > -[[ $inum -lt $root_inum ]] || _notrun "Could not set up test" > +# Create a filesystem which contains a fake root inode > +inums=($(_scratch_xfs_create_fake_root)) > +root_inum=${inums[0]} > +fake_inum=${inums[1]} > > # Now try a dump and restore. Cribbed from xfs/068 > _create_dumpdir_stress > diff --git a/tests/xfs/554 b/tests/xfs/554 > index 65084cb3..16fc052c 100755 > --- a/tests/xfs/554 > +++ b/tests/xfs/554 > @@ -21,33 +21,10 @@ _require_xfs_io_command "falloc" > _require_scratch > _require_xfsrestore_xflag > > -# A large stripe unit will put the root inode out quite far > -# due to alignment, leaving free blocks ahead of it. > -_scratch_mkfs_xfs -d sunit=1024,swidth=1024 > $seqres.full 2>&1 || _fail "mkfs failed" > - > -# Mounting /without/ a stripe should allow inodes to be allocated > -# in lower free blocks, without the stripe alignment. > -_scratch_mount -o sunit=0,swidth=0 > - > -root_inum=$(stat -c %i $SCRATCH_MNT) > - > -# Consume space after the root inode so that the blocks before > -# root look "close" for the next inode chunk allocation > -$XFS_IO_PROG -f -c "falloc 0 16m" $SCRATCH_MNT/fillfile > - > -# And make a bunch of inodes until we (hopefully) get one lower > -# than root, in a new inode chunk. > -echo "root_inum: $root_inum" >> $seqres.full > -for i in $(seq 0 4096) ; do > - fname=$SCRATCH_MNT/$(printf "FILE_%03d" $i) > - touch $fname > - inum=$(stat -c "%i" $fname) > - [[ $inum -lt $root_inum ]] && break > -done > - > -echo "created: $inum" >> $seqres.full > - > -[[ $inum -lt $root_inum ]] || _notrun "Could not set up test" > +# Create a filesystem which contains a fake root inode > +inums=($(_scratch_xfs_create_fake_root)) > +root_inum=${inums[0]} > +fake_inum=${inums[1]} > > # Now try a dump and restore. Cribbed from xfs/068 > _create_dumpdir_stress > @@ -59,10 +36,10 @@ _do_dump_file > > # Set the wrong root inode number to the dump file > # as problematic xfsdump used to do. > -$here/src/fake-dump-rootino $dump_file $inum > +$here/src/fake-dump-rootino $dump_file $fake_inum > > _do_restore_file -x | \ > -sed -e "s/rootino #${inum}/rootino #FAKENO/g" \ > +sed -e "s/rootino #${fake_inum}/rootino #FAKENO/g" \ > -e "s/# to ${root_inum}/# to ROOTNO/g" \ > -e "/entries processed$/s/[0-9][0-9]*/NUM/g" > > diff --git a/tests/xfs/557 b/tests/xfs/557 > index 425695db..522c4f06 100644 > --- a/tests/xfs/557 > +++ b/tests/xfs/557 > @@ -21,33 +21,10 @@ _require_scratch > _fixed_by_kernel_commit XXXXXXXXXXXX \ > "xfs: get root inode correctly at bulkstat" > > -# A large stripe unit will put the root inode out quite far > -# due to alignment, leaving free blocks ahead of it. > -_scratch_mkfs_xfs -d sunit=1024,swidth=1024 > $seqres.full 2>&1 || _fail "mkfs failed" > - > -# Mounting /without/ a stripe should allow inodes to be allocated > -# in lower free blocks, without the stripe alignment. > -_scratch_mount -o sunit=0,swidth=0 > - > -root_inum=$(stat -c %i $SCRATCH_MNT) > - > -# Consume space after the root inode so that the blocks before > -# root look "close" for the next inode chunk allocation > -$XFS_IO_PROG -f -c "falloc 0 16m" $SCRATCH_MNT/fillfile > - > -# And make a bunch of inodes until we (hopefully) get one lower > -# than root, in a new inode chunk. > -echo "root_inum: $root_inum" >> $seqres.full > -for i in $(seq 0 4096) ; do > - fname=$SCRATCH_MNT/$(printf "FILE_%03d" $i) > - touch $fname > - inum=$(stat -c "%i" $fname) > - [[ $inum -lt $root_inum ]] && break > -done > - > -echo "created: $inum" >> $seqres.full > - > -[[ $inum -lt $root_inum ]] || _notrun "Could not set up test" > +# Create a filesystem which contains a fake root inode > +inums=($(_scratch_xfs_create_fake_root)) > +root_inum=${inums[0]} > +fake_inum=${inums[1]} > > # Get root ino with XFS_BULK_IREQ_SPECIAL_ROOT > bulkstat_root_inum=$($XFS_IO_PROG -c 'bulkstat_single root' $SCRATCH_MNT | grep bs_ino | awk '{print $3;}') > -- > 2.39.1 >