Commit 1ba106818615faddb63ba782f85f3498b9eb61c6
1 parent
dae6ad8f37
Exists in
master
and in
4 other branches
switch do_spufs_create() to user_path_create(), fix double-unlock
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 3 changed files with 21 additions and 32 deletions Side-by-side Diff
arch/powerpc/platforms/cell/spufs/inode.c
... | ... | @@ -611,15 +611,14 @@ |
611 | 611 | |
612 | 612 | static struct file_system_type spufs_type; |
613 | 613 | |
614 | -long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode, | |
615 | - struct file *filp) | |
614 | +long spufs_create(struct path *path, struct dentry *dentry, | |
615 | + unsigned int flags, mode_t mode, struct file *filp) | |
616 | 616 | { |
617 | - struct dentry *dentry; | |
618 | 617 | int ret; |
619 | 618 | |
620 | 619 | ret = -EINVAL; |
621 | 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 | 622 | goto out; |
624 | 623 | |
625 | 624 | /* don't accept undefined flags */ |
626 | 625 | |
627 | 626 | |
628 | 627 | |
629 | 628 | |
630 | 629 | |
631 | 630 | |
632 | 631 | |
... | ... | @@ -627,33 +626,27 @@ |
627 | 626 | goto out; |
628 | 627 | |
629 | 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 | 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 | 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 | 635 | mode &= ~current_umask(); |
642 | 636 | |
643 | 637 | if (flags & SPU_CREATE_GANG) |
644 | - ret = spufs_create_gang(nd->path.dentry->d_inode, | |
645 | - dentry, nd->path.mnt, mode); | |
638 | + ret = spufs_create_gang(path->dentry->d_inode, | |
639 | + dentry, path->mnt, mode); | |
646 | 640 | else |
647 | - ret = spufs_create_context(nd->path.dentry->d_inode, | |
648 | - dentry, nd->path.mnt, flags, mode, | |
641 | + ret = spufs_create_context(path->dentry->d_inode, | |
642 | + dentry, path->mnt, flags, mode, | |
649 | 643 | filp); |
650 | 644 | if (ret >= 0) |
651 | - fsnotify_mkdir(nd->path.dentry->d_inode, dentry); | |
645 | + fsnotify_mkdir(path->dentry->d_inode, dentry); | |
652 | 646 | return ret; |
653 | 647 | |
654 | -out_dir: | |
655 | - mutex_unlock(&nd->path.dentry->d_inode->i_mutex); | |
656 | 648 | out: |
649 | + mutex_unlock(&path->dentry->d_inode->i_mutex); | |
657 | 650 | return ret; |
658 | 651 | } |
659 | 652 |
arch/powerpc/platforms/cell/spufs/spufs.h
... | ... | @@ -248,7 +248,7 @@ |
248 | 248 | /* system call implementation */ |
249 | 249 | extern struct spufs_calls spufs_calls; |
250 | 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 | 252 | mode_t mode, struct file *filp); |
253 | 253 | /* ELF coredump callbacks for writing SPU ELF notes */ |
254 | 254 | extern int spufs_coredump_extra_notes_size(void); |
arch/powerpc/platforms/cell/spufs/syscalls.c
... | ... | @@ -62,21 +62,17 @@ |
62 | 62 | static long do_spu_create(const char __user *pathname, unsigned int flags, |
63 | 63 | mode_t mode, struct file *neighbor) |
64 | 64 | { |
65 | - char *tmp; | |
65 | + struct path path; | |
66 | + struct dentry *dentry; | |
66 | 67 | int ret; |
67 | 68 | |
68 | - tmp = getname(pathname); | |
69 | - ret = PTR_ERR(tmp); | |
70 | - if (!IS_ERR(tmp)) { | |
71 | - struct nameidata nd; | |
72 | - | |
73 | - ret = kern_path_parent(tmp, &nd); | |
74 | - if (!ret) { | |
75 | - nd.flags |= LOOKUP_OPEN | LOOKUP_CREATE; | |
76 | - ret = spufs_create(&nd, flags, mode, neighbor); | |
77 | - path_put(&nd.path); | |
78 | - } | |
79 | - putname(tmp); | |
69 | + dentry = user_path_create(AT_FDCWD, pathname, &path, 1); | |
70 | + ret = PTR_ERR(dentry); | |
71 | + if (!IS_ERR(dentry)) { | |
72 | + ret = spufs_create(&path, dentry, flags, mode, neighbor); | |
73 | + mutex_unlock(&path.dentry->d_inode->i_mutex); | |
74 | + dput(dentry); | |
75 | + path_put(&path); | |
80 | 76 | } |
81 | 77 | |
82 | 78 | return ret; |