From: Maneesh Soni sysfs_remove_dir modifies d_subdirs list which results in inconsistency when there is concurrent dcache_readdir is going on. I think there is no need for sysfs_remove_dir to modify d_subdirs list and removal of dentries from d_child list is taken care in the final dput(). The folloing patch fixes this race. The patch is tested by running these two loops simlutaneously on a SMP box. #while true; do tree /sys/class/net > /dev/null; done #while true; do insmod ./dummy.o; rmmod dummy.o; done o This patch fixes sysfs_remove_dir race with dcache_readdir. There is no need for sysfs_remove_dir to modify the d_subdirs list for the directory being deleted as it is taken care in the final dput. Modifying this list results in inconsistent d_subdirs list and causes infinite loop in concurrently occuring dcache_readdir. fs/sysfs/dir.c | 4 +--- 1 files changed, 1 insertion(+), 3 deletions(-) diff -puN fs/sysfs/dir.c~sysfs_remove_dir-vs-dcache_readdir-race-fix fs/sysfs/dir.c --- 25/fs/sysfs/dir.c~sysfs_remove_dir-vs-dcache_readdir-race-fix 2004-01-03 14:16:20.000000000 -0800 +++ 25-akpm/fs/sysfs/dir.c 2004-01-03 14:16:20.000000000 -0800 @@ -123,8 +123,8 @@ void sysfs_remove_dir(struct kobject * k node = dentry->d_subdirs.next; while (node != &dentry->d_subdirs) { struct dentry * d = list_entry(node,struct dentry,d_child); - list_del_init(node); + node = node->next; pr_debug(" o %s (%d): ",d->d_name.name,atomic_read(&d->d_count)); if (d->d_inode) { d = dget_locked(d); @@ -140,9 +140,7 @@ void sysfs_remove_dir(struct kobject * k spin_lock(&dcache_lock); } pr_debug(" done\n"); - node = dentry->d_subdirs.next; } - list_del_init(&dentry->d_child); spin_unlock(&dcache_lock); up(&dentry->d_inode->i_sem); _