Skip to content

Commit

Permalink
[POWERPC] spufs: Fix gang destroy leaks
Browse files Browse the repository at this point in the history
Previously, closing a SPE gang that still has contexts would trigger
a WARN_ON, and leak the allocated gang.

This change fixes the problem by using the gang's reference counts to
destroy the gang instead. The gangs will persist until their last
reference (be it context or open file handle) is gone.

Also, avoid using statements with side-effects in a WARN_ON().

Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Jeremy Kerr authored and Paul Mackerras committed Jun 7, 2007
1 parent ce92987 commit 877907d
Showing 1 changed file with 5 additions and 35 deletions.
40 changes: 5 additions & 35 deletions arch/powerpc/platforms/cell/spufs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,37 +349,6 @@ static int spufs_create_context(struct inode *inode,
return ret;
}

static int spufs_rmgang(struct inode *root, struct dentry *dir)
{
/* FIXME: this fails if the dir is not empty,
which causes a leak of gangs. */
return simple_rmdir(root, dir);
}

static int spufs_gang_close(struct inode *inode, struct file *file)
{
struct inode *parent;
struct dentry *dir;
int ret;

dir = file->f_path.dentry;
parent = dir->d_parent->d_inode;

ret = spufs_rmgang(parent, dir);
WARN_ON(ret);

return dcache_dir_close(inode, file);
}

const struct file_operations spufs_gang_fops = {
.open = dcache_dir_open,
.release = spufs_gang_close,
.llseek = dcache_dir_lseek,
.read = generic_read_dir,
.readdir = dcache_readdir,
.fsync = simple_sync_file,
};

static int
spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
{
Expand Down Expand Up @@ -407,7 +376,6 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
inode->i_fop = &simple_dir_operations;

d_instantiate(dentry, inode);
dget(dentry);
dir->i_nlink++;
dentry->d_inode->i_nlink++;
return ret;
Expand Down Expand Up @@ -437,7 +405,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
goto out;
}

filp->f_op = &spufs_gang_fops;
filp->f_op = &simple_dir_operations;
fd_install(ret, filp);
out:
return ret;
Expand All @@ -458,8 +426,10 @@ static int spufs_create_gang(struct inode *inode,
* in error path of *_open().
*/
ret = spufs_gang_open(dget(dentry), mntget(mnt));
if (ret < 0)
WARN_ON(spufs_rmgang(inode, dentry));
if (ret < 0) {
int err = simple_rmdir(inode, dentry);
WARN_ON(err);
}

out:
mutex_unlock(&inode->i_mutex);
Expand Down

0 comments on commit 877907d

Please sign in to comment.