* [PATCH v5] cifs: don't update i_size in cifs_do_truncate without a cached handle
[not found] <c5ae6c999664ec603d3ca6aa8a226439d89eed48@manguebit.org>
@ 2026-08-27 1:57 ` Frank Sorenson
2026-08-28 23:10 ` Paulo Alcantara
0 siblings, 1 reply; 2+ messages in thread
From: Frank Sorenson @ 2026-08-27 1:57 UTC (permalink / raw)
To: linux-cifs; +Cc: pc, linkinjeon, stable
If find_writable_file() returns null, cifs_file_flush will return
0 without issuing set_file_size, and the outer 'if (!rc)' block
will set i_size to 0 before telling the server to truncate. If
the cifs_open() then fails, the inode will have size 0, while
the server file is unchanged.
Move the netfs_resize_file() and cifs_setsize() into the 'if
(cfile)', so they only run after a successful set_file_size.
In the no-handle else branch, evict stale pages with
truncate_inode_pages before the O_TRUNC open to dispose of old
cache pages, and let the open response set the i_size.
Fixes: 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
---
v5 changes:
- take inode_lock/filemap_invalidate_lock as required
fs/smb/client/file.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 389083f9ce00..100acc76e9be 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -1012,10 +1012,26 @@ static int cifs_do_truncate(const unsigned int xid, struct dentry *dentry)
server = tcon->ses->server;
rc = server->ops->set_file_size(xid, tcon,
cfile, 0, false);
- }
- if (!rc) {
- netfs_resize_file(&cinode->netfs, 0, true);
- cifs_setsize(inode, 0);
+ if (!rc) {
+ inode_lock(inode);
+ filemap_invalidate_lock(inode->i_mapping);
+ netfs_resize_file(&cinode->netfs, 0, true);
+ cifs_setsize(inode, 0);
+ filemap_invalidate_unlock(inode->i_mapping);
+ inode_unlock(inode);
+ cifs_invalidate_cache(inode, 0);
+ }
+ } else {
+ /*
+ * No cached handle; evict stale pages so they can't
+ * be served after the file is later extended; let
+ * the server's O_TRUNC open response set the i_size
+ */
+ inode_lock(inode);
+ filemap_invalidate_lock(inode->i_mapping);
+ truncate_inode_pages(inode->i_mapping, 0);
+ filemap_invalidate_unlock(inode->i_mapping);
+ inode_unlock(inode);
cifs_invalidate_cache(inode, 0);
}
}
--
2.55.0
^ permalink raw reply related [flat|nested] 2+ messages in thread