diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-05-30 21:46:31 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-07 12:36:34 -0800 |
commit | 32644b435fb7dd62e3e2d1814d71925d1c4532d1 (patch) | |
tree | 62fdf2f7bde9b5bcb1aa534f490e7947a394cd4f | |
parent | c9c166173df097b83c2dd189f6f5a3882f8dd8a8 (diff) |
bcache: btree iter tweaks
-rw-r--r-- | drivers/md/bcache/btree_iter.c | 35 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.c | 3 |
2 files changed, 23 insertions, 15 deletions
diff --git a/drivers/md/bcache/btree_iter.c b/drivers/md/bcache/btree_iter.c index 435bceafaac7..989c6be55109 100644 --- a/drivers/md/bcache/btree_iter.c +++ b/drivers/md/bcache/btree_iter.c @@ -9,9 +9,11 @@ #include <trace/events/bcache.h> +#define BTREE_ITER_NOT_END ((struct btree *) 1) + static inline bool is_btree_node(struct btree_iter *iter, unsigned l) { - return ((unsigned long) iter->nodes[l]) > 1; + return iter->nodes[l] && iter->nodes[l] != BTREE_ITER_NOT_END; } /* Btree node locking: */ @@ -330,7 +332,7 @@ void bch_btree_iter_node_drop_linked(struct btree_iter *iter, struct btree *b) for_each_linked_btree_iter(iter, linked) if (linked->nodes[level] == b) { btree_node_unlock(linked, level); - linked->nodes[level] = (void *) 1; + linked->nodes[level] = BTREE_ITER_NOT_END; } } @@ -341,7 +343,7 @@ void bch_btree_iter_node_drop(struct btree_iter *iter, struct btree *b) if (iter->nodes[level] == b) { BUG_ON(b->lock.state.intent_lock != 1); btree_node_unlock(iter, level); - iter->nodes[level] = (void *) 1; + iter->nodes[level] = BTREE_ITER_NOT_END; } } @@ -617,14 +619,17 @@ struct bkey_s_c bch_btree_iter_peek(struct btree_iter *iter) while (1) { ret = __bch_btree_iter_traverse(iter, 0, pos); - if (ret) + if (unlikely(ret)) return bkey_s_c_null; - if (likely((k = __btree_iter_peek(iter)).k)) { - EBUG_ON(bkey_cmp(k.k->p, pos) < 0); - - /* extents... */ - if (bkey_cmp(bkey_start_pos(k.k), iter->pos) > 0) + k = __btree_iter_peek(iter); + if (likely(k.k)) { + /* + * iter->pos should always be equal to the key we just + * returned - except extents can straddle iter->pos: + */ + if (!iter->is_extents || + bkey_cmp(bkey_start_pos(k.k), iter->pos) > 0) bch_btree_iter_set_pos(iter, bkey_start_pos(k.k)); return k; } @@ -646,7 +651,7 @@ struct bkey_s_c bch_btree_iter_peek_with_holes(struct btree_iter *iter) while (1) { ret = __bch_btree_iter_traverse(iter, 0, iter->pos); - if (ret) + if (unlikely(ret)) return bkey_s_c_null; k = __btree_iter_peek_all(iter); @@ -656,15 +661,15 @@ recheck: bkey_init(&n); n.p = iter->pos; - if (!k.k) - k.k = &iter->nodes[0]->key.k; - - if (iter->btree_id == BTREE_ID_EXTENTS) { + if (iter->is_extents) { if (n.p.offset == KEY_OFFSET_MAX) { iter->pos = bkey_successor(iter->pos); goto recheck; } + if (!k.k) + k.k = &iter->nodes[0]->key.k; + bch_key_resize(&n, min_t(u64, KEY_SIZE_MAX, (k.k->p.inode == n.p.inode @@ -705,7 +710,7 @@ void __bch_btree_iter_init(struct btree_iter *iter, struct cache_set *c, iter->error = 0; iter->c = c; iter->pos = pos; - iter->nodes[iter->level] = (void *) 1; + iter->nodes[iter->level] = BTREE_ITER_NOT_END; iter->nodes[iter->level + 1] = NULL; iter->next = iter; } diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index 9e7f44e014a3..a54cc5aa4ed1 100644 --- a/drivers/md/bcache/btree_update.c +++ b/drivers/md/bcache/btree_update.c @@ -1853,6 +1853,9 @@ int bch_btree_insert_check_key(struct btree_iter *iter, bkey_copy(&tmp.key, check_key); + /* XXX rewind shouldn't be necessary... */ + BUG_ON(bkey_cmp(iter->pos, bkey_start_pos(&check_key->k))); + bch_btree_iter_rewind(iter, bkey_start_pos(&check_key->k)); ret = bch_btree_insert_at(iter, &tmp.key, NULL, NULL, |