staging: dgrp: implement error handling in dgrp_create_class_sysfs_files()
authorAlexey Khoroshilov <khoroshilov@ispras.ru>
Fri, 5 Apr 2013 21:14:23 +0000 (01:14 +0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 5 Apr 2013 21:24:11 +0000 (14:24 -0700)
There is no any error handling in dgrp_create_class_sysfs_files().
The patch adds code to check return values and propagate them to dgrp_init_module().

Found by Linux Driver Verification project (linuxtesting.org).

Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/dgrp/dgrp_common.h
drivers/staging/dgrp/dgrp_driver.c
drivers/staging/dgrp/dgrp_sysfs.c

index 0583fe9c7b035cd6810635bf6beb7c6e5a47daf1..2832b8e26c4b65c59043cb1249d5941fb65c1dac 100644 (file)
@@ -66,7 +66,7 @@ extern void dgrp_register_dpa_hook(struct proc_dir_entry *de);
 extern void dgrp_dpa_data(struct nd_struct *, int, u8 *, int);
 
 /* from dgrp_sysfs.c */
-extern void dgrp_create_class_sysfs_files(void);
+extern int dgrp_create_class_sysfs_files(void);
 extern void dgrp_remove_class_sysfs_files(void);
 
 extern void dgrp_create_node_class_sysfs_files(struct nd_struct *nd);
index aa262588e9b938a20b1ab1f12c05f9590e8115e0..e456dc6cb367cd2fdfcf372075022881a4b945d0 100644 (file)
@@ -66,6 +66,8 @@ module_exit(dgrp_cleanup_module);
  */
 static int dgrp_init_module(void)
 {
+       int ret;
+
        INIT_LIST_HEAD(&nd_struct_list);
 
        spin_lock_init(&dgrp_poll_data.poll_lock);
@@ -74,7 +76,9 @@ static int dgrp_init_module(void)
        dgrp_poll_data.timer.function = dgrp_poll_handler;
        dgrp_poll_data.timer.data = (unsigned long) &dgrp_poll_data;
 
-       dgrp_create_class_sysfs_files();
+       ret = dgrp_create_class_sysfs_files();
+       if (ret)
+               return ret;
 
        dgrp_register_proc();
 
index be179adfb7c7a0d5cbb9b81e6a023d29f73baf99..7d1b36d1e75fc57f8120c06c16754c20e5bddc40 100644 (file)
@@ -85,30 +85,50 @@ static struct attribute_group dgrp_global_settings_attribute_group = {
 
 
 
-void dgrp_create_class_sysfs_files(void)
+int dgrp_create_class_sysfs_files(void)
 {
        int ret = 0;
        int max_majors = 1U << (32 - MINORBITS);
 
        dgrp_class = class_create(THIS_MODULE, "digi_realport");
+       if (IS_ERR(dgrp_class))
+               return PTR_ERR(dgrp_class);
        ret = class_create_file(dgrp_class, &class_attr_driver_version);
+       if (ret)
+               goto err_class;
 
        dgrp_class_global_settings_dev = device_create(dgrp_class, NULL,
                MKDEV(0, max_majors + 1), NULL, "driver_settings");
-
+       if (IS_ERR(dgrp_class_global_settings_dev)) {
+               ret = PTR_ERR(dgrp_class_global_settings_dev);
+               goto err_file;
+       }
        ret = sysfs_create_group(&dgrp_class_global_settings_dev->kobj,
                &dgrp_global_settings_attribute_group);
        if (ret) {
                pr_alert("%s: failed to create sysfs global settings device attributes.\n",
                        __func__);
-               sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
-                       &dgrp_global_settings_attribute_group);
-               return;
+               goto err_dev1;
        }
 
        dgrp_class_nodes_dev = device_create(dgrp_class, NULL,
                MKDEV(0, max_majors + 2), NULL, "nodes");
+       if (IS_ERR(dgrp_class_nodes_dev)) {
+               ret = PTR_ERR(dgrp_class_nodes_dev);
+               goto err_group;
+       }
 
+       return 0;
+err_group:
+       sysfs_remove_group(&dgrp_class_global_settings_dev->kobj,
+               &dgrp_global_settings_attribute_group);
+err_dev1:
+       device_destroy(dgrp_class, MKDEV(0, max_majors + 1));
+err_file:
+       class_remove_file(dgrp_class, &class_attr_driver_version);
+err_class:
+       class_destroy(dgrp_class);
+       return ret;
 }