linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / lib / kobject.c
index 8737dfd..efe67fa 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/string.h>
 #include <linux/module.h>
 #include <linux/stat.h>
+#include <linux/slab.h>
 
 /**
  *     populate_dir - populate directory with attributes.
@@ -71,6 +72,8 @@ static int get_kobj_path_length(struct kobject *kobj)
         * Add 1 to strlen for leading '/' of each level.
         */
        do {
+               if (kobject_name(parent) == NULL)
+                       return 0;
                length += strlen(kobject_name(parent)) + 1;
                parent = parent->parent;
        } while (parent);
@@ -100,12 +103,14 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length)
  * @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 kobject *kobj, int gfp_mask)
+char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
 {
        char *path;
        int len;
 
        len = get_kobj_path_length(kobj);
+       if (len == 0)
+               return NULL;
        path = kmalloc(len, gfp_mask);
        if (!path)
                return NULL;
@@ -140,9 +145,9 @@ void kobject_init(struct kobject * kobj)
 static void unlink(struct kobject * kobj)
 {
        if (kobj->kset) {
-               down_write(&kobj->kset->subsys->rwsem);
+               spin_lock(&kobj->kset->list_lock);
                list_del_init(&kobj->entry);
-               up_write(&kobj->kset->subsys->rwsem);
+               spin_unlock(&kobj->kset->list_lock);
        }
        kobject_put(kobj);
 }
@@ -161,6 +166,11 @@ int kobject_add(struct kobject * kobj)
                return -ENOENT;
        if (!kobj->k_name)
                kobj->k_name = kobj->name;
+       if (!kobj->k_name) {
+               pr_debug("kobject attempted to be registered with no name!\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
        parent = kobject_get(kobj->parent);
 
        pr_debug("kobject %s: registering. parent: %s, set: %s\n",
@@ -168,13 +178,13 @@ int kobject_add(struct kobject * kobj)
                 kobj->kset ? kobj->kset->kobj.name : "<NULL>" );
 
        if (kobj->kset) {
-               down_write(&kobj->kset->subsys->rwsem);
+               spin_lock(&kobj->kset->list_lock);
 
                if (!parent)
                        parent = kobject_get(&kobj->kset->kobj);
 
                list_add_tail(&kobj->entry,&kobj->kset->list);
-               up_write(&kobj->kset->subsys->rwsem);
+               spin_unlock(&kobj->kset->list_lock);
        }
        kobj->parent = parent;
 
@@ -184,8 +194,6 @@ int kobject_add(struct kobject * kobj)
                unlink(kobj);
                if (parent)
                        kobject_put(parent);
-       } else {
-               kobject_hotplug(kobj, KOBJ_ADD);
        }
 
        return error;
@@ -207,7 +215,8 @@ int kobject_register(struct kobject * kobj)
                        printk("kobject_register failed for %s (%d)\n",
                               kobject_name(kobj),error);
                        dump_stack();
-               }
+               } else
+                       kobject_uevent(kobj, KOBJ_ADD);
        } else
                error = -EINVAL;
        return error;
@@ -217,13 +226,12 @@ int kobject_register(struct kobject * kobj)
 /**
  *     kobject_set_name - Set the name of an object
  *     @kobj:  object.
- *     @name:  name. 
+ *     @fmt:   format string used to build the name
  *
  *     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.
  */
-
 int kobject_set_name(struct kobject * kobj, const char * fmt, ...)
 {
        int error = 0;
@@ -281,7 +289,7 @@ EXPORT_SYMBOL(kobject_set_name);
  *     @new_name: object's new name
  */
 
-int kobject_rename(struct kobject * kobj, char *new_name)
+int kobject_rename(struct kobject * kobj, const char *new_name)
 {
        int error = 0;
 
@@ -301,7 +309,6 @@ int kobject_rename(struct kobject * kobj, char *new_name)
 
 void kobject_del(struct kobject * kobj)
 {
-       kobject_hotplug(kobj, KOBJ_REMOVE);
        sysfs_remove_dir(kobj);
        unlink(kobj);
 }
@@ -314,6 +321,7 @@ void kobject_del(struct kobject * kobj)
 void kobject_unregister(struct kobject * kobj)
 {
        pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
+       kobject_uevent(kobj, KOBJ_REMOVE);
        kobject_del(kobj);
        kobject_put(kobj);
 }
@@ -380,6 +388,7 @@ void kset_init(struct kset * k)
 {
        kobject_init(&k->kobj);
        INIT_LIST_HEAD(&k->list);
+       spin_lock_init(&k->list_lock);
 }
 
 
@@ -444,7 +453,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name)
        struct list_head * entry;
        struct kobject * ret = NULL;
 
-       down_read(&kset->subsys->rwsem);
+       spin_lock(&kset->list_lock);
        list_for_each(entry,&kset->list) {
                struct kobject * k = to_kobj(entry);
                if (kobject_name(k) && !strcmp(kobject_name(k),name)) {
@@ -452,7 +461,7 @@ struct kobject * kset_find_obj(struct kset * kset, const char * name)
                        break;
                }
        }
-       up_read(&kset->subsys->rwsem);
+       spin_unlock(&kset->list_lock);
        return ret;
 }
 
@@ -524,7 +533,6 @@ 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);
@@ -532,7 +540,6 @@ EXPORT_SYMBOL(kobject_get);
 EXPORT_SYMBOL(kobject_put);
 EXPORT_SYMBOL(kobject_add);
 EXPORT_SYMBOL(kobject_del);
-EXPORT_SYMBOL(kobject_rename);
 
 EXPORT_SYMBOL(kset_register);
 EXPORT_SYMBOL(kset_unregister);