#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2021 Oracle. All Rights Reserved. # # FS QA Test No. 541 # # Regression test for kernel commits: # # 83193e5ebb01 ("xfs: correct the narrative around misaligned rtinherit/extszinherit dirs") # 5aa5b278237f ("xfs: don't expose misaligned extszinherit hints to userspace") # 0e2af9296f4f ("xfs: improve FSGROWFSRT precondition checking") # 0925fecc5574 ("xfs: fix an integer overflow error in xfs_growfs_rt") # b102a46ce16f ("xfs: detect misaligned rtinherit directory extent size hints") # # Test for xfs_growfs to make sure that we can add a realtime device and set # its extent size hint at the same time. # . ./common/preamble _begin_fstest auto quick realtime growfs # Import common functions. . ./common/filter # real QA test starts here # Modify as appropriate. _supported_fs xfs _require_realtime _require_scratch # Format scratch fs with no realtime section. SCRATCH_RTDEV="" _scratch_mkfs | _filter_mkfs 2> $tmp.mkfs >> $seqres.full _scratch_mount # Check that there's no realtime section. source $tmp.mkfs test $rtblocks -eq 0 || echo "expected 0 rtblocks, got $rtblocks" # Compute a new rt extent size and a separate rt extent size hint to exercise # the code that ignores hints that aren't a multiple of the extent size. XFS_MAX_RTEXTSIZE=$((1024 * 1024 * 1024)) new_rtextsz=$((rtextsz + dbsize)) if [ $new_rtextsz -gt $XFS_MAX_RTEXTSIZE ]; then new_rtextsz=$((rtextsz - dbsize)) fi new_rtextsz_blocks=$(( new_rtextsz / dbsize )) new_extszhint=$((rtextsz * 2)) if [ $new_extszhint -eq $new_rtextsz ]; then new_extszhint=$((rtextsz * 3)) fi # Set the inheritable extent size hint and rt status. $XFS_IO_PROG -c 'chattr +t' -c "extsize $new_extszhint" $SCRATCH_MNT # Check that the hint was set correctly after_extszhint=$($XFS_IO_PROG -c 'stat' $SCRATCH_MNT | \ grep 'fsxattr.extsize' | cut -d ' ' -f 3) test $after_extszhint -eq $new_extszhint || \ echo "expected extszhint $new_extszhint, got $after_extszhint" # Add a realtime section and change the extent size. echo $XFS_GROWFS_PROG -e $new_rtextsz_blocks -r $SCRATCH_MNT >> $seqres.full $XFS_GROWFS_PROG -e $new_rtextsz_blocks -r $SCRATCH_MNT >> $seqres.full 2> $tmp.growfs res=$? cat $tmp.growfs # If the growfs failed, skip the post-test check because the scratch fs does # not have SCRATCH_RTDEV configured. If the kernel didn't support adding the # rt volume, skip everything else. if [ $res -ne 0 ]; then rm -f ${RESULT_DIR}/require_scratch if grep -q "Operation not supported" $tmp.growfs; then _notrun "growfs not supported on rt volume" fi fi # Now that the root directory's extsize hint is no longer aligned to the rt # extent size, check that we don't report it to userspace any more. grow_extszhint=$($XFS_IO_PROG -c 'stat' $SCRATCH_MNT | \ grep 'fsxattr.extsize' | cut -d ' ' -f 3) 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) 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) test $after_rtextsz_blocks -eq $new_rtextsz_blocks || \ echo "expected rtextsize $new_rtextsz_blocks, got $after_rtextsz_blocks" # Create a new realtime file to prove that we can. echo moo > $SCRATCH_MNT/a sync -f $SCRATCH_MNT $XFS_IO_PROG -c 'lsattr -v' $SCRATCH_MNT/a | \ cut -d ' ' -f 1 | \ grep -q realtime || \ echo "$SCRATCH_MNT/a is not a realtime file?" # Check that the root directory's hint (which was aligned before the grow and # misaligned after) did not propagate to the new realtime file. file_extszhint=$($XFS_IO_PROG -c 'stat' $SCRATCH_MNT/a | \ grep 'fsxattr.extsize' | cut -d ' ' -f 3) test $file_extszhint -eq 0 || \ echo "expected file extszhint 0, got $file_extszhint" # success, all done echo Silence is golden status=0 exit