Paulo Alcantara ac6d95
From 57c55cd7c77b81827757fdbe8dda8c3927c52b4e Mon Sep 17 00:00:00 2001
Paulo Alcantara ac6d95
From: Ronnie Sahlberg <lsahlber@redhat.com>
Paulo Alcantara ac6d95
Date: Thu, 24 May 2018 06:54:27 +1000
Paulo Alcantara ac6d95
Subject: [PATCH] cifs: invalidate cache when we truncate a file
Paulo Alcantara ac6d95
Git-commit: 57c55cd7c77b81827757fdbe8dda8c3927c52b4e
Paulo Alcantara ac6d95
Patch-mainline: v4.18-rc1
Paulo Alcantara ac6d95
References: bsc#1051510
Paulo Alcantara ac6d95
Paulo Alcantara ac6d95
RHBZ: 1566345
Paulo Alcantara ac6d95
Paulo Alcantara ac6d95
When truncating a file we always do this synchronously to the server.
Paulo Alcantara ac6d95
Thus we need to make sure that the cached inode metadata is
Paulo Alcantara ac6d95
marked as stale so that on next getattr we will refresh the metadata.
Paulo Alcantara ac6d95
In this particular bug we want to ensure that both ctime and mtime
Paulo Alcantara ac6d95
are updated and become visible to the application after a truncate.
Paulo Alcantara ac6d95
Paulo Alcantara ac6d95
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Paulo Alcantara ac6d95
Signed-off-by: Steve French <stfrench@microsoft.com>
Paulo Alcantara ac6d95
Reported-by: Xiaoli Feng <xifeng@redhat.com>
Paulo Alcantara ac6d95
Acked-by: Paulo Alcantara <palcantara@suse.de>
Paulo Alcantara ac6d95
---
Paulo Alcantara ac6d95
 fs/cifs/inode.c | 13 +++++++++----
Paulo Alcantara ac6d95
 1 file changed, 9 insertions(+), 4 deletions(-)
Paulo Alcantara ac6d95
Paulo Alcantara ac6d95
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
Paulo Alcantara ac6d95
index 3c371f7f5963..745fd7fe8d0e 100644
Paulo Alcantara ac6d95
--- a/fs/cifs/inode.c
Paulo Alcantara ac6d95
+++ b/fs/cifs/inode.c
Paulo Alcantara ac6d95
@@ -746,7 +746,8 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
Paulo Alcantara ac6d95
 	cifs_dbg(FYI, "Getting info on %s\n", full_path);
Paulo Alcantara ac6d95
 
Paulo Alcantara ac6d95
 	if ((data == NULL) && (*inode != NULL)) {
Paulo Alcantara ac6d95
-		if (CIFS_CACHE_READ(CIFS_I(*inode))) {
Paulo Alcantara ac6d95
+		if (CIFS_CACHE_READ(CIFS_I(*inode)) &&
Paulo Alcantara ac6d95
+		    CIFS_I(*inode)->time != 0) {
Paulo Alcantara ac6d95
 			cifs_dbg(FYI, "No need to revalidate cached inode sizes\n");
Paulo Alcantara ac6d95
 			goto cgii_exit;
Paulo Alcantara ac6d95
 		}
Paulo Alcantara ac6d95
@@ -1857,15 +1858,15 @@ cifs_inode_needs_reval(struct inode *inode)
Paulo Alcantara ac6d95
 	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
Paulo Alcantara ac6d95
 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
Paulo Alcantara ac6d95
 
Paulo Alcantara ac6d95
+	if (cifs_i->time == 0)
Paulo Alcantara ac6d95
+		return true;
Paulo Alcantara ac6d95
+
Paulo Alcantara ac6d95
 	if (CIFS_CACHE_READ(cifs_i))
Paulo Alcantara ac6d95
 		return false;
Paulo Alcantara ac6d95
 
Paulo Alcantara ac6d95
 	if (!lookupCacheEnabled)
Paulo Alcantara ac6d95
 		return true;
Paulo Alcantara ac6d95
 
Paulo Alcantara ac6d95
-	if (cifs_i->time == 0)
Paulo Alcantara ac6d95
-		return true;
Paulo Alcantara ac6d95
-
Paulo Alcantara ac6d95
 	if (!cifs_sb->actimeo)
Paulo Alcantara ac6d95
 		return true;
Paulo Alcantara ac6d95
 
Paulo Alcantara ac6d95
@@ -2104,10 +2105,14 @@ static int cifs_truncate_page(struct address_space *mapping, loff_t from)
Paulo Alcantara ac6d95
 
Paulo Alcantara ac6d95
 static void cifs_setsize(struct inode *inode, loff_t offset)
Paulo Alcantara ac6d95
 {
Paulo Alcantara ac6d95
+	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
Paulo Alcantara ac6d95
+
Paulo Alcantara ac6d95
 	spin_lock(&inode->i_lock);
Paulo Alcantara ac6d95
 	i_size_write(inode, offset);
Paulo Alcantara ac6d95
 	spin_unlock(&inode->i_lock);
Paulo Alcantara ac6d95
 
Paulo Alcantara ac6d95
+	/* Cached inode must be refreshed on truncate */
Paulo Alcantara ac6d95
+	cifs_i->time = 0;
Paulo Alcantara ac6d95
 	truncate_pagecache(inode, offset);
Paulo Alcantara ac6d95
 }
Paulo Alcantara ac6d95
 
Paulo Alcantara ac6d95
-- 
Paulo Alcantara ac6d95
2.20.1
Paulo Alcantara ac6d95