From: Martin Schwidefsky Fix dcache reference counting in sysfs. 25-akpm/fs/sysfs/bin.c | 1 + 25-akpm/fs/sysfs/dir.c | 6 +++--- 25-akpm/fs/sysfs/file.c | 5 +---- 25-akpm/fs/sysfs/inode.c | 2 +- 25-akpm/fs/sysfs/symlink.c | 1 + 5 files changed, 7 insertions(+), 8 deletions(-) diff -puN fs/sysfs/bin.c~sysfs-memleak-fix fs/sysfs/bin.c --- 25/fs/sysfs/bin.c~sysfs-memleak-fix Fri Aug 29 10:19:14 2003 +++ 25-akpm/fs/sysfs/bin.c Fri Aug 29 10:19:14 2003 @@ -168,6 +168,7 @@ int sysfs_create_bin_file(struct kobject dentry->d_inode->i_size = attr->size; dentry->d_inode->i_fop = &bin_fops; } + dput(dentry); } else error = PTR_ERR(dentry); up(&parent->d_inode->i_sem); diff -puN fs/sysfs/dir.c~sysfs-memleak-fix fs/sysfs/dir.c --- 25/fs/sysfs/dir.c~sysfs-memleak-fix Fri Aug 29 10:19:14 2003 +++ 25-akpm/fs/sysfs/dir.c Fri Aug 29 10:19:14 2003 @@ -35,10 +35,8 @@ create_dir(struct kobject * k, struct de if (!error) { dentry->d_fsdata = k; p->d_inode->i_nlink++; - } else { - dput(dentry); - dentry = ERR_PTR(error); } + dput(dentry); } up(&p->d_inode->i_sem); return dentry; @@ -136,6 +134,7 @@ void sysfs_remove_dir(struct kobject * k * Unlink and unhash. */ spin_unlock(&dcache_lock); + d_delete(d); simple_unlink(dentry->d_inode,d); dput(d); spin_lock(&dcache_lock); @@ -143,6 +142,7 @@ void sysfs_remove_dir(struct kobject * k 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); diff -puN fs/sysfs/file.c~sysfs-memleak-fix fs/sysfs/file.c --- 25/fs/sysfs/file.c~sysfs-memleak-fix Fri Aug 29 10:19:14 2003 +++ 25-akpm/fs/sysfs/file.c Fri Aug 29 10:19:14 2003 @@ -356,10 +356,7 @@ int sysfs_add_file(struct dentry * dir, error = sysfs_create(dentry,(attr->mode & S_IALLUGO) | S_IFREG,init_file); if (!error) dentry->d_fsdata = (void *)attr; - else { - dput(dentry); - dentry = ERR_PTR(error); - } + dput(dentry); } else error = PTR_ERR(dentry); up(&dir->d_inode->i_sem); diff -puN fs/sysfs/inode.c~sysfs-memleak-fix fs/sysfs/inode.c --- 25/fs/sysfs/inode.c~sysfs-memleak-fix Fri Aug 29 10:19:14 2003 +++ 25-akpm/fs/sysfs/inode.c Fri Aug 29 10:19:14 2003 @@ -97,8 +97,8 @@ void sysfs_hash_and_remove(struct dentry pr_debug("sysfs: Removing %s (%d)\n", victim->d_name.name, atomic_read(&victim->d_count)); - simple_unlink(dir->d_inode,victim); d_delete(victim); + simple_unlink(dir->d_inode,victim); } /* * Drop reference from sysfs_get_dentry() above. diff -puN fs/sysfs/symlink.c~sysfs-memleak-fix fs/sysfs/symlink.c --- 25/fs/sysfs/symlink.c~sysfs-memleak-fix Fri Aug 29 10:19:14 2003 +++ 25-akpm/fs/sysfs/symlink.c Fri Aug 29 10:19:14 2003 @@ -102,6 +102,7 @@ int sysfs_create_link(struct kobject * k error = sysfs_symlink(dentry->d_inode,d,path); else error = PTR_ERR(d); + dput(d); up(&dentry->d_inode->i_sem); kfree(path); return error; _