Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2011-07-24 08:15:18 +0200
committerJiri Slaby <jslaby@suse.cz>2011-07-24 08:15:18 +0200
commitdfe0dcf0437348de10d54887fb95ba9ab417439f (patch)
treedda762d82b5b92889125f32febea6c678237a33e
parentbbe1cb6d929f3fbb97bc22ff6be162dcbe99037c (diff)
fix crash in scsi_dispatch_cmd() (bnc#707853).
-rw-r--r--patches.fixes/SCSI-fix-crash-in-scsi_dispatch_cmd.patch79
-rw-r--r--series.conf1
2 files changed, 80 insertions, 0 deletions
diff --git a/patches.fixes/SCSI-fix-crash-in-scsi_dispatch_cmd.patch b/patches.fixes/SCSI-fix-crash-in-scsi_dispatch_cmd.patch
new file mode 100644
index 0000000000..94e84e9ec5
--- /dev/null
+++ b/patches.fixes/SCSI-fix-crash-in-scsi_dispatch_cmd.patch
@@ -0,0 +1,79 @@
+From bfe159a51203c15d23cb3158fffdc25ec4b4dda1 Mon Sep 17 00:00:00 2001
+From: James Bottomley <James.Bottomley@HansenPartnership.com>
+Date: Thu, 7 Jul 2011 15:45:40 -0500
+Subject: [SCSI] fix crash in scsi_dispatch_cmd()
+Git-commit: bfe159a51203c15d23cb3158fffdc25ec4b4dda1
+Patch-mainline: yes
+References: bnc#707853
+
+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.
+
+Cc: stable@kernel.org
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ block/blk-core.c | 3 +++
+ block/blk-exec.c | 7 +++++++
+ drivers/scsi/scsi_lib.c | 2 ++
+ 3 files changed, 12 insertions(+), 0 deletions(-)
+
+diff --git a/block/blk-core.c b/block/blk-core.c
+index d2f8f40..1d49e1c 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -839,6 +839,9 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
+ {
+ struct request *rq;
+
++ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
++ return NULL;
++
+ BUG_ON(rw != READ && rw != WRITE);
+
+ spin_lock_irq(q->queue_lock);
+diff --git a/block/blk-exec.c b/block/blk-exec.c
+index 8a0e7ec..a1ebceb 100644
+--- a/block/blk-exec.c
++++ b/block/blk-exec.c
+@@ -50,6 +50,13 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
+ {
+ int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
+
++ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
++ rq->errors = -ENXIO;
++ if (rq->end_io)
++ rq->end_io(rq, rq->errors);
++ return;
++ }
++
+ rq->rq_disk = bd_disk;
+ rq->end_io = done;
+ WARN_ON(irqs_disabled());
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index ec1803a..28d9c9d 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))
+--
+1.7.6
+
diff --git a/series.conf b/series.conf
index 9a95d14952..b8a9d866db 100644
--- a/series.conf
+++ b/series.conf
@@ -368,6 +368,7 @@
patches.fixes/sd_liberal_28_sense_invalid.diff
patches.fixes/scsi-ibmvscsi-module_alias.patch
+ patches.fixes/SCSI-fix-crash-in-scsi_dispatch_cmd.patch
########################################################
# DRM/Video