lkml.org 
[lkml]   [2006]   [Jan]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 07/13] 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>

Index: linux-2.6.15-rc/arch/powerpc/platforms/cell/spufs/inode.c
===================================================================
--- linux-2.6.15-rc.orig/arch/powerpc/platforms/cell/spufs/inode.c
+++ linux-2.6.15-rc/arch/powerpc/platforms/cell/spufs/inode.c
@@ -134,47 +134,18 @@ spufs_delete_inode(struct inode *inode)
clear_inode(inode);
}

-static int
-spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
- int mode, struct spu_context *ctx)
-{
- struct dentry *dentry;
- int ret;
-
- while (files->name && files->name[0]) {
- ret = -ENOMEM;
- dentry = d_alloc_name(dir, files->name);
- if (!dentry)
- goto out;
- ret = spufs_new_file(dir->d_sb, dentry, files->ops,
- files->mode & mode, ctx);
- if (ret)
- goto out;
- files++;
- }
- return 0;
-out:
- // FIXME: remove all files that are left
-
- return ret;
-}
-
-static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
+static void spufs_prune_dir(struct dentry *dir)
{
struct dentry *dentry, *tmp;
- struct spu_context *ctx;
-
- /* remove all entries */
- down(&root->i_sem);
- down(&dir_dentry->d_inode->i_sem);
- list_for_each_entry_safe(dentry, tmp, &dir_dentry->d_subdirs, d_child) {
+ down(&dir->d_inode->i_sem);
+ list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock);
if (!(d_unhashed(dentry)) && dentry->d_inode) {
dget_locked(dentry);
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
- simple_unlink(dir_dentry->d_inode, dentry);
+ simple_unlink(dir->d_inode, dentry);
spin_unlock(&dcache_lock);
dput(dentry);
} else {
@@ -182,8 +153,17 @@ static int spufs_rmdir(struct inode *roo
spin_unlock(&dcache_lock);
}
}
- shrink_dcache_parent(dir_dentry);
- up(&dir_dentry->d_inode->i_sem);
+ shrink_dcache_parent(dir);
+ up(&dir->d_inode->i_sem);
+}
+
+static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry)
+{
+ struct spu_context *ctx;
+
+ /* remove all entries */
+ down(&root->i_sem);
+ spufs_prune_dir(dir_dentry);
up(&root->i_sem);

/* We have to give up the mm_struct */
@@ -194,6 +174,29 @@ static int spufs_rmdir(struct inode *roo
return simple_rmdir(root, dir_dentry);
}

+static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
+ int mode, struct spu_context *ctx)
+{
+ struct dentry *dentry;
+ int ret;
+
+ while (files->name && files->name[0]) {
+ ret = -ENOMEM;
+ dentry = d_alloc_name(dir, files->name);
+ if (!dentry)
+ goto out;
+ ret = spufs_new_file(dir->d_sb, dentry, files->ops,
+ files->mode & mode, ctx);
+ if (ret)
+ goto out;
+ files++;
+ }
+ return 0;
+out:
+ spufs_prune_dir(dir);
+ return ret;
+}
+
static int spufs_dir_close(struct inode *inode, struct file *file)
{
struct inode *dir;
--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2006-01-04 21:04    [W:1.085 / U:0.012 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site