summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2025-09-03 11:48:57 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2025-09-06 16:51:26 -0400
commitb7b8574225e9d2b5f1fb5483886ab797892f43b5 (patch)
tree2924b4420caa76576c7c050f29e03e21870b857c
parentca247c89900ae90207f4d321e260cd93b7c7d104 (diff)
NFS: nfs_invalidate_folio() must observe the offset and size arguments
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>
-rw-r--r--fs/nfs/file.c7
-rw-r--r--fs/nfs/write.c1
2 files changed, 5 insertions, 3 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index a3105f944a0e..8059ece82468 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -475,10 +475,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);
}
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 8b7c04737967..e359fbcdc8a0 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -2045,6 +2045,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;