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;
 }
