kobject: send KOBJ_REMOVE uevent when the object is removed from sysfs
It is possible for a KOBJ_REMOVE uevent to be sent to userspace way after the files are actually gone from sysfs, due to how reference counting for kobjects work. This should not be a problem, but it would be good to properly send the information when things are going away, not at some later point in time in the future. Before this move, if a kobject's parent was torn down before the child, when the call to kobject_uevent() happened, the parent walk to try to reconstruct the full path of the kobject could be a total mess and cause crashes. It's not good to try to tear down a kobject tree from top down, but let's at least try to not to crash if a user does so. Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://lore.kernel.org/r/20200524153041.2361-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
f7d8f3f092
commit
0e5596c54a
|
@ -620,6 +620,13 @@ void kobject_del(struct kobject *kobj)
|
|||
if (ktype)
|
||||
sysfs_remove_groups(kobj, ktype->default_groups);
|
||||
|
||||
/* send "remove" if the caller did not do it but sent "add" */
|
||||
if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) {
|
||||
pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n",
|
||||
kobject_name(kobj), kobj);
|
||||
kobject_uevent(kobj, KOBJ_REMOVE);
|
||||
}
|
||||
|
||||
sysfs_remove_dir(kobj);
|
||||
sysfs_put(sd);
|
||||
|
||||
|
@ -673,13 +680,6 @@ static void kobject_cleanup(struct kobject *kobj)
|
|||
pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed. See Documentation/kobject.txt.\n",
|
||||
kobject_name(kobj), kobj);
|
||||
|
||||
/* send "remove" if the caller did not do it but sent "add" */
|
||||
if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) {
|
||||
pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n",
|
||||
kobject_name(kobj), kobj);
|
||||
kobject_uevent(kobj, KOBJ_REMOVE);
|
||||
}
|
||||
|
||||
/* remove from sysfs if the caller did not do it */
|
||||
if (kobj->state_in_sysfs) {
|
||||
pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n",
|
||||
|
|
Loading…
Reference in New Issue