summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-05-30 16:05:09 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2016-07-30 01:13:54 -0800
commitd9ec478c57c165528011840dd8420d4da823dd1a (patch)
tree6851b7beefb4455747dc3eb4dfd42c5594e6133a
parentcd336596ae51c0d56aac0e29a19e9a15b31bd3a7 (diff)
bcache: remove sentinel null from btree_iter
-rw-r--r--drivers/md/bcache/btree_iter.c23
-rw-r--r--drivers/md/bcache/btree_iter.h4
2 files changed, 13 insertions, 14 deletions
diff --git a/drivers/md/bcache/btree_iter.c b/drivers/md/bcache/btree_iter.c
index 0963827efe18..59483bbe57e9 100644
--- a/drivers/md/bcache/btree_iter.c
+++ b/drivers/md/bcache/btree_iter.c
@@ -514,19 +514,17 @@ static inline void btree_iter_lock_root(struct btree_iter *iter, struct bpos pos
{
struct cache_set *c = iter->c;
- iter->nodes_locked = 0;
- iter->nodes_intent_locked = 0;
- memset(iter->nodes, 0, sizeof(iter->nodes));
-
while (1) {
struct btree *b = c->btree_roots[iter->btree_id].b;
+ unsigned level = READ_ONCE(b->level);
- iter->level = b->level;
+ btree_iter_verify_locking(iter, level);
- btree_iter_verify_locking(iter, iter->level);
-
- if (btree_node_lock(b, iter, iter->level,
+ if (btree_node_lock(b, iter, level,
(b != c->btree_roots[iter->btree_id].b))) {
+ iter->level = level;
+ if (level + 1 < BTREE_MAX_DEPTH)
+ iter->nodes[level + 1] = NULL;
btree_iter_node_set(iter, b, pos);
break;
}
@@ -591,7 +589,8 @@ retry:
* If we've got a btree node locked (i.e. we aren't about to relock the
* root) - advance its node iterator if necessary:
*/
- if (iter->nodes[iter->level]) {
+ if (iter->level < BTREE_MAX_DEPTH &&
+ iter->nodes[iter->level]) {
struct bkey_s_c k;
while ((k = __btree_iter_peek_all(iter)).k &&
@@ -606,7 +605,8 @@ retry:
* btree_iter_lock_root() comes next and that it can't fail
*/
while (iter->level > l)
- if (iter->nodes[iter->level]) {
+ if (iter->level < BTREE_MAX_DEPTH &&
+ iter->nodes[iter->level]) {
struct closure cl;
int ret;
@@ -672,7 +672,8 @@ struct btree *bch_btree_iter_next_node(struct btree_iter *iter)
btree_iter_up(iter);
- if (!iter->nodes[iter->level])
+ if (iter->level >= BTREE_MAX_DEPTH ||
+ !iter->nodes[iter->level])
return NULL;
/* parent node usually won't be locked: redo traversal if necessary */
diff --git a/drivers/md/bcache/btree_iter.h b/drivers/md/bcache/btree_iter.h
index c021a2633d2f..c06e692b895e 100644
--- a/drivers/md/bcache/btree_iter.h
+++ b/drivers/md/bcache/btree_iter.h
@@ -48,10 +48,8 @@ struct btree_iter {
* always fail (but since freeing a btree node takes a write lock on the
* node, which increments the node's lock seq, that's not actually
* necessary in that example).
- *
- * One extra slot for a sentinel NULL:
*/
- struct btree *nodes[BTREE_MAX_DEPTH + 1];
+ struct btree *nodes[BTREE_MAX_DEPTH];
struct btree_node_iter node_iters[BTREE_MAX_DEPTH];
/*