]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/scsi-dh-queuedata-accessors
Merge branch 'master' of git://git.ipfire.org/ipfire-2.x
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / scsi-dh-queuedata-accessors
1 From: Hannes Reinecke <hare@suse.de>
2 Subject: Kernel bug triggered in multipath
3 References: bnc#486001
4
5 Starting multipath on a cciss device will cause a kernel
6 warning to be triggered. Problem is that we're using the
7 ->queuedata field of the request_queue to derefence the
8 scsi device; however, for other (non-SCSI) devices this
9 points to a totally different structure.
10 So we should rather be using accessors here which make
11 sure we're only returning valid SCSI device structures.
12
13 Signed-off-by: Hannes Reinecke <hare@suse.de>
14
15 ---
16 drivers/scsi/device_handler/scsi_dh.c | 10 +++++-----
17 drivers/scsi/scsi_lib.c | 11 +++++++++++
18 include/scsi/scsi_device.h | 1 +
19 3 files changed, 17 insertions(+), 5 deletions(-)
20
21 --- a/drivers/scsi/device_handler/scsi_dh.c
22 +++ b/drivers/scsi/device_handler/scsi_dh.c
23 @@ -427,7 +427,7 @@ int scsi_dh_activate(struct request_queu
24 struct scsi_device_handler *scsi_dh = NULL;
25
26 spin_lock_irqsave(q->queue_lock, flags);
27 - sdev = q->queuedata;
28 + sdev = scsi_device_from_queue(q);
29 if (sdev && sdev->scsi_dh_data)
30 scsi_dh = sdev->scsi_dh_data->scsi_dh;
31 if (!scsi_dh || !get_device(&sdev->sdev_gendev))
32 @@ -456,7 +456,7 @@ int scsi_dh_handler_exist(const char *na
33 EXPORT_SYMBOL_GPL(scsi_dh_handler_exist);
34
35 /*
36 - * scsi_dh_handler_attach - Attach device handler
37 + * scsi_dh_attach - Attach device handler
38 * @sdev - sdev the handler should be attached to
39 * @name - name of the handler to attach
40 */
41 @@ -472,7 +472,7 @@ int scsi_dh_attach(struct request_queue
42 return -EINVAL;
43
44 spin_lock_irqsave(q->queue_lock, flags);
45 - sdev = q->queuedata;
46 + sdev = scsi_device_from_queue(q);
47 if (!sdev || !get_device(&sdev->sdev_gendev))
48 err = -ENODEV;
49 spin_unlock_irqrestore(q->queue_lock, flags);
50 @@ -487,7 +487,7 @@ int scsi_dh_attach(struct request_queue
51 EXPORT_SYMBOL_GPL(scsi_dh_attach);
52
53 /*
54 - * scsi_dh_handler_detach - Detach device handler
55 + * scsi_dh_detach - Detach device handler
56 * @sdev - sdev the handler should be detached from
57 *
58 * This function will detach the device handler only
59 @@ -501,7 +501,7 @@ void scsi_dh_detach(struct request_queue
60 struct scsi_device_handler *scsi_dh = NULL;
61
62 spin_lock_irqsave(q->queue_lock, flags);
63 - sdev = q->queuedata;
64 + sdev = scsi_device_from_queue(q);
65 if (!sdev || !get_device(&sdev->sdev_gendev))
66 sdev = NULL;
67 spin_unlock_irqrestore(q->queue_lock, flags);
68 --- a/drivers/scsi/scsi_lib.c
69 +++ b/drivers/scsi/scsi_lib.c
70 @@ -1696,6 +1696,17 @@ static void scsi_request_fn(struct reque
71 spin_lock_irq(q->queue_lock);
72 }
73
74 +struct scsi_device *scsi_device_from_queue(struct request_queue *q)
75 +{
76 + struct scsi_device *sdev = NULL;
77 +
78 + if (q->request_fn == scsi_request_fn)
79 + sdev = q->queuedata;
80 +
81 + return sdev;
82 +}
83 +EXPORT_SYMBOL_GPL(scsi_device_from_queue);
84 +
85 u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost)
86 {
87 struct device *host_dev;
88 --- a/include/scsi/scsi_device.h
89 +++ b/include/scsi/scsi_device.h
90 @@ -291,6 +291,7 @@ extern void starget_for_each_device(stru
91 extern void __starget_for_each_device(struct scsi_target *, void *,
92 void (*fn)(struct scsi_device *,
93 void *));
94 +extern struct scsi_device *scsi_device_from_queue(struct request_queue *);
95
96 /* only exposed to implement shost_for_each_device */
97 extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,