summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-10-23 11:24:25 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-10-23 15:27:17 -0400
commit898f635c4297e91ceac675d83c4a460f26118342 (patch)
tree1e6e1d3fb179fffa8f78a094a0db1e31e841ad19
parent6eaa61496fb3b93cceface7a296415fc4c030bce (diff)
NFSv4: Don't ignore the error return codes from nfs_intent_set_file
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>
-rw-r--r--fs/nfs/dir.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index fe549f5ef20f..a847acf4d3cd 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -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;
}