diff options
author | Damien Le Moal <damien.lemoal@wdc.com> | 2017-04-24 16:51:15 +0900 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-04-25 13:00:58 -0400 |
commit | 868ed5a5b73f7cc18432ffe6e8d8addd395e91a1 (patch) | |
tree | c0af5e998f376ef5d89efd8fccb2c159bab1ac1b /drivers/scsi/sd_zbc.c | |
parent | f70532406aa4193e484b1e3c4d7d613f39257a44 (diff) | |
download | lwn-868ed5a5b73f7cc18432ffe6e8d8addd395e91a1.tar.gz lwn-868ed5a5b73f7cc18432ffe6e8d8addd395e91a1.zip |
scsi: sd_zbc: Do not write lock zones for reset
Resetting a zone write pointer is equivalent to discarding sectors:
after a reset, the zone sectors will contain zeros (or the format
pattern). So there is no need for mutual exclusion between a zone reset
and write. Similarly to discard, make it the responsability of the user
to properly synchronize between reset and write (as is done now for
discard and write).
Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/sd_zbc.c')
-rw-r--r-- | drivers/scsi/sd_zbc.c | 42 |
1 files changed, 16 insertions, 26 deletions
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 29ba1d7e9b2e..fcf0fad72dd9 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -237,7 +237,6 @@ int sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd) struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); sector_t sector = blk_rq_pos(rq); sector_t block = sectors_to_logical(sdkp->device, sector); - unsigned int zno = block >> sdkp->zone_shift; if (!sd_is_zoned(sdkp)) /* Not a zoned device */ @@ -250,11 +249,6 @@ int sd_zbc_setup_reset_cmnd(struct scsi_cmnd *cmd) /* Unaligned request */ return BLKPREP_KILL; - /* Do not allow concurrent reset and writes */ - if (sdkp->zones_wlock && - test_and_set_bit(zno, sdkp->zones_wlock)) - return BLKPREP_DEFER; - cmd->cmd_len = 16; memset(cmd->cmnd, 0, cmd->cmd_len); cmd->cmnd[0] = ZBC_OUT; @@ -324,38 +318,34 @@ void sd_zbc_complete(struct scsi_cmnd *cmd, struct request *rq = cmd->request; switch (req_op(rq)) { + case REQ_OP_ZONE_RESET: + + if (result && + sshdr->sense_key == ILLEGAL_REQUEST && + sshdr->asc == 0x24) + /* + * INVALID FIELD IN CDB error: reset of a conventional + * zone was attempted. Nothing to worry about, so be + * quiet about the error. + */ + rq->rq_flags |= RQF_QUIET; + break; + case REQ_OP_WRITE: case REQ_OP_WRITE_SAME: - case REQ_OP_ZONE_RESET: /* Unlock the zone */ sd_zbc_write_unlock_zone(cmd); - if (!result || - sshdr->sense_key != ILLEGAL_REQUEST) - break; - - switch (sshdr->asc) { - case 0x24: - /* - * INVALID FIELD IN CDB error: For a zone reset, - * this means that a reset of a conventional - * zone was attempted. Nothing to worry about in - * this case, so be quiet about the error. - */ - if (req_op(rq) == REQ_OP_ZONE_RESET) - rq->rq_flags |= RQF_QUIET; - break; - case 0x21: + if (result && + sshdr->sense_key == ILLEGAL_REQUEST && + sshdr->asc == 0x21) /* * INVALID ADDRESS FOR WRITE error: It is unlikely that * retrying write requests failed with any kind of * alignement error will result in success. So don't. */ cmd->allowed = 0; - break; - } - break; case REQ_OP_ZONE_REPORT: |