The error path in spufs_fill_dir() is broken. If d_alloc_name() or spufs_new_file() fails, spufs_prune_dir() is getting called. At this time dir->inode is not set and a NULL pointer is dereferenced by mutex_lock(). This bugfix replaces spufs_prune_dir() with a shorter version that does not touch dir->inode but simply removes all children. Signed-off-by: Sebastian Siewior CC: arnd@arndb.de CC: jk@ozlabs.org Index: ps3-linux/arch/powerpc/platforms/cell/spufs/inode.c =================================================================== --- ps3-linux.orig/arch/powerpc/platforms/cell/spufs/inode.c +++ ps3-linux/arch/powerpc/platforms/cell/spufs/inode.c @@ -174,6 +174,26 @@ static int spufs_rmdir(struct inode *par return simple_rmdir(parent, dir); } +/* + * remove all children from dir. dir->inode is not set so don't + * just simply use spufs_prune_dir() and panic afterwards :) + * dput() looks like it will do the right thing: + * - dec parent's ref counter + * - remove child from parent's child list + * - free child's inode if possible + * - free child + */ +static void spufs_prune_incomplete_dir(struct dentry *dir) +{ + struct dentry *child, *tmp; + + list_for_each_entry_safe(child, tmp, &dir->d_subdirs, d_u.d_child) { + dput(child); + } + + shrink_dcache_parent(dir); +} + static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, int mode, struct spu_context *ctx) { @@ -193,7 +213,7 @@ static int spufs_fill_dir(struct dentry } return 0; out: - spufs_prune_dir(dir); + spufs_prune_incomplete_dir(dir); return ret; } --