diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2010-06-05 13:17:36 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-06-04 21:47:36 -0400 |
commit | 80a3d1bb410e000e176931a076cdf19a1e89a955 (patch) | |
tree | 6883bbc3b2032d9604374513ccfd496dd63e76ba /kernel/module.c | |
parent | c8e21ced08b39ef8dfe7236fb2a923a95f645262 (diff) |
module: move sysfs exposure to end of load_module
This means a little extra work, but is more logical: we don't put
anything in sysfs until we're about to put the module into the
global list an parse its parameters.
This also gives us a logical place to put duplicate module detection
in the next patch.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'kernel/module.c')
-rw-r--r-- | kernel/module.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/kernel/module.c b/kernel/module.c index bbb1d812c79c..c690d9885797 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
@@ -560,7 +560,6 @@ static int already_uses(struct module *a, struct module *b) | |||
560 | */ | 560 | */ |
561 | static int add_module_usage(struct module *a, struct module *b) | 561 | static int add_module_usage(struct module *a, struct module *b) |
562 | { | 562 | { |
563 | int no_warn; | ||
564 | struct module_use *use; | 563 | struct module_use *use; |
565 | 564 | ||
566 | DEBUGP("Allocating new usage for %s.\n", a->name); | 565 | DEBUGP("Allocating new usage for %s.\n", a->name); |
@@ -574,7 +573,6 @@ static int add_module_usage(struct module *a, struct module *b) | |||
574 | use->target = b; | 573 | use->target = b; |
575 | list_add(&use->source_list, &b->source_list); | 574 | list_add(&use->source_list, &b->source_list); |
576 | list_add(&use->target_list, &a->target_list); | 575 | list_add(&use->target_list, &a->target_list); |
577 | no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name); | ||
578 | return 0; | 576 | return 0; |
579 | } | 577 | } |
580 | 578 | ||
@@ -619,7 +617,6 @@ static void module_unload_free(struct module *mod) | |||
619 | list_del(&use->source_list); | 617 | list_del(&use->source_list); |
620 | list_del(&use->target_list); | 618 | list_del(&use->target_list); |
621 | kfree(use); | 619 | kfree(use); |
622 | sysfs_remove_link(i->holders_dir, mod->name); | ||
623 | } | 620 | } |
624 | } | 621 | } |
625 | 622 | ||
@@ -1303,6 +1300,29 @@ static inline void remove_notes_attrs(struct module *mod) | |||
1303 | #endif | 1300 | #endif |
1304 | 1301 | ||
1305 | #ifdef CONFIG_SYSFS | 1302 | #ifdef CONFIG_SYSFS |
1303 | static void add_usage_links(struct module *mod) | ||
1304 | { | ||
1305 | #ifdef CONFIG_MODULE_UNLOAD | ||
1306 | struct module_use *use; | ||
1307 | int nowarn; | ||
1308 | |||
1309 | list_for_each_entry(use, &mod->target_list, target_list) { | ||
1310 | nowarn = sysfs_create_link(use->target->holders_dir, | ||
1311 | &mod->mkobj.kobj, mod->name); | ||
1312 | } | ||
1313 | #endif | ||
1314 | } | ||
1315 | |||
1316 | static void del_usage_links(struct module *mod) | ||
1317 | { | ||
1318 | #ifdef CONFIG_MODULE_UNLOAD | ||
1319 | struct module_use *use; | ||
1320 | |||
1321 | list_for_each_entry(use, &mod->target_list, target_list) | ||
1322 | sysfs_remove_link(use->target->holders_dir, mod->name); | ||
1323 | #endif | ||
1324 | } | ||
1325 | |||
1306 | int module_add_modinfo_attrs(struct module *mod) | 1326 | int module_add_modinfo_attrs(struct module *mod) |
1307 | { | 1327 | { |
1308 | struct module_attribute *attr; | 1328 | struct module_attribute *attr; |
@@ -1385,6 +1405,10 @@ int mod_sysfs_setup(struct module *mod, | |||
1385 | { | 1405 | { |
1386 | int err; | 1406 | int err; |
1387 | 1407 | ||
1408 | err = mod_sysfs_init(mod); | ||
1409 | if (err) | ||
1410 | goto out; | ||
1411 | |||
1388 | mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj); | 1412 | mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj); |
1389 | if (!mod->holders_dir) { | 1413 | if (!mod->holders_dir) { |
1390 | err = -ENOMEM; | 1414 | err = -ENOMEM; |
@@ -1399,6 +1423,8 @@ int mod_sysfs_setup(struct module *mod, | |||
1399 | if (err) | 1423 | if (err) |
1400 | goto out_unreg_param; | 1424 | goto out_unreg_param; |
1401 | 1425 | ||
1426 | add_usage_links(mod); | ||
1427 | |||
1402 | kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); | 1428 | kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD); |
1403 | return 0; | 1429 | return 0; |
1404 | 1430 | ||
@@ -1408,6 +1434,7 @@ out_unreg_holders: | |||
1408 | kobject_put(mod->holders_dir); | 1434 | kobject_put(mod->holders_dir); |
1409 | out_unreg: | 1435 | out_unreg: |
1410 | kobject_put(&mod->mkobj.kobj); | 1436 | kobject_put(&mod->mkobj.kobj); |
1437 | out: | ||
1411 | return err; | 1438 | return err; |
1412 | } | 1439 | } |
1413 | 1440 | ||
@@ -1422,10 +1449,15 @@ static void mod_sysfs_fini(struct module *mod) | |||
1422 | { | 1449 | { |
1423 | } | 1450 | } |
1424 | 1451 | ||
1452 | static void del_usage_links(struct module *mod) | ||
1453 | { | ||
1454 | } | ||
1455 | |||
1425 | #endif /* CONFIG_SYSFS */ | 1456 | #endif /* CONFIG_SYSFS */ |
1426 | 1457 | ||
1427 | static void mod_kobject_remove(struct module *mod) | 1458 | static void mod_kobject_remove(struct module *mod) |
1428 | { | 1459 | { |
1460 | del_usage_links(mod); | ||
1429 | module_remove_modinfo_attrs(mod); | 1461 | module_remove_modinfo_attrs(mod); |
1430 | module_param_sysfs_remove(mod); | 1462 | module_param_sysfs_remove(mod); |
1431 | kobject_put(mod->mkobj.drivers_dir); | 1463 | kobject_put(mod->mkobj.drivers_dir); |
@@ -2242,11 +2274,6 @@ static noinline struct module *load_module(void __user *umod, | |||
2242 | /* Now we've moved module, initialize linked lists, etc. */ | 2274 | /* Now we've moved module, initialize linked lists, etc. */ |
2243 | module_unload_init(mod); | 2275 | module_unload_init(mod); |
2244 | 2276 | ||
2245 | /* add kobject, so we can reference it. */ | ||
2246 | err = mod_sysfs_init(mod); | ||
2247 | if (err) | ||
2248 | goto free_unload; | ||
2249 | |||
2250 | /* Set up license info based on the info section */ | 2277 | /* Set up license info based on the info section */ |
2251 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); | 2278 | set_license(mod, get_modinfo(sechdrs, infoindex, "license")); |
2252 | 2279 | ||
@@ -2443,6 +2470,7 @@ static noinline struct module *load_module(void __user *umod, | |||
2443 | err = mod_sysfs_setup(mod, mod->kp, mod->num_kp); | 2470 | err = mod_sysfs_setup(mod, mod->kp, mod->num_kp); |
2444 | if (err < 0) | 2471 | if (err < 0) |
2445 | goto unlink; | 2472 | goto unlink; |
2473 | |||
2446 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 2474 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
2447 | add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 2475 | add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
2448 | 2476 | ||
@@ -2461,9 +2489,6 @@ static noinline struct module *load_module(void __user *umod, | |||
2461 | module_arch_cleanup(mod); | 2489 | module_arch_cleanup(mod); |
2462 | cleanup: | 2490 | cleanup: |
2463 | free_modinfo(mod); | 2491 | free_modinfo(mod); |
2464 | kobject_del(&mod->mkobj.kobj); | ||
2465 | kobject_put(&mod->mkobj.kobj); | ||
2466 | free_unload: | ||
2467 | module_unload_free(mod); | 2492 | module_unload_free(mod); |
2468 | #if defined(CONFIG_MODULE_UNLOAD) | 2493 | #if defined(CONFIG_MODULE_UNLOAD) |
2469 | free_percpu(mod->refptr); | 2494 | free_percpu(mod->refptr); |