aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2010-03-30 14:31:25 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-21 12:37:31 -0400
commitbc451f2058238013e1cdf4acd443c01734d332f0 (patch)
tree16a1ca2f762edcfbda8f2a4afb6763ba7b090271 /drivers/base
parentba514a57f5c38d9d79ea15e75059e07f49238726 (diff)
kobj: Add basic infrastructure for dealing with namespaces.
Move complete knowledge of namespaces into the kobject layer so we can use that information when reporting kobjects to userspace. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/class.c9
-rw-r--r--drivers/base/core.c77
2 files changed, 72 insertions, 14 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 9c6a0d6408e7..8e231d05b400 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -63,6 +63,14 @@ static void class_release(struct kobject *kobj)
63 kfree(cp); 63 kfree(cp);
64} 64}
65 65
66static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject *kobj)
67{
68 struct class_private *cp = to_class(kobj);
69 struct class *class = cp->class;
70
71 return class->ns_type;
72}
73
66static const struct sysfs_ops class_sysfs_ops = { 74static const struct sysfs_ops class_sysfs_ops = {
67 .show = class_attr_show, 75 .show = class_attr_show,
68 .store = class_attr_store, 76 .store = class_attr_store,
@@ -71,6 +79,7 @@ static const struct sysfs_ops class_sysfs_ops = {
71static struct kobj_type class_ktype = { 79static struct kobj_type class_ktype = {
72 .sysfs_ops = &class_sysfs_ops, 80 .sysfs_ops = &class_sysfs_ops,
73 .release = class_release, 81 .release = class_release,
82 .child_ns_type = class_child_ns_type,
74}; 83};
75 84
76/* Hotplug events for classes go to the class class_subsys */ 85/* Hotplug events for classes go to the class class_subsys */
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 356dd011b8f9..f0699918e2f6 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -131,9 +131,21 @@ static void device_release(struct kobject *kobj)
131 kfree(p); 131 kfree(p);
132} 132}
133 133
134static const void *device_namespace(struct kobject *kobj)
135{
136 struct device *dev = to_dev(kobj);
137 const void *ns = NULL;
138
139 if (dev->class && dev->class->ns_type)
140 ns = dev->class->namespace(dev);
141
142 return ns;
143}
144
134static struct kobj_type device_ktype = { 145static struct kobj_type device_ktype = {
135 .release = device_release, 146 .release = device_release,
136 .sysfs_ops = &dev_sysfs_ops, 147 .sysfs_ops = &dev_sysfs_ops,
148 .namespace = device_namespace,
137}; 149};
138 150
139 151
@@ -595,11 +607,59 @@ static struct kobject *virtual_device_parent(struct device *dev)
595 return virtual_dir; 607 return virtual_dir;
596} 608}
597 609
598static struct kobject *get_device_parent(struct device *dev, 610struct class_dir {
599 struct device *parent) 611 struct kobject kobj;
612 struct class *class;
613};
614
615#define to_class_dir(obj) container_of(obj, struct class_dir, kobj)
616
617static void class_dir_release(struct kobject *kobj)
618{
619 struct class_dir *dir = to_class_dir(kobj);
620 kfree(dir);
621}
622
623static const
624struct kobj_ns_type_operations *class_dir_child_ns_type(struct kobject *kobj)
600{ 625{
626 struct class_dir *dir = to_class_dir(kobj);
627 return dir->class->ns_type;
628}
629
630static struct kobj_type class_dir_ktype = {
631 .release = class_dir_release,
632 .sysfs_ops = &kobj_sysfs_ops,
633 .child_ns_type = class_dir_child_ns_type
634};
635
636static struct kobject *
637class_dir_create_and_add(struct class *class, struct kobject *parent_kobj)
638{
639 struct class_dir *dir;
601 int retval; 640 int retval;
602 641
642 dir = kzalloc(sizeof(*dir), GFP_KERNEL);
643 if (!dir)
644 return NULL;
645
646 dir->class = class;
647 kobject_init(&dir->kobj, &class_dir_ktype);
648
649 dir->kobj.kset = &class->p->class_dirs;
650
651 retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name);
652 if (retval < 0) {
653 kobject_put(&dir->kobj);
654 return NULL;
655 }
656 return &dir->kobj;
657}
658
659
660static struct kobject *get_device_parent(struct device *dev,
661 struct device *parent)
662{
603 if (dev->class) { 663 if (dev->class) {
604 static DEFINE_MUTEX(gdp_mutex); 664 static DEFINE_MUTEX(gdp_mutex);
605 struct kobject *kobj = NULL; 665 struct kobject *kobj = NULL;
@@ -634,18 +694,7 @@ static struct kobject *get_device_parent(struct device *dev,
634 } 694 }
635 695
636 /* or create a new class-directory at the parent device */ 696 /* or create a new class-directory at the parent device */
637 k = kobject_create(); 697 k = class_dir_create_and_add(dev->class, parent_kobj);
638 if (!k) {
639 mutex_unlock(&gdp_mutex);
640 return NULL;
641 }
642 k->kset = &dev->class->p->class_dirs;
643 retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
644 if (retval < 0) {
645 mutex_unlock(&gdp_mutex);
646 kobject_put(k);
647 return NULL;
648 }
649 /* do not emit an uevent for this simple "glue" directory */ 698 /* do not emit an uevent for this simple "glue" directory */
650 mutex_unlock(&gdp_mutex); 699 mutex_unlock(&gdp_mutex);
651 return k; 700 return k;