Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6fd4c5c authored by Wang Xiaojun's avatar Wang Xiaojun Committed by Jaegeuk Kim
Browse files

BACKPORT: f2fs: fix wrong total_sections check and fsmeta check



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).

Bug: 208371174
Signed-off-by: default avatarWang Xiaojun <wangxiaojun11@huawei.com>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
(cherry picked from commit 56faf97ebce8)
Change-Id: I36a97300e13bd760c29958bc36d85b441dd40eaa
parent ce664fbd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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)
+4 −4
Original line number Diff line number Diff line
@@ -2708,7 +2708,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);
@@ -2778,6 +2778,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);
@@ -2791,8 +2792,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);
@@ -2899,7 +2899,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;