0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/kobject.h>
0014 #include <linux/string.h>
0015 #include <linux/export.h>
0016 #include <linux/stat.h>
0017 #include <linux/slab.h>
0018 #include <linux/random.h>
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 const void *kobject_namespace(struct kobject *kobj)
0029 {
0030 const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj);
0031
0032 if (!ns_ops || ns_ops->type == KOBJ_NS_TYPE_NONE)
0033 return NULL;
0034
0035 return kobj->ktype->namespace(kobj);
0036 }
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 void kobject_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
0049 {
0050 *uid = GLOBAL_ROOT_UID;
0051 *gid = GLOBAL_ROOT_GID;
0052
0053 if (kobj->ktype->get_ownership)
0054 kobj->ktype->get_ownership(kobj, uid, gid);
0055 }
0056
0057 static int create_dir(struct kobject *kobj)
0058 {
0059 const struct kobj_type *ktype = get_ktype(kobj);
0060 const struct kobj_ns_type_operations *ops;
0061 int error;
0062
0063 error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
0064 if (error)
0065 return error;
0066
0067 if (ktype) {
0068 error = sysfs_create_groups(kobj, ktype->default_groups);
0069 if (error) {
0070 sysfs_remove_dir(kobj);
0071 return error;
0072 }
0073 }
0074
0075
0076
0077
0078
0079 sysfs_get(kobj->sd);
0080
0081
0082
0083
0084
0085 ops = kobj_child_ns_ops(kobj);
0086 if (ops) {
0087 BUG_ON(ops->type <= KOBJ_NS_TYPE_NONE);
0088 BUG_ON(ops->type >= KOBJ_NS_TYPES);
0089 BUG_ON(!kobj_ns_type_registered(ops->type));
0090
0091 sysfs_enable_ns(kobj->sd);
0092 }
0093
0094 return 0;
0095 }
0096
0097 static int get_kobj_path_length(struct kobject *kobj)
0098 {
0099 int length = 1;
0100 struct kobject *parent = kobj;
0101
0102
0103
0104
0105
0106 do {
0107 if (kobject_name(parent) == NULL)
0108 return 0;
0109 length += strlen(kobject_name(parent)) + 1;
0110 parent = parent->parent;
0111 } while (parent);
0112 return length;
0113 }
0114
0115 static void fill_kobj_path(struct kobject *kobj, char *path, int length)
0116 {
0117 struct kobject *parent;
0118
0119 --length;
0120 for (parent = kobj; parent; parent = parent->parent) {
0121 int cur = strlen(kobject_name(parent));
0122
0123 length -= cur;
0124 memcpy(path + length, kobject_name(parent), cur);
0125 *(path + --length) = '/';
0126 }
0127
0128 pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj),
0129 kobj, __func__, path);
0130 }
0131
0132
0133
0134
0135
0136
0137
0138
0139 char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
0140 {
0141 char *path;
0142 int len;
0143
0144 len = get_kobj_path_length(kobj);
0145 if (len == 0)
0146 return NULL;
0147 path = kzalloc(len, gfp_mask);
0148 if (!path)
0149 return NULL;
0150 fill_kobj_path(kobj, path, len);
0151
0152 return path;
0153 }
0154 EXPORT_SYMBOL_GPL(kobject_get_path);
0155
0156
0157 static void kobj_kset_join(struct kobject *kobj)
0158 {
0159 if (!kobj->kset)
0160 return;
0161
0162 kset_get(kobj->kset);
0163 spin_lock(&kobj->kset->list_lock);
0164 list_add_tail(&kobj->entry, &kobj->kset->list);
0165 spin_unlock(&kobj->kset->list_lock);
0166 }
0167
0168
0169 static void kobj_kset_leave(struct kobject *kobj)
0170 {
0171 if (!kobj->kset)
0172 return;
0173
0174 spin_lock(&kobj->kset->list_lock);
0175 list_del_init(&kobj->entry);
0176 spin_unlock(&kobj->kset->list_lock);
0177 kset_put(kobj->kset);
0178 }
0179
0180 static void kobject_init_internal(struct kobject *kobj)
0181 {
0182 if (!kobj)
0183 return;
0184 kref_init(&kobj->kref);
0185 INIT_LIST_HEAD(&kobj->entry);
0186 kobj->state_in_sysfs = 0;
0187 kobj->state_add_uevent_sent = 0;
0188 kobj->state_remove_uevent_sent = 0;
0189 kobj->state_initialized = 1;
0190 }
0191
0192
0193 static int kobject_add_internal(struct kobject *kobj)
0194 {
0195 int error = 0;
0196 struct kobject *parent;
0197
0198 if (!kobj)
0199 return -ENOENT;
0200
0201 if (!kobj->name || !kobj->name[0]) {
0202 WARN(1,
0203 "kobject: (%p): attempted to be registered with empty name!\n",
0204 kobj);
0205 return -EINVAL;
0206 }
0207
0208 parent = kobject_get(kobj->parent);
0209
0210
0211 if (kobj->kset) {
0212 if (!parent)
0213 parent = kobject_get(&kobj->kset->kobj);
0214 kobj_kset_join(kobj);
0215 kobj->parent = parent;
0216 }
0217
0218 pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
0219 kobject_name(kobj), kobj, __func__,
0220 parent ? kobject_name(parent) : "<NULL>",
0221 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
0222
0223 error = create_dir(kobj);
0224 if (error) {
0225 kobj_kset_leave(kobj);
0226 kobject_put(parent);
0227 kobj->parent = NULL;
0228
0229
0230 if (error == -EEXIST)
0231 pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
0232 __func__, kobject_name(kobj));
0233 else
0234 pr_err("%s failed for %s (error: %d parent: %s)\n",
0235 __func__, kobject_name(kobj), error,
0236 parent ? kobject_name(parent) : "'none'");
0237 } else
0238 kobj->state_in_sysfs = 1;
0239
0240 return error;
0241 }
0242
0243
0244
0245
0246
0247
0248
0249 int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
0250 va_list vargs)
0251 {
0252 const char *s;
0253
0254 if (kobj->name && !fmt)
0255 return 0;
0256
0257 s = kvasprintf_const(GFP_KERNEL, fmt, vargs);
0258 if (!s)
0259 return -ENOMEM;
0260
0261
0262
0263
0264
0265
0266
0267 if (strchr(s, '/')) {
0268 char *t;
0269
0270 t = kstrdup(s, GFP_KERNEL);
0271 kfree_const(s);
0272 if (!t)
0273 return -ENOMEM;
0274 strreplace(t, '/', '!');
0275 s = t;
0276 }
0277 kfree_const(kobj->name);
0278 kobj->name = s;
0279
0280 return 0;
0281 }
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
0293 {
0294 va_list vargs;
0295 int retval;
0296
0297 va_start(vargs, fmt);
0298 retval = kobject_set_name_vargs(kobj, fmt, vargs);
0299 va_end(vargs);
0300
0301 return retval;
0302 }
0303 EXPORT_SYMBOL(kobject_set_name);
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 void kobject_init(struct kobject *kobj, const struct kobj_type *ktype)
0318 {
0319 char *err_str;
0320
0321 if (!kobj) {
0322 err_str = "invalid kobject pointer!";
0323 goto error;
0324 }
0325 if (!ktype) {
0326 err_str = "must have a ktype to be initialized properly!\n";
0327 goto error;
0328 }
0329 if (kobj->state_initialized) {
0330
0331 pr_err("kobject (%p): tried to init an initialized object, something is seriously wrong.\n",
0332 kobj);
0333 dump_stack();
0334 }
0335
0336 kobject_init_internal(kobj);
0337 kobj->ktype = ktype;
0338 return;
0339
0340 error:
0341 pr_err("kobject (%p): %s\n", kobj, err_str);
0342 dump_stack();
0343 }
0344 EXPORT_SYMBOL(kobject_init);
0345
0346 static __printf(3, 0) int kobject_add_varg(struct kobject *kobj,
0347 struct kobject *parent,
0348 const char *fmt, va_list vargs)
0349 {
0350 int retval;
0351
0352 retval = kobject_set_name_vargs(kobj, fmt, vargs);
0353 if (retval) {
0354 pr_err("kobject: can not set name properly!\n");
0355 return retval;
0356 }
0357 kobj->parent = parent;
0358 return kobject_add_internal(kobj);
0359 }
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394 int kobject_add(struct kobject *kobj, struct kobject *parent,
0395 const char *fmt, ...)
0396 {
0397 va_list args;
0398 int retval;
0399
0400 if (!kobj)
0401 return -EINVAL;
0402
0403 if (!kobj->state_initialized) {
0404 pr_err("kobject '%s' (%p): tried to add an uninitialized object, something is seriously wrong.\n",
0405 kobject_name(kobj), kobj);
0406 dump_stack();
0407 return -EINVAL;
0408 }
0409 va_start(args, fmt);
0410 retval = kobject_add_varg(kobj, parent, fmt, args);
0411 va_end(args);
0412
0413 return retval;
0414 }
0415 EXPORT_SYMBOL(kobject_add);
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432 int kobject_init_and_add(struct kobject *kobj, const struct kobj_type *ktype,
0433 struct kobject *parent, const char *fmt, ...)
0434 {
0435 va_list args;
0436 int retval;
0437
0438 kobject_init(kobj, ktype);
0439
0440 va_start(args, fmt);
0441 retval = kobject_add_varg(kobj, parent, fmt, args);
0442 va_end(args);
0443
0444 return retval;
0445 }
0446 EXPORT_SYMBOL_GPL(kobject_init_and_add);
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458 int kobject_rename(struct kobject *kobj, const char *new_name)
0459 {
0460 int error = 0;
0461 const char *devpath = NULL;
0462 const char *dup_name = NULL, *name;
0463 char *devpath_string = NULL;
0464 char *envp[2];
0465
0466 kobj = kobject_get(kobj);
0467 if (!kobj)
0468 return -EINVAL;
0469 if (!kobj->parent) {
0470 kobject_put(kobj);
0471 return -EINVAL;
0472 }
0473
0474 devpath = kobject_get_path(kobj, GFP_KERNEL);
0475 if (!devpath) {
0476 error = -ENOMEM;
0477 goto out;
0478 }
0479 devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
0480 if (!devpath_string) {
0481 error = -ENOMEM;
0482 goto out;
0483 }
0484 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
0485 envp[0] = devpath_string;
0486 envp[1] = NULL;
0487
0488 name = dup_name = kstrdup_const(new_name, GFP_KERNEL);
0489 if (!name) {
0490 error = -ENOMEM;
0491 goto out;
0492 }
0493
0494 error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
0495 if (error)
0496 goto out;
0497
0498
0499 dup_name = kobj->name;
0500 kobj->name = name;
0501
0502
0503
0504
0505 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
0506
0507 out:
0508 kfree_const(dup_name);
0509 kfree(devpath_string);
0510 kfree(devpath);
0511 kobject_put(kobj);
0512
0513 return error;
0514 }
0515 EXPORT_SYMBOL_GPL(kobject_rename);
0516
0517
0518
0519
0520
0521
0522 int kobject_move(struct kobject *kobj, struct kobject *new_parent)
0523 {
0524 int error;
0525 struct kobject *old_parent;
0526 const char *devpath = NULL;
0527 char *devpath_string = NULL;
0528 char *envp[2];
0529
0530 kobj = kobject_get(kobj);
0531 if (!kobj)
0532 return -EINVAL;
0533 new_parent = kobject_get(new_parent);
0534 if (!new_parent) {
0535 if (kobj->kset)
0536 new_parent = kobject_get(&kobj->kset->kobj);
0537 }
0538
0539
0540 devpath = kobject_get_path(kobj, GFP_KERNEL);
0541 if (!devpath) {
0542 error = -ENOMEM;
0543 goto out;
0544 }
0545 devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
0546 if (!devpath_string) {
0547 error = -ENOMEM;
0548 goto out;
0549 }
0550 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
0551 envp[0] = devpath_string;
0552 envp[1] = NULL;
0553 error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
0554 if (error)
0555 goto out;
0556 old_parent = kobj->parent;
0557 kobj->parent = new_parent;
0558 new_parent = NULL;
0559 kobject_put(old_parent);
0560 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
0561 out:
0562 kobject_put(new_parent);
0563 kobject_put(kobj);
0564 kfree(devpath_string);
0565 kfree(devpath);
0566 return error;
0567 }
0568 EXPORT_SYMBOL_GPL(kobject_move);
0569
0570 static void __kobject_del(struct kobject *kobj)
0571 {
0572 struct kernfs_node *sd;
0573 const struct kobj_type *ktype;
0574
0575 sd = kobj->sd;
0576 ktype = get_ktype(kobj);
0577
0578 if (ktype)
0579 sysfs_remove_groups(kobj, ktype->default_groups);
0580
0581
0582 if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) {
0583 pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n",
0584 kobject_name(kobj), kobj);
0585 kobject_uevent(kobj, KOBJ_REMOVE);
0586 }
0587
0588 sysfs_remove_dir(kobj);
0589 sysfs_put(sd);
0590
0591 kobj->state_in_sysfs = 0;
0592 kobj_kset_leave(kobj);
0593 kobj->parent = NULL;
0594 }
0595
0596
0597
0598
0599
0600
0601
0602
0603 void kobject_del(struct kobject *kobj)
0604 {
0605 struct kobject *parent;
0606
0607 if (!kobj)
0608 return;
0609
0610 parent = kobj->parent;
0611 __kobject_del(kobj);
0612 kobject_put(parent);
0613 }
0614 EXPORT_SYMBOL(kobject_del);
0615
0616
0617
0618
0619
0620 struct kobject *kobject_get(struct kobject *kobj)
0621 {
0622 if (kobj) {
0623 if (!kobj->state_initialized)
0624 WARN(1, KERN_WARNING
0625 "kobject: '%s' (%p): is not initialized, yet kobject_get() is being called.\n",
0626 kobject_name(kobj), kobj);
0627 kref_get(&kobj->kref);
0628 }
0629 return kobj;
0630 }
0631 EXPORT_SYMBOL(kobject_get);
0632
0633 struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
0634 {
0635 if (!kobj)
0636 return NULL;
0637 if (!kref_get_unless_zero(&kobj->kref))
0638 kobj = NULL;
0639 return kobj;
0640 }
0641 EXPORT_SYMBOL(kobject_get_unless_zero);
0642
0643
0644
0645
0646
0647 static void kobject_cleanup(struct kobject *kobj)
0648 {
0649 struct kobject *parent = kobj->parent;
0650 const struct kobj_type *t = get_ktype(kobj);
0651 const char *name = kobj->name;
0652
0653 pr_debug("kobject: '%s' (%p): %s, parent %p\n",
0654 kobject_name(kobj), kobj, __func__, kobj->parent);
0655
0656 if (t && !t->release)
0657 pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed. See Documentation/core-api/kobject.rst.\n",
0658 kobject_name(kobj), kobj);
0659
0660
0661 if (kobj->state_in_sysfs) {
0662 pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n",
0663 kobject_name(kobj), kobj);
0664 __kobject_del(kobj);
0665 } else {
0666
0667 parent = NULL;
0668 }
0669
0670 if (t && t->release) {
0671 pr_debug("kobject: '%s' (%p): calling ktype release\n",
0672 kobject_name(kobj), kobj);
0673 t->release(kobj);
0674 }
0675
0676
0677 if (name) {
0678 pr_debug("kobject: '%s': free name\n", name);
0679 kfree_const(name);
0680 }
0681
0682 kobject_put(parent);
0683 }
0684
0685 #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
0686 static void kobject_delayed_cleanup(struct work_struct *work)
0687 {
0688 kobject_cleanup(container_of(to_delayed_work(work),
0689 struct kobject, release));
0690 }
0691 #endif
0692
0693 static void kobject_release(struct kref *kref)
0694 {
0695 struct kobject *kobj = container_of(kref, struct kobject, kref);
0696 #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
0697 unsigned long delay = HZ + HZ * (get_random_int() & 0x3);
0698 pr_info("kobject: '%s' (%p): %s, parent %p (delayed %ld)\n",
0699 kobject_name(kobj), kobj, __func__, kobj->parent, delay);
0700 INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
0701
0702 schedule_delayed_work(&kobj->release, delay);
0703 #else
0704 kobject_cleanup(kobj);
0705 #endif
0706 }
0707
0708
0709
0710
0711
0712
0713
0714 void kobject_put(struct kobject *kobj)
0715 {
0716 if (kobj) {
0717 if (!kobj->state_initialized)
0718 WARN(1, KERN_WARNING
0719 "kobject: '%s' (%p): is not initialized, yet kobject_put() is being called.\n",
0720 kobject_name(kobj), kobj);
0721 kref_put(&kobj->kref, kobject_release);
0722 }
0723 }
0724 EXPORT_SYMBOL(kobject_put);
0725
0726 static void dynamic_kobj_release(struct kobject *kobj)
0727 {
0728 pr_debug("kobject: (%p): %s\n", kobj, __func__);
0729 kfree(kobj);
0730 }
0731
0732 static struct kobj_type dynamic_kobj_ktype = {
0733 .release = dynamic_kobj_release,
0734 .sysfs_ops = &kobj_sysfs_ops,
0735 };
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748 static struct kobject *kobject_create(void)
0749 {
0750 struct kobject *kobj;
0751
0752 kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
0753 if (!kobj)
0754 return NULL;
0755
0756 kobject_init(kobj, &dynamic_kobj_ktype);
0757 return kobj;
0758 }
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773 struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
0774 {
0775 struct kobject *kobj;
0776 int retval;
0777
0778 kobj = kobject_create();
0779 if (!kobj)
0780 return NULL;
0781
0782 retval = kobject_add(kobj, parent, "%s", name);
0783 if (retval) {
0784 pr_warn("%s: kobject_add error: %d\n", __func__, retval);
0785 kobject_put(kobj);
0786 kobj = NULL;
0787 }
0788 return kobj;
0789 }
0790 EXPORT_SYMBOL_GPL(kobject_create_and_add);
0791
0792
0793
0794
0795
0796 void kset_init(struct kset *k)
0797 {
0798 kobject_init_internal(&k->kobj);
0799 INIT_LIST_HEAD(&k->list);
0800 spin_lock_init(&k->list_lock);
0801 }
0802
0803
0804 static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,
0805 char *buf)
0806 {
0807 struct kobj_attribute *kattr;
0808 ssize_t ret = -EIO;
0809
0810 kattr = container_of(attr, struct kobj_attribute, attr);
0811 if (kattr->show)
0812 ret = kattr->show(kobj, kattr, buf);
0813 return ret;
0814 }
0815
0816 static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,
0817 const char *buf, size_t count)
0818 {
0819 struct kobj_attribute *kattr;
0820 ssize_t ret = -EIO;
0821
0822 kattr = container_of(attr, struct kobj_attribute, attr);
0823 if (kattr->store)
0824 ret = kattr->store(kobj, kattr, buf, count);
0825 return ret;
0826 }
0827
0828 const struct sysfs_ops kobj_sysfs_ops = {
0829 .show = kobj_attr_show,
0830 .store = kobj_attr_store,
0831 };
0832 EXPORT_SYMBOL_GPL(kobj_sysfs_ops);
0833
0834
0835
0836
0837
0838 int kset_register(struct kset *k)
0839 {
0840 int err;
0841
0842 if (!k)
0843 return -EINVAL;
0844
0845 kset_init(k);
0846 err = kobject_add_internal(&k->kobj);
0847 if (err)
0848 return err;
0849 kobject_uevent(&k->kobj, KOBJ_ADD);
0850 return 0;
0851 }
0852 EXPORT_SYMBOL(kset_register);
0853
0854
0855
0856
0857
0858 void kset_unregister(struct kset *k)
0859 {
0860 if (!k)
0861 return;
0862 kobject_del(&k->kobj);
0863 kobject_put(&k->kobj);
0864 }
0865 EXPORT_SYMBOL(kset_unregister);
0866
0867
0868
0869
0870
0871
0872
0873
0874
0875
0876 struct kobject *kset_find_obj(struct kset *kset, const char *name)
0877 {
0878 struct kobject *k;
0879 struct kobject *ret = NULL;
0880
0881 spin_lock(&kset->list_lock);
0882
0883 list_for_each_entry(k, &kset->list, entry) {
0884 if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
0885 ret = kobject_get_unless_zero(k);
0886 break;
0887 }
0888 }
0889
0890 spin_unlock(&kset->list_lock);
0891 return ret;
0892 }
0893 EXPORT_SYMBOL_GPL(kset_find_obj);
0894
0895 static void kset_release(struct kobject *kobj)
0896 {
0897 struct kset *kset = container_of(kobj, struct kset, kobj);
0898 pr_debug("kobject: '%s' (%p): %s\n",
0899 kobject_name(kobj), kobj, __func__);
0900 kfree(kset);
0901 }
0902
0903 static void kset_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
0904 {
0905 if (kobj->parent)
0906 kobject_get_ownership(kobj->parent, uid, gid);
0907 }
0908
0909 static struct kobj_type kset_ktype = {
0910 .sysfs_ops = &kobj_sysfs_ops,
0911 .release = kset_release,
0912 .get_ownership = kset_get_ownership,
0913 };
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930 static struct kset *kset_create(const char *name,
0931 const struct kset_uevent_ops *uevent_ops,
0932 struct kobject *parent_kobj)
0933 {
0934 struct kset *kset;
0935 int retval;
0936
0937 kset = kzalloc(sizeof(*kset), GFP_KERNEL);
0938 if (!kset)
0939 return NULL;
0940 retval = kobject_set_name(&kset->kobj, "%s", name);
0941 if (retval) {
0942 kfree(kset);
0943 return NULL;
0944 }
0945 kset->uevent_ops = uevent_ops;
0946 kset->kobj.parent = parent_kobj;
0947
0948
0949
0950
0951
0952
0953 kset->kobj.ktype = &kset_ktype;
0954 kset->kobj.kset = NULL;
0955
0956 return kset;
0957 }
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973 struct kset *kset_create_and_add(const char *name,
0974 const struct kset_uevent_ops *uevent_ops,
0975 struct kobject *parent_kobj)
0976 {
0977 struct kset *kset;
0978 int error;
0979
0980 kset = kset_create(name, uevent_ops, parent_kobj);
0981 if (!kset)
0982 return NULL;
0983 error = kset_register(kset);
0984 if (error) {
0985 kfree(kset);
0986 return NULL;
0987 }
0988 return kset;
0989 }
0990 EXPORT_SYMBOL_GPL(kset_create_and_add);
0991
0992
0993 static DEFINE_SPINLOCK(kobj_ns_type_lock);
0994 static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES];
0995
0996 int kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
0997 {
0998 enum kobj_ns_type type = ops->type;
0999 int error;
1000
1001 spin_lock(&kobj_ns_type_lock);
1002
1003 error = -EINVAL;
1004 if (type >= KOBJ_NS_TYPES)
1005 goto out;
1006
1007 error = -EINVAL;
1008 if (type <= KOBJ_NS_TYPE_NONE)
1009 goto out;
1010
1011 error = -EBUSY;
1012 if (kobj_ns_ops_tbl[type])
1013 goto out;
1014
1015 error = 0;
1016 kobj_ns_ops_tbl[type] = ops;
1017
1018 out:
1019 spin_unlock(&kobj_ns_type_lock);
1020 return error;
1021 }
1022
1023 int kobj_ns_type_registered(enum kobj_ns_type type)
1024 {
1025 int registered = 0;
1026
1027 spin_lock(&kobj_ns_type_lock);
1028 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES))
1029 registered = kobj_ns_ops_tbl[type] != NULL;
1030 spin_unlock(&kobj_ns_type_lock);
1031
1032 return registered;
1033 }
1034
1035 const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent)
1036 {
1037 const struct kobj_ns_type_operations *ops = NULL;
1038
1039 if (parent && parent->ktype && parent->ktype->child_ns_type)
1040 ops = parent->ktype->child_ns_type(parent);
1041
1042 return ops;
1043 }
1044
1045 const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
1046 {
1047 return kobj_child_ns_ops(kobj->parent);
1048 }
1049
1050 bool kobj_ns_current_may_mount(enum kobj_ns_type type)
1051 {
1052 bool may_mount = true;
1053
1054 spin_lock(&kobj_ns_type_lock);
1055 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1056 kobj_ns_ops_tbl[type])
1057 may_mount = kobj_ns_ops_tbl[type]->current_may_mount();
1058 spin_unlock(&kobj_ns_type_lock);
1059
1060 return may_mount;
1061 }
1062
1063 void *kobj_ns_grab_current(enum kobj_ns_type type)
1064 {
1065 void *ns = NULL;
1066
1067 spin_lock(&kobj_ns_type_lock);
1068 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1069 kobj_ns_ops_tbl[type])
1070 ns = kobj_ns_ops_tbl[type]->grab_current_ns();
1071 spin_unlock(&kobj_ns_type_lock);
1072
1073 return ns;
1074 }
1075 EXPORT_SYMBOL_GPL(kobj_ns_grab_current);
1076
1077 const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk)
1078 {
1079 const void *ns = NULL;
1080
1081 spin_lock(&kobj_ns_type_lock);
1082 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1083 kobj_ns_ops_tbl[type])
1084 ns = kobj_ns_ops_tbl[type]->netlink_ns(sk);
1085 spin_unlock(&kobj_ns_type_lock);
1086
1087 return ns;
1088 }
1089
1090 const void *kobj_ns_initial(enum kobj_ns_type type)
1091 {
1092 const void *ns = NULL;
1093
1094 spin_lock(&kobj_ns_type_lock);
1095 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1096 kobj_ns_ops_tbl[type])
1097 ns = kobj_ns_ops_tbl[type]->initial_ns();
1098 spin_unlock(&kobj_ns_type_lock);
1099
1100 return ns;
1101 }
1102
1103 void kobj_ns_drop(enum kobj_ns_type type, void *ns)
1104 {
1105 spin_lock(&kobj_ns_type_lock);
1106 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1107 kobj_ns_ops_tbl[type] && kobj_ns_ops_tbl[type]->drop_ns)
1108 kobj_ns_ops_tbl[type]->drop_ns(ns);
1109 spin_unlock(&kobj_ns_type_lock);
1110 }
1111 EXPORT_SYMBOL_GPL(kobj_ns_drop);