diff options
Diffstat (limited to 'lib/kobject.c')
-rw-r--r-- | lib/kobject.c | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/lib/kobject.c b/lib/kobject.c index f07c57252e82..640bd98a4c8a 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -746,17 +746,56 @@ void kset_unregister(struct kset *k) | |||
746 | */ | 746 | */ |
747 | struct kobject *kset_find_obj(struct kset *kset, const char *name) | 747 | struct kobject *kset_find_obj(struct kset *kset, const char *name) |
748 | { | 748 | { |
749 | return kset_find_obj_hinted(kset, name, NULL); | ||
750 | } | ||
751 | |||
752 | /** | ||
753 | * kset_find_obj_hinted - search for object in kset given a predecessor hint. | ||
754 | * @kset: kset we're looking in. | ||
755 | * @name: object's name. | ||
756 | * @hint: hint to possible object's predecessor. | ||
757 | * | ||
758 | * Check the hint's next object and if it is a match return it directly, | ||
759 | * otherwise, fall back to the behavior of kset_find_obj(). Either way | ||
760 | * a reference for the returned object is held and the reference on the | ||
761 | * hinted object is released. | ||
762 | */ | ||
763 | struct kobject *kset_find_obj_hinted(struct kset *kset, const char *name, | ||
764 | struct kobject *hint) | ||
765 | { | ||
749 | struct kobject *k; | 766 | struct kobject *k; |
750 | struct kobject *ret = NULL; | 767 | struct kobject *ret = NULL; |
751 | 768 | ||
752 | spin_lock(&kset->list_lock); | 769 | spin_lock(&kset->list_lock); |
770 | |||
771 | if (!hint) | ||
772 | goto slow_search; | ||
773 | |||
774 | /* end of list detection */ | ||
775 | if (hint->entry.next == kset->list.next) | ||
776 | goto slow_search; | ||
777 | |||
778 | k = container_of(hint->entry.next, struct kobject, entry); | ||
779 | if (!kobject_name(k) || strcmp(kobject_name(k), name)) | ||
780 | goto slow_search; | ||
781 | |||
782 | ret = kobject_get(k); | ||
783 | goto unlock_exit; | ||
784 | |||
785 | slow_search: | ||
753 | list_for_each_entry(k, &kset->list, entry) { | 786 | list_for_each_entry(k, &kset->list, entry) { |
754 | if (kobject_name(k) && !strcmp(kobject_name(k), name)) { | 787 | if (kobject_name(k) && !strcmp(kobject_name(k), name)) { |
755 | ret = kobject_get(k); | 788 | ret = kobject_get(k); |
756 | break; | 789 | break; |
757 | } | 790 | } |
758 | } | 791 | } |
792 | |||
793 | unlock_exit: | ||
759 | spin_unlock(&kset->list_lock); | 794 | spin_unlock(&kset->list_lock); |
795 | |||
796 | if (hint) | ||
797 | kobject_put(hint); | ||
798 | |||
760 | return ret; | 799 | return ret; |
761 | } | 800 | } |
762 | 801 | ||
@@ -909,14 +948,14 @@ const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj) | |||
909 | } | 948 | } |
910 | 949 | ||
911 | 950 | ||
912 | const void *kobj_ns_current(enum kobj_ns_type type) | 951 | void *kobj_ns_grab_current(enum kobj_ns_type type) |
913 | { | 952 | { |
914 | const void *ns = NULL; | 953 | void *ns = NULL; |
915 | 954 | ||
916 | spin_lock(&kobj_ns_type_lock); | 955 | spin_lock(&kobj_ns_type_lock); |
917 | if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && | 956 | if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && |
918 | kobj_ns_ops_tbl[type]) | 957 | kobj_ns_ops_tbl[type]) |
919 | ns = kobj_ns_ops_tbl[type]->current_ns(); | 958 | ns = kobj_ns_ops_tbl[type]->grab_current_ns(); |
920 | spin_unlock(&kobj_ns_type_lock); | 959 | spin_unlock(&kobj_ns_type_lock); |
921 | 960 | ||
922 | return ns; | 961 | return ns; |
@@ -948,23 +987,15 @@ const void *kobj_ns_initial(enum kobj_ns_type type) | |||
948 | return ns; | 987 | return ns; |
949 | } | 988 | } |
950 | 989 | ||
951 | /* | 990 | void kobj_ns_drop(enum kobj_ns_type type, void *ns) |
952 | * kobj_ns_exit - invalidate a namespace tag | ||
953 | * | ||
954 | * @type: the namespace type (i.e. KOBJ_NS_TYPE_NET) | ||
955 | * @ns: the actual namespace being invalidated | ||
956 | * | ||
957 | * This is called when a tag is no longer valid. For instance, | ||
958 | * when a network namespace exits, it uses this helper to | ||
959 | * make sure no sb's sysfs_info points to the now-invalidated | ||
960 | * netns. | ||
961 | */ | ||
962 | void kobj_ns_exit(enum kobj_ns_type type, const void *ns) | ||
963 | { | 991 | { |
964 | sysfs_exit_ns(type, ns); | 992 | spin_lock(&kobj_ns_type_lock); |
993 | if ((type > KOBJ_NS_TYPE_NONE) && (type < KOBJ_NS_TYPES) && | ||
994 | kobj_ns_ops_tbl[type] && kobj_ns_ops_tbl[type]->drop_ns) | ||
995 | kobj_ns_ops_tbl[type]->drop_ns(ns); | ||
996 | spin_unlock(&kobj_ns_type_lock); | ||
965 | } | 997 | } |
966 | 998 | ||
967 | |||
968 | EXPORT_SYMBOL(kobject_get); | 999 | EXPORT_SYMBOL(kobject_get); |
969 | EXPORT_SYMBOL(kobject_put); | 1000 | EXPORT_SYMBOL(kobject_put); |
970 | EXPORT_SYMBOL(kobject_del); | 1001 | EXPORT_SYMBOL(kobject_del); |