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 return -EINVAL;
503
504 devpath = kobject_get_path(kobj, GFP_KERNEL);
505 if (!devpath) {
506 error = -ENOMEM;
507 goto out;
508 }
509 devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
510 if (!devpath_string) {
511 error = -ENOMEM;
512 goto out;
513 }
514 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
515 envp[0] = devpath_string;
516 envp[1] = NULL;
517
518 name = dup_name = kstrdup_const(new_name, GFP_KERNEL);
519 if (!name) {
520 error = -ENOMEM;
521 goto out;
522 }
523
524 error = sysfs_rename_dir_ns(kobj, new_name, kobject_namespace(kobj));
525 if (error)
526 goto out;
527
528
529 dup_name = kobj->name;
530 kobj->name = name;
531
532
533
534
535 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
536
537out:
538 kfree_const(dup_name);
539 kfree(devpath_string);
540 kfree(devpath);
541 kobject_put(kobj);
542
543 return error;
544}
545EXPORT_SYMBOL_GPL(kobject_rename);
546
547
548
549
550
551
552int kobject_move(struct kobject *kobj, struct kobject *new_parent)
553{
554 int error;
555 struct kobject *old_parent;
556 const char *devpath = NULL;
557 char *devpath_string = NULL;
558 char *envp[2];
559
560 kobj = kobject_get(kobj);
561 if (!kobj)
562 return -EINVAL;
563 new_parent = kobject_get(new_parent);
564 if (!new_parent) {
565 if (kobj->kset)
566 new_parent = kobject_get(&kobj->kset->kobj);
567 }
568
569
570 devpath = kobject_get_path(kobj, GFP_KERNEL);
571 if (!devpath) {
572 error = -ENOMEM;
573 goto out;
574 }
575 devpath_string = kmalloc(strlen(devpath) + 15, GFP_KERNEL);
576 if (!devpath_string) {
577 error = -ENOMEM;
578 goto out;
579 }
580 sprintf(devpath_string, "DEVPATH_OLD=%s", devpath);
581 envp[0] = devpath_string;
582 envp[1] = NULL;
583 error = sysfs_move_dir_ns(kobj, new_parent, kobject_namespace(kobj));
584 if (error)
585 goto out;
586 old_parent = kobj->parent;
587 kobj->parent = new_parent;
588 new_parent = NULL;
589 kobject_put(old_parent);
590 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
591out:
592 kobject_put(new_parent);
593 kobject_put(kobj);
594 kfree(devpath_string);
595 kfree(devpath);
596 return error;
597}
598EXPORT_SYMBOL_GPL(kobject_move);
599
600
601
602
603
604
605
606
607void kobject_del(struct kobject *kobj)
608{
609 struct kernfs_node *sd;
610 const struct kobj_type *ktype;
611
612 if (!kobj)
613 return;
614
615 sd = kobj->sd;
616 ktype = get_ktype(kobj);
617
618 if (ktype)
619 sysfs_remove_groups(kobj, ktype->default_groups);
620
621 sysfs_remove_dir(kobj);
622 sysfs_put(sd);
623
624 kobj->state_in_sysfs = 0;
625 kobj_kset_leave(kobj);
626 kobject_put(kobj->parent);
627 kobj->parent = NULL;
628}
629EXPORT_SYMBOL(kobject_del);
630
631
632
633
634
635struct kobject *kobject_get(struct kobject *kobj)
636{
637 if (kobj) {
638 if (!kobj->state_initialized)
639 WARN(1, KERN_WARNING
640 "kobject: '%s' (%p): is not initialized, yet kobject_get() is being called.\n",
641 kobject_name(kobj), kobj);
642 kref_get(&kobj->kref);
643 }
644 return kobj;
645}
646EXPORT_SYMBOL(kobject_get);
647
648struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
649{
650 if (!kobj)
651 return NULL;
652 if (!kref_get_unless_zero(&kobj->kref))
653 kobj = NULL;
654 return kobj;
655}
656EXPORT_SYMBOL(kobject_get_unless_zero);
657
658
659
660
661
662static void kobject_cleanup(struct kobject *kobj)
663{
664 struct kobj_type *t = get_ktype(kobj);
665 const char *name = kobj->name;
666
667 pr_debug("kobject: '%s' (%p): %s, parent %p\n",
668 kobject_name(kobj), kobj, __func__, kobj->parent);
669
670 if (t && !t->release)
671 pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed. See Documentation/kobject.txt.\n",
672 kobject_name(kobj), kobj);
673
674
675 if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) {
676 pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n",
677 kobject_name(kobj), kobj);
678 kobject_uevent(kobj, KOBJ_REMOVE);
679 }
680
681
682 if (kobj->state_in_sysfs) {
683 pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n",
684 kobject_name(kobj), kobj);
685 kobject_del(kobj);
686 }
687
688 if (t && t->release) {
689 pr_debug("kobject: '%s' (%p): calling ktype release\n",
690 kobject_name(kobj), kobj);
691 t->release(kobj);
692 }
693
694
695 if (name) {
696 pr_debug("kobject: '%s': free name\n", name);
697 kfree_const(name);
698 }
699}
700
701#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
702static void kobject_delayed_cleanup(struct work_struct *work)
703{
704 kobject_cleanup(container_of(to_delayed_work(work),
705 struct kobject, release));
706}
707#endif
708
709static void kobject_release(struct kref *kref)
710{
711 struct kobject *kobj = container_of(kref, struct kobject, kref);
712#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
713 unsigned long delay = HZ + HZ * (get_random_int() & 0x3);
714 pr_info("kobject: '%s' (%p): %s, parent %p (delayed %ld)\n",
715 kobject_name(kobj), kobj, __func__, kobj->parent, delay);
716 INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup);
717
718 schedule_delayed_work(&kobj->release, delay);
719#else
720 kobject_cleanup(kobj);
721#endif
722}
723
724
725
726
727
728
729
730void kobject_put(struct kobject *kobj)
731{
732 if (kobj) {
733 if (!kobj->state_initialized)
734 WARN(1, KERN_WARNING
735 "kobject: '%s' (%p): is not initialized, yet kobject_put() is being called.\n",
736 kobject_name(kobj), kobj);
737 kref_put(&kobj->kref, kobject_release);
738 }
739}
740EXPORT_SYMBOL(kobject_put);
741
742static void dynamic_kobj_release(struct kobject *kobj)
743{
744 pr_debug("kobject: (%p): %s\n", kobj, __func__);
745 kfree(kobj);
746}
747
748static struct kobj_type dynamic_kobj_ktype = {
749 .release = dynamic_kobj_release,
750 .sysfs_ops = &kobj_sysfs_ops,
751};
752
753
754
755
756
757
758
759
760
761
762
763
764struct kobject *kobject_create(void)
765{
766 struct kobject *kobj;
767
768 kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
769 if (!kobj)
770 return NULL;
771
772 kobject_init(kobj, &dynamic_kobj_ktype);
773 return kobj;
774}
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
790{
791 struct kobject *kobj;
792 int retval;
793
794 kobj = kobject_create();
795 if (!kobj)
796 return NULL;
797
798 retval = kobject_add(kobj, parent, "%s", name);
799 if (retval) {
800 pr_warn("%s: kobject_add error: %d\n", __func__, retval);
801 kobject_put(kobj);
802 kobj = NULL;
803 }
804 return kobj;
805}
806EXPORT_SYMBOL_GPL(kobject_create_and_add);
807
808
809
810
811
812void kset_init(struct kset *k)
813{
814 kobject_init_internal(&k->kobj);
815 INIT_LIST_HEAD(&k->list);
816 spin_lock_init(&k->list_lock);
817}
818
819
820static ssize_t kobj_attr_show(struct kobject *kobj, struct attribute *attr,
821 char *buf)
822{
823 struct kobj_attribute *kattr;
824 ssize_t ret = -EIO;
825
826 kattr = container_of(attr, struct kobj_attribute, attr);
827 if (kattr->show)
828 ret = kattr->show(kobj, kattr, buf);
829 return ret;
830}
831
832static ssize_t kobj_attr_store(struct kobject *kobj, struct attribute *attr,
833 const char *buf, size_t count)
834{
835 struct kobj_attribute *kattr;
836 ssize_t ret = -EIO;
837
838 kattr = container_of(attr, struct kobj_attribute, attr);
839 if (kattr->store)
840 ret = kattr->store(kobj, kattr, buf, count);
841 return ret;
842}
843
844const struct sysfs_ops kobj_sysfs_ops = {
845 .show = kobj_attr_show,
846 .store = kobj_attr_store,
847};
848EXPORT_SYMBOL_GPL(kobj_sysfs_ops);
849
850
851
852
853
854int kset_register(struct kset *k)
855{
856 int err;
857
858 if (!k)
859 return -EINVAL;
860
861 kset_init(k);
862 err = kobject_add_internal(&k->kobj);
863 if (err)
864 return err;
865 kobject_uevent(&k->kobj, KOBJ_ADD);
866 return 0;
867}
868EXPORT_SYMBOL(kset_register);
869
870
871
872
873
874void kset_unregister(struct kset *k)
875{
876 if (!k)
877 return;
878 kobject_del(&k->kobj);
879 kobject_put(&k->kobj);
880}
881EXPORT_SYMBOL(kset_unregister);
882
883
884
885
886
887
888
889
890
891
892struct kobject *kset_find_obj(struct kset *kset, const char *name)
893{
894 struct kobject *k;
895 struct kobject *ret = NULL;
896
897 spin_lock(&kset->list_lock);
898
899 list_for_each_entry(k, &kset->list, entry) {
900 if (kobject_name(k) && !strcmp(kobject_name(k), name)) {
901 ret = kobject_get_unless_zero(k);
902 break;
903 }
904 }
905
906 spin_unlock(&kset->list_lock);
907 return ret;
908}
909EXPORT_SYMBOL_GPL(kset_find_obj);
910
911static void kset_release(struct kobject *kobj)
912{
913 struct kset *kset = container_of(kobj, struct kset, kobj);
914 pr_debug("kobject: '%s' (%p): %s\n",
915 kobject_name(kobj), kobj, __func__);
916 kfree(kset);
917}
918
919static void kset_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid)
920{
921 if (kobj->parent)
922 kobject_get_ownership(kobj->parent, uid, gid);
923}
924
925static struct kobj_type kset_ktype = {
926 .sysfs_ops = &kobj_sysfs_ops,
927 .release = kset_release,
928 .get_ownership = kset_get_ownership,
929};
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946static struct kset *kset_create(const char *name,
947 const struct kset_uevent_ops *uevent_ops,
948 struct kobject *parent_kobj)
949{
950 struct kset *kset;
951 int retval;
952
953 kset = kzalloc(sizeof(*kset), GFP_KERNEL);
954 if (!kset)
955 return NULL;
956 retval = kobject_set_name(&kset->kobj, "%s", name);
957 if (retval) {
958 kfree(kset);
959 return NULL;
960 }
961 kset->uevent_ops = uevent_ops;
962 kset->kobj.parent = parent_kobj;
963
964
965
966
967
968
969 kset->kobj.ktype = &kset_ktype;
970 kset->kobj.kset = NULL;
971
972 return kset;
973}
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989struct kset *kset_create_and_add(const char *name,
990 const struct kset_uevent_ops *uevent_ops,
991 struct kobject *parent_kobj)
992{
993 struct kset *kset;
994 int error;
995
996 kset = kset_create(name, uevent_ops, parent_kobj);
997 if (!kset)
998 return NULL;
999 error = kset_register(kset);
1000 if (error) {
1001 kfree(kset);
1002 return NULL;
1003 }
1004 return kset;
1005}
1006EXPORT_SYMBOL_GPL(kset_create_and_add);
1007
1008
1009static DEFINE_SPINLOCK(kobj_ns_type_lock);
1010static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES];
1011
1012int kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
1013{
1014 enum kobj_ns_type type = ops->type;
1015 int error;
1016
1017 spin_lock(&kobj_ns_type_lock);
1018
1019 error = -EINVAL;
1020 if (type >= KOBJ_NS_TYPES)
1021 goto out;
1022
1023 error = -EINVAL;
1024 if (type <= KOBJ_NS_TYPE_NONE)
1025 goto out;
1026
1027 error = -EBUSY;
1028 if (kobj_ns_ops_tbl[type])
1029 goto out;
1030
1031 error = 0;
1032 kobj_ns_ops_tbl[type] = ops;
1033
1034out:
1035 spin_unlock(&kobj_ns_type_lock);
1036 return error;
1037}
1038
1039int kobj_ns_type_registered(enum kobj_ns_type type)
1040{
1041 int registered = 0;
1042
1043 spin_lock(&kobj_ns_type_lock);
1044 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES))
1045 registered = kobj_ns_ops_tbl[type] != NULL;
1046 spin_unlock(&kobj_ns_type_lock);
1047
1048 return registered;
1049}
1050
1051const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent)
1052{
1053 const struct kobj_ns_type_operations *ops = NULL;
1054
1055 if (parent && parent->ktype && parent->ktype->child_ns_type)
1056 ops = parent->ktype->child_ns_type(parent);
1057
1058 return ops;
1059}
1060
1061const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj)
1062{
1063 return kobj_child_ns_ops(kobj->parent);
1064}
1065
1066bool kobj_ns_current_may_mount(enum kobj_ns_type type)
1067{
1068 bool may_mount = true;
1069
1070 spin_lock(&kobj_ns_type_lock);
1071 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1072 kobj_ns_ops_tbl[type])
1073 may_mount = kobj_ns_ops_tbl[type]->current_may_mount();
1074 spin_unlock(&kobj_ns_type_lock);
1075
1076 return may_mount;
1077}
1078
1079void *kobj_ns_grab_current(enum kobj_ns_type type)
1080{
1081 void *ns = NULL;
1082
1083 spin_lock(&kobj_ns_type_lock);
1084 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1085 kobj_ns_ops_tbl[type])
1086 ns = kobj_ns_ops_tbl[type]->grab_current_ns();
1087 spin_unlock(&kobj_ns_type_lock);
1088
1089 return ns;
1090}
1091EXPORT_SYMBOL_GPL(kobj_ns_grab_current);
1092
1093const void *kobj_ns_netlink(enum kobj_ns_type type, struct sock *sk)
1094{
1095 const void *ns = NULL;
1096
1097 spin_lock(&kobj_ns_type_lock);
1098 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1099 kobj_ns_ops_tbl[type])
1100 ns = kobj_ns_ops_tbl[type]->netlink_ns(sk);
1101 spin_unlock(&kobj_ns_type_lock);
1102
1103 return ns;
1104}
1105
1106const void *kobj_ns_initial(enum kobj_ns_type type)
1107{
1108 const void *ns = NULL;
1109
1110 spin_lock(&kobj_ns_type_lock);
1111 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1112 kobj_ns_ops_tbl[type])
1113 ns = kobj_ns_ops_tbl[type]->initial_ns();
1114 spin_unlock(&kobj_ns_type_lock);
1115
1116 return ns;
1117}
1118
1119void kobj_ns_drop(enum kobj_ns_type type, void *ns)
1120{
1121 spin_lock(&kobj_ns_type_lock);
1122 if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) &&
1123 kobj_ns_ops_tbl[type] && kobj_ns_ops_tbl[type]->drop_ns)
1124 kobj_ns_ops_tbl[type]->drop_ns(ns);
1125 spin_unlock(&kobj_ns_type_lock);
1126}
1127EXPORT_SYMBOL_GPL(kobj_ns_drop);
1128