Re: [PATCH 3/6] block: Implement support for zoned block devices

2016-07-19 Thread Damien Le Moal


On 7/19/16 22:20, Hannes Reinecke wrote:

Implement a RB-Tree holding the zone information and
add support functions for maintaining the RB-Tree.

Signed-off-by: Hannes Reinecke 
---
 block/Kconfig  |  9 +++
 block/Makefile |  1 +
 block/blk-core.c   |  5 
 block/blk-zoned.c  | 70 ++
 include/linux/blkdev.h | 47 +
 5 files changed, 132 insertions(+)
 create mode 100644 block/blk-zoned.c


Reviewed-by: Damien Le Moal 
Tested-by: Damien Le Moal 

--
Damien Le Moal, Ph.D.
Sr. Manager, System Software Group, HGST Research,
HGST, a Western Digital brand
damien.lem...@hgst.com
(+81) 0466-98-3593 (ext. 513593)
1 kirihara-cho, Fujisawa,
Kanagawa, 252-0888 Japan
www.hgst.com
Western Digital Corporation (and its subsidiaries) E-mail Confidentiality Notice 
& Disclaimer:

This e-mail and any files transmitted with it may contain confidential or 
legally privileged information of WDC and/or its affiliates, and are intended 
solely for the use of the individual or entity to which they are addressed. If 
you are not the intended recipient, any disclosure, copying, distribution or 
any action taken or omitted to be taken in reliance on it, is prohibited. If 
you have received this e-mail in error, please notify the sender immediately 
and delete the e-mail in its entirety from your system.

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/6] block: Implement support for zoned block devices

2016-07-19 Thread Hannes Reinecke
Implement a RB-Tree holding the zone information and
add support functions for maintaining the RB-Tree.

Signed-off-by: Hannes Reinecke 
---
 block/Kconfig  |  9 +++
 block/Makefile |  1 +
 block/blk-core.c   |  5 
 block/blk-zoned.c  | 70 ++
 include/linux/blkdev.h | 47 +
 5 files changed, 132 insertions(+)
 create mode 100644 block/blk-zoned.c

diff --git a/block/Kconfig b/block/Kconfig
index 0363cd7..8162312 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -113,6 +113,15 @@ config BLK_DEV_THROTTLING
 
See Documentation/cgroups/blkio-controller.txt for more information.
 
+config BLK_DEV_ZONED
+   bool "Zoned block device support"
+   default n
+   ---help---
+   Block layer zoned block device support. This option enables
+   support for zoned block (ZAC/ZBC) devices.
+
+   Say yes here if you have a ZAC or ZBC storage device.
+
 config BLK_CMDLINE_PARSER
bool "Block device command line partition parser"
default n
diff --git a/block/Makefile b/block/Makefile
index 9eda232..bc9e62c 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_BLK_DEV_BSG) += bsg.o
 obj-$(CONFIG_BLK_DEV_BSGLIB)   += bsg-lib.o
 obj-$(CONFIG_BLK_CGROUP)   += blk-cgroup.o
 obj-$(CONFIG_BLK_DEV_THROTTLING)   += blk-throttle.o
+obj-$(CONFIG_BLK_DEV_ZONED)+= blk-zoned.o
 obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
 obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
 obj-$(CONFIG_IOSCHED_CFQ)  += cfq-iosched.o
diff --git a/block/blk-core.c b/block/blk-core.c
index 2475b1c7..e273194 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -588,6 +588,8 @@ void blk_cleanup_queue(struct request_queue *q)
blk_mq_free_queue(q);
percpu_ref_exit(&q->q_usage_counter);
 
+   blk_drop_zones(q);
+
spin_lock_irq(lock);
if (q->queue_lock != &q->__queue_lock)
q->queue_lock = &q->__queue_lock;
@@ -724,6 +726,9 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, 
int node_id)
 #ifdef CONFIG_BLK_CGROUP
INIT_LIST_HEAD(&q->blkg_list);
 #endif
+#ifdef CONFIG_BLK_DEV_ZONED
+   q->zones = RB_ROOT;
+#endif
INIT_DELAYED_WORK(&q->delay_work, blk_delay_work);
 
kobject_init(&q->kobj, &blk_queue_ktype);
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
new file mode 100644
index 000..975e863
--- /dev/null
+++ b/block/blk-zoned.c
@@ -0,0 +1,70 @@
+/*
+ * Zoned block device handling
+ *
+ * Copyright (c) 2015, Hannes Reinecke
+ * Copyright (c) 2015, SUSE Linux GmbH
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t lba)
+{
+   struct rb_root *root = &q->zones;
+   struct rb_node *node = root->rb_node;
+
+   while (node) {
+   struct blk_zone *zone = container_of(node, struct blk_zone,
+node);
+
+   if (lba < zone->start)
+   node = node->rb_left;
+   else if (lba >= zone->start + zone->len)
+   node = node->rb_right;
+   else
+   return zone;
+   }
+   return NULL;
+}
+EXPORT_SYMBOL_GPL(blk_lookup_zone);
+
+struct blk_zone *blk_insert_zone(struct request_queue *q, struct blk_zone 
*data)
+{
+   struct rb_root *root = &q->zones;
+   struct rb_node **new = &(root->rb_node), *parent = NULL;
+
+   /* Figure out where to put new node */
+   while (*new) {
+   struct blk_zone *this = container_of(*new, struct blk_zone,
+node);
+   parent = *new;
+   if (data->start + data->len <= this->start)
+   new = &((*new)->rb_left);
+   else if (data->start >= this->start + this->len)
+   new = &((*new)->rb_right);
+   else {
+   /* Return existing zone */
+   return this;
+   }
+   }
+   /* Add new node and rebalance tree. */
+   rb_link_node(&data->node, parent, new);
+   rb_insert_color(&data->node, root);
+
+   return NULL;
+}
+EXPORT_SYMBOL_GPL(blk_insert_zone);
+
+void blk_drop_zones(struct request_queue *q)
+{
+   struct rb_root *root = &q->zones;
+   struct blk_zone *zone, *next;
+
+   rbtree_postorder_for_each_entry_safe(zone, next, root, node) {
+   kfree(zone);
+   }
+   q->zones = RB_ROOT;
+}
+EXPORT_SYMBOL_GPL(blk_drop_zones);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 3d9cf32..d5e3d8b 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -249,6 +249,50 @@ struct blk_queue_tag {
 #define BLK_SCSI_MAX_CMDS  (256)
 #define BLK_SCSI_CMD_PER_LONG  (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
 
+#ifdef CONFIG_BLK_DE