aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:17 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2005-10-18 17:20:17 -0400
commit02a913a73b52071e93f4b76db3e86138d19efffd (patch)
tree1dc1abbd2d8f57a6fd593dd252d6d7ecc7c811c5 /fs/nfs/dir.c
parent834f2a4a1554dc5b2598038b3fe8703defcbe467 (diff)
NFSv4: Eliminate nfsv4 open race...
Make NFSv4 return the fully initialized file pointer with the stateid that it created in the lookup w/intent. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c29
1 files changed, 13 insertions, 16 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index c70eabd6d17..a6e251f21fd 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -914,7 +914,6 @@ static int is_atomic_open(struct inode *dir, struct nameidata *nd)
914static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) 914static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
915{ 915{
916 struct dentry *res = NULL; 916 struct dentry *res = NULL;
917 struct inode *inode = NULL;
918 int error; 917 int error;
919 918
920 /* Check that we are indeed trying to open this file */ 919 /* Check that we are indeed trying to open this file */
@@ -928,8 +927,10 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
928 dentry->d_op = NFS_PROTO(dir)->dentry_ops; 927 dentry->d_op = NFS_PROTO(dir)->dentry_ops;
929 928
930 /* Let vfs_create() deal with O_EXCL */ 929 /* Let vfs_create() deal with O_EXCL */
931 if (nd->intent.open.flags & O_EXCL) 930 if (nd->intent.open.flags & O_EXCL) {
932 goto no_entry; 931 d_add(dentry, NULL);
932 goto out;
933 }
933 934
934 /* Open the file on the server */ 935 /* Open the file on the server */
935 lock_kernel(); 936 lock_kernel();
@@ -943,18 +944,18 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
943 944
944 if (nd->intent.open.flags & O_CREAT) { 945 if (nd->intent.open.flags & O_CREAT) {
945 nfs_begin_data_update(dir); 946 nfs_begin_data_update(dir);
946 inode = nfs4_atomic_open(dir, dentry, nd); 947 res = nfs4_atomic_open(dir, dentry, nd);
947 nfs_end_data_update(dir); 948 nfs_end_data_update(dir);
948 } else 949 } else
949 inode = nfs4_atomic_open(dir, dentry, nd); 950 res = nfs4_atomic_open(dir, dentry, nd);
950 unlock_kernel(); 951 unlock_kernel();
951 if (IS_ERR(inode)) { 952 if (IS_ERR(res)) {
952 error = PTR_ERR(inode); 953 error = PTR_ERR(res);
953 switch (error) { 954 switch (error) {
954 /* Make a negative dentry */ 955 /* Make a negative dentry */
955 case -ENOENT: 956 case -ENOENT:
956 inode = NULL; 957 res = NULL;
957 break; 958 goto out;
958 /* This turned out not to be a regular file */ 959 /* This turned out not to be a regular file */
959 case -ELOOP: 960 case -ELOOP:
960 if (!(nd->intent.open.flags & O_NOFOLLOW)) 961 if (!(nd->intent.open.flags & O_NOFOLLOW))
@@ -962,13 +963,9 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
962 /* case -EISDIR: */ 963 /* case -EISDIR: */
963 /* case -EINVAL: */ 964 /* case -EINVAL: */
964 default: 965 default:
965 res = ERR_PTR(error);
966 goto out; 966 goto out;
967 } 967 }
968 } 968 } else if (res != NULL)
969no_entry:
970 res = d_add_unique(dentry, inode);
971 if (res != NULL)
972 dentry = res; 969 dentry = res;
973 nfs_renew_times(dentry); 970 nfs_renew_times(dentry);
974 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 971 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
@@ -1012,7 +1009,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1012 */ 1009 */
1013 lock_kernel(); 1010 lock_kernel();
1014 verifier = nfs_save_change_attribute(dir); 1011 verifier = nfs_save_change_attribute(dir);
1015 ret = nfs4_open_revalidate(dir, dentry, openflags); 1012 ret = nfs4_open_revalidate(dir, dentry, openflags, nd);
1016 if (!ret) 1013 if (!ret)
1017 nfs_set_verifier(dentry, verifier); 1014 nfs_set_verifier(dentry, verifier);
1018 unlock_kernel(); 1015 unlock_kernel();
@@ -1135,7 +1132,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
1135 1132
1136 lock_kernel(); 1133 lock_kernel();
1137 nfs_begin_data_update(dir); 1134 nfs_begin_data_update(dir);
1138 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags); 1135 error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, nd);
1139 nfs_end_data_update(dir); 1136 nfs_end_data_update(dir);
1140 if (error != 0) 1137 if (error != 0)
1141 goto out_err; 1138 goto out_err;