scsi: qla2xxx: Unregister chrdev if module initialization fails
authorBart Van Assche <bvanassche@acm.org>
Thu, 4 Apr 2019 19:44:46 +0000 (12:44 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 27 Jan 2020 13:50:37 +0000 (14:50 +0100)
[ Upstream commit c794d24ec9eb6658909955772e70f34bef5b5b91 ]

If module initialization fails after the character device has been
registered, unregister the character device. Additionally, avoid
duplicating error path code.

Cc: Himanshu Madhani <hmadhani@marvell.com>
Cc: Giridhar Malavali <giridhar.malavali@qlogic.com>
Fixes: 6a03b4cd78f3 ("[SCSI] qla2xxx: Add char device to increase driver use count") # v2.6.35.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/qla2xxx/qla_os.c

index bb20a4a..fff20a3 100644 (file)
@@ -6967,8 +6967,7 @@ qla2x00_module_init(void)
        /* Initialize target kmem_cache and mem_pools */
        ret = qlt_init();
        if (ret < 0) {
-               kmem_cache_destroy(srb_cachep);
-               return ret;
+               goto destroy_cache;
        } else if (ret > 0) {
                /*
                 * If initiator mode is explictly disabled by qlt_init(),
@@ -6989,11 +6988,10 @@ qla2x00_module_init(void)
        qla2xxx_transport_template =
            fc_attach_transport(&qla2xxx_transport_functions);
        if (!qla2xxx_transport_template) {
-               kmem_cache_destroy(srb_cachep);
                ql_log(ql_log_fatal, NULL, 0x0002,
                    "fc_attach_transport failed...Failing load!.\n");
-               qlt_exit();
-               return -ENODEV;
+               ret = -ENODEV;
+               goto qlt_exit;
        }
 
        apidev_major = register_chrdev(0, QLA2XXX_APIDEV, &apidev_fops);
@@ -7005,27 +7003,37 @@ qla2x00_module_init(void)
        qla2xxx_transport_vport_template =
            fc_attach_transport(&qla2xxx_transport_vport_functions);
        if (!qla2xxx_transport_vport_template) {
-               kmem_cache_destroy(srb_cachep);
-               qlt_exit();
-               fc_release_transport(qla2xxx_transport_template);
                ql_log(ql_log_fatal, NULL, 0x0004,
                    "fc_attach_transport vport failed...Failing load!.\n");
-               return -ENODEV;
+               ret = -ENODEV;
+               goto unreg_chrdev;
        }
        ql_log(ql_log_info, NULL, 0x0005,
            "QLogic Fibre Channel HBA Driver: %s.\n",
            qla2x00_version_str);
        ret = pci_register_driver(&qla2xxx_pci_driver);
        if (ret) {
-               kmem_cache_destroy(srb_cachep);
-               qlt_exit();
-               fc_release_transport(qla2xxx_transport_template);
-               fc_release_transport(qla2xxx_transport_vport_template);
                ql_log(ql_log_fatal, NULL, 0x0006,
                    "pci_register_driver failed...ret=%d Failing load!.\n",
                    ret);
+               goto release_vport_transport;
        }
        return ret;
+
+release_vport_transport:
+       fc_release_transport(qla2xxx_transport_vport_template);
+
+unreg_chrdev:
+       if (apidev_major >= 0)
+               unregister_chrdev(apidev_major, QLA2XXX_APIDEV);
+       fc_release_transport(qla2xxx_transport_template);
+
+qlt_exit:
+       qlt_exit();
+
+destroy_cache:
+       kmem_cache_destroy(srb_cachep);
+       return ret;
 }
 
 /**