ChangeSet 1.1537.6.8, 2005/02/18 15:50:12-05:00, [EMAIL PROTECTED] [PATCH] libata: fix command queue leak when xlat_func fails ata_scsi_translate allocates from the libata command queue by calling ata_scsi_qc_new. If xlat_func returns non-zero, control jumps to err_out which fails to free the allocated command. Fix is to add a new API to free unused commands. Signed-off-by: John W. Linville <[EMAIL PROTECTED]> Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
libata-core.c | 18 ++++++++++++++++++ libata-scsi.c | 1 + libata.h | 1 + 3 files changed, 20 insertions(+) diff -Nru a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c --- a/drivers/scsi/libata-core.c 2005-03-04 12:02:28 -08:00 +++ b/drivers/scsi/libata-core.c 2005-03-04 12:02:28 -08:00 @@ -2752,6 +2752,24 @@ } /** + * ata_qc_free - free unused ata_queued_cmd + * @qc: Command to complete + * + * Designed to free unused ata_queued_cmd object + * in case something prevents using it. + * + * LOCKING: + * + */ +void ata_qc_free(struct ata_queued_cmd *qc) +{ + assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */ + assert(qc->waiting == NULL); /* nothing should be waiting */ + + __ata_qc_complete(qc); +} + +/** * ata_qc_complete - Complete an active ATA command * @qc: Command to complete * @drv_stat: ATA status register contents diff -Nru a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c --- a/drivers/scsi/libata-scsi.c 2005-03-04 12:02:28 -08:00 +++ b/drivers/scsi/libata-scsi.c 2005-03-04 12:02:28 -08:00 @@ -663,6 +663,7 @@ return; err_out: + ata_qc_free(qc); ata_bad_cdb(cmd, done); DPRINTK("EXIT - badcmd\n"); } diff -Nru a/drivers/scsi/libata.h b/drivers/scsi/libata.h --- a/drivers/scsi/libata.h 2005-03-04 12:02:28 -08:00 +++ b/drivers/scsi/libata.h 2005-03-04 12:02:28 -08:00 @@ -37,6 +37,7 @@ /* libata-core.c */ extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, struct ata_device *dev); +extern void ata_qc_free(struct ata_queued_cmd *qc); extern int ata_qc_issue(struct ata_queued_cmd *qc); extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); extern void ata_dev_select(struct ata_port *ap, unsigned int device, - To unsubscribe from this list: send the line "unsubscribe bk-commits-24" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html