return ret;
}
-static int bch_btree_insert_recurse(struct btree *b, struct btree_op *op,
- struct keylist *keys, atomic_t *journal_ref,
- struct bkey *replace_key)
-{
- if (bch_keylist_empty(keys))
- return 0;
-
- if (b->level) {
- struct bkey *k;
-
- k = bch_next_recurse_key(b, &START_KEY(keys->keys));
- if (!k) {
- btree_bug(b, "no key to recurse on at level %i/%i",
- b->level, b->c->root->level);
+struct btree_insert_op {
+ struct btree_op op;
+ struct keylist *keys;
+ atomic_t *journal_ref;
+ struct bkey *replace_key;
+};
- bch_keylist_reset(keys);
- return -EIO;
- }
+int btree_insert_fn(struct btree_op *b_op, struct btree *b)
+{
+ struct btree_insert_op *op = container_of(b_op,
+ struct btree_insert_op, op);
- return btree(insert_recurse, k, b, op, keys,
- journal_ref, replace_key);
- } else {
- return bch_btree_insert_node(b, op, keys,
- journal_ref, replace_key);
- }
+ int ret = bch_btree_insert_node(b, &op->op, op->keys,
+ op->journal_ref, op->replace_key);
+ if (ret && !bch_keylist_empty(op->keys))
+ return ret;
+ else
+ return MAP_DONE;
}
-int bch_btree_insert(struct btree_op *op, struct cache_set *c,
- struct keylist *keys, atomic_t *journal_ref,
- struct bkey *replace_key)
+int bch_btree_insert(struct cache_set *c, struct keylist *keys,
+ atomic_t *journal_ref, struct bkey *replace_key)
{
+ struct btree_insert_op op;
int ret = 0;
+ BUG_ON(current->bio_list);
BUG_ON(bch_keylist_empty(keys));
- while (!bch_keylist_empty(keys)) {
- op->lock = 0;
- ret = btree_root(insert_recurse, c, op, keys,
- journal_ref, replace_key);
+ bch_btree_op_init(&op.op, 0);
+ op.keys = keys;
+ op.journal_ref = journal_ref;
+ op.replace_key = replace_key;
- if (ret == -EAGAIN) {
- BUG();
- ret = 0;
- } else if (ret) {
- struct bkey *k;
+ while (!ret && !bch_keylist_empty(keys)) {
+ op.op.lock = 0;
+ ret = bch_btree_map_leaf_nodes(&op.op, c,
+ &START_KEY(keys->keys),
+ btree_insert_fn);
+ }
- pr_err("error %i", ret);
+ if (ret) {
+ struct bkey *k;
- while ((k = bch_keylist_pop(keys)))
- bkey_put(c, k, 0);
- }
- }
+ pr_err("error %i", ret);
- if (op->insert_collision)
- return -ESRCH;
+ while ((k = bch_keylist_pop(keys)))
+ bkey_put(c, k, 0);
+ } else if (op.op.insert_collision)
+ ret = -ESRCH;
return ret;
}
uint64_t start = i->j.last_seq, end = i->j.seq, n = start;
struct keylist keylist;
- struct btree_op op;
bch_keylist_init(&keylist);
- bch_btree_op_init(&op, SHRT_MAX);
list_for_each_entry(i, list, list) {
BUG_ON(i->pin && atomic_read(i->pin) != 1);
bkey_copy(keylist.top, k);
bch_keylist_push(&keylist);
- ret = bch_btree_insert(&op, s, &keylist, i->pin, NULL);
+ ret = bch_btree_insert(s, &keylist, i->pin, NULL);
if (ret)
goto err;
/* This is kind of a dumb way of signalling errors. */
if (KEY_DIRTY(&w->key)) {
+ int ret;
unsigned i;
- struct btree_op op;
struct keylist keys;
- int ret;
- bch_btree_op_init(&op, -1);
bch_keylist_init(&keys);
bkey_copy(keys.top, &w->key);
for (i = 0; i < KEY_PTRS(&w->key); i++)
atomic_inc(&PTR_BUCKET(dc->disk.c, &w->key, i)->pin);
- ret = bch_btree_insert(&op, dc->disk.c, &keys, NULL, &w->key);
+ ret = bch_btree_insert(dc->disk.c, &keys, NULL, &w->key);
if (ret)
trace_bcache_writeback_collision(&w->key);