summaryrefslogtreecommitdiff
path: root/fs/bcachefs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-02-20 17:57:06 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:08:16 -0400
commit28062d320bded23eb7d24633e6ab11ea3c03487b (patch)
treef09019b5cdb92d6572289de96a62a4326d58218b /fs/bcachefs
parent86a225c42d44ba966504801c6d953745184ea9cf (diff)
downloadlwn-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.c19
-rw-r--r--fs/bcachefs/buckets.h2
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,