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