| .. | .. |
|---|
| 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 |
|---|