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