diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-06-26 11:54:58 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-07-20 01:44:06 -0400 |
commit | 1ba106818615faddb63ba782f85f3498b9eb61c6 (patch) | |
tree | 45454702de65167453ebb873e8503456b2d0c640 /arch | |
parent | dae6ad8f37529963ae7df52baaccf056b38f210e (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.c | 29 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 2 | ||||
-rw-r--r-- | 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: | |||
611 | 611 | ||
612 | static struct file_system_type spufs_type; | 612 | static struct file_system_type spufs_type; |
613 | 613 | ||
614 | long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, | 614 | long 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 | ||
654 | out_dir: | ||
655 | mutex_unlock(&nd->path.dentry->d_inode->i_mutex); | ||
656 | out: | 648 | out: |
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 */ |
249 | extern struct spufs_calls spufs_calls; | 249 | extern struct spufs_calls spufs_calls; |
250 | long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); | 250 | long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); |
251 | long spufs_create(struct nameidata *nd, unsigned int flags, | 251 | long 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 */ |
254 | extern int spufs_coredump_extra_notes_size(void); | 254 | 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: | |||
62 | static long do_spu_create(const char __user *pathname, unsigned int flags, | 62 | static 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; |