summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSlava Pestov <sviatoslavpestov@gmail.com>2014-06-23 14:00:40 -0700
committerKent Overstreet <kent.overstreet@gmail.com>2016-10-07 09:00:20 -0800
commit10e975651fc1364b87fea9355aa6cf65995fc749 (patch)
tree5dc2f82966d1d40f2cbcc875c61094bac54f0c37
parent837fe30c01ea7bfc8c7e5a6b1481a2c1fdaff10a (diff)
bcache: refactor bch_btree_insert()
bch_btree_insert() now blocks on bucket allocation, and request.c directly uses bch_btree_map_leaf_nodes() / bch_btree_insert_node(). This actually simplifies some things and removes code. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r--drivers/md/bcache/btree.c74
-rw-r--r--drivers/md/bcache/btree.h7
-rw-r--r--drivers/md/bcache/inode.c4
-rw-r--r--drivers/md/bcache/journal.c2
-rw-r--r--drivers/md/bcache/request.c39
-rw-r--r--drivers/md/bcache/request.h2
-rw-r--r--drivers/md/bcache/writeback.c4
7 files changed, 58 insertions, 74 deletions
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index 45903db933f8..be6b79079923 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -2493,12 +2493,10 @@ out:
}
struct btree_insert_op {
+ struct closure cl;
struct btree_op op;
struct keylist *keys;
struct bkey *replace_key;
- /* for waiting on journal write */
- unsigned flush:1;
- struct closure *parent;
};
static int btree_insert_fn(struct btree_op *b_op, struct btree *b)
@@ -2507,8 +2505,8 @@ static int btree_insert_fn(struct btree_op *b_op, struct btree *b)
struct btree_insert_op, op);
int ret = bch_btree_insert_node(b, &op->op, op->keys,
- op->replace_key, op->parent,
- op->flush);
+ op->replace_key, &op->cl,
+ false);
return bch_keylist_empty(op->keys) ? MAP_DONE : ret;
}
@@ -2519,67 +2517,37 @@ static int btree_insert_fn(struct btree_op *b_op, struct btree *b)
* @reserve: reserve to allocate btree node from
* @insert_keys: list of keys to insert
* @replace_key: old key for compare exchange
- * @parent: closure for waiting
- * @flush: if true, closure will wait on last key to be inserted
- *
- * The @parent closure is used to wait on btree node allocation as well as
- * the journal write (if @flush is set). The journal wait will only happen
- * if the full list is inserted.
- *
- * Returns -EAGAIN if closure was put on a waitlist waiting for
- * btree node allocation.
*/
int bch_btree_insert(struct cache_set *c, enum btree_id id,
- enum alloc_reserve reserve, struct keylist *keys,
- struct bkey *replace_key, struct closure *parent,
- bool flush)
+ struct keylist *keys, struct bkey *replace_key)
{
struct btree_insert_op op;
int ret = 0;
BUG_ON(bch_keylist_empty(keys));
- __bch_btree_op_init(&op.op, id, reserve, 0);
+ closure_init_stack(&op.cl);
+ bch_btree_op_init(&op.op, id, 0);
op.keys = keys;
op.replace_key = replace_key;
- op.flush = flush;
- op.parent = parent;
-
- while (!ret && !bch_keylist_empty(keys)) {
- op.op.lock = 0;
- ret = bch_btree_map_leaf_nodes(&op.op, c,
- id == BTREE_ID_EXTENTS
- ? &START_KEY(keys->keys)
- : keys->keys,
- btree_insert_fn);
- }
-
- if (ret && ret != -EAGAIN)
- pr_err("error %i", ret);
- else if (!ret && op.op.insert_collision)
- ret = -ESRCH;
-
- return ret;
-}
-
-/**
- * bch_btree_insert_sync - like bch_btree_insert but blocks on allocation
- */
-int bch_btree_insert_sync(struct cache_set *c, enum btree_id id,
- struct keylist *keys, struct bkey *replace_key)
-{
- struct closure cl;
- int ret;
-
- closure_init_stack(&cl);
while (1) {
- ret = bch_btree_insert(c, id, id, keys, replace_key,
- &cl, false);
+ while (!ret && !bch_keylist_empty(keys)) {
+ op.op.lock = 0;
+ ret = bch_btree_map_leaf_nodes(&op.op, c,
+ id == BTREE_ID_EXTENTS
+ ? &START_KEY(keys->keys)
+ : keys->keys,
+ btree_insert_fn);
+ }
+
if (ret == -EAGAIN)
- closure_sync(&cl);
- else
- return ret;
+ closure_sync(&op.cl);
+ else if (op.op.insert_collision)
+ return -ESRCH;
+
+ BUG_ON(ret);
+ return 0;
}
}
diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h
index ce23ceb114ac..c3b7972dff22 100644
--- a/drivers/md/bcache/btree.h
+++ b/drivers/md/bcache/btree.h
@@ -266,11 +266,8 @@ struct btree *bch_btree_node_get(struct cache_set *, struct btree_op *,
int bch_btree_insert_check_key(struct btree *, struct btree_op *,
struct bkey *, struct closure *);
-int bch_btree_insert(struct cache_set *, enum btree_id,
- enum alloc_reserve, struct keylist *, struct bkey *,
- struct closure *, bool);
-int bch_btree_insert_sync(struct cache_set *, enum btree_id,
- struct keylist *, struct bkey *);
+int bch_btree_insert(struct cache_set *, enum btree_id, struct keylist *,
+ struct bkey *);
int bch_btree_insert_node(struct btree *, struct btree_op *, struct keylist *,
struct bkey *, struct closure *, bool);
int bch_btree_insert_node_sync(struct btree *, struct btree_op *,
diff --git a/drivers/md/bcache/inode.c b/drivers/md/bcache/inode.c
index 32b3839b8dfb..0a24c6c08a13 100644
--- a/drivers/md/bcache/inode.c
+++ b/drivers/md/bcache/inode.c
@@ -81,7 +81,7 @@ int bch_inode_update(struct cache_set *c, struct bch_inode *inode)
struct keylist keys;
bch_keylist_init_single(&keys, &inode->i_key);
- return bch_btree_insert_sync(c, BTREE_ID_INODES, &keys, NULL);
+ return bch_btree_insert(c, BTREE_ID_INODES, &keys, NULL);
}
struct inode_rm_op {
@@ -142,7 +142,7 @@ int bch_inode_rm(struct cache_set *c, u64 inode_nr)
SET_KEY_DELETED(&inode, 1);
bch_keylist_init_single(&keys, &inode);
- return bch_btree_insert_sync(c, BTREE_ID_INODES, &keys, NULL);
+ return bch_btree_insert(c, BTREE_ID_INODES, &keys, NULL);
}
struct find_op {
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 4823136a50dc..47f229e05960 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -356,7 +356,7 @@ static int bch_journal_replay_key(struct cache_set *c, enum btree_id id,
bch_keylist_init_single(&keys, k);
- ret = bch_btree_insert_sync(c, id, &keys, NULL);
+ ret = bch_btree_insert(c, id, &keys, NULL);
BUG_ON(!bch_keylist_empty(&keys));
cond_resched();
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 9bbda41efb4a..f47af60a3de7 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -73,31 +73,45 @@ static enum alloc_reserve bch_btree_reserve(struct data_insert_op *op)
return BTREE_ID_EXTENTS;
}
+static int btree_insert_fn(struct btree_op *b_op, struct btree *b)
+{
+ struct data_insert_op *op = container_of(b_op,
+ struct data_insert_op, op);
+ struct bkey *replace_key = op->replace ? &op->replace_key : NULL;
+
+ int ret = bch_btree_insert_node(b, &op->op, &op->insert_keys,
+ replace_key, &op->cl,
+ op->flush);
+ return bch_keylist_empty(&op->insert_keys) ? MAP_DONE : ret;
+}
+
/**
* bch_data_insert_keys - insert extent btree keys for a write
*/
static void bch_data_insert_keys(struct closure *cl)
{
struct data_insert_op *op = container_of(cl, struct data_insert_op, cl);
- struct bkey *replace_key = op->replace ? &op->replace_key : NULL;
+ struct keylist *keys = &op->insert_keys;
enum btree_id id = BTREE_ID_EXTENTS;
enum alloc_reserve reserve;
+ int ret = 0;
unsigned i;
- int ret;
reserve = bch_btree_reserve(op);
+ __bch_btree_op_init(&op->op, id, reserve, 0);
- ret = bch_btree_insert(op->c, id, reserve, &op->insert_keys,
- replace_key, cl, op->flush);
+ while (!ret && !bch_keylist_empty(keys)) {
+ op->op.lock = 0;
+ ret = bch_btree_map_leaf_nodes(&op->op, op->c,
+ &START_KEY(keys->keys),
+ btree_insert_fn);
+ }
- if (ret == -ESRCH) {
- op->replace_collision = true;
- } else if (ret == -EAGAIN) {
+ if (ret == -EAGAIN)
continue_at(cl, bch_data_insert_keys, op->c->btree_insert_wq);
- } else if (ret) {
- op->error = -ENOMEM;
- op->insert_data_done = true;
- }
+
+ if (op->op.insert_collision)
+ op->replace_collision = true;
for (i = 0; i < ARRAY_SIZE(op->open_buckets); i++)
if (op->open_buckets[i]) {
@@ -515,6 +529,9 @@ out_submit:
generic_make_request(orig_bio);
}
+/**
+ * cache_promote - promote data stored in higher tiers
+ */
static void cache_promote(struct cache_set *c, struct bio *bio,
struct bkey *k)
{
diff --git a/drivers/md/bcache/request.h b/drivers/md/bcache/request.h
index 5976f060d863..a322ba15eba7 100644
--- a/drivers/md/bcache/request.h
+++ b/drivers/md/bcache/request.h
@@ -14,6 +14,8 @@ struct data_insert_op {
struct workqueue_struct *wq;
struct bio *bio;
+ struct btree_op op;
+
uint16_t write_point;
short error;
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index 1b7f0497dcc3..135805b94a6f 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -105,8 +105,8 @@ static void write_dirty_finish(struct closure *cl)
SET_KEY_CACHED(keys.top, true);
bch_keylist_push(&keys);
- ret = bch_btree_insert_sync(dc->disk.c, BTREE_ID_EXTENTS,
- &keys, &w->key);
+ ret = bch_btree_insert(dc->disk.c, BTREE_ID_EXTENTS,
+ &keys, &w->key);
if (ret)
trace_bcache_writeback_collision(&w->key);