Commit 8867fe58 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Al Viro

nfs: clean up ->create in nfs_rpc_ops

Don't pass nfs_open_context() to ->create().  Only the NFS4 implementation
needed that and only because it wanted to return an open file using open
intents.  That task has been replaced by ->atomic_open so it is not necessary
anymore to pass the context to the create rpc operation.

Despite nfs4_proc_create apparently being okay with a NULL context it Oopses
somewhere down the call chain.  So allocate a context here.
Signed-off-by: default avatarMiklos Szeredi <mszeredi@suse.cz>
CC: Trond Myklebust <Trond.Myklebust@netapp.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 0dd2b474
...@@ -114,10 +114,8 @@ const struct inode_operations nfs3_dir_inode_operations = { ...@@ -114,10 +114,8 @@ const struct inode_operations nfs3_dir_inode_operations = {
static struct file *nfs_atomic_open(struct inode *, struct dentry *, static struct file *nfs_atomic_open(struct inode *, struct dentry *,
struct opendata *, unsigned, umode_t, struct opendata *, unsigned, umode_t,
bool *); bool *);
static int nfs4_create(struct inode *dir, struct dentry *dentry,
umode_t mode, struct nameidata *nd);
const struct inode_operations nfs4_dir_inode_operations = { const struct inode_operations nfs4_dir_inode_operations = {
.create = nfs4_create, .create = nfs_create,
.lookup = nfs_lookup, .lookup = nfs_lookup,
.atomic_open = nfs_atomic_open, .atomic_open = nfs_atomic_open,
.link = nfs_link, .link = nfs_link,
...@@ -1582,42 +1580,6 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -1582,42 +1580,6 @@ static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
return nfs_lookup_revalidate(dentry, nd); return nfs_lookup_revalidate(dentry, nd);
} }
static int nfs4_create(struct inode *dir, struct dentry *dentry,
umode_t mode, struct nameidata *nd)
{
struct nfs_open_context *ctx = NULL;
struct iattr attr;
int error;
int open_flags = O_CREAT|O_EXCL;
dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE;
if (nd)
open_flags = nd->intent.open.flags;
ctx = create_nfs_open_context(dentry, open_flags);
error = PTR_ERR(ctx);
if (IS_ERR(ctx))
goto out_err_drop;
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx);
if (error != 0)
goto out_put_ctx;
put_nfs_open_context(ctx);
return 0;
out_put_ctx:
put_nfs_open_context(ctx);
out_err_drop:
d_drop(dentry);
return error;
}
#endif /* CONFIG_NFSV4 */ #endif /* CONFIG_NFSV4 */
/* /*
...@@ -1684,7 +1646,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, ...@@ -1684,7 +1646,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry,
if (nd) if (nd)
open_flags = nd->intent.open.flags; open_flags = nd->intent.open.flags;
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, NULL); error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags);
if (error != 0) if (error != 0)
goto out_err; goto out_err;
return 0; return 0;
......
...@@ -314,7 +314,7 @@ static void nfs3_free_createdata(struct nfs3_createdata *data) ...@@ -314,7 +314,7 @@ static void nfs3_free_createdata(struct nfs3_createdata *data)
*/ */
static int static int
nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags, struct nfs_open_context *ctx) int flags)
{ {
struct nfs3_createdata *data; struct nfs3_createdata *data;
umode_t mode = sattr->ia_mode; umode_t mode = sattr->ia_mode;
......
...@@ -2806,37 +2806,22 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page, ...@@ -2806,37 +2806,22 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page,
} }
/* /*
* Got race? * This is just for mknod. open(O_CREAT) will always do ->open_context().
* We will need to arrange for the VFS layer to provide an atomic open.
* Until then, this create/open method is prone to inefficiency and race
* conditions due to the lookup, create, and open VFS calls from sys_open()
* placed on the wire.
*
* Given the above sorry state of affairs, I'm simply sending an OPEN.
* The file will be opened again in the subsequent VFS open call
* (nfs4_proc_file_open).
*
* The open for read will just hang around to be used by any process that
* opens the file O_RDONLY. This will all be resolved with the VFS changes.
*/ */
static int static int
nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags, struct nfs_open_context *ctx) int flags)
{ {
struct dentry *de = dentry; struct nfs_open_context *ctx;
struct nfs4_state *state; struct nfs4_state *state;
struct rpc_cred *cred = NULL;
fmode_t fmode = 0;
int status = 0; int status = 0;
if (ctx != NULL) { ctx = alloc_nfs_open_context(dentry, FMODE_READ);
cred = ctx->cred; if (IS_ERR(ctx))
de = ctx->dentry; return PTR_ERR(ctx);
fmode = ctx->mode;
}
sattr->ia_mode &= ~current_umask(); sattr->ia_mode &= ~current_umask();
state = nfs4_do_open(dir, de, fmode, flags, sattr, cred, NULL); state = nfs4_do_open(dir, dentry, ctx->mode, flags, sattr, ctx->cred, NULL);
d_drop(dentry); d_drop(dentry);
if (IS_ERR(state)) { if (IS_ERR(state)) {
status = PTR_ERR(state); status = PTR_ERR(state);
...@@ -2844,11 +2829,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, ...@@ -2844,11 +2829,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
} }
d_add(dentry, igrab(state->inode)); d_add(dentry, igrab(state->inode));
nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
if (ctx != NULL) ctx->state = state;
ctx->state = state;
else
nfs4_close_sync(state, fmode);
out: out:
put_nfs_open_context(ctx);
return status; return status;
} }
......
...@@ -259,7 +259,7 @@ static void nfs_free_createdata(const struct nfs_createdata *data) ...@@ -259,7 +259,7 @@ static void nfs_free_createdata(const struct nfs_createdata *data)
static int static int
nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
int flags, struct nfs_open_context *ctx) int flags)
{ {
struct nfs_createdata *data; struct nfs_createdata *data;
struct rpc_message msg = { struct rpc_message msg = {
......
...@@ -1374,7 +1374,7 @@ struct nfs_rpc_ops { ...@@ -1374,7 +1374,7 @@ struct nfs_rpc_ops {
int (*readlink)(struct inode *, struct page *, unsigned int, int (*readlink)(struct inode *, struct page *, unsigned int,
unsigned int); unsigned int);
int (*create) (struct inode *, struct dentry *, int (*create) (struct inode *, struct dentry *,
struct iattr *, int, struct nfs_open_context *); struct iattr *, int);
int (*remove) (struct inode *, struct qstr *); int (*remove) (struct inode *, struct qstr *);
void (*unlink_setup) (struct rpc_message *, struct inode *dir); void (*unlink_setup) (struct rpc_message *, struct inode *dir);
void (*unlink_rpc_prepare) (struct rpc_task *, struct nfs_unlinkdata *); void (*unlink_rpc_prepare) (struct rpc_task *, struct nfs_unlinkdata *);
......
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