summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>2002-12-29 13:51:34 -0600
committerKai Germaschewski <kai@tp1.ruhr-uni-bochum.de>2002-12-29 13:51:34 -0600
commitf5a46614de328e867f778e4dffa71b48eb29340f (patch)
treee20250a27ae5dbeb927a7d085cd7dc162aa829e5 /kernel
parent8f99d72cc9359b80ef6c50a00ad098c78ac035ed (diff)
parentbec7aa00ffe5b1270837b965fdfe80be3e8e6e2e (diff)
Merge tp1.ruhr-uni-bochum.de:/home/kai/kernel/v2.5/linux-2.5
into tp1.ruhr-uni-bochum.de:/home/kai/kernel/v2.5/linux-2.5.make
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exec_domain.c7
-rw-r--r--kernel/exit.c6
-rw-r--r--kernel/fork.c14
-rw-r--r--kernel/intermodule.c2
-rw-r--r--kernel/ksyms.c1
-rw-r--r--kernel/module.c112
-rw-r--r--kernel/printk.c2
-rw-r--r--kernel/resource.c2
8 files changed, 67 insertions, 79 deletions
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index e0b31f7f5243..162a5c23e606 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -172,7 +172,7 @@ __set_personality(u_long personality)
fsp = copy_fs_struct(current->fs);
if (fsp == NULL) {
- put_exec_domain(ep);
+ module_put(ep->module);
return -ENOMEM;;
}
@@ -194,10 +194,7 @@ __set_personality(u_long personality)
current_thread_info()->exec_domain = ep;
set_fs_altroot();
- put_exec_domain(oep);
-
- printk(KERN_DEBUG "[%s:%d]: set personality to %lx\n",
- current->comm, current->pid, personality);
+ module_put(oep->module);
return 0;
}
diff --git a/kernel/exit.c b/kernel/exit.c
index 5e7fcdaa6221..6adea537242a 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -664,9 +664,9 @@ fake_volatile:
if (current->leader)
disassociate_ctty(1);
- put_exec_domain(tsk->thread_info->exec_domain);
- if (tsk->binfmt && tsk->binfmt->module)
- __MOD_DEC_USE_COUNT(tsk->binfmt->module);
+ module_put(tsk->thread_info->exec_domain->module);
+ if (tsk->binfmt)
+ module_put(tsk->binfmt->module);
tsk->exit_code = code;
exit_notify();
diff --git a/kernel/fork.c b/kernel/fork.c
index b8771509f285..6f7298827344 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -743,10 +743,11 @@ static struct task_struct *copy_process(unsigned long clone_flags,
if (nr_threads >= max_threads)
goto bad_fork_cleanup_count;
- get_exec_domain(p->thread_info->exec_domain);
+ if (!try_module_get(p->thread_info->exec_domain->module))
+ goto bad_fork_cleanup_count;
- if (p->binfmt && p->binfmt->module)
- __MOD_INC_USE_COUNT(p->binfmt->module);
+ if (p->binfmt && !try_module_get(p->binfmt->module))
+ goto bad_fork_cleanup_put_domain;
#ifdef CONFIG_PREEMPT
/*
@@ -958,9 +959,10 @@ bad_fork_cleanup_security:
bad_fork_cleanup:
if (p->pid > 0)
free_pidmap(p->pid);
- put_exec_domain(p->thread_info->exec_domain);
- if (p->binfmt && p->binfmt->module)
- __MOD_DEC_USE_COUNT(p->binfmt->module);
+ if (p->binfmt)
+ module_put(p->binfmt->module);
+bad_fork_cleanup_put_domain:
+ module_put(p->thread_info->exec_domain->module);
bad_fork_cleanup_count:
atomic_dec(&p->user->processes);
free_uid(p->user);
diff --git a/kernel/intermodule.c b/kernel/intermodule.c
index a6cd1d08afa4..9228ca4fe035 100644
--- a/kernel/intermodule.c
+++ b/kernel/intermodule.c
@@ -166,7 +166,7 @@ void inter_module_put(const char *im_name)
ime = list_entry(tmp, struct inter_module_entry, list);
if (strcmp(ime->im_name, im_name) == 0) {
if (ime->owner)
- __MOD_DEC_USE_COUNT(ime->owner);
+ module_put(ime->owner);
spin_unlock(&ime_lock);
return;
}
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index f634f12d4bef..cd49778dd1f3 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -299,6 +299,7 @@ EXPORT_SYMBOL(dcache_dir_open);
EXPORT_SYMBOL(dcache_dir_close);
EXPORT_SYMBOL(dcache_dir_lseek);
EXPORT_SYMBOL(dcache_readdir);
+EXPORT_SYMBOL(simple_getattr);
EXPORT_SYMBOL(simple_statfs);
EXPORT_SYMBOL(simple_lookup);
EXPORT_SYMBOL(simple_dir_operations);
diff --git a/kernel/module.c b/kernel/module.c
index c73b19336f1e..4b789cf97f5d 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -60,6 +60,13 @@ struct sizes
unsigned long core_size;
};
+/* Stub function for modules which don't have an initfn */
+int init_module(void)
+{
+ return 0;
+}
+EXPORT_SYMBOL(init_module);
+
/* Find a symbol, return value and the symbol group */
static unsigned long __find_symbol(const char *name,
struct kernel_symbol_group **group)
@@ -357,6 +364,12 @@ static inline int try_force(unsigned int flags)
}
#endif /* CONFIG_MODULE_FORCE_UNLOAD */
+/* Stub function for modules which don't have an exitfn */
+void cleanup_module(void)
+{
+}
+EXPORT_SYMBOL(cleanup_module);
+
asmlinkage long
sys_delete_module(const char *name_user, unsigned int flags)
{
@@ -405,7 +418,9 @@ sys_delete_module(const char *name_user, unsigned int flags)
}
}
- if (!mod->exit || mod->unsafe) {
+ /* If it has an init func, it must have an exit func to unload */
+ if ((mod->init != init_module && mod->exit == cleanup_module)
+ || mod->unsafe) {
forced = try_force(flags);
if (!forced) {
/* This module can't be removed */
@@ -452,8 +467,7 @@ sys_delete_module(const char *name_user, unsigned int flags)
destroy:
/* Final destruction now noone is using it. */
- if (mod->exit)
- mod->exit();
+ mod->exit();
free_module(mod);
out:
@@ -473,7 +487,7 @@ static void print_unload_info(struct seq_file *m, struct module *mod)
if (mod->unsafe)
seq_printf(m, " [unsafe]");
- if (!mod->exit)
+ if (mod->init != init_module && mod->exit == cleanup_module)
seq_printf(m, " [permanent]");
seq_printf(m, "\n");
@@ -707,15 +721,15 @@ static void free_module(struct module *mod)
list_del(&mod->extable.list);
spin_unlock_irq(&modlist_lock);
- /* These may be NULL, but that's OK */
- module_free(mod, mod->module_init);
- module_free(mod, mod->module_core);
-
/* Module unload stuff */
module_unload_free(mod);
- /* Finally, free the module structure */
- module_free(mod, mod);
+ /* This may be NULL, but that's OK */
+ module_free(mod, mod->module_init);
+ kfree(mod->args);
+
+ /* Finally, free the core (containing the module structure) */
+ module_free(mod, mod->module_core);
}
void *__symbol_get(const char *symbol)
@@ -770,27 +784,6 @@ static void *copy_section(const char *name,
return dest;
}
-/* Look for the special symbols */
-static int grab_private_symbols(Elf_Shdr *sechdrs,
- unsigned int symbolsec,
- const char *strtab,
- struct module *mod)
-{
- Elf_Sym *sym = (void *)sechdrs[symbolsec].sh_offset;
- unsigned int i;
-
- for (i = 1; i < sechdrs[symbolsec].sh_size/sizeof(*sym); i++) {
- if (symbol_is("__initfn", strtab + sym[i].st_name))
- mod->init = (void *)sym[i].st_value;
-#ifdef CONFIG_MODULE_UNLOAD
- if (symbol_is("__exitfn", strtab + sym[i].st_name))
- mod->exit = (void *)sym[i].st_value;
-#endif
- }
-
- return 0;
-}
-
/* Deal with the given section */
static int handle_section(const char *name,
Elf_Shdr *sechdrs,
@@ -809,9 +802,6 @@ static int handle_section(const char *name,
case SHT_RELA:
ret = apply_relocate_add(sechdrs, strtab, symindex, i, mod);
break;
- case SHT_SYMTAB:
- ret = grab_private_symbols(sechdrs, i, strtab, mod);
- break;
default:
DEBUGP("Ignoring section %u: %s\n", i,
sechdrs[i].sh_type==SHT_NULL ? "NULL":
@@ -919,9 +909,6 @@ static void simplify_symbols(Elf_Shdr *sechdrs,
strtab + sym[i].st_name,
mod,
&ksg);
- /* We fake up "__this_module" */
- if (symbol_is("__this_module", strtab+sym[i].st_name))
- sym[i].st_value = (unsigned long)mod;
}
}
}
@@ -963,9 +950,9 @@ static struct module *load_module(void *umod,
{
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
- char *secstrings;
+ char *secstrings, *args;
unsigned int i, symindex, exportindex, strindex, setupindex, exindex,
- modnameindex, obsparmindex;
+ modindex, obsparmindex;
long arglen;
unsigned long common_length;
struct sizes sizes, used;
@@ -1006,7 +993,7 @@ static struct module *load_module(void *umod,
exportindex = setupindex = obsparmindex = 0;
/* And these should exist, but gcc whinges if we don't init them */
- symindex = strindex = exindex = modnameindex = 0;
+ symindex = strindex = exindex = modindex = 0;
/* Find where important sections are */
for (i = 1; i < hdr->e_shnum; i++) {
@@ -1014,21 +1001,19 @@ static struct module *load_module(void *umod,
/* Internal symbols */
DEBUGP("Symbol table in section %u\n", i);
symindex = i;
+ /* Strings */
+ strindex = sechdrs[i].sh_link;
+ DEBUGP("String table found in section %u\n", strindex);
} else if (strcmp(secstrings+sechdrs[i].sh_name,
- ".gnu.linkonce.modname") == 0) {
- /* This module's name */
- DEBUGP("Module name in section %u\n", i);
- modnameindex = i;
+ ".gnu.linkonce.this_module") == 0) {
+ /* The module struct */
+ DEBUGP("Module in section %u\n", i);
+ modindex = i;
} else if (strcmp(secstrings+sechdrs[i].sh_name, "__ksymtab")
== 0) {
/* Exported symbols. */
DEBUGP("EXPORT table in section %u\n", i);
exportindex = i;
- } else if (strcmp(secstrings + sechdrs[i].sh_name, ".strtab")
- == 0) {
- /* Strings */
- DEBUGP("String table found in section %u\n", i);
- strindex = i;
} else if (strcmp(secstrings+sechdrs[i].sh_name, "__param")
== 0) {
/* Setup parameter info */
@@ -1057,39 +1042,35 @@ static struct module *load_module(void *umod,
#endif
}
- if (!modnameindex) {
- DEBUGP("Module has no name!\n");
+ if (!modindex) {
+ printk(KERN_WARNING "No module found in object\n");
err = -ENOEXEC;
goto free_hdr;
}
+ mod = (void *)hdr + sechdrs[modindex].sh_offset;
- /* Now allocate space for the module proper, and copy name and args. */
+ /* Now copy in args */
err = strlen_user(uargs);
if (err < 0)
goto free_hdr;
arglen = err;
- mod = module_alloc(sizeof(*mod) + arglen+1);
- if (!mod) {
+ args = kmalloc(arglen+1, GFP_KERNEL);
+ if (!args) {
err = -ENOMEM;
goto free_hdr;
}
- memset(mod, 0, sizeof(*mod) + arglen+1);
- if (copy_from_user(mod->args, uargs, arglen) != 0) {
+ if (copy_from_user(args, uargs, arglen+1) != 0) {
err = -EFAULT;
goto free_mod;
}
- strncpy(mod->name, (char *)hdr + sechdrs[modnameindex].sh_offset,
- sizeof(mod->name)-1);
if (find_module(mod->name)) {
err = -EEXIST;
goto free_mod;
}
- mod->symbols.owner = mod;
mod->state = MODULE_STATE_COMING;
- module_unload_init(mod);
/* How much space will we need? (Common area in first) */
common_length = read_commons(hdr, &sechdrs[symindex]);
@@ -1138,6 +1119,9 @@ static struct module *load_module(void *umod,
if (IS_ERR(ptr))
goto cleanup;
sechdrs[i].sh_offset = (unsigned long)ptr;
+ /* Have we just copied __this_module across? */
+ if (i == modindex)
+ mod = ptr;
} else {
sechdrs[i].sh_offset += (unsigned long)hdr;
}
@@ -1146,6 +1130,9 @@ static struct module *load_module(void *umod,
if (used.init_size > mod->init_size || used.core_size > mod->core_size)
BUG();
+ /* Now we've moved module, initialize linked lists, etc. */
+ module_unload_init(mod);
+
/* Fix up syms, so that st_value is a pointer to location. */
simplify_symbols(sechdrs, symindex, strindex, mod->module_core, mod);
@@ -1182,6 +1169,7 @@ static struct module *load_module(void *umod,
if (err < 0)
goto cleanup;
+ mod->args = args;
if (obsparmindex) {
err = obsolete_params(mod->name, mod->args,
(struct obsolete_modparm *)
@@ -1214,7 +1202,7 @@ static struct module *load_module(void *umod,
free_core:
module_free(mod, mod->module_core);
free_mod:
- module_free(mod, mod);
+ kfree(args);
free_hdr:
vfree(hdr);
if (err < 0) return ERR_PTR(err);
@@ -1265,7 +1253,7 @@ sys_init_module(void *umod,
up(&module_mutex);
/* Start the module */
- ret = mod->init ? mod->init() : 0;
+ ret = mod->init();
if (ret < 0) {
/* Init routine failed: abort. Try to protect us from
buggy refcounters. */
diff --git a/kernel/printk.c b/kernel/printk.c
index cbe027aaf151..bb1bcb0d723f 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -638,7 +638,7 @@ void register_console(struct console * console)
}
if (console->flags & CON_PRINTBUFFER) {
/*
- * release_cosole_sem() will print out the buffered messages for us.
+ * release_console_sem() will print out the buffered messages for us.
*/
spin_lock_irqsave(&logbuf_lock, flags);
con_start = log_start;
diff --git a/kernel/resource.c b/kernel/resource.c
index 9664ad073db7..83d04826245d 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -237,7 +237,7 @@ struct resource * __request_region(struct resource *parent, unsigned long start,
return res;
}
-int __check_region(struct resource *parent, unsigned long start, unsigned long n)
+int __deprecated __check_region(struct resource *parent, unsigned long start, unsigned long n)
{
struct resource * res;