[PATCH 4.9 086/101] f2fs: return error during fill_super

2018-12-06 Thread Greg Kroah-Hartman
4.9-stable review patch.  If anyone has any objections, please let me know.

--

From: Jaegeuk Kim 

commit c39a1b348c4fe172729eff77c533dabc3c7cdaa7 upstream.

Let's avoid BUG_ON during fill_super, when on-disk was totall corrupted.

Reviewed-by: Chao Yu 
Signed-off-by: Jaegeuk Kim 
Signed-off-by: Sudip Mukherjee 
Signed-off-by: Greg Kroah-Hartman 
[bwh: Backported to 4.9: adjust context]
Signed-off-by: Ben Hutchings 
Signed-off-by: Greg Kroah-Hartman 
---
 fs/f2fs/segment.c |   16 
 fs/f2fs/segment.h |   22 ++
 2 files changed, 30 insertions(+), 8 deletions(-)

--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2322,7 +2322,7 @@ static int build_curseg(struct f2fs_sb_i
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);
@@ -2333,6 +2333,7 @@ static void build_sit_entries(struct f2f
unsigned int i, start, end;
unsigned int readed, start_blk = 0;
int nrpages = MAX_BIO_BLOCKS(sbi) * 8;
+   int err = 0;
 
do {
readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT, true);
@@ -2350,7 +2351,9 @@ static void build_sit_entries(struct f2f
sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
f2fs_put_page(page, 1);
 
-   check_block_count(sbi, start, );
+   err = check_block_count(sbi, start, );
+   if (err)
+   return err;
seg_info_from_raw_sit(se, );
 
/* build discard map only one time */
@@ -2378,7 +2381,9 @@ static void build_sit_entries(struct f2f
 
old_valid_blocks = se->valid_blocks;
 
-   check_block_count(sbi, start, );
+   err = check_block_count(sbi, start, );
+   if (err)
+   break;
seg_info_from_raw_sit(se, );
 
if (f2fs_discard_en(sbi)) {
@@ -2393,6 +2398,7 @@ static void build_sit_entries(struct f2f
se->valid_blocks - old_valid_blocks;
}
up_read(>journal_rwsem);
+   return err;
 }
 
 static void init_free_segmap(struct f2fs_sb_info *sbi)
@@ -2559,7 +2565,9 @@ int build_segment_manager(struct f2fs_sb
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);
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -600,7 +600,7 @@ static inline void verify_block_addr(str
 /*
  * 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
@@ -622,11 +622,25 @@ static inline void check_block_count(str
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,




[PATCH 4.9 086/101] f2fs: return error during fill_super

2018-12-06 Thread Greg Kroah-Hartman
4.9-stable review patch.  If anyone has any objections, please let me know.

--

From: Jaegeuk Kim 

commit c39a1b348c4fe172729eff77c533dabc3c7cdaa7 upstream.

Let's avoid BUG_ON during fill_super, when on-disk was totall corrupted.

Reviewed-by: Chao Yu 
Signed-off-by: Jaegeuk Kim 
Signed-off-by: Sudip Mukherjee 
Signed-off-by: Greg Kroah-Hartman 
[bwh: Backported to 4.9: adjust context]
Signed-off-by: Ben Hutchings 
Signed-off-by: Greg Kroah-Hartman 
---
 fs/f2fs/segment.c |   16 
 fs/f2fs/segment.h |   22 ++
 2 files changed, 30 insertions(+), 8 deletions(-)

--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2322,7 +2322,7 @@ static int build_curseg(struct f2fs_sb_i
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);
@@ -2333,6 +2333,7 @@ static void build_sit_entries(struct f2f
unsigned int i, start, end;
unsigned int readed, start_blk = 0;
int nrpages = MAX_BIO_BLOCKS(sbi) * 8;
+   int err = 0;
 
do {
readed = ra_meta_pages(sbi, start_blk, nrpages, META_SIT, true);
@@ -2350,7 +2351,9 @@ static void build_sit_entries(struct f2f
sit = sit_blk->entries[SIT_ENTRY_OFFSET(sit_i, start)];
f2fs_put_page(page, 1);
 
-   check_block_count(sbi, start, );
+   err = check_block_count(sbi, start, );
+   if (err)
+   return err;
seg_info_from_raw_sit(se, );
 
/* build discard map only one time */
@@ -2378,7 +2381,9 @@ static void build_sit_entries(struct f2f
 
old_valid_blocks = se->valid_blocks;
 
-   check_block_count(sbi, start, );
+   err = check_block_count(sbi, start, );
+   if (err)
+   break;
seg_info_from_raw_sit(se, );
 
if (f2fs_discard_en(sbi)) {
@@ -2393,6 +2398,7 @@ static void build_sit_entries(struct f2f
se->valid_blocks - old_valid_blocks;
}
up_read(>journal_rwsem);
+   return err;
 }
 
 static void init_free_segmap(struct f2fs_sb_info *sbi)
@@ -2559,7 +2565,9 @@ int build_segment_manager(struct f2fs_sb
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);
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -600,7 +600,7 @@ static inline void verify_block_addr(str
 /*
  * 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
@@ -622,11 +622,25 @@ static inline void check_block_count(str
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,