From: Chao Shi <coshi036@gmail.com>
To: Jan Kara <jack@suse.cz>, Christian Brauner <brauner@kernel.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Matthew Wilcox <willy@infradead.org>,
linux-fsdevel@vger.kernel.org
Cc: Theodore Ts'o <tytso@mit.edu>,
Andreas Dilger <adilger.kernel@dilger.ca>,
Baokun Li <libaokun@linux.alibaba.com>,
Ojaswin Mujoo <ojaswin@linux.ibm.com>,
Ritesh Harjani <ritesh.list@gmail.com>,
Zhang Yi <yi.zhang@huawei.com>,
Zhang Yi <yi.zhang@huaweicloud.com>,
Bob Copeland <me@bobcopeland.com>,
Namjae Jeon <linkinjeon@kernel.org>,
Sungjong Seo <sj1557.seo@samsung.com>,
Yuezhang Mo <yuezhang.mo@sony.com>,
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>,
Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>,
Joseph Qi <joseph.qi@linux.alibaba.com>,
Andreas Gruenbacher <agruenba@redhat.com>,
linux-ext4@vger.kernel.org, ocfs2-devel@lists.linux.dev,
gfs2@lists.linux.dev, linux-kernel@vger.kernel.org,
Chao Shi <coshi036@gmail.com>, Weidong Zhu <weizhu@fiu.edu>
Subject: [PATCH v2 20/21] buffer: stop touching BH_Uptodate on write completion
Date: Thu, 6 Aug 2026 12:58:43 -0400 [thread overview]
Message-ID: <61d7d5737f5773f53ee543f375fcde81aa8d28c2.1785951556.git.coshi036@gmail.com> (raw)
In-Reply-To: <cover.1785951556.git.coshi036@gmail.com>
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.
Setting BH_Uptodate on success goes too. A buffer has to be up to date
before it can be written - you cannot write out data you do not have - so
the only thing that assignment could do is paper over a caller that got
that wrong. Write completion now leaves BH_Uptodate alone in both
directions.
What this changes for readers. A buffer whose write failed stays up to
date, so the read paths stop replacing it with the on-disk copy:
__bread_gfp() no longer sends it to __bread_slow(), and
bh_uptodate_or_lock() reports it as usable. That is the intent. ocfs2
changes the most, because ocfs2_read_blocks() decides whether to go to disk
on its own cluster uptodate cache and only tests BH_Uptodate after the
wait, so a block whose write failed makes that read return -EIO today and
from here it succeeds and hands back the in-memory data. A caller that
needs to know the write failed asks BH_Write_EIO.
Found by FuzzNvme.
Acked-by: Weidong Zhu <weizhu@fiu.edu>
Signed-off-by: Chao Shi <coshi036@gmail.com>
---
fs/buffer.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/fs/buffer.c b/fs/buffer.c
index aebf74abbc49..425fbfe72ad1 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -202,12 +202,9 @@ void bh_end_write(struct bio *bio)
struct buffer_head *bh;
bool success = bio_endio_bh(bio, &bh);
- if (success) {
- set_buffer_uptodate(bh);
- } else {
+ if (!success) {
buffer_io_error(bh, ", lost sync page write");
mark_buffer_write_io_error(bh);
- clear_buffer_uptodate(bh);
}
unlock_buffer(bh);
}
@@ -436,12 +433,9 @@ void bh_end_async_write(struct bio *bio)
BUG_ON(!buffer_async_write(bh));
folio = bh->b_folio;
- if (success) {
- set_buffer_uptodate(bh);
- } else {
+ if (!success) {
buffer_io_error(bh, ", lost async page write");
mark_buffer_write_io_error(bh);
- clear_buffer_uptodate(bh);
}
first = folio_buffers(folio);
--
2.43.0
next prev parent reply other threads:[~2026-08-06 17:00 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 16:58 [PATCH v2 00/21] buffer: stop clearing BH_Uptodate when a write fails Chao Shi
2026-08-06 16:58 ` [PATCH v2 01/21] buffer_head: Remove b_page Chao Shi
2026-08-06 16:58 ` [PATCH v2 02/21] buffer: allow a buffer_head to point at memory outside the page cache Chao Shi
2026-08-06 16:58 ` [PATCH v2 03/21] jbd2: point the shadow buffer at the frozen data directly Chao Shi
2026-08-06 16:58 ` [PATCH v2 04/21] buffer: read the folio's mapping directly in buffer_set_crypto_ctx() Chao Shi
2026-08-06 16:58 ` [PATCH v2 05/21] buffer: clear BH_Write_EIO when a buffer is forgotten Chao Shi
2026-08-06 16:58 ` [PATCH v2 06/21] buffer: discard BH_Write_EIO along with the rest of the buffer state Chao Shi
2026-08-06 16:58 ` [PATCH v2 07/21] buffer: detect metadata write errors with buffer_write_io_error() Chao Shi
2026-08-06 16:58 ` [PATCH v2 08/21] adfs: check for a directory write error " Chao Shi
2026-08-06 16:58 ` [PATCH v2 09/21] ext2: check for an xattr block " Chao Shi
2026-08-06 16:58 ` [PATCH v2 10/21] omfs: check for an inode " Chao Shi
2026-08-06 16:58 ` [PATCH v2 11/21] exfat: check for a directory " Chao Shi
2026-08-06 16:58 ` [PATCH v2 12/21] fat: check for a metadata " Chao Shi
2026-08-06 16:58 ` [PATCH v2 13/21] ext4: " Chao Shi
2026-08-06 16:58 ` [PATCH v2 14/21] ocfs2: " Chao Shi
2026-08-06 16:58 ` [PATCH v2 15/21] ocfs2: check for a stale write error before reusing a metadata buffer Chao Shi
2026-08-06 16:58 ` [PATCH v2 16/21] gfs2: check for a metadata write error with buffer_write_io_error() Chao Shi
2026-08-06 16:58 ` [PATCH v2 17/21] jbd2: report journal write errors with BH_Write_EIO Chao Shi
2026-08-06 16:58 ` [PATCH v2 18/21] jbd2: say what jbd2_freeze_jh_data()'s assertion is actually checking Chao Shi
2026-08-06 16:58 ` [PATCH v2 19/21] ext4, jbd2: report fast commit write errors with BH_Write_EIO Chao Shi
2026-08-06 16:58 ` Chao Shi [this message]
2026-08-06 16:58 ` [PATCH v2 21/21] buffer: clear BH_Write_EIO when a write succeeds, not when one starts Chao Shi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=61d7d5737f5773f53ee543f375fcde81aa8d28c2.1785951556.git.coshi036@gmail.com \
--to=coshi036@gmail.com \
--cc=adilger.kernel@dilger.ca \
--cc=agruenba@redhat.com \
--cc=brauner@kernel.org \
--cc=gfs2@lists.linux.dev \
--cc=hirofumi@mail.parknet.co.jp \
--cc=jack@suse.cz \
--cc=jlbec@evilplan.org \
--cc=joseph.qi@linux.alibaba.com \
--cc=libaokun@linux.alibaba.com \
--cc=linkinjeon@kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark@fasheh.com \
--cc=me@bobcopeland.com \
--cc=ocfs2-devel@lists.linux.dev \
--cc=ojaswin@linux.ibm.com \
--cc=ritesh.list@gmail.com \
--cc=sj1557.seo@samsung.com \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
--cc=weizhu@fiu.edu \
--cc=willy@infradead.org \
--cc=yi.zhang@huawei.com \
--cc=yi.zhang@huaweicloud.com \
--cc=yuezhang.mo@sony.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox