From 1ba106818615faddb63ba782f85f3498b9eb61c6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 26 Jun 2011 11:54:58 -0400 Subject: [PATCH] switch do_spufs_create() to user_path_create(), fix double-unlock Signed-off-by: Al Viro --- arch/powerpc/platforms/cell/spufs/inode.c | 29 ++++++++------------ arch/powerpc/platforms/cell/spufs/spufs.h | 2 +- arch/powerpc/platforms/cell/spufs/syscalls.c | 22 ++++++--------- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 856e9c398068..e481f6b9a789 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -611,15 +611,14 @@ out: static struct file_system_type spufs_type; -long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, - struct file *filp) +long spufs_create(struct path *path, struct dentry *dentry, + unsigned int flags, mode_t mode, struct file *filp) { - struct dentry *dentry; int ret; ret = -EINVAL; /* check if we are on spufs */ - if (nd->path.dentry->d_sb->s_type != &spufs_type) + if (path->dentry->d_sb->s_type != &spufs_type) goto out; /* don't accept undefined flags */ @@ -627,33 +626,27 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, goto out; /* only threads can be underneath a gang */ - if (nd->path.dentry != nd->path.dentry->d_sb->s_root) { + if (path->dentry != path->dentry->d_sb->s_root) { if ((flags & SPU_CREATE_GANG) || - !SPUFS_I(nd->path.dentry->d_inode)->i_gang) + !SPUFS_I(path->dentry->d_inode)->i_gang) goto out; } - dentry = lookup_create(nd, 1); - ret = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto out_dir; - mode &= ~current_umask(); if (flags & SPU_CREATE_GANG) - ret = spufs_create_gang(nd->path.dentry->d_inode, - dentry, nd->path.mnt, mode); + ret = spufs_create_gang(path->dentry->d_inode, + dentry, path->mnt, mode); else - ret = spufs_create_context(nd->path.dentry->d_inode, - dentry, nd->path.mnt, flags, mode, + ret = spufs_create_context(path->dentry->d_inode, + dentry, path->mnt, flags, mode, filp); if (ret >= 0) - fsnotify_mkdir(nd->path.dentry->d_inode, dentry); + fsnotify_mkdir(path->dentry->d_inode, dentry); return ret; -out_dir: - mutex_unlock(&nd->path.dentry->d_inode->i_mutex); out: + mutex_unlock(&path->dentry->d_inode->i_mutex); return ret; } diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index c448bac65518..099245f230b2 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -248,7 +248,7 @@ extern const struct spufs_tree_descr spufs_dir_debug_contents[]; /* system call implementation */ extern struct spufs_calls spufs_calls; long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); -long spufs_create(struct nameidata *nd, unsigned int flags, +long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags, mode_t mode, struct file *filp); /* ELF coredump callbacks for writing SPU ELF notes */ extern int spufs_coredump_extra_notes_size(void); diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c index a3d2ce54ea2e..609e016e92d0 100644 --- a/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -62,21 +62,17 @@ out: static long do_spu_create(const char __user *pathname, unsigned int flags, mode_t mode, struct file *neighbor) { - char *tmp; + struct path path; + struct dentry *dentry; int ret; - tmp = getname(pathname); - ret = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - struct nameidata nd; - - ret = kern_path_parent(tmp, &nd); - if (!ret) { - nd.flags |= LOOKUP_OPEN | LOOKUP_CREATE; - ret = spufs_create(&nd, flags, mode, neighbor); - path_put(&nd.path); - } - putname(tmp); + dentry = user_path_create(AT_FDCWD, pathname, &path, 1); + ret = PTR_ERR(dentry); + if (!IS_ERR(dentry)) { + ret = spufs_create(&path, dentry, flags, mode, neighbor); + mutex_unlock(&path.dentry->d_inode->i_mutex); + dput(dentry); + path_put(&path); } return ret;