]> err.no Git - linux-2.6/commitdiff
[PATCH] sysfs: sysfs_remove_dir() needs to invalidate the dentry
authorGreg Kroah-Hartman <gregkh@suse.de>
Thu, 16 Mar 2006 23:44:26 +0000 (15:44 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 20 Mar 2006 21:42:57 +0000 (13:42 -0800)
When calling sysfs_remove_dir() don't allow any further sysfs functions
to work for this kobject anymore.  This fixes a nasty USB cdc-acm oops
on disconnect.

Many thanks to Bob Copeland and Paul Fulghum for taking the time to
track this down.

Cc: Bob Copeland <email@bobcopeland.com>
Cc: Paul Fulghum <paulkf@microgate.com>
Cc: Maneesh Soni <maneesh@in.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/sysfs/dir.c
fs/sysfs/inode.c

index 49bd219275db30d6616a05ff8509045f88a39ec5..cfd290d3d6b1f1080a09d29ca3d86a240bf37e00 100644 (file)
@@ -302,6 +302,7 @@ void sysfs_remove_dir(struct kobject * kobj)
         * Drop reference from dget() on entrance.
         */
        dput(dentry);
+       kobj->dentry = NULL;
 }
 
 int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
index 689f7bcfaf3043b5585853f33589d59a77398008..6beee6f6a67463e77e72ea01c173ce54e6cf918c 100644 (file)
@@ -227,12 +227,16 @@ void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
 void sysfs_hash_and_remove(struct dentry * dir, const char * name)
 {
        struct sysfs_dirent * sd;
-       struct sysfs_dirent * parent_sd = dir->d_fsdata;
+       struct sysfs_dirent * parent_sd;
+
+       if (!dir)
+               return;
 
        if (dir->d_inode == NULL)
                /* no inode means this hasn't been made visible yet */
                return;
 
+       parent_sd = dir->d_fsdata;
        mutex_lock(&dir->d_inode->i_mutex);
        list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
                if (!sd->s_element)