Commit 28062d32 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix gc handling of bucket gens

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 86a225c4
...@@ -142,22 +142,23 @@ static int bch2_gc_mark_key(struct bch_fs *c, struct bkey_s_c k, ...@@ -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) { bkey_for_each_ptr(ptrs, ptr) {
struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev);
struct bucket *g = PTR_BUCKET(ca, ptr, true); 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, if (mustfix_fsck_err_on(!g->gen_valid, c,
"found ptr with missing gen in alloc btree,\n" "found ptr with missing gen in alloc btree,\n"
"type %u gen %u", "type %u gen %u",
k.k->type, ptr->gen)) { k.k->type, ptr->gen)) {
g->_mark.gen = ptr->gen; g2->_mark.gen = g->_mark.gen = ptr->gen;
g->_mark.dirty = true; g2->_mark.dirty = g->_mark.dirty = true;
g->gen_valid = 1; g2->gen_valid = g->gen_valid = true;
} }
if (mustfix_fsck_err_on(gen_cmp(ptr->gen, g->mark.gen) > 0, c, if (mustfix_fsck_err_on(gen_cmp(ptr->gen, g->mark.gen) > 0, c,
"%u ptr gen in the future: %u > %u", "%u ptr gen in the future: %u > %u",
k.k->type, ptr->gen, g->mark.gen)) { k.k->type, ptr->gen, g->mark.gen)) {
g->_mark.gen = ptr->gen; g2->_mark.gen = g->_mark.gen = ptr->gen;
g->_mark.dirty = true; g2->_mark.dirty = g->_mark.dirty = true;
g->gen_valid = 1; g2->gen_valid = g->gen_valid = true;
set_bit(BCH_FS_FIXED_GENS, &c->flags); set_bit(BCH_FS_FIXED_GENS, &c->flags);
} }
} }
...@@ -692,10 +693,12 @@ static int bch2_gc_start(struct bch_fs *c) ...@@ -692,10 +693,12 @@ static int bch2_gc_start(struct bch_fs *c)
dst->first_bucket = src->first_bucket; dst->first_bucket = src->first_bucket;
dst->nbuckets = src->nbuckets; 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]._mark.gen =
dst->b[b].oldest_gen = dst->b[b].oldest_gen =
src->b[b].mark.gen; src->b[b].mark.gen;
dst->b[b].gen_valid = src->b[b].gen_valid;
}
}; };
percpu_up_write(&c->mark_lock); percpu_up_write(&c->mark_lock);
...@@ -754,6 +757,8 @@ int bch2_gc(struct bch_fs *c, struct list_head *journal, bool initial) ...@@ -754,6 +757,8 @@ int bch2_gc(struct bch_fs *c, struct list_head *journal, bool initial)
if (iter++ <= 2) { if (iter++ <= 2) {
bch_info(c, "Fixed gens, restarting mark and sweep:"); bch_info(c, "Fixed gens, restarting mark and sweep:");
clear_bit(BCH_FS_FIXED_GENS, &c->flags); clear_bit(BCH_FS_FIXED_GENS, &c->flags);
__gc_pos_set(c, gc_phase(GC_PHASE_NOT_RUNNING));
bch2_gc_free(c);
goto again; goto again;
} }
......
...@@ -91,7 +91,7 @@ static inline struct bucket *PTR_BUCKET(struct bch_dev *ca, ...@@ -91,7 +91,7 @@ static inline struct bucket *PTR_BUCKET(struct bch_dev *ca,
const struct bch_extent_ptr *ptr, const struct bch_extent_ptr *ptr,
bool gc) 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, static inline struct bucket_mark ptr_bucket_mark(struct bch_dev *ca,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment