On Fri, Sep 15, 2023 at 03:57:34PM +0300, Dan Carpenter wrote:
> Hello Kent Overstreet,
> 
> The patch 93a640e2570b: "bcachefs: GFP_NOIO -> GFP_NOFS" from May 28,
> 2023 (linux-next), leads to the following Smatch static checker
> warning:
> 
> fs/bcachefs/journal_io.c:1461 journal_buf_realloc() warn: sleeping in atomic 
> context
> fs/bcachefs/journal_io.c:1662 bch2_journal_entries_postprocess() warn: 
> sleeping in atomic context
> fs/bcachefs/journal_io.c:1764 bch2_journal_write() warn: sleeping in atomic 
> context
> fs/bcachefs/journal_io.c:788 jset_validate() warn: sleeping in atomic context
> fs/bcachefs/replicas.c:439 bch2_mark_replicas() warn: sleeping in atomic 
> context
> 
> All this sleeping in atomic warnings start in journal_write_done()
> where it takes spin_lock(&j->lock) so preempt is disabled.


>From 0528bebd8b42ce43a39da8e911bf21825f5085dd Mon Sep 17 00:00:00 2001
From: Kent Overstreet <[email protected]>
Date: Tue, 19 Sep 2023 22:36:30 -0400
Subject: [PATCH] bcachefs: drop journal lock before calling journal_write

bch2_journal_write() expects process context, it takes journal_lock as
needed.

Reported-by: Dan Carpenter <[email protected]>
Signed-off-by: Kent Overstreet <[email protected]>

diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c
index 269c8e8a1d95..6a3d6a374e9c 100644
--- a/fs/bcachefs/journal_io.c
+++ b/fs/bcachefs/journal_io.c
@@ -1554,6 +1554,7 @@ static void journal_write_done(struct closure *cl)
 
        if (!journal_state_count(new, new.unwritten_idx) &&
            journal_last_unwritten_seq(j) <= journal_cur_seq(j)) {
+               spin_unlock(&j->lock);
                closure_call(&j->io, bch2_journal_write, c->io_complete_wq, 
NULL);
        } else if (journal_last_unwritten_seq(j) == journal_cur_seq(j) &&
                   new.cur_entry_offset < JOURNAL_ENTRY_CLOSED_VAL) {
@@ -1566,10 +1567,11 @@ static void journal_write_done(struct closure *cl)
                 * might want to be written now:
                 */
 
+               spin_unlock(&j->lock);
                mod_delayed_work(c->io_complete_wq, &j->write_work, max(0L, 
delta));
+       } else {
+               spin_unlock(&j->lock);
        }
-
-       spin_unlock(&j->lock);
 }
 
 static void journal_write_endio(struct bio *bio)

Reply via email to