diff options
author | Greg Kroah-Hartman <greg@kroah.com> | 2004-08-24 22:45:48 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <greg@kroah.com> | 2004-08-24 22:45:48 -0700 |
commit | f75bdb62b88f893e24f67be1831e55f15eb79f25 (patch) | |
tree | 4ae13cb5f650e966b77ed3b2d3fe59a92bf39f87 /lib | |
parent | 32a8ed459490371bb9e5973bae5c502f94dd8034 (diff) | |
parent | 764dfe0b8c158293b2905f5a1fe213bd91d4e3f0 (diff) | |
download | history-f75bdb62b88f893e24f67be1831e55f15eb79f25.tar.gz |
Merge kroah.com:/home/greg/linux/BK/bleed-2.6
into kroah.com:/home/greg/linux/BK/driver-2.6
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile | 5 | ||||
-rw-r--r-- | lib/kobject.c | 57 | ||||
-rw-r--r-- | lib/kref.c | 29 |
3 files changed, 52 insertions, 39 deletions
diff --git a/lib/Makefile b/lib/Makefile index f80da458005952..b62c9ef212edc9 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -5,12 +5,9 @@ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \ bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \ - kobject.o idr.o div64.o parser.o int_sqrt.o \ + kobject.o kref.o idr.o div64.o parser.o int_sqrt.o \ bitmap.o extable.o -# hack for now till some static code uses krefs, then it can move up above... -obj-y += kref.o - lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o diff --git a/lib/kobject.c b/lib/kobject.c index 781f3e8966955f..a971b8e55e6b75 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); diff --git a/lib/kref.c b/lib/kref.c index ee141adbf2e558..2218b7ae7db6fa 100644 --- a/lib/kref.c +++ b/lib/kref.c @@ -11,48 +11,45 @@ * */ -/* #define DEBUG */ - #include <linux/kref.h> #include <linux/module.h> /** * kref_init - initialize object. * @kref: object in question. - * @release: pointer to a function that will clean up the object - * when the last reference to the object is released. - * This pointer is required. */ -void kref_init(struct kref *kref, void (*release)(struct kref *kref)) +void kref_init(struct kref *kref) { - WARN_ON(release == NULL); atomic_set(&kref->refcount,1); - kref->release = release; } /** * kref_get - increment refcount for object. * @kref: object. */ -struct kref *kref_get(struct kref *kref) +void kref_get(struct kref *kref) { WARN_ON(!atomic_read(&kref->refcount)); atomic_inc(&kref->refcount); - return kref; } /** * kref_put - decrement refcount for object. * @kref: object. + * @release: pointer to the function that will clean up the object when the + * last reference to the object is released. + * This pointer is required, and it is not acceptable to pass kfree + * in as this function. * - * Decrement the refcount, and if 0, call kref->release(). + * Decrement the refcount, and if 0, call release(). */ -void kref_put(struct kref *kref) +void kref_put(struct kref *kref, void (*release) (struct kref *kref)) { - if (atomic_dec_and_test(&kref->refcount)) { - pr_debug("kref cleaning up\n"); - kref->release(kref); - } + WARN_ON(release == NULL); + WARN_ON(release == (void (*)(struct kref *))kfree); + + if (atomic_dec_and_test(&kref->refcount)) + release(kref); } EXPORT_SYMBOL(kref_init); |