aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2015-03-30 12:09:36 -0700
committerDan Pasanen <dan.pasanen@gmail.com>2015-11-12 09:37:22 -0600
commitbbd949599fb06fc510c201570e4dd208963c683e (patch)
treee9c2c12aa668baee3cab406c1bda72fe211c4c4d
parent3d47578c077930719a50fa8991ceff19511a267a (diff)
downloadandroid_external_f2fs-tools-bbd949599fb06fc510c201570e4dd208963c683e.tar.gz
android_external_f2fs-tools-bbd949599fb06fc510c201570e4dd208963c683e.tar.bz2
android_external_f2fs-tools-bbd949599fb06fc510c201570e4dd208963c683e.zip
fsck.f2fs: fix missing i_links
If a child is a directory, we should increase parent's i_links. Previously, it counts direct dentry blocks excluding indirect blocks. This patch fixes to count child_cnt correctly in order to get precise i_links. Change-Id: I2f23f78e3eaeb99c82868cac6a0dec357b1b04a3 Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fsck/fsck.c34
-rw-r--r--fsck/fsck.h8
-rw-r--r--fsck/main.c2
3 files changed, 25 insertions, 19 deletions
diff --git a/fsck/fsck.c b/fsck/fsck.c
index 828d889..2325e4a 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -426,7 +426,7 @@ out:
int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
u32 nid, u8 *name, enum FILE_TYPE ftype, enum NODE_TYPE ntype,
- u32 *blk_cnt)
+ u32 *blk_cnt, u32 *child_cnt, u32 *child_files)
{
struct node_info ni;
struct f2fs_node *node_blk = NULL;
@@ -445,19 +445,19 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
f2fs_set_main_bitmap(sbi, ni.blk_addr,
CURSEG_WARM_NODE);
fsck_chk_dnode_blk(sbi, inode, nid, ftype, node_blk,
- blk_cnt, &ni);
+ blk_cnt, child_cnt, child_files, &ni);
break;
case TYPE_INDIRECT_NODE:
f2fs_set_main_bitmap(sbi, ni.blk_addr,
CURSEG_COLD_NODE);
fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
- blk_cnt);
+ blk_cnt, child_cnt, child_files);
break;
case TYPE_DOUBLE_INDIRECT_NODE:
f2fs_set_main_bitmap(sbi, ni.blk_addr,
CURSEG_COLD_NODE);
fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
- blk_cnt);
+ blk_cnt, child_cnt, child_files);
break;
default:
ASSERT(0);
@@ -610,7 +610,8 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
if (le32_to_cpu(node_blk->i.i_nid[idx]) != 0) {
ret = fsck_chk_node_blk(sbi, &node_blk->i,
le32_to_cpu(node_blk->i.i_nid[idx]),
- NULL, ftype, ntype, blk_cnt);
+ NULL, ftype, ntype, blk_cnt,
+ &child_cnt, &child_files);
if (!ret) {
*blk_cnt = *blk_cnt + 1;
} else if (config.fix_on) {
@@ -667,10 +668,10 @@ skip_blkcnt_fix:
int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
u32 nid, enum FILE_TYPE ftype, struct f2fs_node *node_blk,
- u32 *blk_cnt, struct node_info *ni)
+ u32 *blk_cnt, u32 *child_cnt, u32 *child_files,
+ struct node_info *ni)
{
int idx, ret;
- u32 child_cnt = 0, child_files = 0;
int need_fix = 0;
for (idx = 0; idx < ADDRS_PER_BLOCK; idx++) {
@@ -678,7 +679,7 @@ int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
continue;
ret = fsck_chk_data_blk(sbi,
le32_to_cpu(node_blk->dn.addr[idx]),
- &child_cnt, &child_files,
+ child_cnt, child_files,
le64_to_cpu(inode->i_blocks) == *blk_cnt, ftype,
nid, idx, ni->version);
if (!ret) {
@@ -697,7 +698,8 @@ int fsck_chk_dnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
}
int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
- enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt)
+ enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt,
+ u32 *child_cnt, u32 *child_files)
{
int ret;
int i = 0;
@@ -707,7 +709,8 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
continue;
ret = fsck_chk_node_blk(sbi, inode,
le32_to_cpu(node_blk->in.nid[i]), NULL,
- ftype, TYPE_DIRECT_NODE, blk_cnt);
+ ftype, TYPE_DIRECT_NODE, blk_cnt,
+ child_cnt, child_files);
if (!ret)
*blk_cnt = *blk_cnt + 1;
else if (ret == -EINVAL)
@@ -717,7 +720,8 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
}
int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
- enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt)
+ enum FILE_TYPE ftype, struct f2fs_node *node_blk, u32 *blk_cnt,
+ u32 *child_cnt, u32 *child_files)
{
int i = 0;
int ret = 0;
@@ -727,7 +731,8 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
continue;
ret = fsck_chk_node_blk(sbi, inode,
le32_to_cpu(node_blk->in.nid[i]), NULL,
- ftype, TYPE_INDIRECT_NODE, blk_cnt);
+ ftype, TYPE_INDIRECT_NODE, blk_cnt,
+ child_cnt, child_files);
if (!ret)
*blk_cnt = *blk_cnt + 1;
else if (ret == -EINVAL)
@@ -896,7 +901,7 @@ static int __chk_dentries(struct f2fs_sb_info *sbi, u32 *child_cnt,
blk_cnt = 1;
ret = fsck_chk_node_blk(sbi,
NULL, le32_to_cpu(dentry[i].ino), name,
- ftype, TYPE_INODE, &blk_cnt);
+ ftype, TYPE_INODE, &blk_cnt, NULL, NULL);
if (ret && config.fix_on) {
int j;
@@ -1060,7 +1065,8 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
DBG(1, "[%3d] ino [0x%x]\n", i, ino);
blk_cnt = 1;
ret = fsck_chk_node_blk(sbi, NULL, ino, NULL,
- F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt);
+ F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt,
+ NULL, NULL);
if (!ret)
new_blk->ino[new_entry_count++] =
orphan_blk->ino[j];
diff --git a/fsck/fsck.h b/fsck/fsck.h
index ffb3ae2..a640ccf 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -81,16 +81,16 @@ enum seg_type {
extern void fsck_chk_orphan_node(struct f2fs_sb_info *);
extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
- u8 *, enum FILE_TYPE, enum NODE_TYPE, u32 *);
+ u8 *, enum FILE_TYPE, enum NODE_TYPE, u32 *, u32 *, u32 *);
extern void fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE,
struct f2fs_node *, u32 *, struct node_info *);
extern int fsck_chk_dnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
- u32, enum FILE_TYPE, struct f2fs_node *, u32 *,
+ u32, enum FILE_TYPE, struct f2fs_node *, u32 *, u32 *, u32 *,
struct node_info *);
extern int fsck_chk_idnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
- enum FILE_TYPE, struct f2fs_node *, u32 *);
+ enum FILE_TYPE, struct f2fs_node *, u32 *, u32 *, u32 *);
extern int fsck_chk_didnode_blk(struct f2fs_sb_info *, struct f2fs_inode *,
- enum FILE_TYPE, struct f2fs_node *, u32 *);
+ enum FILE_TYPE, struct f2fs_node *, u32 *, u32 *, u32 *);
extern int fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32, u32 *, u32 *,
int, enum FILE_TYPE, u32, u16, u8);
extern int fsck_chk_dentry_blk(struct f2fs_sb_info *, u32, u32 *, u32 *, int);
diff --git a/fsck/main.c b/fsck/main.c
index e0b126b..ba76bf8 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -153,7 +153,7 @@ static void do_fsck(struct f2fs_sb_info *sbi)
/* Traverse all block recursively from root inode */
blk_cnt = 1;
fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num, (u8 *)"/",
- F2FS_FT_DIR, TYPE_INODE, &blk_cnt);
+ F2FS_FT_DIR, TYPE_INODE, &blk_cnt, NULL, NULL);
fsck_verify(sbi);
fsck_free(sbi);
}