4 # Test handling of invalid inode modes
6 # Set all possible file type values for different types of files
7 # and verify that xfs_repair detects the correct errors.
9 #-----------------------------------------------------------------------
11 # Copyright (C) 2016 CTERA Networks. All Rights Reserved.
12 # Author: Amir Goldstein <amir73il@gmail.com>
14 # This program is free software; you can redistribute it and/or
15 # modify it under the terms of the GNU General Public License as
16 # published by the Free Software Foundation.
18 # This program is distributed in the hope that it would be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write the Free Software Foundation,
25 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 #-----------------------------------------------------------------------
30 seqres=$RESULT_DIR/$seq
31 echo "QA output created by $seq"
34 status=1 # failure is the default!
35 trap "_cleanup; exit \$status" 0 1 2 3 15
42 # get standard environment, filters and checks
47 # real QA test starts here
52 # This test will corrupt fs intentionally, so there will be WARNINGs
53 # in dmesg as expected
58 _scratch_mkfs >>$seqres.full 2>&1
62 # Create our test files.
63 testdir=$SCRATCH_MNT/test
66 echo 123 > $testdir/DATA
68 ln -s $testdir/DATA $testdir/SYMLINK
69 mknod $testdir/CHRDEV c 1 1
70 mknod $testdir/BLKDEV b 1 1
73 xfs_info $SCRATCH_MNT | grep -q "ftype=1" && FTYPE_FEATURE=1
75 # Record test dir inode for xfs_repair filter
78 pino=$(ls -id $testdir | awk '{print $1}')
79 echo "s/inode $pino/PARENT_INO/" >> $inode_filter
80 echo "s/directory $pino/directory PARENT_INO/" >> $inode_filter
83 # Record inode numbers for xfs_db commands and xfs_repair filter
84 for f in DIR DATA EMPTY SYMLINK CHRDEV BLKDEV FIFO; do
85 ino=$(ls -id $testdir/$f | awk '{print $1}')
87 echo "s/inode $ino/${f}_INO/" >> $inode_filter
92 # Possible mode file type values (mode & S_IFMT) >> 12
93 dtypes="0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17"
94 echo "===== Find inode by file type:"
96 # Set all our test files to dt value
97 for ino in $inodes; do
98 _scratch_xfs_db -c "inode $ino" -c "print core.mode" | \
99 grep -q "0${dt}0...$" && \
100 (echo "dt=$dt => inode $ino" | sed -f $inode_filter)
103 for dt in $dtypes; do
105 echo "===== Setting dt=$dt to all files:"
106 # Set all our test files to dt value
107 for ino in $inodes; do
108 _scratch_xfs_db -x -c "inode $ino" -c "write core.mode 0${dt}0644"
110 # Repair should detect the inconsistencies
111 # For invalid dt values, all files would have been junked.
112 # For valid dt values, one test file is expected to be valid.
113 # The rest would either have wrong format or non matching dir ftype.
114 _scratch_xfs_repair -n 2>&1 | tee -a $seqres.full | \
115 _filter_repair | grep "^would have junked" | sed -f $inode_filter | sort -u
116 # If ftype feature is enabled, when setting file type to one of the
117 # special types (i.e. FIFO(1), CHRDEV(2),BLKDEV(6),SOCKET(14)),
118 # xfs_repair is expected to detect ftype mismatch error. Otherewise,
119 # xfs_repair is not expected to detect ftype mismatch error.
120 if [ "$FTYPE_FEATURE" = 1 ] && (echo ':1:2:6:14:' | grep -q ":$dt:"); then
121 _scratch_xfs_repair -n 2>&1 | grep -q "^would fix ftype mismatch" || \
122 echo "xfs_repair should fix ftype mismatch"
124 _scratch_xfs_repair -n 2>&1 | grep -q -v "^would fix ftype mismatch" || \
125 echo "xfs_repair should not fix ftype mismatch"
129 for file in DIR DATA EMPTY SYMLINK CHRDEV BLKDEV FIFO; do
131 ftype=$(stat --printf=%F $testdir/$file 2>$tmp.stat.err)
132 if [ -s $tmp.stat.err ]; then
135 echo "stat: '$testdir/$file' is a $ftype"
136 # Verify that readlink of a file posing as a symlink
137 # and ls of a file posing as a directory does not blow up.
138 # NOTE that ls DOES ASSERT with kernel 4.9 and XFS_DEBUG=y
139 # on malformed directory
140 if [ -d $testdir/$file ]; then
141 ls $testdir/$file &> /dev/null
142 elif [ -h $testdir/$file ]; then
143 readlink $testdir/$file &> /dev/null
150 # Repair should detect and junk all test files
151 _scratch_xfs_repair 2>&1 >> $seqres.full 2>&1 || _fail "xfs_repair should not fail"