On Jan 25, 2008 3:09 PM, Greg Kroah-Hartman <[EMAIL PROTECTED]> wrote:
> 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 <[EMAIL PROTECTED]>
> Cc: Miklos Szeredi <[EMAIL PROTECTED]>
> Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
> ---
>  include/linux/kobject.h |    4 ++-
>  lib/kobject.c           |   92 
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 94 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/kobject.h b/include/linux/kobject.h
> index 0b97b3a..f91aeb7 100644
> --- a/include/linux/kobject.h
> +++ b/include/linux/kobject.h
> @@ -150,11 +150,13 @@ struct kset {
>         struct kset_uevent_ops  *uevent_ops;
>  };
>
> -
>  extern void kset_init(struct kset * k);
>  extern int __must_check kset_add(struct kset * k);
>  extern int __must_check kset_register(struct kset * k);
>  extern void kset_unregister(struct kset * k);
> +extern struct kset * __must_check kset_create_and_add(const char *name,
> +                                               struct kset_uevent_ops *u,
> +                                               struct kobject *parent_kobj);
>
>  static inline struct kset * to_kset(struct kobject * kobj)
>  {
> diff --git a/lib/kobject.c b/lib/kobject.c
> index 8f24940..4fb27ba 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);

How about : kobject_put(&kset->kobj);

> +               return NULL;
> +       }
> +       return kset;
> +}
> +EXPORT_SYMBOL_GPL(kset_create_and_add);
> +
>  EXPORT_SYMBOL(kobject_init);
>  EXPORT_SYMBOL(kobject_register);
>  EXPORT_SYMBOL(kobject_unregister);
> --
> 1.5.3.8
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [EMAIL PROTECTED]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to