[PATCH v7 16/27] scsi-multipath: clear path when device is blocked
From: John Garry
Date: Tue Sep 01 2026 - 06:54:02 EST
From: John Garry <john.garry@xxxxxxxxx>
Add scsi_mpath_dev_clear_path() to clear a device path when it becomes
blocked.
Signed-off-by: John Garry <john.garry@xxxxxxxxx>
---
drivers/scsi/scsi_lib.c | 3 +++
drivers/scsi/scsi_multipath.c | 10 ++++++++++
include/scsi/scsi_multipath.h | 5 +++++
3 files changed, 18 insertions(+)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index af27fd3df8d46..f02b3a50e20cd 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>
@@ -3009,6 +3010,8 @@ static void scsi_device_block(struct scsi_device *sdev, void *data)
scsi_stop_queue(sdev);
mutex_unlock(&sdev->state_mutex);
+ if ((err == 0) && sdev->scsi_mpath_dev)
+ scsi_mpath_dev_clear_path(sdev->scsi_mpath_dev);
WARN_ONCE(err, "%s: failed to block %s in state %d\n",
__func__, dev_name(&sdev->sdev_gendev), state);
diff --git a/drivers/scsi/scsi_multipath.c b/drivers/scsi/scsi_multipath.c
index 68fe50f62158c..b16fe6a55fa73 100644
--- a/drivers/scsi/scsi_multipath.c
+++ b/drivers/scsi/scsi_multipath.c
@@ -238,6 +238,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 d2ef94ebd29af..2064a3e922748 100644
--- a/include/scsi/scsi_multipath.h
+++ b/include/scsi/scsi_multipath.h
@@ -55,6 +55,7 @@ int scsi_mpath_try_get_head(struct scsi_mpath_head *scsi_mpath_head);
void scsi_mpath_put_head(struct scsi_mpath_head *scsi_mpath_head);
void scsi_mpath_add_sysfs_link(struct scsi_device *sdev);
void scsi_mpath_remove_sysfs_link(struct scsi_device *sdev);
+void scsi_mpath_dev_clear_path(struct scsi_mpath_device *scsi_mpath_dev);
#else /* CONFIG_SCSI_MULTIPATH */
struct scsi_mpath_head {
@@ -99,5 +100,9 @@ static inline void scsi_mpath_add_sysfs_link(struct scsi_device *sdev)
static inline void scsi_mpath_remove_sysfs_link(struct scsi_device *sdev)
{
}
+static inline
+void scsi_mpath_dev_clear_path(struct scsi_mpath_device *scsi_mpath_dev)
+{
+}
#endif /* CONFIG_SCSI_MULTIPATH */
#endif /* _SCSI_SCSI_MULTIPATH_H */
--
2.43.7