[kernel/f15-30-going-on-40] Fix the USB eject problem for real.
Dave Jones
davej at fedoraproject.org
Thu Jul 28 20:50:08 UTC 2011
commit 3acc7b100d8a7c504374cb81ddc4d042cdbb5bf1
Author: Dave Jones <davej at redhat.com>
Date: Thu Jul 28 16:47:47 2011 -0400
Fix the USB eject problem for real.
fix-scsi_dispatch_cmd.patch | 68 +++++++++++++++++++++++++++++++++++++++++++
kernel.spec | 7 ++++
2 files changed, 75 insertions(+), 0 deletions(-)
---
diff --git a/fix-scsi_dispatch_cmd.patch b/fix-scsi_dispatch_cmd.patch
new file mode 100644
index 0000000..3976791
--- /dev/null
+++ b/fix-scsi_dispatch_cmd.patch
@@ -0,0 +1,68 @@
+commit bfe159a51203c15d23cb3158fffdc25ec4b4dda1
+Author: James Bottomley <James.Bottomley at HansenPartnership.com>
+Date: Thu Jul 7 15:45:40 2011 -0500
+
+ [SCSI] fix crash in scsi_dispatch_cmd()
+
+ 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 at kernel.org
+ Signed-off-by: James Bottomley <JBottomley at Parallels.com>
+
+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))
diff --git a/kernel.spec b/kernel.spec
index e6c4295..42e0f81 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -683,6 +683,8 @@ Patch12205: runtime_pm_fixups.patch
Patch12303: dmar-disable-when-ricoh-multifunction.patch
+Patch13000: fix-scsi_dispatch_cmd.patch
+
%endif
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1260,6 +1262,8 @@ ApplyPatch neuter_intel_microcode_load.patch
# rhbz#605888
ApplyPatch dmar-disable-when-ricoh-multifunction.patch
+ApplyPatch fix-scsi_dispatch_cmd.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -1872,6 +1876,9 @@ fi
# and build.
%changelog
+* Thu Jul 28 2011 Dave Jones <davej at redhat.com>
+- fix crash in scsi_dispatch_cmd()
+
* Thu Jul 28 2011 Dave Jones <davej at redhat.com> 2.6.40-1
- Turn off debugging options. (make release)
More information about the scm-commits
mailing list