When host-managed SMR disks have different physical sector size and logical sector size, writes to conventional zones should be aligned to the logical sector size. On the other hand, ZBC/ZAC requires that writes to sequential write required zones shall be aligned to the physical sector size. Otherwise, the disks return the unaligned write command error. However, this error is common with other failure reasons. The error is also reported when the write start sector is not at the write pointer, or the write end sector is not in the same zone. To clarify the write failure cause is the physical sector alignment, confirm before issuing write commands that the writes to sequential write required zones are aligned to the physical sector size. If not, print a relevant error message. This makes failure analysis easier, and also avoids error handling in low level drivers. Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx> --- drivers/scsi/sd.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 47dafe6b8a66..6d115b2fa99a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1123,6 +1123,7 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd) sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq)); sector_t threshold; unsigned int nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq)); + unsigned int pb_sectors = sdkp->physical_block_size >> SECTOR_SHIFT; unsigned int mask = logical_to_sectors(sdp, 1) - 1; bool write = rq_data_dir(rq) == WRITE; unsigned char protect, fua; @@ -1145,6 +1146,15 @@ static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd) goto fail; } + if (sdkp->device->type == TYPE_ZBC && blk_rq_zone_is_seq(rq) && + (req_op(rq) == REQ_OP_WRITE || req_op(rq) == REQ_OP_ZONE_APPEND) && + (!IS_ALIGNED(blk_rq_pos(rq), pb_sectors) || + !IS_ALIGNED(blk_rq_sectors(rq), pb_sectors))) { + scmd_printk(KERN_ERR, cmd, + "Sequential write request not aligned to the physical block size\n"); + goto fail; + } + if ((blk_rq_pos(rq) & mask) || (blk_rq_sectors(rq) & mask)) { scmd_printk(KERN_ERR, cmd, "request not aligned to the logical block size\n"); goto fail; -- 2.38.1