1
2
3
4
5
6
7
8
9
10
11
12
13#include <linux/kobject.h>
14#include <linux/string.h>
15#include <linux/export.h>
16#include <linux/stat.h>
17#include <linux/slab.h>
18#include <linux/random.h>
19
20
21
22
23
24
25
26
27
28const void *kobject_namespace(struct kobject *kobj)
29{
30 const struct kobj_ns_type_operations *ns_ops = kobj_ns_ops(kobj);
31
32 if (!ns_ops || ns_ops->type == KOBJ_NS_TYPE_NONE)
33 return NULL;
34
35 return kobj->ktype->namespace(kobj);
36}
37
38
39
40
41
42
43
44
45
46
47
48void kobject_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
49{
50 *uid = GLOBAL_ROOT_UID;
51 *gid = GLOBAL_ROOT_GID;
52
53 if (kobj->ktype->get_ownership)
54 kobj->ktype->get_ownership(kobj, uid, gid);
55}
56
57
58
59
60
61
62
63
64
65
66static int populate_dir(struct kobject *kobj)
67{
68 struct kobj_type *t = get_ktype(kobj);
69 struct attribute *attr;
70 int error = 0;
71 int i;
72
73 if (t && t->default_attrs) {
74 for (i = 0; (attr = t->default_attrs[i]) != NULL; i++) {
75 error = sysfs_create_file(kobj, attr);
76 if (error)
77 break;
78 }
79 }
80 return error;
81}
82
83static int create_dir(struct kobject *kobj)
84{
85 const struct kobj_type *ktype = get_ktype(kobj);
86 const struct kobj_ns_type_operations *ops;
87 int error;
88
89 error = sysfs_create_dir_ns(kobj, kobject_namespace(kobj));
90 if (error)
91 return error;
92
93 error = populate_dir(kobj);
94 if (error) {
95 sysfs_remove_dir(kobj);
96 return error;
97 }
98
99 if (ktype) {
100 error = sysfs_create_groups(kobj, ktype->default_groups);
101 if (error) {
102 sysfs_remove_dir(kobj);
103 return error;
104 }
105 }
106
107
108
109
110
111 sysfs_get(kobj->sd);
112
113
114
115
116
117 ops = kobj_child_ns_ops(kobj);
118 if (ops) {
119 BUG_ON(ops->type <= KOBJ_NS_TYPE_NONE);
120 BUG_ON(ops->type >= KOBJ_NS_TYPES);
121 BUG_ON(!kobj_ns_type_registered(ops->type));
122
123 sysfs_enable_ns(kobj->sd);
124 }
125
126 return 0;
127}
128
129static int get_kobj_path_length(struct kobject *kobj)
130{
131 int length = 1;
132 struct kobject *parent = kobj;
133
134
135
136
137
138 do {
139 if (kobject_name(parent) == NULL)
140 return 0;
141 length += strlen(kobject_name(parent)) + 1;
142 parent = parent->parent;
143 } while (parent);
144 return length;
145}
146
147static void fill_kobj_path(struct kobject *kobj, char *path, int length)
148{
149 struct kobject *parent;
150
151 --length;
152 for (parent = kobj; parent; parent = parent->parent) {
153 int cur = strlen(kobject_name(parent));
154
155 length -= cur;
156 memcpy(path + length, kobject_name(parent), cur);
157 *(path + --length) = '/';
158 }
159
160 pr_debug("kobject: '%s' (%p): %s: path = '%s'\n", kobject_name(kobj),
161 kobj, __func__, path);
162}
163
164
165
166
167
168
169
170
171char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
172{
173 char *path;
174 int len;
175
176 len = get_kobj_path_length(kobj);
177 if (len == 0)
178 return NULL;
179 path = kzalloc(len, gfp_mask);
180 if (!path)
181 return NULL;
182 fill_kobj_path(kobj, path, len);
183
184 return path;
185}
186EXPORT_SYMBOL_GPL(kobject_get_path);
187
188
189static void kobj_kset_join(struct kobject *kobj)
190{
191 if (!kobj->kset)
192 return;
193
194 kset_get(kobj->kset);
195 spin_lock(&kobj->kset->list_lock);
196 list_add_tail(&kobj->entry, &kobj->kset->list);
197 spin_unlock(&kobj->kset->list_lock);
198}
199
200
201static void kobj_kset_leave(struct kobject *kobj)
202{
203 if (!kobj->kset)
204 return;
205
206 spin_lock(&kobj->kset->list_lock);
207 list_del_init(&kobj->entry);
208 spin_unlock(&kobj->kset->list_lock);
209 kset_put(kobj->kset);
210}
211
212static void kobject_init_internal(struct kobject *kobj)
213{
214 if (!kobj)
215 return;
216 kref_init(&kobj->kref);
217 INIT_LIST_HEAD(&kobj->entry);
218 kobj->state_in_sysfs = 0;
219 kobj->state_add_uevent_sent = 0;
220 kobj->state_remove_uevent_sent = 0;
221 kobj->state_initialized = 1;
222}
223
224
225static int kobject_add_internal(struct kobject *kobj)
226{
227 int error = 0;
228 struct kobject *parent;
229
230 if (!kobj)
231 return -ENOENT;
232
233 if (!kobj->name || !kobj->name[0]) {
234 WARN(1,
235 "kobject: (%p): attempted to be registered with empty name!\n",
236 kobj);
237 return -EINVAL;
238 }
239
240 parent = kobject_get(kobj->parent);
241
242
243 if (kobj->kset) {
244 if (!parent)
245 parent = kobject_get(&kobj->kset->kobj);
246 kobj_kset_join(kobj);
247 kobj->parent = parent;
248 }
249
250 pr_debug("kobject: '%s' (%p): %s: parent: '%s', set: '%s'\n",
251 kobject_name(kobj), kobj, __func__,
252 parent ? kobject_name(parent) : "<NULL>",
253 kobj->kset ? kobject_name(&kobj->kset->kobj) : "<NULL>");
254
255 error = create_dir(kobj);
256 if (error) {
257 kobj_kset_leave(kobj);
258 kobject_put(parent);
259 kobj->parent = NULL;
260
261
262 if (error == -EEXIST)
263 pr_err("%s failed for %s with -EEXIST, don't try to register things with the same name in the same directory.\n",
264 __func__, kobject_name(kobj));
265 else
266 pr_err("%s failed for %s (error: %d parent: %s)\n",
267 __func__, kobject_name(kobj), error,
268 parent ? kobject_name(parent) : "'none'");
269 } else
270 kobj->state_in_sysfs = 1;
271
272 return error;
273}
274
275
276
277
278
279
280
281int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
282 va_list vargs)
283{
284 const char *s;
285
286 if (kobj->name && !fmt)
287 return 0;
288
289 s = kvasprintf_const(GFP_KERNEL, fmt, vargs);
290 if (!s)
291 return -ENOMEM;
292
293
294
295
296
297
298
299 if (strchr(s, '/')) {
300 char *t;
301
302 t = kstrdup(s, GFP_KERNEL);
303 kfree_const(s);
304 if (!t)
305 return -ENOMEM;
306 strreplace(t, '/', '!');
307 s = t;
308 }
309 kfree_const(kobj->name);
310 kobj->name = s;
311
312 return 0;
313}
314
315
316
317
318
319
320
321
322
323
324int kobject_set_name(struct kobject *kobj, const char *fmt, ...)
325{
326 va_list vargs;
327 int retval;
328
329 va_start(vargs, fmt);
330 retval = kobject_set_name_vargs(kobj, fmt, vargs);
331 va_end(vargs);
332
333 return retval;
334}
335EXPORT_SYMBOL(kobject_set_name);
336
337
338
339
340
341
342
343
344
345
346
347
348
349void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
350{
351 char *err_str;
352
353 if (!kobj) {
354 err_str = "invalid kobject pointer!";
355 goto error;
356 }
357 if (!ktype) {
358 err_str = "must have a ktype to be initialized properly!\n";
359 goto error;
360 }
361 if (kobj->state_initialized) {
362
363 pr_err("kobject (%p): tried to init an initialized object, something is seriously wrong.\n",
364 kobj);
365 dump_stack();
366 }
367
368 kobject_init_internal(kobj);
369 kobj->ktype = ktype;
370 return;
371
372error:
373 pr_err("kobject (%p): %s\n", kobj, err_str);
374 dump_stack();
375}
376EXPORT_SYMBOL(kobject_init);
377
378static __printf(3, 0) int kobject_add_varg(struct kobject *kobj,
379 struct kobject *parent,
380 const char *fmt, va_list vargs)
381{
382 int retval;
383
384 retval = kobject_set_name_vargs(kobj, fmt, vargs);
385 if (retval) {
386 pr_err("kobject: can not set name properly!\n");
387 return retval;
388 }
389 kobj->parent = parent;
390 return kobject_add_internal(kobj);
391}
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426int kobject_add(struct kobject *kobj, struct kobject *parent,
427 const char *fmt, ...)
428{
429 va_list args;
430 int retval;
431
432 if (!kobj)
433 return -EINVAL;
434
435 if (!kobj->state_initialized) {
436 pr_err("kobject '%s' (%p): tried to add an uninitialized object, something is seriously wrong.\n",
437 kobject_name(kobj), kobj);
438 dump_stack();
439 return -EINVAL;
440 }
441 va_start(args, fmt);
442 retval = kobject_add_varg(kobj, parent, fmt, args);
443 va_end(args);
444
445 return retval;
446}
447EXPORT_SYMBOL(kobject_add);
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
465 struct kobject *parent, const char *fmt, ...)
466{
467 va_list args;
468 int retval;
469
470 kobject_init(kobj, ktype);
471
472 va_start(args, fmt);
473 retval = kobject_add_varg(kobj, parent, fmt, args);
474 va_end(args);
475
476 return retval;
477}
478EXPORT_SYMBOL_GPL(kobject_init_and_add);
479
480
481
482
483
484
485
486
487
488
489
490int kobject_rename(struct kobject *kobj, const char *new_name)
491{
492 int error = 0;
493 const char *devpath = NULL;
494 const char *dup_name = NULL, *name;
495 char *devpath_string = NULL;
496 char *envp[2];
497
498 kobj = kobject_get(kobj);
499 if (!kobj)
500 return -EINVAL;
501 if (!kobj->parent) {
502 kobject_put(kobj);
503 return -EINVAL;
504 }
505
506 devpath = kobject_get_path(kobj, GFP_KERNEL);
507 if (!devpath) {
508 error = -ENOMEM;
509 goto out;
510 }
511 devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
512 if (!devpath_string) {
513 error = -ENOMEM;
514 goto out;
515 }
516 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
517 envp[0] = devpath_string;
518 envp[1] = NULL;
519
520 name = dup_name = kstrdup_const(new_name, GFP_KERNEL);
521 if (!name) {
522 error = -ENOMEM;
523 goto out;
524 }
525
526 error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
527 if (error)
528 goto out;
529
530
531 dup_name = kobj->name;
532 kobj->name = name;
533
534
535
536
537 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
538
539out:
540 kfree_const(dup_name);
541 kfree(devpath_string);
542 kfree(devpath);
543 kobject_put(kobj);
544
545 return error;
546}
547EXPORT_SYMBOL_GPL(kobject_rename);
548
549
550
551
552
553
554int kobject_move(struct kobject *kobj, struct kobject *new_parent)
555{
556 int error;
557 struct kobject *old_parent;
558 const char *devpath = NULL;
559 char *devpath_string = NULL;
560 char *envp[2];
561
562 kobj = kobject_get(kobj);
563 if (!kobj)
564 return -EINVAL;
565 new_parent = kobject_get(new_parent);
566 if (!new_parent) {
567 if (kobj->kset)
568 new_parent = kobject_get(&kobj->kset->kobj);
569 }
570
571
572 devpath = kobject_get_path(kobj, GFP_KERNEL);
573 if (!devpath) {
574 error = -ENOMEM;
575 goto out;
576 }
577 devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
578 if (!devpath_string) {
579 error = -ENOMEM;
580 goto out;
581 }
582 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
583 envp[0] = devpath_string;
584 envp[1] = NULL;
585 error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
586 if (error)
587 goto out;
588 old_parent = kobj->parent;
589 kobj->parent = new_parent;
590 new_parent = NULL;
591 kobject_put(old_parent);
592 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
593out:
594 kobject_put(new_parent);
595 kobject_put(kobj);
596 kfree(devpath_string);
597 kfree(devpath);
598 return error;
599}
600EXPORT_SYMBOL_GPL(kobject_move);
601
602static void __kobject_del(struct kobject *kobj)
603{
604 struct kernfs_node *sd;
605 const struct kobj_type *ktype;
606
607 sd = kobj->sd;
608 ktype = get_ktype(kobj);
609
610 if (ktype)
611 sysfs_remove_groups(kobj, ktype->default_groups);
612
613
614 if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) {
615 pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n",
616 kobject_name(kobj), kobj);
617 kobject_uevent(kobj, KOBJ_REMOVE);
618 }
619
620 sysfs_remove_dir(kobj);
621 sysfs_put(sd);
622
623 kobj->state_in_sysfs = 0;
624 kobj_kset_leave(kobj);
625 kobj->parent = NULL;
626}
627
628
629
630
631
632
633
634
635void kobject_del(struct kobject *kobj)
636{
637 struct kobject *parent;
638
639 if (!kobj)
640 return;
641
642 parent = kobj->parent;
643 __kobject_del(kobj);
644 kobject_put(parent);
645}
646EXPORT_SYMBOL(kobject_del);
647
648
649
650
651
652struct kobject *kobject_get(struct kobject *kobj)
653{
654 if (kobj) {
655 if (!kobj->state_initialized)
656 WARN(1, KERN_WARNING
657 "kobject: '%s' (%p): is not initialized, yet kobject_get() is being called.\n",
658 kobject_name(kobj), kobj);
659 kref_get(&kobj->kref);
660 }
661 return kobj;
662}
663EXPORT_SYMBOL(kobject_get);
664
665struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
666{
667 if (!kobj)
668 return NULL;
669 if (!kref_get_unless_zero(&kobj->kref))
670 kobj = NULL;
671 return kobj;
672}
673EXPORT_SYMBOL(kobject_get_unless_zero);
674
675
676
677
678
679static void kobject_cleanup(struct kobject *kobj)
680{
681 struct kobject *parent = kobj->parent;
682 struct kobj_type *t = get_ktype(kobj);
683 const char *name = kobj->name;
684
685 pr_debug("kobject: '%s' (%p): %s, parent %p\n",
686 kobject_name(kobj), kobj, __func__, kobj->parent);
687
688 if (t && !t->release)
689 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",
690 kobject_name(kobj), kobj);
691
692
693 if (kobj->state_in_sysfs) {
694 pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n",
695 kobject_name(kobj), kobj);
696 __kobject_del(kobj);
697 } else {
698
699 parent = NULL;
700 }
701
702 if (t && t->release) {
703 pr_debug("kobject: '%s' (%p): calling ktype release\n",
704 kobject_name(kobj), kobj);
705 t->release(kobj);
706 }
707
708
709 if (name) {
710 pr_debug("kobject: '%s': free name\n", name);
711 kfree_const(name);
712 }
713
714 kobject_put(parent);
715}
716
717#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
718static void kobject_delayed_cleanup(struct work_struct *work)
719{
720 kobject_cleanup(container_of(to_delayed_work(work),
721 struct kobject, release));
722}
723#endif
724
725static void kobject_release(struct kref *kref)
726{
727 struct kobject *kobj = container_of(kref, struct kobject, kref);
728#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
729 unsigned long delay = HZ + HZ * (get_random_int() & 0x3);
730 pr_info("kobject: '%s' (%p): %s, parent %p (delayed %ld)\n",
731 kobject_name(kobj), kobj, __func__, kobj->parent, delay);
732 INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
733
734 schedule_delayed_work(&kobj->release, delay);
735#else
736 kobject_cleanup(kobj);
737#endif
738}
739
740
741
742
743
744
745
746void kobject_put(struct kobject *kobj)
747{
748 if (kobj) {
749 if (!kobj->state_initialized)
750 WARN(1, KERN_WARNING
751 "kobject: '%s' (%p): is not initialized, yet kobject_put() is being called.\n",
752 kobject_name(kobj), kobj);
753 kref_put(&kobj->kref, kobject_release);
754 }
755}
756EXPORT_SYMBOL(kobject_put);
757
758static void dynamic_kobj_release(struct kobject *kobj)
759{
760 pr_debug("kobject: (%p): %s\n", kobj, __func__);
761 kfree(kobj);
762}
763
764static struct kobj_type dynamic_kobj_ktype = {
765 .release = dynamic_kobj_release,
766 .sysfs_ops = &kobj_sysfs_ops,
767};
768
769
770
771
772
773
774
775
776
777
778
779
780struct kobject *kobject_create(void)
781{
782 struct kobject *kobj;
783
784 kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
785 if (!kobj)
786 return NULL;
787
788 kobject_init(kobj, &dynamic_kobj_ktype);
789 return kobj;
790}
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
806{
807 struct kobject *kobj;
808 int retval;
809
810 kobj = kobject_create();
811 if (!kobj)
812 return NULL;
813
814 retval = kobject_add(kobj, parent, "%s", name);
815 if (retval) {
816 pr_warn("%s: kobject_add error: %d\n", __func__, retval);
817 kobject_put(kobj);
818 kobj = NULL;
819 }
820 return kobj;
821}
822EXPORT_SYMBOL_GPL(kobject_create_and_add);
823
824
825
826
827
828void kset_init(struct kset *k)
829{
830 kobject_init_internal(&k->kobj);
831 INIT_LIST_HEAD(&k->list);
832 spin_lock_init(&k->list_lock);
833}
834
835
836static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,
837 char *buf)
838{
839 struct kobj_attribute *kattr;
840 ssize_t ret = -EIO;
841
842 kattr = container_of(attr, struct kobj_attribute, attr);
843 if (kattr->show)
844 ret = kattr->show(kobj, kattr, buf);
845 return ret;
846}
847
848static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,
849 const char *buf, size_t count)
850{
851 struct kobj_attribute *kattr;
852 ssize_t ret = -EIO;
853
854 kattr = container_of(attr, struct kobj_attribute, attr);
855 if (kattr->store)
856 ret = kattr->store(kobj, kattr, buf, count);
857 return ret;
858}
859
860const struct sysfs_ops kobj_sysfs_ops = {
861 .show = kobj_attr_show,
862 .store = kobj_attr_store,
863};
864EXPORT_SYMBOL_GPL(kobj_sysfs_ops);
865
866
867
868
869
870int kset_register(struct kset *k)
871{
872 int err;
873
874 if (!k)
875 return -EINVAL;
876
877 kset_init(k);
878 err = kobject_add_internal(&k->kobj);
879 if (err)
880 return err;
881 kobject_uevent(&k->kobj, KOBJ_ADD);
882 return 0;
883}
884EXPORT_SYMBOL(kset_register);
885
886
887
888
889
890void kset_unregister(struct kset *k)
891{
892 if (!k)
893 return;
894 kobject_del(&k->kobj);
895 kobject_put(&k->kobj);
896}
897EXPORT_SYMBOL(kset_unregister);
898
899
900
901
902
903
904
905
906
907
908struct kobject *kset_find_obj(struct kset *kset, const char *name)
909{
910 struct kobject *k;
911 struct kobject *ret = NULL;
912
913 spin_lock(&kset->list_lock);
914
915 list_for_each_entry(k, &kset->list, entry) {
916 if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
917 ret = kobject_get_unless_zero(k);
918 break;
919 }
920 }
921
922 spin_unlock(&kset->list_lock);
923 return ret;
924}
925EXPORT_SYMBOL_GPL(kset_find_obj);
926
927static void kset_release(struct kobject *kobj)
928{
929 struct kset *kset = container_of(kobj, struct kset, kobj);
930 pr_debug("kobject: '%s' (%p): %s\n",
931 kobject_name(kobj), kobj, __func__);
932 kfree(kset);
933}
934
935static void kset_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
936{
937 if (kobj->parent)
938 kobject_get_ownership(kobj->parent, uid, gid);
939}
940
941static struct kobj_type kset_ktype = {
942 .sysfs_ops = &kobj_sysfs_ops,
943 .release = kset_release,
944 .get_ownership = kset_get_ownership,
945};
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962static struct kset *kset_create(const char *name,
963 const struct kset_uevent_ops *uevent_ops,
964 struct kobject *parent_kobj)
965{
966 struct kset *kset;
967 int retval;
968
969 kset = kzalloc(sizeof(*kset), GFP_KERNEL);
970 if (!kset)
971 return NULL;
972 retval = kobject_set_name(&kset->kobj, "%s", name);
973 if (retval) {
974 kfree(kset);
975 return NULL;
976 }
977 kset->uevent_ops = uevent_ops;
978 kset->kobj.parent = parent_kobj;
979
980
981
982
983
984
985 kset->kobj.ktype = &kset_ktype;
986 kset->kobj.kset = NULL;
987
988 return kset;
989}
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005struct kset *kset_create_and_add(const char *name,
1006 const struct kset_uevent_ops *uevent_ops,
1007 struct kobject *parent_kobj)
1008{
1009 struct kset *kset;
1010 int error;
1011
1012 kset = kset_create(name, uevent_ops, parent_kobj);
1013 if (!kset)
1014 return NULL;
1015 error = kset_register(kset);
1016 if (error) {
1017 kfree(kset);
1018 return NULL;
1019 }
1020 return kset;
1021}
1022EXPORT_SYMBOL_GPL(kset_create_and_add);
1023
1024
1025static DEFINE_SPINLOCK(kobj_ns_type_lock);
1026static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES];
1027
1028int kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
1029{
1030 enum kobj_ns_type type = ops->type;
1031 int error;
1032
1033 spin_lock(&kobj_ns_type_lock);
1034
1035 error = -EINVAL;
1036 if (type >= KOBJ_NS_TYPES)
1037 goto out;
1038
1039 error = -EINVAL;
1040 if (type <= KOBJ_NS_TYPE_NONE)
1041 goto out;
1042
1043 error = -EBUSY;
1044 if (kobj_ns_ops_tbl[type])
1045 goto out;
1046
1047 error = 0;
1048 kobj_ns_ops_tbl[type] = ops;
1049
1050out:
1051 spin_unlock(&kobj_ns_type_lock);
1052 return error;
1053}
1054
1055int kobj_ns_type_registered(enum kobj_ns_type type)
1056{
1057 int registered = 0;
1058
1059 spin_lock(&kobj_ns_type_lock);
1060 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES))
1061 registered = kobj_ns_ops_tbl[type] != NULL;
1062 spin_unlock(&kobj_ns_type_lock);
1063
1064 return registered;
1065}
1066
1067const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent)
1068{
1069 const struct kobj_ns_type_operations *ops = NULL;
1070
1071 if (parent && parent->ktype && parent->ktype->child_ns_type)
1072 ops = parent->ktype->child_ns_type(parent);
1073
1074 return ops;
1075}
1076
1077const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
1078{
1079 return kobj_child_ns_ops(kobj->parent);
1080}
1081
1082bool kobj_ns_current_may_mount(enum kobj_ns_type type)
1083{
1084 bool may_mount = true;
1085
1086 spin_lock(&kobj_ns_type_lock);
1087 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1088 kobj_ns_ops_tbl[type])
1089 may_mount = kobj_ns_ops_tbl[type]->current_may_mount();
1090 spin_unlock(&kobj_ns_type_lock);
1091
1092 return may_mount;
1093}
1094
1095void *kobj_ns_grab_current(enum kobj_ns_type type)
1096{
1097 void *ns = NULL;
1098
1099 spin_lock(&kobj_ns_type_lock);
1100 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1101 kobj_ns_ops_tbl[type])
1102 ns = kobj_ns_ops_tbl[type]->grab_current_ns();
1103 spin_unlock(&kobj_ns_type_lock);
1104
1105 return ns;
1106}
1107EXPORT_SYMBOL_GPL(kobj_ns_grab_current);
1108
1109const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk)
1110{
1111 const void *ns = NULL;
1112
1113 spin_lock(&kobj_ns_type_lock);
1114 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1115 kobj_ns_ops_tbl[type])
1116 ns = kobj_ns_ops_tbl[type]->netlink_ns(sk);
1117 spin_unlock(&kobj_ns_type_lock);
1118
1119 return ns;
1120}
1121
1122const void *kobj_ns_initial(enum kobj_ns_type type)
1123{
1124 const void *ns = NULL;
1125
1126 spin_lock(&kobj_ns_type_lock);
1127 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1128 kobj_ns_ops_tbl[type])
1129 ns = kobj_ns_ops_tbl[type]->initial_ns();
1130 spin_unlock(&kobj_ns_type_lock);
1131
1132 return ns;
1133}
1134
1135void kobj_ns_drop(enum kobj_ns_type type, void *ns)
1136{
1137 spin_lock(&kobj_ns_type_lock);
1138 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1139 kobj_ns_ops_tbl[type] && kobj_ns_ops_tbl[type]->drop_ns)
1140 kobj_ns_ops_tbl[type]->drop_ns(ns);
1141 spin_unlock(&kobj_ns_type_lock);
1142}
1143EXPORT_SYMBOL_GPL(kobj_ns_drop);
1144