summaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-12-05 00:34:34 +0100
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-12-05 00:34:34 +0100
commit1cd9cb05f96e526f41bb4704caa95dc40ed08c5d (patch)
treebce7b634a76c12c695f4b69551709ec5c155f393 /fs/nfs/dir.c
parentNFS: Fix incorrect size revalidation when holding a delegation (diff)
downloadlinux-1cd9cb05f96e526f41bb4704caa95dc40ed08c5d.tar.xz
linux-1cd9cb05f96e526f41bb4704caa95dc40ed08c5d.zip
NFS: Only look at the change attribute cache state in nfs_check_verifier
When looking at whether or not our dcache is valid, we really don't care about the general state of the directory attribute cache. Instead, we we only care about the state of the change attribute. This fixes a performance issue when the client is responsible for changing the directory contents; a number of NFSv4 operations will atomically update the directory change attribute, but may not return all the other attributes. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f5702457c052..7483722162fa 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1030,8 +1030,6 @@ EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate);
static int nfs_check_verifier(struct inode *dir, struct dentry *dentry,
int rcu_walk)
{
- int ret;
-
if (IS_ROOT(dentry))
return 1;
if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
@@ -1039,12 +1037,12 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry,
if (!nfs_verify_change_attribute(dir, dentry->d_time))
return 0;
/* Revalidate nfsi->cache_change_attribute before we declare a match */
- if (rcu_walk)
- ret = nfs_revalidate_inode_rcu(NFS_SERVER(dir), dir);
- else
- ret = nfs_revalidate_inode(NFS_SERVER(dir), dir);
- if (ret < 0)
- return 0;
+ if (nfs_mapping_need_revalidate_inode(dir)) {
+ if (rcu_walk)
+ return 0;
+ if (__nfs_revalidate_inode(NFS_SERVER(dir), dir) < 0)
+ return 0;
+ }
if (!nfs_verify_change_attribute(dir, dentry->d_time))
return 0;
return 1;