From: "Darrick J. Wong" <djwong@kernel.org>
To: Joanne Koong <joannelkoong@gmail.com>
Cc: brauner@kernel.org, willy@infradead.org, wegao@suse.com,
sashal@kernel.org, hch@infradead.org,
linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v1 1/1] iomap: don't mark folio uptodate if read IO has bytes pending
Date: Wed, 18 Feb 2026 18:45:34 -0800 [thread overview]
Message-ID: <20260219024534.GN6467@frogsfrogsfrogs> (raw)
In-Reply-To: <20260219003911.344478-2-joannelkoong@gmail.com>
On Wed, Feb 18, 2026 at 04:39:11PM -0800, Joanne Koong wrote:
> If a folio has ifs metadata attached to it and the folio is partially
> read in through an async IO helper with the rest of it then being read
> in through post-EOF zeroing or as inline data, and the helper
> successfully finishes the read first, then post-EOF zeroing / reading
> inline will mark the folio as uptodate in iomap_set_range_uptodate().
>
> This is a problem because when the read completion path later calls
> iomap_read_end(), it will call folio_end_read(), which sets the uptodate
> bit using XOR semantics. Calling folio_end_read() on a folio that was
> already marked uptodate clears the uptodate bit.
Aha, I wondered if that xor thing was going to come back to bite us.
> Fix this by not marking the folio as uptodate if the read IO has bytes
> pending. The folio uptodate state will be set in the read completion
> path through iomap_end_read() -> folio_end_read().
>
> Reported-by: Wei Gao <wegao@suse.com>
> Suggested-by: Sasha Levin <sashal@kernel.org>
> Tested-by: Wei Gao <wegao@suse.com>
> Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
> Fixes: b2f35ac4146d ("iomap: add caller-provided callbacks for read and readahead")
I would add:
Link: https://lore.kernel.org/linux-fsdevel/aYbmy8JdgXwsGaPP@autotest-wegao.qe.prg2.suse.org/
Cc: <stable@vger.kernel.org> # v6.19
since the recent discussion around this was sort of buried in a
different thread, and the original patch is now in a released kernel.
> ---
> fs/iomap/buffered-io.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
> index 58887513b894..4fc5ce963feb 100644
> --- a/fs/iomap/buffered-io.c
> +++ b/fs/iomap/buffered-io.c
> @@ -80,18 +80,27 @@ static void iomap_set_range_uptodate(struct folio *folio, size_t off,
> {
> struct iomap_folio_state *ifs = folio->private;
> unsigned long flags;
> - bool uptodate = true;
> + bool mark_uptodate = true;
>
> if (folio_test_uptodate(folio))
> return;
>
> if (ifs) {
> spin_lock_irqsave(&ifs->state_lock, flags);
> - uptodate = ifs_set_range_uptodate(folio, ifs, off, len);
> + /*
> + * If a read with bytes pending is in progress, we must not call
> + * folio_mark_uptodate(). The read completion path
> + * (iomap_read_end()) will call folio_end_read(), which uses XOR
> + * semantics to set the uptodate bit. If we set it here, the XOR
> + * in folio_end_read() will clear it, leaving the folio not
> + * uptodate.
Yeah, that makes sense. How difficult is this to write up as an fstest?
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
--D
> + */
> + mark_uptodate = ifs_set_range_uptodate(folio, ifs, off, len) &&
> + !ifs->read_bytes_pending;
> spin_unlock_irqrestore(&ifs->state_lock, flags);
> }
>
> - if (uptodate)
> + if (mark_uptodate)
> folio_mark_uptodate(folio);
> }
>
> --
> 2.47.3
>
>
next prev parent reply other threads:[~2026-02-19 2:45 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-19 0:39 [PATCH v1 0/1] iomap: don't mark folio uptodate if read IO has bytes pending Joanne Koong
2026-02-19 0:39 ` [PATCH v1 1/1] " Joanne Koong
2026-02-19 2:45 ` Darrick J. Wong [this message]
2026-02-19 4:23 ` Matthew Wilcox
2026-02-19 6:11 ` Darrick J. Wong
2026-02-19 6:11 ` Christoph Hellwig
2026-02-20 22:13 ` Joanne Koong
2026-02-20 23:45 ` Darrick J. Wong
2026-02-23 23:53 ` Joanne Koong
2026-02-24 15:16 ` Christoph Hellwig
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=20260219024534.GN6467@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=brauner@kernel.org \
--cc=hch@infradead.org \
--cc=joannelkoong@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=sashal@kernel.org \
--cc=wegao@suse.com \
--cc=willy@infradead.org \
/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