bcachefs: Fix gc handling of bucket gens
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 20 Feb 2019 22:57:06 +0000 (17:57 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:16 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_gc.c
fs/bcachefs/buckets.h

index 56402fc64bc22f881ac5563c34df2a1d311d9373..c899a77bf89192646ba1f6487873aa89d13946a7 100644 (file)
@@ -142,22 +142,23 @@ static int bch2_gc_mark_key(struct bch_fs *c, struct bkey_s_c k,
                bkey_for_each_ptr(ptrs, ptr) {
                        struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
                        struct bucket *g = PTR_BUCKET(ca, ptr, true);
+                       struct bucket *g2 = PTR_BUCKET(ca, ptr, false);
 
                        if (mustfix_fsck_err_on(!g->gen_valid, c,
                                        "found ptr with missing gen in alloc btree,\n"
                                        "type %u gen %u",
                                        k.k->type, ptr->gen)) {
-                               g->_mark.gen    = ptr->gen;
-                               g->_mark.dirty  = true;
-                               g->gen_valid    = 1;
+                               g2->_mark.gen   = g->_mark.gen          = ptr->gen;
+                               g2->_mark.dirty = g->_mark.dirty        = true;
+                               g2->gen_valid   = g->gen_valid          = true;
                        }
 
                        if (mustfix_fsck_err_on(gen_cmp(ptr->gen, g->mark.gen) > 0, c,
                                        "%u ptr gen in the future: %u > %u",
                                        k.k->type, ptr->gen, g->mark.gen)) {
-                               g->_mark.gen    = ptr->gen;
-                               g->_mark.dirty  = true;
-                               g->gen_valid    = 1;
+                               g2->_mark.gen   = g->_mark.gen          = ptr->gen;
+                               g2->_mark.dirty = g->_mark.dirty        = true;
+                               g2->gen_valid   = g->gen_valid          = true;
                                set_bit(BCH_FS_FIXED_GENS, &c->flags);
                        }
                }
@@ -692,10 +693,12 @@ static int bch2_gc_start(struct bch_fs *c)
                dst->first_bucket       = src->first_bucket;
                dst->nbuckets           = src->nbuckets;
 
-               for (b = 0; b < src->nbuckets; b++)
+               for (b = 0; b < src->nbuckets; b++) {
                        dst->b[b]._mark.gen =
                                dst->b[b].oldest_gen =
                                src->b[b].mark.gen;
+                       dst->b[b].gen_valid = src->b[b].gen_valid;
+               }
        };
 
        percpu_up_write(&c->mark_lock);
@@ -754,6 +757,8 @@ out:
                if (iter++ <= 2) {
                        bch_info(c, "Fixed gens, restarting mark and sweep:");
                        clear_bit(BCH_FS_FIXED_GENS, &c->flags);
+                       __gc_pos_set(c, gc_phase(GC_PHASE_NOT_RUNNING));
+                       bch2_gc_free(c);
                        goto again;
                }
 
index 5f0b5a6ec9ad5dfb16a29edc40ad23dfca6b1670..342def8cf60366a143b6a477766d4c8f8ec3c417 100644 (file)
@@ -91,7 +91,7 @@ static inline struct bucket *PTR_BUCKET(struct bch_dev *ca,
                                        const struct bch_extent_ptr *ptr,
                                        bool gc)
 {
-       return bucket(ca, PTR_BUCKET_NR(ca, ptr));
+       return __bucket(ca, PTR_BUCKET_NR(ca, ptr), gc);
 }
 
 static inline struct bucket_mark ptr_bucket_mark(struct bch_dev *ca,