]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - kernel/module.c
fix struct user_info export's sysfs interaction
[linux-2.6-omap-h63xx.git] / kernel / module.c
index 3202c9950073ebc05fb232a625da27d2ec35eee8..d03fcd9d652cd78523c559cc53d2929ee405727d 100644 (file)
@@ -47,8 +47,6 @@
 #include <asm/cacheflush.h>
 #include <linux/license.h>
 
-extern int module_sysfs_initialized;
-
 #if 0
 #define DEBUGP printk
 #else
@@ -81,7 +79,8 @@ int unregister_module_notifier(struct notifier_block * nb)
 }
 EXPORT_SYMBOL(unregister_module_notifier);
 
-/* We require a truly strong try_module_get() */
+/* We require a truly strong try_module_get(): 0 means failure due to
+   ongoing or failed initialization etc. */
 static inline int strong_try_module_get(struct module *mod)
 {
        if (mod && mod->state == MODULE_STATE_COMING)
@@ -952,7 +951,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
        ret = __find_symbol(name, &owner, &crc,
                        !(mod->taints & TAINT_PROPRIETARY_MODULE));
        if (ret) {
-               /* use_module can fail due to OOM, or module unloading */
+               /* use_module can fail due to OOM,
+                  or module initialization or unloading */
                if (!check_version(sechdrs, versindex, name, mod, crc) ||
                    !use_module(mod, owner))
                        ret = 0;
@@ -1120,7 +1120,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
                ++loaded;
        }
 
-       notes_attrs->dir = kobject_add_dir(&mod->mkobj.kobj, "notes");
+       notes_attrs->dir = kobject_create_and_add("notes", &mod->mkobj.kobj);
        if (!notes_attrs->dir)
                goto out;
 
@@ -1221,7 +1221,8 @@ int mod_sysfs_init(struct module *mod)
        err = kobject_set_name(&mod->mkobj.kobj, "%s", mod->name);
        if (err)
                goto out;
-       kobj_set_kset_s(&mod->mkobj, module_subsys);
+       mod->mkobj.kobj.kset = module_kset;
+       mod->mkobj.kobj.ktype = &module_ktype;
        mod->mkobj.mod = mod;
 
        kobject_init(&mod->mkobj.kobj);
@@ -1241,7 +1242,7 @@ int mod_sysfs_setup(struct module *mod,
        if (err)
                goto out;
 
-       mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders");
+       mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj);
        if (!mod->holders_dir) {
                err = -ENOMEM;
                goto out_unreg;
@@ -1369,7 +1370,7 @@ dup:
        return ret;
 }
 
-/* Change all symbols so that sh_value encodes the pointer directly. */
+/* Change all symbols so that st_value encodes the pointer directly. */
 static int simplify_symbols(Elf_Shdr *sechdrs,
                            unsigned int symindex,
                            const char *strtab,
@@ -2212,29 +2213,34 @@ static const char *get_ksymbol(struct module *mod,
 /* For kallsyms to ask for address resolution.  NULL means not found.
    We don't lock, as this is used for oops resolution and races are a
    lesser concern. */
+/* FIXME: Risky: returns a pointer into a module w/o lock */
 const char *module_address_lookup(unsigned long addr,
                                  unsigned long *size,
                                  unsigned long *offset,
                                  char **modname)
 {
        struct module *mod;
+       const char *ret = NULL;
 
+       preempt_disable();
        list_for_each_entry(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size)
                    || within(addr, mod->module_core, mod->core_size)) {
                        if (modname)
                                *modname = mod->name;
-                       return get_ksymbol(mod, addr, size, offset);
+                       ret = get_ksymbol(mod, addr, size, offset);
+                       break;
                }
        }
-       return NULL;
+       preempt_enable();
+       return ret;
 }
 
 int lookup_module_symbol_name(unsigned long addr, char *symname)
 {
        struct module *mod;
 
-       mutex_lock(&module_mutex);
+       preempt_disable();
        list_for_each_entry(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size) ||
                    within(addr, mod->module_core, mod->core_size)) {
@@ -2244,12 +2250,12 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
                        if (!sym)
                                goto out;
                        strlcpy(symname, sym, KSYM_NAME_LEN);
-                       mutex_unlock(&module_mutex);
+                       preempt_enable();
                        return 0;
                }
        }
 out:
-       mutex_unlock(&module_mutex);
+       preempt_enable();
        return -ERANGE;
 }
 
@@ -2258,7 +2264,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
 {
        struct module *mod;
 
-       mutex_lock(&module_mutex);
+       preempt_disable();
        list_for_each_entry(mod, &modules, list) {
                if (within(addr, mod->module_init, mod->init_size) ||
                    within(addr, mod->module_core, mod->core_size)) {
@@ -2271,12 +2277,12 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
                                strlcpy(modname, mod->name, MODULE_NAME_LEN);
                        if (name)
                                strlcpy(name, sym, KSYM_NAME_LEN);
-                       mutex_unlock(&module_mutex);
+                       preempt_enable();
                        return 0;
                }
        }
 out:
-       mutex_unlock(&module_mutex);
+       preempt_enable();
        return -ERANGE;
 }
 
@@ -2285,7 +2291,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
 {
        struct module *mod;
 
-       mutex_lock(&module_mutex);
+       preempt_disable();
        list_for_each_entry(mod, &modules, list) {
                if (symnum < mod->num_symtab) {
                        *value = mod->symtab[symnum].st_value;
@@ -2294,12 +2300,12 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
                                KSYM_NAME_LEN);
                        strlcpy(module_name, mod->name, MODULE_NAME_LEN);
                        *exported = is_exported(name, mod);
-                       mutex_unlock(&module_mutex);
+                       preempt_enable();
                        return 0;
                }
                symnum -= mod->num_symtab;
        }
-       mutex_unlock(&module_mutex);
+       preempt_enable();
        return -ERANGE;
 }
 
@@ -2322,6 +2328,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)
        unsigned long ret = 0;
 
        /* Don't lock: we're in enough trouble already. */
+       preempt_disable();
        if ((colon = strchr(name, ':')) != NULL) {
                *colon = '\0';
                if ((mod = find_module(name)) != NULL)
@@ -2332,6 +2339,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)
                        if ((ret = mod_find_symname(mod, name)) != 0)
                                break;
        }
+       preempt_enable();
        return ret;
 }
 #endif /* CONFIG_KALLSYMS */
@@ -2512,7 +2520,7 @@ static void module_create_drivers_dir(struct module_kobject *mk)
        if (!mk || mk->drivers_dir)
                return;
 
-       mk->drivers_dir = kobject_add_dir(&mk->kobj, "drivers");
+       mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
 }
 
 void module_add_driver(struct module *mod, struct device_driver *drv)
@@ -2530,7 +2538,7 @@ void module_add_driver(struct module *mod, struct device_driver *drv)
                struct kobject *mkobj;
 
                /* Lookup built-in module entry in /sys/modules */
-               mkobj = kset_find_obj(&module_subsys, drv->mod_name);
+               mkobj = kset_find_obj(module_kset, drv->mod_name);
                if (mkobj) {
                        mk = container_of(mkobj, struct module_kobject, kobj);
                        /* remember our module structure */