summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-10-04 19:14:43 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2019-10-04 19:14:43 -0400
commite854c9bdca8232e8d875c28fdbf846b9fbc78c1a (patch)
treee0006ab078f2075f7ee8622f643c84c7fcfadeff
parentdea1ffabc84c6db75d20d5f8c2d5702913500403 (diff)
bcachefs: Don't allocate memory under mark_lock
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--fs/bcachefs/btree_gc.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
index f4adb07a3de2..ea0c9b2331e3 100644
--- a/fs/bcachefs/btree_gc.c
+++ b/fs/bcachefs/btree_gc.c
@@ -640,12 +640,7 @@ static int bch2_gc_start(struct bch_fs *c,
{
struct bch_dev *ca;
unsigned i;
-
- /*
- * indicate to stripe code that we need to allocate for the gc stripes
- * radix tree, too
- */
- gc_pos_set(c, gc_phase(GC_PHASE_START));
+ int ret;
BUG_ON(c->usage_gc);
@@ -673,6 +668,18 @@ static int bch2_gc_start(struct bch_fs *c,
}
}
+ ret = bch2_ec_mem_alloc(c, true);
+ if (ret)
+ return ret;
+
+ percpu_down_write(&c->mark_lock);
+
+ /*
+ * indicate to stripe code that we need to allocate for the gc stripes
+ * radix tree, too
+ */
+ gc_pos_set(c, gc_phase(GC_PHASE_START));
+
for_each_member_device(ca, c, i) {
struct bucket_array *dst = __bucket_array(ca, 1);
struct bucket_array *src = __bucket_array(ca, 0);
@@ -697,7 +704,9 @@ static int bch2_gc_start(struct bch_fs *c,
}
};
- return bch2_ec_mem_alloc(c, true);
+ percpu_up_write(&c->mark_lock);
+
+ return 0;
}
/**
@@ -730,10 +739,7 @@ int bch2_gc(struct bch_fs *c, struct journal_keys *journal_keys,
down_write(&c->gc_lock);
again:
- percpu_down_write(&c->mark_lock);
ret = bch2_gc_start(c, metadata_only);
- percpu_up_write(&c->mark_lock);
-
if (ret)
goto out;