Re: [PATCH 19/19] buffer: stop clearing BH_Uptodate when a write fails
Zhang Yi <[email protected]> Wed, 5 Aug 2026 18:55:20 +0800
| Newsgroups | dev.linux.lists.gfs2,dev.linux.lists.ocfs2-devel,org.kernel.vger.linux-ext4,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 8/5/2026 5:00 PM, Jan Kara wrote: > On Wed 05-08-26 12:52:11, Zhang Yi wrote: >> On 8/2/2026 6:01 AM, Chao Shi wrote: >>> A buffer whose write failed still holds exactly the data the filesystem >>> asked to be written. It is the disk that is out of date, not the buffer. >>> Clearing BH_Uptodate says the opposite, and callers act on it: >>> >>> - mark_buffer_dirty() has a WARN_ON_ONCE(!buffer_uptodate(bh)). A >>> filesystem that dirties the buffer again after a failed write - which is >>> the normal way to retry - trips it. That is the warning this series >>> started from. >>> >>> - a buffer that is not up to date gets re-read from disk, which replaces >>> the data the filesystem was trying to write with the stale on-disk copy, >>> silently. >>> >>> - the window between the write completing and the buffer being marked not >>> up to date is visible to anyone holding the folio lock, so the state is >>> not even self consistent while it lasts. >>> >>> BH_Write_EIO already records the failure, and by now every place in the >>> tree that needs to know about it tests that flag instead: the two core >>> helpers in this file, adfs, exfat, ext2, ext4, fat, gfs2, jbd2, ocfs2 and >>> omfs, converted one filesystem at a time in the preceding patches. The >>> private completion handlers in jbd2 and ext4 fast commit were converted >>> along with their waiters. Nothing is left that reads BH_Uptodate to find >>> out whether a write failed, so the clears can go. >>> >>> Found by FuzzNvme. >>> >>> Signed-off-by: Chao Shi <[email protected]> >> >> It looks like after this series, we may need to revisit the necessity of >> ext4_buffer_uptodate() in the ext4 filesystem. IIRC, it was originally >> introduced as a compromise to address this issue. Now that we no longer >> clear the buffer uptodate flag after a failed IO write, this flag will >> still remain valid when getting/reading bh. Therefore, the necessity of >> ext4_buffer_uptodate() is worth reconsidering. > > Deninitely :) There are several hacks in ext4 (and other filesystems as > well) that could be removed after this patch set. But let's settle on the > generic changes first. > > Honza Yeah, that would be great! Best Regards, Yi. > >>> --- >>> fs/buffer.c | 2 -- >>> 1 file changed, 2 deletions(-) >>> >>> diff --git a/fs/buffer.c b/fs/buffer.c >>> index ac978d9090c2..0002f0736398 100644 >>> --- a/fs/buffer.c >>> +++ b/fs/buffer.c >>> @@ -207,7 +207,6 @@ void bh_end_write(struct bio *bio) >>> } else { >>> buffer_io_error(bh, ", lost sync page write"); >>> mark_buffer_write_io_error(bh); >>> - clear_buffer_uptodate(bh); >>> } >>> unlock_buffer(bh); >>> } >>> @@ -441,7 +440,6 @@ void bh_end_async_write(struct bio *bio) >>> } else { >>> buffer_io_error(bh, ", lost async page write"); >>> mark_buffer_write_io_error(bh); >>> - clear_buffer_uptodate(bh); >>> } >>> >>> first = folio_buffers(folio); >>