scsi_dh_alua: separate out alua_stpg()

Separate out SET TARGET PORT GROUP functionality into a separate
function alua_stpg().

Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Hannes Reinecke 2016-02-19 09:16:59 +01:00 committed by Martin K. Petersen
parent d42ae5f338
commit f2ecf13a24
1 changed files with 61 additions and 34 deletions

View File

@ -578,6 +578,65 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h, int wait_
return err;
}
/*
* alua_stpg - Issue a SET TARGET PORT GROUP command
*
* Issue a SET TARGET PORT GROUP command and evaluate the
* response. Returns SCSI_DH_RETRY if the target port group
* state is found to be in 'transitioning'.
* If SCSI_DH_OK is returned the passed-in 'fn' function
* this function will take care of executing 'fn'.
* Otherwise 'fn' should be executed by the caller with the
* returned error code.
*/
static unsigned alua_stpg(struct scsi_device *sdev, struct alua_dh_data *h,
activate_complete fn, void *data)
{
int err = SCSI_DH_OK;
int stpg = 0;
if (!(h->tpgs & TPGS_MODE_EXPLICIT))
/* Only implicit ALUA supported */
goto out;
switch (h->state) {
case TPGS_STATE_NONOPTIMIZED:
stpg = 1;
if ((h->flags & ALUA_OPTIMIZE_STPG) &&
!h->pref &&
(h->tpgs & TPGS_MODE_IMPLICIT))
stpg = 0;
break;
case TPGS_STATE_STANDBY:
case TPGS_STATE_UNAVAILABLE:
stpg = 1;
break;
case TPGS_STATE_OFFLINE:
err = SCSI_DH_IO;
break;
case TPGS_STATE_TRANSITIONING:
err = SCSI_DH_RETRY;
break;
default:
break;
}
if (stpg) {
h->callback_fn = fn;
h->callback_data = data;
err = submit_stpg(h);
if (err != SCSI_DH_OK)
h->callback_fn = h->callback_data = NULL;
else
fn = NULL;
}
out:
if (fn)
fn(data, err);
return err;
}
/*
* alua_initialize - Initialize ALUA state
* @sdev: the device to be initialized
@ -655,7 +714,6 @@ static int alua_activate(struct scsi_device *sdev,
{
struct alua_dh_data *h = sdev->handler_data;
int err = SCSI_DH_OK;
int stpg = 0;
err = alua_rtpg(sdev, h, 1);
if (err != SCSI_DH_OK)
@ -664,41 +722,10 @@ static int alua_activate(struct scsi_device *sdev,
if (optimize_stpg)
h->flags |= ALUA_OPTIMIZE_STPG;
if (h->tpgs & TPGS_MODE_EXPLICIT) {
switch (h->state) {
case TPGS_STATE_NONOPTIMIZED:
stpg = 1;
if ((h->flags & ALUA_OPTIMIZE_STPG) &&
(!h->pref) &&
(h->tpgs & TPGS_MODE_IMPLICIT))
stpg = 0;
break;
case TPGS_STATE_STANDBY:
case TPGS_STATE_UNAVAILABLE:
stpg = 1;
break;
case TPGS_STATE_OFFLINE:
err = SCSI_DH_IO;
break;
case TPGS_STATE_TRANSITIONING:
err = SCSI_DH_RETRY;
break;
default:
break;
}
}
if (stpg) {
h->callback_fn = fn;
h->callback_data = data;
err = submit_stpg(h);
if (err == SCSI_DH_OK)
return 0;
h->callback_fn = h->callback_data = NULL;
}
err = alua_stpg(sdev, h, fn, data);
out:
if (fn)
if (err != SCSI_DH_OK && fn)
fn(data, err);
return 0;
}