bcachefs: don't do initial gc if have alloc info feature
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 6 Feb 2019 16:56:51 +0000 (11:56 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:15 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs.h
fs/bcachefs/bcachefs_format.h
fs/bcachefs/btree_gc.c
fs/bcachefs/recovery.c
fs/bcachefs/super-io.c

index 90c44ef0fbe056d95f82a84fa3fc41a64f0f18b5..81597383dc200069bd16b0f66f1a72e5617c7fc5 100644 (file)
@@ -568,6 +568,7 @@ struct bch_fs {
                u32             time_base_hi;
                u32             time_precision;
                u64             features;
+               u64             compat;
        }                       sb;
 
        struct bch_sb_handle    disk_sb;
index 71ba708c3e2bda394f09f207c84c43740738059d..a663f9d3fb5150214f95fbae414f2da960d49fcb 100644 (file)
@@ -1279,6 +1279,10 @@ enum bch_sb_features {
        BCH_FEATURE_NR,
 };
 
+enum bch_sb_compat {
+       BCH_COMPAT_FEAT_ALLOC_INFO      = 0,
+};
+
 /* options: */
 
 #define BCH_REPLICAS_MAX               4U
index ac3fa1efb6499834c56b1ee642531074f6702d60..899bdfa4d6d33fe1434c28837a919face4d9eaa8 100644 (file)
@@ -577,7 +577,8 @@ static void bch2_gc_done(struct bch_fs *c, bool initial)
 
        percpu_down_write(&c->mark_lock);
 
-       if (initial) {
+       if (initial &&
+           !(c->sb.compat & (1ULL << BCH_COMPAT_FEAT_ALLOC_INFO))) {
                bch2_gc_done_nocheck(c);
                goto out;
        }
@@ -819,9 +820,6 @@ out:
        bch2_gc_free(c);
        up_write(&c->gc_lock);
 
-       if (!ret && initial)
-               set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags);
-
        trace_gc_end(c);
        bch2_time_stats_update(&c->times[BCH_TIME_btree_gc], start_time);
 
index 31d2bce7bb57fbc70ef67875e05bcdc4a8cdcb7c..1c09ae4f5f2fbb54271752ca4febed0ec9f3d90c 100644 (file)
@@ -300,14 +300,18 @@ int bch2_fs_recovery(struct bch_fs *c)
 
        set_bit(BCH_FS_ALLOC_READ_DONE, &c->flags);
 
-       bch_verbose(c, "starting mark and sweep:");
-       err = "error in recovery";
-       ret = bch2_gc(c, &journal, true);
-       if (ret)
-               goto err;
-       bch_verbose(c, "mark and sweep done");
+       if (!(c->sb.compat & (1ULL << BCH_COMPAT_FEAT_ALLOC_INFO)) ||
+           c->opts.fsck) {
+               bch_verbose(c, "starting mark and sweep:");
+               err = "error in recovery";
+               ret = bch2_gc(c, &journal, true);
+               if (ret)
+                       goto err;
+               bch_verbose(c, "mark and sweep done");
+       }
 
        clear_bit(BCH_FS_REBUILD_REPLICAS, &c->flags);
+       set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags);
 
        /*
         * Skip past versions that might have possibly been used (as nonces),
@@ -411,6 +415,8 @@ int bch2_fs_initialize(struct bch_fs *c)
        if (ret)
                goto err;
 
+       set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags);
+
        err = "unable to allocate journal buckets";
        for_each_online_member(ca, c, i)
                if (bch2_dev_journal_alloc(ca)) {
index 0cc8565b070f42ed129433980573d40d958aaf12..ff9728b62b6eb56da7b98fb4f2685ce399b82d11 100644 (file)
@@ -371,6 +371,7 @@ static void bch2_sb_update(struct bch_fs *c)
        c->sb.time_base_hi      = le32_to_cpu(src->time_base_hi);
        c->sb.time_precision    = le32_to_cpu(src->time_precision);
        c->sb.features          = le64_to_cpu(src->features[0]);
+       c->sb.compat            = le64_to_cpu(src->compat[0]);
 
        for_each_member_device(ca, c, i)
                ca->mi = bch2_mi_to_cpu(mi->members + i);
@@ -888,8 +889,10 @@ void bch2_sb_clean_renumber(struct bch_sb_field_clean *clean, int write)
 static void bch2_fs_mark_dirty(struct bch_fs *c)
 {
        mutex_lock(&c->sb_lock);
-       if (BCH_SB_CLEAN(c->disk_sb.sb)) {
+       if (BCH_SB_CLEAN(c->disk_sb.sb) ||
+           (c->disk_sb.sb->compat[0] & (1ULL << BCH_COMPAT_FEAT_ALLOC_INFO))) {
                SET_BCH_SB_CLEAN(c->disk_sb.sb, false);
+               c->disk_sb.sb->compat[0] &= ~(1ULL << BCH_COMPAT_FEAT_ALLOC_INFO);
                bch2_write_super(c);
        }
        mutex_unlock(&c->sb_lock);
@@ -1011,6 +1014,8 @@ void bch2_fs_mark_clean(struct bch_fs *c, bool clean)
 
        SET_BCH_SB_CLEAN(c->disk_sb.sb, true);
 
+       c->disk_sb.sb->compat[0] |= 1ULL << BCH_COMPAT_FEAT_ALLOC_INFO;
+
        u64s = sizeof(*sb_clean) / sizeof(u64) + c->journal.entry_u64s_reserved;
 
        sb_clean = bch2_sb_resize_clean(&c->disk_sb, u64s);