6.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu quic_zijuhu@quicinc.com
[ 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: 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@quici... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/base/core.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c index b5399262198a6..6c1a944c00d9b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -4515,9 +4515,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) @@ -4532,7 +4534,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; @@ -4541,16 +4543,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);