Previously, once fsck.f2fs detects that directory missed '.' or
'..' dirent, it tags inode w/ F2FS_INLINE_DOTS flag, and expects
f2fs kernel module can repaire it online during it runs to lookup()
on target directory.

This patch abandons previous implementation, and do repaires directly.

Reviewed-by: Sheng Yong <shengy...@oppo.com>
Signed-off-by: Chao Yu <c...@kernel.org>
---
 fsck/fsck.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
 fsck/main.c |  4 +++-
 2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/fsck/fsck.c b/fsck/fsck.c
index 54ddc11..f8ea7f0 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -1307,17 +1307,52 @@ skip_blkcnt_fix:
                                                nid, i_links, child.links);
                        }
                }
-               if ((child.dot == 0 || child.dotdot == 0) &&
-                               !(node_blk->i.i_inline & F2FS_INLINE_DOTS)) {
-                       ASSERT_MSG("ino: 0x%x dot: %u, dotdot: %u",
+               if (child.dot == 0 || child.dotdot == 0) {
+                       ASSERT_MSG("ino: 0x%x has no '.' and/or '..' dirents, 
dot: %u, dotdot: %u",
                                        nid, child.dot, child.dotdot);
                        if (c.fix_on) {
-                               node_blk->i.i_inline |= F2FS_INLINE_DOTS;
+                               umode_t mode = le16_to_cpu(node_blk->i.i_mode);
+                               block_t blkaddr;
+
+                               ret = convert_inline_dentry(sbi, node_blk,
+                                                               &ni->blk_addr);
+                               FIX_MSG("convert inline dentry ino: %u, pino: 
%u, ret: %d",
+                                               nid, child_d->p_ino, ret);
+                               if (ret)
+                                       goto skip_dot_fix;
+
+                               if (child.dot == 0) {
+                                       char *name = ".";
+
+                                       ret = f2fs_add_link(sbi, node_blk,
+                                               (const unsigned char *)name,
+                                               1, nid, map_de_type(mode),
+                                               &blkaddr, 0);
+                                       FIX_MSG("add missing '%s' dirent in 
ino: %u, pino: %u, ret:%d",
+                                               name, nid, child_d->p_ino, ret);
+                                       if (ret)
+                                               goto skip_dot_fix;
+                               }
+
+                               if (child.dotdot == 0) {
+                                       char *name = "..";
+
+                                       ret = f2fs_add_link(sbi, node_blk,
+                                               (const unsigned char *)name,
+                                               2, child_d->p_ino,
+                                               map_de_type(mode),
+                                               &blkaddr, 0);
+                                       FIX_MSG("add missing '%s' dirent in 
ino: %u, pino: %u, ret:%d",
+                                               name, nid, child_d->p_ino, ret);
+                                       if (ret)
+                                               goto skip_dot_fix;
+                               }
+
                                need_fix = 1;
-                               FIX_MSG("Dir: 0x%x set inline_dots", nid);
                        }
                }
        }
+skip_dot_fix:
 
        i_gc_failures = le16_to_cpu(node_blk->i.i_gc_failures);
 
diff --git a/fsck/main.c b/fsck/main.c
index 8881936..4e0254d 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -892,6 +892,7 @@ static int do_fsck(struct f2fs_sb_info *sbi)
        u32 flag = le32_to_cpu(ckpt->ckpt_flags);
        u32 blk_cnt;
        struct f2fs_compr_blk_cnt cbc;
+       struct child_info child = { 0 };
        errcode_t ret;
 
        fsck_init(sbi);
@@ -957,8 +958,9 @@ static int do_fsck(struct f2fs_sb_info *sbi)
        if (fsck_sanity_check_nat(sbi, sbi->root_ino_num))
                fsck_chk_root_inode(sbi);
 
+       child.p_ino = sbi->root_ino_num;
        fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num,
-                       F2FS_FT_DIR, TYPE_INODE, &blk_cnt, &cbc, NULL);
+                       F2FS_FT_DIR, TYPE_INODE, &blk_cnt, &cbc, &child);
        fsck_chk_quota_files(sbi);
 
        ret = fsck_verify(sbi);
-- 
2.40.1



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

Reply via email to