Commit 2b448c6b authored by James Bottomley's avatar James Bottomley

[SCSI] fix memory etc. leak caused by double preparing requeued commands

parent 30b010d8
...@@ -658,7 +658,7 @@ inline void __scsi_release_command(Scsi_Cmnd * SCpnt) ...@@ -658,7 +658,7 @@ inline void __scsi_release_command(Scsi_Cmnd * SCpnt)
* Notes: This could be called either from an interrupt context or a * Notes: This could be called either from an interrupt context or a
* normal process context. * normal process context.
*/ */
static int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason) int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
{ {
struct Scsi_Host *host = cmd->host; struct Scsi_Host *host = cmd->host;
unsigned long flags; unsigned long flags;
......
...@@ -480,6 +480,7 @@ extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd, ...@@ -480,6 +480,7 @@ extern void scsi_do_cmd(Scsi_Cmnd *, const void *cmnd,
void (*done) (struct scsi_cmnd *), void (*done) (struct scsi_cmnd *),
int timeout, int retries); int timeout, int retries);
extern int scsi_dev_init(void); extern int scsi_dev_init(void);
extern int scsi_mlqueue_insert(struct scsi_cmnd *, int);
/* /*
* Newer request-based interfaces. * Newer request-based interfaces.
......
...@@ -1005,7 +1005,8 @@ void scsi_request_fn(request_queue_t * q) ...@@ -1005,7 +1005,8 @@ void scsi_request_fn(request_queue_t * q)
req = NULL; req = NULL;
spin_unlock_irq(q->queue_lock); spin_unlock_irq(q->queue_lock);
if (SCpnt->request->flags & (REQ_CMD | REQ_BLOCK_PC)) { if (!(SCpnt->request->flags & REQ_DONTPREP)
&& (SCpnt->request->flags & (REQ_CMD | REQ_BLOCK_PC))) {
/* /*
* This will do a couple of things: * This will do a couple of things:
* 1) Fill in the actual SCSI command. * 1) Fill in the actual SCSI command.
...@@ -1026,18 +1027,8 @@ void scsi_request_fn(request_queue_t * q) ...@@ -1026,18 +1027,8 @@ void scsi_request_fn(request_queue_t * q)
* required). * required).
*/ */
if (!scsi_init_io(SCpnt)) { if (!scsi_init_io(SCpnt)) {
scsi_mlqueue_insert(SCpnt, SCSI_MLQUEUE_DEVICE_BUSY);
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
SHpnt->host_busy--;
SDpnt->device_busy--;
if (SDpnt->device_busy == 0) {
SDpnt->starved = 1;
SHpnt->some_device_starved = 1;
}
SCpnt->request->special = SCpnt;
SCpnt->request->flags |= REQ_SPECIAL;
if(blk_rq_tagged(SCpnt->request))
blk_queue_end_tag(q, SCpnt->request);
_elv_add_request(q, SCpnt->request, 0, 0);
break; break;
} }
...@@ -1058,6 +1049,7 @@ void scsi_request_fn(request_queue_t * q) ...@@ -1058,6 +1049,7 @@ void scsi_request_fn(request_queue_t * q)
continue; continue;
} }
} }
SCpnt->request->flags |= REQ_DONTPREP;
/* /*
* Finally, initialize any error handling parameters, and set up * Finally, initialize any error handling parameters, and set up
* the timers for timeouts. * the timers for timeouts.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment