Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146769534
D43020.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D43020.diff
View Options
diff --git a/sys/compat/linuxkpi/common/include/linux/kobject.h b/sys/compat/linuxkpi/common/include/linux/kobject.h
--- a/sys/compat/linuxkpi/common/include/linux/kobject.h
+++ b/sys/compat/linuxkpi/common/include/linux/kobject.h
@@ -35,8 +35,10 @@
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/slab.h>
+#include <linux/spinlock.h>
struct kobject;
+struct kset;
struct sysctl_oid;
#define KOBJ_CHANGE 0x01
@@ -57,6 +59,7 @@
const struct kobj_type *ktype;
struct list_head entry;
struct sysctl_oid *oidp;
+ struct kset *kset;
};
extern struct kobject *mm_kobj;
@@ -77,6 +80,17 @@
const char *buf, size_t count);
};
+struct kset_uevent_ops {
+ /* TODO */
+};
+
+struct kset {
+ struct list_head list;
+ spinlock_t list_lock;
+ struct kobject kobj;
+ const struct kset_uevent_ops *uevent_ops;
+};
+
static inline void
kobject_init(struct kobject *kobj, const struct kobj_type *ktype)
{
@@ -154,6 +168,41 @@
*/
}
+void kset_init(struct kset *kset);
+int kset_register(struct kset *kset);
+void kset_unregister(struct kset *kset);
+struct kset * 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)
+{
+ if (kobj != NULL)
+ return container_of(kobj, struct kset, kobj);
+ else
+ return NULL;
+}
+
+static inline struct kset *
+kset_get(struct kset *kset)
+{
+ if (kset != NULL) {
+ struct kobject *kobj;
+
+ kobj = kobject_get(&kset->kobj);
+ return to_kset(kobj);
+ } else {
+ return NULL;
+ }
+}
+
+static inline void
+kset_put(struct kset *kset)
+{
+ if (kset != NULL)
+ kobject_put(&kset->kobj);
+}
+
void linux_kobject_kfree_name(struct kobject *kobj);
#endif /* _LINUXKPI_LINUX_KOBJECT_H_ */
diff --git a/sys/compat/linuxkpi/common/src/linux_kobject.c b/sys/compat/linuxkpi/common/src/linux_kobject.c
--- a/sys/compat/linuxkpi/common/src/linux_kobject.c
+++ b/sys/compat/linuxkpi/common/src/linux_kobject.c
@@ -30,6 +30,10 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
+static void kset_join(struct kobject *kobj);
+static void kset_leave(struct kobject *kobj);
+static void kset_kfree(struct kobject *kobj);
+
struct kobject *
kobject_create(void)
{
@@ -101,12 +105,16 @@
}
static int
-kobject_add_complete(struct kobject *kobj, struct kobject *parent)
+kobject_add_complete(struct kobject *kobj)
{
const struct kobj_type *t;
int error;
- kobj->parent = parent;
+ if (kobj->kset != NULL) {
+ kset_join(kobj);
+ kobj->parent = &kobj->kset->kobj;
+ }
+
error = sysfs_create_dir(kobj);
if (error == 0 && kobj->ktype && kobj->ktype->default_attrs) {
struct attribute **attr;
@@ -120,6 +128,10 @@
if (error)
sysfs_remove_dir(kobj);
}
+
+ if (error != 0)
+ kset_leave(kobj);
+
return (error);
}
@@ -129,13 +141,15 @@
va_list args;
int error;
+ kobj->parent = parent;
+
va_start(args, fmt);
error = kobject_set_name_vargs(kobj, fmt, args);
va_end(args);
if (error)
return (error);
- return kobject_add_complete(kobj, parent);
+ return kobject_add_complete(kobj);
}
int
@@ -155,7 +169,7 @@
va_end(args);
if (error)
return (error);
- return kobject_add_complete(kobj, parent);
+ return kobject_add_complete(kobj);
}
void
@@ -166,6 +180,7 @@
kobj = container_of(kref, struct kobject, kref);
sysfs_remove_dir(kobj);
+ kset_leave(kobj);
name = kobj->name;
if (kobj->ktype && kobj->ktype->release)
kobj->ktype->release(kobj);
@@ -219,3 +234,121 @@
.show = lkpi_kobj_attr_show,
.store = lkpi_kobj_attr_store,
};
+
+const struct kobj_type linux_kset_kfree_type = {
+ .release = kset_kfree
+};
+
+static struct kset *
+kset_create(const char *name,
+ const struct kset_uevent_ops *uevent_ops,
+ struct kobject *parent_kobj)
+{
+ struct kset *kset;
+
+ kset = kzalloc(sizeof(*kset), GFP_KERNEL);
+ if (kset == NULL)
+ return (NULL);
+
+ kset->uevent_ops = uevent_ops;
+
+ kobject_set_name(&kset->kobj, "%s", name);
+ kset->kobj.parent = parent_kobj;
+ kset->kobj.kset = NULL;
+
+ return (kset);
+}
+
+void
+kset_init(struct kset *kset)
+{
+ kobject_init(&kset->kobj, &linux_kset_kfree_type);
+ INIT_LIST_HEAD(&kset->list);
+ spin_lock_init(&kset->list_lock);
+}
+
+static void
+kset_join(struct kobject *kobj)
+{
+ struct kset *kset;
+
+ kset = kobj->kset;
+ if (kset == NULL)
+ return;
+
+ kset_get(kobj->kset);
+
+ spin_lock(&kset->list_lock);
+ list_add_tail(&kobj->entry, &kset->list);
+ spin_unlock(&kset->list_lock);
+}
+
+static void
+kset_leave(struct kobject *kobj)
+{
+ struct kset *kset;
+
+ kset = kobj->kset;
+ if (kset == NULL)
+ return;
+
+ spin_lock(&kset->list_lock);
+ list_del_init(&kobj->entry);
+ spin_unlock(&kset->list_lock);
+
+ kset_put(kobj->kset);
+}
+
+struct kset *
+kset_create_and_add(const char *name, const struct kset_uevent_ops *u,
+ struct kobject *parent_kobj)
+{
+ int ret;
+ struct kset *kset;
+
+ kset = kset_create(name, u, parent_kobj);
+ if (kset == NULL)
+ return (NULL);
+
+ ret = kset_register(kset);
+ if (ret != 0) {
+ linux_kobject_kfree_name(&kset->kobj);
+ kfree(kset);
+ return (NULL);
+ }
+
+ return (kset);
+}
+
+int
+kset_register(struct kset *kset)
+{
+ int ret;
+
+ if (kset == NULL)
+ return -EINVAL;
+
+ kset_init(kset);
+ ret = kobject_add_complete(&kset->kobj);
+
+ return ret;
+}
+
+void
+kset_unregister(struct kset *kset)
+{
+ if (kset == NULL)
+ return;
+
+ kobject_del(&kset->kobj);
+ kobject_put(&kset->kobj);
+}
+
+static void
+kset_kfree(struct kobject *kobj)
+{
+ struct kset *kset;
+
+ kset = to_kset(kobj);
+ kfree(kset);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 6, 11:00 AM (3 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29323348
Default Alt Text
D43020.diff (5 KB)
Attached To
Mode
D43020: linuxkpi: Add `struct kset` support in <linux/kobject.h>
Attached
Detach File
Event Timeline
Log In to Comment