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 _begin_fstest auto quick repair
14 # Import common functions.
18 # Override the default cleanup function.
22 _scratch_unmount 2>/dev/null
26 _sparse_inode_populate()
31 for i in $(seq 0 $count)
36 # Inode chunks are allocated 64 inodes at a time. If we remove 1 out of
37 # every 32 we allocated above, we'll end up leaving an inode or two free
38 # in each chunk. This ensures that most records are inserted into the
40 for i in $(seq 0 32 $count)
51 _corrupt_finobt_records()
55 # determine the root block of the finobt
56 free_root=`$XFS_DB_PROG -c "agi 0" -c "p free_root" $dev |
59 # Corrupt a freecount value. This should never exceed 64.
60 $XFS_DB_PROG -x -c "fsb $free_root" -c "type finobt" \
61 -c "write recs[1].freecount 70" $dev
63 # Create a corrupted non-free record, which should never appear in the
65 $XFS_DB_PROG -x -c "fsb $free_root" -c "type finobt" \
66 -c "write recs[2].freecount 0" $dev
67 $XFS_DB_PROG -x -c "fsb $free_root" -c "type finobt" \
68 -c "write recs[2].free 0" $dev
71 _corrupt_finobt_root()
75 # nuke the agi finobt root fields
78 -c "write -c free_root 0" \
79 -c "write -c free_level 0" \
80 $dev | grep -v "Allowing write of corrupted"
83 # real QA test starts here
87 _require_xfs_mkfs_finobt
90 _scratch_mkfs_xfs "-m crc=1,finobt=1 -d agcount=2" | _filter_mkfs 2>$seqres.full
92 # sparsely populate the fs such that we create records with free inodes
94 _sparse_inode_populate $SCRATCH_MNT 999
97 # corrupt some finobt records
98 _corrupt_finobt_records $SCRATCH_DEV
100 # repair should detect the inconsistencies
101 _scratch_xfs_repair 2>&1 | _filter_repair
104 # nuke the finobt root, repair will have to regenerate from the inobt
105 _corrupt_finobt_root $SCRATCH_DEV
107 filter_finobt_repair() {
108 sed -e '/^agi has bad CRC/d' \
109 -e '/^bad levels/d' \
110 -e '/^bad finobt block/d' | \
111 _filter_repair_lostblocks
114 _scratch_xfs_repair 2>&1 | filter_finobt_repair