* [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE
[not found] <cover.1755612705.git.trond.myklebust@hammerspace.com>
@ 2025-09-10 1:53 ` Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 1/3] filemap: Add a helper for filesystems implementing dropbehind Trond Myklebust
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Trond Myklebust @ 2025-09-10 1:53 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-fsdevel, Anna Schumaker
From: Trond Myklebust <trond.myklebust@hammerspace.com>
The main issue is allowing support on 2 stage writes (i.e. unstable
WRITE followed by a COMMIT) since those don't follow the current
assumption that the 'dropbehind' flag can be fulfilled as soon as the
writeback lock is dropped.
v2:
- Make use of the new iocb parameter for nfs_write_begin()
v3:
- Set/clear PG_DROPBEHIND on the head of the nfs_page group
- Simplify helper folio_end_dropbehind
v4:
- Replace filemap_end_dropbehind_write() with folio_end_dropbehind()
- Add a helper to replace folio_end_writeback with an equivalent that
does not attempt to interpret the dropbehind flag
- Keep the folio dropbehind flag set until the NFS client is ready to
call folio_end_dropbehind.
- Don't try to do a read-modify-write in nfs_write_begin() if the folio
has the dropbehind flag set.
v5:
- Change helper function export types to EXPORT_SYMBOL_GPL
Trond Myklebust (3):
filemap: Add a helper for filesystems implementing dropbehind
filemap: Add a version of folio_end_writeback that ignores dropbehind
NFS: Enable use of the RWF_DONTCACHE flag on the NFS client
fs/nfs/file.c | 9 +++++----
fs/nfs/nfs4file.c | 1 +
fs/nfs/write.c | 4 +++-
include/linux/pagemap.h | 2 ++
mm/filemap.c | 34 ++++++++++++++++++++++++++--------
5 files changed, 37 insertions(+), 13 deletions(-)
--
2.51.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v5 1/3] filemap: Add a helper for filesystems implementing dropbehind
2025-09-10 1:53 ` [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE Trond Myklebust
@ 2025-09-10 1:53 ` Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 2/3] filemap: Add a version of folio_end_writeback that ignores dropbehind Trond Myklebust
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Trond Myklebust @ 2025-09-10 1:53 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-fsdevel, Anna Schumaker
From: Trond Myklebust <trond.myklebust@hammerspace.com>
Add a helper to allow filesystems to attempt to free the 'dropbehind'
folio.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Link: https://lore.kernel.org/all/5588a06f6d5a2cf6746828e2d36e7ada668b1739.1745381692.git.trond.myklebust@hammerspace.com/
Reviewed-by: Mike Snitzer <snitzer@kernel.org>
---
include/linux/pagemap.h | 1 +
mm/filemap.c | 5 +++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 12a12dae727d..201b7c6f6441 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -1221,6 +1221,7 @@ void folio_wait_writeback(struct folio *folio);
int folio_wait_writeback_killable(struct folio *folio);
void end_page_writeback(struct page *page);
void folio_end_writeback(struct folio *folio);
+void folio_end_dropbehind(struct folio *folio);
void folio_wait_stable(struct folio *folio);
void __folio_mark_dirty(struct folio *folio, struct address_space *, int warn);
void folio_account_cleaned(struct folio *folio, struct bdi_writeback *wb);
diff --git a/mm/filemap.c b/mm/filemap.c
index 751838ef05e5..66cec689bec4 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1608,7 +1608,7 @@ static void filemap_end_dropbehind(struct folio *folio)
* completes. Do that now. If we fail, it's likely because of a big folio -
* just reset dropbehind for that case and latter completions should invalidate.
*/
-static void filemap_end_dropbehind_write(struct folio *folio)
+void folio_end_dropbehind(struct folio *folio)
{
if (!folio_test_dropbehind(folio))
return;
@@ -1625,6 +1625,7 @@ static void filemap_end_dropbehind_write(struct folio *folio)
folio_unlock(folio);
}
}
+EXPORT_SYMBOL_GPL(folio_end_dropbehind);
/**
* folio_end_writeback - End writeback against a folio.
@@ -1660,7 +1661,7 @@ void folio_end_writeback(struct folio *folio)
if (__folio_end_writeback(folio))
folio_wake_bit(folio, PG_writeback);
- filemap_end_dropbehind_write(folio);
+ folio_end_dropbehind(folio);
acct_reclaim_writeback(folio);
folio_put(folio);
}
--
2.51.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v5 2/3] filemap: Add a version of folio_end_writeback that ignores dropbehind
2025-09-10 1:53 ` [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 1/3] filemap: Add a helper for filesystems implementing dropbehind Trond Myklebust
@ 2025-09-10 1:53 ` Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 3/3] NFS: Enable use of the RWF_DONTCACHE flag on the NFS client Trond Myklebust
2025-09-10 1:59 ` [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE Trond Myklebust
3 siblings, 0 replies; 5+ messages in thread
From: Trond Myklebust @ 2025-09-10 1:53 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-fsdevel, Anna Schumaker
From: Trond Myklebust <trond.myklebust@hammerspace.com>
Filesystems such as NFS may need to defer dropbehind until after their
2-stage writes are done. This adds a helper
folio_end_writeback_no_dropbehind() that allows them to release the
writeback flag without immediately dropping the folio.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
include/linux/pagemap.h | 1 +
mm/filemap.c | 29 +++++++++++++++++++++++------
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 201b7c6f6441..5b26465358ce 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -1221,6 +1221,7 @@ void folio_wait_writeback(struct folio *folio);
int folio_wait_writeback_killable(struct folio *folio);
void end_page_writeback(struct page *page);
void folio_end_writeback(struct folio *folio);
+void folio_end_writeback_no_dropbehind(struct folio *folio);
void folio_end_dropbehind(struct folio *folio);
void folio_wait_stable(struct folio *folio);
void __folio_mark_dirty(struct folio *folio, struct address_space *, int warn);
diff --git a/mm/filemap.c b/mm/filemap.c
index 66cec689bec4..d12bbb4c9d8a 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1628,14 +1628,15 @@ void folio_end_dropbehind(struct folio *folio)
EXPORT_SYMBOL_GPL(folio_end_dropbehind);
/**
- * folio_end_writeback - End writeback against a folio.
+ * folio_end_writeback_no_dropbehind - End writeback against a folio.
* @folio: The folio.
*
* The folio must actually be under writeback.
+ * This call is intended for filesystems that need to defer dropbehind.
*
* Context: May be called from process or interrupt context.
*/
-void folio_end_writeback(struct folio *folio)
+void folio_end_writeback_no_dropbehind(struct folio *folio)
{
VM_BUG_ON_FOLIO(!folio_test_writeback(folio), folio);
@@ -1651,6 +1652,25 @@ void folio_end_writeback(struct folio *folio)
folio_rotate_reclaimable(folio);
}
+ if (__folio_end_writeback(folio))
+ folio_wake_bit(folio, PG_writeback);
+
+ acct_reclaim_writeback(folio);
+}
+EXPORT_SYMBOL_GPL(folio_end_writeback_no_dropbehind);
+
+/**
+ * folio_end_writeback - End writeback against a folio.
+ * @folio: The folio.
+ *
+ * The folio must actually be under writeback.
+ *
+ * Context: May be called from process or interrupt context.
+ */
+void folio_end_writeback(struct folio *folio)
+{
+ VM_BUG_ON_FOLIO(!folio_test_writeback(folio), folio);
+
/*
* Writeback does not hold a folio reference of its own, relying
* on truncation to wait for the clearing of PG_writeback.
@@ -1658,11 +1678,8 @@ void folio_end_writeback(struct folio *folio)
* reused before the folio_wake_bit().
*/
folio_get(folio);
- if (__folio_end_writeback(folio))
- folio_wake_bit(folio, PG_writeback);
-
+ folio_end_writeback_no_dropbehind(folio);
folio_end_dropbehind(folio);
- acct_reclaim_writeback(folio);
folio_put(folio);
}
EXPORT_SYMBOL(folio_end_writeback);
--
2.51.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v5 3/3] NFS: Enable use of the RWF_DONTCACHE flag on the NFS client
2025-09-10 1:53 ` [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 1/3] filemap: Add a helper for filesystems implementing dropbehind Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 2/3] filemap: Add a version of folio_end_writeback that ignores dropbehind Trond Myklebust
@ 2025-09-10 1:53 ` Trond Myklebust
2025-09-10 1:59 ` [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE Trond Myklebust
3 siblings, 0 replies; 5+ messages in thread
From: Trond Myklebust @ 2025-09-10 1:53 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-fsdevel, Anna Schumaker
From: Trond Myklebust <trond.myklebust@hammerspace.com>
The NFS client needs to defer dropbehind until after any writes to the
folio have been persisted on the server. Since this may be a 2 step
process, use folio_end_writeback_no_dropbehind() to allow release of the
writeback flag, and then call folio_end_dropbehind() once the COMMIT is
done.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
fs/nfs/file.c | 9 +++++----
fs/nfs/nfs4file.c | 1 +
fs/nfs/write.c | 4 +++-
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 8059ece82468..9025c93bcaf1 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -361,6 +361,8 @@ static bool nfs_want_read_modify_write(struct file *file, struct folio *folio,
if (pnfs_ld_read_whole_page(file_inode(file)))
return true;
+ if (folio_test_dropbehind(folio))
+ return false;
/* Open for reading too? */
if (file->f_mode & FMODE_READ)
return true;
@@ -380,7 +382,6 @@ static int nfs_write_begin(const struct kiocb *iocb,
loff_t pos, unsigned len, struct folio **foliop,
void **fsdata)
{
- fgf_t fgp = FGP_WRITEBEGIN;
struct folio *folio;
struct file *file = iocb->ki_filp;
int once_thru = 0;
@@ -390,10 +391,8 @@ static int nfs_write_begin(const struct kiocb *iocb,
file, mapping->host->i_ino, len, (long long) pos);
nfs_truncate_last_folio(mapping, i_size_read(mapping->host), pos);
- fgp |= fgf_set_order(len);
start:
- folio = __filemap_get_folio(mapping, pos >> PAGE_SHIFT, fgp,
- mapping_gfp_mask(mapping));
+ folio = write_begin_get_folio(iocb, mapping, pos >> PAGE_SHIFT, len);
if (IS_ERR(folio))
return PTR_ERR(folio);
*foliop = folio;
@@ -405,6 +404,7 @@ static int nfs_write_begin(const struct kiocb *iocb,
} else if (!once_thru &&
nfs_want_read_modify_write(file, folio, pos, len)) {
once_thru = 1;
+ folio_clear_dropbehind(folio);
ret = nfs_read_folio(file, folio);
folio_put(folio);
if (!ret)
@@ -949,5 +949,6 @@ const struct file_operations nfs_file_operations = {
.splice_write = iter_file_splice_write,
.check_flags = nfs_check_flags,
.setlease = simple_nosetlease,
+ .fop_flags = FOP_DONTCACHE,
};
EXPORT_SYMBOL_GPL(nfs_file_operations);
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index c9a0d1e420c6..7f43e890d356 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -456,4 +456,5 @@ const struct file_operations nfs4_file_operations = {
#else
.llseek = nfs_file_llseek,
#endif
+ .fop_flags = FOP_DONTCACHE,
};
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 647c53d1418a..a671de3dda07 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -296,7 +296,7 @@ static void nfs_folio_end_writeback(struct folio *folio)
{
struct nfs_server *nfss = NFS_SERVER(folio->mapping->host);
- folio_end_writeback(folio);
+ folio_end_writeback_no_dropbehind(folio);
if (atomic_long_dec_return(&nfss->writeback) <
NFS_CONGESTION_OFF_THRESH) {
nfss->write_congested = 0;
@@ -745,6 +745,8 @@ static void nfs_inode_remove_request(struct nfs_page *req)
clear_bit(PG_MAPPED, &req->wb_head->wb_flags);
}
spin_unlock(&mapping->i_private_lock);
+
+ folio_end_dropbehind(folio);
}
nfs_page_group_unlock(req);
--
2.51.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE
2025-09-10 1:53 ` [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE Trond Myklebust
` (2 preceding siblings ...)
2025-09-10 1:53 ` [PATCH v5 3/3] NFS: Enable use of the RWF_DONTCACHE flag on the NFS client Trond Myklebust
@ 2025-09-10 1:59 ` Trond Myklebust
3 siblings, 0 replies; 5+ messages in thread
From: Trond Myklebust @ 2025-09-10 1:59 UTC (permalink / raw)
To: Andrew Morton; +Cc: linux-mm, linux-fsdevel, Anna Schumaker, linux-nfs
Hi Andrew,
On Tue, 2025-09-09 at 21:53 -0400, Trond Myklebust wrote:
> From: Trond Myklebust <trond.myklebust@hammerspace.com>
>
> The main issue is allowing support on 2 stage writes (i.e. unstable
> WRITE followed by a COMMIT) since those don't follow the current
> assumption that the 'dropbehind' flag can be fulfilled as soon as the
> writeback lock is dropped.
>
> v2:
> - Make use of the new iocb parameter for nfs_write_begin()
> v3:
> - Set/clear PG_DROPBEHIND on the head of the nfs_page group
> - Simplify helper folio_end_dropbehind
> v4:
> - Replace filemap_end_dropbehind_write() with folio_end_dropbehind()
> - Add a helper to replace folio_end_writeback with an equivalent
> that
> does not attempt to interpret the dropbehind flag
> - Keep the folio dropbehind flag set until the NFS client is ready
> to
> call folio_end_dropbehind.
> - Don't try to do a read-modify-write in nfs_write_begin() if the
> folio
> has the dropbehind flag set.
> v5:
> - Change helper function export types to EXPORT_SYMBOL_GPL
>
> Trond Myklebust (3):
> filemap: Add a helper for filesystems implementing dropbehind
> filemap: Add a version of folio_end_writeback that ignores
> dropbehind
> NFS: Enable use of the RWF_DONTCACHE flag on the NFS client
>
> fs/nfs/file.c | 9 +++++----
> fs/nfs/nfs4file.c | 1 +
> fs/nfs/write.c | 4 +++-
> include/linux/pagemap.h | 2 ++
> mm/filemap.c | 34 ++++++++++++++++++++++++++--------
> 5 files changed, 37 insertions(+), 13 deletions(-)
Since the above series has already done the rounds in the linux-nfs and
linux-fsdevel mailing lists, could you please ask you to shepherd it in
to the 6.18 merge window? As you can see above the larger set of
changes are to mm/filemap.c rather than being NFS specific.
Cheers
Trond
--
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trondmy@kernel.org, trond.myklebust@hammerspace.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-09-10 1:59 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <cover.1755612705.git.trond.myklebust@hammerspace.com>
2025-09-10 1:53 ` [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 1/3] filemap: Add a helper for filesystems implementing dropbehind Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 2/3] filemap: Add a version of folio_end_writeback that ignores dropbehind Trond Myklebust
2025-09-10 1:53 ` [PATCH v5 3/3] NFS: Enable use of the RWF_DONTCACHE flag on the NFS client Trond Myklebust
2025-09-10 1:59 ` [PATCH v5 0/3] Initial NFS client support for RWF_DONTCACHE Trond Myklebust
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox