iomap: support ioends for buffered reads

Support using the ioend structure to defer I/O completion for
buffered reads by calling into the buffered read I/O completion
handler from iomap_finish_ioend.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260223132021.292832-15-hch@lst.de
Tested-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Christoph Hellwig 2026-02-23 05:20:14 -08:00 committed by Christian Brauner
parent 57287771fa
commit e8f9cf03c9
No known key found for this signature in database
GPG Key ID: 91C61BC06578DCA2
3 changed files with 25 additions and 9 deletions

View File

@ -8,14 +8,27 @@
#include "internal.h"
#include "trace.h"
static u32 __iomap_read_end_io(struct bio *bio, int error)
{
struct folio_iter fi;
u32 folio_count = 0;
bio_for_each_folio_all(fi, bio) {
iomap_finish_folio_read(fi.folio, fi.offset, fi.length, error);
folio_count++;
}
bio_put(bio);
return folio_count;
}
static void iomap_read_end_io(struct bio *bio)
{
int error = blk_status_to_errno(bio->bi_status);
struct folio_iter fi;
__iomap_read_end_io(bio, blk_status_to_errno(bio->bi_status));
}
bio_for_each_folio_all(fi, bio)
iomap_finish_folio_read(fi.folio, fi.offset, fi.length, error);
bio_put(bio);
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,

View File

@ -4,6 +4,7 @@
#define IOEND_BATCH_SIZE 4096
u32 iomap_finish_ioend_buffered_read(struct iomap_ioend *ioend);
u32 iomap_finish_ioend_direct(struct iomap_ioend *ioend);
#ifdef CONFIG_BLOCK

View File

@ -37,7 +37,7 @@ EXPORT_SYMBOL_GPL(iomap_init_ioend);
* state, release holds on bios, and finally free up memory. Do not use the
* ioend after this.
*/
static u32 iomap_finish_ioend_buffered(struct iomap_ioend *ioend)
static u32 iomap_finish_ioend_buffered_write(struct iomap_ioend *ioend)
{
struct inode *inode = ioend->io_inode;
struct bio *bio = &ioend->io_bio;
@ -87,7 +87,7 @@ iomap_fail_ioends(
while ((ioend = list_first_entry_or_null(&tmp, struct iomap_ioend,
io_list))) {
list_del_init(&ioend->io_list);
iomap_finish_ioend_buffered(ioend);
iomap_finish_ioend_buffered_write(ioend);
cond_resched();
}
}
@ -120,7 +120,7 @@ static void ioend_writeback_end_bio(struct bio *bio)
return;
}
iomap_finish_ioend_buffered(ioend);
iomap_finish_ioend_buffered_write(ioend);
}
/*
@ -313,7 +313,9 @@ static u32 iomap_finish_ioend(struct iomap_ioend *ioend, int error)
return 0;
if (ioend->io_flags & IOMAP_IOEND_DIRECT)
return iomap_finish_ioend_direct(ioend);
return iomap_finish_ioend_buffered(ioend);
if (bio_op(&ioend->io_bio) == REQ_OP_READ)
return iomap_finish_ioend_buffered_read(ioend);
return iomap_finish_ioend_buffered_write(ioend);
}
/*