Skip to content

Commit 0f4498c

Browse files
committed
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
2 parents 7931c53 + 4edbe1d commit 0f4498c

File tree

6 files changed

+46
-13
lines changed

6 files changed

+46
-13
lines changed

drivers/md/dm-ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ static int list_devices(struct file *filp, struct dm_ioctl *param, size_t param_
529529
* Grab our output buffer.
530530
*/
531531
nl = orig_nl = get_result_buffer(param, param_size, &len);
532-
if (len < needed) {
532+
if (len < needed || len < sizeof(nl->dev)) {
533533
param->flags |= DM_BUFFER_FULL_FLAG;
534534
goto out;
535535
}

drivers/md/dm-table.c

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,13 @@ static int device_not_zoned_model(struct dm_target *ti, struct dm_dev *dev,
15941594
return blk_queue_zoned_model(q) != *zoned_model;
15951595
}
15961596

1597+
/*
1598+
* Check the device zoned model based on the target feature flag. If the target
1599+
* has the DM_TARGET_ZONED_HM feature flag set, host-managed zoned devices are
1600+
* also accepted but all devices must have the same zoned model. If the target
1601+
* has the DM_TARGET_MIXED_ZONED_MODEL feature set, the devices can have any
1602+
* zoned model with all zoned devices having the same zone size.
1603+
*/
15971604
static bool dm_table_supports_zoned_model(struct dm_table *t,
15981605
enum blk_zoned_model zoned_model)
15991606
{
@@ -1603,13 +1610,15 @@ static bool dm_table_supports_zoned_model(struct dm_table *t,
16031610
for (i = 0; i < dm_table_get_num_targets(t); i++) {
16041611
ti = dm_table_get_target(t, i);
16051612

1606-
if (zoned_model == BLK_ZONED_HM &&
1607-
!dm_target_supports_zoned_hm(ti->type))
1608-
return false;
1609-
1610-
if (!ti->type->iterate_devices ||
1611-
ti->type->iterate_devices(ti, device_not_zoned_model, &zoned_model))
1612-
return false;
1613+
if (dm_target_supports_zoned_hm(ti->type)) {
1614+
if (!ti->type->iterate_devices ||
1615+
ti->type->iterate_devices(ti, device_not_zoned_model,
1616+
&zoned_model))
1617+
return false;
1618+
} else if (!dm_target_supports_mixed_zoned_model(ti->type)) {
1619+
if (zoned_model == BLK_ZONED_HM)
1620+
return false;
1621+
}
16131622
}
16141623

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

1633+
if (!blk_queue_is_zoned(q))
1634+
return 0;
1635+
16241636
return blk_queue_zone_sectors(q) != *zone_sectors;
16251637
}
16261638

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

16441661
if (dm_table_any_dev_attr(table, device_not_matches_zone_sectors, &zone_sectors)) {
1645-
DMERR("%s: zone sectors is not consistent across all devices",
1662+
DMERR("%s: zone sectors is not consistent across all zoned devices",
16461663
dm_device_name(table->md));
16471664
return -EINVAL;
16481665
}

drivers/md/dm-verity-target.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#define DM_VERITY_OPT_IGN_ZEROES "ignore_zero_blocks"
3535
#define DM_VERITY_OPT_AT_MOST_ONCE "check_at_most_once"
3636

37-
#define DM_VERITY_OPTS_MAX (2 + DM_VERITY_OPTS_FEC + \
37+
#define DM_VERITY_OPTS_MAX (3 + DM_VERITY_OPTS_FEC + \
3838
DM_VERITY_ROOT_HASH_VERIFICATION_OPTS)
3939

4040
static unsigned dm_verity_prefetch_cluster = DM_VERITY_DEFAULT_PREFETCH_SIZE;

drivers/md/dm-zoned-target.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1143,7 +1143,7 @@ static int dmz_message(struct dm_target *ti, unsigned int argc, char **argv,
11431143
static struct target_type dmz_type = {
11441144
.name = "zoned",
11451145
.version = {2, 0, 0},
1146-
.features = DM_TARGET_SINGLETON | DM_TARGET_ZONED_HM,
1146+
.features = DM_TARGET_SINGLETON | DM_TARGET_MIXED_ZONED_MODEL,
11471147
.module = THIS_MODULE,
11481148
.ctr = dmz_ctr,
11491149
.dtr = dmz_dtr,

drivers/md/dm.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,10 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
20362036
if (size != dm_get_size(md))
20372037
memset(&md->geometry, 0, sizeof(md->geometry));
20382038

2039-
set_capacity_and_notify(md->disk, size);
2039+
if (!get_capacity(md->disk))
2040+
set_capacity(md->disk, size);
2041+
else
2042+
set_capacity_and_notify(md->disk, size);
20402043

20412044
dm_table_event_callback(t, event_callback, md);
20422045

include/linux/device-mapper.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,11 @@ struct target_type {
253253
#define dm_target_passes_integrity(type) ((type)->features & DM_TARGET_PASSES_INTEGRITY)
254254

255255
/*
256-
* Indicates that a target supports host-managed zoned block devices.
256+
* Indicates support for zoned block devices:
257+
* - DM_TARGET_ZONED_HM: the target also supports host-managed zoned
258+
* block devices but does not support combining different zoned models.
259+
* - DM_TARGET_MIXED_ZONED_MODEL: the target supports combining multiple
260+
* devices with different zoned models.
257261
*/
258262
#ifdef CONFIG_BLK_DEV_ZONED
259263
#define DM_TARGET_ZONED_HM 0x00000040
@@ -275,6 +279,15 @@ struct target_type {
275279
#define DM_TARGET_PASSES_CRYPTO 0x00000100
276280
#define dm_target_passes_crypto(type) ((type)->features & DM_TARGET_PASSES_CRYPTO)
277281

282+
#ifdef CONFIG_BLK_DEV_ZONED
283+
#define DM_TARGET_MIXED_ZONED_MODEL 0x00000200
284+
#define dm_target_supports_mixed_zoned_model(type) \
285+
((type)->features & DM_TARGET_MIXED_ZONED_MODEL)
286+
#else
287+
#define DM_TARGET_MIXED_ZONED_MODEL 0x00000000
288+
#define dm_target_supports_mixed_zoned_model(type) (false)
289+
#endif
290+
278291
struct dm_target {
279292
struct dm_table *table;
280293
struct target_type *type;

0 commit comments

Comments
 (0)