Commit e6d5599d authored by John W. Linville's avatar John W. Linville Committed by Jeff Garzik

[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: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 999471bf
......@@ -2751,6 +2751,24 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
clear_bit(tag, &ap->qactive);
}
/**
* 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
......
......@@ -701,6 +701,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
return;
err_out:
ata_qc_free(qc);
ata_bad_cdb(cmd, done);
DPRINTK("EXIT - badcmd\n");
}
......
......@@ -37,6 +37,7 @@ struct ata_scsi_args {
/* 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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment