aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/file.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 1ad8c93c1b85..07c1b4ec00df 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -488,17 +488,56 @@ const struct file_operations sysfs_file_operations = {
488 .poll = sysfs_poll, 488 .poll = sysfs_poll,
489}; 489};
490 490
491int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
492 const void **pns)
493{
494 struct sysfs_dirent *dir_sd = kobj->sd;
495 const struct sysfs_ops *ops;
496 const void *ns = NULL;
497 int err;
498
499 err = 0;
500 if (!sysfs_ns_type(dir_sd))
501 goto out;
502
503 err = -EINVAL;
504 if (!kobj->ktype)
505 goto out;
506 ops = kobj->ktype->sysfs_ops;
507 if (!ops)
508 goto out;
509 if (!ops->namespace)
510 goto out;
511
512 err = 0;
513 ns = ops->namespace(kobj, attr);
514out:
515 if (err) {
516 WARN(1, KERN_ERR "missing sysfs namespace attribute operation for "
517 "kobject: %s\n", kobject_name(kobj));
518 }
519 *pns = ns;
520 return err;
521}
522
491int sysfs_add_file_mode(struct sysfs_dirent *dir_sd, 523int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
492 const struct attribute *attr, int type, mode_t amode) 524 const struct attribute *attr, int type, mode_t amode)
493{ 525{
494 umode_t mode = (amode & S_IALLUGO) | S_IFREG; 526 umode_t mode = (amode & S_IALLUGO) | S_IFREG;
495 struct sysfs_addrm_cxt acxt; 527 struct sysfs_addrm_cxt acxt;
496 struct sysfs_dirent *sd; 528 struct sysfs_dirent *sd;
529 const void *ns;
497 int rc; 530 int rc;
498 531
532 rc = sysfs_attr_ns(dir_sd->s_dir.kobj, attr, &ns);
533 if (rc)
534 return rc;
535
499 sd = sysfs_new_dirent(attr->name, mode, type); 536 sd = sysfs_new_dirent(attr->name, mode, type);
500 if (!sd) 537 if (!sd)
501 return -ENOMEM; 538 return -ENOMEM;
539
540 sd->s_ns = ns;
502 sd->s_attr.attr = (void *)attr; 541 sd->s_attr.attr = (void *)attr;
503 sysfs_dirent_init_lockdep(sd); 542 sysfs_dirent_init_lockdep(sd);
504 543
@@ -586,12 +625,17 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
586{ 625{
587 struct sysfs_dirent *sd; 626 struct sysfs_dirent *sd;
588 struct iattr newattrs; 627 struct iattr newattrs;
628 const void *ns;
589 int rc; 629 int rc;
590 630
631 rc = sysfs_attr_ns(kobj, attr, &ns);
632 if (rc)
633 return rc;
634
591 mutex_lock(&sysfs_mutex); 635 mutex_lock(&sysfs_mutex);
592 636
593 rc = -ENOENT; 637 rc = -ENOENT;
594 sd = sysfs_find_dirent(kobj->sd, NULL, attr->name); 638 sd = sysfs_find_dirent(kobj->sd, ns, attr->name);
595 if (!sd) 639 if (!sd)
596 goto out; 640 goto out;
597 641
@@ -616,7 +660,12 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
616 660
617void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) 661void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
618{ 662{
619 sysfs_hash_and_remove(kobj->sd, NULL, attr->name); 663 const void *ns;
664
665 if (sysfs_attr_ns(kobj, attr, &ns))
666 return;
667
668 sysfs_hash_and_remove(kobj->sd, ns, attr->name);
620} 669}
621 670
622void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) 671void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr)