]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iomap: add read_folio_range() handler for buffered writes
authorChristoph Hellwig <hch@lst.de>
Thu, 10 Jul 2025 13:33:37 +0000 (15:33 +0200)
committerChristian Brauner <brauner@kernel.org>
Mon, 14 Jul 2025 08:51:33 +0000 (10:51 +0200)
Add a read_folio_range() handler for buffered writes that filesystems
may pass in if they wish to provide a custom handler for synchronously
reading in the contents of a folio.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
[hch: renamed to read_folio_range, pass less arguments]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/20250710133343.399917-14-hch@lst.de
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Documentation/filesystems/iomap/operations.rst
fs/iomap/buffered-io.c
include/linux/iomap.h

index a9b48ce4af9205839cfb44eb134116c529a6fd38..067ed8e14ef34d57690cb1f1134e341f7f6b1d1b 100644 (file)
@@ -68,6 +68,8 @@ The following address space operations can be wrapped easily:
      void (*put_folio)(struct inode *inode, loff_t pos, unsigned copied,
                        struct folio *folio);
      bool (*iomap_valid)(struct inode *inode, const struct iomap *iomap);
+     int (*read_folio_range)(const struct iomap_iter *iter,
+                       struct folio *folio, loff_t pos, size_t len);
  };
 
 iomap calls these functions:
@@ -123,6 +125,10 @@ iomap calls these functions:
     ``->iomap_valid``, then the iomap should considered stale and the
     validation failed.
 
+  - ``read_folio_range``: Called to synchronously read in the range that will
+    be written to. If this function is not provided, iomap will default to
+    submitting a bio read request.
+
 These ``struct kiocb`` flags are significant for buffered I/O with iomap:
 
  * ``IOCB_NOWAIT``: Turns on ``IOMAP_NOWAIT``.
index 8a44f56a3a80f5e26228d1084848200e1c911146..aed4fc30a8490f7e2da6601c800d0413e17634b8 100644 (file)
@@ -671,7 +671,8 @@ static int iomap_read_folio_range(const struct iomap_iter *iter,
        return submit_bio_wait(&bio);
 }
 
-static int __iomap_write_begin(const struct iomap_iter *iter, size_t len,
+static int __iomap_write_begin(const struct iomap_iter *iter,
+               const struct iomap_write_ops *write_ops, size_t len,
                struct folio *folio)
 {
        struct iomap_folio_state *ifs;
@@ -722,8 +723,12 @@ static int __iomap_write_begin(const struct iomap_iter *iter, size_t len,
                        if (iter->flags & IOMAP_NOWAIT)
                                return -EAGAIN;
 
-                       status = iomap_read_folio_range(iter, folio,
-                                       block_start, plen);
+                       if (write_ops && write_ops->read_folio_range)
+                               status = write_ops->read_folio_range(iter,
+                                               folio, block_start, plen);
+                       else
+                               status = iomap_read_folio_range(iter,
+                                               folio, block_start, plen);
                        if (status)
                                return status;
                }
@@ -839,7 +844,7 @@ static int iomap_write_begin(struct iomap_iter *iter,
        else if (srcmap->flags & IOMAP_F_BUFFER_HEAD)
                status = __block_write_begin_int(folio, pos, len, NULL, srcmap);
        else
-               status = __iomap_write_begin(iter, len, folio);
+               status = __iomap_write_begin(iter, write_ops, len, folio);
 
        if (unlikely(status))
                goto out_unlock;
index 80f543cc4fe8ad02bbee1a222fe49c55bf0ffd86..73dceabc21c8c7be0e01ac7ce25851dfdbb4bde3 100644 (file)
@@ -166,6 +166,16 @@ struct iomap_write_ops {
         * locked by the iomap code.
         */
        bool (*iomap_valid)(struct inode *inode, const struct iomap *iomap);
+
+       /*
+        * Optional if the filesystem wishes to provide a custom handler for
+        * reading in the contents of a folio, otherwise iomap will default to
+        * submitting a bio read request.
+        *
+        * The read must be done synchronously.
+        */
+       int (*read_folio_range)(const struct iomap_iter *iter,
+                       struct folio *folio, loff_t pos, size_t len);
 };
 
 /*