On Sat, Mar 24, 2007 at 08:35:35AM +0530, Maneesh Soni wrote:
Hi Ethan / Andrew,
I have modified the previous patch (which was dropped from -mm) and now keeping
the statement making s_dentry as NULL in sysfs_d_iput(), so this should
_safely_ fix sysfs_readdir() oops.
Please see the other mail for sysfs_d_iput() BUG hit.
Thanks
Maneesh
--
Maneesh Soni
Linux Technology Center,
IBM India Systems and Technology Lab,
Bangalore, India
o sysfs_d_iput() is invoked in dentry reclaim path under memory pressure. This
happens without i_mutex. It also nullifies s_dentry to indicate that
the associated dentry is evicted. sysfs_readdir() accesses the s_dentry,
and gets the inode number from the associated dentry->d_inode, if
there is one, else it invokes iunique(). This can create a race situation,
and crash while accessing the d_inode in sysfs_readdir().
o The race happens when the dentry is getting reclaimed and detached from
the corresponding sysfs_dirent though sysfs_dirent is still a valid
node. Accessing dentry fields are ok as it is under RCU but the inode is
not hence we may see oops accessing dentry->d_inode->i_no.
o The following patch always use i_unique() to get the inode number in
sysfs_readdir. This is ok as sysfs doesnot have permanent inode numbering.
It could be slower but avoids the oops.
Signed-off-by: Maneesh Soni <maneesh@in.ibm.com>
---
linux-2.6.21-rc5-mm3-maneesh/fs/sysfs/dir.c | 5 +----
1 files changed, 1 insertion(+), 4 deletions(-)
diff -puN fs/sysfs/dir.c~fix-sysfs_readdir-oops fs/sysfs/dir.c
--- linux-2.6.21-rc5-mm3/fs/sysfs/dir.c~fix-sysfs_readdir-oops 2007-04-03 10:39:52.000000000 +0530
+++ linux-2.6.21-rc5-mm3-maneesh/fs/sysfs/dir.c 2007-04-03 10:39:52.000000000 +0530
@@ -538,10 +538,7 @@ static int sysfs_readdir(struct file * f
name = sysfs_get_name(next);
len = strlen(name);
- if (next->s_dentry)
- ino = next->s_dentry->d_inode->i_ino;
- else
- ino = iunique(sysfs_sb, 2);
+ ino = iunique(sysfs_sb, 2);
if (filldir(dirent, name, len, filp->f_pos, ino,
dt_type(next)) < 0)
_
-