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 7f0485dd30 ("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 <weizhu@fiu.edu>
Signed-off-by: Chao Shi <coshi036@gmail.com>
Link: https://patch.msgid.link/970d8b9603d4620ab73038f49bc36831e37e00a0.1785951556.git.coshi036@gmail.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
Chao Shi 2026-08-06 12:58:42 -04:00 committed by Christian Brauner
parent b1c88ae0b5
commit 8ed37e18b9
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2

View File

@ -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;
}