bcachefs: Fix more lockdep splats in debug.c
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 21 Jun 2023 10:44:44 +0000 (06:44 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:10:04 +0000 (17:10 -0400)
Similar to previous fixes, we can't incur page faults while holding
btree locks.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_iter.h
fs/bcachefs/debug.c
fs/bcachefs/errcode.h
fs/bcachefs/io.c

index d2af3f38e6f524f66bfd0dc109dc10c41145191b..9ef9527dda6bc7d9e625e545ea2ceb69b7c9b0fb 100644 (file)
@@ -286,7 +286,7 @@ __always_inline
 static inline int btree_trans_restart_nounlock(struct btree_trans *trans, int err)
 {
        BUG_ON(err <= 0);
-       BUG_ON(!bch2_err_matches(err, BCH_ERR_transaction_restart));
+       BUG_ON(!bch2_err_matches(-err, BCH_ERR_transaction_restart));
 
        trans->restarted = err;
        trans->last_restarted_ip = _THIS_IP_;
index df0e14dc96e6d81228bc23e39d894a030cb94389..ae47e1854b80a217c46c49236275afcf90f20ca7 100644 (file)
@@ -378,26 +378,25 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
        i->size = size;
        i->ret  = 0;
 
-       bch2_trans_init(&trans, i->c, 0, 0);
+       ret = flush_buf(i);
+       if (ret)
+               return ret;
 
+       bch2_trans_init(&trans, i->c, 0, 0);
        ret = for_each_btree_key2(&trans, iter, i->id, i->from,
                                  BTREE_ITER_PREFETCH|
                                  BTREE_ITER_ALL_SNAPSHOTS, k, ({
-               ret = flush_buf(i);
-               if (ret)
-                       break;
-
                bch2_bkey_val_to_text(&i->buf, i->c, k);
                prt_newline(&i->buf);
-               0;
+               drop_locks_do(&trans, flush_buf(i));
        }));
        i->from = iter.pos;
 
+       bch2_trans_exit(&trans);
+
        if (!ret)
                ret = flush_buf(i);
 
-       bch2_trans_exit(&trans);
-
        return ret ?: i->ret;
 }
 
@@ -429,19 +428,24 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
                return i->ret;
 
        bch2_trans_init(&trans, i->c, 0, 0);
+retry:
+       bch2_trans_begin(&trans);
 
        for_each_btree_node(&trans, iter, i->id, i->from, 0, b, ret) {
-               ret = flush_buf(i);
-               if (ret)
-                       break;
-
                bch2_btree_node_to_text(&i->buf, i->c, b);
                i->from = !bpos_eq(SPOS_MAX, b->key.k.p)
                        ? bpos_successor(b->key.k.p)
                        : b->key.k.p;
+
+               ret = drop_locks_do(&trans, flush_buf(i));
+               if (ret)
+                       break;
        }
        bch2_trans_iter_exit(&trans, &iter);
 
+       if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
+               goto retry;
+
        bch2_trans_exit(&trans);
 
        if (!ret)
@@ -483,17 +487,13 @@ static ssize_t bch2_read_bfloat_failed(struct file *file, char __user *buf,
                struct bkey_packed *_k =
                        bch2_btree_node_iter_peek(&l->iter, l->b);
 
-               ret = flush_buf(i);
-               if (ret)
-                       break;
-
                if (bpos_gt(l->b->key.k.p, i->prev_node)) {
                        bch2_btree_node_to_text(&i->buf, i->c, l->b);
                        i->prev_node = l->b->key.k.p;
                }
 
                bch2_bfloat_to_text(&i->buf, l->b, _k);
-               0;
+               drop_locks_do(&trans, flush_buf(i));
        }));
        i->from = iter.pos;
 
index 12c0c44eb6b0338c0b20569ed24044c24e9e01e8..621ff46472055e5603da3edff9db0b11ccc5317b 100644 (file)
@@ -224,7 +224,7 @@ bool __bch2_err_matches(int, int);
 
 static inline bool _bch2_err_matches(int err, int class)
 {
-       return err && __bch2_err_matches(err, class);
+       return err < 0 && __bch2_err_matches(err, class);
 }
 
 #define bch2_err_matches(_err, _class)                 \
index 25a9f657910c6ede0509af8e1f3b83cdfb67d5ea..0f5cbfa78b71dd1f98a8312442f66bff90b32fe4 100644 (file)
@@ -1645,7 +1645,7 @@ err_bucket_stale:
                percpu_ref_put(&bch_dev_bkey_exists(c, buckets[i].b.inode)->io_ref);
 
        /* We can retry this: */
-       ret = BCH_ERR_transaction_restart;
+       ret = -BCH_ERR_transaction_restart;
        goto out;
 }