Currently there exists the kset_create_and_add() helper that does not allow to have a different ktype for the created kset kobject. To allow a different ktype this patch will introduce the function kset_type_create_and_add() that allows to set a different ktype instead of using the global default kset_ktype variable. In my example I need to separate the created kobject inside the kset by net-namespaces. This patch allows me to do that by providing a user defined kobj_type structure that implements the necessary namespace functionality. Signed-off-by: Alexander Aring <aahringo@xxxxxxxxxx> --- include/linux/kobject.h | 8 +++++-- lib/kobject.c | 49 +++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/include/linux/kobject.h b/include/linux/kobject.h index c8219505a79f..7504b7547ed2 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -175,8 +175,12 @@ struct kset { void kset_init(struct kset *kset); int __must_check kset_register(struct kset *kset); void kset_unregister(struct kset *kset); -struct kset * __must_check kset_create_and_add(const char *name, const struct kset_uevent_ops *u, - struct kobject *parent_kobj); +struct kset * __must_check +kset_type_create_and_add(const char *name, const struct kset_uevent_ops *u, + struct kobject *parent_kobj, const struct kobj_type *ktype); +struct kset * __must_check +kset_create_and_add(const char *name, const 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 72fa20f405f1..fbae94ea9bb5 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -957,7 +957,8 @@ static const struct kobj_type kset_ktype = { */ static struct kset *kset_create(const char *name, const struct kset_uevent_ops *uevent_ops, - struct kobject *parent_kobj) + struct kobject *parent_kobj, + const struct kobj_type *ktype) { struct kset *kset; int retval; @@ -973,17 +974,32 @@ static struct kset *kset_create(const char *name, kset->uevent_ops = uevent_ops; kset->kobj.parent = parent_kobj; - /* - * 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_ktype; + kset->kobj.ktype = ktype; kset->kobj.kset = NULL; return kset; } +struct kset *kset_type_create_and_add(const char *name, + const struct kset_uevent_ops *uevent_ops, + struct kobject *parent_kobj, + const struct kobj_type *ktype) +{ + struct kset *kset; + int error; + + kset = kset_create(name, uevent_ops, parent_kobj, ktype); + if (!kset) + return NULL; + error = kset_register(kset); + if (error) { + kfree(kset); + return NULL; + } + return kset; +} +EXPORT_SYMBOL_GPL(kset_type_create_and_add); + /** * kset_create_and_add() - Create a struct kset dynamically and add it to sysfs. * @@ -1002,18 +1018,13 @@ struct kset *kset_create_and_add(const char *name, const 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; + /* + * 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. + */ + return kset_type_create_and_add(name, uevent_ops, parent_kobj, + &kset_ktype); } EXPORT_SYMBOL_GPL(kset_create_and_add); -- 2.43.0