From 7a83d456a86d559a6347115d206d23774bc152d9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 24 Oct 2007 21:52:56 -0700 Subject: kobject: remove incorrect comment in kobject_rename As pointed out by Kay. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 3590f022a609..9500339ae024 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -334,8 +334,6 @@ int kobject_rename(struct kobject * kobj, const char *new_name) sprintf(devpath_string, "DEVPATH_OLD=%s", devpath); envp[0] = devpath_string; envp[1] = NULL; - /* Note : if we want to send the new name alone, not the full path, - * we could probably use kobject_name(kobj); */ error = sysfs_rename_dir(kobj, new_name); -- cgit v1.2.2 From 663a47430b361f863b515752a97166a7a4b92d35 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 29 Nov 2007 18:32:47 -0500 Subject: kobject: fix up kobject_set_name to use kvasprintf Kay pointed out that kobject_set_name was being very stupid, doing two allocations for every call, when it should just be using the kernel function kvasprintf() instead. This change adds the internal kobject_set_name_vargs() function, which other follow-on patches will be using. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 71 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 39 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 9500339ae024..4a310e55a886 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -232,60 +232,53 @@ int kobject_register(struct kobject * kobj) return error; } +/** + * kobject_set_name_vargs - Set the name of an kobject + * @kobj: struct kobject to set the name of + * @fmt: format string used to build the name + * @vargs: vargs to format the string. + */ +static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, + va_list vargs) +{ + va_list aq; + char *name; + + va_copy(aq, vargs); + name = kvasprintf(GFP_KERNEL, fmt, vargs); + va_end(aq); + + if (!name) + return -ENOMEM; + + /* Free the old name, if necessary. */ + kfree(kobj->k_name); + + /* Now, set the new name */ + kobj->k_name = name; + + return 0; +} /** * kobject_set_name - Set the name of a kobject - * @kobj: kobject to name + * @kobj: struct kobject to set the name of * @fmt: format string used to build the name * * This sets the name of the kobject. If you have already added the * kobject to the system, you must call kobject_rename() in order to * change the name of the kobject. */ -int kobject_set_name(struct kobject * kobj, const char * fmt, ...) +int kobject_set_name(struct kobject *kobj, const char *fmt, ...) { - int error = 0; - int limit; - int need; va_list args; - char *name; + int retval; - /* find out how big a buffer we need */ - name = kmalloc(1024, GFP_KERNEL); - if (!name) { - error = -ENOMEM; - goto done; - } va_start(args, fmt); - need = vsnprintf(name, 1024, fmt, args); + retval = kobject_set_name_vargs(kobj, fmt, args); va_end(args); - kfree(name); - /* Allocate the new space and copy the string in */ - limit = need + 1; - name = kmalloc(limit, GFP_KERNEL); - if (!name) { - error = -ENOMEM; - goto done; - } - va_start(args, fmt); - need = vsnprintf(name, limit, fmt, args); - va_end(args); - - /* something wrong with the string we copied? */ - if (need >= limit) { - kfree(name); - error = -EFAULT; - goto done; - } - - /* Free the old name, if necessary. */ - kfree(kobj->k_name); - - /* Now, set the new name */ - kobj->k_name = name; -done: - return error; + return retval; } EXPORT_SYMBOL(kobject_set_name); -- cgit v1.2.2 From 18041f4775688af073d9b3ab0ffc262c1847e60b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Dec 2007 21:31:08 -0800 Subject: kobject: make kobject_cleanup be static No one except the kobject core calls it so make the function static. Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 4a310e55a886..a152036db006 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -436,12 +436,11 @@ struct kobject * kobject_get(struct kobject * kobj) return kobj; } -/** - * kobject_cleanup - free kobject resources. - * @kobj: object. +/* + * kobject_cleanup - free kobject resources. + * @kobj: object to cleanup */ - -void kobject_cleanup(struct kobject * kobj) +static void kobject_cleanup(struct kobject *kobj) { struct kobj_type * t = get_ktype(kobj); struct kset * s = kobj->kset; -- cgit v1.2.2 From e86000d042d23904bbb609af2f8618a541cf129b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Dec 2007 21:31:08 -0800 Subject: kobject: add kobject_init_ng function This is what the kobject_init function is going to become. Add this to the kernel and then we can convert the tree over to use it. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index a152036db006..60586bcc7a71 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -282,6 +282,48 @@ int kobject_set_name(struct kobject *kobj, const char *fmt, ...) } EXPORT_SYMBOL(kobject_set_name); +/** + * kobject_init_ng - initialize a kobject structure + * @kobj: pointer to the kobject to initialize + * @ktype: pointer to the ktype for this kobject. + * + * This function will properly initialize a kobject such that it can then + * be passed to the kobject_add() call. + * + * After this function is called, the kobject MUST be cleaned up by a call + * to kobject_put(), not by a call to kfree directly to ensure that all of + * the memory is cleaned up properly. + */ +void kobject_init_ng(struct kobject *kobj, struct kobj_type *ktype) +{ + char *err_str; + + if (!kobj) { + err_str = "invalid kobject pointer!"; + goto error; + } + if (!ktype) { + err_str = "must have a ktype to be initialized properly!\n"; + goto error; + } + if (atomic_read(&kobj->kref.refcount)) { + /* do not error out as sometimes we can recover */ + printk(KERN_ERR "kobject: reference count is already set, " + "something is seriously wrong.\n"); + dump_stack(); + } + + kref_init(&kobj->kref); + INIT_LIST_HEAD(&kobj->entry); + kobj->ktype = ktype; + return; + +error: + printk(KERN_ERR "kobject: %s\n", err_str); + dump_stack(); +} +EXPORT_SYMBOL(kobject_init_ng); + /** * kobject_rename - change the name of an object * @kobj: object in question. -- cgit v1.2.2 From 244f6cee9a928103132a722292bfa0eb84114b07 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Dec 2007 21:31:08 -0800 Subject: kobject: add kobject_add_ng function This is what the kobject_add function is going to become. Add this to the kernel and then we can convert the tree over to use it. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 60586bcc7a71..329fd1126b3f 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -324,6 +324,72 @@ error: } EXPORT_SYMBOL(kobject_init_ng); +static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, + const char *fmt, va_list vargs) +{ + va_list aq; + int retval; + + va_copy(aq, vargs); + retval = kobject_set_name_vargs(kobj, fmt, aq); + va_end(aq); + if (retval) { + printk(KERN_ERR "kobject: can not set name properly!\n"); + return retval; + } + kobj->parent = parent; + return kobject_add(kobj); +} + +/** + * kobject_add_ng - the main kobject add function + * @kobj: the kobject to add + * @parent: pointer to the parent of the kobject. + * @fmt: format to name the kobject with. + * + * The kobject name is set and added to the kobject hierarchy in this + * function. + * + * If @parent is set, then the parent of the @kobj will be set to it. + * If @parent is NULL, then the parent of the @kobj will be set to the + * kobject associted with the kset assigned to this kobject. If no kset + * is assigned to the kobject, then the kobject will be located in the + * root of the sysfs tree. + * + * If this function returns an error, kobject_put() must be called to + * properly clean up the memory associated with the object. + * + * If the function is successful, the only way to properly clean up the + * memory is with a call to kobject_del(), in which case, a call to + * kobject_put() is not necessary (kobject_del() does the final + * kobject_put() to call the release function in the ktype's release + * pointer.) + * + * Under no instance should the kobject that is passed to this function + * be directly freed with a call to kfree(), that can leak memory. + * + * Note, no uevent will be created with this call, the caller should set + * up all of the necessary sysfs files for the object and then call + * kobject_uevent() with the UEVENT_ADD parameter to ensure that + * userspace is properly notified of this kobject's creation. + */ +int kobject_add_ng(struct kobject *kobj, struct kobject *parent, + const char *fmt, ...) +{ + va_list args; + int retval; + + if (!kobj) + return -EINVAL; + + va_start(args, fmt); + retval = kobject_add_varg(kobj, parent, fmt, args); + va_end(args); + + return retval; +} +EXPORT_SYMBOL(kobject_add_ng); + /** * kobject_rename - change the name of an object * @kobj: object in question. -- cgit v1.2.2 From c11c4154e7ff4cebfadad849b1e22689d759c3f4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Dec 2007 21:31:08 -0800 Subject: kobject: add kobject_init_and_add function Also add a kobject_init_and_add function which bundles up what a lot of the current callers want to do all at once, and it properly handles the memory usages, unlike kobject_register(); Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 329fd1126b3f..8f249408b2ec 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -390,6 +390,33 @@ int kobject_add_ng(struct kobject *kobj, struct kobject *parent, } EXPORT_SYMBOL(kobject_add_ng); +/** + * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy + * @kobj: pointer to the kobject to initialize + * @ktype: pointer to the ktype for this kobject. + * @parent: pointer to the parent of this kobject. + * @fmt: the name of the kobject. + * + * This function combines the call to kobject_init_ng() and + * kobject_add_ng(). The same type of error handling after a call to + * kobject_add_ng() and kobject lifetime rules are the same here. + */ +int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, + struct kobject *parent, const char *fmt, ...) +{ + va_list args; + int retval; + + kobject_init_ng(kobj, ktype); + + va_start(args, fmt); + retval = kobject_add_varg(kobj, parent, fmt, args); + va_end(args); + + return retval; +} +EXPORT_SYMBOL_GPL(kobject_init_and_add); + /** * kobject_rename - change the name of an object * @kobj: object in question. -- cgit v1.2.2 From b727c702896f88d2ff6c3e03bd011d7c3dffe3e1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 27 Sep 2007 14:48:53 -0700 Subject: kset: add kset_create_and_add function Now ksets can be dynamically created on the fly, no static definitions are required. Thanks to Miklos for hints on how to make this work better for the callers. And thanks to Kay for finding some stupid bugs in my original version and pointing out that we need to handle the fact that kobject's can have a kset as a parent and to handle that properly in kobject_add(). Cc: Kay Sievers Cc: Miklos Szeredi Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 8f249408b2ec..4fb27ba28807 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -186,8 +186,15 @@ int kobject_add(struct kobject * kobj) if (kobj->kset) { spin_lock(&kobj->kset->list_lock); - if (!parent) + if (!parent) { parent = kobject_get(&kobj->kset->kobj); + /* + * If the kset is our parent, get a second + * reference, we drop both the kset and the + * parent ref on cleanup + */ + kobject_get(parent); + } list_add_tail(&kobj->entry,&kobj->kset->list); spin_unlock(&kobj->kset->list_lock); @@ -787,6 +794,89 @@ int subsys_create_file(struct kset *s, struct subsys_attribute *a) return error; } +static void kset_release(struct kobject *kobj) +{ + struct kset *kset = container_of(kobj, struct kset, kobj); + pr_debug("kset %s: now freed\n", kobject_name(kobj)); + kfree(kset); +} + +static struct kobj_type kset_type = { + .release = kset_release, +}; + +/** + * kset_create - create a struct kset dynamically + * + * @name: the name for the kset + * @uevent_ops: a struct kset_uevent_ops for the kset + * @parent_kobj: the parent kobject of this kset, if any. + * + * This function creates a kset structure dynamically. This structure can + * then be registered with the system and show up in sysfs with a call to + * kset_register(). When you are finished with this structure, if + * kset_register() has been called, call kset_unregister() and the + * structure will be dynamically freed when it is no longer being used. + * + * If the kset was not able to be created, NULL will be returned. + */ +static struct kset *kset_create(const char *name, + struct kset_uevent_ops *uevent_ops, + struct kobject *parent_kobj) +{ + struct kset *kset; + + kset = kzalloc(sizeof(*kset), GFP_KERNEL); + if (!kset) + return NULL; + kobject_set_name(&kset->kobj, name); + kset->uevent_ops = uevent_ops; + kset->kobj.parent = parent_kobj; + + /* + * The kobject of this kset will have a type of kset_type and belong to + * no kset itself. That way we can properly free it when it is + * finished being used. + */ + kset->kobj.ktype = &kset_type; + kset->kobj.kset = NULL; + + return kset; +} + +/** + * kset_create_and_add - create a struct kset dynamically and add it to sysfs + * + * @name: the name for the kset + * @uevent_ops: a struct kset_uevent_ops for the kset + * @parent_kobj: the parent kobject of this kset, if any. + * + * This function creates a kset structure dynamically and registers it + * with sysfs. When you are finished with this structure, call + * kset_unregister() and the structure will be dynamically freed when it + * is no longer being used. + * + * If the kset was not able to be created, NULL will be returned. + */ +struct kset *kset_create_and_add(const char *name, + struct kset_uevent_ops *uevent_ops, + struct kobject *parent_kobj) +{ + struct kset *kset; + int error; + + kset = kset_create(name, uevent_ops, parent_kobj); + if (!kset) + return NULL; + error = kset_register(kset); + if (error) { + kfree(kset); + return NULL; + } + return kset; +} +EXPORT_SYMBOL_GPL(kset_create_and_add); + EXPORT_SYMBOL(kobject_init); EXPORT_SYMBOL(kobject_register); EXPORT_SYMBOL(kobject_unregister); -- cgit v1.2.2 From 3f9e3ee9dc3605e5c593b5d708494571fb0d3970 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Nov 2007 13:16:15 -0800 Subject: kobject: add kobject_create_and_add function This lets users create dynamic kobjects much easier. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 18 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 4fb27ba28807..98422a3eeffc 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -619,18 +619,69 @@ void kobject_put(struct kobject * kobj) kref_put(&kobj->kref, kobject_release); } - -static void dir_release(struct kobject *kobj) +static void dynamic_kobj_release(struct kobject *kobj) { + pr_debug("%s: freeing %s\n", __FUNCTION__, kobject_name(kobj)); kfree(kobj); } -static struct kobj_type dir_ktype = { - .release = dir_release, - .sysfs_ops = NULL, - .default_attrs = NULL, +static struct kobj_type dynamic_kobj_ktype = { + .release = dynamic_kobj_release, }; +/* + * kobject_create - create a struct kobject dynamically + * + * This function creates a kobject structure dynamically and sets it up + * to be a "dynamic" kobject with a default release function set up. + * + * If the kobject was not able to be created, NULL will be returned. + */ +static struct kobject *kobject_create(void) +{ + struct kobject *kobj; + + kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); + if (!kobj) + return NULL; + + kobject_init_ng(kobj, &dynamic_kobj_ktype); + return kobj; +} + +/** + * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs + * + * @name: the name for the kset + * @parent: the parent kobject of this kobject, if any. + * + * This function creates a kset structure dynamically and registers it + * with sysfs. When you are finished with this structure, call + * kobject_unregister() and the structure will be dynamically freed when + * it is no longer being used. + * + * If the kobject was not able to be created, NULL will be returned. + */ +struct kobject *kobject_create_and_add(const char *name, struct kobject *parent) +{ + struct kobject *kobj; + int retval; + + kobj = kobject_create(); + if (!kobj) + return NULL; + + retval = kobject_add_ng(kobj, parent, "%s", name); + if (retval) { + printk(KERN_WARNING "%s: kobject_add error: %d\n", + __FUNCTION__, retval); + kobject_put(kobj); + kobj = NULL; + } + return kobj; +} +EXPORT_SYMBOL_GPL(kobject_create_and_add); + /** * kobject_kset_add_dir - add sub directory of object. * @kset: kset the directory is belongs to. @@ -645,23 +696,17 @@ struct kobject *kobject_kset_add_dir(struct kset *kset, struct kobject *k; int ret; - if (!parent) - return NULL; - - k = kzalloc(sizeof(*k), GFP_KERNEL); + k = kobject_create(); if (!k) return NULL; k->kset = kset; - k->parent = parent; - k->ktype = &dir_ktype; - kobject_set_name(k, name); - ret = kobject_register(k); + ret = kobject_add_ng(k, parent, "%s", name); if (ret < 0) { - printk(KERN_WARNING "%s: kobject_register error: %d\n", + printk(KERN_WARNING "%s: kobject_add error: %d\n", __func__, ret); - kobject_del(k); - return NULL; + kobject_put(k); + k = NULL; } return k; @@ -676,7 +721,7 @@ struct kobject *kobject_kset_add_dir(struct kset *kset, */ struct kobject *kobject_add_dir(struct kobject *parent, const char *name) { - return kobject_kset_add_dir(NULL, parent, name); + return kobject_create_and_add(name, parent); } /** -- cgit v1.2.2 From 4ff6abff832fbc6cb1d769f6106c841bc2b09f63 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Nov 2007 22:24:43 -0800 Subject: kobject: get rid of kobject_add_dir kobject_create_and_add is the same as kobject_add_dir, so drop kobject_add_dir. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 98422a3eeffc..96b61d9a9284 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -712,18 +712,6 @@ struct kobject *kobject_kset_add_dir(struct kset *kset, return k; } -/** - * 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) -{ - return kobject_create_and_add(name, parent); -} - /** * kset_init - initialize a kset for use * @k: kset -- cgit v1.2.2 From 43968d2f1648f4dc92437dc0363a3e88377445b3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 5 Nov 2007 22:24:43 -0800 Subject: kobject: get rid of kobject_kset_add_dir kobject_kset_add_dir is only called in one place so remove it and use kobject_create() instead. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 37 +++++-------------------------------- 1 file changed, 5 insertions(+), 32 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 96b61d9a9284..67c3d38d48f0 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -629,15 +629,18 @@ static struct kobj_type dynamic_kobj_ktype = { .release = dynamic_kobj_release, }; -/* +/** * kobject_create - create a struct kobject dynamically * * This function creates a kobject structure dynamically and sets it up * to be a "dynamic" kobject with a default release function set up. * * If the kobject was not able to be created, NULL will be returned. + * The kobject structure returned from here must be cleaned up with a + * call to kobject_put() and not kfree(), as kobject_init_ng() has + * already been called on this structure. */ -static struct kobject *kobject_create(void) +struct kobject *kobject_create(void) { struct kobject *kobj; @@ -682,36 +685,6 @@ struct kobject *kobject_create_and_add(const char *name, struct kobject *parent) } EXPORT_SYMBOL_GPL(kobject_create_and_add); -/** - * kobject_kset_add_dir - add sub directory of object. - * @kset: kset the directory is belongs to. - * @parent: object in which a directory is created. - * @name: directory name. - * - * Add a plain directory object as child of given object. - */ -struct kobject *kobject_kset_add_dir(struct kset *kset, - struct kobject *parent, const char *name) -{ - struct kobject *k; - int ret; - - k = kobject_create(); - if (!k) - return NULL; - - k->kset = kset; - ret = kobject_add_ng(k, parent, "%s", name); - if (ret < 0) { - printk(KERN_WARNING "%s: kobject_add error: %d\n", - __func__, ret); - kobject_put(k); - k = NULL; - } - - return k; -} - /** * kset_init - initialize a kset for use * @k: kset -- cgit v1.2.2 From 23b5212cc7422f475b82124334b64277b5b43013 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 2 Nov 2007 13:47:53 +0100 Subject: Driver Core: add kobj_attribute handling Add kobj_sysfs_ops to replace subsys_sysfs_ops. There is no need for special kset operations, we want to be able to use simple attribute operations at any kobject, not only ksets. The whole concept of any default sysfs attribute operations will go away with the upcoming removal of subsys_sysfs_ops. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 67c3d38d48f0..1c343fe4ba63 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -697,6 +697,35 @@ void kset_init(struct kset * k) spin_lock_init(&k->list_lock); } +/* default kobject attribute operations */ +static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct kobj_attribute *kattr; + ssize_t ret = -EIO; + + kattr = container_of(attr, struct kobj_attribute, attr); + if (kattr->show) + ret = kattr->show(kobj, kattr, buf); + return ret; +} + +static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) +{ + struct kobj_attribute *kattr; + ssize_t ret = -EIO; + + kattr = container_of(attr, struct kobj_attribute, attr); + if (kattr->store) + ret = kattr->store(kobj, kattr, buf, count); + return ret; +} + +struct sysfs_ops kobj_sysfs_ops = { + .show = kobj_attr_show, + .store = kobj_attr_store, +}; /** * kset_add - add a kset object to the hierarchy. -- cgit v1.2.2 From 386f275f5d097758f867bc99ddeaeb7a03b6b190 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 2 Nov 2007 13:47:53 +0100 Subject: Driver Core: switch all dynamic ksets to kobj_sysfs_ops Switch all dynamically created ksets, that export simple attributes, to kobj_attribute from subsys_attribute. Struct subsys_attribute will be removed. Signed-off-by: Kay Sievers Cc: Mike Halcrow Cc: Phillip Hellewell Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 1c343fe4ba63..99f6354a5751 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -626,7 +626,8 @@ static void dynamic_kobj_release(struct kobject *kobj) } static struct kobj_type dynamic_kobj_ktype = { - .release = dynamic_kobj_release, + .release = dynamic_kobj_release, + .sysfs_ops = &kobj_sysfs_ops, }; /** @@ -836,7 +837,8 @@ static void kset_release(struct kobject *kobj) kfree(kset); } -static struct kobj_type kset_type = { +static struct kobj_type kset_ktype = { + .sysfs_ops = &kobj_sysfs_ops, .release = kset_release, }; @@ -869,11 +871,11 @@ static struct kset *kset_create(const char *name, kset->kobj.parent = parent_kobj; /* - * The kobject of this kset will have a type of kset_type and belong to + * The kobject of this kset will have a type of kset_ktype and belong to * no kset itself. That way we can properly free it when it is * finished being used. */ - kset->kobj.ktype = &kset_type; + kset->kobj.ktype = &kset_ktype; kset->kobj.kset = NULL; return kset; -- cgit v1.2.2 From 000f2a4d8cfc1e1cbc0aa98136015e7ae7719b46 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 2 Nov 2007 13:47:53 +0100 Subject: Driver Core: kill subsys_attribute and default sysfs ops Remove the no longer needed subsys_attributes, they are all converted to the more sensical kobj_attributes. There is no longer a magic fallback in sysfs attribute operations, all kobjects which create simple attributes need explicitely a ktype assigned, which tells the core what was intended here. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 99f6354a5751..c742ac25228a 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -810,26 +810,6 @@ void subsystem_unregister(struct kset *s) kset_unregister(s); } -/** - * subsystem_create_file - export sysfs attribute file. - * @s: subsystem. - * @a: subsystem attribute descriptor. - */ - -int subsys_create_file(struct kset *s, struct subsys_attribute *a) -{ - int error = 0; - - if (!s || !a) - return -EINVAL; - - if (kset_get(s)) { - error = sysfs_create_file(&s->kobj, &a->attr); - kset_put(s); - } - return error; -} - static void kset_release(struct kobject *kobj) { struct kset *kset = container_of(kobj, struct kset, kobj); @@ -927,4 +907,3 @@ EXPORT_SYMBOL(kset_unregister); EXPORT_SYMBOL(subsystem_register); EXPORT_SYMBOL(subsystem_unregister); -EXPORT_SYMBOL(subsys_create_file); -- cgit v1.2.2 From 2fb9113b974c3c7c43e76647bd5077238e274e1c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 6 Nov 2007 15:03:30 -0800 Subject: kobject: remove subsystem_(un)register functions These functions are no longer used and are the last remants of the old subsystem crap. So delete them for good. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index c742ac25228a..7919c32a3a15 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -800,16 +800,6 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name) return ret; } -int subsystem_register(struct kset *s) -{ - return kset_register(s); -} - -void subsystem_unregister(struct kset *s) -{ - kset_unregister(s); -} - static void kset_release(struct kobject *kobj) { struct kset *kset = container_of(kobj, struct kset, kobj); @@ -904,6 +894,3 @@ EXPORT_SYMBOL(kobject_del); EXPORT_SYMBOL(kset_register); EXPORT_SYMBOL(kset_unregister); - -EXPORT_SYMBOL(subsystem_register); -EXPORT_SYMBOL(subsystem_unregister); -- cgit v1.2.2 From cfb36fff45e3997b8044c81045fc4869ba5f281a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 Nov 2007 10:46:22 -0800 Subject: kobject: grab the kset reference in kobject_add, not kobject_init kobject_init should not be grabing any references, but only initializing the object. This patch fixes this, and makes the lock hold-time shorter for when a kset is present in the kobject. The current kernel tree has been audited to verify that this change should be safe. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 7919c32a3a15..4d52b6f534bc 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -133,7 +133,6 @@ void kobject_init(struct kobject * kobj) return; kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); - kobj->kset = kset_get(kobj->kset); } @@ -184,7 +183,7 @@ int kobject_add(struct kobject * kobj) kobj->kset ? kobject_name(&kobj->kset->kobj) : "" ); if (kobj->kset) { - spin_lock(&kobj->kset->list_lock); + kobj->kset = kset_get(kobj->kset); if (!parent) { parent = kobject_get(&kobj->kset->kobj); @@ -196,7 +195,8 @@ int kobject_add(struct kobject * kobj) kobject_get(parent); } - list_add_tail(&kobj->entry,&kobj->kset->list); + spin_lock(&kobj->kset->list_lock); + list_add_tail(&kobj->entry, &kobj->kset->list); spin_unlock(&kobj->kset->list_lock); kobj->parent = parent; } -- cgit v1.2.2 From 9f66fa2a4690a16da0dbaae2f44ddfc313802504 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 28 Nov 2007 23:49:41 -0800 Subject: kobject: clean up debugging messages The kobject debugging messages are a mess. This provides a unified message that makes them actually useful. The format for new kobject debug messages should be: kobject: 'KOBJECT_NAME' (ADDRESS): FUNCTION_NAME: message.\n Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 4d52b6f534bc..1015f74212d0 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -95,7 +95,8 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) *(path + --length) = '/'; } - pr_debug("%s: path = '%s'\n",__FUNCTION__,path); + pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj), + kobj, __FUNCTION__,path); } /** @@ -171,15 +172,17 @@ int kobject_add(struct kobject * kobj) if (!kobj->k_name) kobject_set_name(kobj, "NO_NAME"); if (!*kobj->k_name) { - pr_debug("kobject attempted to be registered with no name!\n"); + pr_debug("kobject (%p) attempted to be registered with no " + "name!\n", kobj); WARN_ON(1); kobject_put(kobj); return -EINVAL; } parent = kobject_get(kobj->parent); - pr_debug("kobject %s: registering. parent: %s, set: %s\n", - kobject_name(kobj), parent ? kobject_name(parent) : "", + pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", + kobject_name(kobj), kobj, __FUNCTION__, + parent ? kobject_name(parent) : "", kobj->kset ? kobject_name(&kobj->kset->kobj) : "" ); if (kobj->kset) { @@ -560,7 +563,8 @@ void kobject_unregister(struct kobject * kobj) { if (!kobj) return; - pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); + pr_debug("kobject: '%s' (%p): %s\n", + kobject_name(kobj), kobj, __FUNCTION__); kobject_uevent(kobj, KOBJ_REMOVE); kobject_del(kobj); kobject_put(kobj); @@ -589,7 +593,8 @@ static void kobject_cleanup(struct kobject *kobj) struct kobject * parent = kobj->parent; const char *name = kobj->k_name; - pr_debug("kobject %s: cleaning up\n",kobject_name(kobj)); + pr_debug("kobject: '%s' (%p): %s\n", + kobject_name(kobj), kobj, __FUNCTION__); if (t && t->release) { t->release(kobj); /* If we have a release function, we can guess that this was @@ -621,7 +626,8 @@ void kobject_put(struct kobject * kobj) static void dynamic_kobj_release(struct kobject *kobj) { - pr_debug("%s: freeing %s\n", __FUNCTION__, kobject_name(kobj)); + pr_debug("kobject: '%s' (%p): %s\n", + kobject_name(kobj), kobj, __FUNCTION__); kfree(kobj); } @@ -803,7 +809,8 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name) static void kset_release(struct kobject *kobj) { struct kset *kset = container_of(kobj, struct kset, kobj); - pr_debug("kset %s: now freed\n", kobject_name(kobj)); + pr_debug("kobject: '%s' (%p): %s\n", + kobject_name(kobj), kobj, __FUNCTION__); kfree(kset); } -- cgit v1.2.2 From 09f82ea92822a7bbb7e816508abbda47ed54a77f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 19 Nov 2007 10:53:40 -0500 Subject: Kobject: drop child->parent ref at unregistration This patch (as1015) reverts changes that were made to the driver core about four years ago. The intent back then was to avoid certain kinds of invalid memory accesses by leaving kernel objects allocated as long as any of their children were still allocated. The original and correct approach was to wait only as long as any children were still _registered_; that's what this patch reinstates. This fixes a problem in the SCSI core made visible by the class_device to regular device conversion: A reference loop (scsi_device holds reference to request_queue, which is the child of a gendisk, which is the child of the scsi_device) prevents the data structures from being released, even though they are deregistered okay. It's possible that this change will cause a few bugs to surface, things that have been hidden for several years. They can be fixed easily enough by having the child device take an explicit reference to the parent whenever needed. Signed-off-by: Alan Stern Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 1015f74212d0..493e991abb1b 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -149,12 +149,16 @@ void kobject_init(struct kobject * kobj) static void unlink(struct kobject * kobj) { + struct kobject *parent = kobj->parent; + if (kobj->kset) { spin_lock(&kobj->kset->list_lock); list_del_init(&kobj->entry); spin_unlock(&kobj->kset->list_lock); } + kobj->parent = NULL; kobject_put(kobj); + kobject_put(parent); } /** @@ -208,7 +212,6 @@ int kobject_add(struct kobject * kobj) if (error) { /* unlink does the kobject_put() for us */ unlink(kobj); - kobject_put(parent); /* be noisy on error issues */ if (error == -EEXIST) @@ -590,7 +593,6 @@ static void kobject_cleanup(struct kobject *kobj) { struct kobj_type * t = get_ktype(kobj); struct kset * s = kobj->kset; - struct kobject * parent = kobj->parent; const char *name = kobj->k_name; pr_debug("kobject: '%s' (%p): %s\n", @@ -604,7 +606,6 @@ static void kobject_cleanup(struct kobject *kobj) } if (s) kset_put(s); - kobject_put(parent); } static void kobject_release(struct kref *kref) -- cgit v1.2.2 From 9e7bbccd0290e720e0874443932869c55f63d5a8 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Dec 2007 23:05:35 -0700 Subject: Kobject: remove kobject_add() as no one uses it anymore The old kobject_add() function is on longer in use, so let us remove it from the public scope (kset mess in the kobject.c file still uses it, but that can be cleaned up later very simply.) Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 493e991abb1b..d04789fa4da9 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -144,7 +144,7 @@ void kobject_init(struct kobject * kobj) * 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. + * kobject_del() and kobject_add_internal() on error. */ static void unlink(struct kobject * kobj) @@ -161,12 +161,7 @@ static void unlink(struct kobject * kobj) kobject_put(parent); } -/** - * kobject_add - add an object to the hierarchy. - * @kobj: object. - */ - -int kobject_add(struct kobject * kobj) +static int kobject_add_internal(struct kobject *kobj) { int error = 0; struct kobject * parent; @@ -215,13 +210,13 @@ int kobject_add(struct kobject * kobj) /* be noisy on error issues */ if (error == -EEXIST) - printk(KERN_ERR "kobject_add failed for %s with " + printk(KERN_ERR "%s failed for %s with " "-EEXIST, don't try to register things with " "the same name in the same directory.\n", - kobject_name(kobj)); + __FUNCTION__, kobject_name(kobj)); else - printk(KERN_ERR "kobject_add failed for %s (%d)\n", - kobject_name(kobj), error); + printk(KERN_ERR "%s failed for %s (%d)\n", + __FUNCTION__, kobject_name(kobj), error); dump_stack(); } @@ -351,7 +346,7 @@ static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, return retval; } kobj->parent = parent; - return kobject_add(kobj); + return kobject_add_internal(kobj); } /** @@ -742,7 +737,7 @@ struct sysfs_ops kobj_sysfs_ops = { int kset_add(struct kset * k) { - return kobject_add(&k->kobj); + return kobject_add_internal(&k->kobj); } @@ -897,7 +892,6 @@ EXPORT_SYMBOL(kobject_register); EXPORT_SYMBOL(kobject_unregister); EXPORT_SYMBOL(kobject_get); EXPORT_SYMBOL(kobject_put); -EXPORT_SYMBOL(kobject_add); EXPORT_SYMBOL(kobject_del); EXPORT_SYMBOL(kset_register); -- cgit v1.2.2 From b2d6db5878a0832659ed58476357eea2db915550 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Dec 2007 23:05:35 -0700 Subject: Kobject: rename kobject_add_ng() to kobject_add() Now that the old kobject_add() function is gone, rename kobject_add_ng() to kobject_add() to clean up the namespace. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index d04789fa4da9..359e114790cb 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -350,7 +350,7 @@ static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, } /** - * kobject_add_ng - the main kobject add function + * kobject_add - the main kobject add function * @kobj: the kobject to add * @parent: pointer to the parent of the kobject. * @fmt: format to name the kobject with. @@ -381,8 +381,8 @@ static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, * kobject_uevent() with the UEVENT_ADD parameter to ensure that * userspace is properly notified of this kobject's creation. */ -int kobject_add_ng(struct kobject *kobj, struct kobject *parent, - const char *fmt, ...) +int kobject_add(struct kobject *kobj, struct kobject *parent, + const char *fmt, ...) { va_list args; int retval; @@ -396,7 +396,7 @@ int kobject_add_ng(struct kobject *kobj, struct kobject *parent, return retval; } -EXPORT_SYMBOL(kobject_add_ng); +EXPORT_SYMBOL(kobject_add); /** * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy @@ -406,8 +406,8 @@ EXPORT_SYMBOL(kobject_add_ng); * @fmt: the name of the kobject. * * This function combines the call to kobject_init_ng() and - * kobject_add_ng(). The same type of error handling after a call to - * kobject_add_ng() and kobject lifetime rules are the same here. + * kobject_add(). The same type of error handling after a call to + * kobject_add() and kobject lifetime rules are the same here. */ int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, struct kobject *parent, const char *fmt, ...) @@ -677,7 +677,7 @@ struct kobject *kobject_create_and_add(const char *name, struct kobject *parent) if (!kobj) return NULL; - retval = kobject_add_ng(kobj, parent, "%s", name); + retval = kobject_add(kobj, parent, "%s", name); if (retval) { printk(KERN_WARNING "%s: kobject_add error: %d\n", __FUNCTION__, retval); -- cgit v1.2.2 From e1543ddf739b22a8c4218716ad50c26b3e147403 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Dec 2007 23:05:35 -0700 Subject: Kobject: remove kobject_init() as no one uses it anymore The old kobject_init() function is on longer in use, so let us remove it from the public scope (kset mess in the kobject.c file still uses it, but that can be cleaned up later very simply.) Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 359e114790cb..10d977b6e69d 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -124,11 +124,7 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) } EXPORT_SYMBOL_GPL(kobject_get_path); -/** - * kobject_init - initialize object. - * @kobj: object in question. - */ -void kobject_init(struct kobject * kobj) +static void kobject_init_internal(struct kobject * kobj) { if (!kobj) return; @@ -232,7 +228,7 @@ int kobject_register(struct kobject * kobj) { int error = -EINVAL; if (kobj) { - kobject_init(kobj); + kobject_init_internal(kobj); error = kobject_add(kobj); if (!error) kobject_uevent(kobj, KOBJ_ADD); @@ -695,7 +691,7 @@ EXPORT_SYMBOL_GPL(kobject_create_and_add); void kset_init(struct kset * k) { - kobject_init(&k->kobj); + kobject_init_internal(&k->kobj); INIT_LIST_HEAD(&k->list); spin_lock_init(&k->list_lock); } @@ -887,7 +883,6 @@ struct kset *kset_create_and_add(const char *name, } EXPORT_SYMBOL_GPL(kset_create_and_add); -EXPORT_SYMBOL(kobject_init); EXPORT_SYMBOL(kobject_register); EXPORT_SYMBOL(kobject_unregister); EXPORT_SYMBOL(kobject_get); -- cgit v1.2.2 From f9cb074bff8e762ef24c44678a5a7d907f82fbeb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Dec 2007 23:05:35 -0700 Subject: Kobject: rename kobject_init_ng() to kobject_init() Now that the old kobject_init() function is gone, rename kobject_init_ng() to kobject_init() to clean up the namespace. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 10d977b6e69d..4cc231c86225 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -287,7 +287,7 @@ int kobject_set_name(struct kobject *kobj, const char *fmt, ...) EXPORT_SYMBOL(kobject_set_name); /** - * kobject_init_ng - initialize a kobject structure + * kobject_init - initialize a kobject structure * @kobj: pointer to the kobject to initialize * @ktype: pointer to the ktype for this kobject. * @@ -298,7 +298,7 @@ EXPORT_SYMBOL(kobject_set_name); * to kobject_put(), not by a call to kfree directly to ensure that all of * the memory is cleaned up properly. */ -void kobject_init_ng(struct kobject *kobj, struct kobj_type *ktype) +void kobject_init(struct kobject *kobj, struct kobj_type *ktype) { char *err_str; @@ -326,7 +326,7 @@ error: printk(KERN_ERR "kobject: %s\n", err_str); dump_stack(); } -EXPORT_SYMBOL(kobject_init_ng); +EXPORT_SYMBOL(kobject_init); static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, const char *fmt, va_list vargs) @@ -401,7 +401,7 @@ EXPORT_SYMBOL(kobject_add); * @parent: pointer to the parent of this kobject. * @fmt: the name of the kobject. * - * This function combines the call to kobject_init_ng() and + * This function combines the call to kobject_init() and * kobject_add(). The same type of error handling after a call to * kobject_add() and kobject lifetime rules are the same here. */ @@ -411,7 +411,7 @@ int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, va_list args; int retval; - kobject_init_ng(kobj, ktype); + kobject_init(kobj, ktype); va_start(args, fmt); retval = kobject_add_varg(kobj, parent, fmt, args); @@ -636,7 +636,7 @@ static struct kobj_type dynamic_kobj_ktype = { * * If the kobject was not able to be created, NULL will be returned. * The kobject structure returned from here must be cleaned up with a - * call to kobject_put() and not kfree(), as kobject_init_ng() has + * call to kobject_put() and not kfree(), as kobject_init() has * already been called on this structure. */ struct kobject *kobject_create(void) @@ -647,7 +647,7 @@ struct kobject *kobject_create(void) if (!kobj) return NULL; - kobject_init_ng(kobj, &dynamic_kobj_ktype); + kobject_init(kobj, &dynamic_kobj_ktype); return kobj; } -- cgit v1.2.2 From 6d06adfaf82d154023141ddc0c9de18b6a49090b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 19 Dec 2007 11:26:50 -0800 Subject: Kobject: remove kobject_register() The function is no longer used by anyone in the kernel, and it prevents the proper sending of the kobject uevent after the needed files are set up by the caller. kobject_init_and_add() can be used in its place. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 4cc231c86225..3326281c96b6 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -219,23 +219,6 @@ static int kobject_add_internal(struct kobject *kobj) return error; } -/** - * kobject_register - initialize and add an object. - * @kobj: object in question. - */ - -int kobject_register(struct kobject * kobj) -{ - int error = -EINVAL; - if (kobj) { - kobject_init_internal(kobj); - error = kobject_add(kobj); - if (!error) - kobject_uevent(kobj, KOBJ_ADD); - } - return error; -} - /** * kobject_set_name_vargs - Set the name of an kobject * @kobj: struct kobject to set the name of @@ -883,7 +866,6 @@ struct kset *kset_create_and_add(const char *name, } EXPORT_SYMBOL_GPL(kset_create_and_add); -EXPORT_SYMBOL(kobject_register); EXPORT_SYMBOL(kobject_unregister); EXPORT_SYMBOL(kobject_get); EXPORT_SYMBOL(kobject_put); -- cgit v1.2.2 From 12e339ac6e31a34fe42396aec8fb1c0b43caf61e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 9 Apr 2002 12:14:34 -0700 Subject: Kset: remove kset_add function No one is calling this anymore, so just remove it and hard-code the one internal-use of it. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 3326281c96b6..c321f1910cc2 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -709,17 +709,6 @@ struct sysfs_ops kobj_sysfs_ops = { .store = kobj_attr_store, }; -/** - * kset_add - add a kset object to the hierarchy. - * @k: kset. - */ - -int kset_add(struct kset * k) -{ - return kobject_add_internal(&k->kobj); -} - - /** * kset_register - initialize and add a kset. * @k: kset. @@ -733,7 +722,7 @@ int kset_register(struct kset * k) return -EINVAL; kset_init(k); - err = kset_add(k); + err = kobject_add_internal(&k->kobj); if (err) return err; kobject_uevent(&k->kobj, KOBJ_ADD); -- cgit v1.2.2 From 0f4dafc0563c6c49e17fe14b3f5f356e4c4b8806 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 19 Dec 2007 01:40:42 +0100 Subject: Kobject: auto-cleanup on final unref We save the current state in the object itself, so we can do proper cleanup when the last reference is dropped. If the initial reference is dropped, the object will be removed from sysfs if needed, if an "add" event was sent, "remove" will be send, and the allocated resources are released. This allows us to clean up some driver core usage as well as allowing us to do other such changes to the rest of the kernel. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 170 +++++++++++++++++++++++++++++++++------------------------- 1 file changed, 96 insertions(+), 74 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index c321f1910cc2..4fce5ca42c2e 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -124,85 +124,74 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) } EXPORT_SYMBOL_GPL(kobject_get_path); -static void kobject_init_internal(struct kobject * kobj) +/* add the kobject to its kset's list */ +static void kobj_kset_join(struct kobject *kobj) { - if (!kobj) + if (!kobj->kset) return; - kref_init(&kobj->kref); - INIT_LIST_HEAD(&kobj->entry); + + kset_get(kobj->kset); + spin_lock(&kobj->kset->list_lock); + list_add_tail(&kobj->entry, &kobj->kset->list); + spin_unlock(&kobj->kset->list_lock); } +/* remove the kobject from its kset's list */ +static void kobj_kset_leave(struct kobject *kobj) +{ + if (!kobj->kset) + return; -/** - * 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_internal() on error. - */ + spin_lock(&kobj->kset->list_lock); + list_del_init(&kobj->entry); + spin_unlock(&kobj->kset->list_lock); + kset_put(kobj->kset); +} -static void unlink(struct kobject * kobj) +static void kobject_init_internal(struct kobject * kobj) { - struct kobject *parent = kobj->parent; - - if (kobj->kset) { - spin_lock(&kobj->kset->list_lock); - list_del_init(&kobj->entry); - spin_unlock(&kobj->kset->list_lock); - } - kobj->parent = NULL; - kobject_put(kobj); - kobject_put(parent); + if (!kobj) + return; + kref_init(&kobj->kref); + INIT_LIST_HEAD(&kobj->entry); } + static int kobject_add_internal(struct kobject *kobj) { int error = 0; struct kobject * parent; - if (!(kobj = kobject_get(kobj))) + if (!kobj) return -ENOENT; - if (!kobj->k_name) - kobject_set_name(kobj, "NO_NAME"); - if (!*kobj->k_name) { - pr_debug("kobject (%p) attempted to be registered with no " + + if (!kobj->k_name || !kobj->k_name[0]) { + pr_debug("kobject: (%p): attempted to be registered with empty " "name!\n", kobj); WARN_ON(1); - kobject_put(kobj); return -EINVAL; } - parent = kobject_get(kobj->parent); - pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", - kobject_name(kobj), kobj, __FUNCTION__, - parent ? kobject_name(parent) : "", - kobj->kset ? kobject_name(&kobj->kset->kobj) : "" ); + parent = kobject_get(kobj->parent); + /* join kset if set, use it as parent if we do not already have one */ if (kobj->kset) { - kobj->kset = kset_get(kobj->kset); - - if (!parent) { + if (!parent) parent = kobject_get(&kobj->kset->kobj); - /* - * If the kset is our parent, get a second - * reference, we drop both the kset and the - * parent ref on cleanup - */ - kobject_get(parent); - } - - spin_lock(&kobj->kset->list_lock); - list_add_tail(&kobj->entry, &kobj->kset->list); - spin_unlock(&kobj->kset->list_lock); + kobj_kset_join(kobj); kobj->parent = parent; } + pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", + kobject_name(kobj), kobj, __FUNCTION__, + parent ? kobject_name(parent) : "", + kobj->kset ? kobject_name(&kobj->kset->kobj) : "" ); + error = create_dir(kobj); if (error) { - /* unlink does the kobject_put() for us */ - unlink(kobj); + kobj_kset_leave(kobj); + kobject_put(parent); + kobj->parent = NULL; /* be noisy on error issues */ if (error == -EEXIST) @@ -214,7 +203,8 @@ static int kobject_add_internal(struct kobject *kobj) printk(KERN_ERR "%s failed for %s (%d)\n", __FUNCTION__, kobject_name(kobj), error); dump_stack(); - } + } else + kobj->state_in_sysfs = 1; return error; } @@ -238,11 +228,13 @@ static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, if (!name) return -ENOMEM; + /* Free the old name, if necessary. */ kfree(kobj->k_name); /* Now, set the new name */ kobj->k_name = name; + kobj->state_name_set = 1; return 0; } @@ -293,20 +285,25 @@ void kobject_init(struct kobject *kobj, struct kobj_type *ktype) err_str = "must have a ktype to be initialized properly!\n"; goto error; } - if (atomic_read(&kobj->kref.refcount)) { + if (kobj->state_initialized) { /* do not error out as sometimes we can recover */ - printk(KERN_ERR "kobject: reference count is already set, " - "something is seriously wrong.\n"); + printk(KERN_ERR "kobject (%p): tried to init an initialized " + "object, something is seriously wrong.\n", kobj); dump_stack(); } kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); kobj->ktype = ktype; + kobj->state_name_set = 0; + kobj->state_in_sysfs = 0; + kobj->state_add_uevent_sent = 0; + kobj->state_remove_uevent_sent = 0; + kobj->state_initialized = 1; return; error: - printk(KERN_ERR "kobject: %s\n", err_str); + printk(KERN_ERR "kobject (%p): %s\n", kobj, err_str); dump_stack(); } EXPORT_SYMBOL(kobject_init); @@ -345,17 +342,10 @@ static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, * * If this function returns an error, kobject_put() must be called to * properly clean up the memory associated with the object. - * - * If the function is successful, the only way to properly clean up the - * memory is with a call to kobject_del(), in which case, a call to - * kobject_put() is not necessary (kobject_del() does the final - * kobject_put() to call the release function in the ktype's release - * pointer.) - * * Under no instance should the kobject that is passed to this function * be directly freed with a call to kfree(), that can leak memory. * - * Note, no uevent will be created with this call, the caller should set + * Note, no "add" uevent will be created with this call, the caller should set * up all of the necessary sysfs files for the object and then call * kobject_uevent() with the UEVENT_ADD parameter to ensure that * userspace is properly notified of this kobject's creation. @@ -369,6 +359,13 @@ int kobject_add(struct kobject *kobj, struct kobject *parent, if (!kobj) return -EINVAL; + if (!kobj->state_initialized) { + printk(KERN_ERR "kobject '%s' (%p): tried to add an " + "uninitialized object, something is seriously wrong.\n", + kobject_name(kobj), kobj); + dump_stack(); + return -EINVAL; + } va_start(args, fmt); retval = kobject_add_varg(kobj, parent, fmt, args); va_end(args); @@ -527,8 +524,12 @@ void kobject_del(struct kobject * kobj) { if (!kobj) return; + sysfs_remove_dir(kobj); - unlink(kobj); + kobj->state_in_sysfs = 0; + kobj_kset_leave(kobj); + kobject_put(kobj->parent); + kobj->parent = NULL; } /** @@ -565,21 +566,43 @@ struct kobject * kobject_get(struct kobject * kobj) */ static void kobject_cleanup(struct kobject *kobj) { - struct kobj_type * t = get_ktype(kobj); - struct kset * s = kobj->kset; + struct kobj_type *t = get_ktype(kobj); const char *name = kobj->k_name; + int name_set = kobj->state_name_set; pr_debug("kobject: '%s' (%p): %s\n", kobject_name(kobj), kobj, __FUNCTION__); + + if (t && !t->release) + pr_debug("kobject: '%s' (%p): does not have a release() " + "function, it is broken and must be fixed.\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", + kobject_name(kobj), kobj); + kobject_del(kobj); + } + if (t && t->release) { + pr_debug("kobject: '%s' (%p): calling ktype release\n", + kobject_name(kobj), kobj); t->release(kobj); - /* If we have a release function, we can guess that this was - * not a statically allocated kobject, so we should be safe to - * free the name */ + } + + /* free name if we allocated it */ + if (name_set && name) { + pr_debug("kobject: '%s': free name\n", name); kfree(name); } - if (s) - kset_put(s); } static void kobject_release(struct kref *kref) @@ -601,8 +624,7 @@ void kobject_put(struct kobject * kobj) static void dynamic_kobj_release(struct kobject *kobj) { - pr_debug("kobject: '%s' (%p): %s\n", - kobject_name(kobj), kobj, __FUNCTION__); + pr_debug("kobject: (%p): %s\n", kobj, __FUNCTION__); kfree(kobj); } -- cgit v1.2.2 From 78a2d906b40fe530ea800c1e873bfe8f02326f1e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 20 Dec 2007 08:13:05 -0800 Subject: Kobject: convert remaining kobject_unregister() to kobject_put() There is no need for kobject_unregister() anymore, thanks to Kay's kobject cleanup changes, so replace all instances of it with kobject_put(). Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 4fce5ca42c2e..462946ee3e64 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -664,7 +664,7 @@ struct kobject *kobject_create(void) * * This function creates a kset structure dynamically and registers it * with sysfs. When you are finished with this structure, call - * kobject_unregister() and the structure will be dynamically freed when + * kobject_put() and the structure will be dynamically freed when * it is no longer being used. * * If the kobject was not able to be created, NULL will be returned. @@ -761,7 +761,7 @@ void kset_unregister(struct kset * k) { if (!k) return; - kobject_unregister(&k->kobj); + kobject_put(&k->kobj); } -- cgit v1.2.2 From 528a4bf1d5ffed310d26fc1d82d45c02949f71cf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 20 Dec 2007 08:13:05 -0800 Subject: Kobject: remove kobject_unregister() as no one uses it anymore There are no in-kernel users of kobject_unregister() so it should be removed. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 462946ee3e64..a0773734545c 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -532,22 +532,6 @@ void kobject_del(struct kobject * kobj) kobj->parent = NULL; } -/** - * kobject_unregister - remove object from hierarchy and decrement refcount. - * @kobj: object going away. - */ - -void kobject_unregister(struct kobject * kobj) -{ - if (!kobj) - return; - pr_debug("kobject: '%s' (%p): %s\n", - kobject_name(kobj), kobj, __FUNCTION__); - kobject_uevent(kobj, KOBJ_REMOVE); - kobject_del(kobj); - kobject_put(kobj); -} - /** * kobject_get - increment refcount for object. * @kobj: object. @@ -877,7 +861,6 @@ struct kset *kset_create_and_add(const char *name, } EXPORT_SYMBOL_GPL(kset_create_and_add); -EXPORT_SYMBOL(kobject_unregister); EXPORT_SYMBOL(kobject_get); EXPORT_SYMBOL(kobject_put); EXPORT_SYMBOL(kobject_del); -- cgit v1.2.2 From af5ca3f4ec5cc4432a42a73b050dd8898ce8fd00 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 20 Dec 2007 02:09:39 +0100 Subject: Driver core: change sysdev classes to use dynamic kobject names All kobjects require a dynamically allocated name now. We no longer need to keep track if the name is statically assigned, we can just unconditionally free() all kobject names on cleanup. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index a0773734545c..8dc32454661d 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -165,7 +165,7 @@ static int kobject_add_internal(struct kobject *kobj) if (!kobj) return -ENOENT; - if (!kobj->k_name || !kobj->k_name[0]) { + if (!kobj->name || !kobj->name[0]) { pr_debug("kobject: (%p): attempted to be registered with empty " "name!\n", kobj); WARN_ON(1); @@ -228,13 +228,11 @@ static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, if (!name) return -ENOMEM; - /* Free the old name, if necessary. */ - kfree(kobj->k_name); + kfree(kobj->name); /* Now, set the new name */ - kobj->k_name = name; - kobj->state_name_set = 1; + kobj->name = name; return 0; } @@ -295,7 +293,6 @@ void kobject_init(struct kobject *kobj, struct kobj_type *ktype) kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); kobj->ktype = ktype; - kobj->state_name_set = 0; kobj->state_in_sysfs = 0; kobj->state_add_uevent_sent = 0; kobj->state_remove_uevent_sent = 0; @@ -551,8 +548,7 @@ struct kobject * kobject_get(struct kobject * kobj) static void kobject_cleanup(struct kobject *kobj) { struct kobj_type *t = get_ktype(kobj); - const char *name = kobj->k_name; - int name_set = kobj->state_name_set; + const char *name = kobj->name; pr_debug("kobject: '%s' (%p): %s\n", kobject_name(kobj), kobj, __FUNCTION__); @@ -583,7 +579,7 @@ static void kobject_cleanup(struct kobject *kobj) } /* free name if we allocated it */ - if (name_set && name) { + if (name) { pr_debug("kobject: '%s': free name\n", name); kfree(name); } -- cgit v1.2.2 From e374a2bfebf359f846216336de91670be40499da Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 24 Jan 2008 21:59:04 -0800 Subject: Kobject: fix coding style issues in kobject c files Clean up the kobject.c and kobject_uevent.c files to follow the proper coding style rules. Signed-off-by: Greg Kroah-Hartman --- lib/kobject.c | 139 +++++++++++++++++++++++++++------------------------------- 1 file changed, 64 insertions(+), 75 deletions(-) (limited to 'lib/kobject.c') diff --git a/lib/kobject.c b/lib/kobject.c index 8dc32454661d..1d63ead1815e 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -18,58 +18,57 @@ #include #include -/** - * populate_dir - populate directory with attributes. - * @kobj: object we're working on. - * - * Most subsystems have a set of default attributes that - * are associated with an object that registers with them. - * This is a helper called during object registration that - * loops through the default attributes of the subsystem - * and creates attributes files for them in sysfs. +/* + * populate_dir - populate directory with attributes. + * @kobj: object we're working on. * + * Most subsystems have a set of default attributes that are associated + * with an object that registers with them. This is a helper called during + * object registration that loops through the default attributes of the + * subsystem and creates attributes files for them in sysfs. */ - -static int populate_dir(struct kobject * kobj) +static int populate_dir(struct kobject *kobj) { - struct kobj_type * t = get_ktype(kobj); - struct attribute * attr; + struct kobj_type *t = get_ktype(kobj); + struct attribute *attr; int error = 0; int i; - + if (t && t->default_attrs) { for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) { - if ((error = sysfs_create_file(kobj,attr))) + error = sysfs_create_file(kobj, attr); + if (error) break; } } return error; } -static int create_dir(struct kobject * kobj) +static int create_dir(struct kobject *kobj) { int error = 0; if (kobject_name(kobj)) { error = sysfs_create_dir(kobj); if (!error) { - if ((error = populate_dir(kobj))) + error = populate_dir(kobj); + if (error) sysfs_remove_dir(kobj); } } return error; } -static inline struct kobject * to_kobj(struct list_head * entry) +static inline struct kobject *to_kobj(struct list_head *entry) { - return container_of(entry,struct kobject,entry); + return container_of(entry, struct kobject, entry); } static int get_kobj_path_length(struct kobject *kobj) { int length = 1; - struct kobject * parent = kobj; + struct kobject *parent = kobj; - /* walk up the ancestors until we hit the one pointing to the + /* walk up the ancestors until we hit the one pointing to the * root. * Add 1 to strlen for leading '/' of each level. */ @@ -84,19 +83,19 @@ static int get_kobj_path_length(struct kobject *kobj) static void fill_kobj_path(struct kobject *kobj, char *path, int length) { - struct kobject * parent; + struct kobject *parent; --length; for (parent = kobj; parent; parent = parent->parent) { int cur = strlen(kobject_name(parent)); /* back up enough to print this name with '/' */ length -= cur; - strncpy (path + length, kobject_name(parent), cur); + strncpy(path + length, kobject_name(parent), cur); *(path + --length) = '/'; } pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj), - kobj, __FUNCTION__,path); + kobj, __FUNCTION__, path); } /** @@ -148,7 +147,7 @@ static void kobj_kset_leave(struct kobject *kobj) kset_put(kobj->kset); } -static void kobject_init_internal(struct kobject * kobj) +static void kobject_init_internal(struct kobject *kobj) { if (!kobj) return; @@ -160,7 +159,7 @@ static void kobject_init_internal(struct kobject * kobj) static int kobject_add_internal(struct kobject *kobj) { int error = 0; - struct kobject * parent; + struct kobject *parent; if (!kobj) return -ENOENT; @@ -185,7 +184,7 @@ static int kobject_add_internal(struct kobject *kobj) pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n", kobject_name(kobj), kobj, __FUNCTION__, parent ? kobject_name(parent) : "", - kobj->kset ? kobject_name(&kobj->kset->kobj) : "" ); + kobj->kset ? kobject_name(&kobj->kset->kobj) : ""); error = create_dir(kobj); if (error) { @@ -399,12 +398,11 @@ int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, EXPORT_SYMBOL_GPL(kobject_init_and_add); /** - * kobject_rename - change the name of an object - * @kobj: object in question. - * @new_name: object's new name + * kobject_rename - change the name of an object + * @kobj: object in question. + * @new_name: object's new name */ - -int kobject_rename(struct kobject * kobj, const char *new_name) +int kobject_rename(struct kobject *kobj, const char *new_name) { int error = 0; const char *devpath = NULL; @@ -461,11 +459,10 @@ out: } /** - * kobject_move - move object to another parent - * @kobj: object in question. - * @new_parent: object's new parent (can be NULL) + * kobject_move - move object to another parent + * @kobj: object in question. + * @new_parent: object's new parent (can be NULL) */ - int kobject_move(struct kobject *kobj, struct kobject *new_parent) { int error; @@ -513,11 +510,10 @@ out: } /** - * kobject_del - unlink kobject from hierarchy. - * @kobj: object. + * kobject_del - unlink kobject from hierarchy. + * @kobj: object. */ - -void kobject_del(struct kobject * kobj) +void kobject_del(struct kobject *kobj) { if (!kobj) return; @@ -530,11 +526,10 @@ void kobject_del(struct kobject * kobj) } /** - * kobject_get - increment refcount for object. - * @kobj: object. + * kobject_get - increment refcount for object. + * @kobj: object. */ - -struct kobject * kobject_get(struct kobject * kobj) +struct kobject *kobject_get(struct kobject *kobj) { if (kobj) kref_get(&kobj->kref); @@ -591,12 +586,12 @@ static void kobject_release(struct kref *kref) } /** - * kobject_put - decrement refcount for object. - * @kobj: object. + * kobject_put - decrement refcount for object. + * @kobj: object. * - * Decrement the refcount, and if 0, call kobject_cleanup(). + * Decrement the refcount, and if 0, call kobject_cleanup(). */ -void kobject_put(struct kobject * kobj) +void kobject_put(struct kobject *kobj) { if (kobj) kref_put(&kobj->kref, kobject_release); @@ -670,11 +665,10 @@ struct kobject *kobject_create_and_add(const char *name, struct kobject *parent) EXPORT_SYMBOL_GPL(kobject_create_and_add); /** - * kset_init - initialize a kset for use - * @k: kset + * kset_init - initialize a kset for use + * @k: kset */ - -void kset_init(struct kset * k) +void kset_init(struct kset *k) { kobject_init_internal(&k->kobj); INIT_LIST_HEAD(&k->list); @@ -712,11 +706,10 @@ struct sysfs_ops kobj_sysfs_ops = { }; /** - * kset_register - initialize and add a kset. - * @k: kset. + * kset_register - initialize and add a kset. + * @k: kset. */ - -int kset_register(struct kset * k) +int kset_register(struct kset *k) { int err; @@ -731,39 +724,35 @@ int kset_register(struct kset * k) return 0; } - /** - * kset_unregister - remove a kset. - * @k: kset. + * kset_unregister - remove a kset. + * @k: kset. */ - -void kset_unregister(struct kset * k) +void kset_unregister(struct kset *k) { if (!k) return; kobject_put(&k->kobj); } - /** - * kset_find_obj - search for object in kset. - * @kset: kset we're looking in. - * @name: object's name. + * kset_find_obj - search for object in kset. + * @kset: kset we're looking in. + * @name: object's name. * - * Lock kset via @kset->subsys, and iterate over @kset->list, - * looking for a matching kobject. If matching object is found - * take a reference and return the object. + * Lock kset via @kset->subsys, and iterate over @kset->list, + * looking for a matching kobject. If matching object is found + * take a reference and return the object. */ - -struct kobject * kset_find_obj(struct kset * kset, const char * name) +struct kobject *kset_find_obj(struct kset *kset, const char *name) { - struct list_head * entry; - struct kobject * ret = NULL; + struct list_head *entry; + struct kobject *ret = NULL; 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)) { + list_for_each(entry, &kset->list) { + struct kobject *k = to_kobj(entry); + if (kobject_name(k) && !strcmp(kobject_name(k), name)) { ret = kobject_get(k); break; } -- cgit v1.2.2