diff options
author | Arnd Bergmann <arnd@arndb.de> | 2006-01-04 20:31:22 +0100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-01-09 15:44:37 +1100 |
commit | c8ca0633e5f2bceab7b4eba4475820fd7674dece (patch) | |
tree | 6801e179da8f4cebf09d19446f9ce6fcaab54d8e | |
parent | 762cf6dac2623473e83bb271f2bbe97d2355c64d (diff) | |
download | linux-3.10-c8ca0633e5f2bceab7b4eba4475820fd7674dece.tar.gz linux-3.10-c8ca0633e5f2bceab7b4eba4475820fd7674dece.tar.bz2 linux-3.10-c8ca0633e5f2bceab7b4eba4475820fd7674dece.zip |
[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: Arnd Bergmann <arndb@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/inode.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 2c3ba4eb41c..45944012b06 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -162,10 +162,10 @@ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) { struct dentry *dentry, *tmp; struct spu_context *ctx; - int err; /* 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) { spin_lock(&dcache_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); } } + shrink_dcache_parent(dir_dentry); + up(&dir_dentry->d_inode->i_sem); + up(&root->i_sem); /* We have to give up the mm_struct */ ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx; spu_forget(ctx); - if (!err) { - shrink_dcache_parent(dir_dentry); - err = simple_rmdir(root, dir_dentry); - } - return err; + /* XXX Do we need to hold i_sem here ? */ + return simple_rmdir(root, dir_dentry); } 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; 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); - up(&dir->i_sem); + return dcache_dir_close(inode, file); } |