diff options
-rw-r--r-- | drivers/gpio/gpiolib.c | 2 | ||||
-rw-r--r-- | drivers/md/bitmap.c | 4 | ||||
-rw-r--r-- | drivers/md/md.c | 6 | ||||
-rw-r--r-- | fs/sysfs/bin.c | 2 | ||||
-rw-r--r-- | fs/sysfs/dir.c | 112 | ||||
-rw-r--r-- | fs/sysfs/file.c | 17 | ||||
-rw-r--r-- | fs/sysfs/group.c | 6 | ||||
-rw-r--r-- | fs/sysfs/inode.c | 4 | ||||
-rw-r--r-- | fs/sysfs/mount.c | 33 | ||||
-rw-r--r-- | fs/sysfs/symlink.c | 15 | ||||
-rw-r--r-- | fs/sysfs/sysfs.h | 20 | ||||
-rw-r--r-- | include/linux/sysfs.h | 10 | ||||
-rw-r--r-- | lib/kobject.c | 1 |
13 files changed, 181 insertions, 51 deletions
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index eb0c3fe44b29..cae1b8c5b08c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -399,7 +399,7 @@ static int gpio_setup_irq(struct gpio_desc *desc, struct device *dev, | |||
399 | goto free_id; | 399 | goto free_id; |
400 | } | 400 | } |
401 | 401 | ||
402 | pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, "value"); | 402 | pdesc->value_sd = sysfs_get_dirent(dev->kobj.sd, NULL, "value"); |
403 | if (!pdesc->value_sd) { | 403 | if (!pdesc->value_sd) { |
404 | ret = -ENODEV; | 404 | ret = -ENODEV; |
405 | goto free_id; | 405 | goto free_id; |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 26ac8aad0b19..f084249295d9 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1678,9 +1678,9 @@ int bitmap_create(mddev_t *mddev) | |||
1678 | 1678 | ||
1679 | bitmap->mddev = mddev; | 1679 | bitmap->mddev = mddev; |
1680 | 1680 | ||
1681 | bm = sysfs_get_dirent(mddev->kobj.sd, "bitmap"); | 1681 | bm = sysfs_get_dirent(mddev->kobj.sd, NULL, "bitmap"); |
1682 | if (bm) { | 1682 | if (bm) { |
1683 | bitmap->sysfs_can_clear = sysfs_get_dirent(bm, "can_clear"); | 1683 | bitmap->sysfs_can_clear = sysfs_get_dirent(bm, NULL, "can_clear"); |
1684 | sysfs_put(bm); | 1684 | sysfs_put(bm); |
1685 | } else | 1685 | } else |
1686 | bitmap->sysfs_can_clear = NULL; | 1686 | bitmap->sysfs_can_clear = NULL; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index cefd63daff31..a9fd491796ac 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1766,7 +1766,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1766 | kobject_del(&rdev->kobj); | 1766 | kobject_del(&rdev->kobj); |
1767 | goto fail; | 1767 | goto fail; |
1768 | } | 1768 | } |
1769 | rdev->sysfs_state = sysfs_get_dirent(rdev->kobj.sd, "state"); | 1769 | rdev->sysfs_state = sysfs_get_dirent(rdev->kobj.sd, NULL, "state"); |
1770 | 1770 | ||
1771 | list_add_rcu(&rdev->same_set, &mddev->disks); | 1771 | list_add_rcu(&rdev->same_set, &mddev->disks); |
1772 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); | 1772 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); |
@@ -4189,7 +4189,7 @@ static int md_alloc(dev_t dev, char *name) | |||
4189 | mutex_unlock(&disks_mutex); | 4189 | mutex_unlock(&disks_mutex); |
4190 | if (!error) { | 4190 | if (!error) { |
4191 | kobject_uevent(&mddev->kobj, KOBJ_ADD); | 4191 | kobject_uevent(&mddev->kobj, KOBJ_ADD); |
4192 | mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, "array_state"); | 4192 | mddev->sysfs_state = sysfs_get_dirent(mddev->kobj.sd, NULL, "array_state"); |
4193 | } | 4193 | } |
4194 | mddev_put(mddev); | 4194 | mddev_put(mddev); |
4195 | return error; | 4195 | return error; |
@@ -4398,7 +4398,7 @@ static int do_md_run(mddev_t * mddev) | |||
4398 | printk(KERN_WARNING | 4398 | printk(KERN_WARNING |
4399 | "md: cannot register extra attributes for %s\n", | 4399 | "md: cannot register extra attributes for %s\n", |
4400 | mdname(mddev)); | 4400 | mdname(mddev)); |
4401 | mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action"); | 4401 | mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, NULL, "sync_action"); |
4402 | } else if (mddev->ro == 2) /* auto-readonly not meaningful */ | 4402 | } else if (mddev->ro == 2) /* auto-readonly not meaningful */ |
4403 | mddev->ro = 0; | 4403 | mddev->ro = 0; |
4404 | 4404 | ||
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index e9d293593e52..806b277453f9 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c | |||
@@ -501,7 +501,7 @@ int sysfs_create_bin_file(struct kobject *kobj, | |||
501 | void sysfs_remove_bin_file(struct kobject *kobj, | 501 | void sysfs_remove_bin_file(struct kobject *kobj, |
502 | const struct bin_attribute *attr) | 502 | const struct bin_attribute *attr) |
503 | { | 503 | { |
504 | sysfs_hash_and_remove(kobj->sd, attr->attr.name); | 504 | sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name); |
505 | } | 505 | } |
506 | 506 | ||
507 | EXPORT_SYMBOL_GPL(sysfs_create_bin_file); | 507 | EXPORT_SYMBOL_GPL(sysfs_create_bin_file); |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 590717861c7a..b2b83067ccc8 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -380,9 +380,15 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | |||
380 | { | 380 | { |
381 | struct sysfs_inode_attrs *ps_iattr; | 381 | struct sysfs_inode_attrs *ps_iattr; |
382 | 382 | ||
383 | if (sysfs_find_dirent(acxt->parent_sd, sd->s_name)) | 383 | if (sysfs_find_dirent(acxt->parent_sd, sd->s_ns, sd->s_name)) |
384 | return -EEXIST; | 384 | return -EEXIST; |
385 | 385 | ||
386 | if (sysfs_ns_type(acxt->parent_sd) && !sd->s_ns) { | ||
387 | WARN(1, KERN_WARNING "sysfs: ns required in '%s' for '%s'\n", | ||
388 | acxt->parent_sd->s_name, sd->s_name); | ||
389 | return -EINVAL; | ||
390 | } | ||
391 | |||
386 | sd->s_parent = sysfs_get(acxt->parent_sd); | 392 | sd->s_parent = sysfs_get(acxt->parent_sd); |
387 | 393 | ||
388 | sysfs_link_sibling(sd); | 394 | sysfs_link_sibling(sd); |
@@ -533,13 +539,17 @@ void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt) | |||
533 | * Pointer to sysfs_dirent if found, NULL if not. | 539 | * Pointer to sysfs_dirent if found, NULL if not. |
534 | */ | 540 | */ |
535 | struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, | 541 | struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, |
542 | const void *ns, | ||
536 | const unsigned char *name) | 543 | const unsigned char *name) |
537 | { | 544 | { |
538 | struct sysfs_dirent *sd; | 545 | struct sysfs_dirent *sd; |
539 | 546 | ||
540 | for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) | 547 | for (sd = parent_sd->s_dir.children; sd; sd = sd->s_sibling) { |
548 | if (sd->s_ns != ns) | ||
549 | continue; | ||
541 | if (!strcmp(sd->s_name, name)) | 550 | if (!strcmp(sd->s_name, name)) |
542 | return sd; | 551 | return sd; |
552 | } | ||
543 | return NULL; | 553 | return NULL; |
544 | } | 554 | } |
545 | 555 | ||
@@ -558,12 +568,13 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, | |||
558 | * Pointer to sysfs_dirent if found, NULL if not. | 568 | * Pointer to sysfs_dirent if found, NULL if not. |
559 | */ | 569 | */ |
560 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | 570 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, |
571 | const void *ns, | ||
561 | const unsigned char *name) | 572 | const unsigned char *name) |
562 | { | 573 | { |
563 | struct sysfs_dirent *sd; | 574 | struct sysfs_dirent *sd; |
564 | 575 | ||
565 | mutex_lock(&sysfs_mutex); | 576 | mutex_lock(&sysfs_mutex); |
566 | sd = sysfs_find_dirent(parent_sd, name); | 577 | sd = sysfs_find_dirent(parent_sd, ns, name); |
567 | sysfs_get(sd); | 578 | sysfs_get(sd); |
568 | mutex_unlock(&sysfs_mutex); | 579 | mutex_unlock(&sysfs_mutex); |
569 | 580 | ||
@@ -572,7 +583,8 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | |||
572 | EXPORT_SYMBOL_GPL(sysfs_get_dirent); | 583 | EXPORT_SYMBOL_GPL(sysfs_get_dirent); |
573 | 584 | ||
574 | static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, | 585 | static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, |
575 | const char *name, struct sysfs_dirent **p_sd) | 586 | enum kobj_ns_type type, const void *ns, const char *name, |
587 | struct sysfs_dirent **p_sd) | ||
576 | { | 588 | { |
577 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 589 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; |
578 | struct sysfs_addrm_cxt acxt; | 590 | struct sysfs_addrm_cxt acxt; |
@@ -583,6 +595,9 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, | |||
583 | sd = sysfs_new_dirent(name, mode, SYSFS_DIR); | 595 | sd = sysfs_new_dirent(name, mode, SYSFS_DIR); |
584 | if (!sd) | 596 | if (!sd) |
585 | return -ENOMEM; | 597 | return -ENOMEM; |
598 | |||
599 | sd->s_flags |= (type << SYSFS_NS_TYPE_SHIFT); | ||
600 | sd->s_ns = ns; | ||
586 | sd->s_dir.kobj = kobj; | 601 | sd->s_dir.kobj = kobj; |
587 | 602 | ||
588 | /* link in */ | 603 | /* link in */ |
@@ -601,7 +616,25 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, | |||
601 | int sysfs_create_subdir(struct kobject *kobj, const char *name, | 616 | int sysfs_create_subdir(struct kobject *kobj, const char *name, |
602 | struct sysfs_dirent **p_sd) | 617 | struct sysfs_dirent **p_sd) |
603 | { | 618 | { |
604 | return create_dir(kobj, kobj->sd, name, p_sd); | 619 | return create_dir(kobj, kobj->sd, |
620 | KOBJ_NS_TYPE_NONE, NULL, name, p_sd); | ||
621 | } | ||
622 | |||
623 | static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj) | ||
624 | { | ||
625 | const struct kobj_ns_type_operations *ops; | ||
626 | enum kobj_ns_type type; | ||
627 | |||
628 | ops = kobj_child_ns_ops(kobj); | ||
629 | if (!ops) | ||
630 | return KOBJ_NS_TYPE_NONE; | ||
631 | |||
632 | type = ops->type; | ||
633 | BUG_ON(type <= KOBJ_NS_TYPE_NONE); | ||
634 | BUG_ON(type >= KOBJ_NS_TYPES); | ||
635 | BUG_ON(!kobj_ns_type_registered(type)); | ||
636 | |||
637 | return type; | ||
605 | } | 638 | } |
606 | 639 | ||
607 | /** | 640 | /** |
@@ -610,7 +643,9 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name, | |||
610 | */ | 643 | */ |
611 | int sysfs_create_dir(struct kobject * kobj) | 644 | int sysfs_create_dir(struct kobject * kobj) |
612 | { | 645 | { |
646 | enum kobj_ns_type type; | ||
613 | struct sysfs_dirent *parent_sd, *sd; | 647 | struct sysfs_dirent *parent_sd, *sd; |
648 | const void *ns = NULL; | ||
614 | int error = 0; | 649 | int error = 0; |
615 | 650 | ||
616 | BUG_ON(!kobj); | 651 | BUG_ON(!kobj); |
@@ -620,7 +655,11 @@ int sysfs_create_dir(struct kobject * kobj) | |||
620 | else | 655 | else |
621 | parent_sd = &sysfs_root; | 656 | parent_sd = &sysfs_root; |
622 | 657 | ||
623 | error = create_dir(kobj, parent_sd, kobject_name(kobj), &sd); | 658 | if (sysfs_ns_type(parent_sd)) |
659 | ns = kobj->ktype->namespace(kobj); | ||
660 | type = sysfs_read_ns_type(kobj); | ||
661 | |||
662 | error = create_dir(kobj, parent_sd, type, ns, kobject_name(kobj), &sd); | ||
624 | if (!error) | 663 | if (!error) |
625 | kobj->sd = sd; | 664 | kobj->sd = sd; |
626 | return error; | 665 | return error; |
@@ -630,13 +669,19 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | |||
630 | struct nameidata *nd) | 669 | struct nameidata *nd) |
631 | { | 670 | { |
632 | struct dentry *ret = NULL; | 671 | struct dentry *ret = NULL; |
633 | struct sysfs_dirent *parent_sd = dentry->d_parent->d_fsdata; | 672 | struct dentry *parent = dentry->d_parent; |
673 | struct sysfs_dirent *parent_sd = parent->d_fsdata; | ||
634 | struct sysfs_dirent *sd; | 674 | struct sysfs_dirent *sd; |
635 | struct inode *inode; | 675 | struct inode *inode; |
676 | enum kobj_ns_type type; | ||
677 | const void *ns; | ||
636 | 678 | ||
637 | mutex_lock(&sysfs_mutex); | 679 | mutex_lock(&sysfs_mutex); |
638 | 680 | ||
639 | sd = sysfs_find_dirent(parent_sd, dentry->d_name.name); | 681 | type = sysfs_ns_type(parent_sd); |
682 | ns = sysfs_info(dir->i_sb)->ns[type]; | ||
683 | |||
684 | sd = sysfs_find_dirent(parent_sd, ns, dentry->d_name.name); | ||
640 | 685 | ||
641 | /* no such entry */ | 686 | /* no such entry */ |
642 | if (!sd) { | 687 | if (!sd) { |
@@ -735,7 +780,8 @@ void sysfs_remove_dir(struct kobject * kobj) | |||
735 | } | 780 | } |
736 | 781 | ||
737 | int sysfs_rename(struct sysfs_dirent *sd, | 782 | int sysfs_rename(struct sysfs_dirent *sd, |
738 | struct sysfs_dirent *new_parent_sd, const char *new_name) | 783 | struct sysfs_dirent *new_parent_sd, const void *new_ns, |
784 | const char *new_name) | ||
739 | { | 785 | { |
740 | const char *dup_name = NULL; | 786 | const char *dup_name = NULL; |
741 | int error; | 787 | int error; |
@@ -743,12 +789,12 @@ int sysfs_rename(struct sysfs_dirent *sd, | |||
743 | mutex_lock(&sysfs_mutex); | 789 | mutex_lock(&sysfs_mutex); |
744 | 790 | ||
745 | error = 0; | 791 | error = 0; |
746 | if ((sd->s_parent == new_parent_sd) && | 792 | if ((sd->s_parent == new_parent_sd) && (sd->s_ns == new_ns) && |
747 | (strcmp(sd->s_name, new_name) == 0)) | 793 | (strcmp(sd->s_name, new_name) == 0)) |
748 | goto out; /* nothing to rename */ | 794 | goto out; /* nothing to rename */ |
749 | 795 | ||
750 | error = -EEXIST; | 796 | error = -EEXIST; |
751 | if (sysfs_find_dirent(new_parent_sd, new_name)) | 797 | if (sysfs_find_dirent(new_parent_sd, new_ns, new_name)) |
752 | goto out; | 798 | goto out; |
753 | 799 | ||
754 | /* rename sysfs_dirent */ | 800 | /* rename sysfs_dirent */ |
@@ -770,6 +816,7 @@ int sysfs_rename(struct sysfs_dirent *sd, | |||
770 | sd->s_parent = new_parent_sd; | 816 | sd->s_parent = new_parent_sd; |
771 | sysfs_link_sibling(sd); | 817 | sysfs_link_sibling(sd); |
772 | } | 818 | } |
819 | sd->s_ns = new_ns; | ||
773 | 820 | ||
774 | error = 0; | 821 | error = 0; |
775 | out: | 822 | out: |
@@ -780,19 +827,28 @@ int sysfs_rename(struct sysfs_dirent *sd, | |||
780 | 827 | ||
781 | int sysfs_rename_dir(struct kobject *kobj, const char *new_name) | 828 | int sysfs_rename_dir(struct kobject *kobj, const char *new_name) |
782 | { | 829 | { |
783 | return sysfs_rename(kobj->sd, kobj->sd->s_parent, new_name); | 830 | struct sysfs_dirent *parent_sd = kobj->sd->s_parent; |
831 | const void *new_ns = NULL; | ||
832 | |||
833 | if (sysfs_ns_type(parent_sd)) | ||
834 | new_ns = kobj->ktype->namespace(kobj); | ||
835 | |||
836 | return sysfs_rename(kobj->sd, parent_sd, new_ns, new_name); | ||
784 | } | 837 | } |
785 | 838 | ||
786 | int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) | 839 | int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent_kobj) |
787 | { | 840 | { |
788 | struct sysfs_dirent *sd = kobj->sd; | 841 | struct sysfs_dirent *sd = kobj->sd; |
789 | struct sysfs_dirent *new_parent_sd; | 842 | struct sysfs_dirent *new_parent_sd; |
843 | const void *new_ns = NULL; | ||
790 | 844 | ||
791 | BUG_ON(!sd->s_parent); | 845 | BUG_ON(!sd->s_parent); |
846 | if (sysfs_ns_type(sd->s_parent)) | ||
847 | new_ns = kobj->ktype->namespace(kobj); | ||
792 | new_parent_sd = new_parent_kobj && new_parent_kobj->sd ? | 848 | new_parent_sd = new_parent_kobj && new_parent_kobj->sd ? |
793 | new_parent_kobj->sd : &sysfs_root; | 849 | new_parent_kobj->sd : &sysfs_root; |
794 | 850 | ||
795 | return sysfs_rename(sd, new_parent_sd, sd->s_name); | 851 | return sysfs_rename(sd, new_parent_sd, new_ns, sd->s_name); |
796 | } | 852 | } |
797 | 853 | ||
798 | /* Relationship between s_mode and the DT_xxx types */ | 854 | /* Relationship between s_mode and the DT_xxx types */ |
@@ -807,32 +863,35 @@ static int sysfs_dir_release(struct inode *inode, struct file *filp) | |||
807 | return 0; | 863 | return 0; |
808 | } | 864 | } |
809 | 865 | ||
810 | static struct sysfs_dirent *sysfs_dir_pos(struct sysfs_dirent *parent_sd, | 866 | static struct sysfs_dirent *sysfs_dir_pos(const void *ns, |
811 | ino_t ino, struct sysfs_dirent *pos) | 867 | struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) |
812 | { | 868 | { |
813 | if (pos) { | 869 | if (pos) { |
814 | int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) && | 870 | int valid = !(pos->s_flags & SYSFS_FLAG_REMOVED) && |
815 | pos->s_parent == parent_sd && | 871 | pos->s_parent == parent_sd && |
816 | ino == pos->s_ino; | 872 | ino == pos->s_ino; |
817 | sysfs_put(pos); | 873 | sysfs_put(pos); |
818 | if (valid) | 874 | if (!valid) |
819 | return pos; | 875 | pos = NULL; |
820 | } | 876 | } |
821 | pos = NULL; | 877 | if (!pos && (ino > 1) && (ino < INT_MAX)) { |
822 | if ((ino > 1) && (ino < INT_MAX)) { | ||
823 | pos = parent_sd->s_dir.children; | 878 | pos = parent_sd->s_dir.children; |
824 | while (pos && (ino > pos->s_ino)) | 879 | while (pos && (ino > pos->s_ino)) |
825 | pos = pos->s_sibling; | 880 | pos = pos->s_sibling; |
826 | } | 881 | } |
882 | while (pos && pos->s_ns != ns) | ||
883 | pos = pos->s_sibling; | ||
827 | return pos; | 884 | return pos; |
828 | } | 885 | } |
829 | 886 | ||
830 | static struct sysfs_dirent *sysfs_dir_next_pos(struct sysfs_dirent *parent_sd, | 887 | static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns, |
831 | ino_t ino, struct sysfs_dirent *pos) | 888 | struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) |
832 | { | 889 | { |
833 | pos = sysfs_dir_pos(parent_sd, ino, pos); | 890 | pos = sysfs_dir_pos(ns, parent_sd, ino, pos); |
834 | if (pos) | 891 | if (pos) |
835 | pos = pos->s_sibling; | 892 | pos = pos->s_sibling; |
893 | while (pos && pos->s_ns != ns) | ||
894 | pos = pos->s_sibling; | ||
836 | return pos; | 895 | return pos; |
837 | } | 896 | } |
838 | 897 | ||
@@ -841,8 +900,13 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
841 | struct dentry *dentry = filp->f_path.dentry; | 900 | struct dentry *dentry = filp->f_path.dentry; |
842 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; | 901 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; |
843 | struct sysfs_dirent *pos = filp->private_data; | 902 | struct sysfs_dirent *pos = filp->private_data; |
903 | enum kobj_ns_type type; | ||
904 | const void *ns; | ||
844 | ino_t ino; | 905 | ino_t ino; |
845 | 906 | ||
907 | type = sysfs_ns_type(parent_sd); | ||
908 | ns = sysfs_info(dentry->d_sb)->ns[type]; | ||
909 | |||
846 | if (filp->f_pos == 0) { | 910 | if (filp->f_pos == 0) { |
847 | ino = parent_sd->s_ino; | 911 | ino = parent_sd->s_ino; |
848 | if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0) | 912 | if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0) |
@@ -857,9 +921,9 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
857 | filp->f_pos++; | 921 | filp->f_pos++; |
858 | } | 922 | } |
859 | mutex_lock(&sysfs_mutex); | 923 | mutex_lock(&sysfs_mutex); |
860 | for (pos = sysfs_dir_pos(parent_sd, filp->f_pos, pos); | 924 | for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos); |
861 | pos; | 925 | pos; |
862 | pos = sysfs_dir_next_pos(parent_sd, filp->f_pos, pos)) { | 926 | pos = sysfs_dir_next_pos(ns, parent_sd, filp->f_pos, pos)) { |
863 | const char * name; | 927 | const char * name; |
864 | unsigned int type; | 928 | unsigned int type; |
865 | int len, ret; | 929 | int len, ret; |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index e222b2582746..1beaa739d0a6 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -478,9 +478,12 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr) | |||
478 | mutex_lock(&sysfs_mutex); | 478 | mutex_lock(&sysfs_mutex); |
479 | 479 | ||
480 | if (sd && dir) | 480 | if (sd && dir) |
481 | sd = sysfs_find_dirent(sd, dir); | 481 | /* Only directories are tagged, so no need to pass |
482 | * a tag explicitly. | ||
483 | */ | ||
484 | sd = sysfs_find_dirent(sd, NULL, dir); | ||
482 | if (sd && attr) | 485 | if (sd && attr) |
483 | sd = sysfs_find_dirent(sd, attr); | 486 | sd = sysfs_find_dirent(sd, NULL, attr); |
484 | if (sd) | 487 | if (sd) |
485 | sysfs_notify_dirent(sd); | 488 | sysfs_notify_dirent(sd); |
486 | 489 | ||
@@ -569,7 +572,7 @@ int sysfs_add_file_to_group(struct kobject *kobj, | |||
569 | int error; | 572 | int error; |
570 | 573 | ||
571 | if (group) | 574 | if (group) |
572 | dir_sd = sysfs_get_dirent(kobj->sd, group); | 575 | dir_sd = sysfs_get_dirent(kobj->sd, NULL, group); |
573 | else | 576 | else |
574 | dir_sd = sysfs_get(kobj->sd); | 577 | dir_sd = sysfs_get(kobj->sd); |
575 | 578 | ||
@@ -599,7 +602,7 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | |||
599 | mutex_lock(&sysfs_mutex); | 602 | mutex_lock(&sysfs_mutex); |
600 | 603 | ||
601 | rc = -ENOENT; | 604 | rc = -ENOENT; |
602 | sd = sysfs_find_dirent(kobj->sd, attr->name); | 605 | sd = sysfs_find_dirent(kobj->sd, NULL, attr->name); |
603 | if (!sd) | 606 | if (!sd) |
604 | goto out; | 607 | goto out; |
605 | 608 | ||
@@ -624,7 +627,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file); | |||
624 | 627 | ||
625 | void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) | 628 | void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) |
626 | { | 629 | { |
627 | sysfs_hash_and_remove(kobj->sd, attr->name); | 630 | sysfs_hash_and_remove(kobj->sd, NULL, attr->name); |
628 | } | 631 | } |
629 | 632 | ||
630 | void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) | 633 | void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) |
@@ -646,11 +649,11 @@ void sysfs_remove_file_from_group(struct kobject *kobj, | |||
646 | struct sysfs_dirent *dir_sd; | 649 | struct sysfs_dirent *dir_sd; |
647 | 650 | ||
648 | if (group) | 651 | if (group) |
649 | dir_sd = sysfs_get_dirent(kobj->sd, group); | 652 | dir_sd = sysfs_get_dirent(kobj->sd, NULL, group); |
650 | else | 653 | else |
651 | dir_sd = sysfs_get(kobj->sd); | 654 | dir_sd = sysfs_get(kobj->sd); |
652 | if (dir_sd) { | 655 | if (dir_sd) { |
653 | sysfs_hash_and_remove(dir_sd, attr->name); | 656 | sysfs_hash_and_remove(dir_sd, NULL, attr->name); |
654 | sysfs_put(dir_sd); | 657 | sysfs_put(dir_sd); |
655 | } | 658 | } |
656 | } | 659 | } |
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index fe611949a7f7..23c1e598792a 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c | |||
@@ -23,7 +23,7 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | |||
23 | int i; | 23 | int i; |
24 | 24 | ||
25 | for (i = 0, attr = grp->attrs; *attr; i++, attr++) | 25 | for (i = 0, attr = grp->attrs; *attr; i++, attr++) |
26 | sysfs_hash_and_remove(dir_sd, (*attr)->name); | 26 | sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); |
27 | } | 27 | } |
28 | 28 | ||
29 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 29 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, |
@@ -39,7 +39,7 @@ static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | |||
39 | * visibility. Do this by first removing then | 39 | * visibility. Do this by first removing then |
40 | * re-adding (if required) the file */ | 40 | * re-adding (if required) the file */ |
41 | if (update) | 41 | if (update) |
42 | sysfs_hash_and_remove(dir_sd, (*attr)->name); | 42 | sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); |
43 | if (grp->is_visible) { | 43 | if (grp->is_visible) { |
44 | mode = grp->is_visible(kobj, *attr, i); | 44 | mode = grp->is_visible(kobj, *attr, i); |
45 | if (!mode) | 45 | if (!mode) |
@@ -132,7 +132,7 @@ void sysfs_remove_group(struct kobject * kobj, | |||
132 | struct sysfs_dirent *sd; | 132 | struct sysfs_dirent *sd; |
133 | 133 | ||
134 | if (grp->name) { | 134 | if (grp->name) { |
135 | sd = sysfs_get_dirent(dir_sd, grp->name); | 135 | sd = sysfs_get_dirent(dir_sd, NULL, grp->name); |
136 | if (!sd) { | 136 | if (!sd) { |
137 | WARN(!sd, KERN_WARNING "sysfs group %p not found for " | 137 | WARN(!sd, KERN_WARNING "sysfs group %p not found for " |
138 | "kobject '%s'\n", grp, kobject_name(kobj)); | 138 | "kobject '%s'\n", grp, kobject_name(kobj)); |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index a4a0a9419711..cf2bad1462ea 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -324,7 +324,7 @@ void sysfs_delete_inode(struct inode *inode) | |||
324 | sysfs_put(sd); | 324 | sysfs_put(sd); |
325 | } | 325 | } |
326 | 326 | ||
327 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name) | 327 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name) |
328 | { | 328 | { |
329 | struct sysfs_addrm_cxt acxt; | 329 | struct sysfs_addrm_cxt acxt; |
330 | struct sysfs_dirent *sd; | 330 | struct sysfs_dirent *sd; |
@@ -334,7 +334,7 @@ int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name) | |||
334 | 334 | ||
335 | sysfs_addrm_start(&acxt, dir_sd); | 335 | sysfs_addrm_start(&acxt, dir_sd); |
336 | 336 | ||
337 | sd = sysfs_find_dirent(dir_sd, name); | 337 | sd = sysfs_find_dirent(dir_sd, ns, name); |
338 | if (sd) | 338 | if (sd) |
339 | sysfs_remove_one(&acxt, sd); | 339 | sysfs_remove_one(&acxt, sd); |
340 | 340 | ||
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 50e4fb6a7403..1afa32ba242c 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -35,7 +35,7 @@ static const struct super_operations sysfs_ops = { | |||
35 | struct sysfs_dirent sysfs_root = { | 35 | struct sysfs_dirent sysfs_root = { |
36 | .s_name = "", | 36 | .s_name = "", |
37 | .s_count = ATOMIC_INIT(1), | 37 | .s_count = ATOMIC_INIT(1), |
38 | .s_flags = SYSFS_DIR, | 38 | .s_flags = SYSFS_DIR | (KOBJ_NS_TYPE_NONE << SYSFS_NS_TYPE_SHIFT), |
39 | .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, | 39 | .s_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, |
40 | .s_ino = 1, | 40 | .s_ino = 1, |
41 | }; | 41 | }; |
@@ -76,7 +76,13 @@ static int sysfs_test_super(struct super_block *sb, void *data) | |||
76 | { | 76 | { |
77 | struct sysfs_super_info *sb_info = sysfs_info(sb); | 77 | struct sysfs_super_info *sb_info = sysfs_info(sb); |
78 | struct sysfs_super_info *info = data; | 78 | struct sysfs_super_info *info = data; |
79 | enum kobj_ns_type type; | ||
79 | int found = 1; | 80 | int found = 1; |
81 | |||
82 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) { | ||
83 | if (sb_info->ns[type] != info->ns[type]) | ||
84 | found = 0; | ||
85 | } | ||
80 | return found; | 86 | return found; |
81 | } | 87 | } |
82 | 88 | ||
@@ -93,6 +99,7 @@ static int sysfs_get_sb(struct file_system_type *fs_type, | |||
93 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 99 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
94 | { | 100 | { |
95 | struct sysfs_super_info *info; | 101 | struct sysfs_super_info *info; |
102 | enum kobj_ns_type type; | ||
96 | struct super_block *sb; | 103 | struct super_block *sb; |
97 | int error; | 104 | int error; |
98 | 105 | ||
@@ -100,6 +107,10 @@ static int sysfs_get_sb(struct file_system_type *fs_type, | |||
100 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 107 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
101 | if (!info) | 108 | if (!info) |
102 | goto out; | 109 | goto out; |
110 | |||
111 | for (type = KOBJ_NS_TYPE_NONE; type < KOBJ_NS_TYPES; type++) | ||
112 | info->ns[type] = kobj_ns_current(type); | ||
113 | |||
103 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); | 114 | sb = sget(fs_type, sysfs_test_super, sysfs_set_super, info); |
104 | if (IS_ERR(sb) || sb->s_fs_info != info) | 115 | if (IS_ERR(sb) || sb->s_fs_info != info) |
105 | kfree(info); | 116 | kfree(info); |
@@ -137,6 +148,26 @@ static struct file_system_type sysfs_fs_type = { | |||
137 | .kill_sb = sysfs_kill_sb, | 148 | .kill_sb = sysfs_kill_sb, |
138 | }; | 149 | }; |
139 | 150 | ||
151 | void sysfs_exit_ns(enum kobj_ns_type type, const void *ns) | ||
152 | { | ||
153 | struct super_block *sb; | ||
154 | |||
155 | mutex_lock(&sysfs_mutex); | ||
156 | spin_lock(&sb_lock); | ||
157 | list_for_each_entry(sb, &sysfs_fs_type.fs_supers, s_instances) { | ||
158 | struct sysfs_super_info *info = sysfs_info(sb); | ||
159 | /* Ignore superblocks that are in the process of unmounting */ | ||
160 | if (sb->s_count <= S_BIAS) | ||
161 | continue; | ||
162 | /* Ignore superblocks with the wrong ns */ | ||
163 | if (info->ns[type] != ns) | ||
164 | continue; | ||
165 | info->ns[type] = NULL; | ||
166 | } | ||
167 | spin_unlock(&sb_lock); | ||
168 | mutex_unlock(&sysfs_mutex); | ||
169 | } | ||
170 | |||
140 | int __init sysfs_init(void) | 171 | int __init sysfs_init(void) |
141 | { | 172 | { |
142 | int err = -ENOMEM; | 173 | int err = -ENOMEM; |
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 942f239a2132..b6ebdaa00f37 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -58,6 +58,8 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, | |||
58 | if (!sd) | 58 | if (!sd) |
59 | goto out_put; | 59 | goto out_put; |
60 | 60 | ||
61 | if (sysfs_ns_type(parent_sd)) | ||
62 | sd->s_ns = target->ktype->namespace(target); | ||
61 | sd->s_symlink.target_sd = target_sd; | 63 | sd->s_symlink.target_sd = target_sd; |
62 | target_sd = NULL; /* reference is now owned by the symlink */ | 64 | target_sd = NULL; /* reference is now owned by the symlink */ |
63 | 65 | ||
@@ -121,7 +123,7 @@ void sysfs_remove_link(struct kobject * kobj, const char * name) | |||
121 | else | 123 | else |
122 | parent_sd = kobj->sd; | 124 | parent_sd = kobj->sd; |
123 | 125 | ||
124 | sysfs_hash_and_remove(parent_sd, name); | 126 | sysfs_hash_and_remove(parent_sd, NULL, name); |
125 | } | 127 | } |
126 | 128 | ||
127 | /** | 129 | /** |
@@ -137,6 +139,7 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ, | |||
137 | const char *old, const char *new) | 139 | const char *old, const char *new) |
138 | { | 140 | { |
139 | struct sysfs_dirent *parent_sd, *sd = NULL; | 141 | struct sysfs_dirent *parent_sd, *sd = NULL; |
142 | const void *old_ns = NULL, *new_ns = NULL; | ||
140 | int result; | 143 | int result; |
141 | 144 | ||
142 | if (!kobj) | 145 | if (!kobj) |
@@ -144,8 +147,11 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ, | |||
144 | else | 147 | else |
145 | parent_sd = kobj->sd; | 148 | parent_sd = kobj->sd; |
146 | 149 | ||
150 | if (targ->sd) | ||
151 | old_ns = targ->sd->s_ns; | ||
152 | |||
147 | result = -ENOENT; | 153 | result = -ENOENT; |
148 | sd = sysfs_get_dirent(parent_sd, old); | 154 | sd = sysfs_get_dirent(parent_sd, old_ns, old); |
149 | if (!sd) | 155 | if (!sd) |
150 | goto out; | 156 | goto out; |
151 | 157 | ||
@@ -155,7 +161,10 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ, | |||
155 | if (sd->s_symlink.target_sd->s_dir.kobj != targ) | 161 | if (sd->s_symlink.target_sd->s_dir.kobj != targ) |
156 | goto out; | 162 | goto out; |
157 | 163 | ||
158 | result = sysfs_rename(sd, parent_sd, new); | 164 | if (sysfs_ns_type(parent_sd)) |
165 | new_ns = targ->ktype->namespace(targ); | ||
166 | |||
167 | result = sysfs_rename(sd, parent_sd, new_ns, new); | ||
159 | 168 | ||
160 | out: | 169 | out: |
161 | sysfs_put(sd); | 170 | sysfs_put(sd); |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 030a39dbb02c..93847d54c2e3 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -58,6 +58,7 @@ struct sysfs_dirent { | |||
58 | struct sysfs_dirent *s_sibling; | 58 | struct sysfs_dirent *s_sibling; |
59 | const char *s_name; | 59 | const char *s_name; |
60 | 60 | ||
61 | const void *s_ns; | ||
61 | union { | 62 | union { |
62 | struct sysfs_elem_dir s_dir; | 63 | struct sysfs_elem_dir s_dir; |
63 | struct sysfs_elem_symlink s_symlink; | 64 | struct sysfs_elem_symlink s_symlink; |
@@ -81,14 +82,22 @@ struct sysfs_dirent { | |||
81 | #define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK) | 82 | #define SYSFS_COPY_NAME (SYSFS_DIR | SYSFS_KOBJ_LINK) |
82 | #define SYSFS_ACTIVE_REF (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR) | 83 | #define SYSFS_ACTIVE_REF (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR) |
83 | 84 | ||
84 | #define SYSFS_FLAG_MASK ~SYSFS_TYPE_MASK | 85 | #define SYSFS_NS_TYPE_MASK 0xff00 |
85 | #define SYSFS_FLAG_REMOVED 0x0200 | 86 | #define SYSFS_NS_TYPE_SHIFT 8 |
87 | |||
88 | #define SYSFS_FLAG_MASK ~(SYSFS_NS_TYPE_MASK|SYSFS_TYPE_MASK) | ||
89 | #define SYSFS_FLAG_REMOVED 0x020000 | ||
86 | 90 | ||
87 | static inline unsigned int sysfs_type(struct sysfs_dirent *sd) | 91 | static inline unsigned int sysfs_type(struct sysfs_dirent *sd) |
88 | { | 92 | { |
89 | return sd->s_flags & SYSFS_TYPE_MASK; | 93 | return sd->s_flags & SYSFS_TYPE_MASK; |
90 | } | 94 | } |
91 | 95 | ||
96 | static inline enum kobj_ns_type sysfs_ns_type(struct sysfs_dirent *sd) | ||
97 | { | ||
98 | return (sd->s_flags & SYSFS_NS_TYPE_MASK) >> SYSFS_NS_TYPE_SHIFT; | ||
99 | } | ||
100 | |||
92 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 101 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
93 | #define sysfs_dirent_init_lockdep(sd) \ | 102 | #define sysfs_dirent_init_lockdep(sd) \ |
94 | do { \ | 103 | do { \ |
@@ -115,6 +124,7 @@ struct sysfs_addrm_cxt { | |||
115 | * mount.c | 124 | * mount.c |
116 | */ | 125 | */ |
117 | struct sysfs_super_info { | 126 | struct sysfs_super_info { |
127 | const void *ns[KOBJ_NS_TYPES]; | ||
118 | }; | 128 | }; |
119 | #define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) | 129 | #define sysfs_info(SB) ((struct sysfs_super_info *)(SB->s_fs_info)) |
120 | extern struct sysfs_dirent sysfs_root; | 130 | extern struct sysfs_dirent sysfs_root; |
@@ -140,8 +150,10 @@ void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd); | |||
140 | void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); | 150 | void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt); |
141 | 151 | ||
142 | struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, | 152 | struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, |
153 | const void *ns, | ||
143 | const unsigned char *name); | 154 | const unsigned char *name); |
144 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | 155 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, |
156 | const void *ns, | ||
145 | const unsigned char *name); | 157 | const unsigned char *name); |
146 | struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type); | 158 | struct sysfs_dirent *sysfs_new_dirent(const char *name, umode_t mode, int type); |
147 | 159 | ||
@@ -152,7 +164,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name, | |||
152 | void sysfs_remove_subdir(struct sysfs_dirent *sd); | 164 | void sysfs_remove_subdir(struct sysfs_dirent *sd); |
153 | 165 | ||
154 | int sysfs_rename(struct sysfs_dirent *sd, | 166 | int sysfs_rename(struct sysfs_dirent *sd, |
155 | struct sysfs_dirent *new_parent_sd, const char *new_name); | 167 | struct sysfs_dirent *new_parent_sd, const void *ns, const char *new_name); |
156 | 168 | ||
157 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) | 169 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) |
158 | { | 170 | { |
@@ -182,7 +194,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); | |||
182 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); | 194 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); |
183 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 195 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
184 | size_t size, int flags); | 196 | size_t size, int flags); |
185 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name); | 197 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name); |
186 | int sysfs_inode_init(void); | 198 | int sysfs_inode_init(void); |
187 | 199 | ||
188 | /* | 200 | /* |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index f0496b3d1811..1885d21b0c80 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -20,6 +20,7 @@ | |||
20 | 20 | ||
21 | struct kobject; | 21 | struct kobject; |
22 | struct module; | 22 | struct module; |
23 | enum kobj_ns_type; | ||
23 | 24 | ||
24 | /* FIXME | 25 | /* FIXME |
25 | * The *owner field is no longer used. | 26 | * The *owner field is no longer used. |
@@ -168,10 +169,14 @@ void sysfs_remove_file_from_group(struct kobject *kobj, | |||
168 | void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr); | 169 | void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr); |
169 | void sysfs_notify_dirent(struct sysfs_dirent *sd); | 170 | void sysfs_notify_dirent(struct sysfs_dirent *sd); |
170 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | 171 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, |
172 | const void *ns, | ||
171 | const unsigned char *name); | 173 | const unsigned char *name); |
172 | struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd); | 174 | struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd); |
173 | void sysfs_put(struct sysfs_dirent *sd); | 175 | void sysfs_put(struct sysfs_dirent *sd); |
174 | void sysfs_printk_last_file(void); | 176 | void sysfs_printk_last_file(void); |
177 | |||
178 | void sysfs_exit_ns(enum kobj_ns_type type, const void *tag); | ||
179 | |||
175 | int __must_check sysfs_init(void); | 180 | int __must_check sysfs_init(void); |
176 | 181 | ||
177 | #else /* CONFIG_SYSFS */ | 182 | #else /* CONFIG_SYSFS */ |
@@ -301,6 +306,7 @@ static inline void sysfs_notify_dirent(struct sysfs_dirent *sd) | |||
301 | } | 306 | } |
302 | static inline | 307 | static inline |
303 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, | 308 | struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, |
309 | const void *ns, | ||
304 | const unsigned char *name) | 310 | const unsigned char *name) |
305 | { | 311 | { |
306 | return NULL; | 312 | return NULL; |
@@ -313,6 +319,10 @@ static inline void sysfs_put(struct sysfs_dirent *sd) | |||
313 | { | 319 | { |
314 | } | 320 | } |
315 | 321 | ||
322 | static inline void sysfs_exit_ns(enum kobj_ns_type type, const void *tag) | ||
323 | { | ||
324 | } | ||
325 | |||
316 | static inline int __must_check sysfs_init(void) | 326 | static inline int __must_check sysfs_init(void) |
317 | { | 327 | { |
318 | return 0; | 328 | return 0; |
diff --git a/lib/kobject.c b/lib/kobject.c index bbb2bb40ee1f..b2c6d1f56e65 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -950,6 +950,7 @@ const void *kobj_ns_initial(enum kobj_ns_type type) | |||
950 | 950 | ||
951 | void kobj_ns_exit(enum kobj_ns_type type, const void *ns) | 951 | void kobj_ns_exit(enum kobj_ns_type type, const void *ns) |
952 | { | 952 | { |
953 | sysfs_exit_ns(type, ns); | ||
953 | } | 954 | } |
954 | 955 | ||
955 | 956 | ||