aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2017-02-17 03:02:45 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-12 00:41:45 -0500
commite9dc8334d765f7910114921c63a0324272f1f636 (patch)
treee31c39b4e85db8bf02a79019d78a1ba9f0a497e2
parent73f5176ecac265b03dcd8ef0aaed6950e5ecb828 (diff)
scsi: use 'scsi_device_from_queue()' for scsi_dh
commit 857de6e00778738dc3d61f75acbac35bdc48e533 upstream. The device handler needs to check if a given queue belongs to a scsi device; only then does it make sense to attach a device handler. [mkp: dropped flags] Signed-off-by: Hannes Reinecke <hare@suse.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/scsi/scsi_dh.c22
-rw-r--r--drivers/scsi/scsi_lib.c23
-rw-r--r--include/scsi/scsi_device.h1
3 files changed, 28 insertions, 18 deletions
diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c
index b8d3b97b217a..84addee05be6 100644
--- a/drivers/scsi/scsi_dh.c
+++ b/drivers/scsi/scsi_dh.c
@@ -219,20 +219,6 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
219} 219}
220EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); 220EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
221 221
222static struct scsi_device *get_sdev_from_queue(struct request_queue *q)
223{
224 struct scsi_device *sdev;
225 unsigned long flags;
226
227 spin_lock_irqsave(q->queue_lock, flags);
228 sdev = q->queuedata;
229 if (!sdev || !get_device(&sdev->sdev_gendev))
230 sdev = NULL;
231 spin_unlock_irqrestore(q->queue_lock, flags);
232
233 return sdev;
234}
235
236/* 222/*
237 * scsi_dh_activate - activate the path associated with the scsi_device 223 * scsi_dh_activate - activate the path associated with the scsi_device
238 * corresponding to the given request queue. 224 * corresponding to the given request queue.
@@ -251,7 +237,7 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
251 struct scsi_device *sdev; 237 struct scsi_device *sdev;
252 int err = SCSI_DH_NOSYS; 238 int err = SCSI_DH_NOSYS;
253 239
254 sdev = get_sdev_from_queue(q); 240 sdev = scsi_device_from_queue(q);
255 if (!sdev) { 241 if (!sdev) {
256 if (fn) 242 if (fn)
257 fn(data, err); 243 fn(data, err);
@@ -298,7 +284,7 @@ int scsi_dh_set_params(struct request_queue *q, const char *params)
298 struct scsi_device *sdev; 284 struct scsi_device *sdev;
299 int err = -SCSI_DH_NOSYS; 285 int err = -SCSI_DH_NOSYS;
300 286
301 sdev = get_sdev_from_queue(q); 287 sdev = scsi_device_from_queue(q);
302 if (!sdev) 288 if (!sdev)
303 return err; 289 return err;
304 290
@@ -321,7 +307,7 @@ int scsi_dh_attach(struct request_queue *q, const char *name)
321 struct scsi_device_handler *scsi_dh; 307 struct scsi_device_handler *scsi_dh;
322 int err = 0; 308 int err = 0;
323 309
324 sdev = get_sdev_from_queue(q); 310 sdev = scsi_device_from_queue(q);
325 if (!sdev) 311 if (!sdev)
326 return -ENODEV; 312 return -ENODEV;
327 313
@@ -359,7 +345,7 @@ const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
359 struct scsi_device *sdev; 345 struct scsi_device *sdev;
360 const char *handler_name = NULL; 346 const char *handler_name = NULL;
361 347
362 sdev = get_sdev_from_queue(q); 348 sdev = scsi_device_from_queue(q);
363 if (!sdev) 349 if (!sdev)
364 return NULL; 350 return NULL;
365 351
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index e64eae4392a4..d8099c7cab00 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2127,6 +2127,29 @@ void scsi_mq_destroy_tags(struct Scsi_Host *shost)
2127 blk_mq_free_tag_set(&shost->tag_set); 2127 blk_mq_free_tag_set(&shost->tag_set);
2128} 2128}
2129 2129
2130/**
2131 * scsi_device_from_queue - return sdev associated with a request_queue
2132 * @q: The request queue to return the sdev from
2133 *
2134 * Return the sdev associated with a request queue or NULL if the
2135 * request_queue does not reference a SCSI device.
2136 */
2137struct scsi_device *scsi_device_from_queue(struct request_queue *q)
2138{
2139 struct scsi_device *sdev = NULL;
2140
2141 if (q->mq_ops) {
2142 if (q->mq_ops == &scsi_mq_ops)
2143 sdev = q->queuedata;
2144 } else if (q->request_fn == scsi_request_fn)
2145 sdev = q->queuedata;
2146 if (!sdev || !get_device(&sdev->sdev_gendev))
2147 sdev = NULL;
2148
2149 return sdev;
2150}
2151EXPORT_SYMBOL_GPL(scsi_device_from_queue);
2152
2130/* 2153/*
2131 * Function: scsi_block_requests() 2154 * Function: scsi_block_requests()
2132 * 2155 *
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 8a9563144890..b9ec4939b80c 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -315,6 +315,7 @@ extern void scsi_remove_device(struct scsi_device *);
315extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); 315extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh);
316void scsi_attach_vpd(struct scsi_device *sdev); 316void scsi_attach_vpd(struct scsi_device *sdev);
317 317
318extern struct scsi_device *scsi_device_from_queue(struct request_queue *q);
318extern int scsi_device_get(struct scsi_device *); 319extern int scsi_device_get(struct scsi_device *);
319extern void scsi_device_put(struct scsi_device *); 320extern void scsi_device_put(struct scsi_device *);
320extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *, 321extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,