return iter->uptodate < BTREE_ITER_NEED_RELOCK;
}
+static struct bpos btree_node_pos(struct btree_bkey_cached_common *_b,
+ enum btree_iter_type type)
+{
+ return type != BTREE_ITER_CACHED
+ ? container_of(_b, struct btree, c)->key.k.p
+ : container_of(_b, struct bkey_cached, c)->key.pos;
+}
+
/* Slowpath: */
bool __bch2_btree_node_lock(struct btree *b, struct bpos pos,
unsigned level, struct btree_iter *iter,
if (iter->btree_id == linked->btree_id &&
btree_node_locked(linked, level) &&
- bkey_cmp(pos, linked->l[level].b->key.k.p) <= 0)
+ bkey_cmp(pos, btree_node_pos((void *) linked->l[level].b,
+ btree_iter_type(linked))) <= 0)
ret = false;
/*
#ifdef CONFIG_BCACHEFS_DEBUG
+static void bch2_btree_iter_verify_cached(struct btree_iter *iter)
+{
+ struct bkey_cached *ck;
+ bool locked = btree_node_locked(iter, 0);
+
+ if (!bch2_btree_node_relock(iter, 0))
+ return;
+
+ ck = (void *) iter->l[0].b;
+ BUG_ON(ck->key.btree_id != iter->btree_id ||
+ bkey_cmp(ck->key.pos, iter->pos));
+
+ if (!locked)
+ btree_node_unlock(iter, 0);
+}
+
static void bch2_btree_iter_verify_level(struct btree_iter *iter,
unsigned level)
{
if (!debug_check_iterators(iter->trans->c))
return;
+ if (btree_iter_type(iter) == BTREE_ITER_CACHED) {
+ if (!level)
+ bch2_btree_iter_verify_cached(iter);
+ return;
+ }
+
BUG_ON(iter->level < iter->min_depth);
if (!btree_iter_node(iter, level))
return ret;
}
-static inline void bch2_btree_iter_checks(struct btree_iter *iter,
- enum btree_iter_type type)
+static inline void bch2_btree_iter_checks(struct btree_iter *iter)
{
+ enum btree_iter_type type = btree_iter_type(iter);
+
EBUG_ON(iter->btree_id >= BTREE_ID_NR);
- EBUG_ON(btree_iter_type(iter) != type);
- BUG_ON(type == BTREE_ITER_KEYS &&
+ BUG_ON((type == BTREE_ITER_KEYS ||
+ type == BTREE_ITER_CACHED) &&
(bkey_cmp(iter->pos, bkey_start_pos(&iter->k)) < 0 ||
bkey_cmp(iter->pos, iter->k.p) > 0));
struct btree *b;
int ret;
- bch2_btree_iter_checks(iter, BTREE_ITER_NODES);
+ EBUG_ON(btree_iter_type(iter) != BTREE_ITER_NODES);
+ bch2_btree_iter_checks(iter);
if (iter->uptodate == BTREE_ITER_UPTODATE)
return iter->l[iter->level].b;
struct btree *b;
int ret;
- bch2_btree_iter_checks(iter, BTREE_ITER_NODES);
+ EBUG_ON(btree_iter_type(iter) != BTREE_ITER_NODES);
+ bch2_btree_iter_checks(iter);
/* already got to end? */
if (!btree_iter_node(iter, iter->level))
struct bkey_s_c k;
int ret;
- bch2_btree_iter_checks(iter, BTREE_ITER_KEYS);
+ EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
+ bch2_btree_iter_checks(iter);
if (iter->uptodate == BTREE_ITER_UPTODATE &&
!bkey_deleted(&iter->k))
struct bkey_s_c k;
int ret;
- bch2_btree_iter_checks(iter, BTREE_ITER_KEYS);
+ EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
+ bch2_btree_iter_checks(iter);
while (1) {
ret = bch2_btree_iter_traverse(iter);
struct bkey_s_c k;
int ret;
- bch2_btree_iter_checks(iter, BTREE_ITER_KEYS);
+ EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
+ bch2_btree_iter_checks(iter);
if (iter->uptodate == BTREE_ITER_UPTODATE &&
!bkey_deleted(&iter->k))
{
struct bpos pos = bkey_start_pos(&iter->k);
- bch2_btree_iter_checks(iter, BTREE_ITER_KEYS);
+ EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
+ bch2_btree_iter_checks(iter);
if (unlikely(!bkey_cmp(pos, POS_MIN)))
return bkey_s_c_null;
struct bkey_s_c k;
int ret;
- bch2_btree_iter_checks(iter, BTREE_ITER_KEYS);
+ EBUG_ON(btree_iter_type(iter) != BTREE_ITER_KEYS);
+ bch2_btree_iter_checks(iter);
if (iter->uptodate == BTREE_ITER_UPTODATE)
return btree_iter_peek_uptodate(iter);
struct bkey_cached *ck;
int ret;
- bch2_btree_iter_checks(iter, BTREE_ITER_CACHED);
+ EBUG_ON(btree_iter_type(iter) != BTREE_ITER_CACHED);
+ bch2_btree_iter_checks(iter);
ret = bch2_btree_iter_traverse(iter);
if (unlikely(ret))
return trans->error ? -EIO : 0;
}
+static void bch2_btree_iter_node_to_text(struct printbuf *out,
+ struct btree_bkey_cached_common *_b,
+ enum btree_iter_type type)
+{
+ pr_buf(out, " %px l=%u %s:",
+ _b, _b->level, bch2_btree_ids[_b->btree_id]);
+ bch2_bpos_to_text(out, btree_node_pos(_b, type));
+}
+
void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c)
{
#ifdef CONFIG_BCACHEFS_DEBUG
for (l = 0; l < BTREE_MAX_DEPTH; l++) {
if (btree_node_locked(iter, l)) {
- b = iter->l[l].b;
-
- pr_buf(out, " %px %s l=%u ",
- b, btree_node_intent_locked(iter, l) ? "i" : "r", l);
- bch2_bpos_to_text(out, b->key.k.p);
+ pr_buf(out, " %s l=%u ",
+ btree_node_intent_locked(iter, l) ? "i" : "r", l);
+ bch2_btree_iter_node_to_text(out,
+ (void *) iter->l[l].b,
+ btree_iter_type(iter));
pr_buf(out, "\n");
}
}
bch2_btree_ids[trans->locking_btree_id]);
bch2_bpos_to_text(out, trans->locking_pos);
- pr_buf(out, " node %px l=%u %s:",
- b, b->c.level,
- bch2_btree_ids[b->c.btree_id]);
- bch2_bpos_to_text(out, b->key.k.p);
+
+ pr_buf(out, " node ");
+ bch2_btree_iter_node_to_text(out,
+ (void *) b,
+ btree_iter_type(&trans->iters[trans->locking_iter_idx]));
pr_buf(out, "\n");
}
}