diff options
| author | Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> | 2002-12-29 13:51:34 -0600 |
|---|---|---|
| committer | Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> | 2002-12-29 13:51:34 -0600 |
| commit | f5a46614de328e867f778e4dffa71b48eb29340f (patch) | |
| tree | e20250a27ae5dbeb927a7d085cd7dc162aa829e5 /kernel | |
| parent | 8f99d72cc9359b80ef6c50a00ad098c78ac035ed (diff) | |
| parent | bec7aa00ffe5b1270837b965fdfe80be3e8e6e2e (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.c | 7 | ||||
| -rw-r--r-- | kernel/exit.c | 6 | ||||
| -rw-r--r-- | kernel/fork.c | 14 | ||||
| -rw-r--r-- | kernel/intermodule.c | 2 | ||||
| -rw-r--r-- | kernel/ksyms.c | 1 | ||||
| -rw-r--r-- | kernel/module.c | 112 | ||||
| -rw-r--r-- | kernel/printk.c | 2 | ||||
| -rw-r--r-- | kernel/resource.c | 2 |
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; |
