patch-2.3.51 linux/kernel/module.c
Next file: linux/kernel/signal.c
Previous file: linux/kernel/ksyms.c
Back to the patch index
Back to the overall index
- Lines: 77
- Date:
Fri Mar 10 10:48:52 2000
- Orig file:
v2.3.50/linux/kernel/module.c
- Orig date:
Tue Dec 14 01:27:24 1999
diff -u --recursive --new-file v2.3.50/linux/kernel/module.c linux/kernel/module.c
@@ -350,6 +350,21 @@
return error;
}
+static spinlock_t unload_lock = SPIN_LOCK_UNLOCKED;
+int try_inc_mod_count(struct module *mod)
+{
+ int res = 1;
+ if (mod) {
+ spin_lock(&unload_lock);
+ if (mod->flags & MOD_DELETED)
+ res = 0;
+ else
+ __MOD_INC_USE_COUNT(mod);
+ spin_unlock(&unload_lock);
+ }
+ return res;
+}
+
asmlinkage long
sys_delete_module(const char *name_user)
{
@@ -377,11 +392,18 @@
}
put_mod_name(name);
error = -EBUSY;
- if (mod->refs != NULL || __MOD_IN_USE(mod))
+ if (mod->refs != NULL)
goto out;
- free_module(mod, 0);
- error = 0;
+ spin_lock(&unload_lock);
+ if (!__MOD_IN_USE(mod)) {
+ mod->flags |= MOD_DELETED;
+ spin_unlock(&unload_lock);
+ free_module(mod, 0);
+ error = 0;
+ } else {
+ spin_unlock(&unload_lock);
+ }
goto out;
}
@@ -390,6 +412,7 @@
something_changed = 0;
for (mod = module_list; mod != &kernel_module; mod = next) {
next = mod->next;
+ spin_lock(&unload_lock);
if (mod->refs == NULL
&& (mod->flags & MOD_AUTOCLEAN)
&& (mod->flags & MOD_RUNNING)
@@ -398,11 +421,16 @@
&& !__MOD_IN_USE(mod)) {
if ((mod->flags & MOD_VISITED)
&& !(mod->flags & MOD_JUST_FREED)) {
+ spin_unlock(&unload_lock);
mod->flags &= ~MOD_VISITED;
} else {
+ mod->flags |= MOD_DELETED;
+ spin_unlock(&unload_lock);
free_module(mod, 1);
something_changed = 1;
}
+ } else {
+ spin_unlock(&unload_lock);
}
}
if (something_changed)
@@ -775,7 +803,6 @@
/* Let the module clean up. */
- mod->flags |= MOD_DELETED;
if (mod->flags & MOD_RUNNING)
{
if(mod->cleanup)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)