patch-2.1.86 linux/kernel/module.c
Next file: linux/kernel/printk.c
Previous file: linux/kernel/ksyms.c
Back to the patch index
Back to the overall index
- Lines: 80
- Date:
Fri Feb 6 10:10:54 1998
- Orig file:
v2.1.85/linux/kernel/module.c
- Orig date:
Sun Jan 4 10:40:17 1998
diff -u --recursive --new-file v2.1.85/linux/kernel/module.c linux/kernel/module.c
@@ -54,7 +54,7 @@
static long get_mod_name(const char *user_name, char **buf);
static void put_mod_name(char *buf);
static struct module *find_module(const char *name);
-static void free_module(struct module *);
+static void free_module(struct module *, int tag_freed);
/*
@@ -363,6 +363,7 @@
struct module *mod, *next;
char *name;
long error = -EPERM;
+ int something_changed;
lock_kernel();
if (!suser())
@@ -386,25 +387,35 @@
if (mod->refs != NULL || __MOD_IN_USE(mod))
goto out;
- free_module(mod);
+ free_module(mod, 0);
error = 0;
goto out;
}
/* Do automatic reaping */
+restart:
+ something_changed = 0;
for (mod = module_list; mod != &kernel_module; mod = next) {
next = mod->next;
- if (mod->refs == NULL &&
- ((mod->flags
- & (MOD_AUTOCLEAN|MOD_RUNNING|MOD_DELETED|MOD_USED_ONCE))
- == (MOD_AUTOCLEAN|MOD_RUNNING|MOD_USED_ONCE)) &&
- !__MOD_IN_USE(mod)) {
- if (mod->flags & MOD_VISITED)
+ if (mod->refs == NULL
+ && (mod->flags & MOD_AUTOCLEAN)
+ && (mod->flags & MOD_RUNNING)
+ && !(mod->flags & MOD_DELETED)
+ && (mod->flags & MOD_USED_ONCE)
+ && !__MOD_IN_USE(mod)) {
+ if ((mod->flags & MOD_VISITED)
+ && !(mod->flags & MOD_JUST_FREED)) {
mod->flags &= ~MOD_VISITED;
- else
- free_module(mod);
+ } else {
+ free_module(mod, 1);
+ something_changed = 1;
+ }
}
}
+ if (something_changed)
+ goto restart;
+ for (mod = module_list; mod != &kernel_module; mod = mod->next)
+ mod->flags &= ~MOD_JUST_FREED;
error = 0;
out:
unlock_kernel();
@@ -764,7 +775,7 @@
*/
static void
-free_module(struct module *mod)
+free_module(struct module *mod, int tag_freed)
{
struct module_ref *dep;
unsigned i;
@@ -786,6 +797,8 @@
for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
continue;
*pp = dep->next_ref;
+ if (tag_freed && dep->dep->refs == NULL)
+ dep->dep->flags |= MOD_JUST_FREED;
}
/* And from the main module list. */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov