Skip to content

Commit 2d669ce

Browse files
kawasakisnitm
authored andcommitted
dm table: Fix zoned model check and zone sectors check
Commit 24f6b60 ("dm table: fix zoned iterate_devices based device capability checks") triggered dm table load failure when dm-zoned device is set up for zoned block devices and a regular device for cache. The commit inverted logic of two callback functions for iterate_devices: device_is_zoned_model() and device_matches_zone_sectors(). The logic of device_is_zoned_model() was inverted then all destination devices of all targets in dm table are required to have the expected zoned model. This is fine for dm-linear, dm-flakey and dm-crypt on zoned block devices since each target has only one destination device. However, this results in failure for dm-zoned with regular cache device since that target has both regular block device and zoned block devices. As for device_matches_zone_sectors(), the commit inverted the logic to require all zoned block devices in each target have the specified zone_sectors. This check also fails for regular block device which does not have zones. To avoid the check failures, fix the zone model check and the zone sectors check. For zone model check, introduce the new feature flag DM_TARGET_MIXED_ZONED_MODEL, and set it to dm-zoned target. When the target has this flag, allow it to have destination devices with any zoned model. For zone sectors check, skip the check if the destination device is not a zoned block device. Also add comments and improve an error message to clarify expectations to the two checks. Fixes: 24f6b60 ("dm table: fix zoned iterate_devices based device capability checks") Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
1 parent 160f99d commit 2d669ce

File tree

3 files changed

+40
-10
lines changed

3 files changed

+40
-10
lines changed

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-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,

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)