kobject: Fix kobject_rename and !CONFIG_SYSFS
authorEric W. Biederman <ebiederm@xmission.com>
Thu, 8 May 2008 21:41:00 +0000 (14:41 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 16 Oct 2008 16:24:52 +0000 (09:24 -0700)
When looking at kobject_rename I found two bugs with
that exist when sysfs support is disabled in the kernel.

kobject_rename does not change the name on the kobject when
sysfs support is not compiled in.

kobject_rename without locking attempts to check the
validity of a rename operation, which the kobject layer
simply does not have the infrastructure to do.

This patch documents the previously unstated requirement of
kobject_rename that is the responsibility of the caller to
provide mutual exclusion and to be certain that the new_name
for the kobject is valid.

This patch modifies sysfs_rename_dir in !CONFIG_SYSFS case
to call kobject_set_name to actually change the kobject_name.

This patch removes the bogus and misleading check in kobject_rename
that attempts to see if a rename is valid.  The check is bogus
because we do not have the proper locking.  The check is misleading
because it looks like we can and do perform checking at the kobject
level that we don't.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Documentation/kobject.txt
drivers/base/core.c
include/linux/sysfs.h
lib/kobject.c

index 51a8021ee532bc03e4e530dd724f3e42ae737bc4..f5d2aad65a672ce65082769b835d621bac11e59a 100644 (file)
@@ -118,6 +118,10 @@ the name of the kobject, call kobject_rename():
 
     int kobject_rename(struct kobject *kobj, const char *new_name);
 
+Note kobject_rename does perform any locking or have a solid notion of
+what names are valid so the provide must provide their own sanity checking
+and serialization.
+
 There is a function called kobject_set_name() but that is legacy cruft and
 is being removed.  If your code needs to call this function, it is
 incorrect and needs to be fixed.
index 9649d1c422a4bd1abbc71ef7849d7b02193fc52a..8c2cc2648f5a5c0ec330df4991f75b6be07131ae 100644 (file)
@@ -1327,6 +1327,11 @@ EXPORT_SYMBOL_GPL(device_destroy);
  * device_rename - renames a device
  * @dev: the pointer to the struct device to be renamed
  * @new_name: the new name of the device
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of device_rename
+ * on the same device to ensure that new_name is valid and
+ * won't conflict with other devices.
  */
 int device_rename(struct device *dev, char *new_name)
 {
index b330e289d71f280f7bb6ca3af431a733039ac420..39924a9622072fa8b96c5a046ec47c4182876cc2 100644 (file)
@@ -20,6 +20,8 @@
 struct kobject;
 struct module;
 
+extern int kobject_set_name(struct kobject *kobj, const char *name, ...)
+                           __attribute__((format(printf, 2, 3)));
 /* FIXME
  * The *owner field is no longer used, but leave around
  * until the tree gets cleaned up fully.
@@ -147,7 +149,7 @@ static inline void sysfs_remove_dir(struct kobject *kobj)
 
 static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name)
 {
-       return 0;
+       return kobject_set_name(kobj, "%s", new_name);
 }
 
 static inline int sysfs_move_dir(struct kobject *kobj,
index fbf0ae28237672a6fafdbbf29e481d76c45ddd11..ae6bb900bfb60823e7ef71898154f5beb55cdd1c 100644 (file)
@@ -387,6 +387,11 @@ EXPORT_SYMBOL_GPL(kobject_init_and_add);
  * kobject_rename - change the name of an object
  * @kobj: object in question.
  * @new_name: object's new name
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of kobject_rename
+ * on the same kobject and to ensure that new_name is valid and
+ * won't conflict with other kobjects.
  */
 int kobject_rename(struct kobject *kobj, const char *new_name)
 {
@@ -401,19 +406,6 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
        if (!kobj->parent)
                return -EINVAL;
 
-       /* see if this name is already in use */
-       if (kobj->kset) {
-               struct kobject *temp_kobj;
-               temp_kobj = kset_find_obj(kobj->kset, new_name);
-               if (temp_kobj) {
-                       printk(KERN_WARNING "kobject '%s' cannot be renamed "
-                              "to '%s' as '%s' is already in existence.\n",
-                              kobject_name(kobj), new_name, new_name);
-                       kobject_put(temp_kobj);
-                       return -EINVAL;
-               }
-       }
-
        devpath = kobject_get_path(kobj, GFP_KERNEL);
        if (!devpath) {
                error = -ENOMEM;