* [PATCH] f2fs: fix FG GC failure when file in victim is pinned @ 2026-06-20 9:34 Jiucheng Xu via B4 Relay 2026-06-22 1:46 ` Chao Yu 0 siblings, 1 reply; 5+ messages in thread From: Jiucheng Xu via B4 Relay @ 2026-06-20 9:34 UTC (permalink / raw) To: Jaegeuk Kim, Chao Yu Cc: linux-f2fs-devel, linux-kernel, jianxin.pan, tuan.zhang, Jiucheng Xu From: Jiucheng Xu <jiucheng.xu@amlogic.com> When continuous write operations occur in the system, BG GC fails to work. This leads to large dirty_segments and small free_segments. If fallocate() is performed on a pinned file with the allocated space exceeding the free_segment, FG_GC reclamation fails. The reason is that the file corresponding to the block in the victim is pinned, causing gc_data_segment() to fail. Since the condition sec_freed < gc_control->nr_free_secs isn't satisfied, GC stops, resulting in the failure of f2fs_fallocate() allocation. Setting gc_control->nr_free_secs = 1 make FG GC continue searching for new victim. Signed-off-by: Jiucheng Xu <jiucheng.xu@amlogic.com> --- fs/f2fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 8acdd94272a0ced448e0ba21635d702cfec10682..3e49a73bbf3a184a314e97bff9509a66c27eac00 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1883,7 +1883,7 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, .init_gc_type = FG_GC, .should_migrate_blocks = false, .err_gc_skipped = true, - .nr_free_secs = 0 }; + .nr_free_secs = 1 }; pgoff_t pg_start, pg_end; loff_t new_size; loff_t off_end; --- base-commit: b51f606aa323d553d786ed681a213f134dc688d6 change-id: 20260620-origin-dev-99cdccc83800 Best regards, -- Jiucheng Xu <jiucheng.xu@amlogic.com> ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] f2fs: fix FG GC failure when file in victim is pinned 2026-06-20 9:34 [PATCH] f2fs: fix FG GC failure when file in victim is pinned Jiucheng Xu via B4 Relay @ 2026-06-22 1:46 ` Chao Yu 2026-06-22 10:40 ` Jiucheng Xu 0 siblings, 1 reply; 5+ messages in thread From: Chao Yu @ 2026-06-22 1:46 UTC (permalink / raw) To: jiucheng.xu, Jaegeuk Kim Cc: chao, linux-f2fs-devel, linux-kernel, jianxin.pan, tuan.zhang On 6/20/26 17:34, Jiucheng Xu via B4 Relay wrote: > From: Jiucheng Xu <jiucheng.xu@amlogic.com> > > When continuous write operations occur in the system, BG GC fails to > work. This leads to large dirty_segments and small free_segments. If > fallocate() is performed on a pinned file with the allocated space > exceeding the free_segment, FG_GC reclamation fails. > > The reason is that the file corresponding to the block in the victim is > pinned, causing gc_data_segment() to fail. Since the condition sec_freed Jiucheng, pinned file should be aligned to section size, why there is fragmented blocks of pinfile locates in dirty sections? > < gc_control->nr_free_secs isn't satisfied, GC stops, resulting in the > failure of f2fs_fallocate() allocation. > > Setting gc_control->nr_free_secs = 1 make FG GC continue searching > for new victim. Maybe we can try this instead of changing f2fs_expand_inode_data() logic: 1. call fggc via ioctl or trigger urgent gc via sysfs 2. fallocate on pinfile, goto 1) if it failed But, anyway, I suspect it's risk, if there is no normal dirty section, FGGC will try to call f2fs_unpin_all_sections(), then migrate dirty section which has pinned blocks, that will cause more damage. Can you please figure out why pinfile is fragmented first... Thanks, > > Signed-off-by: Jiucheng Xu <jiucheng.xu@amlogic.com> > --- > fs/f2fs/file.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c > index 8acdd94272a0ced448e0ba21635d702cfec10682..3e49a73bbf3a184a314e97bff9509a66c27eac00 100644 > --- a/fs/f2fs/file.c > +++ b/fs/f2fs/file.c > @@ -1883,7 +1883,7 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, > .init_gc_type = FG_GC, > .should_migrate_blocks = false, > .err_gc_skipped = true, > - .nr_free_secs = 0 }; > + .nr_free_secs = 1 }; > pgoff_t pg_start, pg_end; > loff_t new_size; > loff_t off_end; > > --- > base-commit: b51f606aa323d553d786ed681a213f134dc688d6 > change-id: 20260620-origin-dev-99cdccc83800 > > Best regards, ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] f2fs: fix FG GC failure when file in victim is pinned 2026-06-22 1:46 ` Chao Yu @ 2026-06-22 10:40 ` Jiucheng Xu 2026-06-25 7:09 ` Chao Yu 0 siblings, 1 reply; 5+ messages in thread From: Jiucheng Xu @ 2026-06-22 10:40 UTC (permalink / raw) To: Chao Yu, Jaegeuk Kim Cc: linux-f2fs-devel, linux-kernel, jianxin.pan, tuan.zhang On 6/22/2026 9:46 AM, Chao Yu wrote: > [Some people who received this message don't often get email from > chao@kernel.org. Learn why this is important at https://aka.ms/ > LearnAboutSenderIdentification ] > > [ EXTERNAL EMAIL ] > > On 6/20/26 17:34, Jiucheng Xu via B4 Relay wrote: >> From: Jiucheng Xu <jiucheng.xu@amlogic.com> >> >> When continuous write operations occur in the system, BG GC fails to >> work. This leads to large dirty_segments and small free_segments. If >> fallocate() is performed on a pinned file with the allocated space >> exceeding the free_segment, FG_GC reclamation fails. >> >> The reason is that the file corresponding to the block in the victim is >> pinned, causing gc_data_segment() to fail. Since the condition sec_freed > > Jiucheng, > > pinned file should be aligned to section size, why there is fragmented > blocks > of pinfile locates in dirty sections? > >> < gc_control->nr_free_secs isn't satisfied, GC stops, resulting in the >> failure of f2fs_fallocate() allocation. >> >> Setting gc_control->nr_free_secs = 1 make FG GC continue searching >> for new victim. > > Maybe we can try this instead of changing f2fs_expand_inode_data() logic: > 1. call fggc via ioctl or trigger urgent gc via sysfs > 2. fallocate on pinfile, goto 1) if it failed > > But, anyway, I suspect it's risk, if there is no normal dirty section, > FGGC will try to call f2fs_unpin_all_sections(), then migrate dirty section > which has pinned blocks, that will cause more damage. > > Can you please figure out why pinfile is fragmented first... Hi Chao, Thanks for your feedback. I just do a test to simulate the Android OTA createCowImage failed when dirty_segments is too large. Simple reproduction steps: 1. In my case, dirty_segments=969, free_segments=96, free space = 1.7G, section:segment = 1:1 2. touch a.bin 3. f2fs_io pinfile set a.bin 4. fallocate -l 1.5G a.bin And f2fs_fallocate() returns -11. Although the urgent mode work fine, but it is not very convenient to control since AOPS has a great deal of code that calls fallocate. I have tried 5 times to fallocate(), but GC always selects the same victim segno. So I think it is an issue. The trace: f2fs_get_victim: dev = (254,0), type = No TYPE, policy = (Foreground GC, LFS-mode, Greedy), victim = 624, cost = 19... f2fs_gc_end: dev = (254,0), ret = 0, seg_freed = 0, sec_freed = 0, nodes = 117, dents = 0, imeta = 98, free_sec:50, free_seg:50, rsv_seg:47, prefree_seg:47 I dump the failed victim segno, block offset in segment and related inode ino: do_garbage_collect: ino=33902 segno=624 off=132 The dump of pinfile 33902 info: main_blkaddr [0x 2600 : 9728] i_inline [0x 61 : 97] inline shows the file is pinned (0x60) i_addr[0x9] [0x 2f7b2 : 194482] i_addr[0xa] [0x 2f7b3 : 194483] i_addr[0xb] [0x 2f7b4 : 194484] ... i_addr[0x1d] [0x 2f7c6 : 194502] i_addr[0x1e] [0x 465af : 288175] i_addr[0x1f] [0x 465b0 : 288176] ... i_addr[0x21] [0x 465b2 : 288178] i_addr[0x22] [0x 5046d : 328813] i_addr[0x23] [0x 5046e : 328814] i_addr[0x24] [0x 505b6 : 329142] i_addr[0x25] [0x 505b7 : 329143] i_addr[0x26] [0x 505b8 : 329144] i_addr[0x27] [0x 50684 : 329348] i_addr[0x28] [0x 50685 : 329349] The file is created by logcat,and looks like indeed fragmented. Calculate the block address: 624 * 512 + 132 + 9728(main_blkaddr) = 329348 So the i_addr[0x27] = 329348 is the failed block. Regarding "why the pinfile is fragmented" you said, we use v5.15 + android U. Is it that v5.15 lacks some patches for special handling of pinfiles? Thanks, > > Thanks, > >> >> Signed-off-by: Jiucheng Xu <jiucheng.xu@amlogic.com> >> --- >> fs/f2fs/file.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c >> index >> 8acdd94272a0ced448e0ba21635d702cfec10682..3e49a73bbf3a184a314e97bff9509a66c27eac00 100644 >> --- a/fs/f2fs/file.c >> +++ b/fs/f2fs/file.c >> @@ -1883,7 +1883,7 @@ static int f2fs_expand_inode_data(struct inode >> *inode, loff_t offset, >> .init_gc_type = FG_GC, >> .should_migrate_blocks = false, >> .err_gc_skipped = true, >> - .nr_free_secs = 0 }; >> + .nr_free_secs = 1 }; >> pgoff_t pg_start, pg_end; >> loff_t new_size; >> loff_t off_end; >> >> --- >> base-commit: b51f606aa323d553d786ed681a213f134dc688d6 >> change-id: 20260620-origin-dev-99cdccc83800 >> >> Best regards, > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] f2fs: fix FG GC failure when file in victim is pinned 2026-06-22 10:40 ` Jiucheng Xu @ 2026-06-25 7:09 ` Chao Yu 2026-06-26 8:12 ` Jiucheng Xu 0 siblings, 1 reply; 5+ messages in thread From: Chao Yu @ 2026-06-25 7:09 UTC (permalink / raw) To: Jiucheng Xu, Jaegeuk Kim Cc: chao, linux-f2fs-devel, linux-kernel, jianxin.pan, tuan.zhang On 6/22/26 18:40, Jiucheng Xu wrote: > > On 6/22/2026 9:46 AM, Chao Yu wrote: >> [Some people who received this message don't often get email from chao@kernel.org. Learn why this is important at https://aka.ms/ LearnAboutSenderIdentification ] >> >> [ EXTERNAL EMAIL ] >> >> On 6/20/26 17:34, Jiucheng Xu via B4 Relay wrote: >>> From: Jiucheng Xu <jiucheng.xu@amlogic.com> >>> >>> When continuous write operations occur in the system, BG GC fails to >>> work. This leads to large dirty_segments and small free_segments. If >>> fallocate() is performed on a pinned file with the allocated space >>> exceeding the free_segment, FG_GC reclamation fails. >>> >>> The reason is that the file corresponding to the block in the victim is >>> pinned, causing gc_data_segment() to fail. Since the condition sec_freed >> >> Jiucheng, >> >> pinned file should be aligned to section size, why there is fragmented blocks >> of pinfile locates in dirty sections? >> >>> < gc_control->nr_free_secs isn't satisfied, GC stops, resulting in the >>> failure of f2fs_fallocate() allocation. >>> >>> Setting gc_control->nr_free_secs = 1 make FG GC continue searching >>> for new victim. >> >> Maybe we can try this instead of changing f2fs_expand_inode_data() logic: >> 1. call fggc via ioctl or trigger urgent gc via sysfs >> 2. fallocate on pinfile, goto 1) if it failed >> >> But, anyway, I suspect it's risk, if there is no normal dirty section, >> FGGC will try to call f2fs_unpin_all_sections(), then migrate dirty section >> which has pinned blocks, that will cause more damage. >> >> Can you please figure out why pinfile is fragmented first... > > Hi Chao, > > Thanks for your feedback. I just do a test to simulate the Android OTA createCowImage failed when dirty_segments is too large. > > Simple reproduction steps: > 1. In my case, dirty_segments=969, free_segments=96, free space = 1.7G, section:segment = 1:1 > 2. touch a.bin > 3. f2fs_io pinfile set a.bin > 4. fallocate -l 1.5G a.bin > > And f2fs_fallocate() returns -11. > > Although the urgent mode work fine, but it is not very convenient to control since AOPS has a great deal of code that calls fallocate. > > I have tried 5 times to fallocate(), but GC always selects the same victim segno. So I think it is an issue. > > > The trace: > f2fs_get_victim: dev = (254,0), type = No TYPE, policy = (Foreground GC, LFS-mode, Greedy), victim = 624, cost = 19... > > f2fs_gc_end: dev = (254,0), ret = 0, seg_freed = 0, sec_freed = 0, nodes = 117, dents = 0, imeta = 98, free_sec:50, free_seg:50, rsv_seg:47, prefree_seg:47 > > > I dump the failed victim segno, block offset in segment and related inode ino: > do_garbage_collect: ino=33902 segno=624 off=132 > > The dump of pinfile 33902 info: > main_blkaddr [0x 2600 : 9728] > i_inline [0x 61 : 97] > inline shows the file is pinned (0x60) > i_addr[0x9] [0x 2f7b2 : 194482] > i_addr[0xa] [0x 2f7b3 : 194483] > i_addr[0xb] [0x 2f7b4 : 194484] > ... > i_addr[0x1d] [0x 2f7c6 : 194502] > i_addr[0x1e] [0x 465af : 288175] > i_addr[0x1f] [0x 465b0 : 288176] > ... > i_addr[0x21] [0x 465b2 : 288178] > i_addr[0x22] [0x 5046d : 328813] > i_addr[0x23] [0x 5046e : 328814] > i_addr[0x24] [0x 505b6 : 329142] > i_addr[0x25] [0x 505b7 : 329143] > i_addr[0x26] [0x 505b8 : 329144] > i_addr[0x27] [0x 50684 : 329348] > i_addr[0x28] [0x 50685 : 329349] > > The file is created by logcat,and looks like indeed fragmented. > > Calculate the block address: > 624 * 512 + 132 + 9728(main_blkaddr) = 329348 > > So the i_addr[0x27] = 329348 is the failed block. > > Regarding "why the pinfile is fragmented" you said, we use v5.15 + android U. Is it that v5.15 lacks some patches for special handling of pinfiles? Ah, I think you can unpin log file created by logcat, the flag is added in aosp/1014260 to avoid fragmentation in filesystem (), but it's gone in aosp/43c6d76a Thanks, > > Thanks, > > >> >> Thanks, >> >>> >>> Signed-off-by: Jiucheng Xu <jiucheng.xu@amlogic.com> >>> --- >>> fs/f2fs/file.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c >>> index 8acdd94272a0ced448e0ba21635d702cfec10682..3e49a73bbf3a184a314e97bff9509a66c27eac00 100644 >>> --- a/fs/f2fs/file.c >>> +++ b/fs/f2fs/file.c >>> @@ -1883,7 +1883,7 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, >>> .init_gc_type = FG_GC, >>> .should_migrate_blocks = false, >>> .err_gc_skipped = true, >>> - .nr_free_secs = 0 }; >>> + .nr_free_secs = 1 }; >>> pgoff_t pg_start, pg_end; >>> loff_t new_size; >>> loff_t off_end; >>> >>> --- >>> base-commit: b51f606aa323d553d786ed681a213f134dc688d6 >>> change-id: 20260620-origin-dev-99cdccc83800 >>> >>> Best regards, >> > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] f2fs: fix FG GC failure when file in victim is pinned 2026-06-25 7:09 ` Chao Yu @ 2026-06-26 8:12 ` Jiucheng Xu 0 siblings, 0 replies; 5+ messages in thread From: Jiucheng Xu @ 2026-06-26 8:12 UTC (permalink / raw) To: Chao Yu, Jaegeuk Kim Cc: linux-f2fs-devel, linux-kernel, jianxin.pan, tuan.zhang On 6/25/2026 3:09 PM, Chao Yu wrote: > [Some people who received this message don't often get email from chao@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] > > [ EXTERNAL EMAIL ] > > On 6/22/26 18:40, Jiucheng Xu wrote: >> >> Regarding "why the pinfile is fragmented" you said, we use v5.15 + android U. Is it that v5.15 lacks some patches for special handling of pinfiles? > > Ah, I think you can unpin log file created by logcat, the flag is added > in aosp/1014260 to avoid fragmentation in filesystem (), but it's gone in > aosp/43c6d76a > > Thanks, Thanks Chao, I think unpinning the log file can avoid this issue. Let me ask a bit more. I wonder why gc_control.nr_free_secs must be 0 in f2fs_expand_inode_data(). static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, loff_t len, int mode) { struct f2fs_gc_control gc_control = { .victim_segno = NULL_SEGNO, .init_gc_type = FG_GC, .should_migrate_blocks = false, .err_gc_skipped = true, .nr_free_secs = 0 }; Since it has reached such an urgent situation that FG GC needs to be triggered, I think the GC should try the second most suitable victim instead of returning -EAGAIN. int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control) { if (gc_type == FG_GC) { sbi->cur_victim_sec = NULL_SEGNO; if (has_enough_free_secs(sbi, sec_freed, 0)) { if (!gc_control->no_bg_gc && total_sec_freed < gc_control->nr_free_secs) //If nr_free_secs = 1, GC can try the second most suitable victim. goto go_gc_more; goto stop; } Is there any risk if it is set to 1? If I'm not mistaken, for pinned files, the allocation in f2fs_expand_inode_data() is also carried out in units of sections. Therefore, it should be reasonable to set nr_free_secs to 1 here. Welcome your feedback! Thanks, >>>> Signed-off-by: Jiucheng Xu <jiucheng.xu@amlogic.com> >>>> --- >>>> fs/f2fs/file.c | 2 +- >>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>> >>>> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c >>>> index 8acdd94272a0ced448e0ba21635d702cfec10682..3e49a73bbf3a184a314e97bff9509a66c27eac00 100644 >>>> --- a/fs/f2fs/file.c >>>> +++ b/fs/f2fs/file.c >>>> @@ -1883,7 +1883,7 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, >>>> .init_gc_type = FG_GC, >>>> .should_migrate_blocks = false, >>>> .err_gc_skipped = true, >>>> - .nr_free_secs = 0 }; >>>> + .nr_free_secs = 1 }; >>>> pgoff_t pg_start, pg_end; >>>> loff_t new_size; >>>> loff_t off_end; >>>> >>>> --- >>>> base-commit: b51f606aa323d553d786ed681a213f134dc688d6 >>>> change-id: 20260620-origin-dev-99cdccc83800 >>>> >>>> Best regards, >>> >> > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-06-26 8:12 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-06-20 9:34 [PATCH] f2fs: fix FG GC failure when file in victim is pinned Jiucheng Xu via B4 Relay 2026-06-22 1:46 ` Chao Yu 2026-06-22 10:40 ` Jiucheng Xu 2026-06-25 7:09 ` Chao Yu 2026-06-26 8:12 ` Jiucheng Xu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome