]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/f2fs/gc.c
Merge tag 'rpmsg-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson...
[linux.git] / fs / f2fs / gc.c
index 8974672db78f39ef929f2bb61230054ae38471e4..5877bd72968966b9b0ec5ecea2c101397698a1f0 100644 (file)
@@ -382,6 +382,16 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
                        nsearched++;
                }
 
+#ifdef CONFIG_F2FS_CHECK_FS
+               /*
+                * skip selecting the invalid segno (that is failed due to block
+                * validity check failure during GC) to avoid endless GC loop in
+                * such cases.
+                */
+               if (test_bit(segno, sm->invalid_segmap))
+                       goto next;
+#endif
+
                secno = GET_SEC_FROM_SEG(sbi, segno);
 
                if (sec_usage_check(sbi, secno))
@@ -627,8 +637,21 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
        source_blkaddr = datablock_addr(NULL, node_page, ofs_in_node);
        f2fs_put_page(node_page, 1);
 
-       if (source_blkaddr != blkaddr)
+       if (source_blkaddr != blkaddr) {
+#ifdef CONFIG_F2FS_CHECK_FS
+               unsigned int segno = GET_SEGNO(sbi, blkaddr);
+               unsigned long offset = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
+
+               if (unlikely(check_valid_map(sbi, segno, offset))) {
+                       if (!test_and_set_bit(segno, SIT_I(sbi)->invalid_segmap)) {
+                               f2fs_err(sbi, "mismatched blkaddr %u (source_blkaddr %u) in seg %u\n",
+                                               blkaddr, source_blkaddr, segno);
+                               f2fs_bug_on(sbi, 1);
+                       }
+               }
+#endif
                return false;
+       }
        return true;
 }
 
@@ -1303,7 +1326,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, bool sync,
                round++;
        }
 
-       if (gc_type == FG_GC)
+       if (gc_type == FG_GC && seg_freed)
                sbi->cur_victim_sec = NULL_SEGNO;
 
        if (sync)