From 288b3271d920c9ba949c3bab0f749f4cecc70e09 Mon Sep 17 00:00:00 2001 From: Shin'ichiro Kawasaki Date: Mon, 6 Mar 2023 15:30:24 +0900 Subject: scsi: sd: Fix wrong zone_write_granularity value during revalidate When the sd driver revalidates host-managed SMR disks, it calls disk_set_zoned() which changes the zone_write_granularity attribute value to the logical block size regardless of the device type. After that, the sd driver overwrites the value in sd_zbc_read_zone() with the physical block size, since ZBC/ZAC requires this for host-managed disks. Between the calls to disk_set_zoned() and sd_zbc_read_zone(), there exists a window where the attribute shows the logical block size as the zone_write_granularity value, which is wrong for host-managed disks. The duration of the window is from 20ms to 200ms, depending on report zone command execution time. To avoid the wrong zone_write_granularity value between disk_set_zoned() and sd_zbc_read_zone(), modify the value not in sd_zbc_read_zone() but just after disk_set_zoned() call. Fixes: a805a4fa4fa3 ("block: introduce zone_write_granularity limit") Signed-off-by: Shin'ichiro Kawasaki Link: https://lore.kernel.org/r/20230306063024.3376959-1-shinichiro.kawasaki@wdc.com Reviewed-by: Damien Le Moal Reviewed-by: Johannes Thumshirn Reviewed-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 4f28dd617eca..4bb87043e6db 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2988,8 +2988,13 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp) } if (sdkp->device->type == TYPE_ZBC) { - /* Host-managed */ + /* + * Host-managed: Per ZBC and ZAC specifications, writes in + * sequential write required zones of host-managed devices must + * be aligned to the device physical block size. + */ disk_set_zoned(sdkp->disk, BLK_ZONED_HM); + blk_queue_zone_write_granularity(q, sdkp->physical_block_size); } else { sdkp->zoned = zoned; if (sdkp->zoned == 1) { -- cgit