FAILED: patch "[PATCH] scsi: sd: sd_zbc: Fix handling of host-aware ZBC disks" failed to apply to 5.8-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.8-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 27ba3e8ff3ab86449e63d38a8d623053591e65fa Mon Sep 17 00:00:00 2001
From: Damien Le Moal <[email protected]>
Date: Tue, 15 Sep 2020 16:33:46 +0900
Subject: [PATCH] scsi: sd: sd_zbc: Fix handling of host-aware ZBC disks
When CONFIG_BLK_DEV_ZONED is disabled, allow using host-aware ZBC disks as regular disks. In this case, ensure that command completion is correctly executed by changing sd_zbc_complete() to return good_bytes instead of 0 and causing a hang during device probe (endless retries).
When CONFIG_BLK_DEV_ZONED is enabled and a host-aware disk is detected to have partitions, it will be used as a regular disk. In this case, make sure to not do anything in sd_zbc_revalidate_zones() as that triggers warnings.
Since all these different cases result in subtle settings of the disk queue zoned model, introduce the block layer helper function blk_queue_set_zoned() to generically implement setting up the effective zoned model according to the disk type, the presence of partitions on the disk and CONFIG_BLK_DEV_ZONED configuration.
block/blk-settings.c +46 -0
@@ -801,6 +801,52 @@ bool blk_queue_can_use_dma_map_merging(struct request_queue *q, }EXPORT_SYMBOL_GPL (blk_queue_can_use_dma_map_merging); +/** +* blk_queue_set_zoned - configure a disk queue zoned model. +* @disk: the gendisk of the queue to configure +* @model: the zoned model to set +* +* Set the zoned model of the request queue of @disk according to @model. +* When @model is BLK_ZONED_HM (host managed), this should be called only +* if zoned block device support is enabled (CONFIG_BLK_DEV_ZONED option). +* If @model specifies BLK_ZONED_HA (host aware), the effective model used +* depends on CONFIG_BLK_DEV_ZONED settings and on the existence of partitions +* on the disk. +*/ +void blk_queue_set_zoned (struct gendisk *disk,enum blk_zoned_model model) +{ +switch (model) { +case BLK_ZONED_HM : +/* +* Host managed devices are supported only if +* CONFIG_BLK_DEV_ZONED is enabled. +*/ +WARN_ON_ONCE (!IS_ENABLED (CONFIG_BLK_DEV_ZONED )); +break ; +case BLK_ZONED_HA : +/* +* Host aware devices can be treated either as regular block +* devices (similar to drive managed devices) or as zoned block +* devices to take advantage of the zone command set, similarly +* to host managed devices. We try the latter if there are no +* partitions and zoned block device support is enabled, else +* we do nothing special as far as the block layer is concerned. +*/ +if (!IS_ENABLED (CONFIG_BLK_DEV_ZONED ) || +disk_has_partitions (disk)) + model =BLK_ZONED_NONE ; +break ; +case BLK_ZONED_NONE : +default : +if (WARN_ON_ONCE (model !=BLK_ZONED_NONE )) + model =BLK_ZONED_NONE ; +break ; + } + + disk->queue->limits.zoned = model; +} +EXPORT_SYMBOL_GPL (blk_queue_set_zoned); +static int __init blk_settings_init (void ) { blk_max_low_pfn = max_low_pfn -1 ;
drivers/scsi/sd.c +18 -12
@@ -2964,26 +2964,32 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)if (sdkp->device->type ==TYPE_ZBC ) {/* Host-managed */ - q->limits.zoned =BLK_ZONED_HM ; +blk_queue_set_zoned (sdkp->disk,BLK_ZONED_HM ); }else { sdkp->zoned = (buffer[8 ] >>4 ) &3 ; -if (sdkp->zoned ==1 && !disk_has_partitions (sdkp->disk)) { +if (sdkp->zoned ==1 ) {/* Host-aware */ - q->limits.zoned =BLK_ZONED_HA ; +blk_queue_set_zoned (sdkp->disk,BLK_ZONED_HA ); }else { -/* -* Treat drive-managed devices and host-aware devices -* with partitions as regular block devices. -*/ - q->limits.zoned =BLK_ZONED_NONE ; -if (sdkp->zoned ==2 && sdkp->first_scan) -sd_printk (KERN_NOTICE , sdkp, -"Drive-managed SMR disk\n" ); +/* Regular disk or drive managed disk */ +blk_queue_set_zoned (sdkp->disk,BLK_ZONED_NONE ); } } -if (blk_queue_is_zoned (q) && sdkp->first_scan) + +if (!sdkp->first_scan) + goto out; + +if (blk_queue_is_zoned (q)) {sd_printk (KERN_NOTICE , sdkp,"Host-%s zoned block device\n" , q->limits.zoned ==BLK_ZONED_HM ?"managed" :"aware" ); + }else { +if (sdkp->zoned ==1 ) +sd_printk (KERN_NOTICE , sdkp, +"Host-aware SMR disk used as regular disk\n" ); +else if (sdkp->zoned ==2 ) +sd_printk (KERN_NOTICE , sdkp, +"Drive-managed SMR disk\n" ); + } out:kfree (buffer);
drivers/scsi/sd.h +1 -1
@@ -259,7 +259,7 @@ static inline blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd,static inline unsigned int sd_zbc_complete (struct scsi_cmnd *cmd,unsigned int good_bytes,struct scsi_sense_hdr *sshdr) { -return 0 ; +return good_bytes; } static inline blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd,
drivers/scsi/sd_zbc.c +5 -1
@@ -667,7 +667,11 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)u32 max_append;int ret =0 ; -if (!sd_is_zoned (sdkp)) +/* +* There is nothing to do for regular disks, including host-aware disks +* that have partitions. +*/ +if (!blk_queue_is_zoned (q))return 0 ;/*
include/linux/blkdev.h +2 -0
@@ -352,6 +352,8 @@ struct queue_limits {typedef int (*report_zones_cb )(struct blk_zone *zone,unsigned int idx,void *data); +void blk_queue_set_zoned (struct gendisk *disk,enum blk_zoned_model model); +#ifdef CONFIG_BLK_DEV_ZONED #define BLK_ALL_ZONES ((unsigned int)-1)
PATCH 1/2 scsi: sd: sd_zbc: Fix handling of host-aware ZBC disks
Upstream commit 27ba3e8ff3ab86449e63d38a8d623053591e65fa
When CONFIG_BLK_DEV_ZONED is disabled, allow using host-aware ZBC disks as regular disks. In this case, ensure that command completion is correctly executed by changing sd_zbc_complete() to return good_bytes instead of 0 and causing a hang during device probe (endless retries).
When CONFIG_BLK_DEV_ZONED is enabled and a host-aware disk is detected to have partitions, it will be used as a regular disk. In this case, make sure to not do anything in sd_zbc_revalidate_zones() as that triggers warnings.
Since all these different cases result in subtle settings of the disk queue zoned model, introduce the block layer helper function blk_queue_set_zoned() to generically implement setting up the effective zoned model according to the disk type, the presence of partitions on the disk and CONFIG_BLK_DEV_ZONED configuration.
--- block/blk-settings.c | 46 ++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/sd.c | 30 ++++++++++++++++----------- drivers/scsi/sd.h | 2 +- drivers/scsi/sd_zbc.c | 37 +++++++++++++++++++-------------- include/linux/blkdev.h | 2 ++ 5 files changed, 89 insertions(+), 28 deletions(-)
block/blk-settings.c +46 -0
@@ -832,6 +832,52 @@ bool blk_queue_can_use_dma_map_merging(struct request_queue *q, }EXPORT_SYMBOL_GPL (blk_queue_can_use_dma_map_merging); +/** +* blk_queue_set_zoned - configure a disk queue zoned model. +* @disk: the gendisk of the queue to configure +* @model: the zoned model to set +* +* Set the zoned model of the request queue of @disk according to @model. +* When @model is BLK_ZONED_HM (host managed), this should be called only +* if zoned block device support is enabled (CONFIG_BLK_DEV_ZONED option). +* If @model specifies BLK_ZONED_HA (host aware), the effective model used +* depends on CONFIG_BLK_DEV_ZONED settings and on the existence of partitions +* on the disk. +*/ +void blk_queue_set_zoned (struct gendisk *disk,enum blk_zoned_model model) +{ +switch (model) { +case BLK_ZONED_HM : +/* +* Host managed devices are supported only if +* CONFIG_BLK_DEV_ZONED is enabled. +*/ +WARN_ON_ONCE (!IS_ENABLED (CONFIG_BLK_DEV_ZONED )); +break ; +case BLK_ZONED_HA : +/* +* Host aware devices can be treated either as regular block +* devices (similar to drive managed devices) or as zoned block +* devices to take advantage of the zone command set, similarly +* to host managed devices. We try the latter if there are no +* partitions and zoned block device support is enabled, else +* we do nothing special as far as the block layer is concerned. +*/ +if (!IS_ENABLED (CONFIG_BLK_DEV_ZONED ) || +disk_has_partitions (disk)) + model =BLK_ZONED_NONE ; +break ; +case BLK_ZONED_NONE : +default : +if (WARN_ON_ONCE (model !=BLK_ZONED_NONE )) + model =BLK_ZONED_NONE ; +break ; + } + + disk->queue->limits.zoned = model; +} +EXPORT_SYMBOL_GPL (blk_queue_set_zoned); +static int __init blk_settings_init (void ) { blk_max_low_pfn = max_low_pfn -1 ;
drivers/scsi/sd.c +18 -12
@@ -2966,26 +2966,32 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)if (sdkp->device->type ==TYPE_ZBC ) {/* Host-managed */ - q->limits.zoned =BLK_ZONED_HM ; +blk_queue_set_zoned (sdkp->disk,BLK_ZONED_HM ); }else { sdkp->zoned = (buffer[8 ] >>4 ) &3 ; -if (sdkp->zoned ==1 && !disk_has_partitions (sdkp->disk)) { +if (sdkp->zoned ==1 ) {/* Host-aware */ - q->limits.zoned =BLK_ZONED_HA ; +blk_queue_set_zoned (sdkp->disk,BLK_ZONED_HA ); }else { -/* -* Treat drive-managed devices and host-aware devices -* with partitions as regular block devices. -*/ - q->limits.zoned =BLK_ZONED_NONE ; -if (sdkp->zoned ==2 && sdkp->first_scan) -sd_printk (KERN_NOTICE , sdkp, -"Drive-managed SMR disk\n" ); +/* Regular disk or drive managed disk */ +blk_queue_set_zoned (sdkp->disk,BLK_ZONED_NONE ); } } -if (blk_queue_is_zoned (q) && sdkp->first_scan) + +if (!sdkp->first_scan) + goto out; + +if (blk_queue_is_zoned (q)) {sd_printk (KERN_NOTICE , sdkp,"Host-%s zoned block device\n" , q->limits.zoned ==BLK_ZONED_HM ?"managed" :"aware" ); + }else { +if (sdkp->zoned ==1 ) +sd_printk (KERN_NOTICE , sdkp, +"Host-aware SMR disk used as regular disk\n" ); +else if (sdkp->zoned ==2 ) +sd_printk (KERN_NOTICE , sdkp, +"Drive-managed SMR disk\n" ); + } out:kfree (buffer);
drivers/scsi/sd.h +1 -1
@@ -260,7 +260,7 @@ static inline blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd,static inline unsigned int sd_zbc_complete (struct scsi_cmnd *cmd,unsigned int good_bytes,struct scsi_sense_hdr *sshdr) { -return 0 ; +return good_bytes; } static inline blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd,
drivers/scsi/sd_zbc.c +22 -15
@@ -645,8 +645,17 @@ static int sd_zbc_revalidate_zones(struct scsi_disk *sdkp, unsigned int nr_zones) {struct gendisk *disk = sdkp->disk; +struct request_queue *q = disk->queue; +u32 max_append;int ret =0 ; +/* +* There is nothing to do for regular disks, including host-aware disks +* that have partitions. +*/ +if (!blk_queue_is_zoned (q)) +return 0 ; +/* * Make sure revalidate zones are serialized to ensure exclusive * updates of the scsi disk data.
@@ -681,6 +690,19 @@ static int sd_zbc_revalidate_zones(struct scsi_disk *sdkp,kvfree (sdkp->rev_wp_offset); sdkp->rev_wp_offset =NULL ; +if (ret) { + sdkp->zone_blocks =0 ; + sdkp->nr_zones =0 ; + sdkp->capacity =0 ; + goto unlock; + } + + max_append =min_t (u32,logical_to_sectors (sdkp->device, zone_blocks), + q->limits.max_segments << (PAGE_SHIFT -9 )); + max_append =min_t (u32, max_append,queue_max_hw_sectors (q)); + +blk_queue_max_zone_append_sectors (q, max_append); + unlock:mutex_unlock (&sdkp->rev_mutex);
@@ -693,7 +715,6 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)struct request_queue *q = disk->queue;unsigned int nr_zones;u32 zone_blocks =0 ; -u32 max_append;int ret;if (!sd_is_zoned (sdkp))
@@ -726,20 +747,6 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)if (ret) goto err; -/* -* On the first scan 'chunk_sectors' isn't setup yet, so calling -* blk_queue_max_zone_append_sectors() will result in a WARN(). Defer -* this setting to the second scan. -*/ -if (sdkp->first_scan) -return 0 ; - - max_append =min_t (u32,logical_to_sectors (sdkp->device, zone_blocks), - q->limits.max_segments << (PAGE_SHIFT -9 )); - max_append =min_t (u32, max_append,queue_max_hw_sectors (q)); - -blk_queue_max_zone_append_sectors (q, max_append); -return 0 ; err:
include/linux/blkdev.h +2 -0
@@ -354,6 +354,8 @@ struct queue_limits {typedef int (*report_zones_cb )(struct blk_zone *zone,unsigned int idx,void *data); +void blk_queue_set_zoned (struct gendisk *disk,enum blk_zoned_model model); +#ifdef CONFIG_BLK_DEV_ZONED #define BLK_ALL_ZONES ((unsigned int)-1)
Signature · 1 line
2.26.2
Greg Kroah-Hartman
maintainerRe: [PATCH 1/2] scsi: sd: sd_zbc: Fix handling of host-aware ZBC disks
Quoted 26 lines · Damien Le Moal
Upstream commit
27ba3e8ff3ab86449e63d38a8d623053591e65faWhen
CONFIG_BLK_DEV_ZONEDis disabled, allow using host-aware ZBC disks as regular disks. In this case, ensure that command completion is correctly executed by changingsd_zbc_complete()to returngood_bytesinstead of 0 and causing a hang during device probe (endless retries).When
CONFIG_BLK_DEV_ZONEDis enabled and a host-aware disk is detected to have partitions, it will be used as a regular disk. In this case, make sure to not do anything insd_zbc_revalidate_zones()as that triggers warnings.Since all these different cases result in subtle settings of the disk queue zoned model, introduce the block layer helper function
blk_queue_set_zoned()to generically implement setting up the effective zoned model according to the disk type, the presence of partitions on the disk andCONFIG_BLK_DEV_ZONEDconfiguration.Fixes b72053072c0b ("block: allow partitions on host aware zone devices")Cc <[email protected]>Reported-by Borislav Petkov <[email protected]>Suggested-by Christoph Hellwig <[email protected]>Reviewed-by Christoph Hellwig <[email protected]>Reviewed-by Johannes Thumshirn <[email protected]>Signed-off-by Damien Le Moal <[email protected]>Signed-off-by Martin K. Petersen <[email protected]>
Quoted 7 lines
--- block/blk-settings.c | 46 ++++++++++++++++++++++++++++++++++++++++++ drivers/scsi/sd.c | 30 ++++++++++++++++----------- drivers/scsi/sd.h | 2 +- drivers/scsi/sd_zbc.c | 37 +++++++++++++++++++-------------- include/linux/blkdev.h | 2 ++ 5 files changed, 89 insertions(+), 28 deletions(-)
THanks for both of these, now queued up.
greg k-h