]> Pileus Git - ~andy/linux/blobdiff - kernel/module.c
kernel/spinlock.c: add default arch_*_relax definitions for GENERIC_LOCKBREAK
[~andy/linux] / kernel / module.c
index 206915830d2993bc54124b0fecf09abadac08a0f..dc582749fa1386db25af23929db4fc20b6c7acce 100644 (file)
@@ -136,6 +136,7 @@ static int param_set_bool_enable_only(const char *val,
 }
 
 static const struct kernel_param_ops param_ops_bool_enable_only = {
+       .flags = KERNEL_PARAM_FL_NOARG,
        .set = param_set_bool_enable_only,
        .get = param_get_bool,
 };
@@ -603,7 +604,7 @@ static void setup_modinfo_##field(struct module *mod, const char *s)  \
 static ssize_t show_modinfo_##field(struct module_attribute *mattr,   \
                        struct module_kobject *mk, char *buffer)      \
 {                                                                     \
-       return sprintf(buffer, "%s\n", mk->mod->field);               \
+       return scnprintf(buffer, PAGE_SIZE, "%s\n", mk->mod->field);  \
 }                                                                     \
 static int modinfo_##field##_exists(struct module *mod)               \
 {                                                                     \
@@ -1611,6 +1612,14 @@ static void module_remove_modinfo_attrs(struct module *mod)
        kfree(mod->modinfo_attrs);
 }
 
+static void mod_kobject_put(struct module *mod)
+{
+       DECLARE_COMPLETION_ONSTACK(c);
+       mod->mkobj.kobj_completion = &c;
+       kobject_put(&mod->mkobj.kobj);
+       wait_for_completion(&c);
+}
+
 static int mod_sysfs_init(struct module *mod)
 {
        int err;
@@ -1638,7 +1647,7 @@ static int mod_sysfs_init(struct module *mod)
        err = kobject_init_and_add(&mod->mkobj.kobj, &module_ktype, NULL,
                                   "%s", mod->name);
        if (err)
-               kobject_put(&mod->mkobj.kobj);
+               mod_kobject_put(mod);
 
        /* delay uevent until full sysfs population */
 out:
@@ -1682,7 +1691,7 @@ out_unreg_param:
 out_unreg_holders:
        kobject_put(mod->holders_dir);
 out_unreg:
-       kobject_put(&mod->mkobj.kobj);
+       mod_kobject_put(mod);
 out:
        return err;
 }
@@ -1691,7 +1700,7 @@ static void mod_sysfs_fini(struct module *mod)
 {
        remove_notes_attrs(mod);
        remove_sect_attrs(mod);
-       kobject_put(&mod->mkobj.kobj);
+       mod_kobject_put(mod);
 }
 
 #else /* !CONFIG_SYSFS */
@@ -2540,21 +2549,20 @@ static int copy_module_from_user(const void __user *umod, unsigned long len,
 /* Sets info->hdr and info->len. */
 static int copy_module_from_fd(int fd, struct load_info *info)
 {
-       struct file *file;
+       struct fd f = fdget(fd);
        int err;
        struct kstat stat;
        loff_t pos;
        ssize_t bytes = 0;
 
-       file = fget(fd);
-       if (!file)
+       if (!f.file)
                return -ENOEXEC;
 
-       err = security_kernel_module_from_file(file);
+       err = security_kernel_module_from_file(f.file);
        if (err)
                goto out;
 
-       err = vfs_getattr(&file->f_path, &stat);
+       err = vfs_getattr(&f.file->f_path, &stat);
        if (err)
                goto out;
 
@@ -2577,7 +2585,7 @@ static int copy_module_from_fd(int fd, struct load_info *info)
 
        pos = 0;
        while (pos < stat.size) {
-               bytes = kernel_read(file, pos, (char *)(info->hdr) + pos,
+               bytes = kernel_read(f.file, pos, (char *)(info->hdr) + pos,
                                    stat.size - pos);
                if (bytes < 0) {
                        vfree(info->hdr);
@@ -2591,7 +2599,7 @@ static int copy_module_from_fd(int fd, struct load_info *info)
        info->len = pos;
 
 out:
-       fput(file);
+       fdput(f);
        return err;
 }