aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/class.c29
-rw-r--r--drivers/net/bonding/bond_sysfs.c14
-rw-r--r--fs/sysfs/file.c95
-rw-r--r--fs/sysfs/group.c7
-rw-r--r--fs/sysfs/sysfs.h5
-rw-r--r--include/linux/device.h24
-rw-r--r--include/linux/netdevice.h16
-rw-r--r--include/linux/sysfs.h31
-rw-r--r--net/core/net-sysfs.c14
9 files changed, 106 insertions, 129 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 8b7818b80056..f96f70419a78 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -47,18 +47,6 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
47 return ret; 47 return ret;
48} 48}
49 49
50static const void *class_attr_namespace(struct kobject *kobj,
51 const struct attribute *attr)
52{
53 struct class_attribute *class_attr = to_class_attr(attr);
54 struct subsys_private *cp = to_subsys_private(kobj);
55 const void *ns = NULL;
56
57 if (class_attr->namespace)
58 ns = class_attr->namespace(cp->class, class_attr);
59 return ns;
60}
61
62static void class_release(struct kobject *kobj) 50static void class_release(struct kobject *kobj)
63{ 51{
64 struct subsys_private *cp = to_subsys_private(kobj); 52 struct subsys_private *cp = to_subsys_private(kobj);
@@ -86,7 +74,6 @@ static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject
86static const struct sysfs_ops class_sysfs_ops = { 74static const struct sysfs_ops class_sysfs_ops = {
87 .show = class_attr_show, 75 .show = class_attr_show,
88 .store = class_attr_store, 76 .store = class_attr_store,
89 .namespace = class_attr_namespace,
90}; 77};
91 78
92static struct kobj_type class_ktype = { 79static struct kobj_type class_ktype = {
@@ -99,21 +86,23 @@ static struct kobj_type class_ktype = {
99static struct kset *class_kset; 86static struct kset *class_kset;
100 87
101 88
102int class_create_file(struct class *cls, const struct class_attribute *attr) 89int class_create_file_ns(struct class *cls, const struct class_attribute *attr,
90 const void *ns)
103{ 91{
104 int error; 92 int error;
105 if (cls) 93 if (cls)
106 error = sysfs_create_file(&cls->p->subsys.kobj, 94 error = sysfs_create_file_ns(&cls->p->subsys.kobj,
107 &attr->attr); 95 &attr->attr, ns);
108 else 96 else
109 error = -EINVAL; 97 error = -EINVAL;
110 return error; 98 return error;
111} 99}
112 100
113void class_remove_file(struct class *cls, const struct class_attribute *attr) 101void class_remove_file_ns(struct class *cls, const struct class_attribute *attr,
102 const void *ns)
114{ 103{
115 if (cls) 104 if (cls)
116 sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr); 105 sysfs_remove_file_ns(&cls->p->subsys.kobj, &attr->attr, ns);
117} 106}
118 107
119static struct class *class_get(struct class *cls) 108static struct class *class_get(struct class *cls)
@@ -600,8 +589,8 @@ int __init classes_init(void)
600 return 0; 589 return 0;
601} 590}
602 591
603EXPORT_SYMBOL_GPL(class_create_file); 592EXPORT_SYMBOL_GPL(class_create_file_ns);
604EXPORT_SYMBOL_GPL(class_remove_file); 593EXPORT_SYMBOL_GPL(class_remove_file_ns);
605EXPORT_SYMBOL_GPL(class_unregister); 594EXPORT_SYMBOL_GPL(class_unregister);
606EXPORT_SYMBOL_GPL(class_destroy); 595EXPORT_SYMBOL_GPL(class_destroy);
607 596
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index c29b836749b6..ec9b6460a38d 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -149,14 +149,6 @@ err_no_cmd:
149 return -EPERM; 149 return -EPERM;
150} 150}
151 151
152static const void *bonding_namespace(struct class *cls,
153 const struct class_attribute *attr)
154{
155 const struct bond_net *bn =
156 container_of(attr, struct bond_net, class_attr_bonding_masters);
157 return bn->net;
158}
159
160/* class attribute for bond_masters file. This ends up in /sys/class/net */ 152/* class attribute for bond_masters file. This ends up in /sys/class/net */
161static const struct class_attribute class_attr_bonding_masters = { 153static const struct class_attribute class_attr_bonding_masters = {
162 .attr = { 154 .attr = {
@@ -165,7 +157,6 @@ static const struct class_attribute class_attr_bonding_masters = {
165 }, 157 },
166 .show = bonding_show_bonds, 158 .show = bonding_show_bonds,
167 .store = bonding_store_bonds, 159 .store = bonding_store_bonds,
168 .namespace = bonding_namespace,
169}; 160};
170 161
171int bond_create_slave_symlinks(struct net_device *master, 162int bond_create_slave_symlinks(struct net_device *master,
@@ -1787,7 +1778,8 @@ int bond_create_sysfs(struct bond_net *bn)
1787 bn->class_attr_bonding_masters = class_attr_bonding_masters; 1778 bn->class_attr_bonding_masters = class_attr_bonding_masters;
1788 sysfs_attr_init(&bn->class_attr_bonding_masters.attr); 1779 sysfs_attr_init(&bn->class_attr_bonding_masters.attr);
1789 1780
1790 ret = netdev_class_create_file(&bn->class_attr_bonding_masters); 1781 ret = netdev_class_create_file_ns(&bn->class_attr_bonding_masters,
1782 bn->net);
1791 /* 1783 /*
1792 * Permit multiple loads of the module by ignoring failures to 1784 * Permit multiple loads of the module by ignoring failures to
1793 * create the bonding_masters sysfs file. Bonding devices 1785 * create the bonding_masters sysfs file. Bonding devices
@@ -1817,7 +1809,7 @@ int bond_create_sysfs(struct bond_net *bn)
1817 */ 1809 */
1818void bond_destroy_sysfs(struct bond_net *bn) 1810void bond_destroy_sysfs(struct bond_net *bn)
1819{ 1811{
1820 netdev_class_remove_file(&bn->class_attr_bonding_masters); 1812 netdev_class_remove_file_ns(&bn->class_attr_bonding_masters, bn->net);
1821} 1813}
1822 1814
1823/* 1815/*
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 15ef5eb13663..e784340f1599 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -485,58 +485,15 @@ const struct file_operations sysfs_file_operations = {
485 .poll = sysfs_poll, 485 .poll = sysfs_poll,
486}; 486};
487 487
488static int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr, 488int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
489 const void **pns) 489 const struct attribute *attr, int type,
490{ 490 umode_t amode, const void *ns)
491 struct sysfs_dirent *dir_sd = kobj->sd;
492 const struct sysfs_ops *ops;
493 const void *ns = NULL;
494 int err;
495
496 if (!dir_sd) {
497 WARN(1, KERN_ERR "sysfs: kobject %s without dirent\n",
498 kobject_name(kobj));
499 return -ENOENT;
500 }
501
502 err = 0;
503 if (!sysfs_ns_type(dir_sd))
504 goto out;
505
506 err = -EINVAL;
507 if (!kobj->ktype)
508 goto out;
509 ops = kobj->ktype->sysfs_ops;
510 if (!ops)
511 goto out;
512 if (!ops->namespace)
513 goto out;
514
515 err = 0;
516 ns = ops->namespace(kobj, attr);
517out:
518 if (err) {
519 WARN(1, KERN_ERR
520 "missing sysfs namespace attribute operation for kobject: %s\n",
521 kobject_name(kobj));
522 }
523 *pns = ns;
524 return err;
525}
526
527int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
528 const struct attribute *attr, int type, umode_t amode)
529{ 491{
530 umode_t mode = (amode & S_IALLUGO) | S_IFREG; 492 umode_t mode = (amode & S_IALLUGO) | S_IFREG;
531 struct sysfs_addrm_cxt acxt; 493 struct sysfs_addrm_cxt acxt;
532 struct sysfs_dirent *sd; 494 struct sysfs_dirent *sd;
533 const void *ns;
534 int rc; 495 int rc;
535 496
536 rc = sysfs_attr_ns(dir_sd->s_dir.kobj, attr, &ns);
537 if (rc)
538 return rc;
539
540 sd = sysfs_new_dirent(attr->name, mode, type); 497 sd = sysfs_new_dirent(attr->name, mode, type);
541 if (!sd) 498 if (!sd)
542 return -ENOMEM; 499 return -ENOMEM;
@@ -559,23 +516,25 @@ int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
559int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, 516int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
560 int type) 517 int type)
561{ 518{
562 return sysfs_add_file_mode(dir_sd, attr, type, attr->mode); 519 return sysfs_add_file_mode_ns(dir_sd, attr, type, attr->mode, NULL);
563} 520}
564 521
565
566/** 522/**
567 * sysfs_create_file - create an attribute file for an object. 523 * sysfs_create_file_ns - create an attribute file for an object with custom ns
568 * @kobj: object we're creating for. 524 * @kobj: object we're creating for
569 * @attr: attribute descriptor. 525 * @attr: attribute descriptor
526 * @ns: namespace the new file should belong to
570 */ 527 */
571int sysfs_create_file(struct kobject *kobj, const struct attribute *attr) 528int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
529 const void *ns)
572{ 530{
573 BUG_ON(!kobj || !kobj->sd || !attr); 531 BUG_ON(!kobj || !kobj->sd || !attr);
574 532
575 return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR); 533 return sysfs_add_file_mode_ns(kobj->sd, attr, SYSFS_KOBJ_ATTR,
534 attr->mode, ns);
576 535
577} 536}
578EXPORT_SYMBOL_GPL(sysfs_create_file); 537EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
579 538
580int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) 539int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr)
581{ 540{
@@ -630,17 +589,12 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
630{ 589{
631 struct sysfs_dirent *sd; 590 struct sysfs_dirent *sd;
632 struct iattr newattrs; 591 struct iattr newattrs;
633 const void *ns;
634 int rc; 592 int rc;
635 593
636 rc = sysfs_attr_ns(kobj, attr, &ns);
637 if (rc)
638 return rc;
639
640 mutex_lock(&sysfs_mutex); 594 mutex_lock(&sysfs_mutex);
641 595
642 rc = -ENOENT; 596 rc = -ENOENT;
643 sd = sysfs_find_dirent(kobj->sd, ns, attr->name); 597 sd = sysfs_find_dirent(kobj->sd, NULL, attr->name);
644 if (!sd) 598 if (!sd)
645 goto out; 599 goto out;
646 600
@@ -655,22 +609,21 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
655EXPORT_SYMBOL_GPL(sysfs_chmod_file); 609EXPORT_SYMBOL_GPL(sysfs_chmod_file);
656 610
657/** 611/**
658 * sysfs_remove_file - remove an object attribute. 612 * sysfs_remove_file_ns - remove an object attribute with a custom ns tag
659 * @kobj: object we're acting for. 613 * @kobj: object we're acting for
660 * @attr: attribute descriptor. 614 * @attr: attribute descriptor
615 * @ns: namespace tag of the file to remove
661 * 616 *
662 * Hash the attribute name and kill the victim. 617 * Hash the attribute name and namespace tag and kill the victim.
663 */ 618 */
664void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr) 619void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
620 const void *ns)
665{ 621{
666 const void *ns; 622 struct sysfs_dirent *dir_sd = kobj->sd;
667
668 if (sysfs_attr_ns(kobj, attr, &ns))
669 return;
670 623
671 sysfs_hash_and_remove(kobj->sd, ns, attr->name); 624 sysfs_hash_and_remove(dir_sd, ns, attr->name);
672} 625}
673EXPORT_SYMBOL_GPL(sysfs_remove_file); 626EXPORT_SYMBOL_GPL(sysfs_remove_file_ns);
674 627
675void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr) 628void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr)
676{ 629{
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c
index 5f92cd2f61c1..25c78f23dae8 100644
--- a/fs/sysfs/group.c
+++ b/fs/sysfs/group.c
@@ -56,9 +56,10 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj,
56 if (!mode) 56 if (!mode)
57 continue; 57 continue;
58 } 58 }
59 error = sysfs_add_file_mode(dir_sd, *attr, 59 error = sysfs_add_file_mode_ns(dir_sd, *attr,
60 SYSFS_KOBJ_ATTR, 60 SYSFS_KOBJ_ATTR,
61 (*attr)->mode | mode); 61 (*attr)->mode | mode,
62 NULL);
62 if (unlikely(error)) 63 if (unlikely(error))
63 break; 64 break;
64 } 65 }
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index b6deca3e301d..a96da2559db2 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -230,8 +230,9 @@ extern const struct file_operations sysfs_file_operations;
230int sysfs_add_file(struct sysfs_dirent *dir_sd, 230int sysfs_add_file(struct sysfs_dirent *dir_sd,
231 const struct attribute *attr, int type); 231 const struct attribute *attr, int type);
232 232
233int sysfs_add_file_mode(struct sysfs_dirent *dir_sd, 233int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
234 const struct attribute *attr, int type, umode_t amode); 234 const struct attribute *attr, int type,
235 umode_t amode, const void *ns);
235/* 236/*
236 * bin.c 237 * bin.c
237 */ 238 */
diff --git a/include/linux/device.h b/include/linux/device.h
index 2a9d6ed59579..ce690ea34547 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -427,8 +427,6 @@ struct class_attribute {
427 char *buf); 427 char *buf);
428 ssize_t (*store)(struct class *class, struct class_attribute *attr, 428 ssize_t (*store)(struct class *class, struct class_attribute *attr,
429 const char *buf, size_t count); 429 const char *buf, size_t count);
430 const void *(*namespace)(struct class *class,
431 const struct class_attribute *attr);
432}; 430};
433 431
434#define CLASS_ATTR(_name, _mode, _show, _store) \ 432#define CLASS_ATTR(_name, _mode, _show, _store) \
@@ -438,10 +436,24 @@ struct class_attribute {
438#define CLASS_ATTR_RO(_name) \ 436#define CLASS_ATTR_RO(_name) \
439 struct class_attribute class_attr_##_name = __ATTR_RO(_name) 437 struct class_attribute class_attr_##_name = __ATTR_RO(_name)
440 438
441extern int __must_check class_create_file(struct class *class, 439extern int __must_check class_create_file_ns(struct class *class,
442 const struct class_attribute *attr); 440 const struct class_attribute *attr,
443extern void class_remove_file(struct class *class, 441 const void *ns);
444 const struct class_attribute *attr); 442extern void class_remove_file_ns(struct class *class,
443 const struct class_attribute *attr,
444 const void *ns);
445
446static inline int __must_check class_create_file(struct class *class,
447 const struct class_attribute *attr)
448{
449 return class_create_file_ns(class, attr, NULL);
450}
451
452static inline void class_remove_file(struct class *class,
453 const struct class_attribute *attr)
454{
455 return class_remove_file_ns(class, attr, NULL);
456}
445 457
446/* Simple class attribute that is just a static string */ 458/* Simple class attribute that is just a static string */
447struct class_attribute_string { 459struct class_attribute_string {
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 3de49aca4519..42421ed49a47 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2873,8 +2873,20 @@ extern int __init dev_proc_init(void);
2873#define dev_proc_init() 0 2873#define dev_proc_init() 0
2874#endif 2874#endif
2875 2875
2876extern int netdev_class_create_file(struct class_attribute *class_attr); 2876extern int netdev_class_create_file_ns(struct class_attribute *class_attr,
2877extern void netdev_class_remove_file(struct class_attribute *class_attr); 2877 const void *ns);
2878extern void netdev_class_remove_file_ns(struct class_attribute *class_attr,
2879 const void *ns);
2880
2881static inline int netdev_class_create_file(struct class_attribute *class_attr)
2882{
2883 return netdev_class_create_file_ns(class_attr, NULL);
2884}
2885
2886static inline void netdev_class_remove_file(struct class_attribute *class_attr)
2887{
2888 netdev_class_remove_file_ns(class_attr, NULL);
2889}
2878 2890
2879extern struct kobj_ns_type_operations net_ns_type_operations; 2891extern struct kobj_ns_type_operations net_ns_type_operations;
2880 2892
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 11baec7c9b26..82f7fac78e77 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -173,7 +173,6 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size)
173struct sysfs_ops { 173struct sysfs_ops {
174 ssize_t (*show)(struct kobject *, struct attribute *, char *); 174 ssize_t (*show)(struct kobject *, struct attribute *, char *);
175 ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t); 175 ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t);
176 const void *(*namespace)(struct kobject *, const struct attribute *);
177}; 176};
178 177
179struct sysfs_dirent; 178struct sysfs_dirent;
@@ -189,13 +188,15 @@ int __must_check sysfs_rename_dir(struct kobject *kobj, const char *new_name);
189int __must_check sysfs_move_dir(struct kobject *kobj, 188int __must_check sysfs_move_dir(struct kobject *kobj,
190 struct kobject *new_parent_kobj); 189 struct kobject *new_parent_kobj);
191 190
192int __must_check sysfs_create_file(struct kobject *kobj, 191int __must_check sysfs_create_file_ns(struct kobject *kobj,
193 const struct attribute *attr); 192 const struct attribute *attr,
193 const void *ns);
194int __must_check sysfs_create_files(struct kobject *kobj, 194int __must_check sysfs_create_files(struct kobject *kobj,
195 const struct attribute **attr); 195 const struct attribute **attr);
196int __must_check sysfs_chmod_file(struct kobject *kobj, 196int __must_check sysfs_chmod_file(struct kobject *kobj,
197 const struct attribute *attr, umode_t mode); 197 const struct attribute *attr, umode_t mode);
198void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr); 198void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
199 const void *ns);
199void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr); 200void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr);
200 201
201int __must_check sysfs_create_bin_file(struct kobject *kobj, 202int __must_check sysfs_create_bin_file(struct kobject *kobj,
@@ -277,8 +278,9 @@ static inline int sysfs_move_dir(struct kobject *kobj,
277 return 0; 278 return 0;
278} 279}
279 280
280static inline int sysfs_create_file(struct kobject *kobj, 281static inline int sysfs_create_file_ns(struct kobject *kobj,
281 const struct attribute *attr) 282 const struct attribute *attr,
283 const void *ns)
282{ 284{
283 return 0; 285 return 0;
284} 286}
@@ -295,8 +297,9 @@ static inline int sysfs_chmod_file(struct kobject *kobj,
295 return 0; 297 return 0;
296} 298}
297 299
298static inline void sysfs_remove_file(struct kobject *kobj, 300static inline void sysfs_remove_file_ns(struct kobject *kobj,
299 const struct attribute *attr) 301 const struct attribute *attr,
302 const void *ns)
300{ 303{
301} 304}
302 305
@@ -435,4 +438,16 @@ static inline int __must_check sysfs_init(void)
435 438
436#endif /* CONFIG_SYSFS */ 439#endif /* CONFIG_SYSFS */
437 440
441static inline int __must_check sysfs_create_file(struct kobject *kobj,
442 const struct attribute *attr)
443{
444 return sysfs_create_file_ns(kobj, attr, NULL);
445}
446
447static inline void sysfs_remove_file(struct kobject *kobj,
448 const struct attribute *attr)
449{
450 return sysfs_remove_file_ns(kobj, attr, NULL);
451}
452
438#endif /* _SYSFS_H_ */ 453#endif /* _SYSFS_H_ */
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index d954b56b4e47..325dee863e46 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1344,17 +1344,19 @@ int netdev_register_kobject(struct net_device *net)
1344 return error; 1344 return error;
1345} 1345}
1346 1346
1347int netdev_class_create_file(struct class_attribute *class_attr) 1347int netdev_class_create_file_ns(struct class_attribute *class_attr,
1348 const void *ns)
1348{ 1349{
1349 return class_create_file(&net_class, class_attr); 1350 return class_create_file_ns(&net_class, class_attr, ns);
1350} 1351}
1351EXPORT_SYMBOL(netdev_class_create_file); 1352EXPORT_SYMBOL(netdev_class_create_file_ns);
1352 1353
1353void netdev_class_remove_file(struct class_attribute *class_attr) 1354void netdev_class_remove_file_ns(struct class_attribute *class_attr,
1355 const void *ns)
1354{ 1356{
1355 class_remove_file(&net_class, class_attr); 1357 class_remove_file_ns(&net_class, class_attr, ns);
1356} 1358}
1357EXPORT_SYMBOL(netdev_class_remove_file); 1359EXPORT_SYMBOL(netdev_class_remove_file_ns);
1358 1360
1359int netdev_kobject_init(void) 1361int netdev_kobject_init(void)
1360{ 1362{