aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-06-26 11:54:58 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2011-07-20 01:44:06 -0400
commit1ba106818615faddb63ba782f85f3498b9eb61c6 (patch)
tree45454702de65167453ebb873e8503456b2d0c640 /arch
parentdae6ad8f37529963ae7df52baaccf056b38f210e (diff)
switch do_spufs_create() to user_path_create(), fix double-unlock
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c29
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h2
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c22
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:
611 611
612static struct file_system_type spufs_type; 612static struct file_system_type spufs_type;
613 613
614long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, 614long spufs_create(struct path *path, struct dentry *dentry,
615 struct file *filp) 615 unsigned int flags, mode_t mode, struct file *filp)
616{ 616{
617 struct dentry *dentry;
618 int ret; 617 int ret;
619 618
620 ret = -EINVAL; 619 ret = -EINVAL;
621 /* check if we are on spufs */ 620 /* check if we are on spufs */
622 if (nd->path.dentry->d_sb->s_type != &spufs_type) 621 if (path->dentry->d_sb->s_type != &spufs_type)
623 goto out; 622 goto out;
624 623
625 /* don't accept undefined flags */ 624 /* don't accept undefined flags */
@@ -627,33 +626,27 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
627 goto out; 626 goto out;
628 627
629 /* only threads can be underneath a gang */ 628 /* only threads can be underneath a gang */
630 if (nd->path.dentry != nd->path.dentry->d_sb->s_root) { 629 if (path->dentry != path->dentry->d_sb->s_root) {
631 if ((flags & SPU_CREATE_GANG) || 630 if ((flags & SPU_CREATE_GANG) ||
632 !SPUFS_I(nd->path.dentry->d_inode)->i_gang) 631 !SPUFS_I(path->dentry->d_inode)->i_gang)
633 goto out; 632 goto out;
634 } 633 }
635 634
636 dentry = lookup_create(nd, 1);
637 ret = PTR_ERR(dentry);
638 if (IS_ERR(dentry))
639 goto out_dir;
640
641 mode &= ~current_umask(); 635 mode &= ~current_umask();
642 636
643 if (flags & SPU_CREATE_GANG) 637 if (flags & SPU_CREATE_GANG)
644 ret = spufs_create_gang(nd->path.dentry->d_inode, 638 ret = spufs_create_gang(path->dentry->d_inode,
645 dentry, nd->path.mnt, mode); 639 dentry, path->mnt, mode);
646 else 640 else
647 ret = spufs_create_context(nd->path.dentry->d_inode, 641 ret = spufs_create_context(path->dentry->d_inode,
648 dentry, nd->path.mnt, flags, mode, 642 dentry, path->mnt, flags, mode,
649 filp); 643 filp);
650 if (ret >= 0) 644 if (ret >= 0)
651 fsnotify_mkdir(nd->path.dentry->d_inode, dentry); 645 fsnotify_mkdir(path->dentry->d_inode, dentry);
652 return ret; 646 return ret;
653 647
654out_dir:
655 mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
656out: 648out:
649 mutex_unlock(&path->dentry->d_inode->i_mutex);
657 return ret; 650 return ret;
658} 651}
659 652
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[];
248/* system call implementation */ 248/* system call implementation */
249extern struct spufs_calls spufs_calls; 249extern struct spufs_calls spufs_calls;
250long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); 250long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
251long spufs_create(struct nameidata *nd, unsigned int flags, 251long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags,
252 mode_t mode, struct file *filp); 252 mode_t mode, struct file *filp);
253/* ELF coredump callbacks for writing SPU ELF notes */ 253/* ELF coredump callbacks for writing SPU ELF notes */
254extern int spufs_coredump_extra_notes_size(void); 254extern 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:
62static long do_spu_create(const char __user *pathname, unsigned int flags, 62static long do_spu_create(const char __user *pathname, unsigned int flags,
63 mode_t mode, struct file *neighbor) 63 mode_t mode, struct file *neighbor)
64{ 64{
65 char *tmp; 65 struct path path;
66 struct dentry *dentry;
66 int ret; 67 int ret;
67 68
68 tmp = getname(pathname); 69 dentry = user_path_create(AT_FDCWD, pathname, &path, 1);
69 ret = PTR_ERR(tmp); 70 ret = PTR_ERR(dentry);
70 if (!IS_ERR(tmp)) { 71 if (!IS_ERR(dentry)) {
71 struct nameidata nd; 72 ret = spufs_create(&path, dentry, flags, mode, neighbor);
72 73 mutex_unlock(&path.dentry->d_inode->i_mutex);
73 ret = kern_path_parent(tmp, &nd); 74 dput(dentry);
74 if (!ret) { 75 path_put(&path);
75 nd.flags |= LOOKUP_OPEN | LOOKUP_CREATE;
76 ret = spufs_create(&nd, flags, mode, neighbor);
77 path_put(&nd.path);
78 }
79 putname(tmp);
80 } 76 }
81 77
82 return ret; 78 return ret;