aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs/inode.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2006-01-04 14:31:27 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:44:42 -0500
commit3f51dd91c80746a5cf76f8c4a77bfc88aa82bb9e (patch)
treef92d9867e51a10b73a3f48fa3d65413f186ac733 /arch/powerpc/platforms/cell/spufs/inode.c
parent346f4d3ce948a381a559dcaefb141d79f492335c (diff)
[PATCH] spufs: fix spufs_fill_dir error path
If creating one entry failed in spufs_fill_dir, we never cleaned up the freshly created entries. Fix this by calling the cleanup function on error. Noticed by Al Viro. Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/inode.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c73
1 files changed, 38 insertions, 35 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index d9a39fb63a8a..687f80d09f41 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -134,47 +134,18 @@ spufs_delete_inode(struct inode *inode)
134 clear_inode(inode); 134 clear_inode(inode);
135} 135}
136 136
137static int 137static void spufs_prune_dir(struct dentry *dir)
138spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
139 int mode, struct spu_context *ctx)
140{
141 struct dentry *dentry;
142 int ret;
143
144 while (files->name && files->name[0]) {
145 ret = -ENOMEM;
146 dentry = d_alloc_name(dir, files->name);
147 if (!dentry)
148 goto out;
149 ret = spufs_new_file(dir->d_sb, dentry, files->ops,
150 files->mode & mode, ctx);
151 if (ret)
152 goto out;
153 files++;
154 }
155 return 0;
156out:
157 // FIXME: remove all files that are left
158
159 return ret;
160}
161
162static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
163{ 138{
164 struct dentry *dentry, *tmp; 139 struct dentry *dentry, *tmp;
165 struct spu_context *ctx; 140 down(&dir->d_inode->i_sem);
166 141 list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
167 /* remove all entries */
168 down(&root->i_sem);
169 down(&dir_dentry->d_inode->i_sem);
170 list_for_each_entry_safe(dentry, tmp, &dir_dentry->d_subdirs, d_child) {
171 spin_lock(&dcache_lock); 142 spin_lock(&dcache_lock);
172 spin_lock(&dentry->d_lock); 143 spin_lock(&dentry->d_lock);
173 if (!(d_unhashed(dentry)) && dentry->d_inode) { 144 if (!(d_unhashed(dentry)) && dentry->d_inode) {
174 dget_locked(dentry); 145 dget_locked(dentry);
175 __d_drop(dentry); 146 __d_drop(dentry);
176 spin_unlock(&dentry->d_lock); 147 spin_unlock(&dentry->d_lock);
177 simple_unlink(dir_dentry->d_inode, dentry); 148 simple_unlink(dir->d_inode, dentry);
178 spin_unlock(&dcache_lock); 149 spin_unlock(&dcache_lock);
179 dput(dentry); 150 dput(dentry);
180 } else { 151 } else {
@@ -182,8 +153,17 @@ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
182 spin_unlock(&dcache_lock); 153 spin_unlock(&dcache_lock);
183 } 154 }
184 } 155 }
185 shrink_dcache_parent(dir_dentry); 156 shrink_dcache_parent(dir);
186 up(&dir_dentry->d_inode->i_sem); 157 up(&dir->d_inode->i_sem);
158}
159
160static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
161{
162 struct spu_context *ctx;
163
164 /* remove all entries */
165 down(&root->i_sem);
166 spufs_prune_dir(dir_dentry);
187 up(&root->i_sem); 167 up(&root->i_sem);
188 168
189 /* We have to give up the mm_struct */ 169 /* We have to give up the mm_struct */
@@ -194,6 +174,29 @@ static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
194 return simple_rmdir(root, dir_dentry); 174 return simple_rmdir(root, dir_dentry);
195} 175}
196 176
177static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
178 int mode, struct spu_context *ctx)
179{
180 struct dentry *dentry;
181 int ret;
182
183 while (files->name && files->name[0]) {
184 ret = -ENOMEM;
185 dentry = d_alloc_name(dir, files->name);
186 if (!dentry)
187 goto out;
188 ret = spufs_new_file(dir->d_sb, dentry, files->ops,
189 files->mode & mode, ctx);
190 if (ret)
191 goto out;
192 files++;
193 }
194 return 0;
195out:
196 spufs_prune_dir(dir);
197 return ret;
198}
199
197static int spufs_dir_close(struct inode *inode, struct file *file) 200static int spufs_dir_close(struct inode *inode, struct file *file)
198{ 201{
199 struct inode *dir; 202 struct inode *dir;