aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2006-01-04 14:31:22 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:44:37 -0500
commitc8ca0633e5f2bceab7b4eba4475820fd7674dece (patch)
tree6801e179da8f4cebf09d19446f9ce6fcaab54d8e
parent762cf6dac2623473e83bb271f2bbe97d2355c64d (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.c20
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
196static int spufs_dir_close(struct inode *inode, struct file *file) 196static 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