Re: [f2fs-dev] [PATCH] fsck.f2fs: handle find_next_free_block failure gracefully
Chao Yu via Linux-f2fs-devel <[email protected]> Mon, 3 Aug 2026 15:39:05 +0800
| Newsgroups | net.sourceforge.lists.linux-f2fs-devel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 7/24/26 03:35, Daeho Jeong wrote: > From: Daeho Jeong <[email protected]> > > When find_next_free_block() fails to allocate a free block, callers like > move_one_curseg_info(), reserve_new_block(), and update_block() previously > crashed via ASSERT(). Seems there are a lot of ASSERT() in path of above functions? e.g. f2fs_create /* write child */ set_summary(&sum, de->ino, 0, ni.version); ret = reserve_new_block(sbi, &blkaddr, &sum, CURSEG_HOT_NODE, 1); nodeblk_alloced = true; ASSERT(!ret); convert_inline_dentry ret = update_block(sbi, node, p_blkaddr, NULL); ASSERT(ret >= 0); Can you please take a look? > > Replace these ASSERT() calls with proper error propagation to gracefully > abort FSCK execution instead of crashing. > > Signed-off-by: Daeho Jeong <[email protected]> > --- > fsck/fsck.c | 22 +++++++++++++++------- > fsck/fsck.h | 8 ++++---- > fsck/main.c | 4 +++- > fsck/mount.c | 28 ++++++++++++++++++---------- > fsck/segment.c | 8 ++++---- > 5 files changed, 44 insertions(+), 26 deletions(-) > > diff --git a/fsck/fsck.c b/fsck/fsck.c > index db44f9d..b128617 100644 > --- a/fsck/fsck.c > +++ b/fsck/fsck.c > @@ -2972,13 +2972,15 @@ int check_curseg_offsets(struct f2fs_sb_info *sbi, bool check_wp) > return 0; > } > > -static void fix_curseg_info(struct f2fs_sb_info *sbi, bool check_wp) > +static int fix_curseg_info(struct f2fs_sb_info *sbi, bool check_wp) > { > - int i, need_update = 0; > + int i, need_update = 0, ret; > > for (i = 0; i < NO_CHECK_TYPE; i++) { > if (check_curseg_offset(sbi, i, check_wp)) { > - update_curseg_info(sbi, i); > + ret = update_curseg_info(sbi, i); Another caller of fix_curseg_info(), fsck_verify() will accept the failure silently, I think it needs to propagate the error to do_fsck(). Thanks, > + if (ret) > + return ret; > need_update = 1; > } > } > @@ -2987,6 +2989,7 @@ static void fix_curseg_info(struct f2fs_sb_info *sbi, bool check_wp) > write_curseg_info(sbi); > flush_curseg_sit_entries(sbi); > } > + return 0; > } > > int check_sit_types(struct f2fs_sb_info *sbi) > @@ -3595,23 +3598,28 @@ static void fix_wp_sit_alignment(struct f2fs_sb_info *UNUSED(sbi)) > * Check and fix consistency with write pointers at the beginning of > * fsck so that following writes by fsck do not fail. > */ > -void fsck_chk_and_fix_write_pointers(struct f2fs_sb_info *sbi) > +int fsck_chk_and_fix_write_pointers(struct f2fs_sb_info *sbi) > { > struct f2fs_fsck *fsck = F2FS_FSCK(sbi); > + int ret = 0; > > if (c.zoned_model != F2FS_ZONED_HM) > - return; > + return 0; > > if (c.fix_on) { > flush_nat_journal_entries(sbi); > flush_sit_journal_entries(sbi); > > - if (check_curseg_offsets(sbi, true)) > - fix_curseg_info(sbi, true); > + if (check_curseg_offsets(sbi, true)) { > + ret = fix_curseg_info(sbi, true); > + if (ret) > + return ret; > + } > > fix_wp_sit_alignment(sbi); > fsck->chk.wp_fixed = 1; > } > + return 0; > } > > int fsck_chk_curseg_info(struct f2fs_sb_info *sbi) > diff --git a/fsck/fsck.h b/fsck/fsck.h > index 05daa2d..ec37e08 100644 > --- a/fsck/fsck.h > +++ b/fsck/fsck.h > @@ -190,7 +190,7 @@ int fsck_chk_inline_dentries(struct f2fs_sb_info *, struct f2fs_node *, > void fsck_chk_checkpoint(struct f2fs_sb_info *sbi); > void fsck_update_sb_flags(struct f2fs_sb_info *sbi); > int fsck_chk_meta(struct f2fs_sb_info *sbi); > -void fsck_chk_and_fix_write_pointers(struct f2fs_sb_info *); > +int fsck_chk_and_fix_write_pointers(struct f2fs_sb_info *sbi); > int fsck_chk_curseg_info(struct f2fs_sb_info *); > void pretty_print_filename(const u8 *raw_name, u32 len, > char out[F2FS_PRINT_NAMELEN], int enc_name); > @@ -227,11 +227,11 @@ extern int f2fs_find_fsync_inode(struct f2fs_sb_info *, struct list_head *); > extern void f2fs_destroy_fsync_dnodes(struct list_head *); > > extern void flush_journal_entries(struct f2fs_sb_info *); > -extern void update_curseg_info(struct f2fs_sb_info *, int); > +extern int update_curseg_info(struct f2fs_sb_info *sbi, int type); > extern void zero_journal_entries(struct f2fs_sb_info *); > extern void flush_sit_entries(struct f2fs_sb_info *); > -extern void move_curseg_info(struct f2fs_sb_info *, u64, int); > -extern void move_one_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left, > +extern int move_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left); > +extern int move_one_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left, > int i); > extern void write_curseg_info(struct f2fs_sb_info *); > extern void save_curseg_warm_node_info(struct f2fs_sb_info *); > diff --git a/fsck/main.c b/fsck/main.c > index 08d38d8..460e4db 100644 > --- a/fsck/main.c > +++ b/fsck/main.c > @@ -985,7 +985,9 @@ static int do_fsck(struct f2fs_sb_info *sbi) > if (c.roll_forward && c.zoned_model == F2FS_ZONED_HM) > save_curseg_warm_node_info(sbi); > > - fsck_chk_and_fix_write_pointers(sbi); > + ret = fsck_chk_and_fix_write_pointers(sbi); > + if (ret) > + return FSCK_OPERATIONAL_ERROR; > > fsck_chk_curseg_info(sbi); > > diff --git a/fsck/mount.c b/fsck/mount.c > index 6f640a0..85ed404 100644 > --- a/fsck/mount.c > +++ b/fsck/mount.c > @@ -3159,7 +3159,7 @@ next_segment: > return -1; > } > > -void move_one_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left, > +int move_one_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left, > int i) > { > struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi); > @@ -3171,7 +3171,7 @@ void move_one_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left, > > if ((get_sb(feature) & F2FS_FEATURE_RO)) { > if (i != CURSEG_HOT_DATA && i != CURSEG_HOT_NODE) > - return; > + return 0; > > if (i == CURSEG_HOT_DATA) { > left = 0; > @@ -3191,7 +3191,10 @@ bypass_ssa: > to = from; > ret = find_next_free_block(sbi, &to, left, i, > c.zoned_model == F2FS_ZONED_HM); > - ASSERT(ret == 0); > + if (ret) { > + ERR_MSG("Failed to find next free block for curseg[%d]\n", i); > + return ret; > + } > > old_segno = curseg->segno; > curseg->segno = GET_SEGNO(sbi, to); > @@ -3211,22 +3214,27 @@ bypass_ssa: > > FIX_MSG("Move curseg[%d] %x -> %x after %"PRIx64"\n", > i, old_segno, curseg->segno, from); > + return 0; > } > > -void move_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left) > +int move_curseg_info(struct f2fs_sb_info *sbi, u64 from, int left) > { > - int i; > + int i, ret; > > /* update summary blocks having nullified journal entries */ > - for (i = 0; i < NO_CHECK_TYPE; i++) > - move_one_curseg_info(sbi, from, left, i); > + for (i = 0; i < NO_CHECK_TYPE; i++) { > + ret = move_one_curseg_info(sbi, from, left, i); > + if (ret) > + return ret; > + } > + return 0; > } > > -void update_curseg_info(struct f2fs_sb_info *sbi, int type) > +int update_curseg_info(struct f2fs_sb_info *sbi, int type) > { > if (!relocate_curseg_offset(sbi, type)) > - return; > - move_one_curseg_info(sbi, SM_I(sbi)->main_blkaddr, 0, type); > + return 0; > + return move_one_curseg_info(sbi, SM_I(sbi)->main_blkaddr, 0, type); > } > > void zero_journal_entries(struct f2fs_sb_info *sbi) > diff --git a/fsck/segment.c b/fsck/segment.c > index 96de22a..46dc747 100644 > --- a/fsck/segment.c > +++ b/fsck/segment.c > @@ -70,8 +70,8 @@ int reserve_new_block(struct f2fs_sb_info *sbi, block_t *to, > } > > if (find_next_free_block(sbi, &blkaddr, left, type, false)) { > - ERR_MSG("Can't find free block"); > - ASSERT(0); > + ERR_MSG("Can't find free block\n"); > + return -ENOSPC; > } > > se = get_seg_entry(sbi, GET_SEGNO(sbi, blkaddr)); > @@ -789,8 +789,8 @@ int update_block(struct f2fs_sb_info *sbi, void *buf, u32 *blkaddr, > > new_blkaddr = SM_I(sbi)->main_blkaddr; > if (find_next_free_block(sbi, &new_blkaddr, 0, type, false)) { > - ERR_MSG("Can't find free block for the update"); > - ASSERT(0); > + ERR_MSG("Can't find free block for the update\n"); > + return -ENOSPC; > } > > ret = dev_write_block(buf, new_blkaddr, f2fs_io_type_to_rw_hint(type)); _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel