]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.fixes/dm-mpath-reattach-dh
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.fixes / dm-mpath-reattach-dh
CommitLineData
2cb7cef9
BS
1From: Hannes Reinecke <hare@suse.de>
2Subject: Reattach device handler for multipath devices
3References: bnc#435688
4
5The multipath daemon might have specified a different device_handler
6than the one a device is attached to by default.
7So we should try to re-attach with the user-specified device_handler
8and only return an error if that fails.
9And we should _not_ detach existing hardware handlers. This will
10set the path to failed during failover.
11
12Signed-off-by: Hannes Reinecke <hare@suse.de
13
14---
15 drivers/md/dm-mpath.c | 16 ++++++++++++----
16 drivers/scsi/device_handler/scsi_dh.c | 10 +++-------
17 2 files changed, 15 insertions(+), 11 deletions(-)
18
19--- a/drivers/md/dm-mpath.c
20+++ b/drivers/md/dm-mpath.c
21@@ -163,8 +163,6 @@ static void free_pgpaths(struct list_hea
22
23 list_for_each_entry_safe(pgpath, tmp, pgpaths, list) {
24 list_del(&pgpath->list);
25- if (m->hw_handler_name)
26- scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
27 dm_put_device(ti, pgpath->path.dev);
28 spin_lock_irqsave(&m->lock, flags);
29 if (m->pgpath_to_activate == pgpath)
30@@ -599,9 +597,19 @@ static struct pgpath *parse_path(struct
31 }
32
33 if (m->hw_handler_name) {
34- r = scsi_dh_attach(bdev_get_queue(p->path.dev->bdev),
35- m->hw_handler_name);
36+ struct request_queue *q = bdev_get_queue(p->path.dev->bdev);
37+
38+ r = scsi_dh_attach(q, m->hw_handler_name);
39+ if (r == -EBUSY) {
40+ /*
41+ * Already attached to different hw_handler,
42+ * try to reattach with correct one.
43+ */
44+ scsi_dh_detach(q);
45+ r = scsi_dh_attach(q, m->hw_handler_name);
46+ }
47 if (r < 0) {
48+ ti->error = "error attaching hardware handler";
49 dm_put_device(ti, p->path.dev);
50 goto bad;
51 }
52--- a/drivers/scsi/device_handler/scsi_dh.c
53+++ b/drivers/scsi/device_handler/scsi_dh.c
54@@ -498,7 +498,6 @@ void scsi_dh_detach(struct request_queue
55 {
56 unsigned long flags;
57 struct scsi_device *sdev;
58- struct scsi_device_handler *scsi_dh = NULL;
59
60 spin_lock_irqsave(q->queue_lock, flags);
61 sdev = scsi_device_from_queue(q);
62@@ -509,12 +508,9 @@ void scsi_dh_detach(struct request_queue
63 if (!sdev)
64 return;
65
66- if (sdev->scsi_dh_data) {
67- /* if sdev is not on internal list, detach */
68- scsi_dh = sdev->scsi_dh_data->scsi_dh;
69- if (!device_handler_match(scsi_dh, sdev))
70- scsi_dh_handler_detach(sdev, scsi_dh);
71- }
72+ if (sdev->scsi_dh_data)
73+ scsi_dh_handler_detach(sdev, sdev->scsi_dh_data->scsi_dh);
74+
75 put_device(&sdev->sdev_gendev);
76 }
77 EXPORT_SYMBOL_GPL(scsi_dh_detach);