[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