When the proportion of dirty segments within a section exceeds the
valid_thresh_ratio, the gc_cost of that section is set to UINT_MAX,
indicating that these sections should not be released. However, if all
section costs within the scanning range of get_victim() are UINT_MAX,
background GC will still occur. Add a condition to prevent this situation.
Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com>
---
fs/f2fs/gc.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 4a8c08f970e3..ffc3188416f4 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -936,6 +936,11 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result,
}
}
+ if (f2fs_sb_has_blkzoned(sbi) && p.min_cost == UINT_MAX) {
+ ret = -ENODATA;
+ goto out;
+ }
+
/* get victim for GC_AT/AT_SSR */
if (is_atgc) {
lookup_victim_by_age(sbi, &p);
--
2.34.1
On 9/9/25 21:44, Liao Yuanhong wrote: > When the proportion of dirty segments within a section exceeds the > valid_thresh_ratio, the gc_cost of that section is set to UINT_MAX, > indicating that these sections should not be released. However, if all > section costs within the scanning range of get_victim() are UINT_MAX, > background GC will still occur. Add a condition to prevent this situation. For this case, f2fs_get_victim() will return 0, and f2fs_gc() will use unchanged segno for GC? Thanks, > > Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com> > --- > fs/f2fs/gc.c | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c > index 4a8c08f970e3..ffc3188416f4 100644 > --- a/fs/f2fs/gc.c > +++ b/fs/f2fs/gc.c > @@ -936,6 +936,11 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result, > } > } > > + if (f2fs_sb_has_blkzoned(sbi) && p.min_cost == UINT_MAX) { > + ret = -ENODATA; > + goto out; > + } > + > /* get victim for GC_AT/AT_SSR */ > if (is_atgc) { > lookup_victim_by_age(sbi, &p);
On 9/15/2025 4:36 PM, Chao Yu wrote: > On 9/9/25 21:44, Liao Yuanhong wrote: >> When the proportion of dirty segments within a section exceeds the >> valid_thresh_ratio, the gc_cost of that section is set to UINT_MAX, >> indicating that these sections should not be released. However, if all >> section costs within the scanning range of get_victim() are UINT_MAX, >> background GC will still occur. Add a condition to prevent this situation. > For this case, f2fs_get_victim() will return 0, and f2fs_gc() will use unchanged > segno for GC? > > Thanks, You're right, segno won't update in this scenario, and this patch feature is redundant. Thanks, Liao >> Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com> >> --- >> fs/f2fs/gc.c | 5 +++++ >> 1 file changed, 5 insertions(+) >> >> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c >> index 4a8c08f970e3..ffc3188416f4 100644 >> --- a/fs/f2fs/gc.c >> +++ b/fs/f2fs/gc.c >> @@ -936,6 +936,11 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result, >> } >> } >> >> + if (f2fs_sb_has_blkzoned(sbi) && p.min_cost == UINT_MAX) { >> + ret = -ENODATA; >> + goto out; >> + } >> + >> /* get victim for GC_AT/AT_SSR */ >> if (is_atgc) { >> lookup_victim_by_age(sbi, &p);
On 9/17/25 15:08, Liao Yuanhong wrote: > > On 9/15/2025 4:36 PM, Chao Yu wrote: >> On 9/9/25 21:44, Liao Yuanhong wrote: >>> When the proportion of dirty segments within a section exceeds the >>> valid_thresh_ratio, the gc_cost of that section is set to UINT_MAX, >>> indicating that these sections should not be released. However, if all >>> section costs within the scanning range of get_victim() are UINT_MAX, >>> background GC will still occur. Add a condition to prevent this situation. >> For this case, f2fs_get_victim() will return 0, and f2fs_gc() will use unchanged >> segno for GC? >> >> Thanks, > > You're right, segno won't update in this scenario, and this patch feature is redundant. Oh, I meant, if f2fs_get_victim() fails to select a valid victim due to the reason you described, f2fs_get_victim() will return 0, and f2fs_gc() will migrate segment #NULL_SEGNO? Or am I missing something? Thanks, > > > Thanks, > > Liao > >>> Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com> >>> --- >>> fs/f2fs/gc.c | 5 +++++ >>> 1 file changed, 5 insertions(+) >>> >>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c >>> index 4a8c08f970e3..ffc3188416f4 100644 >>> --- a/fs/f2fs/gc.c >>> +++ b/fs/f2fs/gc.c >>> @@ -936,6 +936,11 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result, >>> } >>> } >>> + if (f2fs_sb_has_blkzoned(sbi) && p.min_cost == UINT_MAX) { >>> + ret = -ENODATA; >>> + goto out; >>> + } >>> + >>> /* get victim for GC_AT/AT_SSR */ >>> if (is_atgc) { >>> lookup_victim_by_age(sbi, &p);
On 9/17/2025 3:57 PM, Chao Yu wrote: > On 9/17/25 15:08, Liao Yuanhong wrote: >> On 9/15/2025 4:36 PM, Chao Yu wrote: >>> On 9/9/25 21:44, Liao Yuanhong wrote: >>>> When the proportion of dirty segments within a section exceeds the >>>> valid_thresh_ratio, the gc_cost of that section is set to UINT_MAX, >>>> indicating that these sections should not be released. However, if all >>>> section costs within the scanning range of get_victim() are UINT_MAX, >>>> background GC will still occur. Add a condition to prevent this situation. >>> For this case, f2fs_get_victim() will return 0, and f2fs_gc() will use unchanged >>> segno for GC? >>> >>> Thanks, >> You're right, segno won't update in this scenario, and this patch feature is redundant. > Oh, I meant, if f2fs_get_victim() fails to select a valid victim due to the reason you > described, f2fs_get_victim() will return 0, and f2fs_gc() will migrate segment #NULL_SEGNO? > Or am I missing something? > > Thanks, Yes. In this scenario, since it won't enter the|p.min_cost > cost|condition,|p.min_segno|will retain its initial value|||NULL_SEGNO|. This is consistent with what you described. Thanks, Liao >> >> Thanks, >> >> Liao >> >>>> Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com> >>>> --- >>>> fs/f2fs/gc.c | 5 +++++ >>>> 1 file changed, 5 insertions(+) >>>> >>>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c >>>> index 4a8c08f970e3..ffc3188416f4 100644 >>>> --- a/fs/f2fs/gc.c >>>> +++ b/fs/f2fs/gc.c >>>> @@ -936,6 +936,11 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result, >>>> } >>>> } >>>> + if (f2fs_sb_has_blkzoned(sbi) && p.min_cost == UINT_MAX) { >>>> + ret = -ENODATA; >>>> + goto out; >>>> + } >>>> + >>>> /* get victim for GC_AT/AT_SSR */ >>>> if (is_atgc) { >>>> lookup_victim_by_age(sbi, &p);
On 9/17/25 16:13, Liao Yuanhong wrote: > > On 9/17/2025 3:57 PM, Chao Yu wrote: >> On 9/17/25 15:08, Liao Yuanhong wrote: >>> On 9/15/2025 4:36 PM, Chao Yu wrote: >>>> On 9/9/25 21:44, Liao Yuanhong wrote: >>>>> When the proportion of dirty segments within a section exceeds the >>>>> valid_thresh_ratio, the gc_cost of that section is set to UINT_MAX, >>>>> indicating that these sections should not be released. However, if all >>>>> section costs within the scanning range of get_victim() are UINT_MAX, >>>>> background GC will still occur. Add a condition to prevent this situation. >>>> For this case, f2fs_get_victim() will return 0, and f2fs_gc() will use unchanged >>>> segno for GC? >>>> >>>> Thanks, >>> You're right, segno won't update in this scenario, and this patch feature is redundant. >> Oh, I meant, if f2fs_get_victim() fails to select a valid victim due to the reason you >> described, f2fs_get_victim() will return 0, and f2fs_gc() will migrate segment #NULL_SEGNO? >> Or am I missing something? >> >> Thanks, > > Yes. In this scenario, since it won't enter the|p.min_cost > cost|condition,|p.min_segno|will retain its initial value|||NULL_SEGNO|. This is consistent with what you described. Do you have a script to reproduce this bug? Thanks, > > > Thanks, > > Liao > >>> >>> Thanks, >>> >>> Liao >>> >>>>> Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com> >>>>> --- >>>>> fs/f2fs/gc.c | 5 +++++ >>>>> 1 file changed, 5 insertions(+) >>>>> >>>>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c >>>>> index 4a8c08f970e3..ffc3188416f4 100644 >>>>> --- a/fs/f2fs/gc.c >>>>> +++ b/fs/f2fs/gc.c >>>>> @@ -936,6 +936,11 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result, >>>>> } >>>>> } >>>>> + if (f2fs_sb_has_blkzoned(sbi) && p.min_cost == UINT_MAX) { >>>>> + ret = -ENODATA; >>>>> + goto out; >>>>> + } >>>>> + >>>>> /* get victim for GC_AT/AT_SSR */ >>>>> if (is_atgc) { >>>>> lookup_victim_by_age(sbi, &p);
On 9/18/2025 10:16 AM, Chao Yu wrote: > On 9/17/25 16:13, Liao Yuanhong wrote: >> On 9/17/2025 3:57 PM, Chao Yu wrote: >>> On 9/17/25 15:08, Liao Yuanhong wrote: >>>> On 9/15/2025 4:36 PM, Chao Yu wrote: >>>>> On 9/9/25 21:44, Liao Yuanhong wrote: >>>>>> When the proportion of dirty segments within a section exceeds the >>>>>> valid_thresh_ratio, the gc_cost of that section is set to UINT_MAX, >>>>>> indicating that these sections should not be released. However, if all >>>>>> section costs within the scanning range of get_victim() are UINT_MAX, >>>>>> background GC will still occur. Add a condition to prevent this situation. >>>>> For this case, f2fs_get_victim() will return 0, and f2fs_gc() will use unchanged >>>>> segno for GC? >>>>> >>>>> Thanks, >>>> You're right, segno won't update in this scenario, and this patch feature is redundant. >>> Oh, I meant, if f2fs_get_victim() fails to select a valid victim due to the reason you >>> described, f2fs_get_victim() will return 0, and f2fs_gc() will migrate segment #NULL_SEGNO? >>> Or am I missing something? >>> >>> Thanks, >> Yes. In this scenario, since it won't enter the|p.min_cost > cost|condition,|p.min_segno|will retain its initial value|||NULL_SEGNO|. This is consistent with what you described. > Do you have a script to reproduce this bug? > > Thanks, I didn't explain it clearly. What I mean is that this patch is redundant, the original code is fine. Thanks, Liao >> >> Thanks, >> >> Liao >> >>>> Thanks, >>>> >>>> Liao >>>> >>>>>> Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com> >>>>>> --- >>>>>> fs/f2fs/gc.c | 5 +++++ >>>>>> 1 file changed, 5 insertions(+) >>>>>> >>>>>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c >>>>>> index 4a8c08f970e3..ffc3188416f4 100644 >>>>>> --- a/fs/f2fs/gc.c >>>>>> +++ b/fs/f2fs/gc.c >>>>>> @@ -936,6 +936,11 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result, >>>>>> } >>>>>> } >>>>>> + if (f2fs_sb_has_blkzoned(sbi) && p.min_cost == UINT_MAX) { >>>>>> + ret = -ENODATA; >>>>>> + goto out; >>>>>> + } >>>>>> + >>>>>> /* get victim for GC_AT/AT_SSR */ >>>>>> if (is_atgc) { >>>>>> lookup_victim_by_age(sbi, &p);
On 9/20/25 10:49, Liao Yuanhong wrote: > > On 9/18/2025 10:16 AM, Chao Yu wrote: >> On 9/17/25 16:13, Liao Yuanhong wrote: >>> On 9/17/2025 3:57 PM, Chao Yu wrote: >>>> On 9/17/25 15:08, Liao Yuanhong wrote: >>>>> On 9/15/2025 4:36 PM, Chao Yu wrote: >>>>>> On 9/9/25 21:44, Liao Yuanhong wrote: >>>>>>> When the proportion of dirty segments within a section exceeds the >>>>>>> valid_thresh_ratio, the gc_cost of that section is set to UINT_MAX, >>>>>>> indicating that these sections should not be released. However, if all >>>>>>> section costs within the scanning range of get_victim() are UINT_MAX, >>>>>>> background GC will still occur. Add a condition to prevent this situation. >>>>>> For this case, f2fs_get_victim() will return 0, and f2fs_gc() will use unchanged >>>>>> segno for GC? >>>>>> >>>>>> Thanks, >>>>> You're right, segno won't update in this scenario, and this patch feature is redundant. >>>> Oh, I meant, if f2fs_get_victim() fails to select a valid victim due to the reason you >>>> described, f2fs_get_victim() will return 0, and f2fs_gc() will migrate segment #NULL_SEGNO? >>>> Or am I missing something? >>>> >>>> Thanks, >>> Yes. In this scenario, since it won't enter the|p.min_cost > cost|condition,|p.min_segno|will retain its initial value|||NULL_SEGNO|. This is consistent with what you described. >> Do you have a script to reproduce this bug? >> >> Thanks, > > I didn't explain it clearly. What I mean is that this patch is redundant, the original code is fine. Oh, I see. I don't see any problem in f2fs_get_victim() as well. Thanks, > > > Thanks, > > Liao > >>> >>> Thanks, >>> >>> Liao >>> >>>>> Thanks, >>>>> >>>>> Liao >>>>> >>>>>>> Signed-off-by: Liao Yuanhong <liaoyuanhong@vivo.com> >>>>>>> --- >>>>>>> fs/f2fs/gc.c | 5 +++++ >>>>>>> 1 file changed, 5 insertions(+) >>>>>>> >>>>>>> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c >>>>>>> index 4a8c08f970e3..ffc3188416f4 100644 >>>>>>> --- a/fs/f2fs/gc.c >>>>>>> +++ b/fs/f2fs/gc.c >>>>>>> @@ -936,6 +936,11 @@ int f2fs_get_victim(struct f2fs_sb_info *sbi, unsigned int *result, >>>>>>> } >>>>>>> } >>>>>>> + if (f2fs_sb_has_blkzoned(sbi) && p.min_cost == UINT_MAX) { >>>>>>> + ret = -ENODATA; >>>>>>> + goto out; >>>>>>> + } >>>>>>> + >>>>>>> /* get victim for GC_AT/AT_SSR */ >>>>>>> if (is_atgc) { >>>>>>> lookup_victim_by_age(sbi, &p);
© 2016 - 2025 Red Hat, Inc.