]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
NFS: nfs_invalidate_folio() must observe the offset and size arguments
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 3 Sep 2025 15:48:57 +0000 (11:48 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 19 Sep 2025 14:35:44 +0000 (16:35 +0200)
[ Upstream commit b7b8574225e9d2b5f1fb5483886ab797892f43b5 ]

If we're truncating part of the folio, then we need to write out the
data on the part that is not covered by the cancellation.

Fixes: d47992f86b30 ("mm: change invalidatepage prototype to accept length")
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/file.c
fs/nfs/write.c

index 033feeab8c346ee89ad001487d543d78a3fe7b3d..a16a619fb8c33bb1e009eec4c1a1ac6443dd014c 100644 (file)
@@ -437,10 +437,11 @@ static void nfs_invalidate_folio(struct folio *folio, size_t offset,
        dfprintk(PAGECACHE, "NFS: invalidate_folio(%lu, %zu, %zu)\n",
                 folio->index, offset, length);
 
-       if (offset != 0 || length < folio_size(folio))
-               return;
        /* Cancel any unstarted writes on this page */
-       nfs_wb_folio_cancel(inode, folio);
+       if (offset != 0 || length < folio_size(folio))
+               nfs_wb_folio(inode, folio);
+       else
+               nfs_wb_folio_cancel(inode, folio);
        folio_wait_private_2(folio); /* [DEPRECATED] */
        trace_nfs_invalidate_folio(inode, folio_pos(folio) + offset, length);
 }
index 2b6b3542405c3013b0c708d0f786bdc48b6a9b5f..fd86546fafd3f85a49600d35786a345dae08d973 100644 (file)
@@ -2058,6 +2058,7 @@ int nfs_wb_folio_cancel(struct inode *inode, struct folio *folio)
                 * release it */
                nfs_inode_remove_request(req);
                nfs_unlock_and_release_request(req);
+               folio_cancel_dirty(folio);
        }
 
        return ret;