summaryrefslogtreecommitdiff
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2010-09-17 10:56:50 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-09-17 10:56:50 -0400
commitcd9a1c0e5ac681871d64804f82291649e2a0accb (patch)
tree900c2bf6ba75c2a02af07091afcf4ba4cfdb2396 /fs/nfs/nfs4proc.c
parent859d5024f450686ad0a42ed3c06f2fa20295c9e6 (diff)
NFSv4: Clean up nfs4_atomic_open
Start moving the 'struct nameidata' dependent code out of the lower level NFS code in preparation for the removal of open intents. Instead of the struct nameidata, we pass down a partially initialised struct nfs_open_context that will be fully initialised by the atomic open upon success. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c40
1 files changed, 11 insertions, 29 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 089da5b5d20..38c3bed2240 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2025,39 +2025,17 @@ out_close:
}
struct dentry *
-nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr)
{
- struct path path = {
- .mnt = nd->path.mnt,
- .dentry = dentry,
- };
+ struct dentry *dentry = ctx->path.dentry;
struct dentry *parent;
- struct iattr attr;
- struct rpc_cred *cred;
struct nfs4_state *state;
struct dentry *res;
- int open_flags = nd->intent.open.flags;
- fmode_t fmode = open_flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC);
-
- if (nd->flags & LOOKUP_CREATE) {
- attr.ia_mode = nd->intent.open.create_mode;
- attr.ia_valid = ATTR_MODE;
- if (!IS_POSIXACL(dir))
- attr.ia_mode &= ~current_umask();
- } else {
- open_flags &= ~O_EXCL;
- attr.ia_valid = 0;
- BUG_ON(open_flags & O_CREAT);
- }
- cred = rpc_lookup_cred();
- if (IS_ERR(cred))
- return (struct dentry *)cred;
parent = dentry->d_parent;
/* Protect against concurrent sillydeletes */
nfs_block_sillyrename(parent);
- state = nfs4_do_open(dir, &path, fmode, open_flags, &attr, cred);
- put_rpccred(cred);
+ state = nfs4_do_open(dir, &ctx->path, ctx->mode, open_flags, attr, ctx->cred);
if (IS_ERR(state)) {
if (PTR_ERR(state) == -ENOENT) {
d_add(dentry, NULL);
@@ -2067,11 +2045,15 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
return (struct dentry *)state;
}
res = d_add_unique(dentry, igrab(state->inode));
- if (res != NULL)
- path.dentry = res;
- nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
+ if (res != NULL) {
+ struct dentry *dummy = ctx->path.dentry;
+
+ ctx->path.dentry = dget(res);
+ dput(dummy);
+ }
+ ctx->state = state;
+ nfs_set_verifier(ctx->path.dentry, nfs_save_change_attribute(dir));
nfs_unblock_sillyrename(parent);
- nfs4_intent_set_file(nd, &path, state, fmode);
return res;
}