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 | ||
