From: John Garry <[email protected]> Add scsi_mpath_dev_clear_path() to clear a device path when it becomes blocked.
Signed-off-by: John Garry <[email protected]> --- drivers/scsi/scsi_lib.c | 6 +++++- drivers/scsi/scsi_multipath.c | 10 ++++++++++ include/scsi/scsi_multipath.h | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 22e2e3223440d..dafa781288046 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -35,6 +35,7 @@ #include <scsi/scsi_host.h> #include <scsi/scsi_transport.h> /* scsi_init_limits() */ #include <scsi/scsi_dh.h> +#include <scsi/scsi_multipath.h> #include <trace/events/scsi.h> @@ -3007,13 +3008,16 @@ static void scsi_device_block(struct scsi_device *sdev, void *data) mutex_lock(&sdev->state_mutex); err = __scsi_internal_device_block_nowait(sdev); state = sdev->sdev_state; - if (err == 0) + if (err == 0) { /* * scsi_stop_queue() must be called with the state_mutex * held. Otherwise a simultaneous scsi_start_queue() call * might unquiesce the queue before we quiesce it. */ scsi_stop_queue(sdev); + if (sdev->scsi_mpath_dev) + scsi_mpath_dev_clear_path(sdev->scsi_mpath_dev); + } mutex_unlock(&sdev->state_mutex); diff --git a/drivers/scsi/scsi_multipath.c b/drivers/scsi/scsi_multipath.c index 9a4b35c597778..6a2b06c148c1a 100644 --- a/drivers/scsi/scsi_multipath.c +++ b/drivers/scsi/scsi_multipath.c @@ -230,6 +230,16 @@ static int scsi_multipath_sdev_init(struct scsi_device *sdev) return 0; } +void scsi_mpath_dev_clear_path(struct scsi_mpath_device *scsi_mpath_dev) +{ + struct mpath_device *mpath_device = &scsi_mpath_dev->mpath_device; + struct scsi_mpath_head *scsi_mpath_head = scsi_mpath_dev->scsi_mpath_head; + struct mpath_head *mpath_head = &scsi_mpath_head->mpath_head; + + if (mpath_clear_current_path(mpath_device)) + mpath_synchronize(mpath_head); +} + static void scsi_mpath_clone_end_io(struct bio *clone) { struct bio *master_bio = clone->bi_private; diff --git a/include/scsi/scsi_multipath.h b/include/scsi/scsi_multipath.h index 5cc37acaa664f..8f58c44d96a77 100644 --- a/include/scsi/scsi_multipath.h +++ b/include/scsi/scsi_multipath.h @@ -54,6 +54,7 @@ void scsi_mpath_add_sysfs_link(struct scsi_device *sdev); void scsi_mpath_remove_sysfs_link(struct scsi_device *sdev); int scsi_mpath_get_head(struct scsi_mpath_head *scsi_mpath_head); void scsi_mpath_put_head(struct scsi_mpath_head *scsi_mpath_head); +void scsi_mpath_dev_clear_path(struct scsi_mpath_device *scsi_mpath_dev); #else /* CONFIG_SCSI_MULTIPATH */ struct scsi_mpath_head { @@ -88,6 +89,10 @@ static inline void scsi_mpath_put_head(struct scsi_mpath_head *scsi_mpath_head) { } +static inline +void scsi_mpath_dev_clear_path(struct scsi_mpath_device *scsi_mpath_dev) +{ +} static inline void scsi_mpath_add_sysfs_link(struct scsi_device *sdev) { } -- 2.43.7

