Provide callbacks for .is_disabled, .is_optimized, and .available_path. These all use scsi_device.sdev_state and scsi_device.access_state.
Member scsi_device.access_state will be driven by ALUA. Currently only device handlers support this, and in future we will have core SCSI support for implicit ALUA (not relying on device handlers). Signed-off-by: John Garry <[email protected]> --- drivers/scsi/scsi_multipath.c | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/scsi/scsi_multipath.c b/drivers/scsi/scsi_multipath.c index 0dcbf12217165..a3bf95e2a18eb 100644 --- a/drivers/scsi/scsi_multipath.c +++ b/drivers/scsi/scsi_multipath.c @@ -308,7 +308,53 @@ static enum mpath_iopolicy_e scsi_mpath_get_iopolicy(struct mpath_head *mpath_he return mpath_read_iopolicy(&scsi_mpath_head->iopolicy); } +static bool scsi_mpath_is_disabled(struct mpath_device *mpath_device) +{ + struct scsi_mpath_device *scsi_mpath_dev = + to_scsi_mpath_device(mpath_device); + struct scsi_device *sdev = scsi_mpath_dev->sdev; + unsigned char access_state = READ_ONCE(sdev->access_state); + + if (sdev->sdev_state != SDEV_RUNNING) + return true; + + if (access_state == SCSI_ACCESS_STATE_OPTIMAL || + access_state == SCSI_ACCESS_STATE_ACTIVE) + return false; + + return true; +} + +static bool scsi_mpath_is_optimized(struct mpath_device *mpath_device) +{ + struct scsi_mpath_device *scsi_mpath_dev = + to_scsi_mpath_device(mpath_device); + struct scsi_device *sdev = scsi_mpath_dev->sdev; + + if (sdev->sdev_state != SDEV_RUNNING) + return false; + + return READ_ONCE(sdev->access_state) == SCSI_ACCESS_STATE_OPTIMAL; +} + +static bool scsi_mpath_available_path(struct mpath_device *mpath_device) +{ + struct scsi_mpath_device *scsi_mpath_dev = + to_scsi_mpath_device(mpath_device); + struct scsi_device *sdev = scsi_mpath_dev->sdev; + enum scsi_device_state sdev_state = sdev->sdev_state; + + if (sdev_state == SDEV_RUNNING || sdev_state == SDEV_QUIESCE || + sdev_state == SDEV_BLOCK || sdev_state == SDEV_CREATED_BLOCK) + return true; + + return false; +} + struct mpath_head_template smpdt = { + .is_disabled = scsi_mpath_is_disabled, + .is_optimized = scsi_mpath_is_optimized, + .available_path = scsi_mpath_available_path, .get_iopolicy = scsi_mpath_get_iopolicy, .clone_bio = scsi_mpath_clone_bio, }; -- 2.43.5

