aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-mpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-mpath.c')
-rw-r--r--drivers/md/dm-mpath.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 6f0d90d4a541..32d0b878eccc 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -64,6 +64,7 @@ struct multipath {
64 spinlock_t lock; 64 spinlock_t lock;
65 65
66 const char *hw_handler_name; 66 const char *hw_handler_name;
67 char *hw_handler_params;
67 unsigned nr_priority_groups; 68 unsigned nr_priority_groups;
68 struct list_head priority_groups; 69 struct list_head priority_groups;
69 unsigned pg_init_required; /* pg_init needs calling? */ 70 unsigned pg_init_required; /* pg_init needs calling? */
@@ -219,6 +220,7 @@ static void free_multipath(struct multipath *m)
219 } 220 }
220 221
221 kfree(m->hw_handler_name); 222 kfree(m->hw_handler_name);
223 kfree(m->hw_handler_params);
222 mempool_destroy(m->mpio_pool); 224 mempool_destroy(m->mpio_pool);
223 kfree(m); 225 kfree(m);
224} 226}
@@ -615,6 +617,17 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
615 dm_put_device(ti, p->path.dev); 617 dm_put_device(ti, p->path.dev);
616 goto bad; 618 goto bad;
617 } 619 }
620
621 if (m->hw_handler_params) {
622 r = scsi_dh_set_params(q, m->hw_handler_params);
623 if (r < 0) {
624 ti->error = "unable to set hardware "
625 "handler parameters";
626 scsi_dh_detach(q);
627 dm_put_device(ti, p->path.dev);
628 goto bad;
629 }
630 }
618 } 631 }
619 632
620 r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error); 633 r = ps->type->add_path(ps, &p->path, as->argc, as->argv, &ti->error);
@@ -705,6 +718,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
705static int parse_hw_handler(struct arg_set *as, struct multipath *m) 718static int parse_hw_handler(struct arg_set *as, struct multipath *m)
706{ 719{
707 unsigned hw_argc; 720 unsigned hw_argc;
721 int ret;
708 struct dm_target *ti = m->ti; 722 struct dm_target *ti = m->ti;
709 723
710 static struct param _params[] = { 724 static struct param _params[] = {
@@ -726,17 +740,33 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m)
726 request_module("scsi_dh_%s", m->hw_handler_name); 740 request_module("scsi_dh_%s", m->hw_handler_name);
727 if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { 741 if (scsi_dh_handler_exist(m->hw_handler_name) == 0) {
728 ti->error = "unknown hardware handler type"; 742 ti->error = "unknown hardware handler type";
729 kfree(m->hw_handler_name); 743 ret = -EINVAL;
730 m->hw_handler_name = NULL; 744 goto fail;
731 return -EINVAL;
732 } 745 }
733 746
734 if (hw_argc > 1) 747 if (hw_argc > 1) {
735 DMWARN("Ignoring user-specified arguments for " 748 char *p;
736 "hardware handler \"%s\"", m->hw_handler_name); 749 int i, j, len = 4;
750
751 for (i = 0; i <= hw_argc - 2; i++)
752 len += strlen(as->argv[i]) + 1;
753 p = m->hw_handler_params = kzalloc(len, GFP_KERNEL);
754 if (!p) {
755 ti->error = "memory allocation failed";
756 ret = -ENOMEM;
757 goto fail;
758 }
759 j = sprintf(p, "%d", hw_argc - 1);
760 for (i = 0, p+=j+1; i <= hw_argc - 2; i++, p+=j+1)
761 j = sprintf(p, "%s", as->argv[i]);
762 }
737 consume(as, hw_argc - 1); 763 consume(as, hw_argc - 1);
738 764
739 return 0; 765 return 0;
766fail:
767 kfree(m->hw_handler_name);
768 m->hw_handler_name = NULL;
769 return ret;
740} 770}
741 771
742static int parse_features(struct arg_set *as, struct multipath *m) 772static int parse_features(struct arg_set *as, struct multipath *m)