dm mpath: rdac fix init race
authorBryn M. Reeves <breeves@redhat.com>
Fri, 19 Oct 2007 21:29:32 +0000 (22:29 +0100)
committerAlasdair G Kergon <agk@redhat.com>
Sat, 20 Oct 2007 01:00:57 +0000 (02:00 +0100)
Re-order the initialisation of dm-rdac to avoid registering the hw
handler before the workqueue has been initialised. Closes a race
that would potentially give an oops.

Signed-off-by: Bryn M. Reeves <breeves@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
drivers/md/dm-mpath-rdac.c

index 16b1613..e04eb5c 100644 (file)
@@ -664,20 +664,21 @@ static struct hw_handler_type rdac_handler = {
 
 static int __init rdac_init(void)
 {
 
 static int __init rdac_init(void)
 {
-       int r = dm_register_hw_handler(&rdac_handler);
-
-       if (r < 0) {
-               DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
-               return r;
-       }
+       int r;
 
        rdac_wkqd = create_singlethread_workqueue("rdac_wkqd");
        if (!rdac_wkqd) {
                DMERR("Failed to create workqueue rdac_wkqd.");
 
        rdac_wkqd = create_singlethread_workqueue("rdac_wkqd");
        if (!rdac_wkqd) {
                DMERR("Failed to create workqueue rdac_wkqd.");
-               dm_unregister_hw_handler(&rdac_handler);
                return -ENOMEM;
        }
 
                return -ENOMEM;
        }
 
+       r = dm_register_hw_handler(&rdac_handler);
+       if (r < 0) {
+               DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
+               destroy_workqueue(rdac_wkqd);
+               return r;
+       }
+
        DMINFO("%s: version %s loaded", RDAC_DM_HWH_NAME, RDAC_DM_HWH_VER);
        return 0;
 }
        DMINFO("%s: version %s loaded", RDAC_DM_HWH_NAME, RDAC_DM_HWH_VER);
        return 0;
 }