aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@osdl.org>2003-01-09 21:26:07 -0600
committerPatrick Mochel <mochel@osdl.org>2003-01-09 21:26:07 -0600
commit00880cfff75b3b1fa44d8586d73fe2663644b0ba (patch)
treed0b505118aa18f9ff5dcdd2134d56b073e7b0928 /lib
parent1a0bc0cc856dd68f6ea4203af64a2b96d3cd9ec1 (diff)
downloadhistory-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.c36
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);
}
/**