Re: [PATCH 8/9] sd: Implement support for ZBC devices

2016-09-19 Thread Shaun Tancheff
On Mon, Sep 19, 2016 at 4:27 PM, Damien Le Moal  wrote:
> From: Hannes Reinecke 
>
> Implement ZBC support functions to setup zoned disks and fill the
> block device zone information tree during the device scan. The
> zone information tree is also always updated on disk revalidation.
> This adds support for the REQ_OP_ZONE* operations and also implements
> the new RESET_WP provisioning mode so that discard requests can be
> mapped to the RESET WRITE POINTER command for devices with a constant
> zone size.
>
> The capacity read of the device triggers the zone information read
> for zoned block devices. As this needs the device zone model, the
> the call to sd_read_capacity is moved after the call to
> sd_read_block_characteristics so that host-aware devices are
> properlly initialized. The call to sd_zbc_read_zones in
> sd_read_capacity may change the device capacity obtained with
> the sd_read_capacity_16 function for devices reporting only the
> capacity of conventional zones at the beginning of the LBA range
> (i.e. devices with rc_basis et to 0).
>
> Signed-off-by: Hannes Reinecke 
> Signed-off-by: Damien Le Moal 
> ---
>  drivers/scsi/Makefile |1 +
>  drivers/scsi/sd.c |  147 --
>  drivers/scsi/sd.h |   68 +++
>  drivers/scsi/sd_zbc.c | 1097 
> +
>  include/scsi/scsi_proto.h |   17 +
>  5 files changed, 1304 insertions(+), 26 deletions(-)
>  create mode 100644 drivers/scsi/sd_zbc.c
>
> diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
> index d539798..fabcb6d 100644
> --- a/drivers/scsi/Makefile
> +++ b/drivers/scsi/Makefile
> @@ -179,6 +179,7 @@ hv_storvsc-y:= storvsc_drv.o
>
>  sd_mod-objs:= sd.o
>  sd_mod-$(CONFIG_BLK_DEV_INTEGRITY) += sd_dif.o
> +sd_mod-$(CONFIG_BLK_DEV_ZONED) += sd_zbc.o
>
>  sr_mod-objs:= sr.o sr_ioctl.o sr_vendor.o
>  ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index d3e852a..46b8b78 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -92,6 +92,7 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);
>  MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK);
>  MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);
>  MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
> +MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC);
>
>  #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
>  #define SD_MINORS  16
> @@ -99,7 +100,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
>  #define SD_MINORS  0
>  #endif
>
> -static void sd_config_discard(struct scsi_disk *, unsigned int);
>  static void sd_config_write_same(struct scsi_disk *);
>  static int  sd_revalidate_disk(struct gendisk *);
>  static void sd_unlock_native_capacity(struct gendisk *disk);
> @@ -162,7 +162,7 @@ cache_type_store(struct device *dev, struct 
> device_attribute *attr,
> static const char temp[] = "temporary ";
> int len;
>
> -   if (sdp->type != TYPE_DISK)
> +   if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
> /* no cache control on RBC devices; theoretically they
>  * can do it, but there's probably so many exceptions
>  * it's not worth the risk */
> @@ -261,7 +261,7 @@ allow_restart_store(struct device *dev, struct 
> device_attribute *attr,
> if (!capable(CAP_SYS_ADMIN))
> return -EACCES;
>
> -   if (sdp->type != TYPE_DISK)
> +   if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
> return -EINVAL;
>
> sdp->allow_restart = simple_strtoul(buf, NULL, 10);
> @@ -369,6 +369,7 @@ static const char *lbp_mode[] = {
> [SD_LBP_WS16]   = "writesame_16",
> [SD_LBP_WS10]   = "writesame_10",
> [SD_LBP_ZERO]   = "writesame_zero",
> +   [SD_ZBC_RESET_WP]   = "reset_wp",
> [SD_LBP_DISABLE]= "disabled",
>  };
>
> @@ -391,6 +392,13 @@ provisioning_mode_store(struct device *dev, struct 
> device_attribute *attr,
> if (!capable(CAP_SYS_ADMIN))
> return -EACCES;
>
> +   if (sdkp->zoned == 1 || sdp->type == TYPE_ZBC) {
> +   if (!strncmp(buf, lbp_mode[SD_ZBC_RESET_WP], 20)) {
> +   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
> +   return count;
> +   }
> +   return -EINVAL;
> +   }
> if (sdp->type != TYPE_DISK)
> return -EINVAL;
>
> @@ -458,7 +466,7 @@ max_write_same_blocks_store(struct device *dev, struct 
> device_attribute *attr,
> if (!capable(CAP_SYS_ADMIN))
> return -EACCES;
>
> -   if (sdp->type != TYPE_DISK)
> +   if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
> return -EINVAL;
>
> err = kstrtoul(buf, 10, &max);
> @@ -631,7 +639,7 @@ static unsigned char sd_setup_protect_cmnd(struct 
> scsi_cmnd *scmd,
> return protect;
>  }
>
> -static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
> +void sd_config_discard(struct

[PATCH 8/9] sd: Implement support for ZBC devices

2016-09-19 Thread Damien Le Moal
From: Hannes Reinecke 

Implement ZBC support functions to setup zoned disks and fill the
block device zone information tree during the device scan. The
zone information tree is also always updated on disk revalidation.
This adds support for the REQ_OP_ZONE* operations and also implements
the new RESET_WP provisioning mode so that discard requests can be
mapped to the RESET WRITE POINTER command for devices with a constant
zone size.

The capacity read of the device triggers the zone information read
for zoned block devices. As this needs the device zone model, the
the call to sd_read_capacity is moved after the call to
sd_read_block_characteristics so that host-aware devices are
properlly initialized. The call to sd_zbc_read_zones in
sd_read_capacity may change the device capacity obtained with
the sd_read_capacity_16 function for devices reporting only the
capacity of conventional zones at the beginning of the LBA range
(i.e. devices with rc_basis et to 0).

Signed-off-by: Hannes Reinecke 
Signed-off-by: Damien Le Moal 
---
 drivers/scsi/Makefile |1 +
 drivers/scsi/sd.c |  147 --
 drivers/scsi/sd.h |   68 +++
 drivers/scsi/sd_zbc.c | 1097 +
 include/scsi/scsi_proto.h |   17 +
 5 files changed, 1304 insertions(+), 26 deletions(-)
 create mode 100644 drivers/scsi/sd_zbc.c

diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index d539798..fabcb6d 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -179,6 +179,7 @@ hv_storvsc-y:= storvsc_drv.o
 
 sd_mod-objs:= sd.o
 sd_mod-$(CONFIG_BLK_DEV_INTEGRITY) += sd_dif.o
+sd_mod-$(CONFIG_BLK_DEV_ZONED) += sd_zbc.o
 
 sr_mod-objs:= sr.o sr_ioctl.o sr_vendor.o
 ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d3e852a..46b8b78 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -92,6 +92,7 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD);
 MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
+MODULE_ALIAS_SCSI_DEVICE(TYPE_ZBC);
 
 #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
 #define SD_MINORS  16
@@ -99,7 +100,6 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
 #define SD_MINORS  0
 #endif
 
-static void sd_config_discard(struct scsi_disk *, unsigned int);
 static void sd_config_write_same(struct scsi_disk *);
 static int  sd_revalidate_disk(struct gendisk *);
 static void sd_unlock_native_capacity(struct gendisk *disk);
@@ -162,7 +162,7 @@ cache_type_store(struct device *dev, struct 
device_attribute *attr,
static const char temp[] = "temporary ";
int len;
 
-   if (sdp->type != TYPE_DISK)
+   if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
/* no cache control on RBC devices; theoretically they
 * can do it, but there's probably so many exceptions
 * it's not worth the risk */
@@ -261,7 +261,7 @@ allow_restart_store(struct device *dev, struct 
device_attribute *attr,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   if (sdp->type != TYPE_DISK)
+   if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
return -EINVAL;
 
sdp->allow_restart = simple_strtoul(buf, NULL, 10);
@@ -369,6 +369,7 @@ static const char *lbp_mode[] = {
[SD_LBP_WS16]   = "writesame_16",
[SD_LBP_WS10]   = "writesame_10",
[SD_LBP_ZERO]   = "writesame_zero",
+   [SD_ZBC_RESET_WP]   = "reset_wp",
[SD_LBP_DISABLE]= "disabled",
 };
 
@@ -391,6 +392,13 @@ provisioning_mode_store(struct device *dev, struct 
device_attribute *attr,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
+   if (sdkp->zoned == 1 || sdp->type == TYPE_ZBC) {
+   if (!strncmp(buf, lbp_mode[SD_ZBC_RESET_WP], 20)) {
+   sd_config_discard(sdkp, SD_ZBC_RESET_WP);
+   return count;
+   }
+   return -EINVAL;
+   }
if (sdp->type != TYPE_DISK)
return -EINVAL;
 
@@ -458,7 +466,7 @@ max_write_same_blocks_store(struct device *dev, struct 
device_attribute *attr,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
 
-   if (sdp->type != TYPE_DISK)
+   if (sdp->type != TYPE_DISK && sdp->type != TYPE_ZBC)
return -EINVAL;
 
err = kstrtoul(buf, 10, &max);
@@ -631,7 +639,7 @@ static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd 
*scmd,
return protect;
 }
 
-static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
+void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
 {
struct request_queue *q = sdkp->disk->queue;
unsigned int logical_block_size = sdkp->device->sector_size;
@@ -683,6 +691,11 @@ static void sd_config_discard(struct scsi_disk *sdkp, 
unsigned int mode)
q-