diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2006-01-04 14:31:22 -0500 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-01-08 23:44:37 -0500 |
| commit | c8ca0633e5f2bceab7b4eba4475820fd7674dece (patch) | |
| tree | 6801e179da8f4cebf09d19446f9ce6fcaab54d8e | |
| parent | 762cf6dac2623473e83bb271f2bbe97d2355c64d (diff) | |
[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 2c3ba4eb41cb..45944012b06a 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) | |||
| 162 | { | 162 | { |
| 163 | struct dentry *dentry, *tmp; | 163 | struct dentry *dentry, *tmp; |
| 164 | struct spu_context *ctx; | 164 | struct spu_context *ctx; |
| 165 | int err; | ||
| 166 | 165 | ||
| 167 | /* remove all entries */ | 166 | /* remove all entries */ |
| 168 | err = 0; | 167 | down(&root->i_sem); |
| 168 | down(&dir_dentry->d_inode->i_sem); | ||
| 169 | list_for_each_entry_safe(dentry, tmp, &dir_dentry->d_subdirs, d_child) { | 169 | list_for_each_entry_safe(dentry, tmp, &dir_dentry->d_subdirs, d_child) { |
| 170 | spin_lock(&dcache_lock); | 170 | spin_lock(&dcache_lock); |
| 171 | spin_lock(&dentry->d_lock); | 171 | spin_lock(&dentry->d_lock); |
| @@ -181,16 +181,16 @@ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) | |||
| 181 | spin_unlock(&dcache_lock); | 181 | spin_unlock(&dcache_lock); |
| 182 | } | 182 | } |
| 183 | } | 183 | } |
| 184 | shrink_dcache_parent(dir_dentry); | ||
| 185 | up(&dir_dentry->d_inode->i_sem); | ||
| 186 | up(&root->i_sem); | ||
| 184 | 187 | ||
| 185 | /* We have to give up the mm_struct */ | 188 | /* We have to give up the mm_struct */ |
| 186 | ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx; | 189 | ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx; |
| 187 | spu_forget(ctx); | 190 | spu_forget(ctx); |
| 188 | 191 | ||
| 189 | if (!err) { | 192 | /* XXX Do we need to hold i_sem here ? */ |
| 190 | shrink_dcache_parent(dir_dentry); | 193 | return simple_rmdir(root, dir_dentry); |
| 191 | err = simple_rmdir(root, dir_dentry); | ||
| 192 | } | ||
| 193 | return err; | ||
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | static int spufs_dir_close(struct inode *inode, struct file *file) | 196 | 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) | |||
| 201 | 201 | ||
| 202 | dentry = file->f_dentry; | 202 | dentry = file->f_dentry; |
| 203 | dir = dentry->d_parent->d_inode; | 203 | dir = dentry->d_parent->d_inode; |
| 204 | down(&dir->i_sem); | 204 | |
| 205 | ret = spufs_rmdir(dir, file->f_dentry); | 205 | ret = spufs_rmdir(dir, dentry); |
| 206 | WARN_ON(ret); | 206 | WARN_ON(ret); |
| 207 | up(&dir->i_sem); | 207 | |
| 208 | return dcache_dir_close(inode, file); | 208 | return dcache_dir_close(inode, file); |
| 209 | } | 209 | } |
| 210 | 210 | ||
