diff options
Diffstat (limited to 'lib/kobject.c')
| -rw-r--r-- | lib/kobject.c | 95 |
1 files changed, 34 insertions, 61 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index 5b4b8886435e..b0b26665c611 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
| @@ -13,11 +13,11 @@ | |||
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/kobject.h> | 15 | #include <linux/kobject.h> |
| 16 | #include <linux/kobj_completion.h> | ||
| 17 | #include <linux/string.h> | 16 | #include <linux/string.h> |
| 18 | #include <linux/export.h> | 17 | #include <linux/export.h> |
| 19 | #include <linux/stat.h> | 18 | #include <linux/stat.h> |
| 20 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <linux/random.h> | ||
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | * kobject_namespace - return @kobj's namespace tag | 23 | * kobject_namespace - return @kobj's namespace tag |
| @@ -65,13 +65,17 @@ static int populate_dir(struct kobject *kobj) | |||
| 65 | 65 | ||
| 66 | static int create_dir(struct kobject *kobj) | 66 | static int create_dir(struct kobject *kobj) |
| 67 | { | 67 | { |
| 68 | const struct kobj_ns_type_operations *ops; | ||
| 68 | int error; | 69 | int error; |
| 69 | 70 | ||
| 70 | error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj)); | 71 | error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj)); |
| 71 | if (!error) { | 72 | if (error) |
| 72 | error = populate_dir(kobj); | 73 | return error; |
| 73 | if (error) | 74 | |
| 74 | sysfs_remove_dir(kobj); | 75 | error = populate_dir(kobj); |
| 76 | if (error) { | ||
| 77 | sysfs_remove_dir(kobj); | ||
| 78 | return error; | ||
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | /* | 81 | /* |
| @@ -80,7 +84,20 @@ static int create_dir(struct kobject *kobj) | |||
| 80 | */ | 84 | */ |
| 81 | sysfs_get(kobj->sd); | 85 | sysfs_get(kobj->sd); |
| 82 | 86 | ||
| 83 | return error; | 87 | /* |
| 88 | * If @kobj has ns_ops, its children need to be filtered based on | ||
| 89 | * their namespace tags. Enable namespace support on @kobj->sd. | ||
| 90 | */ | ||
| 91 | ops = kobj_child_ns_ops(kobj); | ||
| 92 | if (ops) { | ||
| 93 | BUG_ON(ops->type <= KOBJ_NS_TYPE_NONE); | ||
| 94 | BUG_ON(ops->type >= KOBJ_NS_TYPES); | ||
| 95 | BUG_ON(!kobj_ns_type_registered(ops->type)); | ||
| 96 | |||
| 97 | kernfs_enable_ns(kobj->sd); | ||
| 98 | } | ||
| 99 | |||
| 100 | return 0; | ||
| 84 | } | 101 | } |
| 85 | 102 | ||
| 86 | static int get_kobj_path_length(struct kobject *kobj) | 103 | static int get_kobj_path_length(struct kobject *kobj) |
| @@ -247,8 +264,10 @@ int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, | |||
| 247 | return 0; | 264 | return 0; |
| 248 | 265 | ||
| 249 | kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs); | 266 | kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs); |
| 250 | if (!kobj->name) | 267 | if (!kobj->name) { |
| 268 | kobj->name = old_name; | ||
| 251 | return -ENOMEM; | 269 | return -ENOMEM; |
| 270 | } | ||
| 252 | 271 | ||
| 253 | /* ewww... some of these buggers have '/' in the name ... */ | 272 | /* ewww... some of these buggers have '/' in the name ... */ |
| 254 | while ((s = strchr(kobj->name, '/'))) | 273 | while ((s = strchr(kobj->name, '/'))) |
| @@ -346,7 +365,7 @@ static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, | |||
| 346 | * | 365 | * |
| 347 | * If @parent is set, then the parent of the @kobj will be set to it. | 366 | * If @parent is set, then the parent of the @kobj will be set to it. |
| 348 | * If @parent is NULL, then the parent of the @kobj will be set to the | 367 | * If @parent is NULL, then the parent of the @kobj will be set to the |
| 349 | * kobject associted with the kset assigned to this kobject. If no kset | 368 | * kobject associated with the kset assigned to this kobject. If no kset |
| 350 | * is assigned to the kobject, then the kobject will be located in the | 369 | * is assigned to the kobject, then the kobject will be located in the |
| 351 | * root of the sysfs tree. | 370 | * root of the sysfs tree. |
| 352 | * | 371 | * |
| @@ -536,7 +555,7 @@ out: | |||
| 536 | */ | 555 | */ |
| 537 | void kobject_del(struct kobject *kobj) | 556 | void kobject_del(struct kobject *kobj) |
| 538 | { | 557 | { |
| 539 | struct sysfs_dirent *sd; | 558 | struct kernfs_node *sd; |
| 540 | 559 | ||
| 541 | if (!kobj) | 560 | if (!kobj) |
| 542 | return; | 561 | return; |
| @@ -625,10 +644,12 @@ static void kobject_release(struct kref *kref) | |||
| 625 | { | 644 | { |
| 626 | struct kobject *kobj = container_of(kref, struct kobject, kref); | 645 | struct kobject *kobj = container_of(kref, struct kobject, kref); |
| 627 | #ifdef CONFIG_DEBUG_KOBJECT_RELEASE | 646 | #ifdef CONFIG_DEBUG_KOBJECT_RELEASE |
| 628 | pr_info("kobject: '%s' (%p): %s, parent %p (delayed)\n", | 647 | unsigned long delay = HZ + HZ * (get_random_int() & 0x3); |
| 629 | kobject_name(kobj), kobj, __func__, kobj->parent); | 648 | pr_info("kobject: '%s' (%p): %s, parent %p (delayed %ld)\n", |
| 649 | kobject_name(kobj), kobj, __func__, kobj->parent, delay); | ||
| 630 | INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup); | 650 | INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup); |
| 631 | schedule_delayed_work(&kobj->release, HZ); | 651 | |
| 652 | schedule_delayed_work(&kobj->release, delay); | ||
| 632 | #else | 653 | #else |
| 633 | kobject_cleanup(kobj); | 654 | kobject_cleanup(kobj); |
| 634 | #endif | 655 | #endif |
| @@ -760,55 +781,6 @@ const struct sysfs_ops kobj_sysfs_ops = { | |||
| 760 | }; | 781 | }; |
| 761 | 782 | ||
| 762 | /** | 783 | /** |
| 763 | * kobj_completion_init - initialize a kobj_completion object. | ||
| 764 | * @kc: kobj_completion | ||
| 765 | * @ktype: type of kobject to initialize | ||
| 766 | * | ||
| 767 | * kobj_completion structures can be embedded within structures with different | ||
| 768 | * lifetime rules. During the release of the enclosing object, we can | ||
| 769 | * wait on the release of the kobject so that we don't free it while it's | ||
| 770 | * still busy. | ||
| 771 | */ | ||
| 772 | void kobj_completion_init(struct kobj_completion *kc, struct kobj_type *ktype) | ||
| 773 | { | ||
| 774 | init_completion(&kc->kc_unregister); | ||
| 775 | kobject_init(&kc->kc_kobj, ktype); | ||
| 776 | } | ||
| 777 | EXPORT_SYMBOL_GPL(kobj_completion_init); | ||
| 778 | |||
| 779 | /** | ||
| 780 | * kobj_completion_release - release a kobj_completion object | ||
| 781 | * @kobj: kobject embedded in kobj_completion | ||
| 782 | * | ||
| 783 | * Used with kobject_release to notify waiters that the kobject has been | ||
| 784 | * released. | ||
| 785 | */ | ||
| 786 | void kobj_completion_release(struct kobject *kobj) | ||
| 787 | { | ||
| 788 | struct kobj_completion *kc = kobj_to_kobj_completion(kobj); | ||
| 789 | complete(&kc->kc_unregister); | ||
| 790 | } | ||
| 791 | EXPORT_SYMBOL_GPL(kobj_completion_release); | ||
| 792 | |||
| 793 | /** | ||
| 794 | * kobj_completion_del_and_wait - release the kobject and wait for it | ||
| 795 | * @kc: kobj_completion object to release | ||
| 796 | * | ||
| 797 | * Delete the kobject from sysfs and drop the reference count. Then wait | ||
| 798 | * until any other outstanding references are also dropped. This routine | ||
| 799 | * is only necessary once other references may have been taken on the | ||
| 800 | * kobject. Typically this happens when the kobject has been published | ||
| 801 | * to sysfs via kobject_add. | ||
| 802 | */ | ||
| 803 | void kobj_completion_del_and_wait(struct kobj_completion *kc) | ||
| 804 | { | ||
| 805 | kobject_del(&kc->kc_kobj); | ||
| 806 | kobject_put(&kc->kc_kobj); | ||
| 807 | wait_for_completion(&kc->kc_unregister); | ||
| 808 | } | ||
| 809 | EXPORT_SYMBOL_GPL(kobj_completion_del_and_wait); | ||
| 810 | |||
| 811 | /** | ||
| 812 | * kset_register - initialize and add a kset. | 784 | * kset_register - initialize and add a kset. |
| 813 | * @k: kset. | 785 | * @k: kset. |
| 814 | */ | 786 | */ |
| @@ -835,6 +807,7 @@ void kset_unregister(struct kset *k) | |||
| 835 | { | 807 | { |
| 836 | if (!k) | 808 | if (!k) |
| 837 | return; | 809 | return; |
| 810 | kobject_del(&k->kobj); | ||
| 838 | kobject_put(&k->kobj); | 811 | kobject_put(&k->kobj); |
| 839 | } | 812 | } |
| 840 | 813 | ||
