From: Kent Overstreet Date: Mon, 15 Nov 2021 22:30:11 +0000 (-0500) Subject: bcachefs: Fix error reporting from bch2_journal_flush_seq X-Git-Tag: v6.7-rc1~201^2~1285 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9be1efe9c57e3eed5fc569caee47d0ddc96530db;p=thirdparty%2Fkernel%2Flinux.git bcachefs: Fix error reporting from bch2_journal_flush_seq - bch2_journal_halt() was unconditionally overwriting j->err_seq, the sequence number that we failed to write - journal_write_done was updating seq_ondisk and flushed_seq_ondisk even for writes that errored, which broke the way bch2_journal_flush_seq_async() locklessly checked for completions. Signed-off-by: Kent Overstreet --- diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index 1ee012d94b4ae..56c477bbce0fb 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -106,7 +106,12 @@ void bch2_journal_halt(struct journal *j) } while ((v = atomic64_cmpxchg(&j->reservations.counter, old.v, new.v)) != old.v); - j->err_seq = journal_cur_seq(j); + /* + * XXX: we're not using j->lock here because this can be called from + * interrupt context, this can race with journal_write_done() + */ + if (!j->err_seq) + j->err_seq = journal_cur_seq(j); journal_wake(j); closure_wake_up(&journal_cur_buf(j)->wait); } diff --git a/fs/bcachefs/journal_io.c b/fs/bcachefs/journal_io.c index ed8d7f90b6071..0cd5ad3118e90 100644 --- a/fs/bcachefs/journal_io.c +++ b/fs/bcachefs/journal_io.c @@ -1258,14 +1258,15 @@ static void journal_write_done(struct closure *cl) if (seq >= j->pin.front) journal_seq_pin(j, seq)->devs = w->devs_written; - j->seq_ondisk = seq; - if (err && (!j->err_seq || seq < j->err_seq)) - j->err_seq = seq; + if (!err) { + j->seq_ondisk = seq; - if (!JSET_NO_FLUSH(w->data)) { - j->flushed_seq_ondisk = seq; - j->last_seq_ondisk = w->last_seq; - } + if (!JSET_NO_FLUSH(w->data)) { + j->flushed_seq_ondisk = seq; + j->last_seq_ondisk = w->last_seq; + } + } else if (!j->err_seq || seq < j->err_seq) + j->err_seq = seq; /* * Updating last_seq_ondisk may let bch2_journal_reclaim_work() discard diff --git a/fs/bcachefs/recovery.c b/fs/bcachefs/recovery.c index be89126055271..c3b4d116275cd 100644 --- a/fs/bcachefs/recovery.c +++ b/fs/bcachefs/recovery.c @@ -1480,7 +1480,7 @@ int bch2_fs_initialize(struct bch_fs *c) } err = "error writing first journal entry"; - ret = bch2_journal_meta(&c->journal); + ret = bch2_journal_flush(&c->journal); if (ret) goto err;