USB: add driver for iowarrior devices.
[pandora-kernel.git] / lib / kobject.c
index 9aed594..f4f6176 100644 (file)
@@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj)
        return error;
 }
 
-static int create_dir(struct kobject * kobj)
+static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
 {
        int error = 0;
        if (kobject_name(kobj)) {
-               error = sysfs_create_dir(kobj);
+               error = sysfs_create_dir(kobj, shadow_parent);
                if (!error) {
                        if ((error = populate_dir(kobj)))
                                sysfs_remove_dir(kobj);
@@ -97,11 +97,12 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length)
 }
 
 /**
- * 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().
+ * kobject_get_path - generate and return the path associated with a given kobj and kset pair.
  *
  * @kobj:      kobject in question, with which to build the path
  * @gfp_mask:  the allocation type used to allocate the path
+ *
+ * The result must be freed by the caller with kfree().
  */
 char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask)
 {
@@ -158,9 +159,10 @@ static void unlink(struct kobject * kobj)
 /**
  *     kobject_add - add an object to the hierarchy.
  *     @kobj:  object.
+ *     @shadow_parent: sysfs directory to add to.
  */
 
-int kobject_add(struct kobject * kobj)
+int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
 {
        int error = 0;
        struct kobject * parent;
@@ -169,7 +171,7 @@ int kobject_add(struct kobject * kobj)
                return -ENOENT;
        if (!kobj->k_name)
                kobj->k_name = kobj->name;
-       if (!kobj->k_name) {
+       if (!*kobj->k_name) {
                pr_debug("kobject attempted to be registered with no name!\n");
                WARN_ON(1);
                return -EINVAL;
@@ -191,12 +193,11 @@ int kobject_add(struct kobject * kobj)
        }
        kobj->parent = parent;
 
-       error = create_dir(kobj);
+       error = create_dir(kobj, shadow_parent);
        if (error) {
                /* unlink does the kobject_put() for us */
                unlink(kobj);
-               if (parent)
-                       kobject_put(parent);
+               kobject_put(parent);
 
                /* be noisy on error issues */
                if (error == -EEXIST)
@@ -213,6 +214,15 @@ int kobject_add(struct kobject * kobj)
        return error;
 }
 
+/**
+ *     kobject_add - add an object to the hierarchy.
+ *     @kobj:  object.
+ */
+int kobject_add(struct kobject * kobj)
+{
+       return kobject_shadow_add(kobj, NULL);
+}
+
 
 /**
  *     kobject_register - initialize and add an object.
@@ -305,16 +315,39 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
        kobj = kobject_get(kobj);
        if (!kobj)
                return -EINVAL;
-       error = sysfs_rename_dir(kobj, new_name);
+       if (!kobj->parent)
+               return -EINVAL;
+       error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name);
        kobject_put(kobj);
 
        return error;
 }
 
 /**
- *     kobject_move - move object to another parent
+ *     kobject_rename - change the name of an object
  *     @kobj:  object in question.
  *     @new_parent: object's new parent
+ *     @new_name: object's new name
+ */
+
+int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent,
+                         const char *new_name)
+{
+       int error = 0;
+
+       kobj = kobject_get(kobj);
+       if (!kobj)
+               return -EINVAL;
+       error = sysfs_rename_dir(kobj, new_parent, new_name);
+       kobject_put(kobj);
+
+       return error;
+}
+
+/**
+ *     kobject_move - move object to another parent
+ *     @kobj:  object in question.
+ *     @new_parent: object's new parent (can be NULL)
  */
 
 int kobject_move(struct kobject *kobj, struct kobject *new_parent)
@@ -330,8 +363,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
                return -EINVAL;
        new_parent = kobject_get(new_parent);
        if (!new_parent) {
-               error = -EINVAL;
-               goto out;
+               if (kobj->kset)
+                       new_parent = kobject_get(&kobj->kset->kobj);
        }
        /* old object path */
        devpath = kobject_get_path(kobj, GFP_KERNEL);
@@ -420,8 +453,7 @@ void kobject_cleanup(struct kobject * kobj)
                t->release(kobj);
        if (s)
                kset_put(s);
-       if (parent) 
-               kobject_put(parent);
+       kobject_put(parent);
 }
 
 static void kobject_release(struct kref *kref)