X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fkobject.c;h=8e7c7199348749e63bb4cf17868e2123aa2c44fc;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=8737dfd72d36072ffb62da436bc2947b78c02a2b;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/lib/kobject.c b/lib/kobject.c index 8737dfd72..8e7c71993 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -14,6 +14,7 @@ #include #include #include +#include /** * populate_dir - populate directory with attributes. @@ -71,6 +72,8 @@ static int get_kobj_path_length(struct kobject *kobj) * Add 1 to strlen for leading '/' of each level. */ do { + if (kobject_name(parent) == NULL) + return 0; length += strlen(kobject_name(parent)) + 1; parent = parent->parent; } while (parent); @@ -100,12 +103,14 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) * @kobj: kobject in question, with which to build the path * @gfp_mask: the allocation type used to allocate the path */ -char *kobject_get_path(struct kobject *kobj, int gfp_mask) +char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) { char *path; int len; len = get_kobj_path_length(kobj); + if (len == 0) + return NULL; path = kmalloc(len, gfp_mask); if (!path) return NULL; @@ -123,6 +128,7 @@ void kobject_init(struct kobject * kobj) { kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); + init_waitqueue_head(&kobj->poll); kobj->kset = kset_get(kobj->kset); } @@ -140,9 +146,9 @@ void kobject_init(struct kobject * kobj) static void unlink(struct kobject * kobj) { if (kobj->kset) { - down_write(&kobj->kset->subsys->rwsem); + spin_lock(&kobj->kset->list_lock); list_del_init(&kobj->entry); - up_write(&kobj->kset->subsys->rwsem); + spin_unlock(&kobj->kset->list_lock); } kobject_put(kobj); } @@ -161,6 +167,11 @@ int kobject_add(struct kobject * kobj) return -ENOENT; if (!kobj->k_name) kobj->k_name = kobj->name; + if (!kobj->k_name) { + pr_debug("kobject attempted to be registered with no name!\n"); + WARN_ON(1); + return -EINVAL; + } parent = kobject_get(kobj->parent); pr_debug("kobject %s: registering. parent: %s, set: %s\n", @@ -168,13 +179,13 @@ int kobject_add(struct kobject * kobj) kobj->kset ? kobj->kset->kobj.name : "" ); if (kobj->kset) { - down_write(&kobj->kset->subsys->rwsem); + spin_lock(&kobj->kset->list_lock); if (!parent) parent = kobject_get(&kobj->kset->kobj); list_add_tail(&kobj->entry,&kobj->kset->list); - up_write(&kobj->kset->subsys->rwsem); + spin_unlock(&kobj->kset->list_lock); } kobj->parent = parent; @@ -184,8 +195,17 @@ int kobject_add(struct kobject * kobj) unlink(kobj); if (parent) kobject_put(parent); - } else { - kobject_hotplug(kobj, KOBJ_ADD); + + /* be noisy on error issues */ + if (error == -EEXIST) + printk("kobject_add failed for %s with -EEXIST, " + "don't try to register things with the " + "same name in the same directory.\n", + kobject_name(kobj)); + else + printk("kobject_add failed for %s (%d)\n", + kobject_name(kobj), error); + dump_stack(); } return error; @@ -199,17 +219,13 @@ int kobject_add(struct kobject * kobj) int kobject_register(struct kobject * kobj) { - int error = 0; + int error = -EINVAL; if (kobj) { kobject_init(kobj); error = kobject_add(kobj); - if (error) { - printk("kobject_register failed for %s (%d)\n", - kobject_name(kobj),error); - dump_stack(); - } - } else - error = -EINVAL; + if (!error) + kobject_uevent(kobj, KOBJ_ADD); + } return error; } @@ -217,13 +233,12 @@ int kobject_register(struct kobject * kobj) /** * kobject_set_name - Set the name of an object * @kobj: object. - * @name: name. + * @fmt: format string used to build the name * * If strlen(name) >= KOBJ_NAME_LEN, then use a dynamically allocated * string that @kobj->k_name points to. Otherwise, use the static * @kobj->name array. */ - int kobject_set_name(struct kobject * kobj, const char * fmt, ...) { int error = 0; @@ -281,7 +296,7 @@ EXPORT_SYMBOL(kobject_set_name); * @new_name: object's new name */ -int kobject_rename(struct kobject * kobj, char *new_name) +int kobject_rename(struct kobject * kobj, const char *new_name) { int error = 0; @@ -301,7 +316,6 @@ int kobject_rename(struct kobject * kobj, char *new_name) void kobject_del(struct kobject * kobj) { - kobject_hotplug(kobj, KOBJ_REMOVE); sysfs_remove_dir(kobj); unlink(kobj); } @@ -314,6 +328,7 @@ void kobject_del(struct kobject * kobj) void kobject_unregister(struct kobject * kobj) { pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); + kobject_uevent(kobj, KOBJ_REMOVE); kobject_del(kobj); kobject_put(kobj); } @@ -371,6 +386,43 @@ void kobject_put(struct kobject * kobj) } +static void dir_release(struct kobject *kobj) +{ + kfree(kobj); +} + +static struct kobj_type dir_ktype = { + .release = dir_release, + .sysfs_ops = NULL, + .default_attrs = NULL, +}; + +/** + * kobject_add_dir - add sub directory of object. + * @parent: object in which a directory is created. + * @name: directory name. + * + * Add a plain directory object as child of given object. + */ +struct kobject *kobject_add_dir(struct kobject *parent, const char *name) +{ + struct kobject *k; + + if (!parent) + return NULL; + + k = kzalloc(sizeof(*k), GFP_KERNEL); + if (!k) + return NULL; + + k->parent = parent; + k->ktype = &dir_ktype; + kobject_set_name(k, name); + kobject_register(k); + + return k; +} + /** * kset_init - initialize a kset for use * @k: kset @@ -380,6 +432,7 @@ void kset_init(struct kset * k) { kobject_init(&k->kobj); INIT_LIST_HEAD(&k->list); + spin_lock_init(&k->list_lock); } @@ -444,7 +497,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name) struct list_head * entry; struct kobject * ret = NULL; - down_read(&kset->subsys->rwsem); + spin_lock(&kset->list_lock); list_for_each(entry,&kset->list) { struct kobject * k = to_kobj(entry); if (kobject_name(k) && !strcmp(kobject_name(k),name)) { @@ -452,7 +505,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name) break; } } - up_read(&kset->subsys->rwsem); + spin_unlock(&kset->list_lock); return ret; } @@ -515,7 +568,7 @@ int subsys_create_file(struct subsystem * s, struct subsys_attribute * a) * @s: subsystem. * @a: attribute desciptor. */ - +#if 0 void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a) { if (subsys_get(s)) { @@ -523,8 +576,8 @@ void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a) subsys_put(s); } } +#endif /* 0 */ -EXPORT_SYMBOL(kobject_get_path); EXPORT_SYMBOL(kobject_init); EXPORT_SYMBOL(kobject_register); EXPORT_SYMBOL(kobject_unregister); @@ -532,14 +585,10 @@ EXPORT_SYMBOL(kobject_get); EXPORT_SYMBOL(kobject_put); EXPORT_SYMBOL(kobject_add); EXPORT_SYMBOL(kobject_del); -EXPORT_SYMBOL(kobject_rename); EXPORT_SYMBOL(kset_register); EXPORT_SYMBOL(kset_unregister); -EXPORT_SYMBOL(kset_find_obj); -EXPORT_SYMBOL(subsystem_init); EXPORT_SYMBOL(subsystem_register); EXPORT_SYMBOL(subsystem_unregister); EXPORT_SYMBOL(subsys_create_file); -EXPORT_SYMBOL(subsys_remove_file);