diff options
author | Patrick Mochel <mochel@osdl.org> | 2003-01-05 11:31:14 -0600 |
---|---|---|
committer | Patrick Mochel <mochel@osdl.org> | 2003-01-05 11:31:14 -0600 |
commit | 3e815107666d4ee5089661a7125af302797b3e08 (patch) | |
tree | 14feb5b3f7d430ab82aec3fd98aeffff1d0aab15 /lib | |
parent | 2e1c40373d7e424a20b44858246ad3ef2ddc4a36 (diff) | |
download | history-3e815107666d4ee5089661a7125af302797b3e08.tar.gz |
Introduce struct kset.
struct kset is what struct subsystem should have originally been called. It
is a set of kobjects, and nothing more, with a much less confusing name than
'subsystem.'
struct kset contains an embedded kobject, making it possible to represent it
in the object hierarchy, and sysfs. This also provides a means for objects
to easily express a list of subordinate objects.
struct subsystem still exists, and contains an rwsem, which its subordinate
ksets use to protect their lists.
An arbitrary number of ksets may belong to a subsystem. A ksets specifies
the subsystem it belongs to via its ->subsys field.
struct subsystem also contains a default kset, which may be used without
having to define a separate kset.
The objects that defined subordinate subsystems (bus and class drivers) have
been converted to use subordinate ksets instead.
Note that the usage of ksets is flexible.
- ksets may contain a list of objects of any type, not just kobjects.
- The objects registered with a kset do not have to be registered.
- ksets themselves do not have to be registered. One can be used by
simply calling kset_init().
- ksets do not need a name if they are not registered.
- Note however that locking must be done manually in these cases.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/kobject.c | 120 |
1 files changed, 93 insertions, 27 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index f2f38b092a6a41..3d414df3683e2c 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -62,7 +62,7 @@ void kobject_init(struct kobject * kobj) { atomic_set(&kobj->refcount,1); INIT_LIST_HEAD(&kobj->entry); - kobj->subsys = subsys_get(kobj->subsys); + kobj->kset = kset_get(kobj->kset); } /** @@ -73,7 +73,6 @@ void kobject_init(struct kobject * kobj) int kobject_add(struct kobject * kobj) { int error = 0; - struct subsystem * s = kobj->subsys; struct kobject * parent; if (!(kobj = kobject_get(kobj))) @@ -81,19 +80,24 @@ int kobject_add(struct kobject * kobj) parent = kobject_get(kobj->parent); - pr_debug("kobject %s: registering. parent: %s, subsys: %s\n", + pr_debug("kobject %s: registering. parent: %s, set: %s\n", kobj->name, parent ? parent->name : "<NULL>", - kobj->subsys ? kobj->subsys->kobj.name : "<NULL>" ); + kobj->kset ? kobj->kset->kobj.name : "<NULL>" ); - if (s) { - down_write(&s->rwsem); + if (kobj->subsys) { + if (!kobj->kset) + kobj->kset = &kobj->subsys->kset; + } + + if (kobj->kset) { + down_write(&kobj->kset->subsys->rwsem); if (parent) list_add_tail(&kobj->entry,&parent->entry); else { - list_add_tail(&kobj->entry,&s->list); - kobj->parent = kobject_get(&s->kobj); + list_add_tail(&kobj->entry,&kobj->kset->list); + kobj->parent = kobject_get(&kobj->kset->kobj); } - up_write(&s->rwsem); + up_write(&kobj->kset->subsys->rwsem); } error = create_dir(kobj); if (error && parent) @@ -127,10 +131,10 @@ int kobject_register(struct kobject * kobj) void kobject_del(struct kobject * kobj) { sysfs_remove_dir(kobj); - if (kobj->subsys) { - down_write(&kobj->subsys->rwsem); + if (kobj->kset) { + down_write(&kobj->kset->subsys->rwsem); list_del_init(&kobj->entry); - up_write(&kobj->subsys->rwsem); + up_write(&kobj->kset->subsys->rwsem); } if (kobj->parent) kobject_put(kobj->parent); @@ -174,17 +178,13 @@ struct kobject * kobject_get(struct kobject * kobj) void kobject_cleanup(struct kobject * kobj) { struct kobj_type * t = kobj->ktype; - struct subsystem * s = kobj->subsys; + struct kset * s = kobj->kset; pr_debug("kobject %s: cleaning up\n",kobj->name); - if (s) { - down_write(&s->rwsem); - list_del_init(&kobj->entry); - up_write(&s->rwsem); - subsys_put(s); - } if (t && t->release) t->release(kobj); + if (s) + kset_put(s); } /** @@ -203,32 +203,98 @@ void kobject_put(struct kobject * kobj) } +/** + * kset_init - initialize a kset for use + * @k: kset + */ + +void kset_init(struct kset * k) +{ + kobject_init(&k->kobj); + INIT_LIST_HEAD(&k->list); +} + + +/** + * kset_add - add a kset object to the hierarchy. + * @k: kset. + * + * Simply, this adds the kset's embedded kobject to the + * hierarchy. + * We also try to make sure that the kset's embedded kobject + * has a parent before it is added. We only care if the embedded + * kobject is not part of a kset itself, since kobject_add() + * assigns a parent in that case. + * If that is the case, and the kset has a controlling subsystem, + * then we set the kset's parent to be said subsystem. + */ + +int kset_add(struct kset * k) +{ + if (!k->kobj.parent && !k->kobj.kset && k->subsys) + k->kobj.parent = &k->subsys->kset.kobj; + + return kobject_add(&k->kobj); +} + + +/** + * kset_register - initialize and add a kset. + * @k: kset. + */ + +int kset_register(struct kset * k) +{ + kset_init(k); + return kset_add(k); +} + + +/** + * kset_unregister - remove a kset. + * @k: kset. + */ + +void kset_unregister(struct kset * k) +{ + kobject_unregister(&k->kobj); +} + + void subsystem_init(struct subsystem * s) { - kobject_init(&s->kobj); + memcpy(&s->kset.kobj,&s->kobj,sizeof(struct kobject)); init_rwsem(&s->rwsem); - INIT_LIST_HEAD(&s->list); + kset_init(&s->kset); } /** * subsystem_register - register a subsystem. * @s: the subsystem we're registering. + * + * Once we register the subsystem, we want to make sure that + * the kset points back to this subsystem for correct usage of + * the rwsem. */ int subsystem_register(struct subsystem * s) { + int error; + subsystem_init(s); - if (s->parent) - s->kobj.parent = &s->parent->kobj; - pr_debug("subsystem %s: registering, parent: %s\n", - s->kobj.name,s->parent ? s->parent->kobj.name : "<none>"); - return kobject_add(&s->kobj); + pr_debug("subsystem %s: registering\n",s->kobj.name); + + if (!(error = kset_add(&s->kset))) { + if (!s->kset.subsys) + s->kset.subsys = s; + } + return error; } void subsystem_unregister(struct subsystem * s) { pr_debug("subsystem %s: unregistering\n",s->kobj.name); - kobject_unregister(&s->kobj); + kset_unregister(&s->kset); } |