Unverified Commit c5690dd0 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Christian Brauner
Browse files

iomap: add read_folio_range() handler for buffered writes



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: default avatarJoanne Koong <joannelkoong@gmail.com>
[hch: renamed to read_folio_range, pass less arguments]
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/20250710133343.399917-14-hch@lst.de


Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent e6caf01d
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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``.
+9 −4
Original line number Diff line number Diff line
@@ -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;
+10 −0
Original line number Diff line number Diff line
@@ -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);
};

/*