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.c27
1 files changed, 6 insertions, 21 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index eff7bdd7731d..5a67671a3973 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -159,12 +159,9 @@ static struct priority_group *alloc_priority_group(void)
159static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) 159static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
160{ 160{
161 struct pgpath *pgpath, *tmp; 161 struct pgpath *pgpath, *tmp;
162 struct multipath *m = ti->private;
163 162
164 list_for_each_entry_safe(pgpath, tmp, pgpaths, list) { 163 list_for_each_entry_safe(pgpath, tmp, pgpaths, list) {
165 list_del(&pgpath->list); 164 list_del(&pgpath->list);
166 if (m->hw_handler_name)
167 scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
168 dm_put_device(ti, pgpath->path.dev); 165 dm_put_device(ti, pgpath->path.dev);
169 free_pgpath(pgpath); 166 free_pgpath(pgpath);
170 } 167 }
@@ -580,6 +577,7 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
580 q = bdev_get_queue(p->path.dev->bdev); 577 q = bdev_get_queue(p->path.dev->bdev);
581 578
582 if (m->retain_attached_hw_handler) { 579 if (m->retain_attached_hw_handler) {
580retain:
583 attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL); 581 attached_handler_name = scsi_dh_attached_handler_name(q, GFP_KERNEL);
584 if (attached_handler_name) { 582 if (attached_handler_name) {
585 /* 583 /*
@@ -599,20 +597,14 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
599 } 597 }
600 598
601 if (m->hw_handler_name) { 599 if (m->hw_handler_name) {
602 /*
603 * Increments scsi_dh reference, even when using an
604 * already-attached handler.
605 */
606 r = scsi_dh_attach(q, m->hw_handler_name); 600 r = scsi_dh_attach(q, m->hw_handler_name);
607 if (r == -EBUSY) { 601 if (r == -EBUSY) {
608 /* 602 char b[BDEVNAME_SIZE];
609 * Already attached to different hw_handler:
610 * try to reattach with correct one.
611 */
612 scsi_dh_detach(q);
613 r = scsi_dh_attach(q, m->hw_handler_name);
614 }
615 603
604 printk(KERN_INFO "dm-mpath: retaining handler on device %s\n",
605 bdevname(p->path.dev->bdev, b));
606 goto retain;
607 }
616 if (r < 0) { 608 if (r < 0) {
617 ti->error = "error attaching hardware handler"; 609 ti->error = "error attaching hardware handler";
618 dm_put_device(ti, p->path.dev); 610 dm_put_device(ti, p->path.dev);
@@ -624,7 +616,6 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps
624 if (r < 0) { 616 if (r < 0) {
625 ti->error = "unable to set hardware " 617 ti->error = "unable to set hardware "
626 "handler parameters"; 618 "handler parameters";
627 scsi_dh_detach(q);
628 dm_put_device(ti, p->path.dev); 619 dm_put_device(ti, p->path.dev);
629 goto bad; 620 goto bad;
630 } 621 }
@@ -734,12 +725,6 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m)
734 return 0; 725 return 0;
735 726
736 m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL); 727 m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL);
737 if (!try_then_request_module(scsi_dh_handler_exist(m->hw_handler_name),
738 "scsi_dh_%s", m->hw_handler_name)) {
739 ti->error = "unknown hardware handler type";
740 ret = -EINVAL;
741 goto fail;
742 }
743 728
744 if (hw_argc > 1) { 729 if (hw_argc > 1) {
745 char *p; 730 char *p;