diff options
author | James Bottomley <James.Bottomley@HansenPartnership.com> | 2011-07-07 15:45:40 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-04 21:58:36 -0700 |
commit | 1768e0b7e77b5c3e11cd0f0ab15358ccba3a9880 (patch) | |
tree | 1883eb13f3b634479e254ed670c1cba5423ee0cb /drivers/scsi | |
parent | b9beb51724bebfc198533144e86601f0099c026e (diff) | |
download | kernel_samsung_smdk4412-1768e0b7e77b5c3e11cd0f0ab15358ccba3a9880.tar.gz kernel_samsung_smdk4412-1768e0b7e77b5c3e11cd0f0ab15358ccba3a9880.tar.bz2 kernel_samsung_smdk4412-1768e0b7e77b5c3e11cd0f0ab15358ccba3a9880.zip |
fix crash in scsi_dispatch_cmd()
commit bfe159a51203c15d23cb3158fffdc25ec4b4dda1 upstream.
USB surprise removal of sr is triggering an oops in
scsi_dispatch_command(). What seems to be happening is that USB is
hanging on to a queue reference until the last close of the upper
device, so the crash is caused by surprise remove of a mounted CD
followed by attempted unmount.
The problem is that USB doesn't issue its final commands as part of
the SCSI teardown path, but on last close when the block queue is long
gone. The long term fix is probably to make sr do the teardown in the
same way as sd (so remove all the lower bits on ejection, but keep the
upper disk alive until last close of user space). However, the
current oops can be simply fixed by not allowing any commands to be
sent to a dead queue.
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ec1803a4872..28d9c9d6b4b 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -213,6 +213,8 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, int ret = DRIVER_ERROR << 24; req = blk_get_request(sdev->request_queue, write, __GFP_WAIT); + if (!req) + return ret; if (bufflen && blk_rq_map_kern(sdev->request_queue, req, buffer, bufflen, __GFP_WAIT)) |