projects
/
openwrt
/
staging
/
blogic.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
| inline |
side by side
(parent:
c81eddb
)
libata: fix locking around blk_abort_request()
author
Tejun Heo
<
[email protected]
>
Wed, 14 Apr 2010 23:57:37 +0000
(08:57 +0900)
committer
Jeff Garzik
<
[email protected]
>
Fri, 23 Apr 2010 01:47:52 +0000
(21:47 -0400)
blk_abort_request() expectes queue lock to be held by the caller.
Grab it before calling the function.
Lack of this synchronization led to infinite loop on corrupt
q->timeout_list.
Signed-off-by: Tejun Heo <
[email protected]
>
Cc: Jens Axboe <
[email protected]
>
Cc:
[email protected]
Signed-off-by: Jeff Garzik <
[email protected]
>
drivers/ata/libata-eh.c
patch
|
blob
|
history
diff --git
a/drivers/ata/libata-eh.c
b/drivers/ata/libata-eh.c
index 9f6cfac0f2cce6ac50bf8ca2262326cad5c21201..9e18cc9be0d37f910345582a180dc4909ad34abb 100644
(file)
--- a/
drivers/ata/libata-eh.c
+++ b/
drivers/ata/libata-eh.c
@@
-879,6
+879,8
@@
static void ata_eh_set_pending(struct ata_port *ap, int fastdrain)
void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
+ struct request_queue *q = qc->scsicmd->device->request_queue;
+ unsigned long flags;
WARN_ON(!ap->ops->error_handler);
@@
-890,7
+892,9
@@
void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
* Note that ATA_QCFLAG_FAILED is unconditionally set after
* this function completes.
*/
+ spin_lock_irqsave(q->queue_lock, flags);
blk_abort_request(qc->scsicmd->request);
+ spin_unlock_irqrestore(q->queue_lock, flags);
}
/**