diff options
author | Patrick Mochel <mochel@osdl.org> | 2003-01-09 21:26:07 -0600 |
---|---|---|
committer | Patrick Mochel <mochel@osdl.org> | 2003-01-09 21:26:07 -0600 |
commit | 00880cfff75b3b1fa44d8586d73fe2663644b0ba (patch) | |
tree | d0b505118aa18f9ff5dcdd2134d56b073e7b0928 /lib | |
parent | 1a0bc0cc856dd68f6ea4203af64a2b96d3cd9ec1 (diff) | |
download | history-00880cfff75b3b1fa44d8586d73fe2663644b0ba.tar.gz |
kobject: make sure we remove kobject from list if kobject_add() failes.
Originally from Louis Zhang.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/kobject.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index c92679bc29d500..2c05717a26a835 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -79,6 +79,29 @@ void kobject_init(struct kobject * kobj) kobj->kset = kset_get(kobj->kset); } + +/** + * unlink - remove kobject from kset list. + * @kobj: kobject. + * + * Remove the kobject from the kset list and decrement + * its parent's refcount. + * This is separated out, so we can use it in both + * kobject_del() and kobject_add() on error. + */ + +static void unlink(struct kobject * kobj) +{ + if (kobj->kset) { + down_write(&kobj->kset->subsys->rwsem); + list_del_init(&kobj->entry); + up_write(&kobj->kset->subsys->rwsem); + } + if (kobj->parent) + kobject_put(kobj->parent); + kobject_put(kobj); +} + /** * kobject_add - add an object to the hierarchy. * @kobj: object. @@ -109,8 +132,8 @@ int kobject_add(struct kobject * kobj) up_write(&kobj->kset->subsys->rwsem); } error = create_dir(kobj); - if (error && parent) - kobject_put(parent); + if (error) + unlink(kobj); return error; } @@ -140,14 +163,7 @@ int kobject_register(struct kobject * kobj) void kobject_del(struct kobject * kobj) { sysfs_remove_dir(kobj); - if (kobj->kset) { - down_write(&kobj->kset->subsys->rwsem); - list_del_init(&kobj->entry); - up_write(&kobj->kset->subsys->rwsem); - } - if (kobj->parent) - kobject_put(kobj->parent); - kobject_put(kobj); + unlink(kobj); } /** |