ata: libata-scsi: Fix ata_scsi_dev_rescan() error path
Commit0c76106cb9
("scsi: sd: Fix TCG OPAL unlock on system resume") incorrectly handles failures of scsi_resume_device() in ata_scsi_dev_rescan(), leading to a double call to spin_unlock_irqrestore() to unlock a device port. Fix this by redefining the goto labels used in case of errors and only unlock the port scsi_scan_mutex when scsi_resume_device() fails. Bug found with the Smatch static checker warning: drivers/ata/libata-scsi.c:4774 ata_scsi_dev_rescan() error: double unlocked 'ap->lock' (orig line 4757) Reported-by: Dan Carpenter <dan.carpenter@linaro.org> Fixes:0c76106cb9
("scsi: sd: Fix TCG OPAL unlock on system resume") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Niklas Cassel <cassel@kernel.org>
This commit is contained in:
parent
24cfd86433
commit
7933650478
|
@ -4745,7 +4745,7 @@ void ata_scsi_dev_rescan(struct work_struct *work)
|
||||||
* bail out.
|
* bail out.
|
||||||
*/
|
*/
|
||||||
if (ap->pflags & ATA_PFLAG_SUSPENDED)
|
if (ap->pflags & ATA_PFLAG_SUSPENDED)
|
||||||
goto unlock;
|
goto unlock_ap;
|
||||||
|
|
||||||
if (!sdev)
|
if (!sdev)
|
||||||
continue;
|
continue;
|
||||||
|
@ -4758,7 +4758,7 @@ void ata_scsi_dev_rescan(struct work_struct *work)
|
||||||
if (do_resume) {
|
if (do_resume) {
|
||||||
ret = scsi_resume_device(sdev);
|
ret = scsi_resume_device(sdev);
|
||||||
if (ret == -EWOULDBLOCK)
|
if (ret == -EWOULDBLOCK)
|
||||||
goto unlock;
|
goto unlock_scan;
|
||||||
dev->flags &= ~ATA_DFLAG_RESUMING;
|
dev->flags &= ~ATA_DFLAG_RESUMING;
|
||||||
}
|
}
|
||||||
ret = scsi_rescan_device(sdev);
|
ret = scsi_rescan_device(sdev);
|
||||||
|
@ -4766,12 +4766,13 @@ void ata_scsi_dev_rescan(struct work_struct *work)
|
||||||
spin_lock_irqsave(ap->lock, flags);
|
spin_lock_irqsave(ap->lock, flags);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto unlock;
|
goto unlock_ap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock:
|
unlock_ap:
|
||||||
spin_unlock_irqrestore(ap->lock, flags);
|
spin_unlock_irqrestore(ap->lock, flags);
|
||||||
|
unlock_scan:
|
||||||
mutex_unlock(&ap->scsi_scan_mutex);
|
mutex_unlock(&ap->scsi_scan_mutex);
|
||||||
|
|
||||||
/* Reschedule with a delay if scsi_rescan_device() returned an error */
|
/* Reschedule with a delay if scsi_rescan_device() returned an error */
|
||||||
|
|
Loading…
Reference in New Issue