| From: Stefan Haberland <sth@linux.vnet.ibm.com> |
| Date: Thu, 12 Apr 2018 13:38:22 +0200 |
| Subject: s390/dasd: fix IO error for newly defined devices |
| |
| commit 5d27a2bf6e14f5c7d1033ad1e993fcd0eba43e83 upstream. |
| |
| 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. |
| |
| 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> |
| [bwh: Backported to 3.16: |
| - Move up assignment of "private" |
| - Adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| --- a/drivers/s390/block/dasd_alias.c |
| +++ b/drivers/s390/block/dasd_alias.c |
| @@ -608,18 +608,26 @@ static int _schedule_lcu_update(struct a |
| |
| int dasd_alias_add_device(struct dasd_device *device) |
| { |
| - struct dasd_eckd_private *private; |
| - struct alias_lcu *lcu; |
| + struct dasd_eckd_private *private = device->private; |
| + __u8 uaddr = private->uid.real_unit_addr; |
| + struct alias_lcu *lcu = private->lcu; |
| unsigned long flags; |
| int rc; |
| |
| - private = (struct dasd_eckd_private *) device->private; |
| - lcu = private->lcu; |
| rc = 0; |
| |
| /* need to take cdev lock before lcu lock */ |
| spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
| spin_lock(&lcu->lock); |
| + /* |
| + * 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) |