summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-01-14 16:19:23 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2021-01-15 14:22:46 -0500
commitbb2281735c5992c8da66a4da552eeab1d376b6df (patch)
treee6470fc70ce45d0ff06bd815afb1a3a5c32d5ee8
parent93347f716249d5b2503bb7504fe9faac2bcd8d36 (diff)
bcachefs: Factor out bch2_ec_stripes_heap_start()
This fixes a bug where mark and sweep gc incorrectly was clearing out the stripes heap and causing assertions to fire later - simpler to just create the stripes heap after gc has finished. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/btree_gc.c8
-rw-r--r--fs/bcachefs/ec.c17
-rw-r--r--fs/bcachefs/ec.h2
-rw-r--r--fs/bcachefs/recovery.c2
4 files changed, 14 insertions, 15 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
index 6b06f6079908..d0635a08d68f 100644
--- a/fs/bcachefs/btree_gc.c
+++ b/fs/bcachefs/btree_gc.c
@@ -607,8 +607,6 @@ static int bch2_gc_done(struct bch_fs *c,
struct genradix_iter src_iter = genradix_iter_init(&c->stripes[1], 0);
struct stripe *dst, *src;
- c->ec_stripes_heap.used = 0;
-
while ((dst = genradix_iter_peek(&dst_iter, &c->stripes[0])) &&
(src = genradix_iter_peek(&src_iter, &c->stripes[1]))) {
BUG_ON(src_iter.pos != dst_iter.pos);
@@ -625,12 +623,6 @@ static int bch2_gc_done(struct bch_fs *c,
copy_stripe_field(block_sectors[i],
"block_sectors[%u]", i);
- if (dst->alive) {
- spin_lock(&c->ec_stripes_heap_lock);
- bch2_stripes_heap_insert(c, dst, dst_iter.pos);
- spin_unlock(&c->ec_stripes_heap_lock);
- }
-
genradix_iter_advance(&dst_iter, &c->stripes[0]);
genradix_iter_advance(&src_iter, &c->stripes[1]);
}
diff --git a/fs/bcachefs/ec.c b/fs/bcachefs/ec.c
index a33be9f609ac..75f39e995c52 100644
--- a/fs/bcachefs/ec.c
+++ b/fs/bcachefs/ec.c
@@ -1450,6 +1450,16 @@ unlock:
mutex_unlock(&c->ec_stripe_head_lock);
}
+void bch2_stripes_heap_start(struct bch_fs *c)
+{
+ struct genradix_iter iter;
+ struct stripe *m;
+
+ genradix_for_each(&c->stripes[0], iter, m)
+ if (m->alive)
+ bch2_stripes_heap_insert(c, m, iter.pos);
+}
+
static int __bch2_stripe_write_key(struct btree_trans *trans,
struct btree_iter *iter,
struct stripe *m,
@@ -1529,18 +1539,11 @@ static int bch2_stripes_read_fn(struct bch_fs *c, enum btree_id id,
int ret = 0;
if (k.k->type == KEY_TYPE_stripe) {
- struct stripe *m;
-
ret = __ec_stripe_mem_alloc(c, k.k->p.offset, GFP_KERNEL) ?:
bch2_mark_key(c, k, 0, 0, NULL, 0,
BTREE_TRIGGER_NOATOMIC);
if (ret)
return ret;
-
- spin_lock(&c->ec_stripes_heap_lock);
- m = genradix_ptr(&c->stripes[0], k.k->p.offset);
- bch2_stripes_heap_insert(c, m, k.k->p.offset);
- spin_unlock(&c->ec_stripes_heap_lock);
}
return ret;
diff --git a/fs/bcachefs/ec.h b/fs/bcachefs/ec.h
index c3959af46833..f124582fdc5f 100644
--- a/fs/bcachefs/ec.h
+++ b/fs/bcachefs/ec.h
@@ -200,6 +200,8 @@ void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *);
void bch2_ec_flush_new_stripes(struct bch_fs *);
+void bch2_stripes_heap_start(struct bch_fs *);
+
struct journal_keys;
int bch2_stripes_read(struct bch_fs *, struct journal_keys *);
int bch2_stripes_write(struct bch_fs *, unsigned);
diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c
index c700b12b2ac0..8c67f1468945 100644
--- a/fs/bcachefs/recovery.c
+++ b/fs/bcachefs/recovery.c
@@ -1125,6 +1125,8 @@ use_clean:
bch_verbose(c, "mark and sweep done");
}
+ bch2_stripes_heap_start(c);
+
clear_bit(BCH_FS_REBUILD_REPLICAS, &c->flags);
set_bit(BCH_FS_INITIAL_GC_DONE, &c->flags);