diff -urN -X dontdiff linux/kernel/module.c 2327-p5-modlist/kernel/module.c --- linux/kernel/module.c Wed Nov 10 08:49:07 1999 +++ 2327-p5-modlist/kernel/module.c Wed Nov 10 12:38:12 1999 @@ -133,7 +133,6 @@ long namelen, error; struct module *mod; - write_lock(&modlist_lock); if (!capable(CAP_SYS_MODULE)) { error = -EPERM; goto err0; @@ -155,6 +154,7 @@ goto err1; } + write_lock(&modlist_lock); memset(mod, 0, sizeof(*mod)); mod->size_of_struct = sizeof(*mod); mod->next = module_list; @@ -165,13 +165,13 @@ put_mod_name(name); module_list = mod; /* link it in */ + write_unlock(&modlist_lock); error = (long) mod; goto err0; err1: put_mod_name(name); err0: - write_unlock(&modlist_lock); return error; } @@ -188,7 +188,6 @@ unsigned long mod_user_size; struct module_ref *dep; - write_lock(&modlist_lock); if (!capable(CAP_SYS_MODULE)) goto err0; if ((namelen = get_mod_name(name_user, &name)) < 0) { @@ -326,11 +325,13 @@ goto err3; } + read_lock(&modlist_lock); for (o = module_list; o != &kernel_module; o = o->next) if (o == d) goto found_dep; printk(KERN_ERR "init_module: found dependency that is " "(no longer?) a module.\n"); + read_unlock(&modlist_lock); goto err3; found_dep: @@ -340,6 +341,7 @@ /* Being referenced by a dependent module counts as a use as far as kmod is concerned. */ d->flags |= MOD_USED_ONCE; + read_unlock(&modlist_lock); } /* Free our temporary memory. */ @@ -367,7 +369,6 @@ err1: put_mod_name(name); err0: - write_unlock(&modlist_lock); return error; } @@ -379,7 +380,6 @@ long error = -EPERM; int something_changed; - write_lock(&modlist_lock); if (!capable(CAP_SYS_MODULE)) goto out; @@ -401,13 +401,16 @@ if (mod->refs != NULL || __MOD_IN_USE(mod)) goto out; + write_lock(&modlist_lock); free_module(mod, 0); + write_unlock(&modlist_lock); error = 0; goto out; } /* Do automatic reaping */ restart: + write_lock(&modlist_lock); something_changed = 0; for (mod = module_list; mod != &kernel_module; mod = next) { next = mod->next; @@ -426,13 +429,13 @@ } } } + write_unlock(&modlist_lock); if (something_changed) goto restart; for (mod = module_list; mod != &kernel_module; mod = mod->next) mod->flags &= ~MOD_JUST_FREED; error = 0; out: - write_unlock(&modlist_lock); return error; } @@ -451,10 +454,9 @@ len = strlen(mod->name)+1; if (len > bufsize) goto calc_space_needed; - if (copy_to_user(buf, mod->name, len)) { - read_unlock(&modlist_lock); + read_unlock(&modlist_lock); + if (copy_to_user(buf, mod->name, len)) return -EFAULT; - } buf += len; bufsize -= len; space += len; @@ -470,8 +472,8 @@ space += len; while ((mod = mod->next) != &kernel_module) space += strlen(mod->name)+1; - read_unlock(&modlist_lock); + if (put_user(space, ret)) return -EFAULT; else @@ -658,7 +660,6 @@ struct module *mod; int err; - read_lock(&modlist_lock); if (name_user == NULL) mod = &kernel_module; else { @@ -704,7 +705,6 @@ break; } out: - read_unlock(&modlist_lock); return err; } @@ -772,7 +772,6 @@ /* * Look for a module by name, ignoring modules marked for deletion. - * Callers must hold modlist_lock at least in read mode. */ static struct module * @@ -780,12 +779,14 @@ { struct module *mod; + read_lock(&modlist_lock); for (mod = module_list; mod ; mod = mod->next) { if (mod->flags & MOD_DELETED) continue; if (!strcmp(mod->name, name)) break; } + read_unlock(&modlist_lock); return mod; } .