2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2014 Red Hat, Inc. All Rights Reserved.
5 # FS QA Test No. xfs/010
7 # Test xfs_repair of the free inode btree (finobt). Make a couple targeted
8 # corruptions and verify that xfs_repair detects and repairs the filesystem to
12 seqres=$RESULT_DIR/$seq
13 echo "QA output created by $seq"
17 status=1 # failure is the default!
19 # get standard environment, filters and checks
27 _scratch_unmount 2>/dev/null
30 trap "_cleanup; exit \$status" 0 1 2 3 15
32 _sparse_inode_populate()
37 for i in $(seq 0 $count)
42 # Inode chunks are allocated 64 inodes at a time. If we remove 1 out of
43 # every 32 we allocated above, we'll end up leaving an inode or two free
44 # in each chunk. This ensures that most records are inserted into the
46 for i in $(seq 0 32 $count)
57 _corrupt_finobt_records()
61 # determine the root block of the finobt
62 free_root=`$XFS_DB_PROG -c "agi 0" -c "p free_root" $dev |
65 # Corrupt a freecount value. This should never exceed 64.
66 $XFS_DB_PROG -x -c "fsb $free_root" -c "type finobt" \
67 -c "write recs[1].freecount 70" $dev
69 # Create a corrupted non-free record, which should never appear in the
71 $XFS_DB_PROG -x -c "fsb $free_root" -c "type finobt" \
72 -c "write recs[2].freecount 0" $dev
73 $XFS_DB_PROG -x -c "fsb $free_root" -c "type finobt" \
74 -c "write recs[2].free 0" $dev
77 _corrupt_finobt_root()
81 # nuke the agi finobt root fields
84 -c "write -c free_root 0" \
85 -c "write -c free_level 0" \
86 $dev | grep -v "Allowing write of corrupted"
89 # real QA test starts here
93 _require_xfs_mkfs_finobt
98 _scratch_mkfs_xfs "-m crc=1,finobt=1 -d agcount=2" | _filter_mkfs 2>$seqres.full
100 # sparsely populate the fs such that we create records with free inodes
102 _sparse_inode_populate $SCRATCH_MNT 999
105 # corrupt some finobt records
106 _corrupt_finobt_records $SCRATCH_DEV
108 # repair should detect the inconsistencies
109 _scratch_xfs_repair 2>&1 | _filter_repair
112 # nuke the finobt root, repair will have to regenerate from the inobt
113 _corrupt_finobt_root $SCRATCH_DEV
115 filter_finobt_repair() {
116 sed -e '/^agi has bad CRC/d' \
117 -e '/^bad levels/d' \
118 -e '/^bad finobt block/d' | \
119 _filter_repair_lostblocks
122 _scratch_xfs_repair 2>&1 | filter_finobt_repair