From: Maneesh Soni sysfs_remove_dir() has to remove the files in the subdirs (corresponding to the attribute groups) and then remove such empty subdirs along with the other attribute files for the given kobject. The following patch does this assuming that there are/will be no attribute sub-groups. 25-akpm/fs/sysfs/dir.c | 22 +++++++++++++++++----- 1 files changed, 17 insertions(+), 5 deletions(-) diff -puN fs/sysfs/dir.c~sysfs_remove_dir-leak-fix fs/sysfs/dir.c --- 25/fs/sysfs/dir.c~sysfs_remove_dir-leak-fix Mon Sep 15 08:10:35 2003 +++ 25-akpm/fs/sysfs/dir.c Mon Sep 15 08:10:35 2003 @@ -119,23 +119,30 @@ void sysfs_remove_dir(struct kobject * k { struct list_head * node; struct dentry * dentry = dget(kobj->dentry); + struct dentry * parent; if (!dentry) return; pr_debug("sysfs %s: removing dir\n",dentry->d_name.name); - down(&dentry->d_inode->i_sem); + parent = dentry; + down(&parent->d_inode->i_sem); spin_lock(&dcache_lock); - node = dentry->d_subdirs.next; - while (node != &dentry->d_subdirs) { - struct dentry * d = list_entry(node,struct dentry,d_child); +repeat: + node = parent->d_subdirs.next; + while (node != &parent->d_subdirs) { + struct dentry * d = list_entry(node, struct dentry, d_child); list_del_init(node); pr_debug(" o %s (%d): ",d->d_name.name,atomic_read(&d->d_count)); if (d->d_inode) { d = dget_locked(d); pr_debug("removing"); + if (!list_empty(&d->d_subdirs)) { + parent = d; + goto repeat; + } /** * Unlink and unhash. @@ -147,7 +154,12 @@ void sysfs_remove_dir(struct kobject * k spin_lock(&dcache_lock); } pr_debug(" done\n"); - node = dentry->d_subdirs.next; + node = parent->d_subdirs.next; + } + + if (!list_empty(&dentry->d_subdirs)) { + parent = dentry; + goto repeat; } list_del_init(&dentry->d_child); spin_unlock(&dcache_lock); _