[PATCH] sysfs: sysfs_remove_dir() needs to invalidate the dentry
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>
This commit is contained in:
Родитель
c4a1745aa0
Коммит
641e6f30a0
|
@ -302,6 +302,7 @@ void sysfs_remove_dir(struct kobject * kobj)
|
||||||
* Drop reference from dget() on entrance.
|
* Drop reference from dget() on entrance.
|
||||||
*/
|
*/
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
|
kobj->dentry = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
|
int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
|
||||||
|
|
|
@ -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)
|
void sysfs_hash_and_remove(struct dentry * dir, const char * name)
|
||||||
{
|
{
|
||||||
struct sysfs_dirent * sd;
|
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)
|
if (dir->d_inode == NULL)
|
||||||
/* no inode means this hasn't been made visible yet */
|
/* no inode means this hasn't been made visible yet */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
parent_sd = dir->d_fsdata;
|
||||||
mutex_lock(&dir->d_inode->i_mutex);
|
mutex_lock(&dir->d_inode->i_mutex);
|
||||||
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
|
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
|
||||||
if (!sd->s_element)
|
if (!sd->s_element)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче