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>
diff --git a/fsck/mount.c b/fsck/mount.c index a202f3d..2fd8e1c 100644 --- a/fsck/mount.c +++ b/fsck/mount.c
@@ -3149,7 +3149,7 @@ continue; } if (!(get_sb(feature) & F2FS_FEATURE_RO) && - IS_CUR_SEGNO(sbi, segno)) + IS_CUR_SECNO(sbi, GET_SEC_FROM_SEG(sbi, segno))) goto next_segment; if (vblocks == 0 && not_enough) goto next_segment;