btrfs/012: check free size of scratch device before copying files
[xfstests-dev.git] / tests / xfs / 530
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2021 Chandan Babu R.  All Rights Reserved.
4 #
5 # FS QA Test 530
6 #
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.
9 #
10 seq=`basename $0`
11 seqres=$RESULT_DIR/$seq
12 echo "QA output created by $seq"
13
14 here=`pwd`
15 tmp=/tmp/$$
16 status=1        # failure is the default!
17 trap "_cleanup; exit \$status" 0 1 2 3 15
18
19 _cleanup()
20 {
21         cd /
22         _scratch_unmount >> $seqres.full 2>&1
23         test -e "$rtdev" && losetup -d $rtdev >> $seqres.full 2>&1
24         rm -f $tmp.* $TEST_DIR/$seq.rtvol
25 }
26
27 # get standard environment, filters and checks
28 . ./common/rc
29 . ./common/filter
30 . ./common/inject
31 . ./common/populate
32
33 # remove previous $seqres.full before test
34 rm -f $seqres.full
35
36 # real QA test starts here
37
38 _supported_fs xfs
39 # Note that we don't _require_realtime because we synthesize a rt volume
40 # below.
41 _require_test
42 _require_xfs_debug
43 _require_test_program "punch-alternating"
44 _require_xfs_io_error_injection "reduce_max_iextents"
45 _require_xfs_io_error_injection "bmap_alloc_minlen_extent"
46 _require_scratch_nocheck
47
48 echo "* Test extending rt inodes"
49
50 _scratch_mkfs | _filter_mkfs >> $seqres.full 2> $tmp.mkfs
51 . $tmp.mkfs
52
53 echo "Create fake rt volume"
54 nr_bitmap_blks=25
55 nr_bits=$((nr_bitmap_blks * dbsize * 8))
56
57 # Realtime extent size has to be atleast 4k in size.
58 if (( $dbsize < 4096 )); then
59         rtextsz=4096
60 else
61         rtextsz=$dbsize
62 fi
63
64 rtdevsz=$((nr_bits * rtextsz))
65 truncate -s $rtdevsz $TEST_DIR/$seq.rtvol
66 rtdev=$(_create_loop_device $TEST_DIR/$seq.rtvol)
67
68 echo "Format and mount rt volume"
69
70 export USE_EXTERNAL=yes
71 export SCRATCH_RTDEV=$rtdev
72 _scratch_mkfs -d size=$((1024 * 1024 * 1024)) -b size=${dbsize} \
73               -r size=${rtextsz},extsize=${rtextsz} >> $seqres.full
74 _try_scratch_mount || _notrun "Couldn't mount fs with synthetic rt volume"
75
76 echo "Consume free space"
77 fillerdir=$SCRATCH_MNT/fillerdir
78 nr_free_blks=$(stat -f -c '%f' $SCRATCH_MNT)
79 nr_free_blks=$((nr_free_blks * 90 / 100))
80
81 _fill_fs $((dbsize * nr_free_blks)) $fillerdir $dbsize 0 >> $seqres.full 2>&1
82
83 echo "Create fragmented filesystem"
84 for dentry in $(ls -1 $fillerdir/); do
85         $here/src/punch-alternating $fillerdir/$dentry >> $seqres.full
86 done
87
88 echo "Inject reduce_max_iextents error tag"
89 _scratch_inject_error reduce_max_iextents 1
90
91 echo "Inject bmap_alloc_minlen_extent error tag"
92 _scratch_inject_error bmap_alloc_minlen_extent 1
93
94 echo "Grow realtime volume"
95 $XFS_GROWFS_PROG -r $SCRATCH_MNT >> $seqres.full 2>&1
96 if [[ $? == 0 ]]; then
97         echo "Growfs succeeded; should have failed."
98         exit 1
99 fi
100
101 _scratch_unmount >> $seqres.full
102
103 echo "Verify rbmino's and rsumino's extent count"
104 for rtino in rbmino rsumino; do
105         ino=$(_scratch_xfs_get_metadata_field $rtino "sb 0")
106         echo "$rtino = $ino" >> $seqres.full
107
108         nextents=$(_scratch_get_iext_count $ino data || \
109                         _fail "Unable to obtain inode fork's extent count")
110         if (( $nextents > 10 )); then
111                 echo "Extent count overflow check failed: nextents = $nextents"
112                 exit 1
113         fi
114 done
115
116 echo "Check filesystem"
117 _check_scratch_fs
118
119 losetup -d $rtdev
120 rm -f $TEST_DIR/$seq.rtvol
121
122 # success, all done
123 status=0
124 exit