Commit 00e1e0ae authored by Trond Myklebust's avatar Trond Myklebust

NFS: cleanup create()

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 906fd2d2
......@@ -997,7 +997,6 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
struct nameidata *nd)
{
struct iattr attr;
struct inode *inode;
int error;
int open_flags = 0;
......@@ -1012,18 +1011,17 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
lock_kernel();
nfs_begin_data_update(dir);
inode = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
nfs_end_data_update(dir);
if (!IS_ERR(inode)) {
d_instantiate(dentry, inode);
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
error = 0;
} else {
error = PTR_ERR(inode);
d_drop(dentry);
}
if (error != 0)
goto out_err;
nfs_renew_times(dentry);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
unlock_kernel();
return 0;
out_err:
unlock_kernel();
d_drop(dentry);
return error;
}
......
......@@ -295,7 +295,7 @@ static int nfs3_proc_commit(struct nfs_write_data *cdata)
* Create a regular file.
* For now, we don't implement O_EXCL.
*/
static struct inode *
static int
nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags)
{
......@@ -342,29 +342,19 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
break;
case NFS3_CREATE_UNCHECKED:
goto exit;
goto out;
}
goto again;
}
exit:
dprintk("NFS reply create: %d\n", status);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
if (status != 0)
goto out;
if (fhandle.size == 0 || !(fattr.valid & NFS_ATTR_FATTR)) {
status = nfs3_proc_lookup(dir, &dentry->d_name, &fhandle, &fattr);
if (status != 0)
goto out;
}
/* When we created the file with exclusive semantics, make
* sure we set the attributes afterwards. */
if (arg.createmode == NFS3_CREATE_EXCLUSIVE) {
struct nfs3_sattrargs arg = {
.fh = &fhandle,
.sattr = sattr,
};
dprintk("NFS call setattr (post-create)\n");
if (!(sattr->ia_valid & ATTR_ATIME_SET))
......@@ -375,20 +365,13 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
/* Note: we could use a guarded setattr here, but I'm
* not sure this buys us anything (and I'd have
* to revamp the NFSv3 XDR code) */
fattr.valid = 0;
status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SETATTR,
&arg, &fattr, 0);
status = nfs3_proc_setattr(dentry, &fattr, sattr);
nfs_refresh_inode(dentry->d_inode, &fattr);
dprintk("NFS reply setattr (post-create): %d\n", status);
}
if (status == 0) {
struct inode *inode;
inode = nfs_fhget(dir->i_sb, &fhandle, &fattr);
if (inode)
return inode;
status = -ENOMEM;
}
out:
return ERR_PTR(status);
dprintk("NFS reply create: %d\n", status);
return status;
}
static int
......
......@@ -1434,38 +1434,37 @@ static int nfs4_proc_commit(struct nfs_write_data *cdata)
* opens the file O_RDONLY. This will all be resolved with the VFS changes.
*/
static struct inode *
static int
nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags)
{
struct inode *inode;
struct nfs4_state *state;
struct rpc_cred *cred;
int status = 0;
cred = rpcauth_lookupcred(NFS_SERVER(dir)->client->cl_auth, 0);
if (IS_ERR(cred))
return (struct inode *)cred;
if (IS_ERR(cred)) {
status = PTR_ERR(cred);
goto out;
}
state = nfs4_do_open(dir, dentry, flags, sattr, cred);
put_rpccred(cred);
if (IS_ERR(state)) {
inode = (struct inode *)state;
status = PTR_ERR(state);
goto out;
}
inode = state->inode;
d_instantiate(dentry, state->inode);
if (flags & O_EXCL) {
struct nfs_fattr fattr;
int status;
status = nfs4_do_setattr(NFS_SERVER(dir), &fattr,
NFS_FH(inode), sattr, state);
NFS_FH(state->inode), sattr, state);
if (status == 0)
goto out;
iput(inode);
inode = ERR_PTR(status);
} else if (flags != 0)
goto out;
nfs4_close_state(state, flags);
out:
return inode;
return status;
}
static int _nfs4_proc_remove(struct inode *dir, struct qstr *name)
......
......@@ -212,7 +212,7 @@ static int nfs_proc_write(struct nfs_write_data *wdata)
return status < 0? status : wdata->res.count;
}
static struct inode *
static int
nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags)
{
......@@ -233,15 +233,10 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
fattr.valid = 0;
dprintk("NFS call create %s\n", dentry->d_name.name);
status = rpc_call(NFS_CLIENT(dir), NFSPROC_CREATE, &arg, &res, 0);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
dprintk("NFS reply create: %d\n", status);
if (status == 0) {
struct inode *inode;
inode = nfs_fhget(dir->i_sb, &fhandle, &fattr);
if (inode)
return inode;
status = -ENOMEM;
}
return ERR_PTR(status);
return status;
}
/*
......
......@@ -682,7 +682,7 @@ struct nfs_rpc_ops {
int (*read) (struct nfs_read_data *);
int (*write) (struct nfs_write_data *);
int (*commit) (struct nfs_write_data *);
struct inode * (*create) (struct inode *, struct dentry *,
int (*create) (struct inode *, struct dentry *,
struct iattr *, int);
int (*remove) (struct inode *, struct qstr *);
int (*unlink_setup) (struct rpc_message *,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment