Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80c716fa authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Martin K. Petersen
Browse files

scsi: scsi_dh_alua: skip RTPG for devices only supporting active/optimized



For hardware only supporting active/optimized there's no point in ever
re-issuing RTPG as the only new state we can possibly read is
active/optimized.  This avoid spurious errors during path failover on
such arrays.

Signed-off-by: default avatarHannes Reinecke <hare@suse.com>
Reviewed-by: default avatarBart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent bcb87240
Loading
Loading
Loading
Loading
+28 −9
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#define TPGS_SUPPORT_LBA_DEPENDENT	0x10
#define TPGS_SUPPORT_OFFLINE		0x40
#define TPGS_SUPPORT_TRANSITION		0x80
#define TPGS_SUPPORT_ALL		0xdf

#define RTPG_FMT_MASK			0x70
#define RTPG_FMT_EXT_HDR		0x10
@@ -81,6 +82,7 @@ struct alua_port_group {
	int			tpgs;
	int			state;
	int			pref;
	int			valid_states;
	unsigned		flags; /* used for optimizing STPG */
	unsigned char		transition_tmo;
	unsigned long		expiry;
@@ -243,6 +245,7 @@ static struct alua_port_group *alua_alloc_pg(struct scsi_device *sdev,
	pg->group_id = group_id;
	pg->tpgs = tpgs;
	pg->state = SCSI_ACCESS_STATE_OPTIMAL;
	pg->valid_states = TPGS_SUPPORT_ALL;
	if (optimize_stpg)
		pg->flags |= ALUA_OPTIMIZE_STPG;
	kref_init(&pg->kref);
@@ -516,7 +519,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
{
	struct scsi_sense_hdr sense_hdr;
	struct alua_port_group *tmp_pg;
	int len, k, off, valid_states = 0, bufflen = ALUA_RTPG_SIZE;
	int len, k, off, bufflen = ALUA_RTPG_SIZE;
	unsigned char *desc, *buff;
	unsigned err, retval;
	unsigned int tpg_desc_tbl_off;
@@ -541,6 +544,22 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
	retval = submit_rtpg(sdev, buff, bufflen, &sense_hdr, pg->flags);

	if (retval) {
		/*
		 * Some (broken) implementations have a habit of returning
		 * an error during things like firmware update etc.
		 * But if the target only supports active/optimized there's
		 * not much we can do; it's not that we can switch paths
		 * or anything.
		 * So ignore any errors to avoid spurious failures during
		 * path failover.
		 */
		if ((pg->valid_states & ~TPGS_SUPPORT_OPTIMIZED) == 0) {
			sdev_printk(KERN_INFO, sdev,
				    "%s: ignoring rtpg result %d\n",
				    ALUA_DH_NAME, retval);
			kfree(buff);
			return SCSI_DH_OK;
		}
		if (!scsi_sense_valid(&sense_hdr)) {
			sdev_printk(KERN_INFO, sdev,
				    "%s: rtpg failed, result %d\n",
@@ -652,7 +671,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
					rcu_read_unlock();
				}
				if (tmp_pg == pg)
					valid_states = desc[1];
					tmp_pg->valid_states = desc[1];
				spin_unlock_irqrestore(&tmp_pg->lock, flags);
			}
			kref_put(&tmp_pg->kref, release_port_group);
@@ -665,13 +684,13 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
		    "%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),
		    pg->pref ? "preferred" : "non-preferred",
		    valid_states&TPGS_SUPPORT_TRANSITION?'T':'t',
		    valid_states&TPGS_SUPPORT_OFFLINE?'O':'o',
		    valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l',
		    valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u',
		    valid_states&TPGS_SUPPORT_STANDBY?'S':'s',
		    valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n',
		    valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a');
		    pg->valid_states&TPGS_SUPPORT_TRANSITION?'T':'t',
		    pg->valid_states&TPGS_SUPPORT_OFFLINE?'O':'o',
		    pg->valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l',
		    pg->valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u',
		    pg->valid_states&TPGS_SUPPORT_STANDBY?'S':'s',
		    pg->valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n',
		    pg->valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a');

	switch (pg->state) {
	case SCSI_ACCESS_STATE_TRANSITIONING: