diff mbox series

[1/2] iomap: make buffered writes work with RWF_DONTCACHE

Message ID 20250203163425.125272-2-axboe@kernel.dk (mailing list archive)
State New
Headers show
Series Add XFS support for RWF_DONTCACHE | expand

Commit Message

Jens Axboe Feb. 3, 2025, 4:32 p.m. UTC
Add iomap buffered write support for RWF_DONTCACHE. If RWF_DONTCACHE is
set for a write, mark the folios being written as uncached. Then
writeback completion will drop the pages. The write_iter handler simply
kicks off writeback for the pages, and writeback completion will take
care of the rest.

This still needs the user of the iomap buffered write helpers to call
folio_end_dropbehind_write() upon successful issue of the writes.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
---
 fs/iomap/buffered-io.c | 4 ++++
 include/linux/iomap.h  | 1 +
 2 files changed, 5 insertions(+)

Comments

Darrick J. Wong Feb. 3, 2025, 5:19 p.m. UTC | #1
On Mon, Feb 03, 2025 at 09:32:38AM -0700, Jens Axboe wrote:
> Add iomap buffered write support for RWF_DONTCACHE. If RWF_DONTCACHE is
> set for a write, mark the folios being written as uncached. Then
> writeback completion will drop the pages. The write_iter handler simply
> kicks off writeback for the pages, and writeback completion will take
> care of the rest.
> 
> This still needs the user of the iomap buffered write helpers to call
> folio_end_dropbehind_write() upon successful issue of the writes.

I thought iomap calls folio_end_writeback, which cares of that?  So xfs
doesn't itself have to call folio_end_dropbehind_write?

> Signed-off-by: Jens Axboe <axboe@kernel.dk>
> ---
>  fs/iomap/buffered-io.c | 4 ++++
>  include/linux/iomap.h  | 1 +
>  2 files changed, 5 insertions(+)
> 
> diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
> index d303e6c8900c..ea863c3cf510 100644
> --- a/fs/iomap/buffered-io.c
> +++ b/fs/iomap/buffered-io.c
> @@ -603,6 +603,8 @@ struct folio *iomap_get_folio(struct iomap_iter *iter, loff_t pos, size_t len)
>  
>  	if (iter->flags & IOMAP_NOWAIT)
>  		fgp |= FGP_NOWAIT;
> +	if (iter->flags & IOMAP_DONTCACHE)
> +		fgp |= FGP_DONTCACHE;
>  	fgp |= fgf_set_order(len);
>  
>  	return __filemap_get_folio(iter->inode->i_mapping, pos >> PAGE_SHIFT,
> @@ -1034,6 +1036,8 @@ iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *i,
>  
>  	if (iocb->ki_flags & IOCB_NOWAIT)
>  		iter.flags |= IOMAP_NOWAIT;
> +	if (iocb->ki_flags & IOCB_DONTCACHE)
> +		iter.flags |= IOMAP_DONTCACHE;
>  
>  	while ((ret = iomap_iter(&iter, ops)) > 0)
>  		iter.processed = iomap_write_iter(&iter, i);
> diff --git a/include/linux/iomap.h b/include/linux/iomap.h
> index 75bf54e76f3b..26b0dbe23e62 100644
> --- a/include/linux/iomap.h
> +++ b/include/linux/iomap.h
> @@ -183,6 +183,7 @@ struct iomap_folio_ops {
>  #define IOMAP_DAX		0
>  #endif /* CONFIG_FS_DAX */
>  #define IOMAP_ATOMIC		(1 << 9)
> +#define IOMAP_DONTCACHE		(1 << 10)

This needs a mention in the iomap documentation.  If the patch below
accurately summarizes what it does nowadays, then you can add it to the
series with a:

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>

--D

diff --git a/Documentation/filesystems/iomap/design.rst b/Documentation/filesystems/iomap/design.rst
index b0d0188a095e55..7b91546750f59e 100644
--- a/Documentation/filesystems/iomap/design.rst
+++ b/Documentation/filesystems/iomap/design.rst
@@ -352,6 +352,11 @@ operations:
    ``IOMAP_NOWAIT`` is often set on behalf of ``IOCB_NOWAIT`` or
    ``RWF_NOWAIT``.
 
+ * ``IOMAP_DONTCACHE`` is set when the caller wishes to perform a
+   buffered file I/O and would like the kernel to drop the pagecache
+   after the I/O completes, if it isn't already being used by another
+   thread.
+
 If it is necessary to read existing file contents from a `different
 <https://lore.kernel.org/all/20191008071527.29304-9-hch@lst.de/>`_
 device or address range on a device, the filesystem should return that
diff --git a/Documentation/filesystems/iomap/operations.rst b/Documentation/filesystems/iomap/operations.rst
index 2c7f5df9d8b037..584ff549f9a659 100644
--- a/Documentation/filesystems/iomap/operations.rst
+++ b/Documentation/filesystems/iomap/operations.rst
@@ -131,6 +131,8 @@ These ``struct kiocb`` flags are significant for buffered I/O with iomap:
 
  * ``IOCB_NOWAIT``: Turns on ``IOMAP_NOWAIT``.
 
+ * ``IOCB_DONTCACHE``: Turns on ``IOMAP_DONTCACHE``.
+
 Internal per-Folio State
 ------------------------
Jens Axboe Feb. 3, 2025, 6:26 p.m. UTC | #2
On 2/3/25 10:19 AM, Darrick J. Wong wrote:
> On Mon, Feb 03, 2025 at 09:32:38AM -0700, Jens Axboe wrote:
>> Add iomap buffered write support for RWF_DONTCACHE. If RWF_DONTCACHE is
>> set for a write, mark the folios being written as uncached. Then
>> writeback completion will drop the pages. The write_iter handler simply
>> kicks off writeback for the pages, and writeback completion will take
>> care of the rest.
>>
>> This still needs the user of the iomap buffered write helpers to call
>> folio_end_dropbehind_write() upon successful issue of the writes.
> 
> I thought iomap calls folio_end_writeback, which cares of that?  So xfs
> doesn't itself have to call folio_end_dropbehind_write?

Yep it does, stale commit message! I'll fix it up and send out a v2.

>>  fs/iomap/buffered-io.c | 4 ++++
>>  include/linux/iomap.h  | 1 +
>>  2 files changed, 5 insertions(+)
>>
>> diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
>> index d303e6c8900c..ea863c3cf510 100644
>> --- a/fs/iomap/buffered-io.c
>> +++ b/fs/iomap/buffered-io.c
>> @@ -603,6 +603,8 @@ struct folio *iomap_get_folio(struct iomap_iter *iter, loff_t pos, size_t len)
>>  
>>  	if (iter->flags & IOMAP_NOWAIT)
>>  		fgp |= FGP_NOWAIT;
>> +	if (iter->flags & IOMAP_DONTCACHE)
>> +		fgp |= FGP_DONTCACHE;
>>  	fgp |= fgf_set_order(len);
>>  
>>  	return __filemap_get_folio(iter->inode->i_mapping, pos >> PAGE_SHIFT,
>> @@ -1034,6 +1036,8 @@ iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *i,
>>  
>>  	if (iocb->ki_flags & IOCB_NOWAIT)
>>  		iter.flags |= IOMAP_NOWAIT;
>> +	if (iocb->ki_flags & IOCB_DONTCACHE)
>> +		iter.flags |= IOMAP_DONTCACHE;
>>  
>>  	while ((ret = iomap_iter(&iter, ops)) > 0)
>>  		iter.processed = iomap_write_iter(&iter, i);
>> diff --git a/include/linux/iomap.h b/include/linux/iomap.h
>> index 75bf54e76f3b..26b0dbe23e62 100644
>> --- a/include/linux/iomap.h
>> +++ b/include/linux/iomap.h
>> @@ -183,6 +183,7 @@ struct iomap_folio_ops {
>>  #define IOMAP_DAX		0
>>  #endif /* CONFIG_FS_DAX */
>>  #define IOMAP_ATOMIC		(1 << 9)
>> +#define IOMAP_DONTCACHE		(1 << 10)
> 
> This needs a mention in the iomap documentation.  If the patch below
> accurately summarizes what it does nowadays, then you can add it to the
> series with a:

Thanks Darrick, I'll add that and your SOB as well.
diff mbox series

Patch

diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index d303e6c8900c..ea863c3cf510 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -603,6 +603,8 @@  struct folio *iomap_get_folio(struct iomap_iter *iter, loff_t pos, size_t len)
 
 	if (iter->flags & IOMAP_NOWAIT)
 		fgp |= FGP_NOWAIT;
+	if (iter->flags & IOMAP_DONTCACHE)
+		fgp |= FGP_DONTCACHE;
 	fgp |= fgf_set_order(len);
 
 	return __filemap_get_folio(iter->inode->i_mapping, pos >> PAGE_SHIFT,
@@ -1034,6 +1036,8 @@  iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *i,
 
 	if (iocb->ki_flags & IOCB_NOWAIT)
 		iter.flags |= IOMAP_NOWAIT;
+	if (iocb->ki_flags & IOCB_DONTCACHE)
+		iter.flags |= IOMAP_DONTCACHE;
 
 	while ((ret = iomap_iter(&iter, ops)) > 0)
 		iter.processed = iomap_write_iter(&iter, i);
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index 75bf54e76f3b..26b0dbe23e62 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -183,6 +183,7 @@  struct iomap_folio_ops {
 #define IOMAP_DAX		0
 #endif /* CONFIG_FS_DAX */
 #define IOMAP_ATOMIC		(1 << 9)
+#define IOMAP_DONTCACHE		(1 << 10)
 
 struct iomap_ops {
 	/*