| From e73e079bf128d68284efedeba1fbbc18d78610f9 Mon Sep 17 00:00:00 2001 |
| From: James Bottomley <James.Bottomley@HansenPartnership.com> |
| Date: Wed, 25 May 2011 15:52:14 -0500 |
| Subject: [SCSI] Fix oops caused by queue refcounting failure |
| |
| From: James Bottomley <James.Bottomley@HansenPartnership.com> |
| |
| commit e73e079bf128d68284efedeba1fbbc18d78610f9 upstream. |
| |
| 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> |
| Signed-off-by: James Bottomley <jbottomley@parallels.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/scsi/scsi_scan.c | 2 +- |
| drivers/scsi/scsi_sysfs.c | 1 + |
| 2 files changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/scsi/scsi_scan.c |
| +++ b/drivers/scsi/scsi_scan.c |
| @@ -294,7 +294,7 @@ static struct scsi_device *scsi_alloc_sd |
| 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); |
| |
| --- a/drivers/scsi/scsi_sysfs.c |
| +++ b/drivers/scsi/scsi_sysfs.c |
| @@ -318,6 +318,7 @@ static void scsi_device_dev_release_user |
| kfree(evt); |
| } |
| |
| + blk_put_queue(sdev->request_queue); |
| /* NULL queue means the device can't be used */ |
| sdev->request_queue = NULL; |
| |