#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (C) 2016 CTERA Networks. All Rights Reserved. # # FSQA Test No. 348 # # Test handling of invalid inode modes # # Set all possible file type values for different types of files # and verify that xfs_repair detects the correct errors. # seq=`basename $0` seqres=$RESULT_DIR/$seq echo "QA output created by $seq" tmp=/tmp/$$ status=1 # failure is the default! trap "_cleanup; exit \$status" 0 1 2 3 15 _cleanup() { rm -f $tmp.* } # get standard environment, filters and checks . ./common/rc . ./common/filter . ./common/repair # real QA test starts here _supported_fs xfs _supported_os Linux _require_scratch # This test will corrupt fs intentionally, so there will be WARNINGs # in dmesg as expected _disable_dmesg_check rm -f $seqres.full _scratch_mkfs >>$seqres.full 2>&1 _scratch_mount # Create our test files. testdir=$SCRATCH_MNT/test mkdir -p $testdir mkdir $testdir/DIR echo 123 > $testdir/DATA touch $testdir/EMPTY ln -s $testdir/DATA $testdir/SYMLINK mknod $testdir/CHRDEV c 1 1 mknod $testdir/BLKDEV b 1 1 mknod $testdir/FIFO p $XFS_INFO_PROG $SCRATCH_MNT | grep -q "ftype=1" && FTYPE_FEATURE=1 # Record test dir inode for xfs_repair filter inode_filter=$tmp.sed rm -f $inode_filter pino=$(ls -id $testdir | awk '{print $1}') echo "s/inode $pino/PARENT_INO/" >> $inode_filter echo "s/directory $pino/directory PARENT_INO/" >> $inode_filter inodes="" # Record inode numbers for xfs_db commands and xfs_repair filter for f in DIR DATA EMPTY SYMLINK CHRDEV BLKDEV FIFO; do ino=$(ls -id $testdir/$f | awk '{print $1}') inodes="$inodes $ino" echo "s/inode $ino/${f}_INO/" >> $inode_filter done _scratch_unmount # Possible mode file type values (mode & S_IFMT) >> 12 dtypes="0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17" echo "===== Find inode by file type:" for dt in $dtypes; do # Set all our test files to dt value for ino in $inodes; do _scratch_xfs_db -c "inode $ino" -c "print core.mode" | \ grep -q "0${dt}0...$" && \ (echo "dt=$dt => inode $ino" | sed -f $inode_filter) done done for dt in $dtypes; do echo echo "===== Setting dt=$dt to all files:" # Set all our test files to dt value for ino in $inodes; do _scratch_xfs_db -x -c "inode $ino" -c "write core.mode 0${dt}0644" done # Repair should detect the inconsistencies # For invalid dt values, all files would have been junked. # For valid dt values, one test file is expected to be valid. # The rest would either have wrong format or non matching dir ftype. _scratch_xfs_repair -n 2>&1 | tee -a $seqres.full | \ _filter_repair | grep "^would have junked" | sed -f $inode_filter | sort -u # If ftype feature is enabled, when setting file type to one of the # special types (i.e. FIFO(1), CHRDEV(2),BLKDEV(6),SOCKET(14)), # xfs_repair is expected to detect ftype mismatch error. Otherewise, # xfs_repair is not expected to detect ftype mismatch error. if [ "$FTYPE_FEATURE" = 1 ] && (echo ':1:2:6:14:' | grep -q ":$dt:"); then _scratch_xfs_repair -n 2>&1 | grep -q "^would fix ftype mismatch" || \ echo "xfs_repair should fix ftype mismatch" else _scratch_xfs_repair -n 2>&1 | grep -q -v "^would fix ftype mismatch" || \ echo "xfs_repair should not fix ftype mismatch" fi _scratch_mount for file in DIR DATA EMPTY SYMLINK CHRDEV BLKDEV FIFO; do rm -f $tmp.stat.err ftype=$(stat --printf=%F $testdir/$file 2>$tmp.stat.err) if [ -s $tmp.stat.err ]; then cat $tmp.stat.err else echo "stat: '$testdir/$file' is a $ftype" # Verify that readlink of a file posing as a symlink # and ls of a file posing as a directory does not blow up. # NOTE that ls DOES ASSERT with kernel 4.9 and XFS_DEBUG=y # on malformed directory if [ -d $testdir/$file ]; then ls $testdir/$file &> /dev/null elif [ -h $testdir/$file ]; then readlink $testdir/$file &> /dev/null fi fi | _filter_scratch done _scratch_unmount done # Repair should detect and junk all test files _scratch_xfs_repair 2>&1 >> $seqres.full 2>&1 || _fail "xfs_repair should not fail" status=0 exit