Commit 0f4498ce authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-5.12/dm-fixes-2' of...

Merge tag 'for-5.12/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mike Snitzer:

 - Fix DM verity target's optional argument processing.

 - Fix DM core's zoned model and zone sectors checks.

 - Fix spurious "detected capacity change" pr_info() when creating new
   DM device.

 - Fix DM ioctl out of bounds array access in handling of
   DM_LIST_DEVICES_CMD when no devices exist.

* tag 'for-5.12/dm-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
  dm ioctl: fix out of bounds array access when no devices
  dm: don't report "detected capacity change" on device creation
  dm table: Fix zoned model check and zone sectors check
  dm verity: fix DM_VERITY_OPTS_MAX value
parents 7931c531 4edbe1d7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -529,7 +529,7 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_
	 * Grab our output buffer.
	 */
	nl = orig_nl = get_result_buffer(param, param_size, &len);
	if (len < needed) {
	if (len < needed || len < sizeof(nl->dev)) {
		param->flags |= DM_BUFFER_FULL_FLAG;
		goto out;
	}
+25 −8
Original line number Diff line number Diff line
@@ -1594,6 +1594,13 @@ static int device_not_zoned_model(struct dm_target *ti, struct dm_dev *dev,
	return blk_queue_zoned_model(q) != *zoned_model;
}

/*
 * Check the device zoned model based on the target feature flag. If the target
 * has the DM_TARGET_ZONED_HM feature flag set, host-managed zoned devices are
 * also accepted but all devices must have the same zoned model. If the target
 * has the DM_TARGET_MIXED_ZONED_MODEL feature set, the devices can have any
 * zoned model with all zoned devices having the same zone size.
 */
static bool dm_table_supports_zoned_model(struct dm_table *t,
					  enum blk_zoned_model zoned_model)
{
@@ -1603,14 +1610,16 @@ static bool dm_table_supports_zoned_model(struct dm_table *t,
	for (i = 0; i < dm_table_get_num_targets(t); i++) {
		ti = dm_table_get_target(t, i);

		if (zoned_model == BLK_ZONED_HM &&
		    !dm_target_supports_zoned_hm(ti->type))
			return false;

		if (dm_target_supports_zoned_hm(ti->type)) {
			if (!ti->type->iterate_devices ||
		    ti->type->iterate_devices(ti, device_not_zoned_model, &zoned_model))
			    ti->type->iterate_devices(ti, device_not_zoned_model,
						      &zoned_model))
				return false;
		} else if (!dm_target_supports_mixed_zoned_model(ti->type)) {
			if (zoned_model == BLK_ZONED_HM)
				return false;
		}
	}

	return true;
}
@@ -1621,9 +1630,17 @@ static int device_not_matches_zone_sectors(struct dm_target *ti, struct dm_dev *
	struct request_queue *q = bdev_get_queue(dev->bdev);
	unsigned int *zone_sectors = data;

	if (!blk_queue_is_zoned(q))
		return 0;

	return blk_queue_zone_sectors(q) != *zone_sectors;
}

/*
 * Check consistency of zoned model and zone sectors across all targets. For
 * zone sectors, if the destination device is a zoned block device, it shall
 * have the specified zone_sectors.
 */
static int validate_hardware_zoned_model(struct dm_table *table,
					 enum blk_zoned_model zoned_model,
					 unsigned int zone_sectors)
@@ -1642,7 +1659,7 @@ static int validate_hardware_zoned_model(struct dm_table *table,
		return -EINVAL;

	if (dm_table_any_dev_attr(table, device_not_matches_zone_sectors, &zone_sectors)) {
		DMERR("%s: zone sectors is not consistent across all devices",
		DMERR("%s: zone sectors is not consistent across all zoned devices",
		      dm_device_name(table->md));
		return -EINVAL;
	}
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
#define DM_VERITY_OPT_IGN_ZEROES	"ignore_zero_blocks"
#define DM_VERITY_OPT_AT_MOST_ONCE	"check_at_most_once"

#define DM_VERITY_OPTS_MAX		(2 + DM_VERITY_OPTS_FEC + \
#define DM_VERITY_OPTS_MAX		(3 + DM_VERITY_OPTS_FEC + \
					 DM_VERITY_ROOT_HASH_VERIFICATION_OPTS)

static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE;
+1 −1
Original line number Diff line number Diff line
@@ -1143,7 +1143,7 @@ static int dmz_message(struct dm_target *ti, unsigned int argc, char **argv,
static struct target_type dmz_type = {
	.name		 = "zoned",
	.version	 = {2, 0, 0},
	.features	 = DM_TARGET_SINGLETON | DM_TARGET_ZONED_HM,
	.features	 = DM_TARGET_SINGLETON | DM_TARGET_MIXED_ZONED_MODEL,
	.module		 = THIS_MODULE,
	.ctr		 = dmz_ctr,
	.dtr		 = dmz_dtr,
+4 −1
Original line number Diff line number Diff line
@@ -2036,6 +2036,9 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
	if (size != dm_get_size(md))
		memset(&md->geometry, 0, sizeof(md->geometry));

	if (!get_capacity(md->disk))
		set_capacity(md->disk, size);
	else
		set_capacity_and_notify(md->disk, size);

	dm_table_event_callback(t, event_callback, md);
Loading