| From 41c16b471c561da9b1981bcec6812cb2efd005ad Mon Sep 17 00:00:00 2001 |
| From: Hannes Reinecke <hare@suse.com> |
| Date: Mon, 7 Oct 2019 15:57:01 +0200 |
| Subject: [PATCH] scsi: scsi_dh_alua: handle RTPG sense code correctly during |
| state transitions |
| |
| commit b6ce6fb121a655aefe41dccc077141c102145a37 upstream. |
| |
| Some arrays are not capable of returning RTPG data during state |
| transitioning, but rather return an 'LUN not accessible, asymmetric access |
| state transition' sense code. In these cases we can set the state to |
| 'transitioning' directly and don't need to evaluate the RTPG data (which we |
| won't have anyway). |
| |
| Link: https://lore.kernel.org/r/20191007135701.32389-1-hare@suse.de |
| Reviewed-by: Laurence Oberman <loberman@redhat.com> |
| Reviewed-by: Ewan D. Milne <emilne@redhat.com> |
| Reviewed-by: Bart Van Assche <bvanassche@acm.org> |
| Signed-off-by: Hannes Reinecke <hare@suse.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c |
| index 4971104b1817..f32da0ca529e 100644 |
| --- a/drivers/scsi/device_handler/scsi_dh_alua.c |
| +++ b/drivers/scsi/device_handler/scsi_dh_alua.c |
| @@ -512,6 +512,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) |
| unsigned int tpg_desc_tbl_off; |
| unsigned char orig_transition_tmo; |
| unsigned long flags; |
| + bool transitioning_sense = false; |
| |
| if (!pg->expiry) { |
| unsigned long transition_tmo = ALUA_FAILOVER_TIMEOUT * HZ; |
| @@ -572,13 +573,19 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) |
| goto retry; |
| } |
| /* |
| - * Retry on ALUA state transition or if any |
| - * UNIT ATTENTION occurred. |
| + * If the array returns with 'ALUA state transition' |
| + * sense code here it cannot return RTPG data during |
| + * transition. So set the state to 'transitioning' directly. |
| */ |
| if (sense_hdr.sense_key == NOT_READY && |
| - sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) |
| - err = SCSI_DH_RETRY; |
| - else if (sense_hdr.sense_key == UNIT_ATTENTION) |
| + sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) { |
| + transitioning_sense = true; |
| + goto skip_rtpg; |
| + } |
| + /* |
| + * Retry on any other UNIT ATTENTION occurred. |
| + */ |
| + if (sense_hdr.sense_key == UNIT_ATTENTION) |
| err = SCSI_DH_RETRY; |
| if (err == SCSI_DH_RETRY && |
| pg->expiry != 0 && time_before(jiffies, pg->expiry)) { |
| @@ -666,7 +673,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) |
| off = 8 + (desc[7] * 4); |
| } |
| |
| + skip_rtpg: |
| spin_lock_irqsave(&pg->lock, flags); |
| + if (transitioning_sense) |
| + pg->state = SCSI_ACCESS_STATE_TRANSITIONING; |
| + |
| sdev_printk(KERN_INFO, sdev, |
| "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n", |
| ALUA_DH_NAME, pg->group_id, print_alua_state(pg->state), |
| -- |
| 2.7.4 |
| |