diff options
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/kernel/module.c b/kernel/module.c index 9de4209f6a67..8a94e054230c 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -537,6 +537,8 @@ static int already_uses(struct module *a, struct module *b) | |||
537 | static int use_module(struct module *a, struct module *b) | 537 | static int use_module(struct module *a, struct module *b) |
538 | { | 538 | { |
539 | struct module_use *use; | 539 | struct module_use *use; |
540 | int no_warn; | ||
541 | |||
540 | if (b == NULL || already_uses(a, b)) return 1; | 542 | if (b == NULL || already_uses(a, b)) return 1; |
541 | 543 | ||
542 | if (!strong_try_module_get(b)) | 544 | if (!strong_try_module_get(b)) |
@@ -552,6 +554,7 @@ static int use_module(struct module *a, struct module *b) | |||
552 | 554 | ||
553 | use->module_which_uses = a; | 555 | use->module_which_uses = a; |
554 | list_add(&use->list, &b->modules_which_use_me); | 556 | list_add(&use->list, &b->modules_which_use_me); |
557 | no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name); | ||
555 | return 1; | 558 | return 1; |
556 | } | 559 | } |
557 | 560 | ||
@@ -569,6 +572,7 @@ static void module_unload_free(struct module *mod) | |||
569 | module_put(i); | 572 | module_put(i); |
570 | list_del(&use->list); | 573 | list_del(&use->list); |
571 | kfree(use); | 574 | kfree(use); |
575 | sysfs_remove_link(i->holders_dir, mod->name); | ||
572 | /* There can be at most one match. */ | 576 | /* There can be at most one match. */ |
573 | break; | 577 | break; |
574 | } | 578 | } |
@@ -1106,9 +1110,7 @@ static void module_remove_modinfo_attrs(struct module *mod) | |||
1106 | kfree(mod->modinfo_attrs); | 1110 | kfree(mod->modinfo_attrs); |
1107 | } | 1111 | } |
1108 | 1112 | ||
1109 | static int mod_sysfs_setup(struct module *mod, | 1113 | static int mod_sysfs_init(struct module *mod) |
1110 | struct kernel_param *kparam, | ||
1111 | unsigned int num_params) | ||
1112 | { | 1114 | { |
1113 | int err; | 1115 | int err; |
1114 | 1116 | ||
@@ -1125,15 +1127,30 @@ static int mod_sysfs_setup(struct module *mod, | |||
1125 | kobj_set_kset_s(&mod->mkobj, module_subsys); | 1127 | kobj_set_kset_s(&mod->mkobj, module_subsys); |
1126 | mod->mkobj.mod = mod; | 1128 | mod->mkobj.mod = mod; |
1127 | 1129 | ||
1128 | /* delay uevent until full sysfs population */ | ||
1129 | kobject_init(&mod->mkobj.kobj); | 1130 | kobject_init(&mod->mkobj.kobj); |
1131 | |||
1132 | out: | ||
1133 | return err; | ||
1134 | } | ||
1135 | |||
1136 | static int mod_sysfs_setup(struct module *mod, | ||
1137 | struct kernel_param *kparam, | ||
1138 | unsigned int num_params) | ||
1139 | { | ||
1140 | int err; | ||
1141 | |||
1142 | /* delay uevent until full sysfs population */ | ||
1130 | err = kobject_add(&mod->mkobj.kobj); | 1143 | err = kobject_add(&mod->mkobj.kobj); |
1131 | if (err) | 1144 | if (err) |
1132 | goto out; | 1145 | goto out; |
1133 | 1146 | ||
1147 | mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders"); | ||
1148 | if (!mod->holders_dir) | ||
1149 | goto out_unreg; | ||
1150 | |||
1134 | err = module_param_sysfs_setup(mod, kparam, num_params); | 1151 | err = module_param_sysfs_setup(mod, kparam, num_params); |
1135 | if (err) | 1152 | if (err) |
1136 | goto out_unreg_drivers; | 1153 | goto out_unreg_holders; |
1137 | 1154 | ||
1138 | err = module_add_modinfo_attrs(mod); | 1155 | err = module_add_modinfo_attrs(mod); |
1139 | if (err) | 1156 | if (err) |
@@ -1144,7 +1161,9 @@ static int mod_sysfs_setup(struct module *mod, | |||
1144 | 1161 | ||
1145 | out_unreg_param: | 1162 | out_unreg_param: |
1146 | module_param_sysfs_remove(mod); | 1163 | module_param_sysfs_remove(mod); |
1147 | out_unreg_drivers: | 1164 | out_unreg_holders: |
1165 | kobject_unregister(mod->holders_dir); | ||
1166 | out_unreg: | ||
1148 | kobject_del(&mod->mkobj.kobj); | 1167 | kobject_del(&mod->mkobj.kobj); |
1149 | kobject_put(&mod->mkobj.kobj); | 1168 | kobject_put(&mod->mkobj.kobj); |
1150 | out: | 1169 | out: |
@@ -1157,6 +1176,8 @@ static void mod_kobject_remove(struct module *mod) | |||
1157 | module_param_sysfs_remove(mod); | 1176 | module_param_sysfs_remove(mod); |
1158 | if (mod->mkobj.drivers_dir) | 1177 | if (mod->mkobj.drivers_dir) |
1159 | kobject_unregister(mod->mkobj.drivers_dir); | 1178 | kobject_unregister(mod->mkobj.drivers_dir); |
1179 | if (mod->holders_dir) | ||
1180 | kobject_unregister(mod->holders_dir); | ||
1160 | 1181 | ||
1161 | kobject_unregister(&mod->mkobj.kobj); | 1182 | kobject_unregister(&mod->mkobj.kobj); |
1162 | } | 1183 | } |
@@ -1761,6 +1782,10 @@ static struct module *load_module(void __user *umod, | |||
1761 | /* Now we've moved module, initialize linked lists, etc. */ | 1782 | /* Now we've moved module, initialize linked lists, etc. */ |
1762 | module_unload_init(mod); | 1783 | module_unload_init(mod); |
1763 | 1784 | ||
1785 | /* Initialize kobject, so we can reference it. */ | ||
1786 | if (mod_sysfs_init(mod) != 0) | ||
1787 | goto cleanup; | ||
1788 | |||
1764 | /* Set up license info based on the info section */ | 1789 | /* Set up license info based on the info section */ |
1765 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); | 1790 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); |
1766 | 1791 | ||