fsck.f2fs missed to check and repair zeroed i_links for char, block,
fifo, sock, symlink and regular inode, fix it.

Tested w/ below testcase:

dev=/dev/vda
mp=/mnt/f2fs
for ((i=0;i<14;i++)) do
        echo "testcase #"$i
        mkfs.f2fs -f $dev >/dev/null 2>&1
        if [ $? != 0 ]; then
                exit
        fi
        mount $dev $mp
        cd $mp

        if [ $i == 0 ]; then
                touch file
                nlink=0
        elif [ $i == 1 ]; then
                mkdir dir
                nlink=1
        elif [ $i == 2 ]; then
                mknod charactor c 9 0
                nlink=0
        elif [ $i == 3 ]; then
                mknod blockdev b 8 0
                nlink=0
        elif [ $i == 4 ]; then
                mkfifo pipe
                nlink=0
        elif [ $i == 5 ]; then
                socket -s $mp/sock & sleep 2
                fuser -k $mp/sock
                nlink=0
        elif [ $i == 6 ]; then
                ln -s file symlink
                nlink=0
        elif [ $i == 7 ]; then
                # orphan inode
                touch atomic
                f2fs_io write 1 0 1 zero atomic_commit ./atomic 2000 &
                rm atomic
                sync
                f2fs_io shutdown 2 ./
                nlink=1
                sleep 2
        elif [ $i == 8 ]; then
                # hardlink on file
                touch file
                ln file hardlink
                nlink=0
        elif [ $i == 9 ]; then
                # hardlink on charactor
                mknod charactor c 9 0
                ln charactor hardlink
                nlink=0
        elif [ $i == 10 ]; then
                # hardlink on blockdev
                mknod blockdev b 8 0
                ln blockdev hardlink
                nlink=0
        elif [ $i == 11 ]; then
                # hardlink on pipe
                mkfifo pipe
                ln pipe hardlink
                nlink=0
        elif [ $i == 12 ]; then
                # hardlink on socket
                socket -s $mp/sock & sleep 2
                fuser -k $mp/sock
                ln sock hardlink
                nlink=0
        elif [ $i == 13 ]; then
                # hardlink on symlink
                ln -s file symlink
                ln symlink hardlink
                nlink=0
        fi

        cd ~/
        umount $mp

        inject.f2fs --node --mb i_links --nid 4 --val $nlink $dev
        if [ $? != 0 ]; then
                exit
        fi

        fsck.f2fs -f $dev
        if [ $? != 1 ]; then
                exit
        fi
        fsck.f2fs $dev
        if [ $? != 0 ]; then
                exit
        fi

        mount $dev $mp
        stat $mp/*
        umount $mp
done

Signed-off-by: Chao Yu <c...@kernel.org>
---
v2:
- update testcase to cover hardlink of non-dir inode
- fix zeroed i_links only
 fsck/fsck.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index aa3fb97..8155cbd 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -942,6 +942,22 @@ check_next:
                if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
                        f2fs_set_main_bitmap(sbi, ni->blk_addr,
                                                        CURSEG_WARM_NODE);
+
+                       if (i_links == 0 && (ftype == F2FS_FT_CHRDEV ||
+                               ftype == F2FS_FT_BLKDEV ||
+                               ftype == F2FS_FT_FIFO ||
+                               ftype == F2FS_FT_SOCK ||
+                               ftype == F2FS_FT_SYMLINK ||
+                               ftype == F2FS_FT_REG_FILE)) {
+                               ASSERT_MSG("ino: 0x%x ftype: %d has i_links: 
%u",
+                                                       nid, ftype, i_links);
+                               if (c.fix_on) {
+                                       node_blk->i.i_links = cpu_to_le32(1);
+                                       need_fix = 1;
+                                       FIX_MSG("ino: 0x%x ftype: %d fix 
i_links: %u -> 1",
+                                               nid, ftype, i_links);
+                               }
+                       }
                        if (i_links > 1 && ftype != F2FS_FT_ORPHAN &&
                                        !is_qf_ino(F2FS_RAW_SUPER(sbi), nid)) {
                                /* First time. Create new hard link node */
-- 
2.48.1.658.g4767266eb4-goog



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to