mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-07-16 22:38:04 +00:00
56e60917b2
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Signed-off-by: Denys Dmytriyenko <denys@ti.com> Signed-off-by: Denys Dmytriyenko <denis@denix.org>
58 lines
2.0 KiB
Diff
58 lines
2.0 KiB
Diff
From c24bb6a70695fb930fc0b976db55fad4334cd992 Mon Sep 17 00:00:00 2001
|
|
From: Bart Van Assche <bvanassche@acm.org>
|
|
Date: Fri, 29 Jun 2012 15:34:26 +0000
|
|
Subject: [PATCH 54/73] Avoid dangling pointer in scsi_requeue_command()
|
|
|
|
commit 940f5d47e2f2e1fa00443921a0abf4822335b54d upstream.
|
|
|
|
When we call scsi_unprep_request() the command associated with the request
|
|
gets destroyed and therefore drops its reference on the device. If this was
|
|
the only reference, the device may get released and we end up with a NULL
|
|
pointer deref when we call blk_requeue_request.
|
|
|
|
Reported-by: Mike Christie <michaelc@cs.wisc.edu>
|
|
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
|
|
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
|
|
Reviewed-by: Tejun Heo <tj@kernel.org>
|
|
[jejb: enhance commend and add commit log for stable]
|
|
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
|
|
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
|
---
|
|
drivers/scsi/scsi_lib.c | 11 +++++++++++
|
|
1 files changed, 11 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
|
|
index 4f68ba6..6c4b620 100644
|
|
--- a/drivers/scsi/scsi_lib.c
|
|
+++ b/drivers/scsi/scsi_lib.c
|
|
@@ -479,15 +479,26 @@ void scsi_requeue_run_queue(struct work_struct *work)
|
|
*/
|
|
static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
|
|
{
|
|
+ struct scsi_device *sdev = cmd->device;
|
|
struct request *req = cmd->request;
|
|
unsigned long flags;
|
|
|
|
+ /*
|
|
+ * We need to hold a reference on the device to avoid the queue being
|
|
+ * killed after the unlock and before scsi_run_queue is invoked which
|
|
+ * may happen because scsi_unprep_request() puts the command which
|
|
+ * releases its reference on the device.
|
|
+ */
|
|
+ get_device(&sdev->sdev_gendev);
|
|
+
|
|
spin_lock_irqsave(q->queue_lock, flags);
|
|
scsi_unprep_request(req);
|
|
blk_requeue_request(q, req);
|
|
spin_unlock_irqrestore(q->queue_lock, flags);
|
|
|
|
scsi_run_queue(q);
|
|
+
|
|
+ put_device(&sdev->sdev_gendev);
|
|
}
|
|
|
|
void scsi_next_command(struct scsi_cmnd *cmd)
|
|
--
|
|
1.7.7.6
|
|
|