diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-02-20 17:57:06 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:16 -0400 |
commit | 28062d320bded23eb7d24633e6ab11ea3c03487b (patch) | |
tree | f09019b5cdb92d6572289de96a62a4326d58218b /fs/bcachefs | |
parent | 86a225c42d44ba966504801c6d953745184ea9cf (diff) | |
download | lwn-28062d320bded23eb7d24633e6ab11ea3c03487b.tar.gz lwn-28062d320bded23eb7d24633e6ab11ea3c03487b.zip |
bcachefs: Fix gc handling of bucket gens
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs')
-rw-r--r-- | fs/bcachefs/btree_gc.c | 19 | ||||
-rw-r--r-- | fs/bcachefs/buckets.h | 2 |
2 files changed, 13 insertions, 8 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index 56402fc64bc2..c899a77bf891 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -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; } diff --git a/fs/bcachefs/buckets.h b/fs/bcachefs/buckets.h index 5f0b5a6ec9ad..342def8cf603 100644 --- a/fs/bcachefs/buckets.h +++ b/fs/bcachefs/buckets.h @@ -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, |