fsck.f2fs: reduce redundant message
PATCH 1/6 fsck.f2fs: reduce redundant message
This assert message is unnecessary to be shown, since caller shows the reason already.
--- fsck/f2fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fsck/f2fs.h +1 -1
@@ -340,7 +340,7 @@ static inline bool IS_VALID_BLK_ADDR(struct f2fs_sb_info *sbi, u32 addr)if (addr >=F2FS_RAW_SUPER (sbi)->block_count || addr <SM_I (sbi)->main_blkaddr) { -ASSERT_MSG ("block addr [0x%x]\n" , addr); +DBG (1 ,"block addr [0x%x]\n" , addr);return 0 ; }
Signature · 9 lines
2.1.1 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/
PATCH 2/6 fsck.f2fs: remove inconsistent named directories
Each inode has its filename inside inode block.
For directory, the name should be matched all the time.
In other cases, it shouldn't, since there is able to be linked to other file names.
--- fsck/fsck.c | 27 ++++++++++++++++++--------- fsck/fsck.h | 2 +- fsck/main.c | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-)
fsck/fsck.c +18 -9
@@ -192,7 +192,7 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,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 node_info *ni,u8 *name) {struct f2fs_fsck *fsck =F2FS_FSCK (sbi);int ret;
@@ -263,6 +263,15 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, } } +if (ntype ==TYPE_INODE && ftype ==F2FS_FT_DIR ) { +u32 len =le32_to_cpu (node_blk->i.i_namelen); +if (name &&memcmp (name, node_blk->i.i_name, len)) { +ASSERT_MSG ("mismatch name [0x%x] [%s vs. %s]" , + nid, name, node_blk->i.i_name); +return -EINVAL ; + } + } +/* workaround to fix later */ if (ftype !=F2FS_FT_ORPHAN ||f2fs_test_bit (nid, fsck->nat_area_bitmap) !=0 )
@@ -297,7 +306,7 @@ static int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,/* Sanity check */ if (sanity_check_nid (sbi, x_nid, node_blk, -F2FS_FT_XATTR ,TYPE_XATTR , &ni)) { +F2FS_FT_XATTR ,TYPE_XATTR , &ni,NULL )) { ret = -EINVAL ; goto out; }
@@ -311,7 +320,7 @@ out: }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 nid,u8 *name,enum FILE_TYPE ftype,enum NODE_TYPE ntype,u32 *blk_cnt) {struct node_info ni;
@@ -320,7 +329,7 @@ int fsck_chk_node_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode, node_blk = (struct f2fs_node *)calloc (BLOCK_SZ ,1 );ASSERT (node_blk !=NULL ); -if (sanity_check_nid (sbi, nid, node_blk, ftype, ntype, &ni)) +if (sanity_check_nid (sbi, nid, node_blk, ftype, ntype, &ni, name)) goto err;if (ntype ==TYPE_INODE ) {
@@ -496,7 +505,7 @@ 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]), - ftype, ntype, blk_cnt); +NULL , ftype, ntype, blk_cnt);if (!ret) { *blk_cnt = *blk_cnt +1 ; }else if (config.fix_on) {
@@ -591,7 +600,7 @@ int fsck_chk_idnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,if (le32_to_cpu (node_blk->in.nid[i]) ==0x0 )continue ; ret =fsck_chk_node_blk (sbi, inode, -le32_to_cpu (node_blk->in.nid[i]), +le32_to_cpu (node_blk->in.nid[i]),NULL , ftype,TYPE_DIRECT_NODE , blk_cnt);if (!ret) *blk_cnt = *blk_cnt +1 ;
@@ -611,7 +620,7 @@ int fsck_chk_didnode_blk(struct f2fs_sb_info *sbi, struct f2fs_inode *inode,if (le32_to_cpu (node_blk->in.nid[i]) ==0x0 )continue ; ret =fsck_chk_node_blk (sbi, inode, -le32_to_cpu (node_blk->in.nid[i]), +le32_to_cpu (node_blk->in.nid[i]),NULL , ftype,TYPE_INDIRECT_NODE , blk_cnt);if (!ret) *blk_cnt = *blk_cnt +1 ;
@@ -764,7 +773,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), +NULL ,le32_to_cpu (dentry[i].ino), name, ftype,TYPE_INODE , &blk_cnt);if (ret && config.fix_on) {
@@ -927,7 +936,7 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi)continue ; } blk_cnt =1 ; -fsck_chk_node_blk (sbi,NULL , ino, +fsck_chk_node_blk (sbi,NULL , ino,NULL ,F2FS_FT_ORPHAN ,TYPE_INODE , &blk_cnt); }memset (orphan_blk,0 ,BLOCK_SZ );
fsck/fsck.h +1 -1
@@ -80,7 +80,7 @@ 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 , -enum FILE_TYPE ,enum NODE_TYPE ,u32 *); +u8 *,enum FILE_TYPE ,enum NODE_TYPE ,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 *,
fsck/main.c +1 -1
@@ -152,7 +152,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, +fsck_chk_node_blk (sbi,NULL , sbi->root_ino_num, (u8 *)"/" ,F2FS_FT_DIR ,TYPE_INODE , &blk_cnt);fsck_verify (sbi);fsck_free (sbi);
Signature · 9 lines
2.1.1 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/
PATCH 3/6 fsck.f2fs: check file types
In reply to Jaegeuk KimIf the file type is mismatched, we should drop that inode.
--- fsck/fsck.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
fsck/fsck.c +28 -0
@@ -189,6 +189,30 @@ static int is_valid_ssa_data_blk(struct f2fs_sb_info *sbi, u32 blk_addr,return 0 ; } +static int __check_inode_mode (u32 nid,enum FILE_TYPE ftype,u32 mode) +{ +if (ftype >=F2FS_FT_MAX ) +return 0 ; +if (S_ISLNK (mode) && ftype !=F2FS_FT_SYMLINK ) + goto err; +if (S_ISREG (mode) && ftype !=F2FS_FT_REG_FILE ) + goto err; +if (S_ISDIR (mode) && ftype !=F2FS_FT_DIR ) + goto err; +if (S_ISCHR (mode) && ftype !=F2FS_FT_CHRDEV ) + goto err; +if (S_ISBLK (mode) && ftype !=F2FS_FT_BLKDEV ) + goto err; +if (S_ISFIFO (mode) && ftype !=F2FS_FT_FIFO ) + goto err; +if (S_ISSOCK (mode) && ftype !=F2FS_FT_SOCK ) + goto err; +return 0 ; +err: +ASSERT_MSG ("mismatch i_mode [0x%x] [0x%x vs. 0x%x]" , nid, ftype, mode); +return -1 ; +} + 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,
@@ -272,6 +296,10 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, } } +if (ntype ==TYPE_INODE && +__check_inode_mode (nid, ftype,le32_to_cpu (node_blk->i.i_mode))) +return -EINVAL ; +/* workaround to fix later */ if (ftype !=F2FS_FT_ORPHAN ||f2fs_test_bit (nid, fsck->nat_area_bitmap) !=0 )
Signature · 9 lines
2.1.1 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/
PATCH 4/6 fsck.f2fs: fix inodes having wrong i_links
In reply to Jaegeuk KimThis patch fixes inodes which have wrong i_links.
--- fsck/fsck.c | 41 +++++++++++++++++++++++++++++++++++++++++ fsck/fsck.h | 1 + 2 files changed, 42 insertions(+)
fsck/fsck.c +41 -0
@@ -63,6 +63,7 @@ static int add_into_hard_link_list(struct f2fs_sb_info *sbi, node->nid = nid; node->links = link_cnt; + node->actual_links =1 ; node->next =NULL ;if (fsck->hard_link_list_head ==NULL ) {
@@ -112,6 +113,7 @@ static int find_and_dec_hard_link_list(struct f2fs_sb_info *sbi, u32 nid)/* Decrease link count */ node->links = node->links -1 ; + node->actual_links++;/* if link count becomes one, remove the node */ if (node->links ==1 ) {
@@ -296,6 +298,10 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid, } } +/* this if only from fix_hard_links */ +if (ftype ==F2FS_FT_MAX ) +return 0 ; +if (ntype ==TYPE_INODE &&__check_inode_mode (nid, ftype,le32_to_cpu (node_blk->i.i_mode)))return -EINVAL ;
@@ -999,6 +1005,40 @@ void fsck_init(struct f2fs_sb_info *sbi)ASSERT (tree_mark !=NULL ); } +static void fix_hard_links (struct f2fs_sb_info *sbi) +{ +struct f2fs_fsck *fsck =F2FS_FSCK (sbi); +struct hard_link_node *tmp, *node; +struct f2fs_node *node_blk =NULL ; +struct node_info ni; +int ret; + +if (fsck->hard_link_list_head ==NULL ) +return ; + + node_blk = (struct f2fs_node *)calloc (BLOCK_SZ ,1 ); +ASSERT (node_blk !=NULL ); + + node = fsck->hard_link_list_head; +while (node) { +/* Sanity check */ +if (sanity_check_nid (sbi, node->nid, node_blk, +F2FS_FT_MAX ,TYPE_INODE , &ni,NULL )) +FIX_MSG ("Failed to fix, rerun fsck.f2fs" ); + + node_blk->i.i_links =cpu_to_le32 (node->actual_links); + +FIX_MSG ("File: 0x%x i_links= 0x%x -> 0x%x" , + node->nid, node->links, node->actual_links); + + ret =dev_write_block (node_blk, ni.blk_addr); +ASSERT (ret >=0 ); + tmp = node; + node = node->next; +free (tmp); + } +} +static void fix_nat_entries (struct f2fs_sb_info *sbi) {struct f2fs_fsck *fsck =F2FS_FSCK (sbi);
@@ -1223,6 +1263,7 @@ int fsck_verify(struct f2fs_sb_info *sbi)/* fix global metadata */ if (force || (config.bug_on && config.fix_on)) { +fix_hard_links (sbi);fix_nat_entries (sbi);rewrite_sit_area_bitmap (sbi);fix_checkpoint (sbi);
fsck/fsck.h +1 -0
@@ -67,6 +67,7 @@ enum NODE_TYPE {struct hard_link_node {u32 nid;u32 links; +u32 actual_links;struct hard_link_node *next; };
Signature · 9 lines
2.1.1 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/
PATCH 5/6 fsck.f2fs: skip block count fix when i_links is fixed
In reply to Jaegeuk KimIf i_links is wrong, we should not check block count, since it doesn't count correctly which results in changing the block count to 1.
This patch fixes that.
--- fsck/fsck.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
fsck/fsck.c +13 -12
@@ -440,7 +440,7 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid,"i_links= 0x%x -> 0x%x" , nid, i_links, i_links + 1); } - goto check; + goto skip_blkcnt_fix; }/* No need to go deep into the node */ return ;
@@ -550,6 +550,18 @@ void fsck_chk_inode_blk(struct f2fs_sb_info *sbi, u32 nid, } } check: +if (i_blocks != *blk_cnt) { +ASSERT_MSG ("ino: 0x%x has i_blocks: %08" PRIx64", " +"but has %u blocks" , + nid, i_blocks, *blk_cnt); +if (config.fix_on) { + node_blk->i.i_blocks =cpu_to_le64 (*blk_cnt); + need_fix =1 ; +FIX_MSG ("[0x%x] i_blocks=0x%08" PRIx64" -> 0x%x" , + nid, i_blocks, *blk_cnt); + } + } +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),
@@ -562,17 +574,6 @@ check: node_blk->i.i_name, (u32)i_blocks); -if (i_blocks != *blk_cnt) { -ASSERT_MSG ("ino: 0x%x has i_blocks: %08" PRIx64", " -"but has %u blocks" , - nid, i_blocks, *blk_cnt); -if (config.fix_on) { - node_blk->i.i_blocks =cpu_to_le64 (*blk_cnt); - need_fix =1 ; -FIX_MSG ("[0x%x] i_blocks=0x%08" PRIx64" -> 0x%x" , - 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);
Signature · 9 lines
2.1.1 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/
PATCH 6/6 fsck.f2fs: preserve orphan blocks
In reply to Jaegeuk KimIf fsck.f2fs found some orphan blocks, previously fsck.f2fs drops them and fixes checkpoint, resulting in false alarm on corruption.
This patch preserves orphan blocks to avoid such the alarms.
--- fsck/fsck.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-)
fsck/fsck.c +36 -12
@@ -946,8 +946,10 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi) {u32 blk_cnt =0 ;block_t start_blk, orphan_blkaddr, i, j; -struct f2fs_orphan_block *orphan_blk; +struct f2fs_orphan_block *orphan_blk, *new_blk;struct f2fs_checkpoint *ckpt =F2FS_CKPT (sbi); +u32 entry_count; +u32 new_entry_count =0 ;if (!is_set_ckpt_flags (ckpt,CP_ORPHAN_PRESENT_FLAG ))return ;
@@ -955,28 +957,43 @@ void fsck_chk_orphan_node(struct f2fs_sb_info *sbi) 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 ); +ASSERT (orphan_blk); + + new_blk =calloc (BLOCK_SZ ,1 ); +ASSERT (new_blk);for (i =0 ; i < orphan_blkaddr; i++) {int ret =dev_read_block (orphan_blk, start_blk + i);ASSERT (ret >=0 ); + entry_count =le32_to_cpu (orphan_blk->entry_count); -for (j =0 ; j <le32_to_cpu (orphan_blk->entry_count); j++) { +for (j =0 ; j < entry_count; j++) {nid_t ino =le32_to_cpu (orphan_blk->ino[j]);DBG (1 ,"[%3d] ino [0x%x]\n" , i, ino); -if (config.fix_on) { -FIX_MSG ("Discard orphan inodes: ino [0x%x]" , - ino); -continue ; - } blk_cnt =1 ; -fsck_chk_node_blk (sbi,NULL , ino,NULL , + ret =fsck_chk_node_blk (sbi,NULL , ino,NULL ,F2FS_FT_ORPHAN ,TYPE_INODE , &blk_cnt); +if (!ret) + new_blk->ino[new_entry_count++] = + orphan_blk->ino[j]; +else if (ret && config.fix_on) +FIX_MSG ("[0x%x] remove from orphan list" , ino); +else if (ret) +ASSERT_MSG ("[0x%x] wrong orphan inode" , ino); + } +if (config.fix_on && entry_count != new_entry_count) { + new_blk->entry_count =cpu_to_le32 (new_entry_count); + ret =dev_write_block (new_blk, start_blk + i); +ASSERT (ret >=0 ); }memset (orphan_blk,0 ,BLOCK_SZ ); +memset (new_blk,0 ,BLOCK_SZ ); }free (orphan_blk); +free (new_blk); }void fsck_init (struct f2fs_sb_info *sbi)
@@ -1056,15 +1073,20 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)struct f2fs_super_block *raw_sb = sbi->raw_super;struct f2fs_checkpoint *ckp =F2FS_CKPT (sbi);unsigned long long cp_blk_no; +u32 flags =CP_UMOUNT_FLAG ; +block_t orphan_blks =0 ;u32 i;int ret;u_int32_t crc =0 ; - ckp->ckpt_flags =cpu_to_le32 (CP_UMOUNT_FLAG ); +if (is_set_ckpt_flags (ckp,CP_ORPHAN_PRESENT_FLAG )) { + orphan_blks =__start_sum_addr (sbi) -1 ; + flags |=CP_ORPHAN_PRESENT_FLAG ; + } + + ckp->ckpt_flags =cpu_to_le32 (flags); ckp->cp_pack_total_block_count = -cpu_to_le32 (8 +le32_to_cpu (raw_sb->cp_payload)); - ckp->cp_pack_start_sum =cpu_to_le32 (1 + -le32_to_cpu (raw_sb->cp_payload)); +cpu_to_le32 (8 + orphan_blks +le32_to_cpu (raw_sb->cp_payload)); ckp->free_segment_count =cpu_to_le32 (fsck->chk.free_segs); ckp->valid_block_count =cpu_to_le32 (fsck->chk.valid_blk_cnt);
@@ -1088,6 +1110,8 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi)ASSERT (ret >=0 ); } + cp_blk_no += orphan_blks; +for (i =0 ; i <NO_CHECK_TYPE ; i++) {struct curseg_info *curseg =CURSEG_I (sbi, i);
Signature · 9 lines
2.1.1 ------------------------------------------------------------------------------ Dive into the World of Parallel Programming The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/