s390/dasd: fix IO error for newly defined devices
authorStefan Haberland <sth@linux.vnet.ibm.com>
Thu, 12 Apr 2018 11:38:22 +0000 (13:38 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 23 Apr 2018 05:57:16 +0000 (07:57 +0200)
When a new CKD storage volume is defined at the storage server, Linux
may be relying on outdated information about that volume, which leads to
the following errors:

1. Command Reject Errors for minidisk on z/VM:

dasd-eckd.b3193d: 0.0.XXXX: An error occurred in the DASD device driver,
  reason=09
dasd(eckd): I/O status report for device 0.0.XXXX:
dasd(eckd): in req: 00000000XXXXXXXX CC:00 FC:04 AC:00 SC:17 DS:02 CS:00
    RC:0
dasd(eckd): device 0.0.2046: Failing CCW: 00000000XXXXXXXX
dasd(eckd): Sense(hex)  0- 7: 80 00 00 00 00 00 00 00
dasd(eckd): Sense(hex)  8-15: 00 00 00 00 00 00 00 00
dasd(eckd): Sense(hex) 16-23: 00 00 00 00 e1 00 0f 00
dasd(eckd): Sense(hex) 24-31: 00 00 40 e2 00 00 00 00
dasd(eckd): 24 Byte: 0 MSG 0, no MSGb to SYSOP

2. Equipment Check errors on LPAR or for dedicated devices on z/VM:

dasd(eckd): I/O status report for device 0.0.XXXX:
dasd(eckd): in req: 00000000XXXXXXXX CC:00 FC:04 AC:00 SC:17 DS:0E CS:40
    fcxs:01 schxs:00 RC:0
dasd(eckd): device 0.0.9713: Failing TCW: 00000000XXXXXXXX
dasd(eckd): Sense(hex)  0- 7: 10 00 00 00 13 58 4d 0f
dasd(eckd): Sense(hex)  8-15: 67 00 00 00 00 00 00 04
dasd(eckd): Sense(hex) 16-23: e5 18 05 33 97 01 0f 0f
dasd(eckd): Sense(hex) 24-31: 00 00 40 e2 00 04 58 0d
dasd(eckd): 24 Byte: 0 MSG f, no MSGb to SYSOP

Fix this problem by using the up-to-date information provided during
online processing via the device specific SNEQ to detect the case of
outdated LCU data. If there is a difference, perform a re-read of that
data.

Cc: stable@vger.kernel.org
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Stefan Haberland <sth@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/block/dasd_alias.c

index 62f5f04d8f615e393c88824606f58d13801c5e6b..5e963fe0e38d4c2125c43ae801ca7e9b28d98d07 100644 (file)
@@ -592,13 +592,22 @@ static int _schedule_lcu_update(struct alias_lcu *lcu,
 int dasd_alias_add_device(struct dasd_device *device)
 {
        struct dasd_eckd_private *private = device->private;
-       struct alias_lcu *lcu;
+       __u8 uaddr = private->uid.real_unit_addr;
+       struct alias_lcu *lcu = private->lcu;
        unsigned long flags;
        int rc;
 
-       lcu = private->lcu;
        rc = 0;
        spin_lock_irqsave(&lcu->lock, flags);
+       /*
+        * Check if device and lcu type differ. If so, the uac data may be
+        * outdated and needs to be updated.
+        */
+       if (private->uid.type !=  lcu->uac->unit[uaddr].ua_type) {
+               lcu->flags |= UPDATE_PENDING;
+               DBF_DEV_EVENT(DBF_WARNING, device, "%s",
+                             "uid type mismatch - trigger rescan");
+       }
        if (!(lcu->flags & UPDATE_PENDING)) {
                rc = _add_device_to_lcu(lcu, device, device);
                if (rc)