summaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@hammerspace.com>2018-05-10 10:08:36 -0400
committerTrond Myklebust <trond.myklebust@hammerspace.com>2018-05-28 13:29:19 -0400
commit479219218fbe0a74bc36310fefc5ac6439c7cece (patch)
treef54fcde2b38595d86aae6f0e78db36a7f294fcbf /fs/nfs/dir.c
parent786b71f5b754273ccef6d9462e52062b3e1f9877 (diff)
downloadlinux-479219218fbe0a74bc36310fefc5ac6439c7cece.tar.bz2
NFS: Optimise away the close-to-open GETATTR when we have NFSv4 OPEN
NFSv4 should not need to perform an extra close-to-open GETATTR as part of the process of looking up a regular file, since the OPEN call will do that for us. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 73f8b43d988c..4a73bd8b4517 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1012,13 +1012,25 @@ int nfs_lookup_verify_inode(struct inode *inode, unsigned int flags)
if (IS_AUTOMOUNT(inode))
return 0;
+
+ if (flags & LOOKUP_OPEN) {
+ switch (inode->i_mode & S_IFMT) {
+ case S_IFREG:
+ /* A NFSv4 OPEN will revalidate later */
+ if (server->caps & NFS_CAP_ATOMIC_OPEN)
+ goto out;
+ /* Fallthrough */
+ case S_IFDIR:
+ if (server->flags & NFS_MOUNT_NOCTO)
+ break;
+ /* NFS close-to-open cache consistency validation */
+ goto out_force;
+ }
+ }
+
/* VFS wants an on-the-wire revalidation */
if (flags & LOOKUP_REVAL)
goto out_force;
- /* This is an open(2) */
- if ((flags & LOOKUP_OPEN) && !(server->flags & NFS_MOUNT_NOCTO) &&
- (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)))
- goto out_force;
out:
return (inode->i_nlink == 0) ? -ENOENT : 0;
out_force: