bcachefs: Improved debug checks
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 17 Aug 2019 19:17:09 +0000 (15:17 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:25 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bset.c
fs/bcachefs/btree_iter.c

index 68442a26756fd95d3c51e9bef752e48cc230b378..78e6fd3f1306b27aa4a3ef7571eab504d4176133 100644 (file)
 static inline void __bch2_btree_node_iter_advance(struct btree_node_iter *,
                                                  struct btree *);
 
+static inline unsigned __btree_node_iter_used(struct btree_node_iter *iter)
+{
+       unsigned n = ARRAY_SIZE(iter->data);
+
+       while (n && __btree_node_iter_set_end(iter, n - 1))
+               --n;
+
+       return n;
+}
+
 struct bset_tree *bch2_bkey_to_bset(struct btree *b, struct bkey_packed *k)
 {
        return bch2_bkey_to_bset_inlined(b, k);
@@ -98,7 +108,8 @@ void bch2_dump_btree_node_iter(struct btree *b,
 {
        struct btree_node_iter_set *set;
 
-       printk(KERN_ERR "btree node iter with %u sets:\n", b->nsets);
+       printk(KERN_ERR "btree node iter with %u/%u sets:\n",
+              __btree_node_iter_used(iter), b->nsets);
 
        btree_node_iter_for_each(iter, set) {
                struct bkey_packed *k = __btree_node_offset_to_key(b, set->k);
@@ -107,8 +118,8 @@ void bch2_dump_btree_node_iter(struct btree *b,
                char buf[100];
 
                bch2_bkey_to_text(&PBUF(buf), &uk);
-               printk(KERN_ERR "set %zu key %zi/%u: %s\n", t - b->set,
-                      k->_data - bset(b, t)->_data, bset(b, t)->u64s, buf);
+               printk(KERN_ERR "set %zu key %u: %s\n",
+                      t - b->set, set->k, buf);
        }
 }
 
@@ -170,8 +181,12 @@ void bch2_btree_node_iter_verify(struct btree_node_iter *iter,
                                 struct btree *b)
 {
        struct btree_node_iter_set *set, *s2;
+       struct bkey_packed *k, *p;
        struct bset_tree *t;
 
+       if (bch2_btree_node_iter_end(iter))
+               return;
+
        /* Verify no duplicates: */
        btree_node_iter_for_each(iter, set)
                btree_node_iter_for_each(iter, s2)
@@ -192,6 +207,18 @@ found:
        btree_node_iter_for_each(iter, set)
                BUG_ON(set != iter->data &&
                       btree_node_iter_cmp(b, set[-1], set[0]) > 0);
+
+       k = bch2_btree_node_iter_peek_all(iter, b);
+
+       for_each_bset(b, t) {
+               if (iter->data[0].end == t->end_offset)
+                       continue;
+
+               p = bch2_bkey_prev_all(b, t,
+                       bch2_btree_node_iter_bset_pos(iter, b, t));
+
+               BUG_ON(p && bkey_iter_cmp(b, k, p) < 0);
+       }
 }
 
 void bch2_verify_insert_pos(struct btree *b, struct bkey_packed *where,
@@ -1652,16 +1679,6 @@ void bch2_btree_node_iter_advance(struct btree_node_iter *iter,
        __bch2_btree_node_iter_advance(iter, b);
 }
 
-static inline unsigned __btree_node_iter_used(struct btree_node_iter *iter)
-{
-       unsigned n = ARRAY_SIZE(iter->data);
-
-       while (n && __btree_node_iter_set_end(iter, n - 1))
-               --n;
-
-       return n;
-}
-
 /*
  * Expensive:
  */
index a91d655035efea72efb0269093e13cf81e7afca6..a702eb3bbefb98250c0ca257d3a92da1babdc3cb 100644 (file)
@@ -1477,6 +1477,8 @@ recheck:
                EBUG_ON(bkey_cmp(k.k->p, iter->pos) < 0);
                EBUG_ON(bkey_deleted(k.k));
                iter->uptodate = BTREE_ITER_UPTODATE;
+
+               __bch2_btree_iter_verify(iter, l->b);
                return k;
        }
 
@@ -1507,6 +1509,8 @@ recheck:
 
        iter->k = n;
        iter->uptodate = BTREE_ITER_UPTODATE;
+
+       __bch2_btree_iter_verify(iter, l->b);
        return (struct bkey_s_c) { &iter->k, NULL };
 }
 
@@ -1539,19 +1543,18 @@ recheck:
                goto recheck;
        }
 
-       if (k.k &&
-           !bkey_deleted(k.k) &&
-           !bkey_cmp(iter->pos, k.k->p)) {
-               iter->uptodate = BTREE_ITER_UPTODATE;
-               return k;
-       } else {
+       if (!k.k ||
+           bkey_deleted(k.k) ||
+           bkey_cmp(iter->pos, k.k->p)) {
                /* hole */
                bkey_init(&iter->k);
                iter->k.p = iter->pos;
-
-               iter->uptodate = BTREE_ITER_UPTODATE;
-               return (struct bkey_s_c) { &iter->k, NULL };
+               k = (struct bkey_s_c) { &iter->k, NULL };
        }
+
+       iter->uptodate = BTREE_ITER_UPTODATE;
+       __bch2_btree_iter_verify(iter, l->b);
+       return k;
 }
 
 struct bkey_s_c bch2_btree_iter_peek_slot(struct btree_iter *iter)