]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
driver core: Fix error handling in driver API device_rename()
authorZijun Hu <quic_zijuhu@quicinc.com>
Mon, 22 Jul 2024 14:48:10 +0000 (22:48 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 31 Jul 2024 12:54:47 +0000 (14:54 +0200)
For class-device, device_rename() failure maybe cause unexpected link name
within its class folder as explained below:

/sys/class/.../old_name -> /sys/devices/.../old_name
device_rename(..., new_name) and failed
/sys/class/.../new_name -> /sys/devices/.../old_name

Fixed by undoing renaming link if renaming kobject failed.

Fixes: f349cf34731c ("driver core: Implement ns directory support for device classes.")
Signed-off-by: Zijun Hu <quic_zijuhu@quicinc.com>
Link: https://lore.kernel.org/r/20240722-device_rename_fix-v2-1-77de1a6c6495@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/base/core.c

index 3e82eaba493265c0baf1e05f41948ea4c63fa392..72798133ed6365956d70a9ac9b7ce4e9aa35554c 100644 (file)
@@ -4516,9 +4516,11 @@ EXPORT_SYMBOL_GPL(device_destroy);
  */
 int device_rename(struct device *dev, const char *new_name)
 {
+       struct subsys_private *sp = NULL;
        struct kobject *kobj = &dev->kobj;
        char *old_device_name = NULL;
        int error;
+       bool is_link_renamed = false;
 
        dev = get_device(dev);
        if (!dev)
@@ -4533,7 +4535,7 @@ int device_rename(struct device *dev, const char *new_name)
        }
 
        if (dev->class) {
-               struct subsys_private *sp = class_to_subsys(dev->class);
+               sp = class_to_subsys(dev->class);
 
                if (!sp) {
                        error = -EINVAL;
@@ -4542,16 +4544,19 @@ int device_rename(struct device *dev, const char *new_name)
 
                error = sysfs_rename_link_ns(&sp->subsys.kobj, kobj, old_device_name,
                                             new_name, kobject_namespace(kobj));
-               subsys_put(sp);
                if (error)
                        goto out;
+
+               is_link_renamed = true;
        }
 
        error = kobject_rename(kobj, new_name);
-       if (error)
-               goto out;
-
 out:
+       if (error && is_link_renamed)
+               sysfs_rename_link_ns(&sp->subsys.kobj, kobj, new_name,
+                                    old_device_name, kobject_namespace(kobj));
+       subsys_put(sp);
+
        put_device(dev);
 
        kfree(old_device_name);