]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iomap: allow file systems to hook into buffered read bio submission
authorChristoph Hellwig <hch@lst.de>
Mon, 23 Feb 2026 13:20:11 +0000 (05:20 -0800)
committerChristian Brauner <brauner@kernel.org>
Tue, 10 Mar 2026 09:29:03 +0000 (10:29 +0100)
File systems such as btrfs have additional operations with bios such as
verifying data checksums.  Allow file systems to hook into submission
of the bio to allow for this processing by replacing the direct
submit_bio call in iomap_read_alloc_bio with a call into ->submit_read
and exporting iomap_read_alloc_bio.  Also add a new field to
struct iomap_read_folio_ctx to track the file logic offset of the current
read context.

Based on a patch from Goldwyn Rodrigues <rgoldwyn@suse.com>.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260223132021.292832-12-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>
fs/iomap/bio.c
include/linux/iomap.h

index 80bbd328bd3ce519e5ad8bf1bbe9fe1451420799..903cb9fe759e79911e401e08fc7760a1e6982669 100644 (file)
@@ -32,10 +32,11 @@ static void iomap_read_alloc_bio(const struct iomap_iter *iter,
        struct folio *folio = ctx->cur_folio;
        gfp_t gfp = mapping_gfp_constraint(folio->mapping, GFP_KERNEL);
        gfp_t orig_gfp = gfp;
-       struct bio *bio = ctx->read_ctx;
+       struct bio *bio;
 
-       if (bio)
-               submit_bio(bio);
+       /* Submit the existing range if there was one. */
+       if (ctx->read_ctx)
+               ctx->ops->submit_read(iter, ctx);
 
        /* Same as readahead_gfp_mask: */
        if (ctx->rac)
@@ -56,9 +57,10 @@ static void iomap_read_alloc_bio(const struct iomap_iter *iter,
        bio_add_folio_nofail(bio, folio, plen,
                        offset_in_folio(folio, iter->pos));
        ctx->read_ctx = bio;
+       ctx->read_ctx_file_offset = iter->pos;
 }
 
-static int iomap_bio_read_folio_range(const struct iomap_iter *iter,
+int iomap_bio_read_folio_range(const struct iomap_iter *iter,
                struct iomap_read_folio_ctx *ctx, size_t plen)
 {
        struct folio *folio = ctx->cur_folio;
@@ -70,10 +72,11 @@ static int iomap_bio_read_folio_range(const struct iomap_iter *iter,
                iomap_read_alloc_bio(iter, ctx, plen);
        return 0;
 }
+EXPORT_SYMBOL_GPL(iomap_bio_read_folio_range);
 
 const struct iomap_read_ops iomap_bio_read_ops = {
-       .read_folio_range = iomap_bio_read_folio_range,
-       .submit_read = iomap_bio_submit_read,
+       .read_folio_range       = iomap_bio_read_folio_range,
+       .submit_read            = iomap_bio_submit_read,
 };
 EXPORT_SYMBOL_GPL(iomap_bio_read_ops);
 
index 6fbe121e2adfd8060447e41c0b3eb272280deb0b..b2b9e649a3b8636f6600097efea8cd3209bbe0e0 100644 (file)
@@ -493,6 +493,7 @@ struct iomap_read_folio_ctx {
        struct folio            *cur_folio;
        struct readahead_control *rac;
        void                    *read_ctx;
+       loff_t                  read_ctx_file_offset;
 };
 
 struct iomap_read_ops {
@@ -599,6 +600,9 @@ int iomap_swapfile_activate(struct swap_info_struct *sis,
 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);
+
 extern const struct iomap_read_ops iomap_bio_read_ops;
 
 static inline void iomap_bio_read_folio(struct folio *folio,