summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2012-06-29 15:33:22 +0000
committerBen Hutchings <ben@decadent.org.uk>2012-08-02 14:37:54 +0100
commit9c63d964e3f093b858a6f06875a68bc4206f71ba (patch)
treee1eb150dbac4bf85f94424953005e408991cdc7d /drivers/scsi/scsi_sysfs.c
parent68e9e9fee2bbec4853a993e98b0df8479292f572 (diff)
Fix device removal NULL pointer dereference
commit 67bd94130015c507011af37858989b199c52e1de upstream. Use blk_queue_dead() to test whether the queue is dead instead of !sdev. Since scsi_prep_fn() may be invoked concurrently with __scsi_remove_device(), keep the queuedata (sdev) pointer in __scsi_remove_device(). This patch fixes a kernel oops that can be triggered by USB device removal. See also http://www.spinics.net/lists/linux-scsi/msg56254.html. Other changes included in this patch: - Swap the blk_cleanup_queue() and kfree() calls in scsi_host_dev_release() to make that code easier to grasp. - Remove the queue dead check from scsi_run_queue() since the queue state can change anyway at any point in that function where the queue lock is not held. - Remove the queue dead check from the start of scsi_request_fn() since it is redundant with the scsi_device_online() check. Reported-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com> Signed-off-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Reviewed-by: Tejun Heo <tj@kernel.org> Signed-off-by: James Bottomley <JBottomley@Parallels.com> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c5
1 files changed, 1 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 04c2a278076e..42c35ff9cceb 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -971,11 +971,8 @@ void __scsi_remove_device(struct scsi_device *sdev)
sdev->host->hostt->slave_destroy(sdev);
transport_destroy_device(dev);
- /* cause the request function to reject all I/O requests */
- sdev->request_queue->queuedata = NULL;
-
/* Freeing the queue signals to block that we're done */
- scsi_free_queue(sdev->request_queue);
+ blk_cleanup_queue(sdev->request_queue);
put_device(dev);
}