mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 06:16:46 +07:00
switch do_spufs_create() to user_path_create(), fix double-unlock
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
dae6ad8f37
commit
1ba1068186
@ -611,15 +611,14 @@ static int spufs_create_gang(struct inode *inode,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -62,21 +62,17 @@ static long do_spu_run(struct file *filp,
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user