summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Le Moal <damien.lemoal@opensource.wdc.com>2022-06-08 04:13:02 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-06-29 09:59:46 +0300
commit10eb239e293516d99f7df050a1a0c8a9cf484070 (patch)
treece4baf3930935ec5091bcde455e26843922959ba
parent15cc30ac2a8d7185f8ebf97dd1ddd90a7c79783b (diff)
downloadlinux-10eb239e293516d99f7df050a1a0c8a9cf484070.tar.xz
scsi: scsi_debug: Fix zone transition to full condition
[ Upstream commit 566d3c57eb526f32951af15866086e236ce1fc8a ] When a write command to a sequential write required or sequential write preferred zone result in the zone write pointer reaching the end of the zone, the zone condition must be set to full AND the number of implicitly or explicitly open zones updated to have a correct accounting for zone resources. However, the function zbc_inc_wp() only sets the zone condition to full without updating the open zone counters, resulting in a zone state machine breakage. Introduce the helper function zbc_set_zone_full() and use it in zbc_inc_wp() to correctly transition zones to the full condition. Link: https://lore.kernel.org/r/20220608011302.92061-1-damien.lemoal@opensource.wdc.com Fixes: f0d1cf9378bd ("scsi: scsi_debug: Add ZBC zone commands") Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com> Acked-by: Douglas Gilbert <dgilbert@interlog.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/scsi/scsi_debug.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 6b00de6b6f0e..5eb959b5f701 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -2746,6 +2746,24 @@ static void zbc_open_zone(struct sdebug_dev_info *devip,
}
}
+static inline void zbc_set_zone_full(struct sdebug_dev_info *devip,
+ struct sdeb_zone_state *zsp)
+{
+ switch (zsp->z_cond) {
+ case ZC2_IMPLICIT_OPEN:
+ devip->nr_imp_open--;
+ break;
+ case ZC3_EXPLICIT_OPEN:
+ devip->nr_exp_open--;
+ break;
+ default:
+ WARN_ONCE(true, "Invalid zone %llu condition %x\n",
+ zsp->z_start, zsp->z_cond);
+ break;
+ }
+ zsp->z_cond = ZC5_FULL;
+}
+
static void zbc_inc_wp(struct sdebug_dev_info *devip,
unsigned long long lba, unsigned int num)
{
@@ -2758,7 +2776,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip,
if (zsp->z_type == ZBC_ZONE_TYPE_SWR) {
zsp->z_wp += num;
if (zsp->z_wp >= zend)
- zsp->z_cond = ZC5_FULL;
+ zbc_set_zone_full(devip, zsp);
return;
}
@@ -2777,7 +2795,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip,
n = num;
}
if (zsp->z_wp >= zend)
- zsp->z_cond = ZC5_FULL;
+ zbc_set_zone_full(devip, zsp);
num -= n;
lba += n;