diff options
-rw-r--r-- | include/linux/module.h | 1 | ||||
-rw-r--r-- | kernel/module.c | 77 | ||||
-rw-r--r-- | kernel/params.c | 10 |
3 files changed, 32 insertions, 56 deletions
diff --git a/include/linux/module.h b/include/linux/module.h index a25d5f61548c..70bd843c71cb 100644 --- a/include/linux/module.h +++ b/include/linux/module.h | |||
@@ -245,6 +245,7 @@ struct module | |||
245 | /* Sysfs stuff. */ | 245 | /* Sysfs stuff. */ |
246 | struct module_kobject mkobj; | 246 | struct module_kobject mkobj; |
247 | struct module_param_attrs *param_attrs; | 247 | struct module_param_attrs *param_attrs; |
248 | struct module_attribute *modinfo_attrs; | ||
248 | const char *version; | 249 | const char *version; |
249 | const char *srcversion; | 250 | const char *srcversion; |
250 | 251 | ||
diff --git a/kernel/module.c b/kernel/module.c index 5ca99fbe9f44..77764f22f021 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -429,7 +429,6 @@ static inline void percpu_modcopy(void *pcpudst, const void *src, | |||
429 | } | 429 | } |
430 | #endif /* CONFIG_SMP */ | 430 | #endif /* CONFIG_SMP */ |
431 | 431 | ||
432 | #ifdef CONFIG_MODULE_UNLOAD | ||
433 | #define MODINFO_ATTR(field) \ | 432 | #define MODINFO_ATTR(field) \ |
434 | static void setup_modinfo_##field(struct module *mod, const char *s) \ | 433 | static void setup_modinfo_##field(struct module *mod, const char *s) \ |
435 | { \ | 434 | { \ |
@@ -461,12 +460,7 @@ static struct module_attribute modinfo_##field = { \ | |||
461 | MODINFO_ATTR(version); | 460 | MODINFO_ATTR(version); |
462 | MODINFO_ATTR(srcversion); | 461 | MODINFO_ATTR(srcversion); |
463 | 462 | ||
464 | static struct module_attribute *modinfo_attrs[] = { | 463 | #ifdef CONFIG_MODULE_UNLOAD |
465 | &modinfo_version, | ||
466 | &modinfo_srcversion, | ||
467 | NULL, | ||
468 | }; | ||
469 | |||
470 | /* Init the unload section of the module. */ | 464 | /* Init the unload section of the module. */ |
471 | static void module_unload_init(struct module *mod) | 465 | static void module_unload_init(struct module *mod) |
472 | { | 466 | { |
@@ -781,6 +775,15 @@ static inline void module_unload_init(struct module *mod) | |||
781 | } | 775 | } |
782 | #endif /* CONFIG_MODULE_UNLOAD */ | 776 | #endif /* CONFIG_MODULE_UNLOAD */ |
783 | 777 | ||
778 | static struct module_attribute *modinfo_attrs[] = { | ||
779 | &modinfo_version, | ||
780 | &modinfo_srcversion, | ||
781 | #ifdef CONFIG_MODULE_UNLOAD | ||
782 | &refcnt, | ||
783 | #endif | ||
784 | NULL, | ||
785 | }; | ||
786 | |||
784 | #ifdef CONFIG_OBSOLETE_MODPARM | 787 | #ifdef CONFIG_OBSOLETE_MODPARM |
785 | /* Bounds checking done below */ | 788 | /* Bounds checking done below */ |
786 | static int obsparm_copy_string(const char *val, struct kernel_param *kp) | 789 | static int obsparm_copy_string(const char *val, struct kernel_param *kp) |
@@ -1106,37 +1109,28 @@ static inline void remove_sect_attrs(struct module *mod) | |||
1106 | } | 1109 | } |
1107 | #endif /* CONFIG_KALLSYMS */ | 1110 | #endif /* CONFIG_KALLSYMS */ |
1108 | 1111 | ||
1109 | |||
1110 | #ifdef CONFIG_MODULE_UNLOAD | ||
1111 | static inline int module_add_refcnt_attr(struct module *mod) | ||
1112 | { | ||
1113 | return sysfs_create_file(&mod->mkobj.kobj, &refcnt.attr); | ||
1114 | } | ||
1115 | static void module_remove_refcnt_attr(struct module *mod) | ||
1116 | { | ||
1117 | return sysfs_remove_file(&mod->mkobj.kobj, &refcnt.attr); | ||
1118 | } | ||
1119 | #else | ||
1120 | static inline int module_add_refcnt_attr(struct module *mod) | ||
1121 | { | ||
1122 | return 0; | ||
1123 | } | ||
1124 | static void module_remove_refcnt_attr(struct module *mod) | ||
1125 | { | ||
1126 | } | ||
1127 | #endif | ||
1128 | |||
1129 | #ifdef CONFIG_MODULE_UNLOAD | ||
1130 | static int module_add_modinfo_attrs(struct module *mod) | 1112 | static int module_add_modinfo_attrs(struct module *mod) |
1131 | { | 1113 | { |
1132 | struct module_attribute *attr; | 1114 | struct module_attribute *attr; |
1115 | struct module_attribute *temp_attr; | ||
1133 | int error = 0; | 1116 | int error = 0; |
1134 | int i; | 1117 | int i; |
1135 | 1118 | ||
1119 | mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) * | ||
1120 | (ARRAY_SIZE(modinfo_attrs) + 1)), | ||
1121 | GFP_KERNEL); | ||
1122 | if (!mod->modinfo_attrs) | ||
1123 | return -ENOMEM; | ||
1124 | |||
1125 | temp_attr = mod->modinfo_attrs; | ||
1136 | for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) { | 1126 | for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) { |
1137 | if (!attr->test || | 1127 | if (!attr->test || |
1138 | (attr->test && attr->test(mod))) | 1128 | (attr->test && attr->test(mod))) { |
1139 | error = sysfs_create_file(&mod->mkobj.kobj,&attr->attr); | 1129 | memcpy(temp_attr, attr, sizeof(*temp_attr)); |
1130 | temp_attr->attr.owner = mod; | ||
1131 | error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr); | ||
1132 | ++temp_attr; | ||
1133 | } | ||
1140 | } | 1134 | } |
1141 | return error; | 1135 | return error; |
1142 | } | 1136 | } |
@@ -1146,12 +1140,16 @@ static void module_remove_modinfo_attrs(struct module *mod) | |||
1146 | struct module_attribute *attr; | 1140 | struct module_attribute *attr; |
1147 | int i; | 1141 | int i; |
1148 | 1142 | ||
1149 | for (i = 0; (attr = modinfo_attrs[i]); i++) { | 1143 | for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) { |
1144 | /* pick a field to test for end of list */ | ||
1145 | if (!attr->attr.name) | ||
1146 | break; | ||
1150 | sysfs_remove_file(&mod->mkobj.kobj,&attr->attr); | 1147 | sysfs_remove_file(&mod->mkobj.kobj,&attr->attr); |
1151 | attr->free(mod); | 1148 | if (attr->free) |
1149 | attr->free(mod); | ||
1152 | } | 1150 | } |
1151 | kfree(mod->modinfo_attrs); | ||
1153 | } | 1152 | } |
1154 | #endif | ||
1155 | 1153 | ||
1156 | static int mod_sysfs_setup(struct module *mod, | 1154 | static int mod_sysfs_setup(struct module *mod, |
1157 | struct kernel_param *kparam, | 1155 | struct kernel_param *kparam, |
@@ -1169,19 +1167,13 @@ static int mod_sysfs_setup(struct module *mod, | |||
1169 | if (err) | 1167 | if (err) |
1170 | goto out; | 1168 | goto out; |
1171 | 1169 | ||
1172 | err = module_add_refcnt_attr(mod); | ||
1173 | if (err) | ||
1174 | goto out_unreg; | ||
1175 | |||
1176 | err = module_param_sysfs_setup(mod, kparam, num_params); | 1170 | err = module_param_sysfs_setup(mod, kparam, num_params); |
1177 | if (err) | 1171 | if (err) |
1178 | goto out_unreg; | 1172 | goto out_unreg; |
1179 | 1173 | ||
1180 | #ifdef CONFIG_MODULE_UNLOAD | ||
1181 | err = module_add_modinfo_attrs(mod); | 1174 | err = module_add_modinfo_attrs(mod); |
1182 | if (err) | 1175 | if (err) |
1183 | goto out_unreg; | 1176 | goto out_unreg; |
1184 | #endif | ||
1185 | 1177 | ||
1186 | return 0; | 1178 | return 0; |
1187 | 1179 | ||
@@ -1193,10 +1185,7 @@ out: | |||
1193 | 1185 | ||
1194 | static void mod_kobject_remove(struct module *mod) | 1186 | static void mod_kobject_remove(struct module *mod) |
1195 | { | 1187 | { |
1196 | #ifdef CONFIG_MODULE_UNLOAD | ||
1197 | module_remove_modinfo_attrs(mod); | 1188 | module_remove_modinfo_attrs(mod); |
1198 | #endif | ||
1199 | module_remove_refcnt_attr(mod); | ||
1200 | module_param_sysfs_remove(mod); | 1189 | module_param_sysfs_remove(mod); |
1201 | 1190 | ||
1202 | kobject_unregister(&mod->mkobj.kobj); | 1191 | kobject_unregister(&mod->mkobj.kobj); |
@@ -1474,7 +1463,6 @@ static char *get_modinfo(Elf_Shdr *sechdrs, | |||
1474 | return NULL; | 1463 | return NULL; |
1475 | } | 1464 | } |
1476 | 1465 | ||
1477 | #ifdef CONFIG_MODULE_UNLOAD | ||
1478 | static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, | 1466 | static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, |
1479 | unsigned int infoindex) | 1467 | unsigned int infoindex) |
1480 | { | 1468 | { |
@@ -1489,7 +1477,6 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, | |||
1489 | attr->attr.name)); | 1477 | attr->attr.name)); |
1490 | } | 1478 | } |
1491 | } | 1479 | } |
1492 | #endif | ||
1493 | 1480 | ||
1494 | #ifdef CONFIG_KALLSYMS | 1481 | #ifdef CONFIG_KALLSYMS |
1495 | int is_exported(const char *name, const struct module *mod) | 1482 | int is_exported(const char *name, const struct module *mod) |
@@ -1803,10 +1790,8 @@ static struct module *load_module(void __user *umod, | |||
1803 | if (strcmp(mod->name, "driverloader") == 0) | 1790 | if (strcmp(mod->name, "driverloader") == 0) |
1804 | add_taint(TAINT_PROPRIETARY_MODULE); | 1791 | add_taint(TAINT_PROPRIETARY_MODULE); |
1805 | 1792 | ||
1806 | #ifdef CONFIG_MODULE_UNLOAD | ||
1807 | /* Set up MODINFO_ATTR fields */ | 1793 | /* Set up MODINFO_ATTR fields */ |
1808 | setup_modinfo(mod, sechdrs, infoindex); | 1794 | setup_modinfo(mod, sechdrs, infoindex); |
1809 | #endif | ||
1810 | 1795 | ||
1811 | /* Fix up syms, so that st_value is a pointer to location. */ | 1796 | /* Fix up syms, so that st_value is a pointer to location. */ |
1812 | err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex, | 1797 | err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex, |
diff --git a/kernel/params.c b/kernel/params.c index c76ad25e6a21..a29150582310 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -638,13 +638,8 @@ static ssize_t module_attr_show(struct kobject *kobj, | |||
638 | if (!attribute->show) | 638 | if (!attribute->show) |
639 | return -EIO; | 639 | return -EIO; |
640 | 640 | ||
641 | if (!try_module_get(mk->mod)) | ||
642 | return -ENODEV; | ||
643 | |||
644 | ret = attribute->show(attribute, mk->mod, buf); | 641 | ret = attribute->show(attribute, mk->mod, buf); |
645 | 642 | ||
646 | module_put(mk->mod); | ||
647 | |||
648 | return ret; | 643 | return ret; |
649 | } | 644 | } |
650 | 645 | ||
@@ -662,13 +657,8 @@ static ssize_t module_attr_store(struct kobject *kobj, | |||
662 | if (!attribute->store) | 657 | if (!attribute->store) |
663 | return -EIO; | 658 | return -EIO; |
664 | 659 | ||
665 | if (!try_module_get(mk->mod)) | ||
666 | return -ENODEV; | ||
667 | |||
668 | ret = attribute->store(attribute, mk->mod, buf, len); | 660 | ret = attribute->store(attribute, mk->mod, buf, len); |
669 | 661 | ||
670 | module_put(mk->mod); | ||
671 | |||
672 | return ret; | 662 | return ret; |
673 | } | 663 | } |
674 | 664 | ||