aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 3e64b98f3a93..e35c8199f82f 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -799,6 +799,9 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
799 goto out_bad; 799 goto out_bad;
800 } 800 }
801 801
802 if (nfs_have_delegation(inode, FMODE_READ))
803 goto out_set_verifier;
804
802 /* Force a full look up iff the parent directory has changed */ 805 /* Force a full look up iff the parent directory has changed */
803 if (!nfs_is_exclusive_create(dir, nd) && nfs_check_verifier(dir, dentry)) { 806 if (!nfs_is_exclusive_create(dir, nd) && nfs_check_verifier(dir, dentry)) {
804 if (nfs_lookup_verify_inode(inode, nd)) 807 if (nfs_lookup_verify_inode(inode, nd))
@@ -817,6 +820,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
817 if ((error = nfs_refresh_inode(inode, &fattr)) != 0) 820 if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
818 goto out_bad; 821 goto out_bad;
819 822
823out_set_verifier:
820 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 824 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
821 out_valid: 825 out_valid:
822 dput(parent); 826 dput(parent);
@@ -973,7 +977,7 @@ struct dentry_operations nfs4_dentry_operations = {
973 * Use intent information to determine whether we need to substitute 977 * Use intent information to determine whether we need to substitute
974 * the NFSv4-style stateful OPEN for the LOOKUP call 978 * the NFSv4-style stateful OPEN for the LOOKUP call
975 */ 979 */
976static int is_atomic_open(struct inode *dir, struct nameidata *nd) 980static int is_atomic_open(struct nameidata *nd)
977{ 981{
978 if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0) 982 if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0)
979 return 0; 983 return 0;
@@ -996,7 +1000,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
996 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); 1000 dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
997 1001
998 /* Check that we are indeed trying to open this file */ 1002 /* Check that we are indeed trying to open this file */
999 if (!is_atomic_open(dir, nd)) 1003 if (!is_atomic_open(nd))
1000 goto no_open; 1004 goto no_open;
1001 1005
1002 if (dentry->d_name.len > NFS_SERVER(dir)->namelen) { 1006 if (dentry->d_name.len > NFS_SERVER(dir)->namelen) {
@@ -1047,10 +1051,10 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1047 struct inode *dir; 1051 struct inode *dir;
1048 int openflags, ret = 0; 1052 int openflags, ret = 0;
1049 1053
1054 if (!is_atomic_open(nd))
1055 goto no_open;
1050 parent = dget_parent(dentry); 1056 parent = dget_parent(dentry);
1051 dir = parent->d_inode; 1057 dir = parent->d_inode;
1052 if (!is_atomic_open(dir, nd))
1053 goto no_open;
1054 /* We can't create new files in nfs_open_revalidate(), so we 1058 /* We can't create new files in nfs_open_revalidate(), so we
1055 * optimize away revalidation of negative dentries. 1059 * optimize away revalidation of negative dentries.
1056 */ 1060 */
@@ -1062,11 +1066,11 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1062 1066
1063 /* NFS only supports OPEN on regular files */ 1067 /* NFS only supports OPEN on regular files */
1064 if (!S_ISREG(inode->i_mode)) 1068 if (!S_ISREG(inode->i_mode))
1065 goto no_open; 1069 goto no_open_dput;
1066 openflags = nd->intent.open.flags; 1070 openflags = nd->intent.open.flags;
1067 /* We cannot do exclusive creation on a positive dentry */ 1071 /* We cannot do exclusive creation on a positive dentry */
1068 if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) 1072 if ((openflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL))
1069 goto no_open; 1073 goto no_open_dput;
1070 /* We can't create new files, or truncate existing ones here */ 1074 /* We can't create new files, or truncate existing ones here */
1071 openflags &= ~(O_CREAT|O_TRUNC); 1075 openflags &= ~(O_CREAT|O_TRUNC);
1072 1076
@@ -1081,10 +1085,9 @@ out:
1081 if (!ret) 1085 if (!ret)
1082 d_drop(dentry); 1086 d_drop(dentry);
1083 return ret; 1087 return ret;
1084no_open: 1088no_open_dput:
1085 dput(parent); 1089 dput(parent);
1086 if (inode != NULL && nfs_have_delegation(inode, FMODE_READ)) 1090no_open:
1087 return 1;
1088 return nfs_lookup_revalidate(dentry, nd); 1091 return nfs_lookup_revalidate(dentry, nd);
1089} 1092}
1090#endif /* CONFIG_NFSV4 */ 1093#endif /* CONFIG_NFSV4 */
@@ -1794,7 +1797,8 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
1794 cache = nfs_access_search_rbtree(inode, cred); 1797 cache = nfs_access_search_rbtree(inode, cred);
1795 if (cache == NULL) 1798 if (cache == NULL)
1796 goto out; 1799 goto out;
1797 if (!time_in_range(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo)) 1800 if (!nfs_have_delegation(inode, FMODE_READ) &&
1801 !time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
1798 goto out_stale; 1802 goto out_stale;
1799 res->jiffies = cache->jiffies; 1803 res->jiffies = cache->jiffies;
1800 res->cred = cache->cred; 1804 res->cred = cache->cred;