Previous, fsck.f2fs only support i_links check and repair for orphan
and directory inode, this patch starts to check and repair i_links for
char, block, fifo, sock, symlink and regular inode.

Tested w/ below testcase:

dev=/dev/vda
mp=/mnt/f2fs
for ((i=0;i<8;i++)) do
        mkfs.f2fs -f $dev
        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 & fuser -k $mp/sock
                nlink=0
        elif [ $i == 6 ]; then
                ln -s file symlink
                nlink=0
        elif [ $i == 7 ]; then
                touch atomic
                f2fs_io write 1 0 1 zero atomic_commit ./atomic 2000 &
                rm atomic
                sync
                f2fs_io shutdown 2 ./
                nlink=1
                sleep 2
        fi

        cd ~/
        umount $mp

        inject.f2fs --node --mb i_links --nid 4 --val $nlink $dev

        fsck.f2fs -f $dev
        fsck.f2fs $dev
done

Signed-off-by: Chao Yu <c...@kernel.org>
---
 fsck/fsck.c | 33 +++++++++++++++++++++++++++------
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index ef9662b..ce88cfe 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -902,7 +902,9 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
        int need_fix = 0;
        int ret;
        u32 cluster_size = 1 << node_blk->i.i_log_cluster_size;
+       u32 target_links;
        bool is_aliasing = IS_DEVICE_ALIASING(&node_blk->i);
+       bool corrupted_nlink = false;
 
        if (!compressed)
                goto check_next;
@@ -1413,14 +1415,33 @@ skip_dot_fix:
                                        nid, (unsigned long)F2FS_BLKSIZE);
        }
 
-       if (ftype == F2FS_FT_ORPHAN && i_links) {
-               ASSERT_MSG("ino: 0x%x is orphan inode, but has i_links: %u",
-                               nid, i_links);
+       if (ftype == F2FS_FT_ORPHAN) {
+               if (i_links) {
+                       corrupted_nlink = true;
+                       target_links = 0;
+               }
+       } else if (ftype == F2FS_FT_CHRDEV || ftype == F2FS_FT_BLKDEV ||
+                       ftype == F2FS_FT_FIFO || ftype == F2FS_FT_SOCK ||
+                       ftype == F2FS_FT_SYMLINK) {
+               if (i_links != 1) {
+                       corrupted_nlink = true;
+                       target_links = 1;
+               }
+       } else if (ftype == F2FS_FT_REG_FILE) {
+               if (i_links == 0) {
+                       corrupted_nlink = true;
+                       target_links = 1;
+               }
+       }
+
+       if (corrupted_nlink) {
+               ASSERT_MSG("ino: 0x%x ftype: %d has i_links: %u",
+                                       nid, ftype, i_links);
                if (c.fix_on) {
-                       node_blk->i.i_links = 0;
+                       node_blk->i.i_links = cpu_to_le32(target_links);
                        need_fix = 1;
-                       FIX_MSG("ino: 0x%x orphan_inode, i_links= 0x%x -> 0",
-                                       nid, i_links);
+                       FIX_MSG("ino: 0x%x ftype: %d fix i_links: %u -> %u",
+                               nid, ftype, i_links, target_links);
                }
        }
 
-- 
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