diff options
-rw-r--r-- | drivers/md/bcache/bset.c | 13 | ||||
-rw-r--r-- | drivers/md/bcache/btree_iter.c | 69 | ||||
-rw-r--r-- | drivers/md/bcache/btree_update.c | 10 |
3 files changed, 67 insertions, 25 deletions
diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index 83d3347c2159..c4bf087235c6 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c @@ -206,8 +206,17 @@ void bch_verify_key_order(struct btree_keys *b, struct bkey uk, uw = bkey_unpack_key(f, where); k = bkey_prev_all(t, where); - BUG_ON(k && - keys_out_of_order(f, k, where, b->ops->is_extents)); + if (k && + keys_out_of_order(f, k, where, b->ops->is_extents)) { + char buf1[100], buf2[100]; + + bch_dump_bucket(b); + uk = bkey_unpack_key(f, k); + bch_bkey_to_text(buf1, sizeof(buf1), &uk); + bch_bkey_to_text(buf2, sizeof(buf2), &uw); + panic("out of order with prev:\n%s\n%s\n", + buf1, buf2); + } k = bkey_next(where); BUG_ON(k != bset_bkey_last(t->data) && diff --git a/drivers/md/bcache/btree_iter.c b/drivers/md/bcache/btree_iter.c index 0a9c2487fa7a..a0d7a204b03c 100644 --- a/drivers/md/bcache/btree_iter.c +++ b/drivers/md/bcache/btree_iter.c @@ -303,12 +303,26 @@ static void __bch_btree_iter_verify(struct btree_iter *iter, k = b->level ? bch_btree_node_iter_prev(&tmp, &b->keys) : bch_btree_node_iter_prev_all(&tmp, &b->keys); - BUG_ON(k && btree_iter_pos_cmp_packed(f, iter->pos, k, - iter->is_extents)); + if (k && btree_iter_pos_cmp_packed(f, iter->pos, k, + iter->is_extents)) { + char buf[100]; + struct bkey uk = bkey_unpack_key(&b->keys.format, k); + + bch_bkey_to_text(buf, sizeof(buf), &uk); + panic("prev key should be before after pos:\n%s\n%llu:%llu\n", + buf, iter->pos.inode, iter->pos.offset); + } k = bch_btree_node_iter_peek_all(node_iter, &b->keys); - BUG_ON(k && !btree_iter_pos_cmp_packed(f, iter->pos, k, - iter->is_extents)); + if (k && !btree_iter_pos_cmp_packed(f, iter->pos, k, + iter->is_extents)) { + char buf[100]; + struct bkey uk = bkey_unpack_key(&b->keys.format, k); + + bch_bkey_to_text(buf, sizeof(buf), &uk); + panic("next key should be before iter pos:\n%llu:%llu\n%s\n", + iter->pos.inode, iter->pos.offset, buf); + } } void bch_btree_iter_verify(struct btree_iter *iter, struct btree *b) @@ -451,7 +465,10 @@ void bch_btree_node_iter_fix(struct btree_iter *iter, __bch_btree_node_iter_fix(linked, b, &linked->node_iters[b->level], t, where, clobber_u64s, new_u64s); - bch_btree_iter_verify(iter, b); + + /* interior node iterators are... special... */ + if (!b->level) + bch_btree_iter_verify(iter, b); } /* peek_all() doesn't skip deleted keys */ @@ -522,14 +539,33 @@ static void btree_iter_verify_new_node(struct btree_iter *iter, struct btree *b) k = bch_btree_node_iter_peek_all(&iter->node_iters[b->level + 1], &iter->nodes[b->level + 1]->keys); - BUG_ON(!k || - bkey_cmp_left_packed(&iter->nodes[b->level + 1]->keys.format, - k, b->key.k.p)); + if (!k || + bkey_deleted(k) || + bkey_cmp_left_packed(&iter->nodes[b->level + 1]->keys.format, + k, b->key.k.p)) { + char buf[100]; + struct bkey uk = bkey_unpack_key(&b->keys.format, k); + + bch_bkey_to_text(buf, sizeof(buf), &uk); + panic("parent iter doesn't point to new node:\n%s\n%llu:%llu\n", + buf, b->key.k.p.inode, b->key.k.p.offset); + } if (!parent_locked) btree_node_unlock(iter, b->level + 1); } +static inline void __btree_iter_init(struct btree_iter *iter, + struct btree *b) +{ + bch_btree_node_iter_init(&iter->node_iters[b->level], &b->keys, + iter->pos, iter->is_extents); + + /* Skip to first non whiteout: */ + if (b->level) + bch_btree_node_iter_peek(&iter->node_iters[b->level], &b->keys); +} + static inline void btree_iter_node_set(struct btree_iter *iter, struct btree *b) { @@ -539,8 +575,7 @@ static inline void btree_iter_node_set(struct btree_iter *iter, iter->lock_seq[b->level] = b->lock.state.seq; iter->nodes[b->level] = b; - bch_btree_node_iter_init(&iter->node_iters[b->level], &b->keys, - iter->pos, iter->is_extents); + __btree_iter_init(iter, b); } static bool btree_iter_pos_in_node(struct btree_iter *iter, struct btree *b) @@ -628,13 +663,8 @@ void bch_btree_iter_reinit_node(struct btree_iter *iter, struct btree *b) struct btree_iter *linked; for_each_linked_btree_node(iter, b, linked) - bch_btree_node_iter_init(&linked->node_iters[b->level], - &linked->nodes[b->level]->keys, - linked->pos, linked->is_extents); - - bch_btree_node_iter_init(&iter->node_iters[b->level], - &iter->nodes[b->level]->keys, - iter->pos, iter->is_extents); + __btree_iter_init(linked, b); + __btree_iter_init(iter, b); } static inline int btree_iter_lock_root(struct btree_iter *iter, @@ -987,10 +1017,7 @@ void bch_btree_iter_rewind(struct btree_iter *iter, struct bpos pos) BUG_ON(bkey_cmp(pos, iter->nodes[iter->level]->data->min_key) < 0); iter->pos = pos; - - bch_btree_node_iter_init(&iter->node_iters[iter->level], - &iter->nodes[iter->level]->keys, - pos, iter->is_extents); + __btree_iter_init(iter, iter->nodes[iter->level]); } struct bkey_s_c bch_btree_iter_peek(struct btree_iter *iter) diff --git a/drivers/md/bcache/btree_update.c b/drivers/md/bcache/btree_update.c index b621f411147d..8a6ea6e180c6 100644 --- a/drivers/md/bcache/btree_update.c +++ b/drivers/md/bcache/btree_update.c @@ -678,8 +678,6 @@ overwrite: if (k->u64s != clobber_u64s || bkey_deleted(&insert->k)) bch_btree_node_iter_fix(iter, b, node_iter, t, k, clobber_u64s, k->u64s); - else - bch_btree_iter_verify(iter, b); } static void btree_node_flush(struct journal *j, struct journal_entry_pin *pin) @@ -1095,6 +1093,7 @@ bch_btree_insert_keys_interior(struct btree *b, struct btree_interior_update *as, struct btree_reserve *res) { + struct btree_iter *linked; struct btree_node_iter node_iter; const struct bkey_format *f = &b->keys.format; struct bkey_i *insert = bch_keylist_front(insert_keys); @@ -1135,6 +1134,13 @@ bch_btree_insert_keys_interior(struct btree *b, btree_interior_update_updated_btree(iter->c, as, b); + for_each_linked_btree_node(iter, b, linked) + bch_btree_node_iter_peek(&linked->node_iters[b->level], + &b->keys); + bch_btree_node_iter_peek(&iter->node_iters[b->level], &b->keys); + + bch_btree_iter_verify(iter, b); + if (bch_maybe_compact_deleted_keys(&b->keys)) bch_btree_iter_reinit_node(iter, b); |