Skip to content

Commit

Permalink
fsck.f2fs: support to add missing '.' or '..' dirent
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Chao Yu <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
  • Loading branch information
chaseyu authored and Jaegeuk Kim committed Sep 6, 2024
1 parent b6056ff commit 4c7114b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
45 changes: 40 additions & 5 deletions fsck/fsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,17 +1307,52 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
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);

Expand Down
4 changes: 3 additions & 1 deletion fsck/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,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);
Expand Down Expand Up @@ -973,8 +974,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);
Expand Down

0 comments on commit 4c7114b

Please sign in to comment.