* [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize
@ 2026-08-28 14:12 Wenjie Qi
2026-08-28 14:12 ` [f2fs-dev] [PATCH 2/2] f2fs: refresh pinned allocation boundary after resize Wenjie Qi
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Wenjie Qi @ 2026-08-28 14:12 UTC (permalink / raw)
To: jaegeuk, chao
Cc: daehojeong, qwjhust, linux-kernel, linux-f2fs-devel, qiwenjie,
sunqiuyang
During a filesystem resize, SBI_IS_RESIZEFS prevents new SIT entries
from being added to the journal and forces existing entries to the SIT
area. However, f2fs_flush_sit_entries() returns early when there are no
new dirty sentries, leaving existing journal entries behind.
After the main area shrinks, a later checkpoint can access a journal
entry whose segment number is outside the new geometry and trigger
f2fs_bug_on().
Only take the zero-dirty fast path when entries may be written back to
the journal. This lets resize drain existing entries through
remove_sits_in_journal() even when there are no new dirty sentries.
Fixes: 04f0b2eaa3b3 ("f2fs: ioctl for removing a range from F2FS")
Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com>
---
fs/f2fs/segment.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 1e7e745be71d..9f9ce25dd07e 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -4816,7 +4816,7 @@ void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc)
down_write(&sit_i->sentry_lock);
- if (!sit_i->dirty_sentries)
+ if (!sit_i->dirty_sentries && to_journal)
goto out;
/*
--
2.43.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 6+ messages in thread* [f2fs-dev] [PATCH 2/2] f2fs: refresh pinned allocation boundary after resize 2026-08-28 14:12 [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize Wenjie Qi @ 2026-08-28 14:12 ` Wenjie Qi 2026-08-28 18:08 ` Daeho Jeong 2026-09-24 15:57 ` [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize Daeho Jeong 2026-10-19 15:40 ` patchwork-bot+f2fs--- via Linux-f2fs-devel 2 siblings, 1 reply; 6+ messages in thread From: Wenjie Qi @ 2026-08-28 14:12 UTC (permalink / raw) To: jaegeuk, chao Cc: daehojeong, qwjhust, linux-kernel, linux-f2fs-devel, qiwenjie, sunqiuyang pinned_area_max_secno is derived from MAIN_SECS(), the zoned device boundary, and resizable_tail_secno. It is currently recalculated only at mount and remount, so online resize leaves the pre-resize value active after MAIN_SECS() changes. A stale value can allow pinned allocations in sections outside the new main-area boundary. Move the calculation to segment.h and call it whenever update_fs_metadata() changes MAIN_SECS(). This also restores the previous boundary when a final checkpoint error rolls the resize metadata back. Mount option validation compares the tail count with the pre-resize section count. Recalculating after a shrink below that tail would make the unsigned subtraction wrap. Reject such a shrink with -EINVAL before taking resize locks or changing filesystem geometry. Fixes: c966d29e01bb ("f2fs: support resizable tail section and unify pinned allocation") Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com> --- fs/f2fs/gc.c | 7 +++++++ fs/f2fs/segment.h | 16 ++++++++++++++++ fs/f2fs/super.c | 15 ++------------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 0a00180c21dc..978e85578c79 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -2326,6 +2326,7 @@ static void update_fs_metadata(struct f2fs_sb_info *sbi, int secs) SM_I(sbi)->segment_count = (int)SM_I(sbi)->segment_count + segs; MAIN_SEGS(sbi) = (int)MAIN_SEGS(sbi) + segs; MAIN_SECS(sbi) += secs; + f2fs_adjust_pinned_area_boundary(sbi); if (sbi->allocate_section_hint > MAIN_SECS(sbi)) sbi->allocate_section_hint = MAIN_SECS(sbi); FREE_I(sbi)->free_sections = (int)FREE_I(sbi)->free_sections + secs; @@ -2398,6 +2399,12 @@ int f2fs_resize_fs(struct file *filp, __u64 block_count) shrunk_blocks = old_block_count - block_count; secs = div_u64(shrunk_blocks, BLKS_PER_SEC(sbi)); + if (secs >= MAIN_SECS(sbi) || + F2FS_OPTION(sbi).resizable_tail_secno >= + MAIN_SECS(sbi) - secs) { + err = -EINVAL; + goto out_drop_write; + } /* stop other GC */ if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, &glc)) { diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 5949aa5200ac..7c7ca0730d77 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -91,6 +91,22 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi, #define GET_ZONE_FROM_SEG(sbi, segno) \ GET_ZONE_FROM_SEC(sbi, GET_SEC_FROM_SEG(sbi, segno)) +static inline void f2fs_adjust_pinned_area_boundary(struct f2fs_sb_info *sbi) +{ + sbi->pinned_area_max_secno = MAIN_SECS(sbi); + if (f2fs_sb_has_blkzoned(sbi) && + sbi->first_seq_zone_segno != NULL_SEGNO) + sbi->pinned_area_max_secno = + min(sbi->pinned_area_max_secno, + GET_SEC_FROM_SEG(sbi, + sbi->first_seq_zone_segno)); + if (F2FS_OPTION(sbi).resizable_tail_secno) + sbi->pinned_area_max_secno = + min(sbi->pinned_area_max_secno, + MAIN_SECS(sbi) - + F2FS_OPTION(sbi).resizable_tail_secno); +} + #define GET_SUM_BLOCK(sbi, segno) \ (SM_I(sbi)->ssa_blkaddr + (segno / (sbi)->sums_per_block)) #define GET_SUM_BLKOFF(sbi, segno) (segno % (sbi)->sums_per_block) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 253a579e9d5b..c8f8ecf49635 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -554,17 +554,6 @@ static inline void adjust_unusable_cap_perc(struct f2fs_sb_info *sbi) F2FS_OPTION(sbi).unusable_cap_perc); } -static inline void adjust_pinned_area_boundary(struct f2fs_sb_info *sbi) -{ - sbi->pinned_area_max_secno = MAIN_SECS(sbi); - if (f2fs_sb_has_blkzoned(sbi) && sbi->first_seq_zone_segno != NULL_SEGNO) - sbi->pinned_area_max_secno = min(sbi->pinned_area_max_secno, - GET_SEC_FROM_SEG(sbi, sbi->first_seq_zone_segno)); - if (F2FS_OPTION(sbi).resizable_tail_secno) - sbi->pinned_area_max_secno = min(sbi->pinned_area_max_secno, - MAIN_SECS(sbi) - F2FS_OPTION(sbi).resizable_tail_secno); -} - static void init_once(void *foo) { struct f2fs_inode_info *fi = (struct f2fs_inode_info *) foo; @@ -3078,7 +3067,7 @@ static int __f2fs_remount(struct fs_context *fc, struct super_block *sb) sb->s_flags = (sb->s_flags & ~SB_POSIXACL) | (test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0); - adjust_pinned_area_boundary(sbi); + f2fs_adjust_pinned_area_boundary(sbi); limit_reserve_root(sbi); fc->sb_flags = (flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME); @@ -5321,7 +5310,7 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc) /* get segno of first zoned block device */ sbi->first_seq_zone_segno = get_first_seq_zone_segno(sbi); - adjust_pinned_area_boundary(sbi); + f2fs_adjust_pinned_area_boundary(sbi); sbi->reserved_pin_section = f2fs_sb_has_blkzoned(sbi) ? ZONED_PIN_SEC_REQUIRED_COUNT : -- 2.43.0 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH 2/2] f2fs: refresh pinned allocation boundary after resize 2026-08-28 14:12 ` [f2fs-dev] [PATCH 2/2] f2fs: refresh pinned allocation boundary after resize Wenjie Qi @ 2026-08-28 18:08 ` Daeho Jeong 2026-08-29 6:07 ` Wenjie Qi 0 siblings, 1 reply; 6+ messages in thread From: Daeho Jeong @ 2026-08-28 18:08 UTC (permalink / raw) To: Wenjie Qi Cc: daehojeong, linux-kernel, linux-f2fs-devel, qiwenjie, jaegeuk, sunqiuyang On Fri, Aug 28, 2026 at 7:19 AM Wenjie Qi <qwjhust@gmail.com> wrote: > > pinned_area_max_secno is derived from MAIN_SECS(), the zoned device > boundary, and resizable_tail_secno. It is currently recalculated only > at mount and remount, so online resize leaves the pre-resize value > active after MAIN_SECS() changes. > > A stale value can allow pinned allocations in sections outside the > new main-area boundary. > > Move the calculation to segment.h and call it whenever > update_fs_metadata() changes MAIN_SECS(). This also restores the > previous boundary when a final checkpoint error rolls the resize > metadata back. > > Mount option validation compares the tail count with the pre-resize > section count. Recalculating after a shrink below that tail would make > the unsigned subtraction wrap. Reject such a shrink with -EINVAL > before taking resize locks or changing filesystem geometry. > > Fixes: c966d29e01bb ("f2fs: support resizable tail section and unify pinned allocation") > Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com> > --- > fs/f2fs/gc.c | 7 +++++++ > fs/f2fs/segment.h | 16 ++++++++++++++++ > fs/f2fs/super.c | 15 ++------------- > 3 files changed, 25 insertions(+), 13 deletions(-) > > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c > index 0a00180c21dc..978e85578c79 100644 > --- a/fs/f2fs/gc.c > +++ b/fs/f2fs/gc.c > @@ -2326,6 +2326,7 @@ static void update_fs_metadata(struct f2fs_sb_info *sbi, int secs) > SM_I(sbi)->segment_count = (int)SM_I(sbi)->segment_count + segs; > MAIN_SEGS(sbi) = (int)MAIN_SEGS(sbi) + segs; > MAIN_SECS(sbi) += secs; > + f2fs_adjust_pinned_area_boundary(sbi); > if (sbi->allocate_section_hint > MAIN_SECS(sbi)) > sbi->allocate_section_hint = MAIN_SECS(sbi); > FREE_I(sbi)->free_sections = (int)FREE_I(sbi)->free_sections + secs; > @@ -2398,6 +2399,12 @@ int f2fs_resize_fs(struct file *filp, __u64 block_count) > > shrunk_blocks = old_block_count - block_count; > secs = div_u64(shrunk_blocks, BLKS_PER_SEC(sbi)); > + if (secs >= MAIN_SECS(sbi) || > + F2FS_OPTION(sbi).resizable_tail_secno >= > + MAIN_SECS(sbi) - secs) { > + err = -EINVAL; > + goto out_drop_write; > + } Hi Wenjie, The condition can be simplified to avoid unsigned subtraction underflow: if (MAIN_SECS(sbi) <= secs + F2FS_OPTION(sbi).resizable_tail_secno) Plus, 1. Could you print out some message here for users to recognize the failure reason? 2. Can we move this check earlier, before mnt_want_write_file(filp)? That way we can return -EINVAL immediately on invalid parameters without the unnecessary mnt_want_write_file() / mnt_drop_write_file() cycle. > > /* stop other GC */ > if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, &glc)) { > diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h > index 5949aa5200ac..7c7ca0730d77 100644 > --- a/fs/f2fs/segment.h > +++ b/fs/f2fs/segment.h > @@ -91,6 +91,22 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi, > #define GET_ZONE_FROM_SEG(sbi, segno) \ > GET_ZONE_FROM_SEC(sbi, GET_SEC_FROM_SEG(sbi, segno)) > > +static inline void f2fs_adjust_pinned_area_boundary(struct f2fs_sb_info *sbi) > +{ > + sbi->pinned_area_max_secno = MAIN_SECS(sbi); > + if (f2fs_sb_has_blkzoned(sbi) && > + sbi->first_seq_zone_segno != NULL_SEGNO) > + sbi->pinned_area_max_secno = > + min(sbi->pinned_area_max_secno, > + GET_SEC_FROM_SEG(sbi, > + sbi->first_seq_zone_segno)); > + if (F2FS_OPTION(sbi).resizable_tail_secno) > + sbi->pinned_area_max_secno = > + min(sbi->pinned_area_max_secno, > + MAIN_SECS(sbi) - > + F2FS_OPTION(sbi).resizable_tail_secno); > +} > + In f2fs_adjust_pinned_area_boundary(), the line breaks around min() seem a bit excessive. Can we format it more concisely like the original version? Thanks, > #define GET_SUM_BLOCK(sbi, segno) \ > (SM_I(sbi)->ssa_blkaddr + (segno / (sbi)->sums_per_block)) > #define GET_SUM_BLKOFF(sbi, segno) (segno % (sbi)->sums_per_block) > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c > index 253a579e9d5b..c8f8ecf49635 100644 > --- a/fs/f2fs/super.c > +++ b/fs/f2fs/super.c > @@ -554,17 +554,6 @@ static inline void adjust_unusable_cap_perc(struct f2fs_sb_info *sbi) > F2FS_OPTION(sbi).unusable_cap_perc); > } > > -static inline void adjust_pinned_area_boundary(struct f2fs_sb_info *sbi) > -{ > - sbi->pinned_area_max_secno = MAIN_SECS(sbi); > - if (f2fs_sb_has_blkzoned(sbi) && sbi->first_seq_zone_segno != NULL_SEGNO) > - sbi->pinned_area_max_secno = min(sbi->pinned_area_max_secno, > - GET_SEC_FROM_SEG(sbi, sbi->first_seq_zone_segno)); > - if (F2FS_OPTION(sbi).resizable_tail_secno) > - sbi->pinned_area_max_secno = min(sbi->pinned_area_max_secno, > - MAIN_SECS(sbi) - F2FS_OPTION(sbi).resizable_tail_secno); > -} > - > static void init_once(void *foo) > { > struct f2fs_inode_info *fi = (struct f2fs_inode_info *) foo; > @@ -3078,7 +3067,7 @@ static int __f2fs_remount(struct fs_context *fc, struct super_block *sb) > sb->s_flags = (sb->s_flags & ~SB_POSIXACL) | > (test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0); > > - adjust_pinned_area_boundary(sbi); > + f2fs_adjust_pinned_area_boundary(sbi); > limit_reserve_root(sbi); > fc->sb_flags = (flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME); > > @@ -5321,7 +5310,7 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc) > /* get segno of first zoned block device */ > sbi->first_seq_zone_segno = get_first_seq_zone_segno(sbi); > > - adjust_pinned_area_boundary(sbi); > + f2fs_adjust_pinned_area_boundary(sbi); > > sbi->reserved_pin_section = f2fs_sb_has_blkzoned(sbi) ? > ZONED_PIN_SEC_REQUIRED_COUNT : > -- > 2.43.0 > > > > _______________________________________________ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH 2/2] f2fs: refresh pinned allocation boundary after resize 2026-08-28 18:08 ` Daeho Jeong @ 2026-08-29 6:07 ` Wenjie Qi 0 siblings, 0 replies; 6+ messages in thread From: Wenjie Qi @ 2026-08-29 6:07 UTC (permalink / raw) To: daeho43 Cc: daehojeong, qwjhust, linux-kernel, linux-f2fs-devel, qiwenjie, jaegeuk, sunqiuyang Hi Daeho, I incorporated the review in v2: - Simplified the incompatible-tail condition. - Added an error message with the main, shrink, and tail section counts. - Moved the check before mnt_want_write_file(). - Restored the compact formatting in the shared boundary helper. - Added a post-freeze recheck for a concurrent remount option change. The complete v2 series was sent separately. Thanks, Wenjie _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize 2026-08-28 14:12 [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize Wenjie Qi 2026-08-28 14:12 ` [f2fs-dev] [PATCH 2/2] f2fs: refresh pinned allocation boundary after resize Wenjie Qi @ 2026-09-24 15:57 ` Daeho Jeong 2026-10-19 15:40 ` patchwork-bot+f2fs--- via Linux-f2fs-devel 2 siblings, 0 replies; 6+ messages in thread From: Daeho Jeong @ 2026-09-24 15:57 UTC (permalink / raw) To: Wenjie Qi Cc: daehojeong, linux-kernel, linux-f2fs-devel, qiwenjie, jaegeuk, sunqiuyang On Fri, Aug 28, 2026 at 7:15 AM Wenjie Qi <qwjhust@gmail.com> wrote: > > During a filesystem resize, SBI_IS_RESIZEFS prevents new SIT entries > from being added to the journal and forces existing entries to the SIT > area. However, f2fs_flush_sit_entries() returns early when there are no > new dirty sentries, leaving existing journal entries behind. > > After the main area shrinks, a later checkpoint can access a journal > entry whose segment number is outside the new geometry and trigger > f2fs_bug_on(). > > Only take the zero-dirty fast path when entries may be written back to > the journal. This lets resize drain existing entries through > remove_sits_in_journal() even when there are no new dirty sentries. > > Fixes: 04f0b2eaa3b3 ("f2fs: ioctl for removing a range from F2FS") > Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com> > --- > fs/f2fs/segment.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c > index 1e7e745be71d..9f9ce25dd07e 100644 > --- a/fs/f2fs/segment.c > +++ b/fs/f2fs/segment.c > @@ -4816,7 +4816,7 @@ void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) > > down_write(&sit_i->sentry_lock); > > - if (!sit_i->dirty_sentries) > + if (!sit_i->dirty_sentries && to_journal) > goto out; > > /* > -- > 2.43.0 > Reviewed-by: Daeho Jeong <daehojeong@google.com> Thanks, > > > _______________________________________________ > Linux-f2fs-devel mailing list > Linux-f2fs-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize 2026-08-28 14:12 [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize Wenjie Qi 2026-08-28 14:12 ` [f2fs-dev] [PATCH 2/2] f2fs: refresh pinned allocation boundary after resize Wenjie Qi 2026-09-24 15:57 ` [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize Daeho Jeong @ 2026-10-19 15:40 ` patchwork-bot+f2fs--- via Linux-f2fs-devel 2 siblings, 0 replies; 6+ messages in thread From: patchwork-bot+f2fs--- via Linux-f2fs-devel @ 2026-10-19 15:40 UTC (permalink / raw) To: Wenjie Qi Cc: daehojeong, linux-kernel, linux-f2fs-devel, qiwenjie, jaegeuk, sunqiuyang Hello: This series was applied to jaegeuk/f2fs.git (dev) by Jaegeuk Kim <jaegeuk@kernel.org>: On Fri, 28 Aug 2026 22:12:39 +0800 you wrote: > During a filesystem resize, SBI_IS_RESIZEFS prevents new SIT entries > from being added to the journal and forces existing entries to the SIT > area. However, f2fs_flush_sit_entries() returns early when there are no > new dirty sentries, leaving existing journal entries behind. > > After the main area shrinks, a later checkpoint can access a journal > entry whose segment number is outside the new geometry and trigger > f2fs_bug_on(). > > [...] Here is the summary with links: - [f2fs-dev,1/2] f2fs: flush SIT journal during filesystem resize https://git.kernel.org/jaegeuk/f2fs/c/a6ede4054551 - [f2fs-dev,2/2] f2fs: refresh pinned allocation boundary after resize (no matching commit) You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-19 15:40 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-28 14:12 [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize Wenjie Qi 2026-08-28 14:12 ` [f2fs-dev] [PATCH 2/2] f2fs: refresh pinned allocation boundary after resize Wenjie Qi 2026-08-28 18:08 ` Daeho Jeong 2026-08-29 6:07 ` Wenjie Qi 2026-09-24 15:57 ` [f2fs-dev] [PATCH 1/2] f2fs: flush SIT journal during filesystem resize Daeho Jeong 2026-10-19 15:40 ` patchwork-bot+f2fs--- via Linux-f2fs-devel
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.