aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2014-08-27 17:06:17 -0700
committerJaegeuk Kim <jaegeuk@kernel.org>2014-08-29 13:43:29 -0700
commit5cd7001f5dfaf1c7f275826c44dcf203d49f4cce (patch)
treef8cbe7747490732bfbcc92415c4586bf41deb569
parent2701c94ab00c350a41ab874a52846b0a93bad9e1 (diff)
downloadandroid_external_f2fs-tools-5cd7001f5dfaf1c7f275826c44dcf203d49f4cce.tar.gz
android_external_f2fs-tools-5cd7001f5dfaf1c7f275826c44dcf203d49f4cce.tar.bz2
android_external_f2fs-tools-5cd7001f5dfaf1c7f275826c44dcf203d49f4cce.zip
fsck.f2fs: handle error cases
Do sanity check first and then update metadata. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fsck/fsck.c344
-rw-r--r--fsck/fsck.h11
-rw-r--r--fsck/main.c40
-rw-r--r--fsck/mount.c3
-rw-r--r--include/f2fs_fs.h4
5 files changed, 205 insertions, 197 deletions
diff --git a/fsck/fsck.c b/fsck/fsck.c
index d2781d9..9ebe2be 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -80,10 +80,8 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct hard_link_node *node = NULL, *prev = NULL;
- if (fsck->hard_link_list_head == NULL) {
- ASSERT(0);
- return -1;
- }
+ if (fsck->hard_link_list_head == NULL)
+ return -EINVAL;
node = fsck->hard_link_list_head;
@@ -92,10 +90,8 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)
node = node->next;
}
- if (node == NULL || (nid != node->nid)) {
- ASSERT(0);
- return -1;
- }
+ if (node == NULL || (nid != node->nid))
+ return -EINVAL;
/* Decrease link count */
node->links = node->links - 1;
@@ -108,9 +104,7 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)
prev->next = node->next;
free(node);
}
-
return 0;
-
}
static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid,
@@ -138,14 +132,16 @@ static int is_valid_ssa_node_blk(struct f2fs_sb_info *sbi, u32 nid,
le32_to_cpu(sum_entry.nid));
DBG(0, "--> node block's nid [0x%x]\n", nid);
ASSERT_MSG("Invalid node seg summary\n");
+ return -EINVAL;
}
+ return 0;
} else if (ret == SEG_TYPE_CUR_NODE) {
/* current node segment has no ssa */
+ return 0;
} else {
ASSERT_MSG("Invalid return value of 'get_sum_entry'");
}
-
- return 1;
+ return -EINVAL;
}
static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
@@ -177,114 +173,145 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
return 1;
}
-int fsck_chk_node_blk(struct f2fs_sb_info *sbi,
- struct f2fs_inode *inode,
- u32 nid,
- enum FILE_TYPE ftype,
- enum NODE_TYPE ntype,
- u32 *blk_cnt)
+static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
+ struct f2fs_node *node_blk,
+ enum FILE_TYPE ftype, enum NODE_TYPE ntype,
+ struct node_info *ni)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
- struct node_info ni;
- struct f2fs_node *node_blk = NULL;
- int ret = 0;
+ int ret;
if (!IS_VALID_NID(sbi, nid)) {
ASSERT_MSG("nid is not valid. [0x%x]", nid);
- return 0;
+ return -EINVAL;
}
- if (ftype != F2FS_FT_ORPHAN ||
- f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0x0)
- f2fs_clear_bit(nid, fsck->nat_area_bitmap);
- else
- ASSERT_MSG("nid duplicated [0x%x]\n", nid);
+ get_node_info(sbi, nid, ni);
+ if (ni->blk_addr == NEW_ADDR) {
+ ASSERT_MSG("nid is NEW_ADDR. [0x%x]", nid);
+ return -EINVAL;
+ }
- get_node_info(sbi, nid, &ni);
+ if (!IS_VALID_BLK_ADDR(sbi, ni->blk_addr)) {
+ ASSERT_MSG("blkaddres is not valid. [0x%x]", ni->blk_addr);
+ return -EINVAL;
+ }
- /* Is it reserved block?
- * if block addresss was 0xffff,ffff,ffff,ffff
- * it means that block was already allocated, but not stored in disk
- */
- if (ni.blk_addr == NEW_ADDR) {
- fsck->chk.valid_blk_cnt++;
- fsck->chk.valid_node_cnt++;
- if (ntype == TYPE_INODE)
- fsck->chk.valid_inode_cnt++;
- return 0;
+ if (is_valid_ssa_node_blk(sbi, nid, ni->blk_addr)) {
+ ASSERT_MSG("summary node block is not valid. [0x%x]", nid);
+ return -EINVAL;
}
- if (!IS_VALID_BLK_ADDR(sbi, ni.blk_addr)) {
- ASSERT_MSG("blkaddres is not valid. [0x%x]", ni.blk_addr);
- return 0;
+ ret = dev_read_block(node_blk, ni->blk_addr);
+ ASSERT(ret >= 0);
+
+ if (ntype == TYPE_INODE &&
+ node_blk->footer.nid != node_blk->footer.ino) {
+ ASSERT_MSG("nid[0x%x] footer.nid[0x%x] footer.ino[0x%x]",
+ nid, le32_to_cpu(node_blk->footer.nid),
+ le32_to_cpu(node_blk->footer.ino));
+ return -EINVAL;
+ }
+ if (ntype != TYPE_INODE &&
+ node_blk->footer.nid == node_blk->footer.ino) {
+ ASSERT_MSG("nid[0x%x] footer.nid[0x%x] footer.ino[0x%x]",
+ nid, le32_to_cpu(node_blk->footer.nid),
+ le32_to_cpu(node_blk->footer.ino));
+ return -EINVAL;
+ }
+
+ if (le32_to_cpu(node_blk->footer.nid) != nid) {
+ ASSERT_MSG("nid[0x%x] blk_addr[0x%x] footer.nid[0x%x]",
+ nid, ni->blk_addr,
+ le32_to_cpu(node_blk->footer.nid));
+ return -EINVAL;
+ }
+
+ if (ntype == TYPE_XATTR) {
+ u32 flag = le32_to_cpu(node_blk->footer.flag);
+
+ if ((flag >> OFFSET_BIT_SHIFT) != XATTR_NODE_OFFSET) {
+ ASSERT_MSG("xnid[0x%x] has wrong ofs:[0x%x]",
+ nid, flag);
+ return -EINVAL;
+ }
+ }
+
+ if ((ntype == TYPE_INODE && ftype == F2FS_FT_DIR) ||
+ (ntype == TYPE_XATTR && ftype == F2FS_FT_XATTR)) {
+ /* not included '.' & '..' */
+ if (f2fs_test_main_bitmap(sbi, ni->blk_addr) != 0) {
+ ASSERT_MSG("Duplicated node blk. nid[0x%x][0x%x]\n",
+ nid, ni->blk_addr);
+ return -EINVAL;
+ }
}
- is_valid_ssa_node_blk(sbi, nid, ni.blk_addr);
+ /* workaround to fix later */
+ if (ftype != F2FS_FT_ORPHAN ||
+ f2fs_test_bit(nid, fsck->nat_area_bitmap) != 0)
+ f2fs_clear_bit(nid, fsck->nat_area_bitmap);
+ else
+ ASSERT_MSG("orphan or xattr nid is duplicated [0x%x]\n",
+ nid);
- if (f2fs_test_sit_bitmap(sbi, ni.blk_addr) == 0)
- ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]", ni.blk_addr);
+ if (f2fs_test_sit_bitmap(sbi, ni->blk_addr) == 0)
+ ASSERT_MSG("SIT bitmap is 0x0. blk_addr[0x%x]",
+ ni->blk_addr);
- if (f2fs_test_main_bitmap(sbi, ni.blk_addr) == 0) {
+ if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
fsck->chk.valid_blk_cnt++;
fsck->chk.valid_node_cnt++;
}
+ return 0;
+}
+
+int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,
+ u32 nid, enum FILE_TYPE ftype, enum NODE_TYPE ntype,
+ u32 *blk_cnt)
+{
+ struct node_info ni;
+ struct f2fs_node *node_blk = NULL;
node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
ASSERT(node_blk != NULL);
- ret = dev_read_block(node_blk, ni.blk_addr);
- ASSERT(ret >= 0);
-
- if (nid != le32_to_cpu(node_blk->footer.nid))
- ASSERT_MSG("nid[0x%x] blk_addr[0x%x] footer.nid[0x%x]",
- nid, ni.blk_addr, le32_to_cpu(node_blk->footer.nid));
+ if (sanity_check_nid(sbi, nid, node_blk, ftype, ntype, &ni))
+ goto err;
if (ntype == TYPE_INODE) {
- ret = fsck_chk_inode_blk(sbi,
- nid,
- ftype,
- node_blk,
- blk_cnt,
- &ni);
+ fsck_chk_inode_blk(sbi, nid, ftype, node_blk, blk_cnt, &ni);
} else {
- /* it's not inode */
- ASSERT(node_blk->footer.nid != node_blk->footer.ino);
-
- if (f2fs_test_main_bitmap(sbi, ni.blk_addr) != 0)
- ASSERT_MSG("Duplicated node blk. nid[0x%x][0x%x]\n",
- nid, ni.blk_addr);
-
f2fs_set_main_bitmap(sbi, ni.blk_addr);
switch (ntype) {
case TYPE_DIRECT_NODE:
- ret = fsck_chk_dnode_blk(sbi, inode, nid, ftype,
- node_blk, blk_cnt, &ni);
+ fsck_chk_dnode_blk(sbi, inode, nid, ftype, node_blk,
+ blk_cnt, &ni);
break;
case TYPE_INDIRECT_NODE:
- ret = fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
+ fsck_chk_idnode_blk(sbi, inode, ftype, node_blk,
blk_cnt);
break;
case TYPE_DOUBLE_INDIRECT_NODE:
- ret = fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
+ fsck_chk_didnode_blk(sbi, inode, ftype, node_blk,
blk_cnt);
break;
default:
ASSERT(0);
}
}
- ASSERT(ret >= 0);
-
free(node_blk);
return 0;
+err:
+ free(node_blk);
+ return -EINVAL;
}
-int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
- u32 nid,
- enum FILE_TYPE ftype,
- struct f2fs_node *node_blk,
- u32 *blk_cnt,
- struct node_info *ni)
+/* start with valid nid and blkaddr */
+void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,
+ enum FILE_TYPE ftype, struct f2fs_node *node_blk,
+ u32 *blk_cnt, struct node_info *ni)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
u32 child_cnt = 0, child_files = 0;
@@ -292,31 +319,13 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
u32 i_links = le32_to_cpu(node_blk->i.i_links);
u64 i_blocks = le64_to_cpu(node_blk->i.i_blocks);
unsigned int idx = 0;
- int ret = 0;
-
- ASSERT(node_blk->footer.nid == node_blk->footer.ino);
- ASSERT(le32_to_cpu(node_blk->footer.nid) == nid);
+ int ret;
if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0)
fsck->chk.valid_inode_cnt++;
- /* Orphan node. i_links should be 0 */
- if (ftype == F2FS_FT_ORPHAN) {
- ASSERT(i_links == 0);
- } else {
- ASSERT(i_links > 0);
- }
-
if (ftype == F2FS_FT_DIR) {
-
- /* not included '.' & '..' */
- if (f2fs_test_main_bitmap(sbi, ni->blk_addr) != 0) {
- DBG(0, "Duplicated inode blk. ino[0x%x][0x%x]\n",
- nid, ni->blk_addr);
- ASSERT(0);
- }
f2fs_set_main_bitmap(sbi, ni->blk_addr);
-
} else {
if (f2fs_test_main_bitmap(sbi, ni->blk_addr) == 0) {
f2fs_set_main_bitmap(sbi, ni->blk_addr);
@@ -326,21 +335,15 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
fsck->chk.multi_hard_link_files++;
}
} else {
- if (i_links <= 1) {
- DBG(0, "Error. Node ID [0x%x]."
- " There are one more hard links."
- " But i_links is [0x%x]\n",
+ DBG(3, "[0x%x] has hard links [0x%x]\n", nid, i_links);
+ if (find_and_dec_hard_link_list(sbi, nid)) {
+ ASSERT_MSG("[0x%x] needs more i_links=0x%x",
nid, i_links);
- ASSERT(0);
+ if (config.fix_cnt)
+ printf("TODO: i_links++\n");
}
-
- DBG(3, "ino[0x%x] has hard links [0x%x]\n",
- nid, i_links);
- ret = find_and_dec_hard_link_list(sbi, nid);
- ASSERT(ret >= 0);
-
/* No need to go deep into the node */
- goto out;
+ return;
}
}
@@ -358,13 +361,13 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
/* check data blocks in inode */
for (idx = 0; idx < ADDRS_PER_INODE(&node_blk->i); idx++) {
if (le32_to_cpu(node_blk->i.i_addr[idx]) != 0) {
- *blk_cnt = *blk_cnt + 1;
ret = fsck_chk_data_blk(sbi,
le32_to_cpu(node_blk->i.i_addr[idx]),
&child_cnt, &child_files,
(i_blocks == *blk_cnt),
ftype, nid, idx, ni->version);
- ASSERT(ret >= 0);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
}
}
@@ -380,11 +383,13 @@ int fsck_chk_inode_blk(struct f2fs_sb_info *sbi,
ASSERT(0);
if (le32_to_cpu(node_blk->i.i_nid[idx]) != 0) {
- *blk_cnt = *blk_cnt + 1;
ret = fsck_chk_node_blk(sbi, &node_blk->i,
le32_to_cpu(node_blk->i.i_nid[idx]),
ftype, ntype, blk_cnt);
- ASSERT(ret >= 0);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
+ else if (config.fix_cnt)
+ printf("TODO delete i_nid[idx] = 0;\n");
}
}
check:
@@ -400,35 +405,46 @@ check:
node_blk->i.i_name,
(u32)i_blocks);
if ((ftype == F2FS_FT_DIR && i_links != child_cnt) ||
- (i_blocks != *blk_cnt)) {
- print_node_info(node_blk);
+ (i_blocks != *blk_cnt)) {
+ if (!config.fix_cnt)
+ print_node_info(node_blk);
+
+ /* node_blk, ni.blkaddr, child_cnt, *blk_cnt */
+ if (config.fix_cnt)
+ printf("TODO fix_inode_block\n");
+ else
+ print_node_info(node_blk);
DBG(1, "blk cnt [0x%x]\n", *blk_cnt);
DBG(1, "child cnt [0x%x]\n", child_cnt);
}
-
- ASSERT(i_blocks == *blk_cnt);
- if (ftype == F2FS_FT_DIR)
- ASSERT(i_links == child_cnt);
-out:
- return 0;
+ if (i_blocks != *blk_cnt)
+ ASSERT_MSG("ino: 0x%x has i_blocks: %lu, but has %u blocks",
+ nid, i_blocks, *blk_cnt);
+ if (ftype == F2FS_FT_DIR && i_links != child_cnt)
+ ASSERT_MSG("ino: 0x%x has i_links: %u but real links: %u",
+ nid, i_links, child_cnt);
+ if (ftype == F2FS_FT_ORPHAN && i_links)
+ ASSERT_MSG("ino: 0x%x is orphan inode, but has i_links: %u",
+ nid, i_links);
}
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)
{
- int idx;
+ int idx, ret;
u32 child_cnt = 0, child_files = 0;
for (idx = 0; idx < ADDRS_PER_BLOCK; idx++) {
if (le32_to_cpu(node_blk->dn.addr[idx]) == 0x0)
continue;
- *blk_cnt = *blk_cnt + 1;
- fsck_chk_data_blk(sbi,
+ ret = fsck_chk_data_blk(sbi,
le32_to_cpu(node_blk->dn.addr[idx]),
&child_cnt, &child_files,
le64_to_cpu(inode->i_blocks) == *blk_cnt, ftype,
nid, idx, ni->version);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
}
return 0;
}
@@ -436,14 +452,19 @@ 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)
{
+ int ret;
int i = 0;
for (i = 0 ; i < NIDS_PER_BLOCK; i++) {
if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
continue;
- *blk_cnt = *blk_cnt + 1;
- fsck_chk_node_blk(sbi, inode, le32_to_cpu(node_blk->in.nid[i]),
+ ret = fsck_chk_node_blk(sbi, inode,
+ le32_to_cpu(node_blk->in.nid[i]),
ftype, TYPE_DIRECT_NODE, blk_cnt);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
+ else if (ret == -EINVAL)
+ printf("delete in.nid[i] = 0;\n");
}
return 0;
}
@@ -452,14 +473,18 @@ 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)
{
int i = 0;
+ int ret = 0;
for (i = 0; i < NIDS_PER_BLOCK; i++) {
if (le32_to_cpu(node_blk->in.nid[i]) == 0x0)
continue;
- *blk_cnt = *blk_cnt + 1;
- fsck_chk_node_blk(sbi, inode,
+ ret = fsck_chk_node_blk(sbi, inode,
le32_to_cpu(node_blk->in.nid[i]),
ftype, TYPE_INDIRECT_NODE, blk_cnt);
+ if (!ret)
+ *blk_cnt = *blk_cnt + 1;
+ else if (ret == -EINVAL)
+ printf("delete in.nid[i] = 0;\n");
}
return 0;
}
@@ -570,7 +595,8 @@ int fsck_chk_dentry_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
TYPE_INODE,
&blk_cnt);
- ASSERT(ret >= 0);
+ if (ret)
+ printf("TODO: delete dentry\n");
i += (name_len + F2FS_SLOT_LEN - 1) / F2FS_SLOT_LEN;
dentries++;
@@ -618,35 +644,34 @@ int fsck_chk_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,
fsck->chk.valid_blk_cnt++;
- if (ftype == F2FS_FT_DIR) {
- fsck_chk_dentry_blk(sbi, blk_addr, child_cnt,
+ if (ftype == F2FS_FT_DIR)
+ return fsck_chk_dentry_blk(sbi, blk_addr, child_cnt,
child_files, last_blk);
- }
-
return 0;
}
-int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
+void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
{
- int ret = 0;
u32 blk_cnt = 0;
-
block_t start_blk, orphan_blkaddr, i, j;
struct f2fs_orphan_block *orphan_blk;
struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
if (!is_set_ckpt_flags(ckpt, CP_ORPHAN_PRESENT_FLAG))
- return 0;
+ return;
+
+ if (config.fix_cnt)
+ return;
start_blk = __start_cp_addr(sbi) + 1 +
le32_to_cpu(F2FS_RAW_SUPER(sbi)->cp_payload);
-
orphan_blkaddr = __start_sum_addr(sbi) - 1;
-
orphan_blk = calloc(BLOCK_SZ, 1);
for (i = 0; i < orphan_blkaddr; i++) {
- dev_read_block(orphan_blk, start_blk + i);
+ int ret = dev_read_block(orphan_blk, start_blk + i);
+
+ ASSERT(ret >= 0);
for (j = 0; j < le32_to_cpu(orphan_blk->entry_count); j++) {
nid_t ino = le32_to_cpu(orphan_blk->ino[j]);
@@ -654,47 +679,42 @@ int fsck_chk_orphan_node(struct f2fs_sb_info *sbi)
blk_cnt = 1;
ret = fsck_chk_node_blk(sbi, NULL, ino,
F2FS_FT_ORPHAN, TYPE_INODE, &blk_cnt);
- ASSERT(ret >= 0);
+ if (ret == -EINVAL)
+ printf("TODO: nothing?\n");
}
memset(orphan_blk, 0, BLOCK_SZ);
}
free(orphan_blk);
- return 0;
}
-int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
- u32 x_nid, u32 *blk_cnt)
+void fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
+ u32 x_nid, u32 *blk_cnt)
{
- struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
+ struct f2fs_node *node_blk = NULL;
struct node_info ni;
if (x_nid == 0x0)
- return 0;
+ return;
- if (f2fs_test_bit(x_nid, fsck->nat_area_bitmap) != 0x0) {
- f2fs_clear_bit(x_nid, fsck->nat_area_bitmap);
- } else {
- ASSERT_MSG("xattr_nid duplicated [0x%x]\n", x_nid);
+ node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
+ ASSERT(node_blk != NULL);
+
+ /* Sanity check */
+ if (sanity_check_nid(sbi, x_nid, node_blk,
+ F2FS_FT_XATTR, TYPE_XATTR, &ni)) {
+ /* TODO: drop xattr node */
+ printf("drop xattr node\n");
+ goto out;
}
*blk_cnt = *blk_cnt + 1;
- fsck->chk.valid_blk_cnt++;
- fsck->chk.valid_node_cnt++;
-
- get_node_info(sbi, x_nid, &ni);
-
- if (f2fs_test_main_bitmap(sbi, ni.blk_addr) != 0) {
- ASSERT_MSG("Duplicated node block for x_attr. "
- "x_nid[0x%x] block addr[0x%x]\n",
- x_nid, ni.blk_addr);
- }
f2fs_set_main_bitmap(sbi, ni.blk_addr);
-
DBG(2, "ino[0x%x] x_nid[0x%x]\n", ino, x_nid);
- return 0;
+out:
+ free(node_blk);
}
-int fsck_init(struct f2fs_sb_info *sbi)
+void fsck_init(struct f2fs_sb_info *sbi)
{
struct f2fs_fsck *fsck = F2FS_FSCK(sbi);
struct f2fs_sm_info *sm_i = SM_I(sbi);
@@ -718,7 +738,7 @@ int fsck_init(struct f2fs_sb_info *sbi)
build_sit_area_bitmap(sbi);
tree_mark = calloc(tree_mark_size, 1);
- return 0;
+ ASSERT(tree_mark != NULL);
}
int fsck_verify(struct f2fs_sb_info *sbi)
diff --git a/fsck/fsck.h b/fsck/fsck.h
index b673646..aecfa9a 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -59,7 +59,8 @@ enum NODE_TYPE {
TYPE_INODE = 37,
TYPE_DIRECT_NODE = 43,
TYPE_INDIRECT_NODE = 53,
- TYPE_DOUBLE_INDIRECT_NODE = 67
+ TYPE_DOUBLE_INDIRECT_NODE = 67,
+ TYPE_XATTR = 77
};
struct hard_link_node {
@@ -76,11 +77,11 @@ enum seg_type {
SEG_TYPE_MAX,
};
-extern int fsck_chk_xattr_blk(struct f2fs_sb_info *, u32, u32, u32 *);
-extern int fsck_chk_orphan_node(struct f2fs_sb_info *);
+extern void fsck_chk_xattr_blk(struct f2fs_sb_info *, u32, u32, u32 *);
+extern void fsck_chk_orphan_node(struct f2fs_sb_info *);
extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
enum FILE_TYPE, enum NODE_TYPE, u32 *);
-extern int fsck_chk_inode_blk(struct f2fs_sb_info *, u32, enum FILE_TYPE,
+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 *,
@@ -102,7 +103,7 @@ extern int get_sum_entry(struct f2fs_sb_info *, u32, struct f2fs_summary *);
extern void get_node_info(struct f2fs_sb_info *, nid_t, struct node_info *);
extern void build_nat_area_bitmap(struct f2fs_sb_info *);
extern int build_sit_area_bitmap(struct f2fs_sb_info *);
-extern int fsck_init(struct f2fs_sb_info *);
+extern void fsck_init(struct f2fs_sb_info *);
extern int fsck_verify(struct f2fs_sb_info *);
extern void fsck_free(struct f2fs_sb_info *);
extern int f2fs_do_mount(struct f2fs_sb_info *);
diff --git a/fsck/main.c b/fsck/main.c
index 266e9b5..7e3bb49 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -131,44 +131,29 @@ void f2fs_parse_options(int argc, char *argv[])
config.device_name = argv[optind];
}
-int do_fsck(struct f2fs_sb_info *sbi)
+static void do_fsck(struct f2fs_sb_info *sbi)
{
u32 blk_cnt;
- int ret;
config.bug_on = 0;
- ret = fsck_init(sbi);
- if (ret < 0)
- return ret;
+ fsck_init(sbi);
fsck_chk_orphan_node(sbi);
/* Traverse all block recursively from root inode */
blk_cnt = 1;
- ret = fsck_chk_node_blk(sbi,
- NULL,
- sbi->root_ino_num,
- F2FS_FT_DIR,
- TYPE_INODE,
- &blk_cnt);
- if (ret < 0)
- goto out1;
-
- ret = fsck_verify(sbi);
-out1:
+ fsck_chk_node_blk(sbi, NULL, sbi->root_ino_num,
+ F2FS_FT_DIR, TYPE_INODE, &blk_cnt);
+ fsck_verify(sbi);
fsck_free(sbi);
- return ret;
}
-int do_dump(struct f2fs_sb_info *sbi)
+static void do_dump(struct f2fs_sb_info *sbi)
{
struct dump_option *opt = (struct dump_option *)config.private;
- int ret;
- ret = fsck_init(sbi);
- if (ret < 0)
- return ret;
+ fsck_init(sbi);
if (opt->end_sit == -1)
opt->end_sit = SM_I(sbi)->main_segments;
@@ -182,15 +167,12 @@ int do_dump(struct f2fs_sb_info *sbi)
dump_inode_from_blkaddr(sbi, opt->blk_addr);
goto cleanup;
}
-
dump_node(sbi, opt->nid);
-
cleanup:
fsck_free(sbi);
- return 0;
}
-int main (int argc, char **argv)
+int main(int argc, char **argv)
{
struct f2fs_sb_info *sbi;
int ret = 0;
@@ -215,10 +197,10 @@ fsck_again:
switch (config.func) {
case FSCK:
- ret = do_fsck(sbi);
+ do_fsck(sbi);
break;
case DUMP:
- ret = do_dump(sbi);
+ do_dump(sbi);
break;
}
@@ -248,5 +230,5 @@ retry:
f2fs_finalize_device(&config);
printf("\nDone.\n");
- return ret;
+ return 0;
}
diff --git a/fsck/mount.c b/fsck/mount.c
index ab5f7f3..a766157 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -1020,7 +1020,8 @@ void build_nat_area_bitmap(struct f2fs_sb_info *sbi)
struct node_info ni;
ni.nid = nid + i;
- if ((nid + i) == F2FS_NODE_INO(sbi) || (nid + i) == F2FS_META_INO(sbi)) {
+ if ((nid + i) == F2FS_NODE_INO(sbi) ||
+ (nid + i) == F2FS_META_INO(sbi)) {
ASSERT(nat_block->entries[i].block_addr != 0x0);
continue;
}
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index dace9aa..c3cc2aa 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -413,6 +413,9 @@ enum {
OFFSET_BIT_SHIFT
};
+#define XATTR_NODE_OFFSET ((((unsigned int)-1) << OFFSET_BIT_SHIFT) \
+ >> OFFSET_BIT_SHIFT)
+
struct node_footer {
__le32 nid; /* node id */
__le32 ino; /* inode nunmber */
@@ -640,6 +643,7 @@ enum FILE_TYPE {
F2FS_FT_MAX,
/* added for fsck */
F2FS_FT_ORPHAN,
+ F2FS_FT_XATTR,
};
/* from f2fs/segment.h */