There was a bug that finishing FG GC unconditionally because free sections
are over-estimated after checkpoint in FG GC.
This patch initializes sec_freed by every checkpoint in FG GC.

Signed-off-by: Yonggil Song <[email protected]>
---
 fs/f2fs/gc.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index d455140322a8..51d7e8d29bf1 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1797,7 +1797,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct 
f2fs_gc_control *gc_control)
 {
        int gc_type = gc_control->init_gc_type;
        unsigned int segno = gc_control->victim_segno;
-       int sec_freed = 0, seg_freed = 0, total_freed = 0;
+       int sec_freed = 0, seg_freed = 0, total_freed = 0, total_sec_freed = 0;
        int ret = 0;
        struct cp_control cpc;
        struct gc_inode_list gc_list = {
@@ -1842,6 +1842,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct 
f2fs_gc_control *gc_control)
                        ret = f2fs_write_checkpoint(sbi, &cpc);
                        if (ret)
                                goto stop;
+                       /* Reset due to checkpoint */
+                       sec_freed = 0;
                }
        }
 
@@ -1866,15 +1868,17 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct 
f2fs_gc_control *gc_control)
                                gc_control->should_migrate_blocks);
        total_freed += seg_freed;
 
-       if (seg_freed == f2fs_usable_segs_in_sec(sbi, segno))
+       if (seg_freed == f2fs_usable_segs_in_sec(sbi, segno)) {
                sec_freed++;
+               total_sec_freed++;
+       }
 
        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 &&
-                           sec_freed < gc_control->nr_free_secs)
+                           total_sec_freed < gc_control->nr_free_secs)
                                goto go_gc_more;
                        goto stop;
                }
@@ -1901,6 +1905,8 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct 
f2fs_gc_control *gc_control)
                ret = f2fs_write_checkpoint(sbi, &cpc);
                if (ret)
                        goto stop;
+               /* Reset due to checkpoint */
+               sec_freed = 0;
        }
 go_gc_more:
        segno = NULL_SEGNO;
@@ -1913,7 +1919,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct 
f2fs_gc_control *gc_control)
        if (gc_type == FG_GC)
                f2fs_unpin_all_sections(sbi, true);
 
-       trace_f2fs_gc_end(sbi->sb, ret, total_freed, sec_freed,
+       trace_f2fs_gc_end(sbi->sb, ret, total_freed, total_sec_freed,
                                get_pages(sbi, F2FS_DIRTY_NODES),
                                get_pages(sbi, F2FS_DIRTY_DENTS),
                                get_pages(sbi, F2FS_DIRTY_IMETA),
@@ -1927,7 +1933,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct 
f2fs_gc_control *gc_control)
        put_gc_inode(&gc_list);
 
        if (gc_control->err_gc_skipped && !ret)
-               ret = sec_freed ? 0 : -EAGAIN;
+               ret = total_sec_freed ? 0 : -EAGAIN;
        return ret;
 }
 
-- 
2.34.1


_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to