bcachefs: Check if stuck in journal_res_get()
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 7 Oct 2024 20:55:34 +0000 (16:55 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 9 Oct 2024 20:57:59 +0000 (16:57 -0400)
Like how we already do when the allocator seems to be stuck, check if
we're waiting too long for a journal reservation and print some debug
info.

This is specifically to track down
https://github.com/koverstreet/bcachefs/issues/656

which is showing up in userspace where we don't have sysfs/debugfs to
get the journal debug info.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/journal.c

index f5f7db5..dc099f0 100644 (file)
@@ -603,6 +603,19 @@ int bch2_journal_res_get_slowpath(struct journal *j, struct journal_res *res,
 {
        int ret;
 
+       if (closure_wait_event_timeout(&j->async_wait,
+                  (ret = __journal_res_get(j, res, flags)) != -BCH_ERR_journal_res_get_blocked ||
+                  (flags & JOURNAL_RES_GET_NONBLOCK),
+                  HZ * 10))
+               return ret;
+
+       struct bch_fs *c = container_of(j, struct bch_fs, journal);
+       struct printbuf buf = PRINTBUF;
+       bch2_journal_debug_to_text(&buf, j);
+       bch_err(c, "Journal stuck? Waited for 10 seconds...\n%s",
+               buf.buf);
+       printbuf_exit(&buf);
+
        closure_wait_event(&j->async_wait,
                   (ret = __journal_res_get(j, res, flags)) != -BCH_ERR_journal_res_get_blocked ||
                   (flags & JOURNAL_RES_GET_NONBLOCK));