]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.fixes/dm-mpath-reattach-dh
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / dm-mpath-reattach-dh
1 From: Hannes Reinecke <hare@suse.de>
2 Subject: Reattach device handler for multipath devices
3 References: bnc#435688
4
5 The multipath daemon might have specified a different device_handler
6 than the one a device is attached to by default.
7 So we should try to re-attach with the user-specified device_handler
8 and only return an error if that fails.
9 And we should _not_ detach existing hardware handlers. This will
10 set the path to failed during failover.
11
12 Signed-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 @@ -593,9 +591,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);