Avoid dangling pointer in scsi_requeue_command()
[pandora-kernel.git] / drivers / scsi / scsi_lib.c
index 4f68ba6..6c4b620 100644 (file)
@@ -479,15 +479,26 @@ void scsi_requeue_run_queue(struct work_struct *work)
  */
 static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
 {
+       struct scsi_device *sdev = cmd->device;
        struct request *req = cmd->request;
        unsigned long flags;
 
+       /*
+        * We need to hold a reference on the device to avoid the queue being
+        * killed after the unlock and before scsi_run_queue is invoked which
+        * may happen because scsi_unprep_request() puts the command which
+        * releases its reference on the device.
+        */
+       get_device(&sdev->sdev_gendev);
+
        spin_lock_irqsave(q->queue_lock, flags);
        scsi_unprep_request(req);
        blk_requeue_request(q, req);
        spin_unlock_irqrestore(q->queue_lock, flags);
 
        scsi_run_queue(q);
+
+       put_device(&sdev->sdev_gendev);
 }
 
 void scsi_next_command(struct scsi_cmnd *cmd)