diff options
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 24 |
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 | ||
823 | out_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 | */ |
976 | static int is_atomic_open(struct inode *dir, struct nameidata *nd) | 980 | static 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; |
1084 | no_open: | 1088 | no_open_dput: |
1085 | dput(parent); | 1089 | dput(parent); |
1086 | if (inode != NULL && nfs_have_delegation(inode, FMODE_READ)) | 1090 | no_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; |