.. | .. |
---|
6 | 6 | * Copyright (c) 2006-2007 Greg Kroah-Hartman <greg@kroah.com> |
---|
7 | 7 | * Copyright (c) 2006-2007 Novell Inc. |
---|
8 | 8 | * |
---|
9 | | - * Please see the file Documentation/kobject.txt for critical information |
---|
| 9 | + * Please see the file Documentation/core-api/kobject.rst for critical information |
---|
10 | 10 | * about using the kobject interface. |
---|
11 | 11 | */ |
---|
12 | 12 | |
---|
.. | .. |
---|
18 | 18 | #include <linux/random.h> |
---|
19 | 19 | |
---|
20 | 20 | /** |
---|
21 | | - * kobject_namespace - return @kobj's namespace tag |
---|
| 21 | + * kobject_namespace() - Return @kobj's namespace tag. |
---|
22 | 22 | * @kobj: kobject in question |
---|
23 | 23 | * |
---|
24 | 24 | * Returns namespace tag of @kobj if its parent has namespace ops enabled |
---|
.. | .. |
---|
36 | 36 | } |
---|
37 | 37 | |
---|
38 | 38 | /** |
---|
39 | | - * kobject_get_ownership - get sysfs ownership data for @kobj |
---|
| 39 | + * kobject_get_ownership() - Get sysfs ownership data for @kobj. |
---|
40 | 40 | * @kobj: kobject in question |
---|
41 | 41 | * @uid: kernel user ID for sysfs objects |
---|
42 | 42 | * @gid: kernel group ID for sysfs objects |
---|
.. | .. |
---|
82 | 82 | |
---|
83 | 83 | static int create_dir(struct kobject *kobj) |
---|
84 | 84 | { |
---|
| 85 | + const struct kobj_type *ktype = get_ktype(kobj); |
---|
85 | 86 | const struct kobj_ns_type_operations *ops; |
---|
86 | 87 | int error; |
---|
87 | 88 | |
---|
.. | .. |
---|
93 | 94 | if (error) { |
---|
94 | 95 | sysfs_remove_dir(kobj); |
---|
95 | 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 | + } |
---|
96 | 105 | } |
---|
97 | 106 | |
---|
98 | 107 | /* |
---|
.. | .. |
---|
153 | 162 | } |
---|
154 | 163 | |
---|
155 | 164 | /** |
---|
156 | | - * kobject_get_path - generate and return the path associated with a given kobj and kset pair. |
---|
157 | | - * |
---|
| 165 | + * kobject_get_path() - Allocate memory and fill in the path for @kobj. |
---|
158 | 166 | * @kobj: kobject in question, with which to build the path |
---|
159 | 167 | * @gfp_mask: the allocation type used to allocate the path |
---|
160 | 168 | * |
---|
161 | | - * The result must be freed by the caller with kfree(). |
---|
| 169 | + * Return: The newly allocated memory, caller must free with kfree(). |
---|
162 | 170 | */ |
---|
163 | 171 | char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) |
---|
164 | 172 | { |
---|
.. | .. |
---|
265 | 273 | } |
---|
266 | 274 | |
---|
267 | 275 | /** |
---|
268 | | - * kobject_set_name_vargs - Set the name of an kobject |
---|
| 276 | + * kobject_set_name_vargs() - Set the name of a kobject. |
---|
269 | 277 | * @kobj: struct kobject to set the name of |
---|
270 | 278 | * @fmt: format string used to build the name |
---|
271 | 279 | * @vargs: vargs to format the string. |
---|
.. | .. |
---|
305 | 313 | } |
---|
306 | 314 | |
---|
307 | 315 | /** |
---|
308 | | - * kobject_set_name - Set the name of a kobject |
---|
| 316 | + * kobject_set_name() - Set the name of a kobject. |
---|
309 | 317 | * @kobj: struct kobject to set the name of |
---|
310 | 318 | * @fmt: format string used to build the name |
---|
311 | 319 | * |
---|
.. | .. |
---|
327 | 335 | EXPORT_SYMBOL(kobject_set_name); |
---|
328 | 336 | |
---|
329 | 337 | /** |
---|
330 | | - * kobject_init - initialize a kobject structure |
---|
| 338 | + * kobject_init() - Initialize a kobject structure. |
---|
331 | 339 | * @kobj: pointer to the kobject to initialize |
---|
332 | 340 | * @ktype: pointer to the ktype for this kobject. |
---|
333 | 341 | * |
---|
.. | .. |
---|
383 | 391 | } |
---|
384 | 392 | |
---|
385 | 393 | /** |
---|
386 | | - * kobject_add - the main kobject add function |
---|
| 394 | + * kobject_add() - The main kobject add function. |
---|
387 | 395 | * @kobj: the kobject to add |
---|
388 | 396 | * @parent: pointer to the parent of the kobject. |
---|
389 | 397 | * @fmt: format to name the kobject with. |
---|
.. | .. |
---|
397 | 405 | * is assigned to the kobject, then the kobject will be located in the |
---|
398 | 406 | * root of the sysfs tree. |
---|
399 | 407 | * |
---|
400 | | - * If this function returns an error, kobject_put() must be called to |
---|
401 | | - * properly clean up the memory associated with the object. |
---|
402 | | - * Under no instance should the kobject that is passed to this function |
---|
403 | | - * be directly freed with a call to kfree(), that can leak memory. |
---|
404 | | - * |
---|
405 | 408 | * Note, no "add" uevent will be created with this call, the caller should set |
---|
406 | 409 | * up all of the necessary sysfs files for the object and then call |
---|
407 | 410 | * kobject_uevent() with the UEVENT_ADD parameter to ensure that |
---|
408 | 411 | * userspace is properly notified of this kobject's creation. |
---|
| 412 | + * |
---|
| 413 | + * Return: If this function returns an error, kobject_put() must be |
---|
| 414 | + * called to properly clean up the memory associated with the |
---|
| 415 | + * object. Under no instance should the kobject that is passed |
---|
| 416 | + * to this function be directly freed with a call to kfree(), |
---|
| 417 | + * that can leak memory. |
---|
| 418 | + * |
---|
| 419 | + * If this function returns success, kobject_put() must also be called |
---|
| 420 | + * in order to properly clean up the memory associated with the object. |
---|
| 421 | + * |
---|
| 422 | + * In short, once this function is called, kobject_put() MUST be called |
---|
| 423 | + * when the use of the object is finished in order to properly free |
---|
| 424 | + * everything. |
---|
409 | 425 | */ |
---|
410 | 426 | int kobject_add(struct kobject *kobj, struct kobject *parent, |
---|
411 | 427 | const char *fmt, ...) |
---|
.. | .. |
---|
431 | 447 | EXPORT_SYMBOL(kobject_add); |
---|
432 | 448 | |
---|
433 | 449 | /** |
---|
434 | | - * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy |
---|
| 450 | + * kobject_init_and_add() - Initialize a kobject structure and add it to |
---|
| 451 | + * the kobject hierarchy. |
---|
435 | 452 | * @kobj: pointer to the kobject to initialize |
---|
436 | 453 | * @ktype: pointer to the ktype for this kobject. |
---|
437 | 454 | * @parent: pointer to the parent of this kobject. |
---|
438 | 455 | * @fmt: the name of the kobject. |
---|
439 | 456 | * |
---|
440 | | - * This function combines the call to kobject_init() and |
---|
441 | | - * kobject_add(). The same type of error handling after a call to |
---|
442 | | - * kobject_add() and kobject lifetime rules are the same here. |
---|
| 457 | + * This function combines the call to kobject_init() and kobject_add(). |
---|
| 458 | + * |
---|
| 459 | + * If this function returns an error, kobject_put() must be called to |
---|
| 460 | + * properly clean up the memory associated with the object. This is the |
---|
| 461 | + * same type of error handling after a call to kobject_add() and kobject |
---|
| 462 | + * lifetime rules are the same here. |
---|
443 | 463 | */ |
---|
444 | 464 | int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype, |
---|
445 | 465 | struct kobject *parent, const char *fmt, ...) |
---|
.. | .. |
---|
458 | 478 | EXPORT_SYMBOL_GPL(kobject_init_and_add); |
---|
459 | 479 | |
---|
460 | 480 | /** |
---|
461 | | - * kobject_rename - change the name of an object |
---|
| 481 | + * kobject_rename() - Change the name of an object. |
---|
462 | 482 | * @kobj: object in question. |
---|
463 | 483 | * @new_name: object's new name |
---|
464 | 484 | * |
---|
.. | .. |
---|
478 | 498 | kobj = kobject_get(kobj); |
---|
479 | 499 | if (!kobj) |
---|
480 | 500 | return -EINVAL; |
---|
481 | | - if (!kobj->parent) |
---|
| 501 | + if (!kobj->parent) { |
---|
| 502 | + kobject_put(kobj); |
---|
482 | 503 | return -EINVAL; |
---|
| 504 | + } |
---|
483 | 505 | |
---|
484 | 506 | devpath = kobject_get_path(kobj, GFP_KERNEL); |
---|
485 | 507 | if (!devpath) { |
---|
.. | .. |
---|
525 | 547 | EXPORT_SYMBOL_GPL(kobject_rename); |
---|
526 | 548 | |
---|
527 | 549 | /** |
---|
528 | | - * kobject_move - move object to another parent |
---|
| 550 | + * kobject_move() - Move object to another parent. |
---|
529 | 551 | * @kobj: object in question. |
---|
530 | 552 | * @new_parent: object's new parent (can be NULL) |
---|
531 | 553 | */ |
---|
.. | .. |
---|
577 | 599 | } |
---|
578 | 600 | EXPORT_SYMBOL_GPL(kobject_move); |
---|
579 | 601 | |
---|
580 | | -/** |
---|
581 | | - * kobject_del - unlink kobject from hierarchy. |
---|
582 | | - * @kobj: object. |
---|
583 | | - */ |
---|
584 | | -void kobject_del(struct kobject *kobj) |
---|
| 602 | +static void __kobject_del(struct kobject *kobj) |
---|
585 | 603 | { |
---|
586 | 604 | struct kernfs_node *sd; |
---|
587 | | - |
---|
588 | | - if (!kobj) |
---|
589 | | - return; |
---|
| 605 | + const struct kobj_type *ktype; |
---|
590 | 606 | |
---|
591 | 607 | sd = kobj->sd; |
---|
| 608 | + ktype = get_ktype(kobj); |
---|
| 609 | + |
---|
| 610 | + if (ktype) |
---|
| 611 | + sysfs_remove_groups(kobj, ktype->default_groups); |
---|
| 612 | + |
---|
| 613 | + /* send "remove" if the caller did not do it but sent "add" */ |
---|
| 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 | + |
---|
592 | 620 | sysfs_remove_dir(kobj); |
---|
593 | 621 | sysfs_put(sd); |
---|
594 | 622 | |
---|
595 | 623 | kobj->state_in_sysfs = 0; |
---|
596 | 624 | kobj_kset_leave(kobj); |
---|
597 | | - kobject_put(kobj->parent); |
---|
598 | 625 | kobj->parent = NULL; |
---|
| 626 | +} |
---|
| 627 | + |
---|
| 628 | +/** |
---|
| 629 | + * kobject_del() - Unlink kobject from hierarchy. |
---|
| 630 | + * @kobj: object. |
---|
| 631 | + * |
---|
| 632 | + * This is the function that should be called to delete an object |
---|
| 633 | + * successfully added via kobject_add(). |
---|
| 634 | + */ |
---|
| 635 | +void 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); |
---|
599 | 645 | } |
---|
600 | 646 | EXPORT_SYMBOL(kobject_del); |
---|
601 | 647 | |
---|
602 | 648 | /** |
---|
603 | | - * kobject_get - increment refcount for object. |
---|
| 649 | + * kobject_get() - Increment refcount for object. |
---|
604 | 650 | * @kobj: object. |
---|
605 | 651 | */ |
---|
606 | 652 | struct kobject *kobject_get(struct kobject *kobj) |
---|
.. | .. |
---|
632 | 678 | */ |
---|
633 | 679 | static void kobject_cleanup(struct kobject *kobj) |
---|
634 | 680 | { |
---|
| 681 | + struct kobject *parent = kobj->parent; |
---|
635 | 682 | struct kobj_type *t = get_ktype(kobj); |
---|
636 | 683 | const char *name = kobj->name; |
---|
637 | 684 | |
---|
.. | .. |
---|
639 | 686 | kobject_name(kobj), kobj, __func__, kobj->parent); |
---|
640 | 687 | |
---|
641 | 688 | if (t && !t->release) |
---|
642 | | - pr_debug("kobject: '%s' (%p): does not have a release() function, it is broken and must be fixed.\n", |
---|
| 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", |
---|
643 | 690 | kobject_name(kobj), kobj); |
---|
644 | | - |
---|
645 | | - /* send "remove" if the caller did not do it but sent "add" */ |
---|
646 | | - if (kobj->state_add_uevent_sent && !kobj->state_remove_uevent_sent) { |
---|
647 | | - pr_debug("kobject: '%s' (%p): auto cleanup 'remove' event\n", |
---|
648 | | - kobject_name(kobj), kobj); |
---|
649 | | - kobject_uevent(kobj, KOBJ_REMOVE); |
---|
650 | | - } |
---|
651 | 691 | |
---|
652 | 692 | /* remove from sysfs if the caller did not do it */ |
---|
653 | 693 | if (kobj->state_in_sysfs) { |
---|
654 | 694 | pr_debug("kobject: '%s' (%p): auto cleanup kobject_del\n", |
---|
655 | 695 | kobject_name(kobj), kobj); |
---|
656 | | - kobject_del(kobj); |
---|
| 696 | + __kobject_del(kobj); |
---|
| 697 | + } else { |
---|
| 698 | + /* avoid dropping the parent reference unnecessarily */ |
---|
| 699 | + parent = NULL; |
---|
657 | 700 | } |
---|
658 | 701 | |
---|
659 | 702 | if (t && t->release) { |
---|
.. | .. |
---|
667 | 710 | pr_debug("kobject: '%s': free name\n", name); |
---|
668 | 711 | kfree_const(name); |
---|
669 | 712 | } |
---|
| 713 | + |
---|
| 714 | + kobject_put(parent); |
---|
670 | 715 | } |
---|
671 | 716 | |
---|
672 | 717 | #ifdef CONFIG_DEBUG_KOBJECT_RELEASE |
---|
.. | .. |
---|
693 | 738 | } |
---|
694 | 739 | |
---|
695 | 740 | /** |
---|
696 | | - * kobject_put - decrement refcount for object. |
---|
| 741 | + * kobject_put() - Decrement refcount for object. |
---|
697 | 742 | * @kobj: object. |
---|
698 | 743 | * |
---|
699 | 744 | * Decrement the refcount, and if 0, call kobject_cleanup(). |
---|
.. | .. |
---|
722 | 767 | }; |
---|
723 | 768 | |
---|
724 | 769 | /** |
---|
725 | | - * kobject_create - create a struct kobject dynamically |
---|
| 770 | + * kobject_create() - Create a struct kobject dynamically. |
---|
726 | 771 | * |
---|
727 | 772 | * This function creates a kobject structure dynamically and sets it up |
---|
728 | 773 | * to be a "dynamic" kobject with a default release function set up. |
---|
.. | .. |
---|
745 | 790 | } |
---|
746 | 791 | |
---|
747 | 792 | /** |
---|
748 | | - * kobject_create_and_add - create a struct kobject dynamically and register it with sysfs |
---|
749 | | - * |
---|
| 793 | + * kobject_create_and_add() - Create a struct kobject dynamically and |
---|
| 794 | + * register it with sysfs. |
---|
750 | 795 | * @name: the name for the kobject |
---|
751 | 796 | * @parent: the parent kobject of this kobject, if any. |
---|
752 | 797 | * |
---|
.. | .. |
---|
777 | 822 | EXPORT_SYMBOL_GPL(kobject_create_and_add); |
---|
778 | 823 | |
---|
779 | 824 | /** |
---|
780 | | - * kset_init - initialize a kset for use |
---|
| 825 | + * kset_init() - Initialize a kset for use. |
---|
781 | 826 | * @k: kset |
---|
782 | 827 | */ |
---|
783 | 828 | void kset_init(struct kset *k) |
---|
.. | .. |
---|
819 | 864 | EXPORT_SYMBOL_GPL(kobj_sysfs_ops); |
---|
820 | 865 | |
---|
821 | 866 | /** |
---|
822 | | - * kset_register - initialize and add a kset. |
---|
| 867 | + * kset_register() - Initialize and add a kset. |
---|
823 | 868 | * @k: kset. |
---|
824 | 869 | */ |
---|
825 | 870 | int kset_register(struct kset *k) |
---|
.. | .. |
---|
828 | 873 | |
---|
829 | 874 | if (!k) |
---|
830 | 875 | return -EINVAL; |
---|
| 876 | + |
---|
| 877 | + if (!k->kobj.ktype) { |
---|
| 878 | + pr_err("must have a ktype to be initialized properly!\n"); |
---|
| 879 | + return -EINVAL; |
---|
| 880 | + } |
---|
831 | 881 | |
---|
832 | 882 | kset_init(k); |
---|
833 | 883 | err = kobject_add_internal(&k->kobj); |
---|
.. | .. |
---|
839 | 889 | EXPORT_SYMBOL(kset_register); |
---|
840 | 890 | |
---|
841 | 891 | /** |
---|
842 | | - * kset_unregister - remove a kset. |
---|
| 892 | + * kset_unregister() - Remove a kset. |
---|
843 | 893 | * @k: kset. |
---|
844 | 894 | */ |
---|
845 | 895 | void kset_unregister(struct kset *k) |
---|
.. | .. |
---|
852 | 902 | EXPORT_SYMBOL(kset_unregister); |
---|
853 | 903 | |
---|
854 | 904 | /** |
---|
855 | | - * kset_find_obj - search for object in kset. |
---|
| 905 | + * kset_find_obj() - Search for object in kset. |
---|
856 | 906 | * @kset: kset we're looking in. |
---|
857 | 907 | * @name: object's name. |
---|
858 | 908 | * |
---|
.. | .. |
---|
887 | 937 | kfree(kset); |
---|
888 | 938 | } |
---|
889 | 939 | |
---|
890 | | -void kset_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid) |
---|
| 940 | +static void kset_get_ownership(struct kobject *kobj, kuid_t *uid, kgid_t *gid) |
---|
891 | 941 | { |
---|
892 | 942 | if (kobj->parent) |
---|
893 | 943 | kobject_get_ownership(kobj->parent, uid, gid); |
---|
.. | .. |
---|
900 | 950 | }; |
---|
901 | 951 | |
---|
902 | 952 | /** |
---|
903 | | - * kset_create - create a struct kset dynamically |
---|
| 953 | + * kset_create() - Create a struct kset dynamically. |
---|
904 | 954 | * |
---|
905 | 955 | * @name: the name for the kset |
---|
906 | 956 | * @uevent_ops: a struct kset_uevent_ops for the kset |
---|
.. | .. |
---|
944 | 994 | } |
---|
945 | 995 | |
---|
946 | 996 | /** |
---|
947 | | - * kset_create_and_add - create a struct kset dynamically and add it to sysfs |
---|
| 997 | + * kset_create_and_add() - Create a struct kset dynamically and add it to sysfs. |
---|
948 | 998 | * |
---|
949 | 999 | * @name: the name for the kset |
---|
950 | 1000 | * @uevent_ops: a struct kset_uevent_ops for the kset |
---|