Commit f7c85868 authored by Al Viro's avatar Al Viro

fix mknod() on nfs4 (hopefully)

a) check the right flags in ->create() (LOOKUP_OPEN, not LOOKUP_CREATE)
b) default (!LOOKUP_OPEN) open_flags is O_CREAT|O_EXCL|FMODE_READ, not 0
c) lookup_instantiate_filp() should be done only with LOOKUP_OPEN;
otherwise we need to issue CLOSE, lest we leak stateid on server.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 51141598
...@@ -1567,7 +1567,7 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode, ...@@ -1567,7 +1567,7 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode,
struct nfs_open_context *ctx = NULL; struct nfs_open_context *ctx = NULL;
struct iattr attr; struct iattr attr;
int error; int error;
int open_flags = 0; int open_flags = O_CREAT|O_EXCL|FMODE_READ;
dfprintk(VFS, "NFS: create(%s/%ld), %s\n", dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
...@@ -1575,27 +1575,27 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode, ...@@ -1575,27 +1575,27 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode,
attr.ia_mode = mode; attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE; attr.ia_valid = ATTR_MODE;
if ((nd->flags & LOOKUP_CREATE) != 0) { if (nd && (nd->flags & LOOKUP_OPEN) != 0)
open_flags = nd->intent.open.flags; open_flags = nd->intent.open.flags;
ctx = create_nfs_open_context(dentry, open_flags); ctx = create_nfs_open_context(dentry, open_flags);
error = PTR_ERR(ctx); error = PTR_ERR(ctx);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
goto out_err_drop; goto out_err_drop;
}
error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx); error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, ctx);
if (error != 0) if (error != 0)
goto out_put_ctx; goto out_put_ctx;
if (ctx != NULL) { if (nd && (nd->flags & LOOKUP_OPEN) != 0) {
error = nfs_intent_set_file(nd, ctx); error = nfs_intent_set_file(nd, ctx);
if (error < 0) if (error < 0)
goto out_err; goto out_err;
} else {
put_nfs_open_context(ctx);
} }
return 0; return 0;
out_put_ctx: out_put_ctx:
if (ctx != NULL) put_nfs_open_context(ctx);
put_nfs_open_context(ctx);
out_err_drop: out_err_drop:
d_drop(dentry); d_drop(dentry);
out_err: out_err:
...@@ -1657,7 +1657,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, ...@@ -1657,7 +1657,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
{ {
struct iattr attr; struct iattr attr;
int error; int error;
int open_flags = 0; int open_flags = O_CREAT|O_EXCL|FMODE_READ;
dfprintk(VFS, "NFS: create(%s/%ld), %s\n", dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
dir->i_sb->s_id, dir->i_ino, dentry->d_name.name); dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
...@@ -1665,7 +1665,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode, ...@@ -1665,7 +1665,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
attr.ia_mode = mode; attr.ia_mode = mode;
attr.ia_valid = ATTR_MODE; attr.ia_valid = ATTR_MODE;
if ((nd->flags & LOOKUP_CREATE) != 0) if (nd && (nd->flags & LOOKUP_OPEN) != 0)
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, NULL);
......
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