fsck.f2fs: fix to avoid selecting current section in find_next_free_block

In find_next_free_block(), when searching for a free block or allocating a
new section, it checks:

	if (!(get_sb(feature) & F2FS_FEATURE_RO) &&
					IS_CUR_SEGNO(sbi, segno))
		goto next_segment;

However, when large section is enabled (segs_per_sec > 1), checking only
IS_CUR_SEGNO(sbi, segno) is insufficient. If segment 0 of a section is
empty, but segment 1 is an active curseg (e.g. CURSEG_WARM_NODE),
IS_CUR_SEGNO(sbi, segno) evaluates to false.

Consequently, find_next_free_block() can treat the section as completely
free and call set_section_type(sbi, segno, want_type). This overwrites the
segment type of all segments in the section, clobbering active curseg
segments (e.g. from NODE to DATA) and leading to an assertion crash in
update_data_blkaddr():

  [update_data_blkaddr:2527] NAT and SIT is inconsistent: ino: 4, nid: 23, blkaddr: 21925780, segtype: 1
  [ASSERT] (update_data_blkaddr:2529) 0

Fix this by using IS_CUR_SECNO(sbi, GET_SEC_FROM_SEG(sbi, segno)) to ensure
that any segment belonging to an active current section is skipped.

Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 file changed