2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2021 Chandan Babu R. All Rights Reserved.
7 # Verify that XFS does not cause inode fork's extent count to overflow when
8 # adding/removing directory entries.
10 seqres=$RESULT_DIR/$seq
11 echo "QA output created by $seq"
15 status=1 # failure is the default!
16 trap "_cleanup; exit \$status" 0 1 2 3 15
24 # get standard environment, filters and checks
30 # remove previous $seqres.full before test
33 # real QA test starts here
38 _require_test_program "punch-alternating"
39 _require_xfs_io_error_injection "reduce_max_iextents"
40 _require_xfs_io_error_injection "bmap_alloc_minlen_extent"
42 _scratch_mkfs_sized $((1024 * 1024 * 1024)) | _filter_mkfs >> $seqres.full 2> $tmp.mkfs
45 # Filesystems with directory block size greater than one FSB will not be tested,
46 # since "7 (i.e. XFS_DA_NODE_MAXDEPTH + 1 data block + 1 free block) * 2 (fsb
47 # count) = 14" is greater than the pseudo max extent count limit of 10.
48 # Extending the pseudo max limit won't help either. Consider the case where 1
49 # FSB is 1k in size and 1 dir block is 64k in size (i.e. fsb count = 64). In
50 # this case, the pseudo max limit has to be greater than 7 * 64 = 448 extents.
51 if (( $dirbsize > $dbsize )); then
52 _notrun "Directory block size ($dirbsize) is larger than FSB size ($dbsize)"
55 echo "Format and mount fs"
56 _scratch_mkfs_sized $((1024 * 1024 * 1024)) >> $seqres.full
57 _scratch_mount >> $seqres.full
59 echo "Consume free space"
60 fillerdir=$SCRATCH_MNT/fillerdir
61 nr_free_blks=$(stat -f -c '%f' $SCRATCH_MNT)
62 nr_free_blks=$((nr_free_blks * 90 / 100))
64 _fill_fs $((dbsize * nr_free_blks)) $fillerdir $dbsize 0 >> $seqres.full 2>&1
66 echo "Create fragmented filesystem"
67 for dentry in $(ls -1 $fillerdir/); do
68 $here/src/punch-alternating $fillerdir/$dentry >> $seqres.full
71 echo "Inject reduce_max_iextents error tag"
72 _scratch_inject_error reduce_max_iextents 1
74 echo "Inject bmap_alloc_minlen_extent error tag"
75 _scratch_inject_error bmap_alloc_minlen_extent 1
79 echo "* Create directory entries"
81 testdir=$SCRATCH_MNT/testdir
84 nr_dents=$((dbsize * 20 / dent_len))
85 for i in $(seq 1 $nr_dents); do
86 dentry="$(printf "%0255d" $i)"
87 touch ${testdir}/$dentry >> $seqres.full 2>&1 || break
90 echo "Verify directory's extent count"
91 nextents=$(_xfs_get_fsxattr nextents $testdir)
92 if (( $nextents > 10 )); then
93 echo "Extent count overflow check failed: nextents = $nextents"
99 echo "* Rename: Populate destination directory"
101 dstdir=$SCRATCH_MNT/dstdir
104 nr_dents=$((dirbsize * 20 / dent_len))
106 echo "Populate \$dstdir by moving new directory entries"
107 for i in $(seq 1 $nr_dents); do
108 dentry="$(printf "%0255d" $i)"
109 dentry=${SCRATCH_MNT}/${dentry}
110 touch $dentry || break
111 mv $dentry $dstdir >> $seqres.full 2>&1 || break
116 echo "Verify \$dstdir's extent count"
118 nextents=$(_xfs_get_fsxattr nextents $dstdir)
119 if (( $nextents > 10 )); then
120 echo "Extent count overflow check failed: nextents = $nextents"
126 echo "* Create multiple hard links to a single file"
128 testdir=$SCRATCH_MNT/testdir
131 testfile=$SCRATCH_MNT/testfile
134 nr_dents=$((dirbsize * 20 / dent_len))
136 echo "Create multiple hardlinks"
137 for i in $(seq 1 $nr_dents); do
138 dentry="$(printf "%0255d" $i)"
139 ln $testfile ${testdir}/${dentry} >> $seqres.full 2>&1 || break
144 echo "Verify directory's extent count"
145 nextents=$(_xfs_get_fsxattr nextents $testdir)
146 if (( $nextents > 10 )); then
147 echo "Extent count overflow check failed: nextents = $nextents"
153 echo "* Create multiple symbolic links to a single file"
155 testdir=$SCRATCH_MNT/testdir
158 testfile=$SCRATCH_MNT/testfile
161 nr_dents=$((dirbsize * 20 / dent_len))
163 echo "Create multiple symbolic links"
164 for i in $(seq 1 $nr_dents); do
165 dentry="$(printf "%0255d" $i)"
166 ln -s $testfile ${testdir}/${dentry} >> $seqres.full 2>&1 || break;
171 echo "Verify directory's extent count"
172 nextents=$(_xfs_get_fsxattr nextents $testdir)
173 if (( $nextents > 10 )); then
174 echo "Extent count overflow check failed: nextents = $nextents"