diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-05-24 17:30:41 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-05-25 14:49:22 +0200 |
commit | 0e5596c54aa2fbfd22842096d3ebb6753b2a220a (patch) | |
tree | 91fb0195638dcd59033694199989f4a4126411d7 /lib/kobject.c | |
parent | f7d8f3f092d001f8d91552d2697643e727694942 (diff) | |
download | linux-0e5596c54aa2fbfd22842096d3ebb6753b2a220a.tar.gz linux-0e5596c54aa2fbfd22842096d3ebb6753b2a220a.tar.bz2 linux-0e5596c54aa2fbfd22842096d3ebb6753b2a220a.zip |
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>
Diffstat (limited to 'lib/kobject.c')
-rw-r--r-- | lib/kobject.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index 83198cb37d8d..2509e22ad74a 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -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", |