]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
NFS: Enable use of the RWF_DONTCACHE flag on the NFS client
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 6 Sep 2025 16:48:16 +0000 (12:48 -0400)
committerAnna Schumaker <anna.schumaker@oracle.com>
Tue, 23 Sep 2025 17:29:50 +0000 (13:29 -0400)
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>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
fs/nfs/file.c
fs/nfs/nfs4file.c
fs/nfs/write.c

index 579f2aaeca94709717ef13be89ebc2acbabd6cff..d020aab40c64ebda30d130b6acee1b9194621457 100644 (file)
@@ -363,6 +363,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;
@@ -382,7 +384,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;
@@ -394,10 +395,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)) {
                ret = PTR_ERR(folio);
                goto out;
@@ -411,6 +410,7 @@ start:
        } 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)
@@ -963,5 +963,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);
index c9a0d1e420c6cb17b209e3f7f48a12dd479dbc24..7f43e890d3564a000dab9365048a3e17dc96395c 100644 (file)
@@ -456,4 +456,5 @@ const struct file_operations nfs4_file_operations = {
 #else
        .llseek         = nfs_file_llseek,
 #endif
+       .fop_flags      = FOP_DONTCACHE,
 };
index 66acc52474356bb9f292f9222298c86f033385e8..ad588ed59c09b9cdaccdfb8322e1686cd34a10b4 100644 (file)
@@ -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;
@@ -748,6 +748,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);