f2fs: fix wrong total_sections check and fsmeta check
authorWang Xiaojun <wangxiaojun11@huawei.com>
Thu, 17 Sep 2020 11:11:58 +0000 (19:11 +0800)
committerJaegeuk Kim <jaegeuk@kernel.org>
Tue, 29 Sep 2020 08:48:34 +0000 (01:48 -0700)
Meta area is not included in section_count computation.
So the minimum number of total_sections is 1 meanwhile it cannot be
greater than segment_count_main.

The minimum number of meta segments is 8 (SB + 2 (CP + SIT + NAT) + SSA).

Signed-off-by: Wang Xiaojun <wangxiaojun11@huawei.com>
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/segment.h
fs/f2fs/super.c

index f5b1883..e81eb07 100644 (file)
@@ -16,6 +16,7 @@
 #define DEF_MAX_RECLAIM_PREFREE_SEGMENTS       4096    /* 8GB in maximum */
 
 #define F2FS_MIN_SEGMENTS      9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
+#define F2FS_MIN_META_SEGMENTS 8 /* SB + 2 (CP + SIT + NAT) + SSA */
 
 /* L: Logical segment # in volume, R: Relative segment # in main area */
 #define GET_L2R_SEGNO(free_i, segno)   ((segno) - (free_i)->start_segno)
index 7a8a32e..4846017 100644 (file)
@@ -2741,7 +2741,7 @@ static inline bool sanity_check_area_boundary(struct f2fs_sb_info *sbi,
 static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
                                struct buffer_head *bh)
 {
-       block_t segment_count, segs_per_sec, secs_per_zone;
+       block_t segment_count, segs_per_sec, secs_per_zone, segment_count_main;
        block_t total_sections, blocks_per_seg;
        struct f2fs_super_block *raw_super = (struct f2fs_super_block *)
                                        (bh->b_data + F2FS_SUPER_OFFSET);
@@ -2812,6 +2812,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
        }
 
        segment_count = le32_to_cpu(raw_super->segment_count);
+       segment_count_main = le32_to_cpu(raw_super->segment_count_main);
        segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
        secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
        total_sections = le32_to_cpu(raw_super->section_count);
@@ -2825,8 +2826,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
                return -EFSCORRUPTED;
        }
 
-       if (total_sections > segment_count ||
-                       total_sections < F2FS_MIN_SEGMENTS ||
+       if (total_sections > segment_count_main || total_sections < 1 ||
                        segs_per_sec > segment_count || !segs_per_sec) {
                f2fs_info(sbi, "Invalid segment/section count (%u, %u x %u)",
                          segment_count, total_sections, segs_per_sec);
@@ -2939,7 +2939,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
        ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
        reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
 
-       if (unlikely(fsmeta < F2FS_MIN_SEGMENTS ||
+       if (unlikely(fsmeta < F2FS_MIN_META_SEGMENTS ||
                        ovp_segments == 0 || reserved_segments == 0)) {
                f2fs_err(sbi, "Wrong layout: check mkfs.f2fs version");
                return 1;