Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 89877e42827f16fa5f86b1df0c2860b1 > files > 1878

kernel-2.6.18-128.1.10.el5.src.rpm

From: Scott Moser <smoser@redhat.com>
Date: Thu, 6 Dec 2007 14:14:26 -0500
Subject: [ppc64] spufs: context destroy vs readdir race
Message-id: Pine.LNX.4.64.0712061410510.19799@squad5-lp1.lab.boston.redhat.com
O-Subject: [PATCH RHEL5u2] bz387841 Kernel oops from spufs context create vs readdir on spufs mountpoint
Bugzilla: 387841

Bug 387841 [1]
---------------

Description:
-----------
spufs: fix context destroy vs /spu readdir race

We can currently cause an oops by repeatedly creating and destroying
contexts, while doing getdents() calls on the "/spu" directory.

This is due to the context's top-level dentry remaining hashed while
the context is being destroyed.

Fix this by unhashing the context's dentry with the
dentry->d_inode->i_mutex held. This way, we'll hit the check for
d_unhashed in dentry_readdir, and won't be included in the
list of subdirs for /spu.

Kernel Version:
--------------
Patch built against 2.6.18-56

Upstream Status:
---------------
http://ozlabs.org/pipermail/cbe-oss-dev/2007-November/003530.html

Test Status:
----
To ensure cross platform build, a brew scratch build has been done against
2.6.18-56 at [2].

I've tested this the kernel listed above with the spufs testsuite at [3].
Withouth this patch, the 01-spu_create/07-destroy-vs-readdir-race test would
fail.  With this patch applied all tests run successfully.

Please review patch below for RHEL5u2
--
[1]:https://bugzilla.redhat.com/show_bug.cgi?id=387841
[3]:http://git.kernel.org/?p=linux/kernel/git/jk/spufs-testsuite.git;a=summary
--
 arch/powerpc/platforms/cell/spufs/inode.c |    1 +
 1 file changed, 1 insertion(+)

Acked-by: David Howells <dhowells@redhat.com>

diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 7555057..d9d211f 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -171,6 +171,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir)
 {
 	/* remove all entries */
 	spufs_prune_dir(dir);
+	d_drop(dir);
 
 	return simple_rmdir(parent, dir);
 }