f2fs: write checkpoint during FG_GC
authorByungki Lee <dominicus79@gmail.com>
Fri, 29 Apr 2022 20:29:53 +0000 (13:29 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Fri, 6 May 2022 17:18:12 +0000 (10:18 -0700)
If there's not enough free sections each of which consistis of large segments,
we can hit no free section for upcoming section allocation. Let's reclaim some
prefree segments by writing checkpoints.

Signed-off-by: Byungki Lee <dominicus79@gmail.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/gc.c

index 6a7e414..a193862 100644 (file)
@@ -1790,23 +1790,31 @@ gc_more:
        if (sync)
                goto stop;
 
-       if (has_not_enough_free_secs(sbi, sec_freed, 0)) {
-               if (skipped_round <= MAX_SKIP_GC_COUNT ||
-                                       skipped_round * 2 < round) {
-                       segno = NULL_SEGNO;
-                       goto gc_more;
-               }
+       if (!has_not_enough_free_secs(sbi, sec_freed, 0))
+               goto stop;
 
-               if (first_skipped < last_skipped &&
-                               (last_skipped - first_skipped) >
-                                               sbi->skipped_gc_rwsem) {
-                       f2fs_drop_inmem_pages_all(sbi, true);
-                       segno = NULL_SEGNO;
-                       goto gc_more;
-               }
-               if (gc_type == FG_GC && !is_sbi_flag_set(sbi, SBI_CP_DISABLED))
+       if (skipped_round <= MAX_SKIP_GC_COUNT || skipped_round * 2 < round) {
+
+               /* Write checkpoint to reclaim prefree segments */
+               if (free_sections(sbi) < NR_CURSEG_PERSIST_TYPE &&
+                               prefree_segments(sbi) &&
+                               !is_sbi_flag_set(sbi, SBI_CP_DISABLED)) {
                        ret = f2fs_write_checkpoint(sbi, &cpc);
-       }
+                       if (ret)
+                               goto stop;
+               }
+               segno = NULL_SEGNO;
+               goto gc_more;
+       }
+       if (first_skipped < last_skipped &&
+                       (last_skipped - first_skipped) >
+                                       sbi->skipped_gc_rwsem) {
+               f2fs_drop_inmem_pages_all(sbi, true);
+               segno = NULL_SEGNO;
+               goto gc_more;
+       }
+       if (gc_type == FG_GC && !is_sbi_flag_set(sbi, SBI_CP_DISABLED))
+               ret = f2fs_write_checkpoint(sbi, &cpc);
 stop:
        SIT_I(sbi)->last_victim[ALLOC_NEXT] = 0;
        SIT_I(sbi)->last_victim[FLUSH_DEVICE] = init_segno;