diff options
-rw-r--r-- | drivers/md/bcache/btree.c | 79 | ||||
-rw-r--r-- | drivers/md/bcache/btree.h | 4 | ||||
-rw-r--r-- | drivers/md/bcache/journal.c | 4 | ||||
-rw-r--r-- | drivers/md/bcache/request.c | 2 | ||||
-rw-r--r-- | drivers/md/bcache/writeback.c | 6 |
5 files changed, 43 insertions, 52 deletions
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 441524dd2d77..f5aa4adadf1d 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c | |||
@@ -2174,61 +2174,56 @@ out: | |||
2174 | return ret; | 2174 | return ret; |
2175 | } | 2175 | } |
2176 | 2176 | ||
2177 | static int bch_btree_insert_recurse(struct btree *b, struct btree_op *op, | 2177 | struct btree_insert_op { |
2178 | struct keylist *keys, atomic_t *journal_ref, | 2178 | struct btree_op op; |
2179 | struct bkey *replace_key) | 2179 | struct keylist *keys; |
2180 | { | 2180 | atomic_t *journal_ref; |
2181 | if (bch_keylist_empty(keys)) | 2181 | struct bkey *replace_key; |
2182 | return 0; | 2182 | }; |
2183 | |||
2184 | if (b->level) { | ||
2185 | struct bkey *k; | ||
2186 | |||
2187 | k = bch_next_recurse_key(b, &START_KEY(keys->keys)); | ||
2188 | if (!k) { | ||
2189 | btree_bug(b, "no key to recurse on at level %i/%i", | ||
2190 | b->level, b->c->root->level); | ||
2191 | 2183 | ||
2192 | bch_keylist_reset(keys); | 2184 | int btree_insert_fn(struct btree_op *b_op, struct btree *b) |
2193 | return -EIO; | 2185 | { |
2194 | } | 2186 | struct btree_insert_op *op = container_of(b_op, |
2187 | struct btree_insert_op, op); | ||
2195 | 2188 | ||
2196 | return btree(insert_recurse, k, b, op, keys, | 2189 | int ret = bch_btree_insert_node(b, &op->op, op->keys, |
2197 | journal_ref, replace_key); | 2190 | op->journal_ref, op->replace_key); |
2198 | } else { | 2191 | if (ret && !bch_keylist_empty(op->keys)) |
2199 | return bch_btree_insert_node(b, op, keys, | 2192 | return ret; |
2200 | journal_ref, replace_key); | 2193 | else |
2201 | } | 2194 | return MAP_DONE; |
2202 | } | 2195 | } |
2203 | 2196 | ||
2204 | int bch_btree_insert(struct btree_op *op, struct cache_set *c, | 2197 | int bch_btree_insert(struct cache_set *c, struct keylist *keys, |
2205 | struct keylist *keys, atomic_t *journal_ref, | 2198 | atomic_t *journal_ref, struct bkey *replace_key) |
2206 | struct bkey *replace_key) | ||
2207 | { | 2199 | { |
2200 | struct btree_insert_op op; | ||
2208 | int ret = 0; | 2201 | int ret = 0; |
2209 | 2202 | ||
2203 | BUG_ON(current->bio_list); | ||
2210 | BUG_ON(bch_keylist_empty(keys)); | 2204 | BUG_ON(bch_keylist_empty(keys)); |
2211 | 2205 | ||
2212 | while (!bch_keylist_empty(keys)) { | 2206 | bch_btree_op_init(&op.op, 0); |
2213 | op->lock = 0; | 2207 | op.keys = keys; |
2214 | ret = btree_root(insert_recurse, c, op, keys, | 2208 | op.journal_ref = journal_ref; |
2215 | journal_ref, replace_key); | 2209 | op.replace_key = replace_key; |
2216 | 2210 | ||
2217 | if (ret == -EAGAIN) { | 2211 | while (!ret && !bch_keylist_empty(keys)) { |
2218 | BUG(); | 2212 | op.op.lock = 0; |
2219 | ret = 0; | 2213 | ret = bch_btree_map_leaf_nodes(&op.op, c, |
2220 | } else if (ret) { | 2214 | &START_KEY(keys->keys), |
2221 | struct bkey *k; | 2215 | btree_insert_fn); |
2216 | } | ||
2222 | 2217 | ||
2223 | pr_err("error %i", ret); | 2218 | if (ret) { |
2219 | struct bkey *k; | ||
2224 | 2220 | ||
2225 | while ((k = bch_keylist_pop(keys))) | 2221 | pr_err("error %i", ret); |
2226 | bkey_put(c, k, 0); | ||
2227 | } | ||
2228 | } | ||
2229 | 2222 | ||
2230 | if (op->insert_collision) | 2223 | while ((k = bch_keylist_pop(keys))) |
2231 | return -ESRCH; | 2224 | bkey_put(c, k, 0); |
2225 | } else if (op.op.insert_collision) | ||
2226 | ret = -ESRCH; | ||
2232 | 2227 | ||
2233 | return ret; | 2228 | return ret; |
2234 | } | 2229 | } |
diff --git a/drivers/md/bcache/btree.h b/drivers/md/bcache/btree.h index 6ff08be3e0c9..8fc1e8925399 100644 --- a/drivers/md/bcache/btree.h +++ b/drivers/md/bcache/btree.h | |||
@@ -281,8 +281,8 @@ struct btree *bch_btree_node_get(struct cache_set *, struct bkey *, int, bool); | |||
281 | 281 | ||
282 | int bch_btree_insert_check_key(struct btree *, struct btree_op *, | 282 | int bch_btree_insert_check_key(struct btree *, struct btree_op *, |
283 | struct bkey *); | 283 | struct bkey *); |
284 | int bch_btree_insert(struct btree_op *, struct cache_set *, | 284 | int bch_btree_insert(struct cache_set *, struct keylist *, |
285 | struct keylist *, atomic_t *, struct bkey *); | 285 | atomic_t *, struct bkey *); |
286 | 286 | ||
287 | int bch_gc_thread_start(struct cache_set *); | 287 | int bch_gc_thread_start(struct cache_set *); |
288 | size_t bch_btree_gc_finish(struct cache_set *); | 288 | size_t bch_btree_gc_finish(struct cache_set *); |
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c index 592adf51128f..86de64a6bf26 100644 --- a/drivers/md/bcache/journal.c +++ b/drivers/md/bcache/journal.c | |||
@@ -302,10 +302,8 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list) | |||
302 | 302 | ||
303 | uint64_t start = i->j.last_seq, end = i->j.seq, n = start; | 303 | uint64_t start = i->j.last_seq, end = i->j.seq, n = start; |
304 | struct keylist keylist; | 304 | struct keylist keylist; |
305 | struct btree_op op; | ||
306 | 305 | ||
307 | bch_keylist_init(&keylist); | 306 | bch_keylist_init(&keylist); |
308 | bch_btree_op_init(&op, SHRT_MAX); | ||
309 | 307 | ||
310 | list_for_each_entry(i, list, list) { | 308 | list_for_each_entry(i, list, list) { |
311 | BUG_ON(i->pin && atomic_read(i->pin) != 1); | 309 | BUG_ON(i->pin && atomic_read(i->pin) != 1); |
@@ -322,7 +320,7 @@ int bch_journal_replay(struct cache_set *s, struct list_head *list) | |||
322 | bkey_copy(keylist.top, k); | 320 | bkey_copy(keylist.top, k); |
323 | bch_keylist_push(&keylist); | 321 | bch_keylist_push(&keylist); |
324 | 322 | ||
325 | ret = bch_btree_insert(&op, s, &keylist, i->pin, NULL); | 323 | ret = bch_btree_insert(s, &keylist, i->pin, NULL); |
326 | if (ret) | 324 | if (ret) |
327 | goto err; | 325 | goto err; |
328 | 326 | ||
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index bcce06a1e466..6cee2ae1d87f 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
@@ -237,7 +237,7 @@ static void bch_data_insert_keys(struct closure *cl) | |||
237 | s->flush_journal | 237 | s->flush_journal |
238 | ? &s->cl : NULL); | 238 | ? &s->cl : NULL); |
239 | 239 | ||
240 | ret = bch_btree_insert(&s->op, s->c, &s->insert_keys, | 240 | ret = bch_btree_insert(s->c, &s->insert_keys, |
241 | journal_ref, replace_key); | 241 | journal_ref, replace_key); |
242 | if (ret == -ESRCH) { | 242 | if (ret == -ESRCH) { |
243 | s->insert_collision = true; | 243 | s->insert_collision = true; |
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 312032ef34f7..ab0f6b449111 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c | |||
@@ -139,12 +139,10 @@ static void write_dirty_finish(struct closure *cl) | |||
139 | 139 | ||
140 | /* This is kind of a dumb way of signalling errors. */ | 140 | /* This is kind of a dumb way of signalling errors. */ |
141 | if (KEY_DIRTY(&w->key)) { | 141 | if (KEY_DIRTY(&w->key)) { |
142 | int ret; | ||
142 | unsigned i; | 143 | unsigned i; |
143 | struct btree_op op; | ||
144 | struct keylist keys; | 144 | struct keylist keys; |
145 | int ret; | ||
146 | 145 | ||
147 | bch_btree_op_init(&op, -1); | ||
148 | bch_keylist_init(&keys); | 146 | bch_keylist_init(&keys); |
149 | 147 | ||
150 | bkey_copy(keys.top, &w->key); | 148 | bkey_copy(keys.top, &w->key); |
@@ -154,7 +152,7 @@ static void write_dirty_finish(struct closure *cl) | |||
154 | for (i = 0; i < KEY_PTRS(&w->key); i++) | 152 | for (i = 0; i < KEY_PTRS(&w->key); i++) |
155 | atomic_inc(&PTR_BUCKET(dc->disk.c, &w->key, i)->pin); | 153 | atomic_inc(&PTR_BUCKET(dc->disk.c, &w->key, i)->pin); |
156 | 154 | ||
157 | ret = bch_btree_insert(&op, dc->disk.c, &keys, NULL, &w->key); | 155 | ret = bch_btree_insert(dc->disk.c, &keys, NULL, &w->key); |
158 | 156 | ||
159 | if (ret) | 157 | if (ret) |
160 | trace_bcache_writeback_collision(&w->key); | 158 | trace_bcache_writeback_collision(&w->key); |