]> www.infradead.org Git - users/hch/misc.git/commitdiff
iomap: add bioset in iomap_read_folio_ops for filesystems to use own bioset
authorGoldwyn Rodrigues <rgoldwyn@suse.com>
Sat, 1 Feb 2025 05:08:17 +0000 (06:08 +0100)
committerChristoph Hellwig <hch@lst.de>
Mon, 3 Feb 2025 09:21:33 +0000 (10:21 +0100)
Allocate the bio from the bioset provided in iomap_read_folio_ops.
If no bioset is provided, fs_bio_set is used which is the standard
bioset for filesystems.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@suse.com>
[hch: factor out two helpers]
Signed-off-by: Christoph Hellwig <hch@lst.de>
fs/iomap/buffered-io.c
include/linux/iomap.h

index 804527dcc9ba8879e10a05350eada61f3957b073..eaffa23eb8e4321ea8c0e6a0660cd6dc25f655b7 100644 (file)
@@ -364,6 +364,39 @@ static inline bool iomap_block_needs_zeroing(const struct iomap_iter *iter,
                pos >= i_size_read(iter->inode);
 }
 
+static struct bio_set *iomap_read_bio_set(struct iomap_readpage_ctx *ctx)
+{
+       if (ctx->ops && ctx->ops->bio_set)
+               return ctx->ops->bio_set;
+       return &fs_bio_set;
+}
+
+static struct bio *iomap_read_alloc_bio(const struct iomap_iter *iter,
+               struct iomap_readpage_ctx *ctx, loff_t length)
+{
+       unsigned int nr_vecs = DIV_ROUND_UP(length, PAGE_SIZE);
+       struct block_device *bdev = iter->iomap.bdev;
+       struct bio_set *bio_set = iomap_read_bio_set(ctx);
+       gfp_t gfp = mapping_gfp_constraint(iter->inode->i_mapping, GFP_KERNEL);
+       gfp_t orig_gfp = gfp;
+       struct bio *bio;
+
+       if (ctx->rac) /* same as readahead_gfp_mask */
+               gfp |= __GFP_NORETRY | __GFP_NOWARN;
+
+       bio = bio_alloc_bioset(bdev, bio_max_segs(nr_vecs), REQ_OP_READ, gfp,
+                       bio_set);
+
+       /*
+        * If the bio_alloc fails, try it again for a single page to avoid
+        * having to deal with partial page reads.  This emulates what
+        * do_mpage_read_folio does.
+        */
+       if (!bio)
+               bio = bio_alloc_bioset(bdev, 1, REQ_OP_READ, orig_gfp, bio_set);
+       return bio;
+}
+
 static void iomap_read_submit_bio(const struct iomap_iter *iter,
                struct iomap_readpage_ctx *ctx)
 {
@@ -411,27 +444,11 @@ static loff_t iomap_readpage_iter(const struct iomap_iter *iter,
        if (!ctx->bio ||
            bio_end_sector(ctx->bio) != sector ||
            !bio_add_folio(ctx->bio, folio, plen, poff)) {
-               gfp_t gfp = mapping_gfp_constraint(folio->mapping, GFP_KERNEL);
-               gfp_t orig_gfp = gfp;
-               unsigned int nr_vecs = DIV_ROUND_UP(length, PAGE_SIZE);
-
                if (ctx->bio)
                        iomap_read_submit_bio(iter, ctx);
 
                ctx->bio_start_pos = offset;
-               if (ctx->rac) /* same as readahead_gfp_mask */
-                       gfp |= __GFP_NORETRY | __GFP_NOWARN;
-               ctx->bio = bio_alloc(iomap->bdev, bio_max_segs(nr_vecs),
-                                    REQ_OP_READ, gfp);
-               /*
-                * If the bio_alloc fails, try it again for a single page to
-                * avoid having to deal with partial page reads.  This emulates
-                * what do_mpage_read_folio does.
-                */
-               if (!ctx->bio) {
-                       ctx->bio = bio_alloc(iomap->bdev, 1, REQ_OP_READ,
-                                            orig_gfp);
-               }
+               ctx->bio = iomap_read_alloc_bio(iter, ctx, length);
                if (ctx->rac)
                        ctx->bio->bi_opf |= REQ_RAHEAD;
                ctx->bio->bi_iter.bi_sector = sector;
index 2930861d1ef1d37419cb9ec8359c66cfef2c1cb4..304be88ecd23d1299247fc304042addd1a2cac2a 100644 (file)
@@ -311,6 +311,12 @@ struct iomap_read_folio_ops {
         */
        void (*submit_io)(struct inode *inode, struct bio *bio,
                          loff_t file_offset);
+
+       /*
+        * Optional, allows filesystem to specify own bio_set, so new bio's
+        * can be allocated from the provided bio_set.
+        */
+       struct bio_set *bio_set;
 };
 
 int iomap_read_folio(struct folio *folio, const struct iomap_ops *ops,