diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2022-05-06 13:34:41 -0700 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2022-05-17 11:19:19 -0700 |
commit | c81d5bae404abc6b257667e84d39b9b50c7063d4 (patch) | |
tree | 0ed9ab5c91bb5178f0d5cd06bd6347806323a912 /fs/f2fs/gc.c | |
parent | c58d7c55de8bf7afd25d13d6eb8ef68782a51be9 (diff) |
f2fs: do not stop GC when requiring a free section
The f2fs_gc uses a bitmap to indicate pinned sections, but when disabling
chckpoint, we call f2fs_gc() with NULL_SEGNO which selects the same dirty
segment as a victim all the time, resulting in checkpoint=disable failure,
for example. Let's pick another one, if we fail to collect it.
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/gc.c')
-rw-r--r-- | fs/f2fs/gc.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index e275b72bc65f..d5fb426e0747 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -147,6 +147,7 @@ do_gc: gc_control.init_gc_type = sync_mode ? FG_GC : BG_GC; gc_control.no_bg_gc = foreground; + gc_control.nr_free_secs = foreground ? 1 : 0; /* if return value is not zero, no victim was selected */ if (f2fs_gc(sbi, &gc_control)) @@ -1761,6 +1762,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control) unsigned int skipped_round = 0, round = 0; trace_f2fs_gc_begin(sbi->sb, gc_type, gc_control->no_bg_gc, + gc_control->nr_free_secs, get_pages(sbi, F2FS_DIRTY_NODES), get_pages(sbi, F2FS_DIRTY_DENTS), get_pages(sbi, F2FS_DIRTY_IMETA), @@ -1823,12 +1825,13 @@ retry: if (gc_type == FG_GC) sbi->cur_victim_sec = NULL_SEGNO; - if (gc_control->init_gc_type == FG_GC) - goto stop; - - if (!has_not_enough_free_secs(sbi, - (gc_type == FG_GC) ? sec_freed : 0, 0)) + if (gc_control->init_gc_type == FG_GC || + !has_not_enough_free_secs(sbi, + (gc_type == FG_GC) ? sec_freed : 0, 0)) { + if (gc_type == FG_GC && sec_freed < gc_control->nr_free_secs) + goto go_gc_more; goto stop; + } /* FG_GC stops GC by skip_count */ if (gc_type == FG_GC) { @@ -1849,6 +1852,7 @@ retry: if (ret) goto stop; } +go_gc_more: segno = NULL_SEGNO; goto gc_more; |