Skip to content

Commit 85d2b0a

Browse files
arndbgregkh
authored andcommitted
module: don't ignore sysfs_create_link() failures
The sysfs_create_link() return code is marked as __must_check, but the module_add_driver() function tries hard to not care, by assigning the return code to a variable. When building with 'make W=1', gcc still warns because this variable is only assigned but not used: drivers/base/module.c: In function 'module_add_driver': drivers/base/module.c:36:6: warning: variable 'no_warn' set but not used [-Wunused-but-set-variable] Rework the code to properly unwind and return the error code to the caller. My reading of the original code was that it tries to not fail when the links already exist, so keep ignoring -EEXIST errors. Fixes: e17e0f5 ("Driver core: show drivers in /sys/module/") See-also: 4a7fb63 ("add __must_check to device management code") Signed-off-by: Arnd Bergmann <[email protected]> Reviewed-by: Luis Chamberlain <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 0bb322b commit 85d2b0a

File tree

3 files changed

+45
-15
lines changed

3 files changed

+45
-15
lines changed

drivers/base/base.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,14 @@ extern struct kset *devices_kset;
192192
void devices_kset_move_last(struct device *dev);
193193

194194
#if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
195-
void module_add_driver(struct module *mod, struct device_driver *drv);
195+
int module_add_driver(struct module *mod, struct device_driver *drv);
196196
void module_remove_driver(struct device_driver *drv);
197197
#else
198-
static inline void module_add_driver(struct module *mod,
199-
struct device_driver *drv) { }
198+
static inline int module_add_driver(struct module *mod,
199+
struct device_driver *drv)
200+
{
201+
return 0;
202+
}
200203
static inline void module_remove_driver(struct device_driver *drv) { }
201204
#endif
202205

drivers/base/bus.c

+8-1
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,12 @@ int bus_add_driver(struct device_driver *drv)
674674
if (error)
675675
goto out_del_list;
676676
}
677-
module_add_driver(drv->owner, drv);
677+
error = module_add_driver(drv->owner, drv);
678+
if (error) {
679+
printk(KERN_ERR "%s: failed to create module links for %s\n",
680+
__func__, drv->name);
681+
goto out_detach;
682+
}
678683

679684
error = driver_create_file(drv, &driver_attr_uevent);
680685
if (error) {
@@ -699,6 +704,8 @@ int bus_add_driver(struct device_driver *drv)
699704

700705
return 0;
701706

707+
out_detach:
708+
driver_detach(drv);
702709
out_del_list:
703710
klist_del(&priv->knode_bus);
704711
out_unregister:

drivers/base/module.c

+31-11
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ static void module_create_drivers_dir(struct module_kobject *mk)
3030
mutex_unlock(&drivers_dir_mutex);
3131
}
3232

33-
void module_add_driver(struct module *mod, struct device_driver *drv)
33+
int module_add_driver(struct module *mod, struct device_driver *drv)
3434
{
3535
char *driver_name;
36-
int no_warn;
3736
struct module_kobject *mk = NULL;
37+
int ret;
3838

3939
if (!drv)
40-
return;
40+
return 0;
4141

4242
if (mod)
4343
mk = &mod->mkobj;
@@ -56,17 +56,37 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
5656
}
5757

5858
if (!mk)
59-
return;
59+
return 0;
60+
61+
ret = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
62+
if (ret)
63+
return ret;
6064

61-
/* Don't check return codes; these calls are idempotent */
62-
no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
6365
driver_name = make_driver_name(drv);
64-
if (driver_name) {
65-
module_create_drivers_dir(mk);
66-
no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
67-
driver_name);
68-
kfree(driver_name);
66+
if (!driver_name) {
67+
ret = -ENOMEM;
68+
goto out;
69+
}
70+
71+
module_create_drivers_dir(mk);
72+
if (!mk->drivers_dir) {
73+
ret = -EINVAL;
74+
goto out;
6975
}
76+
77+
ret = sysfs_create_link(mk->drivers_dir, &drv->p->kobj, driver_name);
78+
if (ret)
79+
goto out;
80+
81+
kfree(driver_name);
82+
83+
return 0;
84+
out:
85+
sysfs_remove_link(&drv->p->kobj, "module");
86+
sysfs_remove_link(mk->drivers_dir, driver_name);
87+
kfree(driver_name);
88+
89+
return ret;
7090
}
7191

7292
void module_remove_driver(struct device_driver *drv)

0 commit comments

Comments
 (0)