[PATCH 5/5] nvme: enable generic interface (/dev/ngXnY) for unknown command sets

Sagi Grimberg sagi at grimberg.me
Wed Jul 13 02:25:38 PDT 2022



On 7/13/22 08:49, Christoph Hellwig wrote:
> From: Joel Granados <j.granados at samsung.com>
> 
> Extend nvme_alloc_ns() and nvme_validate_ns() for unknown command-set as
> well. Both are made to use a new helper (nvme_update_ns_info_cs_indep)
> which is similar to nvme_update_ns_info but performs fewer operations
> to get the generic interface up.
> 
> Suggested-by: Christoph Hellwig <hch at lst.de>
> Signed-off-by: Joel Granados <j.granados at samsung.com>
> Signed-off-by: Kanchan Joshi <joshi.k at samsung.com>
> [hch: rebased on other refactoring patches]
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---
>   drivers/nvme/host/core.c | 36 ++++++++++++++++++++++++++++++------
>   1 file changed, 30 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index dca7580f785a8..f865d0b185c32 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -1954,6 +1954,31 @@ static void nvme_set_chunk_sectors(struct nvme_ns *ns, struct nvme_id_ns *id)
>   	blk_queue_chunk_sectors(ns->queue, iob);
>   }
>   
> +static int nvme_update_ns_info_generic(struct nvme_ns *ns,
> +		struct nvme_ns_info *info)
> +{
> +	blk_mq_freeze_queue(ns->disk->queue);
> +	nvme_set_queue_limits(ns->ctrl, ns->queue);
> +	set_disk_ro(ns->disk, nvme_ns_is_readonly(ns, info));
> +	blk_mq_unfreeze_queue(ns->disk->queue);
> +
> +	if (nvme_ns_head_multipath(ns->head)) {
> +		blk_mq_freeze_queue(ns->head->disk->queue);
> +		set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info));
> +		nvme_mpath_revalidate_paths(ns);
> +		blk_stack_limits(&ns->head->disk->queue->limits,
> +				 &ns->queue->limits, 0);
> +		ns->head->disk->flags |= GENHD_FL_HIDDEN;
> +		blk_mq_unfreeze_queue(ns->head->disk->queue);
> +	}
> +
> +	/* Hide the block-interface for these devices */
> +	ns->disk->flags |= GENHD_FL_HIDDEN;
> +	set_bit(NVME_NS_READY, &ns->flags);
> +
> +	return 0;
> +}
> +
>   static int nvme_update_ns_info_block(struct nvme_ns *ns,
>   		struct nvme_ns_info *info)
>   {
> @@ -2024,17 +2049,15 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
>   	case NVME_CSI_ZNS:
>   		if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
>   			dev_warn(ns->ctrl->device,
> -	"nsid %u not supported without CONFIG_BLK_DEV_ZONED\n",
> +	"block device for nsid %u not supported without CONFIG_BLK_DEV_ZONED\n",
>   				info->nsid);
> -			return -ENODEV;
> +			return nvme_update_ns_info_generic(ns, info);
>   		}
>   		return nvme_update_ns_info_block(ns, info);
>   	case NVME_CSI_NVM:
>   		return nvme_update_ns_info_block(ns, info);
>   	default:
> -		dev_warn(ns->ctrl->device, "unknown csi %u for nsid %u\n",
> -			info->ids.csi, info->nsid);
> -		return -ENODEV;

Maybe we want to keep the log? can be converted to dev_info/dev_dbg, but
seems useful to have.

> +		return nvme_update_ns_info_generic(ns, info);
>   	}
>   }
>   
> @@ -4341,7 +4364,8 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
>   	 * data structure to find all the generic information that is needed to
>   	 * set up a namespace.  If not fall back to the legacy version.
>   	 */
> -	if (ctrl->cap & NVME_CAP_CRMS_CRIMS) {
> +	if ((ctrl->cap & NVME_CAP_CRMS_CRIMS) ||
> +	    (info.ids.csi != NVME_CSI_NVM && info.ids.csi != NVME_CSI_ZNS)) {
>   		if (nvme_ns_info_from_id_cs_indep(ctrl, &info))
>   			return;
>   	} else {



More information about the Linux-nvme mailing list