diff options
author | Steve French <stfrench@microsoft.com> | 2020-02-18 18:07:57 -0600 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2020-03-22 22:49:09 -0500 |
commit | ffdec8d64291c5d2e61da96cc64fbb57469fd5cf (patch) | |
tree | 14f8f443d59f75a5d1678fe0ed4001a251d94d81 /fs/cifs | |
parent | 16fbf79b0f83bc752cee8589279f1ebfe57b3b6e (diff) |
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.
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/inode.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b16f8d23e97b..aad7d2cad9a0 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; |