patch-2.4.5 linux/kernel/module.c

Next file: linux/kernel/resource.c
Previous file: linux/kernel/ksyms.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.4/linux/kernel/module.c linux/kernel/module.c
@@ -554,8 +554,8 @@
 	put_mod_name(name);
 
 	/* Initialize the module.  */
-	mod->flags |= MOD_INITIALIZING;
 	atomic_set(&mod->uc.usecount,1);
+	mod->flags |= MOD_INITIALIZING;
 	if (mod->init && (error = mod->init()) != 0) {
 		atomic_set(&mod->uc.usecount,0);
 		mod->flags &= ~MOD_INITIALIZING;
@@ -613,11 +613,6 @@
 	if (name_user) {
 		if ((error = get_mod_name(name_user, &name)) < 0)
 			goto out;
-		if (error == 0) {
-			error = -EINVAL;
-			put_mod_name(name);
-			goto out;
-		}
 		error = -ENOENT;
 		if ((mod = find_module(name)) == NULL) {
 			put_mod_name(name);
@@ -847,7 +842,6 @@
 		bufsize -= len;
 		space += len;
 	}
-
 	if (put_user(i, ret))
 		return -EFAULT;
 	else
@@ -876,8 +870,11 @@
 		info.addr = (unsigned long)mod;
 		info.size = mod->size;
 		info.flags = mod->flags;
+		
+		/* usecount is one too high here - report appropriately to
+		   compensate for locking */
 		info.usecount = (mod_member_present(mod, can_unload)
-				 && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount));
+				 && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount)-1);
 
 		if (copy_to_user(buf, &info, sizeof(struct module_info)))
 			return -EFAULT;
@@ -909,15 +906,17 @@
 			goto out;
 		}
 		err = -ENOENT;
-		if (namelen == 0)
-			mod = &kernel_module;
-		else if ((mod = find_module(name)) == NULL) {
+		if ((mod = find_module(name)) == NULL) {
 			put_mod_name(name);
 			goto out;
 		}
 		put_mod_name(name);
 	}
 
+	/* __MOD_ touches the flags. We must avoid that */
+	
+	atomic_inc(&mod->uc.usecount);
+		
 	switch (which)
 	{
 	case 0:
@@ -942,6 +941,8 @@
 		err = -EINVAL;
 		break;
 	}
+	atomic_dec(&mod->uc.usecount);
+	
 out:
 	unlock_kernel();
 	return err;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)