X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fkobject.c;h=a971b8e55e6b75dc1a22214a7cfc77b22d9457d9;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=781f3e8966955f4f0c109b9c19a43a4231725f81;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/lib/kobject.c b/lib/kobject.c index 781f3e896..a971b8e55 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -58,14 +58,11 @@ static int create_dir(struct kobject * kobj) return error; } - static inline struct kobject * to_kobj(struct list_head * entry) { return container_of(entry,struct kobject,entry); } - -#ifdef CONFIG_HOTPLUG static int get_kobj_path_length(struct kset *kset, struct kobject *kobj) { int length = 1; @@ -98,6 +95,31 @@ static void fill_kobj_path(struct kset *kset, struct kobject *kobj, char *path, pr_debug("%s: path = '%s'\n",__FUNCTION__,path); } +/** + * kobject_get_path - generate and return the path associated with a given kobj + * and kset pair. The result must be freed by the caller with kfree(). + * + * @kset: kset in question, with which to build the path + * @kobj: kobject in question, with which to build the path + * @gfp_mask: the allocation type used to allocate the path + */ +char * kobject_get_path(struct kset *kset, struct kobject *kobj, int gfp_mask) +{ + char *path; + int len; + + len = get_kobj_path_length(kset, kobj); + path = kmalloc(len, gfp_mask); + if (!path) + return NULL; + memset(path, 0x00, len); + fill_kobj_path(kset, kobj, path, len); + + return path; +} + +#ifdef CONFIG_HOTPLUG + #define BUFFER_SIZE 1024 /* should be enough memory for the env */ #define NUM_ENVP 32 /* number of env pointers */ static unsigned long sequence_num; @@ -112,7 +134,6 @@ static void kset_hotplug(const char *action, struct kset *kset, char *scratch; int i = 0; int retval; - int kobj_path_length; char *kobj_path = NULL; char *name = NULL; unsigned long seq; @@ -163,12 +184,9 @@ static void kset_hotplug(const char *action, struct kset *kset, envp [i++] = scratch; scratch += sprintf(scratch, "SEQNUM=%ld", seq) + 1; - kobj_path_length = get_kobj_path_length (kset, kobj); - kobj_path = kmalloc (kobj_path_length, GFP_KERNEL); + kobj_path = kobject_get_path(kset, kobj, GFP_KERNEL); if (!kobj_path) goto exit; - memset (kobj_path, 0x00, kobj_path_length); - fill_kobj_path (kset, kobj, kobj_path, kobj_path_length); envp [i++] = scratch; scratch += sprintf (scratch, "DEVPATH=%s", kobj_path) + 1; @@ -225,10 +243,9 @@ void kobject_hotplug(const char *action, struct kobject *kobj) * kobject_init - initialize object. * @kobj: object in question. */ - void kobject_init(struct kobject * kobj) { - atomic_set(&kobj->refcount,1); + kref_init(&kobj->kref); INIT_LIST_HEAD(&kobj->entry); kobj->kset = kset_get(kobj->kset); } @@ -325,7 +342,7 @@ int kobject_register(struct kobject * kobj) * @kobj: object. * @name: name. * - * If strlen(name) < KOBJ_NAME_LEN, then use a dynamically allocated + * If strlen(name) >= KOBJ_NAME_LEN, then use a dynamically allocated * string that @kobj->k_name points to. Otherwise, use the static * @kobj->name array. */ @@ -429,10 +446,8 @@ void kobject_unregister(struct kobject * kobj) struct kobject * kobject_get(struct kobject * kobj) { - if (kobj) { - WARN_ON(!atomic_read(&kobj->refcount)); - atomic_inc(&kobj->refcount); - } + if (kobj) + kref_get(&kobj->kref); return kobj; } @@ -459,17 +474,21 @@ void kobject_cleanup(struct kobject * kobj) kobject_put(parent); } +static void kobject_release(struct kref *kref) +{ + kobject_cleanup(container_of(kref, struct kobject, kref)); +} + /** * kobject_put - decrement refcount for object. * @kobj: object. * * Decrement the refcount, and if 0, call kobject_cleanup(). */ - void kobject_put(struct kobject * kobj) { - if (atomic_dec_and_test(&kobj->refcount)) - kobject_cleanup(kobj); + if (kobj) + kref_put(&kobj->kref, kobject_release); } @@ -626,7 +645,7 @@ void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a) } } - +EXPORT_SYMBOL(kobject_get_path); EXPORT_SYMBOL(kobject_init); EXPORT_SYMBOL(kobject_register); EXPORT_SYMBOL(kobject_unregister);