Tejun,
These two patches fix problems with the checks of the ZBC_OUT command fields prior to its translation to ZAC MANAGEMENT OUT.
The first patch fixes an incorrect out-of-range check and changes the returned asc/ascq to the ZBC defined INVALID FIELD IN CDB instead of (the more natural but incorrect) LBA OUT OF RANGE.
The second patch disables the ZBC_OUT command block address check if the ALL bit is set, as defined by the ZBC specifications.
Thank you for considering these patches for inclusion in 4.18 fixes (and CC stable).
Damien Le Moal (2): ata: Fix ZBC_OUT command block check ata: Fix ZBC_OUT all bit handling
drivers/ata/libata-scsi.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
The block (LBA) specified must not exceed the last addressable LBA, which is dev->nr_sectors - 1. So fix the correct check is "if (block >= dev->n_sectors)" and not "if (block > dev->n_sectords)".
Additionally, the asc/ascq to return for an LBA that is not a zone start LBA should be ILLEGAL REQUEST, regardless if the bad LBA is out of range.
Reported-by: David Butterfield david.butterfield@wdc.com Signed-off-by: Damien Le Moal damien.lemoal@wdc.com --- drivers/ata/libata-scsi.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 6a91d04351d9..a5543751f446 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3805,8 +3805,13 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) */ goto invalid_param_len; } - if (block > dev->n_sectors) - goto out_of_range; + if (block >= dev->n_sectors) { + /* + * Block must be a valid zone ID (a zone start LBA). + */ + fp = 2; + goto invalid_fld; + }
all = cdb[14] & 0x1;
@@ -3837,10 +3842,6 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) invalid_fld: ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); return 1; - out_of_range: - /* "Logical Block Address out of range" */ - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x00); - return 1; invalid_param_len: /* "Parameter list length error" */ ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0);
On Tue, Jun 26, 2018 at 04:18:37PM +0900, Damien Le Moal wrote:
The block (LBA) specified must not exceed the last addressable LBA, which is dev->nr_sectors - 1. So fix the correct check is "if (block >= dev->n_sectors)" and not "if (block > dev->n_sectords)".
Additionally, the asc/ascq to return for an LBA that is not a zone start LBA should be ILLEGAL REQUEST, regardless if the bad LBA is out of range.
Reported-by: David Butterfield david.butterfield@wdc.com Signed-off-by: Damien Le Moal damien.lemoal@wdc.com
<formletter>
This is not the correct way to submit patches for inclusion in the stable kernel tree. Please read: https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html for how to do this properly.
</formletter>
If the ALL bit is set in the ZBC_OUT command, the command zone ID field (block) should be ignored.
Reported-by: David Butterfield david.butterfield@wdc.com Signed-off-by: Damien Le Moal damien.lemoal@wdc.com --- drivers/ata/libata-scsi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a5543751f446..aad1b01447de 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3805,7 +3805,14 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) */ goto invalid_param_len; } - if (block >= dev->n_sectors) { + + all = cdb[14] & 0x1; + if (all) { + /* + * Ignore the block address (zone ID) as defined by ZBC. + */ + block = 0; + } else if (block >= dev->n_sectors) { /* * Block must be a valid zone ID (a zone start LBA). */ @@ -3813,8 +3820,6 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) goto invalid_fld; }
- all = cdb[14] & 0x1; - if (ata_ncq_enabled(qc->dev) && ata_fpdma_zac_mgmt_out_supported(qc->dev)) { tf->protocol = ATA_PROT_NCQ_NODATA;
On Tue, Jun 26, 2018 at 04:18:38PM +0900, Damien Le Moal wrote:
If the ALL bit is set in the ZBC_OUT command, the command zone ID field (block) should be ignored.
Reported-by: David Butterfield david.butterfield@wdc.com Signed-off-by: Damien Le Moal damien.lemoal@wdc.com
drivers/ata/libata-scsi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
<formletter>
This is not the correct way to submit patches for inclusion in the stable kernel tree. Please read: https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html for how to do this properly.
</formletter>
linux-stable-mirror@lists.linaro.org