driver core: Fix error handling in driver API device_rename()

[ Upstream commit 6d8249ac29bc23260dfa9747eb398ce76012d73c ]

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: f349cf3473 ("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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Zijun Hu 2024-07-22 22:48:10 +08:00 committed by Greg Kroah-Hartman
parent 0f115888ea
commit dd69fb026c
1 changed files with 10 additions and 5 deletions

View File

@ -4485,9 +4485,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)
@ -4502,7 +4504,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;
@ -4511,16 +4513,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);