Re: don't merge bios over iomap boundaries, was: Re: [PATCH] erofs: prevent buffered read bio merges across device chunks
From: zhaoyifan (H)
Date: Thu Jun 18 2026 - 03:16:26 EST
Hi Christoph,
This patch works well under my workload (at least correctness-wise). Thanks.
Tested-by: Yifan Zhao <zhaoyifan28@xxxxxxxxxx>
Thanks,
Yifan
On 2026/6/12 14:25, Christoph Hellwig wrote:
On Fri, Jun 12, 2026 at 11:42:38AM +0800, Gao Xiang wrote:
Yes. iomap should not try to build bios over iomap boundaries.Reported-by: Kelu Ye <yekelu1@xxxxxxxxxx>I think it's an iomap bug instead, see:
Assisted-by: Codex:GPT-5.5
Signed-off-by: Yifan Zhao <zhaoyifan28@xxxxxxxxxx>
iomap_bio_read_folio_range(), we should fix iomap instead.
caused various issues. Ritesh ran into that with the ext2 port
back in the day, and I actually ran into it again with an under
development xfs feature.
Can you try this patch?
---
From 297230cc3c08cbfef3670b08c4e35813c18c523e Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <hch@xxxxxx>
Date: Sun, 7 Jun 2026 08:53:20 +0200
Subject: iomap: submit read bio after each extent
This keeps bios from crossing RTG boundaries in XFS and probably fixes
all kinds of other stuff..
Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
fs/iomap/buffered-io.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index d55b936e6986..3642a11c102f 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -597,12 +597,13 @@ void iomap_read_folio(const struct iomap_ops *ops,
trace_iomap_readpage(iter.inode, 1);
- while ((ret = iomap_iter(&iter, ops)) > 0)
+ while ((ret = iomap_iter(&iter, ops)) > 0) {
iter.status = iomap_read_folio_iter(&iter, ctx,
&bytes_submitted);
-
- if (ctx->read_ctx && ctx->ops->submit_read)
- ctx->ops->submit_read(&iter, ctx);
+ if (ctx->read_ctx && ctx->ops->submit_read)
+ ctx->ops->submit_read(&iter, ctx);
+ ctx->read_ctx = NULL;
+ }
if (ctx->cur_folio)
iomap_read_end(ctx->cur_folio, bytes_submitted);
@@ -664,12 +665,13 @@ void iomap_readahead(const struct iomap_ops *ops,
trace_iomap_readahead(rac->mapping->host, readahead_count(rac));
- while (iomap_iter(&iter, ops) > 0)
+ while (iomap_iter(&iter, ops) > 0) {
iter.status = iomap_readahead_iter(&iter, ctx,
&cur_bytes_submitted);
-
- if (ctx->read_ctx && ctx->ops->submit_read)
- ctx->ops->submit_read(&iter, ctx);
+ if (ctx->read_ctx && ctx->ops->submit_read)
+ ctx->ops->submit_read(&iter, ctx);
+ ctx->read_ctx = NULL;
+ }
if (ctx->cur_folio)
iomap_read_end(ctx->cur_folio, cur_bytes_submitted);