aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2012-06-05 09:10:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-14 08:33:08 -0400
commit8867fe5899010a0c0ac36dadfdacf1072b1c990c (patch)
tree3af6bb8d50fb06a46a451ba23bde8dac98361c25 /fs/nfs/nfs4proc.c
parent0dd2b474d0b69d58859399b1df7fdc699ea005d4 (diff)
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: Miklos Szeredi <mszeredi@suse.cz> CC: Trond Myklebust <Trond.Myklebust@netapp.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c37
1 files changed, 10 insertions, 27 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 15fc7e4664ed..c157b2089b47 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2806,37 +2806,22 @@ static int nfs4_proc_readlink(struct inode *inode, struct page *page,
2806} 2806}
2807 2807
2808/* 2808/*
2809 * Got race? 2809 * This is just for mknod. open(O_CREAT) will always do ->open_context().
2810 * We will need to arrange for the VFS layer to provide an atomic open.
2811 * Until then, this create/open method is prone to inefficiency and race
2812 * conditions due to the lookup, create, and open VFS calls from sys_open()
2813 * placed on the wire.
2814 *
2815 * Given the above sorry state of affairs, I'm simply sending an OPEN.
2816 * The file will be opened again in the subsequent VFS open call
2817 * (nfs4_proc_file_open).
2818 *
2819 * The open for read will just hang around to be used by any process that
2820 * opens the file O_RDONLY. This will all be resolved with the VFS changes.
2821 */ 2810 */
2822
2823static int 2811static int
2824nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, 2812nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2825 int flags, struct nfs_open_context *ctx) 2813 int flags)
2826{ 2814{
2827 struct dentry *de = dentry; 2815 struct nfs_open_context *ctx;
2828 struct nfs4_state *state; 2816 struct nfs4_state *state;
2829 struct rpc_cred *cred = NULL;
2830 fmode_t fmode = 0;
2831 int status = 0; 2817 int status = 0;
2832 2818
2833 if (ctx != NULL) { 2819 ctx = alloc_nfs_open_context(dentry, FMODE_READ);
2834 cred = ctx->cred; 2820 if (IS_ERR(ctx))
2835 de = ctx->dentry; 2821 return PTR_ERR(ctx);
2836 fmode = ctx->mode; 2822
2837 }
2838 sattr->ia_mode &= ~current_umask(); 2823 sattr->ia_mode &= ~current_umask();
2839 state = nfs4_do_open(dir, de, fmode, flags, sattr, cred, NULL); 2824 state = nfs4_do_open(dir, dentry, ctx->mode, flags, sattr, ctx->cred, NULL);
2840 d_drop(dentry); 2825 d_drop(dentry);
2841 if (IS_ERR(state)) { 2826 if (IS_ERR(state)) {
2842 status = PTR_ERR(state); 2827 status = PTR_ERR(state);
@@ -2844,11 +2829,9 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
2844 } 2829 }
2845 d_add(dentry, igrab(state->inode)); 2830 d_add(dentry, igrab(state->inode));
2846 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 2831 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
2847 if (ctx != NULL) 2832 ctx->state = state;
2848 ctx->state = state;
2849 else
2850 nfs4_close_sync(state, fmode);
2851out: 2833out:
2834 put_nfs_open_context(ctx);
2852 return status; 2835 return status;
2853} 2836}
2854 2837