Merge patch series "iomap: consolidate bio submission"

Christoph Hellwig <hch@lst.de> says:

This patch changes how iomap submits bios for reads.  The old behavior
to build up bios across iomap was already considered problematic for
a while, but we now ran into a erofs bug because of it, so it's time
to finally fix it.

* patches from https://patch.msgid.link/20260629121750.3392300-2-hch@lst.de:
  iomap: submit read bio after each extent
  fuse: call fuse_send_readpages explicitly from fuse_readahead
  iomap: consolidate bio submission

Link: https://patch.msgid.link/20260629121750.3392300-2-hch@lst.de
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
Christian Brauner
2026-07-01 15:26:51 +02:00
8 changed files with 30 additions and 36 deletions

View File

@@ -253,10 +253,7 @@ static void exfat_iomap_read_end_io(struct bio *bio)
static void exfat_iomap_bio_submit_read(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx)
{
struct bio *bio = ctx->read_ctx;
bio->bi_end_io = exfat_iomap_read_end_io;
submit_bio(bio);
iomap_bio_submit_read_endio(iter, ctx, exfat_iomap_read_end_io);
}
const struct iomap_read_ops exfat_iomap_bio_read_ops = {

View File

@@ -981,19 +981,8 @@ static int fuse_iomap_read_folio_range_async(const struct iomap_iter *iter,
return ret;
}
static void fuse_iomap_submit_read(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx)
{
struct fuse_fill_read_data *data = ctx->read_ctx;
if (data->ia)
fuse_send_readpages(data->ia, data->file, data->nr_bytes,
data->fc->async_read);
}
static const struct iomap_read_ops fuse_iomap_read_ops = {
.read_folio_range = fuse_iomap_read_folio_range_async,
.submit_read = fuse_iomap_submit_read,
};
static int fuse_read_folio(struct file *file, struct folio *folio)
@@ -1116,6 +1105,9 @@ static void fuse_readahead(struct readahead_control *rac)
return;
iomap_readahead(&fuse_iomap_ops, &ctx, NULL);
if (data.ia)
fuse_send_readpages(data.ia, data.file, data.nr_bytes,
fc->async_read);
}
static ssize_t fuse_cache_read_iter(struct kiocb *iocb, struct iov_iter *to)

View File

@@ -78,14 +78,24 @@ u32 iomap_finish_ioend_buffered_read(struct iomap_ioend *ioend)
return __iomap_read_end_io(&ioend->io_bio, ioend->io_error);
}
static void iomap_bio_submit_read(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx)
void iomap_bio_submit_read_endio(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx, bio_end_io_t end_io)
{
struct bio *bio = ctx->read_ctx;
bio->bi_end_io = end_io;
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);
static void iomap_bio_submit_read(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx)
{
return iomap_bio_submit_read_endio(iter, ctx, iomap_read_end_io);
}
static struct bio_set *iomap_read_bio_set(struct iomap_read_folio_ctx *ctx)
@@ -127,7 +137,6 @@ static void iomap_read_alloc_bio(const struct iomap_iter *iter,
if (ctx->rac)
bio->bi_opf |= REQ_RAHEAD;
bio->bi_iter.bi_sector = iomap_sector(iomap, iter->pos);
bio->bi_end_io = iomap_read_end_io;
bio_add_folio_nofail(bio, folio, plen,
offset_in_folio(folio, iter->pos));
ctx->read_ctx = bio;

View 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);

View File

@@ -38,11 +38,9 @@ static void ntfs_iomap_read_end_io(struct bio *bio)
}
static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx)
struct iomap_read_folio_ctx *ctx)
{
struct bio *bio = ctx->read_ctx;
bio->bi_end_io = ntfs_iomap_read_end_io;
submit_bio(bio);
iomap_bio_submit_read_endio(iter, ctx, ntfs_iomap_read_end_io);
}
static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {

View File

@@ -608,10 +608,7 @@ static void ntfs_iomap_read_end_io(struct bio *bio)
static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx)
{
struct bio *bio = ctx->read_ctx;
bio->bi_end_io = ntfs_iomap_read_end_io;
submit_bio(bio);
iomap_bio_submit_read_endio(iter, ctx, ntfs_iomap_read_end_io);
}
static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {

View File

@@ -764,8 +764,7 @@ xfs_bio_submit_read(
/* defer read completions to the ioend workqueue */
iomap_init_ioend(iter->inode, bio, ctx->read_ctx_file_offset, 0);
bio->bi_end_io = xfs_end_bio;
submit_bio(bio);
iomap_bio_submit_read_endio(iter, ctx, xfs_end_bio);
}
static const struct iomap_read_ops xfs_iomap_read_ops = {

View File

@@ -622,6 +622,8 @@ extern struct bio_set iomap_ioend_bioset;
#ifdef CONFIG_BLOCK
int iomap_bio_read_folio_range(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx, size_t plen);
void iomap_bio_submit_read_endio(const struct iomap_iter *iter,
struct iomap_read_folio_ctx *ctx, bio_end_io_t end_io);
extern const struct iomap_read_ops iomap_bio_read_ops;