]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iomap: submit read bio after each extent
authorChristoph Hellwig <hch@lst.de>
Mon, 29 Jun 2026 12:17:40 +0000 (14:17 +0200)
committerChristian Brauner <brauner@kernel.org>
Wed, 1 Jul 2026 13:26:47 +0000 (15:26 +0200)
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 <yekelu1@huawei.com>
Reported-by: Yifan Zhao <zhaoyifan28@huawei.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260629121750.3392300-4-hch@lst.de
Tested-by: Yifan Zhao <zhaoyifan28@huawei.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
fs/iomap/bio.c
fs/iomap/buffered-io.c

index 0f31e35567b4b4c6593aa9e53e06632660a242e4..dc8ac7e370a5c3a6cf831247d55ea6b674a57c33 100644 (file)
@@ -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);
 
index 8d4806dc46d468b4a930441998e6edf8ec716f16..276720bc18dc525cf11958b050a0897cefd3fb63 100644 (file)
@@ -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);