mirror of
https://github.com/torvalds/linux.git
synced 2026-03-07 23:04:33 +01:00
ata: libata-eh: Fix detection of deferred qc timeouts
If the ata_qc_for_each_raw() loop finishes without finding a matching SCSI
command for any QC, the variable qc will hold a pointer to the last element
examined, which has the tag i == ATA_MAX_QUEUE - 1. This qc can match the
port deferred QC (ap->deferred_qc).
If that happens, the condition qc == ap->deferred_qc evaluates to true
despite the loop not breaking with a match on the SCSI command for this QC.
In that case, the error handler mistakenly intercepts a command that has
not been issued yet and that has not timed out, and thus erroneously
returning a timeout error.
Fix the problem by checking for i < ATA_MAX_QUEUE in addition to
qc == ap->deferred_qc.
The problem was found by an experimental code review agent based on
gemini-3.1-pro while reviewing backports into v6.18.y.
Assisted-by: Gemini:gemini-3.1-pro
Fixes: eddb98ad93 ("ata: libata-eh: correctly handle deferred qc timeouts")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
[cassel: modified commit log as suggested by Damien]
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Niklas Cassel <cassel@kernel.org>
This commit is contained in:
parent
b92b0075ee
commit
ee0e6e69a7
1 changed files with 1 additions and 1 deletions
|
|
@ -647,7 +647,7 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
|
|||
break;
|
||||
}
|
||||
|
||||
if (qc == ap->deferred_qc) {
|
||||
if (i < ATA_MAX_QUEUE && qc == ap->deferred_qc) {
|
||||
/*
|
||||
* This is a deferred command that timed out while
|
||||
* waiting for the command queue to drain. Since the qc
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue