libata: fix locking around blk_abort_request()
PATCH 1/1 libata: fix locking around blk_abort_request()
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.
--- drivers/ata/libata-eh.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/ata/libata-eh.c +4 -0
@@ -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); }/**
Jeff Garzik
AppliedQuoted 6 lines · Tejun Heo
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.
Quoted 6 lines
--- drivers/ata/libata-eh.c | 4 ++++ 1 file changed, 4 insertions(+)
applied