Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80a3d1bb authored by Rusty Russell's avatar Rusty Russell
Browse files

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: default avatarRusty Russell <rusty@rustcorp.com.au>
parent c8e21ced
Loading
Loading
Loading
Loading
+36 −11
Original line number Diff line number Diff line
@@ -560,7 +560,6 @@ static int already_uses(struct module *a, struct module *b)
 */
static int add_module_usage(struct module *a, struct module *b)
{
	int no_warn;
	struct module_use *use;

	DEBUGP("Allocating new usage for %s.\n", a->name);
@@ -574,7 +573,6 @@ static int add_module_usage(struct module *a, struct module *b)
	use->target = b;
	list_add(&use->source_list, &b->source_list);
	list_add(&use->target_list, &a->target_list);
	no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
	return 0;
}

@@ -619,7 +617,6 @@ static void module_unload_free(struct module *mod)
		list_del(&use->source_list);
		list_del(&use->target_list);
		kfree(use);
		sysfs_remove_link(i->holders_dir, mod->name);
	}
}

@@ -1303,6 +1300,29 @@ static inline void remove_notes_attrs(struct module *mod)
#endif

#ifdef CONFIG_SYSFS
static void add_usage_links(struct module *mod)
{
#ifdef CONFIG_MODULE_UNLOAD
	struct module_use *use;
	int nowarn;

	list_for_each_entry(use, &mod->target_list, target_list) {
		nowarn = sysfs_create_link(use->target->holders_dir,
					   &mod->mkobj.kobj, mod->name);
	}
#endif
}

static void del_usage_links(struct module *mod)
{
#ifdef CONFIG_MODULE_UNLOAD
	struct module_use *use;

	list_for_each_entry(use, &mod->target_list, target_list)
		sysfs_remove_link(use->target->holders_dir, mod->name);
#endif
}

int module_add_modinfo_attrs(struct module *mod)
{
	struct module_attribute *attr;
@@ -1385,6 +1405,10 @@ int mod_sysfs_setup(struct module *mod,
{
	int err;

	err = mod_sysfs_init(mod);
	if (err)
		goto out;

	mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj);
	if (!mod->holders_dir) {
		err = -ENOMEM;
@@ -1399,6 +1423,8 @@ int mod_sysfs_setup(struct module *mod,
	if (err)
		goto out_unreg_param;

	add_usage_links(mod);

	kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
	return 0;

@@ -1408,6 +1434,7 @@ out_unreg_holders:
	kobject_put(mod->holders_dir);
out_unreg:
	kobject_put(&mod->mkobj.kobj);
out:
	return err;
}

@@ -1422,10 +1449,15 @@ static void mod_sysfs_fini(struct module *mod)
{
}

static void del_usage_links(struct module *mod)
{
}

#endif /* CONFIG_SYSFS */

static void mod_kobject_remove(struct module *mod)
{
	del_usage_links(mod);
	module_remove_modinfo_attrs(mod);
	module_param_sysfs_remove(mod);
	kobject_put(mod->mkobj.drivers_dir);
@@ -2242,11 +2274,6 @@ static noinline struct module *load_module(void __user *umod,
	/* Now we've moved module, initialize linked lists, etc. */
	module_unload_init(mod);

	/* add kobject, so we can reference it. */
	err = mod_sysfs_init(mod);
	if (err)
		goto free_unload;

	/* Set up license info based on the info section */
	set_license(mod, get_modinfo(sechdrs, infoindex, "license"));

@@ -2443,6 +2470,7 @@ static noinline struct module *load_module(void __user *umod,
	err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
	if (err < 0)
		goto unlink;

	add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
	add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);

@@ -2461,9 +2489,6 @@ static noinline struct module *load_module(void __user *umod,
	module_arch_cleanup(mod);
 cleanup:
	free_modinfo(mod);
	kobject_del(&mod->mkobj.kobj);
	kobject_put(&mod->mkobj.kobj);
 free_unload:
	module_unload_free(mod);
#if defined(CONFIG_MODULE_UNLOAD)
	free_percpu(mod->refptr);