#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2021 Chandan Babu R. All Rights Reserved. # # FS QA Test 530 # # Verify that XFS does not cause bitmap/summary inode fork's extent count to # overflow when growing an the realtime volume of the filesystem. # seq=`basename $0` seqres=$RESULT_DIR/$seq echo "QA output created by $seq" here=`pwd` tmp=/tmp/$$ status=1 # failure is the default! trap "_cleanup; exit \$status" 0 1 2 3 15 _cleanup() { cd / _scratch_unmount >> $seqres.full 2>&1 test -e "$rtdev" && losetup -d $rtdev >> $seqres.full 2>&1 rm -f $tmp.* $TEST_DIR/$seq.rtvol } # get standard environment, filters and checks . ./common/rc . ./common/filter . ./common/inject . ./common/populate # remove previous $seqres.full before test rm -f $seqres.full # real QA test starts here _supported_fs xfs # Note that we don't _require_realtime because we synthesize a rt volume # below. _require_test _require_xfs_debug _require_test_program "punch-alternating" _require_xfs_io_error_injection "reduce_max_iextents" _require_xfs_io_error_injection "bmap_alloc_minlen_extent" _require_scratch_nocheck echo "* Test extending rt inodes" _scratch_mkfs | _filter_mkfs >> $seqres.full 2> $tmp.mkfs . $tmp.mkfs echo "Create fake rt volume" nr_bitmap_blks=25 nr_bits=$((nr_bitmap_blks * dbsize * 8)) # Realtime extent size has to be atleast 4k in size. if (( $dbsize < 4096 )); then rtextsz=4096 else rtextsz=$dbsize fi rtdevsz=$((nr_bits * rtextsz)) truncate -s $rtdevsz $TEST_DIR/$seq.rtvol rtdev=$(_create_loop_device $TEST_DIR/$seq.rtvol) echo "Format and mount rt volume" export USE_EXTERNAL=yes export SCRATCH_RTDEV=$rtdev _scratch_mkfs -d size=$((1024 * 1024 * 1024)) -b size=${dbsize} \ -r size=${rtextsz},extsize=${rtextsz} >> $seqres.full _try_scratch_mount || _notrun "Couldn't mount fs with synthetic rt volume" echo "Consume free space" fillerdir=$SCRATCH_MNT/fillerdir nr_free_blks=$(stat -f -c '%f' $SCRATCH_MNT) nr_free_blks=$((nr_free_blks * 90 / 100)) _fill_fs $((dbsize * nr_free_blks)) $fillerdir $dbsize 0 >> $seqres.full 2>&1 echo "Create fragmented filesystem" for dentry in $(ls -1 $fillerdir/); do $here/src/punch-alternating $fillerdir/$dentry >> $seqres.full done echo "Inject reduce_max_iextents error tag" _scratch_inject_error reduce_max_iextents 1 echo "Inject bmap_alloc_minlen_extent error tag" _scratch_inject_error bmap_alloc_minlen_extent 1 echo "Grow realtime volume" $XFS_GROWFS_PROG -r $SCRATCH_MNT >> $seqres.full 2>&1 if [[ $? == 0 ]]; then echo "Growfs succeeded; should have failed." exit 1 fi _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 || \ _fail "Unable to obtain inode fork's extent count") if (( $nextents > 10 )); then echo "Extent count overflow check failed: nextents = $nextents" exit 1 fi done echo "Check filesystem" _check_scratch_fs losetup -d $rtdev rm -f $TEST_DIR/$seq.rtvol # success, all done status=0 exit