aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/kobject.c92
1 files changed, 91 insertions, 1 deletions
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)
186 if (kobj->kset) { 186 if (kobj->kset) {
187 spin_lock(&kobj->kset->list_lock); 187 spin_lock(&kobj->kset->list_lock);
188 188
189 if (!parent) 189 if (!parent) {
190 parent = kobject_get(&kobj->kset->kobj); 190 parent = kobject_get(&kobj->kset->kobj);
191 /*
192 * If the kset is our parent, get a second
193 * reference, we drop both the kset and the
194 * parent ref on cleanup
195 */
196 kobject_get(parent);
197 }
191 198
192 list_add_tail(&kobj->entry,&kobj->kset->list); 199 list_add_tail(&kobj->entry,&kobj->kset->list);
193 spin_unlock(&kobj->kset->list_lock); 200 spin_unlock(&kobj->kset->list_lock);
@@ -787,6 +794,89 @@ int subsys_create_file(struct kset *s, struct subsys_attribute *a)
787 return error; 794 return error;
788} 795}
789 796
797static void kset_release(struct kobject *kobj)
798{
799 struct kset *kset = container_of(kobj, struct kset, kobj);
800 pr_debug("kset %s: now freed\n", kobject_name(kobj));
801 kfree(kset);
802}
803
804static struct kobj_type kset_type = {
805 .release = kset_release,
806};
807
808/**
809 * kset_create - create a struct kset dynamically
810 *
811 * @name: the name for the kset
812 * @uevent_ops: a struct kset_uevent_ops for the kset
813 * @parent_kobj: the parent kobject of this kset, if any.
814 *
815 * This function creates a kset structure dynamically. This structure can
816 * then be registered with the system and show up in sysfs with a call to
817 * kset_register(). When you are finished with this structure, if
818 * kset_register() has been called, call kset_unregister() and the
819 * structure will be dynamically freed when it is no longer being used.
820 *
821 * If the kset was not able to be created, NULL will be returned.
822 */
823static struct kset *kset_create(const char *name,
824 struct kset_uevent_ops *uevent_ops,
825 struct kobject *parent_kobj)
826{
827 struct kset *kset;
828
829 kset = kzalloc(sizeof(*kset), GFP_KERNEL);
830 if (!kset)
831 return NULL;
832 kobject_set_name(&kset->kobj, name);
833 kset->uevent_ops = uevent_ops;
834 kset->kobj.parent = parent_kobj;
835
836 /*
837 * The kobject of this kset will have a type of kset_type and belong to
838 * no kset itself. That way we can properly free it when it is
839 * finished being used.
840 */
841 kset->kobj.ktype = &kset_type;
842 kset->kobj.kset = NULL;
843
844 return kset;
845}
846
847/**
848 * kset_create_and_add - create a struct kset dynamically and add it to sysfs
849 *
850 * @name: the name for the kset
851 * @uevent_ops: a struct kset_uevent_ops for the kset
852 * @parent_kobj: the parent kobject of this kset, if any.
853 *
854 * This function creates a kset structure dynamically and registers it
855 * with sysfs. When you are finished with this structure, call
856 * kset_unregister() and the structure will be dynamically freed when it
857 * is no longer being used.
858 *
859 * If the kset was not able to be created, NULL will be returned.
860 */
861struct kset *kset_create_and_add(const char *name,
862 struct kset_uevent_ops *uevent_ops,
863 struct kobject *parent_kobj)
864{
865 struct kset *kset;
866 int error;
867
868 kset = kset_create(name, uevent_ops, parent_kobj);
869 if (!kset)
870 return NULL;
871 error = kset_register(kset);
872 if (error) {
873 kfree(kset);
874 return NULL;
875 }
876 return kset;
877}
878EXPORT_SYMBOL_GPL(kset_create_and_add);
879
790EXPORT_SYMBOL(kobject_init); 880EXPORT_SYMBOL(kobject_init);
791EXPORT_SYMBOL(kobject_register); 881EXPORT_SYMBOL(kobject_register);
792EXPORT_SYMBOL(kobject_unregister); 882EXPORT_SYMBOL(kobject_unregister);