summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2023-04-03 08:24:51 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-06-21 03:32:17 -0400
commit02ffefe0c589484fa0797532507a7ed86430912f (patch)
tree10feb9bf673b1286c3e359f9257edddd2d3526da
parentf45597ccb3dac4fa8a349bf06d5d242bf4d374a3 (diff)
iomap: add nosubmit flag to skip data I/O on iomap mapping
Implement a quick and dirty hack to skip data I/O submission on a specified mapping. The iomap layer will still perform every step up through constructing the bio as if it will be submitted, but instead invokes completion on the bio directly from submit context. The purpose of this is to facilitate filesystem metadata performance testing without the overhead of actual data I/O. Note that this may be dangerous in current form in that folios are not explicitly zeroed where they otherwise wouldn't be, so whatever previous data exists in a folio prior to being added to a read bio is mapped into pagecache for the file. Signed-off-by: Brian Foster <bfoster@redhat.com>
-rw-r--r--fs/iomap/buffered-io.c45
-rw-r--r--include/linux/iomap.h1
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: