NFSv4: Don't ignore the error return codes from nfs_intent_set_file
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Sat, 23 Oct 2010 15:24:25 +0000 (11:24 -0400)
committerTrond Myklebust <Trond.Myklebust@netapp.com>
Sat, 23 Oct 2010 19:27:17 +0000 (15:27 -0400)
If nfs_intent_set_file() returns an error, we usually want to pass that
back up the stack.

Also ensure that nfs_open_revalidate() returns '1' on success.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
fs/nfs/dir.c

index fe549f5ef20f007453d01888916b94c22fb54e5b..a847acf4d3cd3e6c6ef315d3b839dc7a3977a3c1 100644 (file)
@@ -1086,6 +1086,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
        struct dentry *res = NULL;
        struct inode *inode;
        int open_flags;
+       int err;
 
        dfprintk(VFS, "NFS: atomic_lookup(%s/%ld), %s\n",
                        dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
@@ -1119,9 +1120,8 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                if (!IS_POSIXACL(dir))
                        attr.ia_mode &= ~current_umask();
        } else {
-               open_flags &= ~O_EXCL;
+               open_flags &= ~(O_EXCL | O_CREAT);
                attr.ia_valid = 0;
-               BUG_ON(open_flags & O_CREAT);
        }
 
        /* Open the file on the server */
@@ -1150,13 +1150,18 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
                }
        }
        res = d_add_unique(dentry, inode);
+       nfs_unblock_sillyrename(dentry->d_parent);
        if (res != NULL) {
                dput(ctx->path.dentry);
                ctx->path.dentry = dget(res);
                dentry = res;
        }
-       nfs_intent_set_file(nd, ctx);
-       nfs_unblock_sillyrename(dentry->d_parent);
+       err = nfs_intent_set_file(nd, ctx);
+       if (err < 0) {
+               if (res != NULL)
+                       dput(res);
+               return ERR_PTR(err);
+       }
 out:
        nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
        return res;
@@ -1221,11 +1226,13 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
                }
        }
        iput(inode);
-       if (inode == dentry->d_inode) {
-               nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
-               nfs_intent_set_file(nd, ctx);
-       } else
+       if (inode != dentry->d_inode)
                goto out_drop;
+
+       nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+       ret = nfs_intent_set_file(nd, ctx);
+       if (ret >= 0)
+               ret = 1;
 out:
        dput(parent);
        return ret;
@@ -1262,20 +1269,24 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode,
                ctx = nameidata_to_nfs_open_context(dentry, nd);
                error = PTR_ERR(ctx);
                if (IS_ERR(ctx))
-                       goto out_err;
+                       goto out_err_drop;
        }
 
        error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx);
        if (error != 0)
                goto out_put_ctx;
-       if (ctx != NULL)
-               nfs_intent_set_file(nd, ctx);
+       if (ctx != NULL) {
+               error = nfs_intent_set_file(nd, ctx);
+               if (error < 0)
+                       goto out_err;
+       }
        return 0;
 out_put_ctx:
        if (ctx != NULL)
                put_nfs_open_context(ctx);
-out_err:
+out_err_drop:
        d_drop(dentry);
+out_err:
        return error;
 }