ANDROID: scsi: scsi_debug: Support npo2 zone sizes

Remove the restriction that the zone size must be a power of two.

Bug: 269471019
Bug: 415836627
Change-Id: I7bd9c8f19ec601b82e0e1c271c3e362ddaf9a0ed
Signed-off-by: Bart Van Assche <bvanassche@google.com>
This commit is contained in:
Bart Van Assche
2025-04-08 14:23:02 -07:00
parent 497ca126dd
commit e395d18c8b

View File

@@ -352,7 +352,6 @@ struct sdebug_dev_info {
bool zoned;
unsigned int zcap;
unsigned int zsize;
unsigned int zsize_shift;
unsigned int nr_zones;
unsigned int nr_conv_zones;
unsigned int nr_seq_zones;
@@ -3146,7 +3145,7 @@ static inline bool sdebug_dev_is_zoned(struct sdebug_dev_info *devip)
static struct sdeb_zone_state *zbc_zone(struct sdebug_dev_info *devip,
unsigned long long lba)
{
u32 zno = lba >> devip->zsize_shift;
u32 zno = div_u64(lba, devip->zsize);
struct sdeb_zone_state *zsp;
if (devip->zcap == devip->zsize || zno < devip->nr_conv_zones)
@@ -5695,6 +5694,14 @@ static void sdebug_q_cmd_wq_complete(struct work_struct *work)
static bool got_shared_uuid;
static uuid_t shared_uuid;
static bool sdebug_is_zone_start(struct sdebug_dev_info *devip, u64 zstart)
{
u32 remainder;
div_u64_rem(zstart, devip->zsize, &remainder);
return remainder == 0;
}
static int sdebug_device_create_zones(struct sdebug_dev_info *devip)
{
struct sdeb_zone_state *zsp;
@@ -5719,10 +5726,6 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip)
return -EINVAL;
}
} else {
if (!is_power_of_2(sdeb_zbc_zone_size_mb)) {
pr_err("Zone size is not a power of 2\n");
return -EINVAL;
}
devip->zsize = (sdeb_zbc_zone_size_mb * SZ_1M)
>> ilog2(sdebug_sector_size);
if (devip->zsize >= capacity) {
@@ -5731,8 +5734,7 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip)
}
}
devip->zsize_shift = ilog2(devip->zsize);
devip->nr_zones = (capacity + devip->zsize - 1) >> devip->zsize_shift;
devip->nr_zones = div_u64(capacity + devip->zsize - 1, devip->zsize);
if (sdeb_zbc_zone_cap_mb == 0) {
devip->zcap = devip->zsize;
@@ -5745,14 +5747,14 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip)
}
}
conv_capacity = (sector_t)sdeb_zbc_nr_conv << devip->zsize_shift;
conv_capacity = (sector_t)sdeb_zbc_nr_conv * devip->zsize;
if (conv_capacity >= capacity) {
pr_err("Number of conventional zones too large\n");
return -EINVAL;
}
devip->nr_conv_zones = sdeb_zbc_nr_conv;
devip->nr_seq_zones = ALIGN(capacity - conv_capacity, devip->zsize) >>
devip->zsize_shift;
devip->nr_seq_zones = div_u64(capacity - conv_capacity +
devip->zsize - 1, devip->zsize);
devip->nr_zones = devip->nr_conv_zones + devip->nr_seq_zones;
/* Add gap zones if zone capacity is smaller than the zone size */
@@ -5783,7 +5785,7 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip)
zsp->z_wp = (sector_t)-1;
zsp->z_size =
min_t(u64, devip->zsize, capacity - zstart);
} else if ((zstart & (devip->zsize - 1)) == 0) {
} else if (sdebug_is_zone_start(devip, zstart)) {
if (devip->zoned)
zsp->z_type = ZBC_ZTYPE_SWR;
else