diff options
-rw-r--r-- | drivers/md/bcache/btree_cache.c | 10 | ||||
-rw-r--r-- | drivers/md/bcache/btree_cache.h | 3 | ||||
-rw-r--r-- | drivers/md/bcache/btree_gc.c | 4 | ||||
-rw-r--r-- | drivers/md/bcache/btree_iter.c | 16 | ||||
-rw-r--r-- | drivers/md/bcache/btree_iter.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.c | 29 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.h | 9 | ||||
-rw-r--r-- | drivers/md/bcache/journal.c | 6 | ||||
-rw-r--r-- | drivers/md/bcache/migrate.c | 6 |
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; } |