| #! /bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2025 Chao Yu. All Rights Reserved. |
| # |
| # FS QA Test No. f2fs/009 |
| # |
| # This is a regression test to check whether fsck can handle corrupted |
| # nlinks correctly, it uses inject.f2fs to inject nlinks w/ wrong value, |
| # and expects fsck.f2fs can detect such corruption and do the repair. |
| # |
| . ./common/preamble |
| _begin_fstest auto quick |
| |
| _require_scratch |
| _require_inject_f2fs_command node i_links |
| _require_command "$(type -P socket)" socket |
| |
| _fixed_by_git_commit f2fs-tools 958cd6e \ |
| "fsck.f2fs: support to repair corrupted i_links" |
| |
| filename=$SCRATCH_MNT/foo |
| hardlink=$SCRATCH_MNT/bar |
| |
| _cleanup() |
| { |
| if [ -n "$pid" ]; then |
| kill $pid &> /dev/null |
| wait |
| fi |
| cd / |
| rm -r -f $tmp.* |
| } |
| |
| inject_and_check() |
| { |
| local nlink=$1 |
| local ino=$2 |
| |
| echo "ino:"$ino >> $seqres.full |
| echo "nlink:"$nlink >> $seqres.full |
| |
| _scratch_unmount |
| |
| $F2FS_INJECT_PROG --node --mb i_links --nid $ino --val $nlink $SCRATCH_DEV \ |
| >> $seqres.full || _fail "fail to inject" |
| |
| _check_scratch_fs >> $seqres.full 2>&1 && _fail "can't find corruption" |
| _repair_scratch_fs >> $seqres.full |
| _check_scratch_fs >> $seqres.full 2>&1 || _fail "fsck can't fix corruption" |
| |
| _scratch_mount |
| _scratch_unmount |
| |
| _scratch_mkfs >> $seqres.full |
| _scratch_mount |
| } |
| |
| check_links() |
| { |
| local nlink=$1 |
| local create_hardlink=$2 |
| local ino=$3 |
| |
| if [ -z $ino ]; then |
| ino=`stat -c '%i' $filename` |
| fi |
| |
| if [ $create_hardlink == 1 ]; then |
| ln $filename $hardlink |
| fi |
| |
| inject_and_check $nlink $ino |
| } |
| |
| _scratch_mkfs >> $seqres.full |
| _scratch_mount |
| |
| touch $filename |
| check_links 0 0 |
| |
| mkdir $filename |
| check_links 1 0 |
| |
| mknod $filename c 9 0 |
| check_links 0 0 |
| |
| mknod $filename b 8 0 |
| check_links 0 0 |
| |
| mkfifo $filename |
| check_links 0 0 |
| |
| socket -s $filename >> $seqres.full 2>&1 & |
| pid=$! |
| sleep 2 |
| ino=`stat -c '%i' $filename` |
| kill $pid >> $seqres.full 2>&1 |
| sleep 2 |
| check_links 0 0 $ino |
| |
| ln -s $SCRATCH_MNT/empty $filename |
| check_links 0 0 |
| |
| touch $filename |
| ino=`stat -c '%i' $filename` |
| $F2FS_IO_PROG write 1 0 1 zero atomic_commit $filename 5000 >> $seqres.full 2>&1 & |
| stat $filename >> $seqres.full |
| rm $filename |
| $F2FS_IO_PROG shutdown 1 $SCRATCH_MNT/ >> $seqres.full |
| sleep 6 |
| check_links 1 0 $ino |
| |
| # hardlink |
| touch $filename |
| check_links 0 1 |
| |
| mknod $filename c 9 0 |
| check_links 0 1 |
| |
| mknod $filename b 8 0 |
| check_links 0 1 |
| |
| mkfifo $filename |
| check_links 0 1 |
| |
| socket -s $filename >> $seqres.full 2>&1 & |
| pid=$! |
| sleep 2 |
| ino=`stat -c '%i' $filename` |
| kill $pid >> $seqres.full 2>&1 |
| sleep 2 |
| check_links 0 1 $ino |
| |
| ln -s $SCRATCH_MNT/empty $filename |
| check_links 0 1 |
| |
| echo "Silence is golden" |
| |
| status=0 |
| exit |