In bch2_bkey_pick_read_device, we're in an RCU lock. So, we can't call any potentially-sleeping functions. However, we call bch2_dev_rcu, which calls bch2_fs_inconsistent in its error case. That then calls bch2_prt_print on a non-atomic printbuf, as well as uses the blocking variant of bch2_print_string_as_lines, both of which lead to calls to potentially-sleeping functions, namely krealloc with GFP_KERNEL and console_lock respectively.
Give a nonzero atomic to the printbuf, and use the nonblocking variant of bch2_print_string_as_lines. Reported-by: [email protected] Closes: https://syzkaller.appspot.com/bug?extid=c82cd2906e2f192410bb Signed-off-by: Bharadwaj Raju <[email protected]> --- fs/bcachefs/error.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c index d4dfd13a8076..6f0f2f12c004 100644 --- a/fs/bcachefs/error.c +++ b/fs/bcachefs/error.c @@ -60,6 +60,8 @@ static bool bch2_fs_trans_inconsistent(struct bch_fs *c, struct btree_trans *tra { struct printbuf buf = PRINTBUF; + buf.atomic++; + bch2_log_msg_start(c, &buf); prt_vprintf(&buf, fmt, args); @@ -68,7 +70,9 @@ static bool bch2_fs_trans_inconsistent(struct bch_fs *c, struct btree_trans *tra if (trans) bch2_trans_updates_to_text(&buf, trans); bool ret = __bch2_inconsistent_error(c, &buf); - bch2_print_string_as_lines(KERN_ERR, buf.buf); + bch2_print_string_as_lines_nonblocking(KERN_ERR, buf.buf); + + buf.atomic--; printbuf_exit(&buf); return ret; -- 2.49.0
