diff options
-rw-r--r-- | fs/iomap/buffered-io.c | 45 | ||||
-rw-r--r-- | include/linux/iomap.h | 1 |
2 files changed, 36 insertions, 10 deletions
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 6f4c97a6d7e9..f5abfa40e3fb 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -292,8 +292,12 @@ static loff_t iomap_readpage_iter(const struct iomap_iter *iter, gfp_t orig_gfp = gfp; unsigned int nr_vecs = DIV_ROUND_UP(length, PAGE_SIZE); - if (ctx->bio) - submit_bio(ctx->bio); + if (ctx->bio) { + if (iomap->flags & IOMAP_F_NOSUBMIT) + bio_endio(ctx->bio); + else + submit_bio(ctx->bio); + } if (ctx->rac) /* same as readahead_gfp_mask */ gfp |= __GFP_NORETRY | __GFP_NOWARN; @@ -346,7 +350,10 @@ int iomap_read_folio(struct folio *folio, const struct iomap_ops *ops) folio_set_error(folio); if (ctx.bio) { - submit_bio(ctx.bio); + if (iter.iomap.flags & IOMAP_F_NOSUBMIT) + bio_endio(ctx.bio); + else + submit_bio(ctx.bio); WARN_ON_ONCE(!ctx.cur_folio_in_bio); } else { WARN_ON_ONCE(ctx.cur_folio_in_bio); @@ -418,8 +425,12 @@ void iomap_readahead(struct readahead_control *rac, const struct iomap_ops *ops) while (iomap_iter(&iter, ops) > 0) iter.processed = iomap_readahead_iter(&iter, &ctx); - if (ctx.bio) - submit_bio(ctx.bio); + if (ctx.bio) { + if (iter.iomap.flags & IOMAP_F_NOSUBMIT) + bio_endio(ctx.bio); + else + submit_bio(ctx.bio); + } if (ctx.cur_folio) { if (!ctx.cur_folio_in_bio) folio_unlock(ctx.cur_folio); @@ -543,11 +554,17 @@ static int iomap_read_folio_sync(loff_t block_start, struct folio *folio, { struct bio_vec bvec; struct bio bio; + int ret = 0; bio_init(&bio, iomap->bdev, &bvec, 1, REQ_OP_READ); bio.bi_iter.bi_sector = iomap_sector(iomap, block_start); bio_add_folio(&bio, folio, plen, poff); - return submit_bio_wait(&bio); + + if (iomap->flags & IOMAP_F_NOSUBMIT) + bio_endio(&bio); + else + ret = submit_bio_wait(&bio); + return ret; } static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos, @@ -1493,7 +1510,10 @@ iomap_submit_ioend(struct iomap_writepage_ctx *wpc, struct iomap_ioend *ioend, return error; } - submit_bio(ioend->io_bio); + if (wpc->iomap.flags & IOMAP_F_NOSUBMIT) + bio_endio(ioend->io_bio); + else + submit_bio(ioend->io_bio); return 0; } @@ -1531,8 +1551,9 @@ iomap_alloc_ioend(struct inode *inode, struct iomap_writepage_ctx *wpc, * traversal in iomap_finish_ioend(). */ static struct bio * -iomap_chain_bio(struct bio *prev) +iomap_chain_bio(struct iomap_writepage_ctx *wpc) { + struct bio *prev = wpc->ioend->io_bio; struct bio *new; new = bio_alloc(prev->bi_bdev, BIO_MAX_VECS, prev->bi_opf, GFP_NOFS); @@ -1541,7 +1562,11 @@ iomap_chain_bio(struct bio *prev) bio_chain(prev, new); bio_get(prev); /* for iomap_finish_ioend */ - submit_bio(prev); + + if (wpc->iomap.flags & IOMAP_F_NOSUBMIT) + bio_endio(prev); + else + submit_bio(prev); return new; } @@ -1588,7 +1613,7 @@ iomap_add_to_ioend(struct inode *inode, loff_t pos, struct folio *folio, } if (!bio_add_folio(wpc->ioend->io_bio, folio, len, poff)) { - wpc->ioend->io_bio = iomap_chain_bio(wpc->ioend->io_bio); + wpc->ioend->io_bio = iomap_chain_bio(wpc); bio_add_folio(wpc->ioend->io_bio, folio, len, poff); } diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 0f8123504e5e..bc3cdaa444df 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -60,6 +60,7 @@ struct vm_fault; #define IOMAP_F_MERGED (1U << 3) #define IOMAP_F_BUFFER_HEAD (1U << 4) #define IOMAP_F_XATTR (1U << 5) +#define IOMAP_F_NOSUBMIT (1U << 6) /* * Flags set by the core iomap code during operations: |