[CIFS] Honor the AT_SYNC_TYPE flags
diff mbox series

Message ID CAH2r5ms3dnvhH1L145krNgMZxoe-E58eAW0=vEBpp6Grfu2H0w@mail.gmail.com
State New
Headers show
Series
  • [CIFS] Honor the AT_SYNC_TYPE flags
Related show

Commit Message

Steve French Feb. 19, 2020, 5:04 a.m. UTC
cifs.ko should not ignore the SYNC flags in getattr

    Check the AT_STATX_FORCE_SYNC flag and force an attribute
    revalidation if requested by the caller, and if the caller
    specificies AT_STATX_DONT_SYNC only revalidate cached attributes
    if required.  In addition do not flush writes in getattr (which
    can be expensive) if size or timestamps not requested by the
    caller.

Comments

Aurelien Aptel Feb. 20, 2020, 4:15 p.m. UTC | #1
Reviewed-by: Aurelien Aptel <aaptel@suse.com>

Patch
diff mbox series

From 29361590ed10fe5db2b02574b19d3ed8afec5bf4 Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@microsoft.com>
Date: Tue, 18 Feb 2020 18:07:57 -0600
Subject: [PATCH] cifs: do not ignore the SYNC flags in getattr

Check the AT_STATX_FORCE_SYNC flag and force an attribute
revalidation if requested by the caller, and if the caller
specificies AT_STATX_DONT_SYNC only revalidate cached attributes
if required.  In addition do not flush writes in getattr (which
can be expensive) if size or timestamps not requested by the
caller.

Signed-off-by: Steve French <stfrench@microsoft.com>
---
 fs/cifs/inode.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 1212ace05258..4fed7a9117c6 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2148,8 +2148,9 @@  int cifs_getattr(const struct path *path, struct kstat *stat,
 	 * We need to be sure that all dirty pages are written and the server
 	 * has actual ctime, mtime and file length.
 	 */
-	if (!CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping &&
-	    inode->i_mapping->nrpages != 0) {
+	if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE)) &&
+	    !CIFS_CACHE_READ(CIFS_I(inode)) &&
+	    inode->i_mapping && inode->i_mapping->nrpages != 0) {
 		rc = filemap_fdatawait(inode->i_mapping);
 		if (rc) {
 			mapping_set_error(inode->i_mapping, rc);
@@ -2157,9 +2158,20 @@  int cifs_getattr(const struct path *path, struct kstat *stat,
 		}
 	}
 
-	rc = cifs_revalidate_dentry_attr(dentry);
-	if (rc)
-		return rc;
+	if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_FORCE_SYNC)
+		CIFS_I(inode)->time = 0; /* force revalidate */
+
+	/*
+	 * If the caller doesn't require syncing, only sync if
+	 * necessary (e.g. due to earlier truncate or setattr
+	 * invalidating the cached metadata)
+	 */
+	if (((flags & AT_STATX_SYNC_TYPE) != AT_STATX_DONT_SYNC) ||
+	    (CIFS_I(inode)->time == 0)) {
+		rc = cifs_revalidate_dentry_attr(dentry);
+		if (rc)
+			return rc;
+	}
 
 	generic_fillattr(inode, stat);
 	stat->blksize = cifs_sb->bsize;
-- 
2.20.1