]> git.karo-electronics.de Git - linux-beck.git/commitdiff
[S390] dasd: prevent validate server for offline devices
authorStefan Haberland <stefan.haberland@de.ibm.com>
Sun, 11 Mar 2012 15:59:37 +0000 (11:59 -0400)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Sun, 11 Mar 2012 15:59:29 +0000 (11:59 -0400)
Calling validate server on devices in offline processing may cause
an OOPS in the dasd_sleep_on function.

Signed-off-by: Stefan Haberland <stefan.haberland@de.ibm.com>
Reviewed-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/block/dasd.c
drivers/s390/block/dasd_eckd.c

index 110137e7ec81caae83eee0d914f61b73e38c746a..f3509120a507f56e3b152e1dee4cb5990ce23d79 100644 (file)
@@ -640,6 +640,10 @@ void dasd_enable_device(struct dasd_device *device)
                dasd_set_target_state(device, DASD_STATE_NEW);
        /* Now wait for the devices to come up. */
        wait_event(dasd_init_waitq, _wait_for_device(device));
+
+       dasd_reload_device(device);
+       if (device->discipline->kick_validate)
+               device->discipline->kick_validate(device);
 }
 
 /*
index 2617b1ed4709bffd1f68971ebe27ea2e61e8f62f..c21871a4e73da92c06119fa3e0f3b7ad93298274 100644 (file)
@@ -1564,6 +1564,12 @@ static void dasd_eckd_do_validate_server(struct work_struct *work)
 static void dasd_eckd_kick_validate_server(struct dasd_device *device)
 {
        dasd_get_device(device);
+       /* exit if device not online or in offline processing */
+       if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||
+          device->state < DASD_STATE_ONLINE) {
+               dasd_put_device(device);
+               return;
+       }
        /* queue call to do_validate_server to the kernel event daemon. */
        schedule_work(&device->kick_validate);
 }
@@ -1993,6 +1999,7 @@ static int dasd_eckd_ready_to_online(struct dasd_device *device)
 static int dasd_eckd_online_to_ready(struct dasd_device *device)
 {
        cancel_work_sync(&device->reload_device);
+       cancel_work_sync(&device->kick_validate);
        return dasd_alias_remove_device(device);
 };
 
@@ -2263,6 +2270,7 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device,
                 * and only if not suspended
                 */
                if (!device->block && private->lcu &&
+                   device->state == DASD_STATE_ONLINE &&
                    !test_bit(DASD_FLAG_OFFLINE, &device->flags) &&
                    !test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {
                        /*