From: Damien Le Moal <damien.lem...@wdc.com>

The target drivers currently available will not operate correctly if a
table target maps onto a host-managed zoned block device.

To avoid problems, this patch introduces the new feature flag
DM_TARGET_ZONED_HM for a target driver to explicitly state that it
supports host-managed zoned block devices. This feature is checked
in dm_get_device() to prevent the addition to a table of a target
mapping to a host-managed zoned block device if the target type does
not have the feature enabled.

Note that as host-aware zoned block devices are backward compatible
with regular block devices, they can be used by any of the current
target types. This new feature is thus restricted to host-managed
zoned block devices.

Signed-off-by: Damien Le Moal <damien.lem...@wdc.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
Reviewed-by: Bart Van Assche <bart.vanass...@sandisk.com>
---
 drivers/md/dm-table.c         | 23 +++++++++++++++++++++++
 include/linux/device-mapper.h |  6 ++++++
 2 files changed, 29 insertions(+)

diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 5f5eae4..6a7e200 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -389,6 +389,24 @@ dev_t dm_get_dev_t(const char *path)
 EXPORT_SYMBOL_GPL(dm_get_dev_t);
 
 /*
+ * Check if the target supports supports host-managed zoned block devices.
+ */
+static bool device_supported(struct dm_target *ti, struct dm_dev *dev)
+{
+       struct block_device *bdev = dev->bdev;
+       char b[BDEVNAME_SIZE];
+
+       if (bdev_zoned_model(bdev) == BLK_ZONED_HM &&
+           !dm_target_zoned_hm(ti->type)) {
+               DMWARN("%s: Unsupported host-managed zoned block device %s",
+                      dm_device_name(ti->table->md), bdevname(bdev, b));
+               return false;
+       }
+
+       return true;
+}
+
+/*
  * Add a device to the list, or just increment the usage count if
  * it's already present.
  */
@@ -427,6 +445,11 @@ int dm_get_device(struct dm_target *ti, const char *path, 
fmode_t mode,
        }
        atomic_inc(&dd->count);
 
+       if (!device_supported(ti, dd->dm_dev)) {
+               dm_put_device(ti, dd->dm_dev);
+               return -ENOTSUPP;
+       }
+
        *result = dd->dm_dev;
        return 0;
 }
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index f4c639c..afd25af 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -218,6 +218,12 @@ struct target_type {
 #define dm_target_is_wildcard(type)    ((type)->features & DM_TARGET_WILDCARD)
 
 /*
+ * Indicates that a target supports host-managed zoned block devices.
+ */
+#define DM_TARGET_ZONED_HM             0x00000010
+#define dm_target_zoned_hm(type)       ((type)->features & DM_TARGET_ZONED_HM)
+
+/*
  * Some targets need to be sent the same WRITE bio severals times so
  * that they can send copies of it to different devices.  This function
  * examines any supplied bio and returns the number of copies of it the
-- 
2.9.3

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to