f2fs: return error during fill_super
Jaegeuk Kim
maintainerPATCH 1/1 f2fs: return error during fill_super
Let's avoid BUG_ON during fill_super, when on-disk was totall corrupted.
Signed-off-by Jaegeuk Kim <[email protected]>
--- fs/f2fs/segment.c | 16 ++++++++++++---- fs/f2fs/segment.h | 22 ++++++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-)
fs/f2fs/segment.c +12 -4
@@ -3476,7 +3476,7 @@ static int build_curseg(struct f2fs_sb_info *sbi)return restore_curseg_summaries (sbi); } -static void build_sit_entries (struct f2fs_sb_info *sbi) +static int build_sit_entries (struct f2fs_sb_info *sbi) {struct sit_info *sit_i =SIT_I (sbi);struct curseg_info *curseg =CURSEG_I (sbi,CURSEG_COLD_DATA );
@@ -3486,6 +3486,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi)int sit_blk_cnt =SIT_BLK_CNT (sbi);unsigned int i, start, end;unsigned int readed, start_blk =0 ; +int err =0 ; do { readed = ra_meta_pages(sbi, start_blk, BIO_MAX_PAGES,
@@ -3504,7 +3505,9 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) sit = sit_blk->entries[SIT_ENTRY_OFFSET (sit_i, start)];f2fs_put_page (page,1 ); -check_block_count (sbi, start, &sit); + err =check_block_count (sbi, start, &sit); +if (err) +return err;seg_info_from_raw_sit (se, &sit);/* build discard map only one time */
@@ -3539,7 +3542,9 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) old_valid_blocks = se->valid_blocks; -check_block_count (sbi, start, &sit); + err =check_block_count (sbi, start, &sit); +if (err) +break ;seg_info_from_raw_sit (se, &sit);if (f2fs_discard_en (sbi)) {
@@ -3559,6 +3564,7 @@ static void build_sit_entries(struct f2fs_sb_info *sbi) se->valid_blocks - old_valid_blocks; }up_read (&curseg->journal_rwsem); +return err; }static void init_free_segmap (struct f2fs_sb_info *sbi)
@@ -3733,7 +3739,9 @@ int build_segment_manager(struct f2fs_sb_info *sbi)return err;/* reinit free segmap based on SIT */ -build_sit_entries (sbi); + err =build_sit_entries (sbi); +if (err) +return err;init_free_segmap (sbi); err =build_dirty_segmap (sbi);
fs/f2fs/segment.h +18 -4
@@ -655,7 +655,7 @@ static inline void verify_block_addr(struct f2fs_sb_info *sbi, block_t blk_addr)/* * Summary block is always treated as an invalid block */ -static inline void check_block_count (struct f2fs_sb_info *sbi, +static inline int check_block_count (struct f2fs_sb_info *sbi,int segno,struct f2fs_sit_entry *raw_sit) {#ifdef CONFIG_F2FS_CHECK_FS
@@ -677,11 +677,25 @@ static inline void check_block_count(struct f2fs_sb_info *sbi, cur_pos = next_pos; is_valid = !is_valid; } while (cur_pos < sbi->blocks_per_seg); -BUG_ON (GET_SIT_VBLOCKS (raw_sit) != valid_blocks); + +if (unlikely (GET_SIT_VBLOCKS (raw_sit) != valid_blocks)) { +f2fs_msg (sbi->sb,KERN_ERR , +"Mismatch valid blocks %d vs. %d" , +GET_SIT_VBLOCKS (raw_sit), valid_blocks); +set_sbi_flag (sbi,SBI_NEED_FSCK ); +return -EINVAL ; + }#endif /* check segment usage, and check boundary of a given segment number */ -f2fs_bug_on (sbi,GET_SIT_VBLOCKS (raw_sit) > sbi->blocks_per_seg - || segno >TOTAL_SEGS (sbi) -1 ); +if (unlikely (GET_SIT_VBLOCKS (raw_sit) > sbi->blocks_per_seg + || segno >TOTAL_SEGS (sbi) -1 )) { +f2fs_msg (sbi->sb,KERN_ERR , +"Wrong valid blocks %d or segno %u" , +GET_SIT_VBLOCKS (raw_sit), segno); +set_sbi_flag (sbi,SBI_NEED_FSCK ); +return -EINVAL ; + } +return 0 ; } static inline pgoff_t current_sit_addr(struct f2fs_sb_info *sbi,
Signature · 1 line
2.15.0.531.g2ccb3012c9-goog
Quoted 3 lines · Jaegeuk Kim
Let's avoid
BUG_ONduringfill_super, when on-disk was totall corrupted.Signed-off-by Jaegeuk Kim <[email protected]>
Reviewed-by Chao Yu <[email protected]>
Thanks,