]> git.karo-electronics.de Git - linux-beck.git/commitdiff
[S390] dasd: fix fixpoint divide exception in define_extent
authorStefan Haberland <stefan.haberland@de.ibm.com>
Tue, 27 Dec 2011 10:27:28 +0000 (11:27 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 27 Dec 2011 10:27:14 +0000 (11:27 +0100)
If an IO request is build on an alias device without prefix enabled
we try to calculate with zero data from the alias device. This
triggers a BUG statement with fixpoint divide exception.
This case is very unlikely and can only happen if the pathgroup is
lost with an alias device already in use.
Prevent the alias device from being used in this case.

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

index c388eda1e2b195943200e4af7308ee1c69935083..553b3c5abb0abf37faa0507f28512e1d3d7ac363 100644 (file)
@@ -705,6 +705,16 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
        if (lcu->pav == NO_PAV ||
            lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING))
                return NULL;
+       if (unlikely(!(private->features.feature[8] & 0x01))) {
+               /*
+                * PAV enabled but prefix not, very unlikely
+                * seems to be a lost pathgroup
+                * use base device to do IO
+                */
+               DBF_DEV_EVENT(DBF_ERR, base_device, "%s",
+                             "Prefix not enabled with PAV enabled\n");
+               return NULL;
+       }
 
        spin_lock_irqsave(&lcu->lock, flags);
        alias_device = group->next;
index 763f1bd9605a9381a2f336bb9d5553fbc8fea518..bbcd5e9206ee27dff5c85fc78ef09353135e3656 100644 (file)
@@ -2397,7 +2397,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(
                                           sizeof(struct PFX_eckd_data));
        } else {
                if (define_extent(ccw++, cqr->data, first_trk,
-                                 last_trk, cmd, startdev) == -EAGAIN) {
+                                 last_trk, cmd, basedev) == -EAGAIN) {
                        /* Clock not in sync and XRC is enabled.
                         * Try again later.
                         */