[PATCH v4 1/2] cifs: don't update i_size in cifs_do_truncate() without a cached handle

Frank Sorenson <[email protected]>
Newsgroups org.kernel.vger.stable,org.kernel.vger.linux-cifs
Message-ID <[email protected]>
If find_writable_file() returns NULL, cifs_file_flush() returns 0
without issuing set_file_size, and the outer if (!rc) block sets i_size
to 0 before the server is told to truncate.  If the subsequent
cifs_open() fails, the inode is stranded at size 0 while the server
file is unchanged.

Move netfs_resize_file() and cifs_setsize() inside the if (cfile) arm
so they only run after a successful set_file_size().  In the no-handle
else branch, call truncate_inode_pages() to evict stale pages before
the O_TRUNC open: cifs_invalidate_cache() is fscache-only and does not
touch the VFS page cache, so without it old pages persist and may be
served as stale data after a later file extension.

Fixes: 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC")
Cc: [email protected]
Cc: Paulo Alcantara <[email protected]>
Signed-off-by: Frank Sorenson <[email protected]>
---
 fs/smb/client/file.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 389083f9ce00..05aeb9d94ffe 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -1012,10 +1012,20 @@ 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) {
+				netfs_resize_file(&cinode->netfs, 0, true);
+				cifs_setsize(inode, 0);
+				cifs_invalidate_cache(inode, 0);
+			}
+		} else {
+			/*
+			 * No cached handle; the server truncates as part of the
+			 * O_TRUNC open request that follows.  Evict stale pages
+			 * from the page cache now so they cannot be served as
+			 * stale data after the file is later extended; i_size is
+			 * updated from the server's open response.
+			 */
+			truncate_inode_pages(inode->i_mapping, 0);
 			cifs_invalidate_cache(inode, 0);
 		}
 	}
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.