summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/bcache/btree_cache.c10
-rw-r--r--drivers/md/bcache/btree_cache.h3
-rw-r--r--drivers/md/bcache/btree_gc.c4
-rw-r--r--drivers/md/bcache/btree_iter.c16
-rw-r--r--drivers/md/bcache/btree_iter.h2
-rw-r--r--drivers/md/bcache/btree_update.c29
-rw-r--r--drivers/md/bcache/btree_update.h9
-rw-r--r--drivers/md/bcache/journal.c6
-rw-r--r--drivers/md/bcache/migrate.c6
9 files changed, 51 insertions, 34 deletions
diff --git a/drivers/md/bcache/btree_cache.c b/drivers/md/bcache/btree_cache.c
index 5a5674af3964..c9584f8d9e2c 100644
--- a/drivers/md/bcache/btree_cache.c
+++ b/drivers/md/bcache/btree_cache.c
@@ -571,12 +571,13 @@ err:
/* Slowpath, don't want it inlined into btree_iter_traverse() */
static noinline struct btree *bch_btree_node_fill(struct btree_iter *iter,
const struct bkey_i *k,
- int level)
+ int level,
+ struct closure *cl)
{
struct cache_set *c = iter->c;
struct btree *b;
- b = mca_alloc(c, &iter->cl);
+ b = mca_alloc(c, cl);
if (IS_ERR(b))
return b;
@@ -633,7 +634,8 @@ static noinline struct btree *bch_btree_node_fill(struct btree_iter *iter,
* the @write parameter.
*/
struct btree *bch_btree_node_get(struct btree_iter *iter,
- const struct bkey_i *k, int level)
+ const struct bkey_i *k, int level,
+ struct closure *cl)
{
int i = 0;
struct btree *b;
@@ -645,7 +647,7 @@ retry:
rcu_read_unlock();
if (unlikely(!b)) {
- b = bch_btree_node_fill(iter, k, level);
+ b = bch_btree_node_fill(iter, k, level, cl);
/* We raced and found the btree node in the cache */
if (!b)
diff --git a/drivers/md/bcache/btree_cache.h b/drivers/md/bcache/btree_cache.h
index e774ddf30e02..e185df336778 100644
--- a/drivers/md/bcache/btree_cache.h
+++ b/drivers/md/bcache/btree_cache.h
@@ -20,7 +20,8 @@ int mca_cannibalize_lock(struct cache_set *, struct closure *);
struct btree *mca_alloc(struct cache_set *, struct closure *);
struct btree *bch_btree_node_get(struct btree_iter *,
- const struct bkey_i *, int);
+ const struct bkey_i *, int,
+ struct closure *);
void bch_btree_cache_free(struct cache_set *);
int bch_btree_cache_alloc(struct cache_set *);
diff --git a/drivers/md/bcache/btree_gc.c b/drivers/md/bcache/btree_gc.c
index cd1c5c2aac20..b353cff5e0b0 100644
--- a/drivers/md/bcache/btree_gc.c
+++ b/drivers/md/bcache/btree_gc.c
@@ -201,7 +201,7 @@ static int bch_gc_btree(struct cache_set *c, enum btree_id btree_id)
gc_pos_set(c, gc_pos_btree_node(b));
if (should_rewrite)
- bch_btree_node_rewrite(b, &iter, false);
+ bch_btree_node_rewrite(&iter, b, NULL);
bch_btree_iter_cond_resched(&iter);
}
@@ -480,7 +480,7 @@ static void bch_coalesce_nodes(struct btree *old_nodes[GC_MERGE_NODES],
block_bytes(c)) > blocks)
return;
- res = bch_btree_reserve_get(c, parent, NULL, nr_old_nodes, false);
+ res = bch_btree_reserve_get(iter, parent, nr_old_nodes, false, NULL);
if (IS_ERR(res))
return;
diff --git a/drivers/md/bcache/btree_iter.c b/drivers/md/bcache/btree_iter.c
index a473d602d2df..96f696783f60 100644
--- a/drivers/md/bcache/btree_iter.c
+++ b/drivers/md/bcache/btree_iter.c
@@ -131,8 +131,6 @@ int bch_btree_iter_unlock(struct btree_iter *iter)
while (iter->nodes_locked)
btree_node_unlock(iter, l++);
- closure_sync(&iter->cl);
-
return iter->error;
}
@@ -374,7 +372,8 @@ static void btree_iter_lock_root(struct btree_iter *iter, struct bpos pos)
}
}
-static int btree_iter_down(struct btree_iter *iter, struct bpos pos)
+static int btree_iter_down(struct btree_iter *iter, struct bpos pos,
+ struct closure *cl)
{
struct btree *b;
struct bkey_s_c k = __btree_iter_peek(iter);
@@ -382,7 +381,7 @@ static int btree_iter_down(struct btree_iter *iter, struct bpos pos)
bkey_reassemble(&tmp.k, k);
- b = bch_btree_node_get(iter, &tmp.k, iter->level - 1);
+ b = bch_btree_node_get(iter, &tmp.k, iter->level - 1, cl);
if (unlikely(IS_ERR(b)))
return PTR_ERR(b);
@@ -481,10 +480,15 @@ retry:
*/
while (iter->level > l)
if (iter->nodes[iter->level]) {
- int ret = btree_iter_down(iter, pos);
+ struct closure cl;
+ int ret;
+
+ closure_init_stack(&cl);
+ ret = btree_iter_down(iter, pos, &cl);
if (unlikely(ret)) {
bch_btree_iter_unlock(iter);
+ closure_sync(&cl);
/*
* We just dropped all our locks - so if we need
@@ -680,8 +684,6 @@ void __bch_btree_iter_init(struct btree_iter *iter, struct cache_set *c,
enum btree_id btree_id, struct bpos pos,
int locks_want)
{
- closure_init_stack(&iter->cl);
-
iter->level = 0;
iter->is_extents = btree_id == BTREE_ID_EXTENTS;
iter->nodes_locked = 0;
diff --git a/drivers/md/bcache/btree_iter.h b/drivers/md/bcache/btree_iter.h
index 55fe9236ea7c..312283a44507 100644
--- a/drivers/md/bcache/btree_iter.h
+++ b/drivers/md/bcache/btree_iter.h
@@ -4,8 +4,6 @@
#include "btree_types.h"
struct btree_iter {
- struct closure cl;
-
/* Current btree depth */
u8 level;
diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c
index 7c478fbf73d1..8746be4b128a 100644
--- a/drivers/md/bcache/btree_update.c
+++ b/drivers/md/bcache/btree_update.c
@@ -566,17 +566,17 @@ err_free:
return ERR_PTR(ret);
}
-struct btree_reserve *bch_btree_reserve_get(struct cache_set *c,
+struct btree_reserve *bch_btree_reserve_get(struct btree_iter *iter,
struct btree *b,
- struct btree_iter *iter,
unsigned extra_nodes,
- bool check_enospc)
+ bool check_enospc,
+ struct closure *cl)
{
unsigned depth = btree_node_root(b)->level - b->level;
unsigned nr_nodes = btree_reserve_required_nodes(depth) + extra_nodes;
- return __bch_btree_reserve_get(c, check_enospc, nr_nodes,
- iter ? &iter->cl : NULL);
+ return __bch_btree_reserve_get(iter->c, check_enospc,
+ nr_nodes, cl);
}
@@ -1451,7 +1451,8 @@ void bch_btree_insert_node(struct btree *b,
}
}
-static int bch_btree_split_leaf(struct btree_iter *iter, unsigned flags)
+static int bch_btree_split_leaf(struct btree_iter *iter, unsigned flags,
+ struct closure *cl)
{
struct cache_set *c = iter->c;
struct btree *b = iter->nodes[0];
@@ -1475,8 +1476,9 @@ static int bch_btree_split_leaf(struct btree_iter *iter, unsigned flags)
goto out_unlock;
}
- reserve = bch_btree_reserve_get(c, b, iter, 0,
- !(flags & BTREE_INSERT_NOFAIL));
+ reserve = bch_btree_reserve_get(iter, b, 0,
+ !(flags & BTREE_INSERT_NOFAIL),
+ cl);
if (IS_ERR(reserve)) {
ret = PTR_ERR(reserve);
goto out_unlock;
@@ -1570,9 +1572,12 @@ int bch_btree_insert_trans(struct btree_insert_trans *trans,
struct journal_res res = { 0, 0 };
struct btree_trans_entry *i;
struct btree_iter *split;
+ struct closure cl;
unsigned u64s;
int ret;
+ closure_init_stack(&cl);
+
trans_for_each_entry(trans, i) {
EBUG_ON(i->iter->level);
EBUG_ON(bkey_cmp(bkey_start_pos(&i->k->k), i->iter->pos));
@@ -1674,7 +1679,7 @@ unlock_split:
*/
bch_journal_res_put(&c->journal, &res, journal_seq);
split:
- ret = bch_btree_split_leaf(split, flags);
+ ret = bch_btree_split_leaf(split, flags, &cl);
if (ret)
goto err;
@@ -1688,6 +1693,7 @@ err:
if (ret == -EAGAIN) {
trans_for_each_entry(trans, i)
bch_btree_iter_unlock(i->iter);
+ closure_sync(&cl);
ret = -EINTR;
}
@@ -1964,7 +1970,8 @@ int bch_btree_delete_range(struct cache_set *c, enum btree_id id,
* Returns 0 on success, -EINTR or -EAGAIN on failure (i.e.
* btree_check_reserve() has to wait)
*/
-int bch_btree_node_rewrite(struct btree *b, struct btree_iter *iter, bool wait)
+int bch_btree_node_rewrite(struct btree_iter *iter, struct btree *b,
+ struct closure *cl)
{
struct cache_set *c = iter->c;
struct btree *n, *parent = iter->nodes[b->level + 1];
@@ -1975,7 +1982,7 @@ int bch_btree_node_rewrite(struct btree *b, struct btree_iter *iter, bool wait)
if (!bch_btree_iter_upgrade(iter))
return -EINTR;
- reserve = bch_btree_reserve_get(c, b, wait ? iter : NULL, 1, true);
+ reserve = bch_btree_reserve_get(iter, b, 1, true, cl);
if (IS_ERR(reserve)) {
trace_bcache_btree_gc_rewrite_node_fail(b);
return PTR_ERR(reserve);
diff --git a/drivers/md/bcache/btree_update.h b/drivers/md/bcache/btree_update.h
index e91ec0fc5880..977f811cbf89 100644
--- a/drivers/md/bcache/btree_update.h
+++ b/drivers/md/bcache/btree_update.h
@@ -128,10 +128,9 @@ void bch_btree_set_root_initial(struct cache_set *, struct btree *,
struct btree_reserve *);
void bch_btree_reserve_put(struct cache_set *, struct btree_reserve *);
-struct btree_reserve *bch_btree_reserve_get(struct cache_set *c,
- struct btree *,
- struct btree_iter *,
- unsigned, bool);
+struct btree_reserve *bch_btree_reserve_get(struct btree_iter *,
+ struct btree *, unsigned,
+ bool, struct closure *);
int bch_btree_root_alloc(struct cache_set *, enum btree_id, struct closure *);
@@ -290,7 +289,7 @@ int bch_btree_delete_range(struct cache_set *, enum btree_id,
struct bpos, struct bpos, u64,
struct extent_insert_hook *, u64 *);
-int bch_btree_node_rewrite(struct btree *, struct btree_iter *, bool);
+int bch_btree_node_rewrite(struct btree_iter *, struct btree *, struct closure *);
#endif /* _BCACHE_BTREE_INSERT_H */
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index baf0f92b0b41..b64c601e8eae 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -150,6 +150,9 @@ static void journal_seq_blacklist_flush(struct journal_entry_pin *pin)
struct cache_set *c = bl->c;
struct btree *b;
struct btree_iter iter;
+ struct closure cl;
+
+ closure_init_stack(&cl);
while (1) {
mutex_lock(&c->journal.blacklist_lock);
@@ -172,9 +175,10 @@ static void journal_seq_blacklist_flush(struct journal_entry_pin *pin)
b = bch_btree_iter_peek_node(&iter);
if (!list_empty_careful(&b->journal_seq_blacklisted))
- bch_btree_node_rewrite(b, &iter, true);
+ bch_btree_node_rewrite(&iter, b, &cl);
bch_btree_iter_unlock(&iter);
+ closure_sync(&cl);
}
journal_pin_drop(&c->journal, &bl->pin);
diff --git a/drivers/md/bcache/migrate.c b/drivers/md/bcache/migrate.c
index 30d78457c6bc..43d86a68fb10 100644
--- a/drivers/md/bcache/migrate.c
+++ b/drivers/md/bcache/migrate.c
@@ -239,8 +239,11 @@ static int bch_move_btree_off(struct cache *ca,
enum btree_id id,
const char *name)
{
+ struct closure cl;
unsigned pass;
+ closure_init_stack(&cl);
+
pr_debug("Moving %s btree off device %u",
name, ca->sb.nr_this_dev);
@@ -258,13 +261,14 @@ retry:
if (!bch_extent_has_device(e, ca->sb.nr_this_dev))
continue;
- if (bch_btree_node_rewrite(b, &iter, true)) {
+ if (bch_btree_node_rewrite(&iter, b, &cl)) {
/*
* Drop locks to upgrade locks or wait on
* reserve: after retaking, recheck in case we
* raced.
*/
bch_btree_iter_unlock(&iter);
+ closure_sync(&cl);
b = bch_btree_iter_peek_node(&iter);
goto retry;
}