summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-10-25 16:24:01 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2016-11-13 13:56:20 -0900
commite1bd0fffe23afca44e657751e22c32a94689ba00 (patch)
treebbec9cd107d9e2f29281288a56f7f8cfb11359e3
parentcfa2adaa9a3b2781faf081681bf2e27ebff13f1f (diff)
bcache: kill most uses of bch_btree_iter_upgrade
-rw-r--r--drivers/md/bcache/btree_iter.c83
-rw-r--r--drivers/md/bcache/btree_iter.h2
-rw-r--r--drivers/md/bcache/six.h2
3 files changed, 39 insertions, 48 deletions
diff --git a/drivers/md/bcache/btree_iter.c b/drivers/md/bcache/btree_iter.c
index 60bac17f65e7..f0e729b7f6eb 100644
--- a/drivers/md/bcache/btree_iter.c
+++ b/drivers/md/bcache/btree_iter.c
@@ -130,23 +130,9 @@ bool bch_btree_iter_upgrade(struct btree_iter *iter)
{
int i;
- for (i = iter->level;
- i < min_t(int, iter->locks_want, BTREE_MAX_DEPTH);
- i++)
- if (iter->nodes[i] && !btree_node_relock(iter, i)) {
- do {
- btree_node_unlock(iter, i);
-
- /*
- * Make sure btree_node_relock() in
- * btree_iter_traverse() fails, so that we keep
- * going up and get all the intent locks we need
- */
- iter->lock_seq[i]--;
- } while (--i >= 0);
-
+ for (i = iter->level; i < iter->locks_want && iter->nodes[i]; i++)
+ if (!btree_node_relock(iter, i))
return false;
- }
return true;
}
@@ -544,6 +530,22 @@ static int __must_check __bch_btree_iter_traverse(struct btree_iter *iter,
iter->at_end_of_leaf = false;
retry:
+ /* make sure we have all the intent locks we need - ugh */
+ if (unlikely(iter->nodes[iter->level] &&
+ iter->level + 1 < iter->locks_want)) {
+ unsigned i;
+
+ for (i = iter->level + 1;
+ i < iter->locks_want && iter->nodes[i];
+ i++)
+ if (!btree_node_relock(iter, i)) {
+ while (iter->nodes[iter->level] &&
+ iter->level + 1 < iter->locks_want)
+ btree_iter_up(iter);
+ break;
+ }
+ }
+
/*
* If the current node isn't locked, go up until we have a locked node
* or run out of nodes:
@@ -551,7 +553,7 @@ retry:
while (iter->nodes[iter->level] &&
!(is_btree_node(iter, iter->level) &&
btree_node_relock(iter, iter->level) &&
- btree_iter_pos_cmp(pos,
+ btree_iter_pos_cmp(iter->pos,
&iter->nodes[iter->level]->key.k,
iter->is_extents)))
btree_iter_up(iter);
@@ -586,14 +588,8 @@ retry:
bch_btree_iter_unlock(iter);
closure_sync(&cl);
- /*
- * We just dropped all our locks - so if we need
- * intent locks, make sure to get them again:
- */
- if (ret == -EAGAIN || ret == -EINTR) {
- bch_btree_iter_upgrade(iter);
+ if (ret == -EAGAIN || ret == -EINTR)
goto retry;
- }
iter->error = ret;
iter->level = BTREE_MAX_DEPTH;
@@ -847,37 +843,32 @@ void bch_btree_iter_link(struct btree_iter *iter, struct btree_iter *linked)
linked->next = iter->next;
iter->next = linked;
+
+ if (IS_ENABLED(CONFIG_BCACHE_DEBUG)) {
+ unsigned nr_iters = 1;
+
+ for_each_linked_btree_iter(iter, linked)
+ nr_iters++;
+
+ BUG_ON(nr_iters > SIX_LOCK_MAX_RECURSE);
+ }
+}
+
+static void __bch_btree_iter_copy(struct btree_iter *dst, struct btree_iter *src)
+{
+ memcpy(dst, src, offsetof(struct btree_iter, next));
+ dst->nodes_locked = dst->nodes_intent_locked = 0;
}
void bch_btree_iter_copy(struct btree_iter *dst, struct btree_iter *src)
{
bch_btree_iter_unlock(dst);
-
- dst->level = src->level;
- dst->is_extents = src->is_extents;
- dst->btree_id = src->btree_id;
- dst->pos = src->pos;
-
- memcpy(dst->lock_seq,
- src->lock_seq,
- sizeof(src->lock_seq));
- memcpy(dst->nodes,
- src->nodes,
- sizeof(src->nodes));
- memcpy(dst->node_iters,
- src->node_iters,
- sizeof(src->node_iters));
-
- bch_btree_iter_upgrade(dst);
+ __bch_btree_iter_copy(dst, src);
}
void bch_btree_iter_init_copy(struct btree_iter *dst, struct btree_iter *src)
{
- *dst = *src;
+ __bch_btree_iter_copy(dst, src);
dst->next = dst;
- dst->nodes_locked = 0;
- dst->nodes_intent_locked = 0;
bch_btree_iter_link(src, dst);
-
- bch_btree_iter_upgrade(dst);
}
diff --git a/drivers/md/bcache/btree_iter.h b/drivers/md/bcache/btree_iter.h
index aa39e37a12f8..694be63f9f1c 100644
--- a/drivers/md/bcache/btree_iter.h
+++ b/drivers/md/bcache/btree_iter.h
@@ -239,10 +239,8 @@ static inline void bch_btree_iter_cond_resched(struct btree_iter *iter)
if (need_resched()) {
bch_btree_iter_unlock(iter);
schedule();
- bch_btree_iter_upgrade(iter);
} else if (race_fault()) {
bch_btree_iter_unlock(iter);
- bch_btree_iter_upgrade(iter);
}
}
diff --git a/drivers/md/bcache/six.h b/drivers/md/bcache/six.h
index da8ec5332f4a..b7dc9bb9cfb3 100644
--- a/drivers/md/bcache/six.h
+++ b/drivers/md/bcache/six.h
@@ -55,6 +55,8 @@ union six_lock_state {
};
};
+#define SIX_LOCK_MAX_RECURSE ((1 << 3) - 1)
+
enum six_lock_type {
SIX_LOCK_read,
SIX_LOCK_intent,