]> git.baikalelectronics.ru Git - kernel.git/commitdiff
scsi: sd: Fix wrong zone_write_granularity value during revalidate
authorShin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Mon, 6 Mar 2023 06:30:24 +0000 (15:30 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 17 Mar 2023 07:50:27 +0000 (08:50 +0100)
[ Upstream commit c4780d9c54a391a8b6fe0474e81ed056871ed2ee ]

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: 172572cc4fbf ("block: introduce zone_write_granularity limit")
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Link: https://lore.kernel.org/r/20230306063024.3376959-1-shinichiro.kawasaki@wdc.com
Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/sd.c
drivers/scsi/sd_zbc.c

index eb76ba0550216d7d55d998e4609ed7ea5d4bdb9a..e934779bf05c8fb57fda6472852523e9e26ee685 100644 (file)
@@ -2933,8 +2933,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) {
index bd15624c63228010ffe68eadd7613a20a6c2287c..4c35b4a916355c06ea47f6f57fa776a3b7135bcb 100644 (file)
@@ -956,14 +956,6 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE])
        disk_set_max_active_zones(disk, 0);
        nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks);
 
-       /*
-        * Per ZBC and ZAC specifications, writes in sequential write required
-        * zones of host-managed devices must be aligned to the device physical
-        * block size.
-        */
-       if (blk_queue_zoned_model(q) == BLK_ZONED_HM)
-               blk_queue_zone_write_granularity(q, sdkp->physical_block_size);
-
        sdkp->early_zone_info.nr_zones = nr_zones;
        sdkp->early_zone_info.zone_blocks = zone_blocks;