scsi: use 'scsi_device_from_queue()' for scsi_dh

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]

Cc: <stable@vger.kernel.org>
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>
This commit is contained in:
Hannes Reinecke 2017-02-17 09:02:45 +01:00 committed by Martin K. Petersen
parent f22aaec97d
commit 857de6e007
3 changed files with 28 additions and 18 deletions

View File

@ -219,20 +219,6 @@ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
} }
EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
static struct scsi_device *get_sdev_from_queue(struct request_queue *q)
{
struct scsi_device *sdev;
unsigned long flags;
spin_lock_irqsave(q->queue_lock, flags);
sdev = q->queuedata;
if (!sdev || !get_device(&sdev->sdev_gendev))
sdev = NULL;
spin_unlock_irqrestore(q->queue_lock, flags);
return sdev;
}
/* /*
* scsi_dh_activate - activate the path associated with the scsi_device * scsi_dh_activate - activate the path associated with the scsi_device
* corresponding to the given request queue. * corresponding to the given request queue.
@ -251,7 +237,7 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
struct scsi_device *sdev; struct scsi_device *sdev;
int err = SCSI_DH_NOSYS; int err = SCSI_DH_NOSYS;
sdev = get_sdev_from_queue(q); sdev = scsi_device_from_queue(q);
if (!sdev) { if (!sdev) {
if (fn) if (fn)
fn(data, err); fn(data, err);
@ -298,7 +284,7 @@ int scsi_dh_set_params(struct request_queue *q, const char *params)
struct scsi_device *sdev; struct scsi_device *sdev;
int err = -SCSI_DH_NOSYS; int err = -SCSI_DH_NOSYS;
sdev = get_sdev_from_queue(q); sdev = scsi_device_from_queue(q);
if (!sdev) if (!sdev)
return err; return err;
@ -321,7 +307,7 @@ int scsi_dh_attach(struct request_queue *q, const char *name)
struct scsi_device_handler *scsi_dh; struct scsi_device_handler *scsi_dh;
int err = 0; int err = 0;
sdev = get_sdev_from_queue(q); sdev = scsi_device_from_queue(q);
if (!sdev) if (!sdev)
return -ENODEV; return -ENODEV;
@ -359,7 +345,7 @@ const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
struct scsi_device *sdev; struct scsi_device *sdev;
const char *handler_name = NULL; const char *handler_name = NULL;
sdev = get_sdev_from_queue(q); sdev = scsi_device_from_queue(q);
if (!sdev) if (!sdev)
return NULL; return NULL;

View File

@ -2231,6 +2231,29 @@ void scsi_mq_destroy_tags(struct Scsi_Host *shost)
blk_mq_free_tag_set(&shost->tag_set); blk_mq_free_tag_set(&shost->tag_set);
} }
/**
* scsi_device_from_queue - return sdev associated with a request_queue
* @q: The request queue to return the sdev from
*
* Return the sdev associated with a request queue or NULL if the
* request_queue does not reference a SCSI device.
*/
struct scsi_device *scsi_device_from_queue(struct request_queue *q)
{
struct scsi_device *sdev = NULL;
if (q->mq_ops) {
if (q->mq_ops == &scsi_mq_ops)
sdev = q->queuedata;
} else if (q->request_fn == scsi_request_fn)
sdev = q->queuedata;
if (!sdev || !get_device(&sdev->sdev_gendev))
sdev = NULL;
return sdev;
}
EXPORT_SYMBOL_GPL(scsi_device_from_queue);
/* /*
* Function: scsi_block_requests() * Function: scsi_block_requests()
* *

View File

@ -315,6 +315,7 @@ extern void scsi_remove_device(struct scsi_device *);
extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh);
void scsi_attach_vpd(struct scsi_device *sdev); void scsi_attach_vpd(struct scsi_device *sdev);
extern struct scsi_device *scsi_device_from_queue(struct request_queue *q);
extern int scsi_device_get(struct scsi_device *); extern int scsi_device_get(struct scsi_device *);
extern void scsi_device_put(struct scsi_device *); extern void scsi_device_put(struct scsi_device *);
extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *, extern struct scsi_device *scsi_device_lookup(struct Scsi_Host *,