@@ -1619,13 +1619,20 @@ static bool dm_table_supports_zoned_model(struct dm_table *t,
return true;
}
-static int device_not_matches_zone_sectors(struct dm_target *ti, struct dm_dev *dev,
+/*
+ * Callback function to check for device zone sector across devices. If the
+ * DM_TARGET_EMULATED_ZONES target feature flag is not set, then the target
+ * should have the same zone sector as the underlying devices.
+ */
+static int check_valid_device_zone_sectors(struct dm_target *ti, struct dm_dev *dev,
sector_t start, sector_t len, void *data)
{
unsigned int *zone_sectors = data;
- if (!bdev_is_zoned(dev->bdev))
+ if (!bdev_is_zoned(dev->bdev) ||
+ dm_target_supports_emulated_zones(ti->type))
return 0;
+
return bdev_zone_sectors(dev->bdev) != *zone_sectors;
}
@@ -1650,7 +1657,7 @@ static int validate_hardware_zoned_model(struct dm_table *t,
if (!zone_sectors)
return -EINVAL;
- if (dm_table_any_dev_attr(t, device_not_matches_zone_sectors, &zone_sectors)) {
+ if (dm_table_any_dev_attr(t, check_valid_device_zone_sectors, &zone_sectors)) {
DMERR("%s: zone sectors is not consistent across all zoned devices",
dm_device_name(t->md));
return -EINVAL;
@@ -294,6 +294,15 @@ struct target_type {
#define dm_target_supports_mixed_zoned_model(type) (false)
#endif
+#ifdef CONFIG_BLK_DEV_ZONED
+#define DM_TARGET_EMULATED_ZONES 0x00000400
+#define dm_target_supports_emulated_zones(type) \
+ ((type)->features & DM_TARGET_EMULATED_ZONES)
+#else
+#define DM_TARGET_EMULATED_ZONES 0x00000000
+#define dm_target_supports_emulated_zones(type) (false)
+#endif
+
struct dm_target {
struct dm_table *table;
struct target_type *type;