[SCSI] libsas: fix deref before check in commit 70b25f890ce
authorJames Bottomley <James.Bottomley@suse.de>
Thu, 13 May 2010 14:31:54 +0000 (09:31 -0500)
committerJames Bottomley <James.Bottomley@suse.de>
Sun, 16 May 2010 19:34:58 +0000 (15:34 -0400)
commit 70b25f890ce9f0520c64075ce9225a5b020a513e
Author: Tejun Heo <tj@kernel.org>
Date:   Thu Apr 15 09:00:08 2010 +0900

    [SCSI] fix locking around blk_abort_request()

Introduced a reference before check problem, fix this by moving the
lock shorthand code to be right at the point of actual use.

Reported-by: Dan Carpenter <error27@gmail.com>
Acked-by: Tejun Heo <tj@kernel.org>
Cc: Stable Tree <stable@kernel.org>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/libsas/sas_ata.c
drivers/scsi/libsas/sas_scsi_host.c

index 88f7446725764b42a4d1eb7c54153605ea5dc9b8..8c496b56556ce232cbbe2dc1832b8cafbf2d1fbc 100644 (file)
@@ -395,12 +395,13 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev,
 void sas_ata_task_abort(struct sas_task *task)
 {
        struct ata_queued_cmd *qc = task->uldd_task;
-       struct request_queue *q = qc->scsicmd->device->request_queue;
        struct completion *waiting;
-       unsigned long flags;
 
        /* Bounce SCSI-initiated commands to the SCSI EH */
        if (qc->scsicmd) {
+               struct request_queue *q = qc->scsicmd->device->request_queue;
+               unsigned long flags;
+
                spin_lock_irqsave(q->queue_lock, flags);
                blk_abort_request(qc->scsicmd->request);
                spin_unlock_irqrestore(q->queue_lock, flags);
index 822835055cef3cc3c0fe9e9d9c6cbd2d7a17c4d4..53849f21ad4247d3edc66da875f1abd7f483a175 100644 (file)
@@ -1030,8 +1030,6 @@ int __sas_task_abort(struct sas_task *task)
 void sas_task_abort(struct sas_task *task)
 {
        struct scsi_cmnd *sc = task->uldd_task;
-       struct request_queue *q = sc->device->request_queue;
-       unsigned long flags;
 
        /* Escape for libsas internal commands */
        if (!sc) {
@@ -1043,13 +1041,15 @@ void sas_task_abort(struct sas_task *task)
 
        if (dev_is_sata(task->dev)) {
                sas_ata_task_abort(task);
-               return;
-       }
+       } else {
+               struct request_queue *q = sc->device->request_queue;
+               unsigned long flags;
 
-       spin_lock_irqsave(q->queue_lock, flags);
-       blk_abort_request(sc->request);
-       spin_unlock_irqrestore(q->queue_lock, flags);
-       scsi_schedule_eh(sc->device->host);
+               spin_lock_irqsave(q->queue_lock, flags);
+               blk_abort_request(sc->request);
+               spin_unlock_irqrestore(q->queue_lock, flags);
+               scsi_schedule_eh(sc->device->host);
+       }
 }
 
 int sas_slave_alloc(struct scsi_device *scsi_dev)