43 lines
1.6 KiB
Diff
43 lines
1.6 KiB
Diff
commit e73e079bf128d68284efedeba1fbbc18d78610f9
|
|
Author: James Bottomley <James.Bottomley@HansenPartnership.com>
|
|
Date: Wed May 25 15:52:14 2011 -0500
|
|
|
|
[SCSI] Fix oops caused by queue refcounting failure
|
|
|
|
In certain circumstances, we can get an oops from a torn down device.
|
|
Most notably this is from CD roms trying to call scsi_ioctl. The root
|
|
cause of the problem is the fact that after scsi_remove_device() has
|
|
been called, the queue is fully torn down. This is actually wrong
|
|
since the queue can be used until the sdev release function is called.
|
|
Therefore, we add an extra reference to the queue which is released in
|
|
sdev->release, so the queue always exists.
|
|
|
|
Reported-by: Parag Warudkar <parag.lkml@gmail.com>
|
|
Cc: stable@kernel.org
|
|
Signed-off-by: James Bottomley <jbottomley@parallels.com>
|
|
|
|
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
|
|
index 58584dc..44e8ca3 100644
|
|
--- a/drivers/scsi/scsi_scan.c
|
|
+++ b/drivers/scsi/scsi_scan.c
|
|
@@ -297,7 +297,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
|
|
kfree(sdev);
|
|
goto out;
|
|
}
|
|
-
|
|
+ blk_get_queue(sdev->request_queue);
|
|
sdev->request_queue->queuedata = sdev;
|
|
scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
|
|
|
|
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
|
|
index e639125..e0bd3f7 100644
|
|
--- a/drivers/scsi/scsi_sysfs.c
|
|
+++ b/drivers/scsi/scsi_sysfs.c
|
|
@@ -322,6 +322,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
|
|
kfree(evt);
|
|
}
|
|
|
|
+ blk_put_queue(sdev->request_queue);
|
|
/* NULL queue means the device can't be used */
|
|
sdev->request_queue = NULL;
|
|
|