2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2021 Chandan Babu R. All Rights Reserved.
7 # Verify that XFS does not cause bitmap/summary inode fork's extent count to
8 # overflow when growing an the realtime volume of the filesystem.
11 _begin_fstest auto quick realtime growfs
13 # Override the default cleanup function.
17 _scratch_unmount >> $seqres.full 2>&1
18 test -e "$rtdev" && losetup -d $rtdev >> $seqres.full 2>&1
19 rm -f $tmp.* $TEST_DIR/$seq.rtvol
22 # Import common functions.
27 # real QA test starts here
30 # Note that we don't _require_realtime because we synthesize a rt volume
34 _require_test_program "punch-alternating"
35 _require_xfs_io_error_injection "reduce_max_iextents"
36 _require_xfs_io_error_injection "bmap_alloc_minlen_extent"
37 _require_scratch_nocheck
39 echo "* Test extending rt inodes"
41 _scratch_mkfs | _filter_mkfs >> $seqres.full 2> $tmp.mkfs
44 echo "Create fake rt volume"
46 nr_bits=$((nr_bitmap_blks * dbsize * 8))
48 # Realtime extent size has to be atleast 4k in size.
49 if (( $dbsize < 4096 )); then
55 rtdevsz=$((nr_bits * rtextsz))
56 truncate -s $rtdevsz $TEST_DIR/$seq.rtvol
57 rtdev=$(_create_loop_device $TEST_DIR/$seq.rtvol)
59 echo "Format and mount rt volume"
61 export USE_EXTERNAL=yes
62 export SCRATCH_RTDEV=$rtdev
63 _scratch_mkfs -d size=$((1024 * 1024 * 1024)) \
64 -r size=${rtextsz},extsize=${rtextsz} >> $seqres.full
65 _try_scratch_mount || _notrun "Couldn't mount fs with synthetic rt volume"
67 # If we didn't get the desired realtime volume and the same blocksize as the
68 # first format (which we used to compute a specific rt geometry), skip the
69 # test. This can happen if the MKFS_OPTIONS conflict with the ones we passed
70 # to _scratch_mkfs or do not result in a valid rt fs geometry. In this case,
71 # _scratch_mkfs will try to "succeed" at formatting by dropping MKFS_OPTIONS,
72 # giving us the wrong geometry.
73 formatted_blksz="$(_get_block_size $SCRATCH_MNT)"
74 test "$formatted_blksz" -ne "$dbsize" && \
75 _notrun "Tried to format with $dbsize blocksize, got $formatted_blksz."
76 $XFS_INFO_PROG $SCRATCH_MNT | egrep -q 'realtime.*blocks=0' && \
77 _notrun "Filesystem should have a realtime volume"
79 echo "Consume free space"
80 fillerdir=$SCRATCH_MNT/fillerdir
81 nr_free_blks=$(stat -f -c '%f' $SCRATCH_MNT)
82 nr_free_blks=$((nr_free_blks * 90 / 100))
84 _fill_fs $((dbsize * nr_free_blks)) $fillerdir $dbsize 0 >> $seqres.full 2>&1
86 echo "Create fragmented filesystem"
87 for dentry in $(ls -1 $fillerdir/); do
88 $here/src/punch-alternating $fillerdir/$dentry >> $seqres.full
91 echo "Inject reduce_max_iextents error tag"
92 _scratch_inject_error reduce_max_iextents 1
94 echo "Inject bmap_alloc_minlen_extent error tag"
95 _scratch_inject_error bmap_alloc_minlen_extent 1
97 echo "Grow realtime volume"
98 $XFS_GROWFS_PROG -r $SCRATCH_MNT >> $seqres.full 2>&1
99 if [[ $? == 0 ]]; then
100 echo "Growfs succeeded; should have failed."
104 _scratch_unmount >> $seqres.full
106 echo "Verify rbmino's and rsumino's extent count"
107 for rtino in rbmino rsumino; do
108 ino=$(_scratch_xfs_get_metadata_field $rtino "sb 0")
109 echo "$rtino = $ino" >> $seqres.full
111 nextents=$(_scratch_get_iext_count $ino data || \
112 _fail "Unable to obtain inode fork's extent count")
113 if (( $nextents > 10 )); then
114 echo "Extent count overflow check failed: nextents = $nextents"
119 echo "Check filesystem"
123 rm -f $TEST_DIR/$seq.rtvol