Commit f7c85868 authored by Al Viro's avatar Al Viro
Browse files

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
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -1567,7 +1567,7 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode,
	struct nfs_open_context *ctx = NULL;
	struct iattr attr;
	int error;
	int open_flags = 0;
	int open_flags = O_CREAT|O_EXCL|FMODE_READ;

	dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
			dir->i_sb->s_id, dir->i_ino, dentry->d_name.name);
@@ -1575,26 +1575,26 @@ static int nfs_open_create(struct inode *dir, struct dentry *dentry, int mode,
	attr.ia_mode = 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;

	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;
	if (ctx != NULL) {
	if (nd && (nd->flags & LOOKUP_OPEN) != 0) {
		error = nfs_intent_set_file(nd, ctx);
		if (error < 0)
			goto out_err;
	} else {
		put_nfs_open_context(ctx);
	}
	return 0;
out_put_ctx:
	if (ctx != NULL)
	put_nfs_open_context(ctx);
out_err_drop:
	d_drop(dentry);
@@ -1657,7 +1657,7 @@ static int nfs_create(struct inode *dir, struct dentry *dentry, int mode,
{
	struct iattr attr;
	int error;
	int open_flags = 0;
	int open_flags = O_CREAT|O_EXCL|FMODE_READ;

	dfprintk(VFS, "NFS: create(%s/%ld), %s\n",
			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,
	attr.ia_mode = 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;

	error = NFS_PROTO(dir)->create(dir, dentry, &attr, open_flags, NULL);