From: Christoph Hellwig Date: Mon, 29 Jun 2026 12:17:40 +0000 (+0200) Subject: iomap: submit read bio after each extent X-Git-Tag: v7.2-rc2~14^2~1^2 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=c1fb97d31782f5a8c66d127624626accbb0dd8bc;p=thirdparty%2Flinux.git iomap: submit read bio after each extent Currently the iomap buffered read path tries to build up read context (i.e. bios for the typical block based case) over multiple iomaps as long as the sector matches. This does not take into account files that can map to multiple different devices. While this could be fixed by a bdev check in iomap_bio_read_folio_range, the building up of I/O over iomaps actually was a problem for the not yet merged ext2 iomap port, as that does want to send out I/O at the end of an indirect block mapped range. So instead of adding more checks move over to a model where a bio only spans a single iomap. Change ->submit_read to be called after each iteration so that the bio based users submit the bio after each iomap. Fuse is unchanged because the previous commit stopped using ->submit_read for it. Fixes: dfeab2e95a75 ("erofs: add multiple device support") Reported-by: Kelu Ye Reported-by: Yifan Zhao Signed-off-by: Christoph Hellwig Link: https://patch.msgid.link/20260629121750.3392300-4-hch@lst.de Tested-by: Yifan Zhao Reviewed-by: "Darrick J. Wong" Signed-off-by: Christian Brauner (Amutable) --- diff --git a/fs/iomap/bio.c b/fs/iomap/bio.c index 0f31e35567b4..dc8ac7e370a5 100644 --- a/fs/iomap/bio.c +++ b/fs/iomap/bio.c @@ -87,6 +87,8 @@ void iomap_bio_submit_read_endio(const struct iomap_iter *iter, if (iter->iomap.flags & IOMAP_F_INTEGRITY) fs_bio_integrity_alloc(bio); submit_bio(bio); + + ctx->read_ctx = NULL; } EXPORT_SYMBOL_GPL(iomap_bio_submit_read_endio); diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 8d4806dc46d4..276720bc18dc 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -642,12 +642,12 @@ void iomap_read_folio(const struct iomap_ops *ops, fsverity_readahead(ctx->vi, folio->index, folio_nr_pages(folio)); - 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); + } if (ctx->cur_folio) iomap_read_end(ctx->cur_folio, bytes_submitted); @@ -718,12 +718,12 @@ void iomap_readahead(const struct iomap_ops *ops, fsverity_readahead(ctx->vi, readahead_index(rac), 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); + } if (ctx->cur_folio) iomap_read_end(ctx->cur_folio, cur_bytes_submitted);