Commit 108e36f0 authored by Damien Le Moal's avatar Damien Le Moal Committed by Martin K. Petersen
Browse files

scsi: scsi_debug: Disallow zone sizes that are not powers of 2

Allowing a non-power-of-2 zone size forces the use of direct division
operations of 64-bit sector values to obtain a zone number or number of
zones. Doing so without using do_div() leads to compilation errors on
32-bit architectures.

Devices with a zone size that is not a power of 2 do not exist today so
allowing their emulation is of limited interest as the sd driver will not
support them anyway. To fix this compilation error, instead of using
do_div() for sector values divisions, simply disallow zone size values that
are not a power of 2.

[mkp: commit desc]

Link: https://lore.kernel.org/r/20200507023526.221574-1-damien.lemoal@wdc.com


Fixes: 98e0a689 ("scsi: scsi_debug: Add zone_size_mb module parameter")
Fixes: f0d1cf93 ("scsi: scsi_debug: Add ZBC zone commands")
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Acked-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarDamien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 64e14ece
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -2657,13 +2657,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)
{
	unsigned int zno;

	if (devip->zsize_shift)
		zno = lba >> devip->zsize_shift;
	else
		zno = lba / devip->zsize;
	return &devip->zstate[zno];
	return &devip->zstate[lba >> devip->zsize_shift];
}

static inline bool zbc_zone_is_conv(struct sdeb_zone_state *zsp)
@@ -4306,7 +4300,7 @@ static int resp_report_zones(struct scsi_cmnd *scp,
		return check_condition_result;
	}

	max_zones = devip->nr_zones - zs_lba / devip->zsize;
	max_zones = devip->nr_zones - (zs_lba >> devip->zsize_shift);
	rep_max_zones = min((alloc_len - 64) >> ilog2(RZONES_DESC_HD),
			    max_zones);

@@ -4826,6 +4820,10 @@ 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) {
@@ -4834,7 +4832,6 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip)
		}
	}

	if (is_power_of_2(devip->zsize))
	devip->zsize_shift = ilog2(devip->zsize);
	devip->nr_zones = (capacity + devip->zsize - 1) >> devip->zsize_shift;