fsck.f2fs: fix missing dentries
If a directory has no dot and dotdot dentries, fsck.f2fs sets inline_dots for
the inode so that f2fs module can handle that properly.
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
diff --git a/fsck/fsck.c b/fsck/fsck.c
index d83f5a8..8211159 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -476,7 +476,7 @@
u32 *blk_cnt, struct node_info *ni)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
- struct child_info child = {0, 0};
+ struct child_info child = {2, 0, 0};
enum NODE_TYPE ntype;
u32 i_links = le32_to_cpu(node_blk->i.i_links);
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
@@ -631,26 +631,38 @@
}
}
skip_blkcnt_fix:
- if (ftype == F2FS_FT_DIR)
- DBG(1, "Directory Inode: 0x%x [%s] depth: %d has %d files\n\n",
- le32_to_cpu(node_blk->footer.ino),
- node_blk->i.i_name,
- le32_to_cpu(node_blk->i.i_current_depth),
- child.files);
if (ftype == F2FS_FT_ORPHAN)
DBG(1, "Orphan Inode: 0x%x [%s] i_blocks: %u\n\n",
le32_to_cpu(node_blk->footer.ino),
node_blk->i.i_name,
(u32)i_blocks);
- if (ftype == F2FS_FT_DIR && i_links != child.links) {
- ASSERT_MSG("ino: 0x%x has i_links: %u but real links: %u",
- nid, i_links, child.links);
- if (config.fix_on) {
- node_blk->i.i_links = cpu_to_le32(child.links);
- need_fix = 1;
- FIX_MSG("Dir: 0x%x i_links= 0x%x -> 0x%x",
+ if (ftype == F2FS_FT_DIR) {
+ DBG(1, "Directory Inode: 0x%x [%s] depth: %d has %d files\n\n",
+ le32_to_cpu(node_blk->footer.ino),
+ node_blk->i.i_name,
+ le32_to_cpu(node_blk->i.i_current_depth),
+ child.files);
+
+ if (i_links != child.links) {
+ ASSERT_MSG("ino: 0x%x i_links: %u, real links: %u",
+ nid, i_links, child.links);
+ if (config.fix_on) {
+ node_blk->i.i_links = cpu_to_le32(child.links);
+ need_fix = 1;
+ FIX_MSG("Dir: 0x%x i_links= 0x%x -> 0x%x",
nid, i_links, child.links);
+ }
+ }
+ if (child.dots < 2 &&
+ !(node_blk->i.i_inline & F2FS_INLINE_DOTS)) {
+ ASSERT_MSG("ino: 0x%x dots: %u",
+ nid, child.dots);
+ if (config.fix_on) {
+ node_blk->i.i_inline |= F2FS_INLINE_DOTS;
+ need_fix = 1;
+ FIX_MSG("Dir: 0x%x set inline_dots", nid);
+ }
}
}
@@ -877,7 +889,7 @@
name_len == 2)) {
i++;
free(name);
- child->links++;
+ child->dots++;
continue;
}
}
diff --git a/fsck/fsck.h b/fsck/fsck.h
index 97e2385..5eac45c 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -22,6 +22,7 @@
struct child_info {
u32 links;
u32 files;
+ u8 dots;
};
struct f2fs_fsck {
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 6ce58c2..d23ae1b 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -436,6 +436,7 @@
#define F2FS_INLINE_DATA 0x02 /* file inline data flag */
#define F2FS_INLINE_DENTRY 0x04 /* file inline dentry flag */
#define F2FS_DATA_EXIST 0x08 /* file inline data exist flag */
+#define F2FS_INLINE_DOTS 0x10 /* file having implicit dot dentries */
#define MAX_INLINE_DATA (sizeof(__le32) * (DEF_ADDRS_PER_INODE - \
F2FS_INLINE_XATTR_ADDRS - 1))