From 8ed37e18b915a36bf382873833656c181d1fb942 Mon Sep 17 00:00:00 2001 From: Chao Shi Date: Thu, 6 Aug 2026 12:58:42 -0400 Subject: [PATCH] jbd2: check for a fast commit write error with buffer_write_io_error() jbd2_fc_wait_bufs() decides whether ext4's fast commit blocks reached the disk by looking at BH_Uptodate once the write has completed. That relies on the write completion handler clearing BH_Uptodate on error, which this series removes: a buffer whose write failed still holds the data the filesystem asked to be written, so declaring it not up to date is wrong and makes callers rewrite or re-read it. Test BH_Write_EIO instead. Nothing is needed on the producer side. These buffers used to be submitted by ext4_fc_submit_bh() with a private completion handler that cleared BH_Uptodate, but commit 7f0485dd3017 ("ext4: remove ext4_end_buffer_io_sync()") dropped it in favour of bh_end_write(), which already reports a failed write with mark_buffer_write_io_error(). The wait in jbd2 is the only half left to convert. A stale flag from an earlier write cannot fool the new test. jbd2_fc_get_buf() looks the buffer up with __getblk() at a fixed block on the journal device, so the same buffer comes back commit after commit, but __bh_submit() clears BH_Write_EIO when it resubmits a buffer for writing. The flag jbd2_fc_wait_bufs() sees always belongs to the write it just waited for. No behaviour change today - bh_end_write() sets BH_Write_EIO and clears BH_Uptodate together. It stops being a no-op at the end of the series, where the new test is the one that still works. Acked-by: Weidong Zhu Signed-off-by: Chao Shi Link: https://patch.msgid.link/970d8b9603d4620ab73038f49bc36831e37e00a0.1785951556.git.coshi036@gmail.com Reviewed-by: Jan Kara Signed-off-by: Christian Brauner (Amutable) --- fs/jbd2/journal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index a4f63d738337..cda1ff8851dc 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -887,7 +887,7 @@ int jbd2_fc_wait_bufs(journal_t *journal, int num_blks) * Update j_fc_off so jbd2_fc_release_bufs can release remain * buffer head. */ - if (unlikely(!buffer_uptodate(bh))) { + if (unlikely(buffer_write_io_error(bh))) { journal->j_fc_off = i + 1; return -EIO; }