Staging: hv: storvsc: Cleanup error handling in the probe function
authorK. Y. Srinivasan <kys@microsoft.com>
Tue, 8 Nov 2011 17:01:41 +0000 (09:01 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Sun, 27 Nov 2011 01:02:07 +0000 (17:02 -0800)
Cleanup error handling in the probe function.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/hv/storvsc_drv.c

index 6a255e97721941b5992080bd058b2ceee0da5d71..a72cc22062b5b9befa7d2dd5a148ef01c32452a2 100644 (file)
@@ -1388,17 +1388,14 @@ static int storvsc_probe(struct hv_device *device,
                                                host_dev->request_pool);
 
        if (!host_dev->request_mempool) {
-               kmem_cache_destroy(host_dev->request_pool);
-               scsi_host_put(host);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_out0;
        }
 
        stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL);
        if (!stor_device) {
-               mempool_destroy(host_dev->request_mempool);
-               kmem_cache_destroy(host_dev->request_pool);
-               scsi_host_put(host);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_out1;
        }
 
        stor_device->destroy = false;
@@ -1409,13 +1406,8 @@ static int storvsc_probe(struct hv_device *device,
 
        stor_device->port_number = host->host_no;
        ret = storvsc_connect_to_vsp(device, storvsc_ringbuffer_size);
-       if (ret) {
-               mempool_destroy(host_dev->request_mempool);
-               kmem_cache_destroy(host_dev->request_pool);
-               scsi_host_put(host);
-               kfree(stor_device);
-               return ret;
-       }
+       if (ret)
+               goto err_out2;
 
        if (dev_is_ide)
                storvsc_get_ide_info(device, &target, &path);
@@ -1435,7 +1427,7 @@ static int storvsc_probe(struct hv_device *device,
        /* Register the HBA and start the scsi bus scan */
        ret = scsi_add_host(host, &device->device);
        if (ret != 0)
-               goto err_out;
+               goto err_out3;
 
        if (!dev_is_ide) {
                scsi_scan_host(host);
@@ -1444,16 +1436,30 @@ static int storvsc_probe(struct hv_device *device,
        ret = scsi_add_device(host, 0, target, 0);
        if (ret) {
                scsi_remove_host(host);
-               goto err_out;
+               goto err_out3;
        }
        return 0;
 
-err_out:
+err_out3:
+       /*
+        * Once we have connected with the host, we would need to
+        * to invoke storvsc_dev_remove() to rollback this state and
+        * this call also frees up the stor_device; hence the jump around
+        * err_out2 label.
+        */
        storvsc_dev_remove(device);
+       goto err_out1;
+
+err_out2:
+       kfree(stor_device);
+
+err_out1:
        mempool_destroy(host_dev->request_mempool);
+
+err_out0:
        kmem_cache_destroy(host_dev->request_pool);
        scsi_host_put(host);
-       return -ENODEV;
+       return ret;
 }
 
 /* The one and only one */