Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8ca0633 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Paul Mackerras
Browse files

[PATCH] spufs: dont hold root->isem in spu_forget



spu_forget will do mmput on the DMA address space,
which can lead to lots of other stuff getting triggered.
We better not hold a semaphore here that we might
need in the process.

Noticed by Al Viro.

Signed-off-by: default avatarArnd Bergmann <arndb@de.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 762cf6da
Loading
Loading
Loading
Loading
+10 −10
Original line number Original line Diff line number Diff line
@@ -162,10 +162,10 @@ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
{
{
	struct dentry *dentry, *tmp;
	struct dentry *dentry, *tmp;
	struct spu_context *ctx;
	struct spu_context *ctx;
	int err;


	/* remove all entries */
	/* remove all entries */
	err = 0;
	down(&root->i_sem);
	down(&dir_dentry->d_inode->i_sem);
	list_for_each_entry_safe(dentry, tmp, &dir_dentry->d_subdirs, d_child) {
	list_for_each_entry_safe(dentry, tmp, &dir_dentry->d_subdirs, d_child) {
		spin_lock(&dcache_lock);
		spin_lock(&dcache_lock);
		spin_lock(&dentry->d_lock);
		spin_lock(&dentry->d_lock);
@@ -181,16 +181,16 @@ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
			spin_unlock(&dcache_lock);
			spin_unlock(&dcache_lock);
		}
		}
	}
	}
	shrink_dcache_parent(dir_dentry);
	up(&dir_dentry->d_inode->i_sem);
	up(&root->i_sem);


	/* We have to give up the mm_struct */
	/* We have to give up the mm_struct */
	ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx;
	ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx;
	spu_forget(ctx);
	spu_forget(ctx);


	if (!err) {
	/* XXX Do we need to hold i_sem here ? */
		shrink_dcache_parent(dir_dentry);
	return simple_rmdir(root, dir_dentry);
		err = simple_rmdir(root, dir_dentry);
	}
	return err;
}
}


static int spufs_dir_close(struct inode *inode, struct file *file)
static int spufs_dir_close(struct inode *inode, struct file *file)
@@ -201,10 +201,10 @@ static int spufs_dir_close(struct inode *inode, struct file *file)


	dentry = file->f_dentry;
	dentry = file->f_dentry;
	dir = dentry->d_parent->d_inode;
	dir = dentry->d_parent->d_inode;
	down(&dir->i_sem);

	ret = spufs_rmdir(dir, file->f_dentry);
	ret = spufs_rmdir(dir, dentry);
	WARN_ON(ret);
	WARN_ON(ret);
	up(&dir->i_sem);

	return dcache_dir_close(inode, file);
	return dcache_dir_close(inode, file);
}
}