diff options
author | Zijun Hu <quic_zijuhu@quicinc.com> | 2024-07-22 22:48:10 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-07-31 14:54:47 +0200 |
commit | 6d8249ac29bc23260dfa9747eb398ce76012d73c (patch) | |
tree | f472a5780747a2b8c3c3b097f255c1ffd066179d /drivers/base | |
parent | 4ea5e9deda3f4cbd471d29e6e99106e51be19c86 (diff) |
driver core: Fix error handling in driver API device_rename()
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>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/core.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index 3e82eaba4932..72798133ed63 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -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); |