2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2017 Red Hat, Inc. All Rights Reserved.
7 # Test readdir on fragmented multi-fsb dir blocks
9 # If the readahead map ends with a partial multi-fsb dir
10 # block, the loop at the end of xfs_dir2_leaf_readbuf() may
11 # walk off the end of the mapping array, read garbage,
12 # corrupt the loop control counter, and never return.
14 # Failure is a hang; KASAN should also catch this.
17 seqres=$RESULT_DIR/$seq
18 echo "QA output created by $seq"
22 status=1 # failure is the default!
23 trap "_cleanup; exit \$status" 0 1 2 3 15
31 # get standard environment, filters and checks
35 # remove previous $seqres.full before test
38 # real QA test starts here
40 # Modify as appropriate.
44 _require_test_program "punch-alternating"
45 _require_xfs_io_command "falloc"
46 _require_xfs_io_command "fpunch"
48 # We want to mkfs with a very specific geometry
50 _scratch_mkfs "-d size=512m -n size=8192 -i size=1024" >> $seqres.full 2>&1 \
51 || _fail "mkfs failed"
54 # Make a ton of mostly-empty inode clusters so we can always
56 mkdir $SCRATCH_MNT/tmp
57 for I in `seq 1 10000`; do touch $SCRATCH_MNT/tmp/$I; done
59 # These mostly-empty clusters will live here:
60 mkdir $SCRATCH_MNT/clusters
61 for I in `seq 1 32 10000`; do
62 mv $SCRATCH_MNT/tmp/$I $SCRATCH_MNT/clusters;
64 rm -rf $SCRATCH_MNT/tmp
66 # Make our test dir with a couple blocks, should be contiguous
67 mkdir $SCRATCH_MNT/testdir
68 # roughly 20 chars per file
69 for I in `seq 1 100`; do
70 touch $SCRATCH_MNT/testdir/12345678901234567890$I;
74 $XFS_IO_PROG -f -c "falloc 0 70m" $SCRATCH_MNT/fragfile ||
75 _fail "Could not allocate space"
77 # Now completely fragment freespace.
79 space=$(stat -f -c '%f * %S * 95 / 100' $SCRATCH_MNT | $BC_PROG)
80 $XFS_IO_PROG -f -c "falloc 0 $space" $SCRATCH_MNT/fillfile ||
81 _fail "Could not allocate space"
83 df -h $SCRATCH_MNT >> $seqres.full 2>&1
85 # Fill remaining space; let this run to failure
86 dd if=/dev/zero of=$SCRATCH_MNT/spacefile1 oflag=direct >> $seqres.full 2>&1
87 # Fragment our all-consuming file
88 $here/src/punch-alternating $SCRATCH_MNT/fragfile >> $seqres.full 2>&1
90 # Punching might have freed up large-ish swaths of metadata
91 # Consume hopefully any remaining contiguous freespace
92 # (and then some for good measure)
93 dd conv=fsync if=/dev/zero of=$SCRATCH_MNT/spacefile2 bs=1M count=64 >> $seqres.full 2>&1
95 # Now populate the directory so that it must allocate these
97 for I in `seq 1 1400`; do
98 touch $SCRATCH_MNT/testdir/12345678901234567890$I;
101 # Now traverse that ugly thing!
102 find $SCRATCH_MNT/testdir | sort | _filter_scratch | md5sum