diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-04-09 07:24:06 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-07 12:36:08 -0800 |
commit | 64e2031d6916042baf920e01e5c9b4e212d6c4a2 (patch) | |
tree | 4077c365019b46f132d5eede096829c9400162c5 | |
parent | 9fb193f1c8fed094a7f8b0480b6f9d06074aba4d (diff) |
bcache: verify btree node lock ordering
-rw-r--r-- | drivers/md/bcache/btree_iter.c | 20 | ||||
-rw-r--r-- | drivers/md/bcache/btree_iter.h | 8 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.c | 4 |
3 files changed, 22 insertions, 10 deletions
diff --git a/drivers/md/bcache/btree_iter.c b/drivers/md/bcache/btree_iter.c index 8b2636541959..d7a28673f68f 100644 --- a/drivers/md/bcache/btree_iter.c +++ b/drivers/md/bcache/btree_iter.c @@ -155,8 +155,8 @@ bool btree_node_relock(struct btree_iter *iter, unsigned level) /* Btree iterator: */ -static bool btree_iter_cmp(struct btree_iter *iter, - struct bpos pos, struct bpos k) +static bool btree_iter_pos_cmp(struct btree_iter *iter, + struct bpos pos, struct bpos k) { return iter->is_extents ? bkey_cmp(pos, k) < 0 @@ -176,7 +176,7 @@ void bch_btree_node_iter_fix(struct btree_iter *iter, unsigned shift = overwrote ? 0 : where->u64s; unsigned offset = __btree_node_key_to_offset(b, where); unsigned old_end = __btree_node_key_to_offset(b, end) - shift; - bool iter_pos_before_new = btree_iter_cmp(iter, iter->pos, + bool iter_pos_before_new = btree_iter_pos_cmp(iter, iter->pos, bkey_unpack_key(f, where).p); BUG_ON(node_iter->used > MAX_BSETS); @@ -264,7 +264,7 @@ static bool btree_iter_pos_in_node(struct btree_iter *iter, { return iter->btree_id == b->btree_id && bkey_cmp(iter->pos, b->data->min_key) >= 0 && - btree_iter_cmp(iter, iter->pos, b->key.k.p); + btree_iter_pos_cmp(iter, iter->pos, b->key.k.p); } /* @@ -410,7 +410,6 @@ static void btree_iter_verify_locking(struct btree_iter *iter) * retaking fails then return -EINTR... but, let's keep things simple * for now: */ - for_each_linked_btree_iter(iter, linked) for (level = 0; level < BTREE_MAX_DEPTH; level++) BUG_ON(btree_node_read_locked(linked, level)); @@ -423,6 +422,12 @@ static void btree_iter_verify_locking(struct btree_iter *iter) for_each_linked_btree_iter(iter, linked) for (level = 0; level < iter->level; level++) BUG_ON(btree_node_intent_locked(linked, level)); + + /* And, lock ordering: */ + for_each_linked_btree_iter(iter, linked) + BUG_ON(btree_node_intent_locked(linked, 0) && + btree_iter_cmp(iter, linked) < 0); + #endif } @@ -451,7 +456,8 @@ retry: while (iter->nodes[iter->level] && !(is_btree_node(iter, iter->level) && btree_node_relock(iter, iter->level) && - btree_iter_cmp(iter, pos, iter->nodes[iter->level]->key.k.p))) + btree_iter_pos_cmp(iter, pos, + iter->nodes[iter->level]->key.k.p))) btree_iter_up(iter); /* @@ -462,7 +468,7 @@ retry: struct bkey_s_c k; while ((k = __btree_iter_peek_all(iter)).k && - !btree_iter_cmp(iter, pos, k.k->p)) + !btree_iter_pos_cmp(iter, pos, k.k->p)) __btree_iter_next_all(iter); } diff --git a/drivers/md/bcache/btree_iter.h b/drivers/md/bcache/btree_iter.h index 1d0186af5000..55fe9236ea7c 100644 --- a/drivers/md/bcache/btree_iter.h +++ b/drivers/md/bcache/btree_iter.h @@ -168,6 +168,14 @@ static inline struct bpos btree_type_successor(enum btree_id id, return pos; } +static inline int btree_iter_cmp(const struct btree_iter *l, + const struct btree_iter *r) +{ + if (l->btree_id != r->btree_id) + return l->btree_id < r->btree_id ? -1 : 1; + return bkey_cmp(l->pos, r->pos); +} + #define for_each_btree_node(_iter, _c, _btree_id, _start, _b) \ for (bch_btree_iter_init((_iter), (_c), (_btree_id), _start), \ (_iter)->is_extents = false, \ diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index c480c9647ef9..001066763dcf 100644 --- a/drivers/md/bcache/btree_update.c +++ b/drivers/md/bcache/btree_update.c @@ -1532,9 +1532,7 @@ static int btree_trans_iter_cmp(const void *_l, const void *_r) const struct btree_insert_trans *l = _l; const struct btree_insert_trans *r = _r; - if (l->iter->btree_id != r->iter->btree_id) - return l->iter->btree_id < r->iter->btree_id ? -1 : 1; - return bkey_cmp(l->iter->pos, r->iter->pos); + return btree_iter_cmp(l->iter, r->iter); } /* Normal update interface: */ |