ocfs2: Proper cleanup in case of error in ocfs2_register_hb_callbacks()
[powerpc.git] / kernel / module.c
index e06b77a..f77e893 100644 (file)
@@ -653,11 +653,20 @@ static void wait_for_zero_refcount(struct module *mod)
        mutex_lock(&module_mutex);
 }
 
-int delete_module(const char *name, unsigned int flags)
+asmlinkage long
+sys_delete_module(const char __user *name_user, unsigned int flags)
 {
        struct module *mod;
+       char name[MODULE_NAME_LEN];
        int ret, forced = 0;
 
+       if (!capable(CAP_SYS_MODULE))
+               return -EPERM;
+
+       if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
+               return -EFAULT;
+       name[MODULE_NAME_LEN-1] = '\0';
+
        if (mutex_lock_interruptible(&module_mutex) != 0)
                return -EINTR;
 
@@ -718,21 +727,6 @@ int delete_module(const char *name, unsigned int flags)
        return ret;
 }
 
-asmlinkage long
-sys_delete_module(const char __user *name_user, unsigned int flags)
-{
-       char name[MODULE_NAME_LEN];
-
-       if (!capable(CAP_SYS_MODULE))
-               return -EPERM;
-
-       if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
-               return -EFAULT;
-       name[MODULE_NAME_LEN-1] = '\0';
-
-       return delete_module(name, flags);
-}
-
 static void print_unload_info(struct seq_file *m, struct module *mod)
 {
        struct module_use *use;
@@ -1074,7 +1068,8 @@ static inline void remove_sect_attrs(struct module *mod)
 }
 #endif /* CONFIG_KALLSYMS */
 
-static int module_add_modinfo_attrs(struct module *mod)
+#ifdef CONFIG_SYSFS
+int module_add_modinfo_attrs(struct module *mod)
 {
        struct module_attribute *attr;
        struct module_attribute *temp_attr;
@@ -1100,7 +1095,7 @@ static int module_add_modinfo_attrs(struct module *mod)
        return error;
 }
 
-static void module_remove_modinfo_attrs(struct module *mod)
+void module_remove_modinfo_attrs(struct module *mod)
 {
        struct module_attribute *attr;
        int i;
@@ -1115,8 +1110,10 @@ static void module_remove_modinfo_attrs(struct module *mod)
        }
        kfree(mod->modinfo_attrs);
 }
+#endif
 
-static int mod_sysfs_init(struct module *mod)
+#ifdef CONFIG_SYSFS
+int mod_sysfs_init(struct module *mod)
 {
        int err;
 
@@ -1139,7 +1136,7 @@ out:
        return err;
 }
 
-static int mod_sysfs_setup(struct module *mod,
+int mod_sysfs_setup(struct module *mod,
                           struct kernel_param *kparam,
                           unsigned int num_params)
 {
@@ -1175,6 +1172,7 @@ out_unreg:
 out:
        return err;
 }
+#endif
 
 static void mod_kobject_remove(struct module *mod)
 {
@@ -2348,6 +2346,7 @@ void print_modules(void)
        printk("\n");
 }
 
+#ifdef CONFIG_SYSFS
 static char *make_driver_name(struct device_driver *drv)
 {
        char *driver_name;
@@ -2420,8 +2419,15 @@ void module_remove_driver(struct device_driver *drv)
                        kfree(driver_name);
                }
        }
+       /*
+        * Undo the additional reference we added in module_add_driver()
+        * via kset_find_obj()
+        */
+       if (drv->mod_name)
+               kobject_put(&drv->kobj);
 }
 EXPORT_SYMBOL(module_remove_driver);
+#endif
 
 #ifdef CONFIG_MODVERSIONS
 /* Generate the signature for struct module here, too, for modversions. */