[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[dm-devel] [PATCH 3/3] dm-multipath: 'default_hw_handler' feature



This patch introduces a 'default_hw_handler' feature for
dm-mpath. When specifying the feature 'default_hw_handler'
dm-multipath will be using the currently attached hardware
handler instead of trying to re-attach with the one
specified during table creation.
If no hardware handler is attached the specified hardware
handler will be used.

Signed-off-by: Hannes Reinecke <hare suse de>
---
 drivers/md/dm-mpath.c |   25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 6d3f2a8..c1ef41d 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -57,6 +57,7 @@ struct priority_group {
 };
 
 #define FEATURE_NO_PARTITIONS 1
+#define FEATURE_DEFAULT_HW_HANDLER 2
 
 /* Multipath context */
 struct multipath {
@@ -589,14 +590,24 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
 
 	if (m->hw_handler_name) {
 		struct request_queue *q = bdev_get_queue(p->path.dev->bdev);
+		const char *hw_handler_name = m->hw_handler_name;
 
-		r = scsi_dh_attach(q, m->hw_handler_name);
+		if (m->features & FEATURE_DEFAULT_HW_HANDLER)
+			hw_handler_name = NULL;
+
+		r = scsi_dh_attach(q, hw_handler_name);
 		if (r == -EBUSY) {
 			/*
 			 * Already attached to different hw_handler,
 			 * try to reattach with correct one.
 			 */
 			scsi_dh_detach(q);
+			r = scsi_dh_attach(q, hw_handler_name);
+		} else if (r == -EINVAL) {
+			/*
+			 * No hardware handler attached, use
+			 * the specified one.
+			 */
 			r = scsi_dh_attach(q, m->hw_handler_name);
 		}
 
@@ -761,7 +772,7 @@ static int parse_features(struct dm_arg_set *as, struct multipath *m)
 	const char *arg_name;
 
 	static struct dm_arg _args[] = {
-		{0, 6, "invalid number of feature args"},
+		{0, 7, "invalid number of feature args"},
 		{1, 50, "pg_init_retries must be between 1 and 50"},
 		{0, 60000, "pg_init_delay_msecs must be between 0 and 60000"},
 	};
@@ -787,6 +798,11 @@ static int parse_features(struct dm_arg_set *as, struct multipath *m)
 			continue;
 		}
 
+		if (!strcasecmp(arg_name, "default_hw_handler")) {
+			m->features |= FEATURE_DEFAULT_HW_HANDLER;
+			continue;
+		}
+
 		if (!strcasecmp(arg_name, "pg_init_retries") &&
 		    (argc >= 1)) {
 			r = dm_read_arg(_args + 1, as, &m->pg_init_retries, &ti->error);
@@ -1371,7 +1387,8 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
 		DMEMIT("%u ", m->queue_if_no_path +
 			      (m->pg_init_retries > 0) * 2 +
 			      (m->pg_init_delay_msecs != DM_PG_INIT_DELAY_DEFAULT) * 2 +
-			      (m->features & FEATURE_NO_PARTITIONS));
+			      (m->features & FEATURE_NO_PARTITIONS) +
+			      (m->features & FEATURE_DEFAULT_HW_HANDLER));
 		if (m->queue_if_no_path)
 			DMEMIT("queue_if_no_path ");
 		if (m->pg_init_retries)
@@ -1380,6 +1397,8 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
 			DMEMIT("pg_init_delay_msecs %u ", m->pg_init_delay_msecs);
 		if (m->features & FEATURE_NO_PARTITIONS)
 			DMEMIT("no_partitions ");
+		if (m->features & FEATURE_DEFAULT_HW_HANDLER)
+			DMEMIT("default_hw_handler ");
 	}
 
 	if (!m->hw_handler_name || type == STATUSTYPE_INFO)
-- 
1.6.0.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]