All of lore.kernel.org
 help / color / mirror / Atom feed
* enable generic interface (/dev/ngX) for unknown command sets v3
@ 2022-07-21  6:03 Christoph Hellwig
  2022-07-21  6:03 ` [PATCH 1/6] nvme: catch -ENODEV from nvme_revalidate_zones again Christoph Hellwig
                   ` (6 more replies)
  0 siblings, 7 replies; 12+ messages in thread
From: Christoph Hellwig @ 2022-07-21  6:03 UTC (permalink / raw)
  To: Joel Granados, kbusch, sagi; +Cc: joshi.k, linux-nvme, gost.dev, k.jensen

Hi all,

this is a version of the patch from Joel rebased on a bunch of cleanups
from me that I think make the layering a lot cleaner.  Let me know what
everyone things.

Changes since v2:
 - add a patch to fix a previous regression in handling of unsupported
   ZNS configs

Changes since v1:
 - log consistent messages when only passthrough is supported for
   namespaces


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/6] nvme: catch -ENODEV from nvme_revalidate_zones again
  2022-07-21  6:03 enable generic interface (/dev/ngX) for unknown command sets v3 Christoph Hellwig
@ 2022-07-21  6:03 ` Christoph Hellwig
  2022-07-21  9:53   ` Joel Granados
  2022-07-21  6:03 ` [PATCH 2/6] nvme: rename nvme_validate_or_alloc_ns to nvme_scan_ns Christoph Hellwig
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2022-07-21  6:03 UTC (permalink / raw)
  To: Joel Granados, kbusch, sagi; +Cc: joshi.k, linux-nvme, gost.dev, k.jensen

nvme_revalidate_zones can also return -ENODEV if e.g. zone sizes aren't
constant or not a power of two.  In that case we should jump to marking
the gendisk hidden and only support pass through.

Fixes: 602e57c9799c ("nvme: also mark passthrough-only namespaces ready in nvme_update_ns_info")
Reported-by: Joel Granados <j.granados@samsung.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/nvme/host/core.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 698e71680e6f3..2e1af9b5c8a91 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1940,8 +1940,10 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 
 	if (ns->head->ids.csi == NVME_CSI_ZNS) {
 		ret = nvme_update_zone_info(ns, lbaf);
-		if (ret)
-			goto out_unfreeze;
+		if (ret) {
+			blk_mq_unfreeze_queue(ns->disk->queue);
+			goto out;
+		}
 	}
 
 	set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) ||
@@ -1952,7 +1954,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 	if (blk_queue_is_zoned(ns->queue)) {
 		ret = nvme_revalidate_zones(ns);
 		if (ret && !nvme_first_scan(ns->disk))
-			return ret;
+			goto out;
 	}
 
 	if (nvme_ns_head_multipath(ns->head)) {
@@ -1967,9 +1969,9 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 		disk_update_readahead(ns->head->disk);
 		blk_mq_unfreeze_queue(ns->head->disk->queue);
 	}
-	return 0;
 
-out_unfreeze:
+	ret = 0;
+out:
 	/*
 	 * If probing fails due an unsupported feature, hide the block device,
 	 * but still allow other access.
@@ -1979,7 +1981,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 		set_bit(NVME_NS_READY, &ns->flags);
 		ret = 0;
 	}
-	blk_mq_unfreeze_queue(ns->disk->queue);
 	return ret;
 }
 
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/6] nvme: rename nvme_validate_or_alloc_ns to nvme_scan_ns
  2022-07-21  6:03 enable generic interface (/dev/ngX) for unknown command sets v3 Christoph Hellwig
  2022-07-21  6:03 ` [PATCH 1/6] nvme: catch -ENODEV from nvme_revalidate_zones again Christoph Hellwig
@ 2022-07-21  6:03 ` Christoph Hellwig
  2022-07-21  6:03 ` [PATCH 3/6] nvme: generalize the nvme_multi_css check in nvme_scan_ns Christoph Hellwig
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2022-07-21  6:03 UTC (permalink / raw)
  To: Joel Granados, kbusch, sagi
  Cc: joshi.k, linux-nvme, gost.dev, k.jensen, Javier González,
	Chaitanya Kulkarni

This shorter name much better fits what this function does in
the scanning process.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Javier González <javier.gonz@samsung.com>
Reviewed-by: Joel Granados <j.granados@samsung.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
---
 drivers/nvme/host/core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 2e1af9b5c8a91..af3b90ca9131d 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4285,7 +4285,7 @@ static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids)
 		nvme_ns_remove(ns);
 }
 
-static void nvme_validate_or_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
+static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 {
 	struct nvme_ns_ids ids = { };
 	struct nvme_id_ns_cs_indep *id;
@@ -4393,7 +4393,7 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl)
 
 			if (!nsid)	/* end of the list? */
 				goto out;
-			nvme_validate_or_alloc_ns(ctrl, nsid);
+			nvme_scan_ns(ctrl, nsid);
 			while (++prev < nsid)
 				nvme_ns_remove_by_nsid(ctrl, prev);
 		}
@@ -4416,7 +4416,7 @@ static void nvme_scan_ns_sequential(struct nvme_ctrl *ctrl)
 	kfree(id);
 
 	for (i = 1; i <= nn; i++)
-		nvme_validate_or_alloc_ns(ctrl, i);
+		nvme_scan_ns(ctrl, i);
 
 	nvme_remove_invalid_namespaces(ctrl, nn);
 }
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/6] nvme: generalize the nvme_multi_css check in nvme_scan_ns
  2022-07-21  6:03 enable generic interface (/dev/ngX) for unknown command sets v3 Christoph Hellwig
  2022-07-21  6:03 ` [PATCH 1/6] nvme: catch -ENODEV from nvme_revalidate_zones again Christoph Hellwig
  2022-07-21  6:03 ` [PATCH 2/6] nvme: rename nvme_validate_or_alloc_ns to nvme_scan_ns Christoph Hellwig
@ 2022-07-21  6:03 ` Christoph Hellwig
  2022-07-21  9:54   ` Joel Granados
  2022-07-21  6:03 ` [PATCH 4/6] nvme: refactor namespace probing Christoph Hellwig
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2022-07-21  6:03 UTC (permalink / raw)
  To: Joel Granados, kbusch, sagi
  Cc: joshi.k, linux-nvme, gost.dev, k.jensen, Javier González,
	Chaitanya Kulkarni

Check for multiple command set support early on an error out if is
not supported when a !NVM command set namespace is found.  This
prepares for adding command set independent passthrough support.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Javier González <javier.gonz@samsung.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
---
 drivers/nvme/host/core.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index af3b90ca9131d..5ba09d010daba 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4295,6 +4295,12 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 	if (nvme_identify_ns_descs(ctrl, nsid, &ids))
 		return;
 
+	if (ids.csi != NVME_CSI_NVM && !nvme_multi_css(ctrl)) {
+		dev_warn(ctrl->device,
+			"command set not reported for nsid: %d\n", nsid);
+		return;
+	}
+
 	/*
 	 * Check if the namespace is ready.  If not ignore it, we will get an
 	 * AEN once it becomes ready and restart the scan.
@@ -4326,12 +4332,6 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 				nsid);
 			break;
 		}
-		if (!nvme_multi_css(ctrl)) {
-			dev_warn(ctrl->device,
-				"command set not reported for nsid: %d\n",
-				nsid);
-			break;
-		}
 		nvme_alloc_ns(ctrl, nsid, &ids);
 		break;
 	default:
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/6] nvme: refactor namespace probing
  2022-07-21  6:03 enable generic interface (/dev/ngX) for unknown command sets v3 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2022-07-21  6:03 ` [PATCH 3/6] nvme: generalize the nvme_multi_css check in nvme_scan_ns Christoph Hellwig
@ 2022-07-21  6:03 ` Christoph Hellwig
  2022-07-21  9:36   ` Joel Granados
  2022-07-21  6:03 ` [PATCH 5/6] nvme: factor out a nvme_ns_is_readonly helper Christoph Hellwig
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2022-07-21  6:03 UTC (permalink / raw)
  To: Joel Granados, kbusch, sagi
  Cc: joshi.k, linux-nvme, gost.dev, k.jensen, Javier González

Change nvme_ns_scan to gather all information needed for generic
namespace setup into a nvme_ns_info structure.  This structure is filled
from the Command Set Idependent Identify Namespace data structure if
it is available or else the legacy Identify namespace structure.

With that everything related to the NVM command set (and the ZNS command
set derived from it) can be encapsulated in the nvme_update_ns_info_block
function while keeping the rest of the namespace probing generic.

The downside is that we now always issue two Identify Namespace calls for
each probed namespace instead of usually just a single one previously.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Javier González <javier.gonz@samsung.com>
---
 drivers/nvme/host/core.c | 230 +++++++++++++++++++++------------------
 1 file changed, 125 insertions(+), 105 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 5ba09d010daba..6169737c233b2 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -31,6 +31,14 @@
 
 #define NVME_MINORS		(1U << MINORBITS)
 
+struct nvme_ns_info {
+	struct nvme_ns_ids ids;
+	u32 nsid;
+	__le32 anagrpid;
+	bool is_shared;
+	bool is_ready;
+};
+
 unsigned int admin_timeout = 60;
 module_param(admin_timeout, uint, 0644);
 MODULE_PARM_DESC(admin_timeout, "timeout in seconds for admin commands");
@@ -1342,8 +1350,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids,
 	}
 }
 
-static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
-		struct nvme_ns_ids *ids)
+static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl,
+		struct nvme_ns_info *info)
 {
 	struct nvme_command c = { };
 	bool csi_seen = false;
@@ -1356,7 +1364,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
 		return 0;
 
 	c.identify.opcode = nvme_admin_identify;
-	c.identify.nsid = cpu_to_le32(nsid);
+	c.identify.nsid = cpu_to_le32(info->nsid);
 	c.identify.cns = NVME_ID_CNS_NS_DESC_LIST;
 
 	data = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
@@ -1368,7 +1376,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
 	if (status) {
 		dev_warn(ctrl->device,
 			"Identify Descriptors failed (nsid=%u, status=0x%x)\n",
-			nsid, status);
+			info->nsid, status);
 		goto free_data;
 	}
 
@@ -1378,7 +1386,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
 		if (cur->nidl == 0)
 			break;
 
-		len = nvme_process_ns_desc(ctrl, ids, cur, &csi_seen);
+		len = nvme_process_ns_desc(ctrl, &info->ids, cur, &csi_seen);
 		if (len < 0)
 			break;
 
@@ -1387,7 +1395,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
 
 	if (nvme_multi_css(ctrl) && !csi_seen) {
 		dev_warn(ctrl->device, "Command set not reported for nsid:%d\n",
-			 nsid);
+			 info->nsid);
 		status = -EINVAL;
 	}
 
@@ -1397,7 +1405,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
 }
 
 static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
-			struct nvme_ns_ids *ids, struct nvme_id_ns **id)
+			struct nvme_id_ns **id)
 {
 	struct nvme_command c = { };
 	int error;
@@ -1420,51 +1428,64 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 	error = NVME_SC_INVALID_NS | NVME_SC_DNR;
 	if ((*id)->ncap == 0) /* namespace not allocated or attached */
 		goto out_free_id;
+	return 0;
 
+out_free_id:
+	kfree(*id);
+	return error;
+}
 
+static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl,
+		struct nvme_ns_info *info)
+{
+	struct nvme_ns_ids *ids = &info->ids;
+	struct nvme_id_ns *id;
+	int ret;
+
+	ret = nvme_identify_ns(ctrl, info->nsid, &id);
+	if (ret)
+		return ret;
+	info->anagrpid = id->anagrpid;
+	info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
+	info->is_ready = true;
 	if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) {
 		dev_info(ctrl->device,
 			 "Ignoring bogus Namespace Identifiers\n");
 	} else {
 		if (ctrl->vs >= NVME_VS(1, 1, 0) &&
 		    !memchr_inv(ids->eui64, 0, sizeof(ids->eui64)))
-			memcpy(ids->eui64, (*id)->eui64, sizeof(ids->eui64));
+			memcpy(ids->eui64, id->eui64, sizeof(ids->eui64));
 		if (ctrl->vs >= NVME_VS(1, 2, 0) &&
 		    !memchr_inv(ids->nguid, 0, sizeof(ids->nguid)))
-			memcpy(ids->nguid, (*id)->nguid, sizeof(ids->nguid));
+			memcpy(ids->nguid, id->nguid, sizeof(ids->nguid));
 	}
-
+	kfree(id);
 	return 0;
-
-out_free_id:
-	kfree(*id);
-	return error;
 }
 
-static int nvme_identify_ns_cs_indep(struct nvme_ctrl *ctrl, unsigned nsid,
-			struct nvme_id_ns_cs_indep **id)
+static int nvme_ns_info_from_id_cs_indep(struct nvme_ctrl *ctrl,
+		struct nvme_ns_info *info)
 {
+	struct nvme_id_ns_cs_indep *id;
 	struct nvme_command c = {
 		.identify.opcode	= nvme_admin_identify,
-		.identify.nsid		= cpu_to_le32(nsid),
+		.identify.nsid		= cpu_to_le32(info->nsid),
 		.identify.cns		= NVME_ID_CNS_NS_CS_INDEP,
 	};
 	int ret;
 
-	*id = kmalloc(sizeof(**id), GFP_KERNEL);
-	if (!*id)
+	id = kmalloc(sizeof(*id), GFP_KERNEL);
+	if (!id)
 		return -ENOMEM;
 
-	ret = nvme_submit_sync_cmd(ctrl->admin_q, &c, *id, sizeof(**id));
-	if (ret) {
-		dev_warn(ctrl->device,
-			 "Identify namespace (CS independent) failed (%d)\n",
-			 ret);
-		kfree(*id);
-		return ret;
+	ret = nvme_submit_sync_cmd(ctrl->admin_q, &c, id, sizeof(*id));
+	if (!ret) {
+		info->anagrpid = id->anagrpid;
+		info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
+		info->is_ready = id->nstat & NVME_NSTAT_NRDY;
 	}
-
-	return 0;
+	kfree(id);
+	return ret;
 }
 
 static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid,
@@ -1925,12 +1946,19 @@ 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(struct nvme_ns *ns, struct nvme_id_ns *id)
+static int nvme_update_ns_info_block(struct nvme_ns *ns,
+		struct nvme_ns_info *info)
 {
-	unsigned lbaf = nvme_lbaf_index(id->flbas);
+	struct nvme_id_ns *id;
+	unsigned lbaf;
 	int ret;
 
+	ret = nvme_identify_ns(ns->ctrl, info->nsid, &id);
+	if (ret)
+		return ret;
+
 	blk_mq_freeze_queue(ns->disk->queue);
+	lbaf = nvme_lbaf_index(id->flbas);
 	ns->lba_shift = id->lbaf[lbaf].ds;
 	nvme_set_queue_limits(ns->ctrl, ns->queue);
 
@@ -1981,9 +2009,30 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
 		set_bit(NVME_NS_READY, &ns->flags);
 		ret = 0;
 	}
+	kfree(id);
 	return ret;
 }
 
+static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
+{
+	switch (info->ids.csi) {
+	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",
+				info->nsid);
+			return -ENODEV;
+		}
+		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;
+	}
+}
+
 static char nvme_pr_type(enum pr_type type)
 {
 	switch (type) {
@@ -3913,7 +3962,7 @@ static int nvme_add_ns_cdev(struct nvme_ns *ns)
 }
 
 static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
-		unsigned nsid, struct nvme_ns_ids *ids)
+		struct nvme_ns_info *info)
 {
 	struct nvme_ns_head *head;
 	size_t size = sizeof(*head);
@@ -3935,8 +3984,9 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
 	if (ret)
 		goto out_ida_remove;
 	head->subsys = ctrl->subsys;
-	head->ns_id = nsid;
-	head->ids = *ids;
+	head->ns_id = info->nsid;
+	head->ids = info->ids;
+	head->shared = info->is_shared;
 	kref_init(&head->ref);
 
 	if (head->ids.csi) {
@@ -3993,55 +4043,54 @@ static int nvme_global_check_duplicate_ids(struct nvme_subsystem *this,
 	return ret;
 }
 
-static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
-		struct nvme_ns_ids *ids, bool is_shared)
+static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
 {
 	struct nvme_ctrl *ctrl = ns->ctrl;
 	struct nvme_ns_head *head = NULL;
 	int ret;
 
-	ret = nvme_global_check_duplicate_ids(ctrl->subsys, ids);
+	ret = nvme_global_check_duplicate_ids(ctrl->subsys, &info->ids);
 	if (ret) {
 		dev_err(ctrl->device,
-			"globally duplicate IDs for nsid %d\n", nsid);
+			"globally duplicate IDs for nsid %d\n", info->nsid);
 		nvme_print_device_info(ctrl);
 		return ret;
 	}
 
 	mutex_lock(&ctrl->subsys->lock);
-	head = nvme_find_ns_head(ctrl, nsid);
+	head = nvme_find_ns_head(ctrl, info->nsid);
 	if (!head) {
-		ret = nvme_subsys_check_duplicate_ids(ctrl->subsys, ids);
+		ret = nvme_subsys_check_duplicate_ids(ctrl->subsys, &info->ids);
 		if (ret) {
 			dev_err(ctrl->device,
 				"duplicate IDs in subsystem for nsid %d\n",
-				nsid);
+				info->nsid);
 			goto out_unlock;
 		}
-		head = nvme_alloc_ns_head(ctrl, nsid, ids);
+		head = nvme_alloc_ns_head(ctrl, info);
 		if (IS_ERR(head)) {
 			ret = PTR_ERR(head);
 			goto out_unlock;
 		}
-		head->shared = is_shared;
 	} else {
 		ret = -EINVAL;
-		if (!is_shared || !head->shared) {
+		if (!info->is_shared || !head->shared) {
 			dev_err(ctrl->device,
-				"Duplicate unshared namespace %d\n", nsid);
+				"Duplicate unshared namespace %d\n",
+				info->nsid);
 			goto out_put_ns_head;
 		}
-		if (!nvme_ns_ids_equal(&head->ids, ids)) {
+		if (!nvme_ns_ids_equal(&head->ids, &info->ids)) {
 			dev_err(ctrl->device,
 				"IDs don't match for shared namespace %d\n",
-					nsid);
+					info->nsid);
 			goto out_put_ns_head;
 		}
 
 		if (!multipath && !list_empty(&head->list)) {
 			dev_warn(ctrl->device,
 				"Found shared namespace %d, but multipathing not supported.\n",
-				nsid);
+				info->nsid);
 			dev_warn_once(ctrl->device,
 				"Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0\n.");
 		}
@@ -4095,20 +4144,15 @@ static void nvme_ns_add_to_ctrl_list(struct nvme_ns *ns)
 	list_add(&ns->list, &ns->ctrl->namespaces);
 }
 
-static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
-		struct nvme_ns_ids *ids)
+static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info)
 {
 	struct nvme_ns *ns;
 	struct gendisk *disk;
-	struct nvme_id_ns *id;
 	int node = ctrl->numa_node;
 
-	if (nvme_identify_ns(ctrl, nsid, ids, &id))
-		return;
-
 	ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
 	if (!ns)
-		goto out_free_id;
+		return;
 
 	disk = blk_mq_alloc_disk(ctrl->tagset, ns);
 	if (IS_ERR(disk))
@@ -4129,7 +4173,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 	ns->ctrl = ctrl;
 	kref_init(&ns->kref);
 
-	if (nvme_init_ns_head(ns, nsid, ids, id->nmic & NVME_NS_NMIC_SHARED))
+	if (nvme_init_ns_head(ns, info))
 		goto out_cleanup_disk;
 
 	/*
@@ -4155,7 +4199,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 			ns->head->instance);
 	}
 
-	if (nvme_update_ns_info(ns, id))
+	if (nvme_update_ns_info(ns, info))
 		goto out_unlink_ns;
 
 	down_write(&ctrl->namespaces_rwsem);
@@ -4169,9 +4213,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 	if (!nvme_ns_head_multipath(ns->head))
 		nvme_add_ns_cdev(ns);
 
-	nvme_mpath_add_disk(ns, id->anagrpid);
+	nvme_mpath_add_disk(ns, info->anagrpid);
 	nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name);
-	kfree(id);
 
 	return;
 
@@ -4191,8 +4234,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
 	blk_cleanup_disk(disk);
  out_free_ns:
 	kfree(ns);
- out_free_id:
-	kfree(id);
 }
 
 static void nvme_ns_remove(struct nvme_ns *ns)
@@ -4251,29 +4292,21 @@ static void nvme_ns_remove_by_nsid(struct nvme_ctrl *ctrl, u32 nsid)
 	}
 }
 
-static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids)
+static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_info *info)
 {
-	struct nvme_id_ns *id;
 	int ret = NVME_SC_INVALID_NS | NVME_SC_DNR;
 
 	if (test_bit(NVME_NS_DEAD, &ns->flags))
 		goto out;
 
-	ret = nvme_identify_ns(ns->ctrl, ns->head->ns_id, ids, &id);
-	if (ret)
-		goto out;
-
 	ret = NVME_SC_INVALID_NS | NVME_SC_DNR;
-	if (!nvme_ns_ids_equal(&ns->head->ids, ids)) {
+	if (!nvme_ns_ids_equal(&ns->head->ids, &info->ids)) {
 		dev_err(ns->ctrl->device,
 			"identifiers changed for nsid %d\n", ns->head->ns_id);
-		goto out_free_id;
+		goto out;
 	}
 
-	ret = nvme_update_ns_info(ns, id);
-
-out_free_id:
-	kfree(id);
+	ret = nvme_update_ns_info(ns, info);
 out:
 	/*
 	 * Only remove the namespace if we got a fatal error back from the
@@ -4287,57 +4320,44 @@ static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids)
 
 static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
 {
-	struct nvme_ns_ids ids = { };
-	struct nvme_id_ns_cs_indep *id;
+	struct nvme_ns_info info = { .nsid = nsid };
 	struct nvme_ns *ns;
-	bool ready = true;
 
-	if (nvme_identify_ns_descs(ctrl, nsid, &ids))
+	if (nvme_identify_ns_descs(ctrl, &info))
 		return;
 
-	if (ids.csi != NVME_CSI_NVM && !nvme_multi_css(ctrl)) {
+	if (info.ids.csi != NVME_CSI_NVM && !nvme_multi_css(ctrl)) {
 		dev_warn(ctrl->device,
 			"command set not reported for nsid: %d\n", nsid);
 		return;
 	}
 
 	/*
-	 * Check if the namespace is ready.  If not ignore it, we will get an
-	 * AEN once it becomes ready and restart the scan.
+	 * If available try to use the Command Set Idependent Identify Namespace
+	 * 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) &&
-	    !nvme_identify_ns_cs_indep(ctrl, nsid, &id)) {
-		ready = id->nstat & NVME_NSTAT_NRDY;
-		kfree(id);
+	if (ctrl->cap & NVME_CAP_CRMS_CRIMS) {
+		if (nvme_ns_info_from_id_cs_indep(ctrl, &info))
+			return;
+	} else {
+		if (nvme_ns_info_from_identify(ctrl, &info))
+			return;
 	}
 
-	if (!ready)
+	/*
+	 * Ignore the namespace if it is not ready. We will get an AEN once it
+	 * becomes ready and restart the scan.
+	 */
+	if (!info.is_ready)
 		return;
 
 	ns = nvme_find_get_ns(ctrl, nsid);
 	if (ns) {
-		nvme_validate_ns(ns, &ids);
+		nvme_validate_ns(ns, &info);
 		nvme_put_ns(ns);
-		return;
-	}
-
-	switch (ids.csi) {
-	case NVME_CSI_NVM:
-		nvme_alloc_ns(ctrl, nsid, &ids);
-		break;
-	case NVME_CSI_ZNS:
-		if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
-			dev_warn(ctrl->device,
-				"nsid %u not supported without CONFIG_BLK_DEV_ZONED\n",
-				nsid);
-			break;
-		}
-		nvme_alloc_ns(ctrl, nsid, &ids);
-		break;
-	default:
-		dev_warn(ctrl->device, "unknown csi %u for nsid %u\n",
-			ids.csi, nsid);
-		break;
+	} else {
+		nvme_alloc_ns(ctrl, &info);
 	}
 }
 
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/6] nvme: factor out a nvme_ns_is_readonly helper
  2022-07-21  6:03 enable generic interface (/dev/ngX) for unknown command sets v3 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2022-07-21  6:03 ` [PATCH 4/6] nvme: refactor namespace probing Christoph Hellwig
@ 2022-07-21  6:03 ` Christoph Hellwig
  2022-07-21  9:54   ` Joel Granados
  2022-07-21  6:03 ` [PATCH 6/6] nvme: enable generic interface (/dev/ngXnY) for unknown command sets Christoph Hellwig
  2022-07-21 22:17 ` enable generic interface (/dev/ngX) for unknown command sets v3 Sagi Grimberg
  6 siblings, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2022-07-21  6:03 UTC (permalink / raw)
  To: Joel Granados, kbusch, sagi
  Cc: joshi.k, linux-nvme, gost.dev, k.jensen, Javier González,
	Chaitanya Kulkarni

Add a little helper to check if a namespace should be marked read-only
that uses a new is_readonly flag in the nvme_ns_info structure.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Javier González <javier.gonz@samsung.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
---
 drivers/nvme/host/core.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 6169737c233b2..271c0de483a9b 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -36,6 +36,7 @@ struct nvme_ns_info {
 	u32 nsid;
 	__le32 anagrpid;
 	bool is_shared;
+	bool is_readonly;
 	bool is_ready;
 };
 
@@ -1447,6 +1448,7 @@ static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl,
 		return ret;
 	info->anagrpid = id->anagrpid;
 	info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
+	info->is_readonly = id->nsattr & NVME_NS_ATTR_RO;
 	info->is_ready = true;
 	if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) {
 		dev_info(ctrl->device,
@@ -1482,6 +1484,7 @@ static int nvme_ns_info_from_id_cs_indep(struct nvme_ctrl *ctrl,
 	if (!ret) {
 		info->anagrpid = id->anagrpid;
 		info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
+		info->is_readonly = id->nsattr & NVME_NS_ATTR_RO;
 		info->is_ready = id->nstat & NVME_NSTAT_NRDY;
 	}
 	kfree(id);
@@ -1909,6 +1912,11 @@ static void nvme_update_disk_info(struct gendisk *disk,
 					   ns->ctrl->max_zeroes_sectors);
 }
 
+static bool nvme_ns_is_readonly(struct nvme_ns *ns, struct nvme_ns_info *info)
+{
+	return info->is_readonly || test_bit(NVME_NS_FORCE_RO, &ns->flags);
+}
+
 static inline bool nvme_first_scan(struct gendisk *disk)
 {
 	/* nvme_alloc_ns() scans the disk prior to adding it */
@@ -1974,8 +1982,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
 		}
 	}
 
-	set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) ||
-		test_bit(NVME_NS_FORCE_RO, &ns->flags));
+	set_disk_ro(ns->disk, nvme_ns_is_readonly(ns, info));
 	set_bit(NVME_NS_READY, &ns->flags);
 	blk_mq_unfreeze_queue(ns->disk->queue);
 
@@ -1988,9 +1995,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
 	if (nvme_ns_head_multipath(ns->head)) {
 		blk_mq_freeze_queue(ns->head->disk->queue);
 		nvme_update_disk_info(ns->head->disk, ns, id);
-		set_disk_ro(ns->head->disk,
-			    (id->nsattr & NVME_NS_ATTR_RO) ||
-				    test_bit(NVME_NS_FORCE_RO, &ns->flags));
+		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);
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/6] nvme: enable generic interface (/dev/ngXnY) for unknown command sets
  2022-07-21  6:03 enable generic interface (/dev/ngX) for unknown command sets v3 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2022-07-21  6:03 ` [PATCH 5/6] nvme: factor out a nvme_ns_is_readonly helper Christoph Hellwig
@ 2022-07-21  6:03 ` Christoph Hellwig
  2022-07-21 22:17 ` enable generic interface (/dev/ngX) for unknown command sets v3 Sagi Grimberg
  6 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2022-07-21  6:03 UTC (permalink / raw)
  To: Joel Granados, kbusch, sagi
  Cc: joshi.k, linux-nvme, gost.dev, k.jensen, Javier González

From: Joel Granados <j.granados@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@lst.de>
Signed-off-by: Joel Granados <j.granados@samsung.com>
Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
[hch: rebased on other refactoring patches]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Javier González <javier.gonz@samsung.com>
---
 drivers/nvme/host/core.c | 41 +++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 271c0de483a9b..bf43edeb74700 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)
 {
@@ -2023,18 +2048,19 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
 	switch (info->ids.csi) {
 	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",
+			dev_info(ns->ctrl->device,
+	"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;
+		dev_info(ns->ctrl->device,
+			"block device for nsid %u not supported (csi %u)\n",
+			info->nsid, info->ids.csi);
+		return nvme_update_ns_info_generic(ns, info);
 	}
 }
 
@@ -4342,7 +4368,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 {
-- 
2.30.2



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/6] nvme: refactor namespace probing
  2022-07-21  6:03 ` [PATCH 4/6] nvme: refactor namespace probing Christoph Hellwig
@ 2022-07-21  9:36   ` Joel Granados
  0 siblings, 0 replies; 12+ messages in thread
From: Joel Granados @ 2022-07-21  9:36 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: kbusch, sagi, joshi.k, linux-nvme, gost.dev, k.jensen,
	Javier González

[-- Attachment #1: Type: text/plain, Size: 16243 bytes --]

On Thu, Jul 21, 2022 at 08:03:18AM +0200, Christoph Hellwig wrote:
> Change nvme_ns_scan to gather all information needed for generic
> namespace setup into a nvme_ns_info structure.  This structure is filled
> from the Command Set Idependent Identify Namespace data structure if
> it is available or else the legacy Identify namespace structure.
> 
> With that everything related to the NVM command set (and the ZNS command
> set derived from it) can be encapsulated in the nvme_update_ns_info_block
> function while keeping the rest of the namespace probing generic.
> 
> The downside is that we now always issue two Identify Namespace calls for
> each probed namespace instead of usually just a single one previously.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Javier González <javier.gonz@samsung.com>
> ---
>  drivers/nvme/host/core.c | 230 +++++++++++++++++++++------------------
>  1 file changed, 125 insertions(+), 105 deletions(-)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 5ba09d010daba..6169737c233b2 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -31,6 +31,14 @@
>  
>  #define NVME_MINORS		(1U << MINORBITS)
>  
> +struct nvme_ns_info {
> +	struct nvme_ns_ids ids;
> +	u32 nsid;
> +	__le32 anagrpid;
> +	bool is_shared;
> +	bool is_ready;
> +};
> +
>  unsigned int admin_timeout = 60;
>  module_param(admin_timeout, uint, 0644);
>  MODULE_PARM_DESC(admin_timeout, "timeout in seconds for admin commands");
> @@ -1342,8 +1350,8 @@ static int nvme_process_ns_desc(struct nvme_ctrl *ctrl, struct nvme_ns_ids *ids,
>  	}
>  }
>  
> -static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
> -		struct nvme_ns_ids *ids)
> +static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl,
> +		struct nvme_ns_info *info)
>  {
>  	struct nvme_command c = { };
>  	bool csi_seen = false;
> @@ -1356,7 +1364,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
>  		return 0;
>  
>  	c.identify.opcode = nvme_admin_identify;
> -	c.identify.nsid = cpu_to_le32(nsid);
> +	c.identify.nsid = cpu_to_le32(info->nsid);
>  	c.identify.cns = NVME_ID_CNS_NS_DESC_LIST;
>  
>  	data = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL);
> @@ -1368,7 +1376,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
>  	if (status) {
>  		dev_warn(ctrl->device,
>  			"Identify Descriptors failed (nsid=%u, status=0x%x)\n",
> -			nsid, status);
> +			info->nsid, status);
>  		goto free_data;
>  	}
>  
> @@ -1378,7 +1386,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
>  		if (cur->nidl == 0)
>  			break;
>  
> -		len = nvme_process_ns_desc(ctrl, ids, cur, &csi_seen);
> +		len = nvme_process_ns_desc(ctrl, &info->ids, cur, &csi_seen);
>  		if (len < 0)
>  			break;
>  
> @@ -1387,7 +1395,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
>  
>  	if (nvme_multi_css(ctrl) && !csi_seen) {
>  		dev_warn(ctrl->device, "Command set not reported for nsid:%d\n",
> -			 nsid);
> +			 info->nsid);
>  		status = -EINVAL;
>  	}
>  
> @@ -1397,7 +1405,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl, unsigned nsid,
>  }
>  
>  static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
> -			struct nvme_ns_ids *ids, struct nvme_id_ns **id)
> +			struct nvme_id_ns **id)
>  {
>  	struct nvme_command c = { };
>  	int error;
> @@ -1420,51 +1428,64 @@ static int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid,
>  	error = NVME_SC_INVALID_NS | NVME_SC_DNR;
>  	if ((*id)->ncap == 0) /* namespace not allocated or attached */
>  		goto out_free_id;
> +	return 0;
>  
> +out_free_id:
> +	kfree(*id);
> +	return error;
> +}
>  
> +static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl,
> +		struct nvme_ns_info *info)
> +{
> +	struct nvme_ns_ids *ids = &info->ids;
> +	struct nvme_id_ns *id;
> +	int ret;
> +
> +	ret = nvme_identify_ns(ctrl, info->nsid, &id);
> +	if (ret)
> +		return ret;
> +	info->anagrpid = id->anagrpid;
> +	info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
> +	info->is_ready = true;
>  	if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) {
>  		dev_info(ctrl->device,
>  			 "Ignoring bogus Namespace Identifiers\n");
>  	} else {
>  		if (ctrl->vs >= NVME_VS(1, 1, 0) &&
>  		    !memchr_inv(ids->eui64, 0, sizeof(ids->eui64)))
> -			memcpy(ids->eui64, (*id)->eui64, sizeof(ids->eui64));
> +			memcpy(ids->eui64, id->eui64, sizeof(ids->eui64));
>  		if (ctrl->vs >= NVME_VS(1, 2, 0) &&
>  		    !memchr_inv(ids->nguid, 0, sizeof(ids->nguid)))
> -			memcpy(ids->nguid, (*id)->nguid, sizeof(ids->nguid));
> +			memcpy(ids->nguid, id->nguid, sizeof(ids->nguid));
>  	}
> -
> +	kfree(id);
>  	return 0;
> -
> -out_free_id:
> -	kfree(*id);
> -	return error;
>  }
>  
> -static int nvme_identify_ns_cs_indep(struct nvme_ctrl *ctrl, unsigned nsid,
> -			struct nvme_id_ns_cs_indep **id)
> +static int nvme_ns_info_from_id_cs_indep(struct nvme_ctrl *ctrl,
> +		struct nvme_ns_info *info)
>  {
> +	struct nvme_id_ns_cs_indep *id;
>  	struct nvme_command c = {
>  		.identify.opcode	= nvme_admin_identify,
> -		.identify.nsid		= cpu_to_le32(nsid),
> +		.identify.nsid		= cpu_to_le32(info->nsid),
>  		.identify.cns		= NVME_ID_CNS_NS_CS_INDEP,
>  	};
>  	int ret;
>  
> -	*id = kmalloc(sizeof(**id), GFP_KERNEL);
> -	if (!*id)
> +	id = kmalloc(sizeof(*id), GFP_KERNEL);
> +	if (!id)
>  		return -ENOMEM;
>  
> -	ret = nvme_submit_sync_cmd(ctrl->admin_q, &c, *id, sizeof(**id));
> -	if (ret) {
> -		dev_warn(ctrl->device,
> -			 "Identify namespace (CS independent) failed (%d)\n",
> -			 ret);
> -		kfree(*id);
> -		return ret;
> +	ret = nvme_submit_sync_cmd(ctrl->admin_q, &c, id, sizeof(*id));
> +	if (!ret) {
> +		info->anagrpid = id->anagrpid;
> +		info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
> +		info->is_ready = id->nstat & NVME_NSTAT_NRDY;
>  	}
> -
> -	return 0;
> +	kfree(id);
> +	return ret;
>  }
>  
>  static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid,
> @@ -1925,12 +1946,19 @@ 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(struct nvme_ns *ns, struct nvme_id_ns *id)
> +static int nvme_update_ns_info_block(struct nvme_ns *ns,
> +		struct nvme_ns_info *info)
>  {
> -	unsigned lbaf = nvme_lbaf_index(id->flbas);
> +	struct nvme_id_ns *id;
> +	unsigned lbaf;
>  	int ret;
>  
> +	ret = nvme_identify_ns(ns->ctrl, info->nsid, &id);
> +	if (ret)
> +		return ret;
> +
>  	blk_mq_freeze_queue(ns->disk->queue);
> +	lbaf = nvme_lbaf_index(id->flbas);
>  	ns->lba_shift = id->lbaf[lbaf].ds;
>  	nvme_set_queue_limits(ns->ctrl, ns->queue);
>  
> @@ -1981,9 +2009,30 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
>  		set_bit(NVME_NS_READY, &ns->flags);
>  		ret = 0;
>  	}
> +	kfree(id);
>  	return ret;
>  }
>  
> +static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
> +{
> +	switch (info->ids.csi) {
> +	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",
> +				info->nsid);
> +			return -ENODEV;
> +		}
> +		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;
> +	}
> +}
> +
>  static char nvme_pr_type(enum pr_type type)
>  {
>  	switch (type) {
> @@ -3913,7 +3962,7 @@ static int nvme_add_ns_cdev(struct nvme_ns *ns)
>  }
>  
>  static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
> -		unsigned nsid, struct nvme_ns_ids *ids)
> +		struct nvme_ns_info *info)
>  {
>  	struct nvme_ns_head *head;
>  	size_t size = sizeof(*head);
> @@ -3935,8 +3984,9 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
>  	if (ret)
>  		goto out_ida_remove;
>  	head->subsys = ctrl->subsys;
> -	head->ns_id = nsid;
> -	head->ids = *ids;
> +	head->ns_id = info->nsid;
> +	head->ids = info->ids;
> +	head->shared = info->is_shared;
>  	kref_init(&head->ref);
>  
>  	if (head->ids.csi) {
> @@ -3993,55 +4043,54 @@ static int nvme_global_check_duplicate_ids(struct nvme_subsystem *this,
>  	return ret;
>  }
>  
> -static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
> -		struct nvme_ns_ids *ids, bool is_shared)
> +static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
>  {
>  	struct nvme_ctrl *ctrl = ns->ctrl;
>  	struct nvme_ns_head *head = NULL;
>  	int ret;
>  
> -	ret = nvme_global_check_duplicate_ids(ctrl->subsys, ids);
> +	ret = nvme_global_check_duplicate_ids(ctrl->subsys, &info->ids);
>  	if (ret) {
>  		dev_err(ctrl->device,
> -			"globally duplicate IDs for nsid %d\n", nsid);
> +			"globally duplicate IDs for nsid %d\n", info->nsid);
>  		nvme_print_device_info(ctrl);
>  		return ret;
>  	}
>  
>  	mutex_lock(&ctrl->subsys->lock);
> -	head = nvme_find_ns_head(ctrl, nsid);
> +	head = nvme_find_ns_head(ctrl, info->nsid);
>  	if (!head) {
> -		ret = nvme_subsys_check_duplicate_ids(ctrl->subsys, ids);
> +		ret = nvme_subsys_check_duplicate_ids(ctrl->subsys, &info->ids);
>  		if (ret) {
>  			dev_err(ctrl->device,
>  				"duplicate IDs in subsystem for nsid %d\n",
> -				nsid);
> +				info->nsid);
>  			goto out_unlock;
>  		}
> -		head = nvme_alloc_ns_head(ctrl, nsid, ids);
> +		head = nvme_alloc_ns_head(ctrl, info);
>  		if (IS_ERR(head)) {
>  			ret = PTR_ERR(head);
>  			goto out_unlock;
>  		}
> -		head->shared = is_shared;
>  	} else {
>  		ret = -EINVAL;
> -		if (!is_shared || !head->shared) {
> +		if (!info->is_shared || !head->shared) {
>  			dev_err(ctrl->device,
> -				"Duplicate unshared namespace %d\n", nsid);
> +				"Duplicate unshared namespace %d\n",
> +				info->nsid);
>  			goto out_put_ns_head;
>  		}
> -		if (!nvme_ns_ids_equal(&head->ids, ids)) {
> +		if (!nvme_ns_ids_equal(&head->ids, &info->ids)) {
>  			dev_err(ctrl->device,
>  				"IDs don't match for shared namespace %d\n",
> -					nsid);
> +					info->nsid);
>  			goto out_put_ns_head;
>  		}
>  
>  		if (!multipath && !list_empty(&head->list)) {
>  			dev_warn(ctrl->device,
>  				"Found shared namespace %d, but multipathing not supported.\n",
> -				nsid);
> +				info->nsid);
>  			dev_warn_once(ctrl->device,
>  				"Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0\n.");
>  		}
> @@ -4095,20 +4144,15 @@ static void nvme_ns_add_to_ctrl_list(struct nvme_ns *ns)
>  	list_add(&ns->list, &ns->ctrl->namespaces);
>  }
>  
> -static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
> -		struct nvme_ns_ids *ids)
> +static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info)
>  {
>  	struct nvme_ns *ns;
>  	struct gendisk *disk;
> -	struct nvme_id_ns *id;
>  	int node = ctrl->numa_node;
>  
> -	if (nvme_identify_ns(ctrl, nsid, ids, &id))
> -		return;
> -
>  	ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
>  	if (!ns)
> -		goto out_free_id;
> +		return;
>  
>  	disk = blk_mq_alloc_disk(ctrl->tagset, ns);
>  	if (IS_ERR(disk))
> @@ -4129,7 +4173,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
>  	ns->ctrl = ctrl;
>  	kref_init(&ns->kref);
>  
> -	if (nvme_init_ns_head(ns, nsid, ids, id->nmic & NVME_NS_NMIC_SHARED))
> +	if (nvme_init_ns_head(ns, info))
>  		goto out_cleanup_disk;
>  
>  	/*
> @@ -4155,7 +4199,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
>  			ns->head->instance);
>  	}
>  
> -	if (nvme_update_ns_info(ns, id))
> +	if (nvme_update_ns_info(ns, info))
>  		goto out_unlink_ns;
>  
>  	down_write(&ctrl->namespaces_rwsem);
> @@ -4169,9 +4213,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
>  	if (!nvme_ns_head_multipath(ns->head))
>  		nvme_add_ns_cdev(ns);
>  
> -	nvme_mpath_add_disk(ns, id->anagrpid);
> +	nvme_mpath_add_disk(ns, info->anagrpid);
>  	nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name);
> -	kfree(id);
>  
>  	return;
>  
> @@ -4191,8 +4234,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid,
>  	blk_cleanup_disk(disk);
>   out_free_ns:
>  	kfree(ns);
> - out_free_id:
> -	kfree(id);
>  }
>  
>  static void nvme_ns_remove(struct nvme_ns *ns)
> @@ -4251,29 +4292,21 @@ static void nvme_ns_remove_by_nsid(struct nvme_ctrl *ctrl, u32 nsid)
>  	}
>  }
>  
> -static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids)
> +static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_info *info)
>  {
> -	struct nvme_id_ns *id;
>  	int ret = NVME_SC_INVALID_NS | NVME_SC_DNR;
>  
>  	if (test_bit(NVME_NS_DEAD, &ns->flags))
>  		goto out;
>  
> -	ret = nvme_identify_ns(ns->ctrl, ns->head->ns_id, ids, &id);
> -	if (ret)
> -		goto out;
> -
>  	ret = NVME_SC_INVALID_NS | NVME_SC_DNR;
> -	if (!nvme_ns_ids_equal(&ns->head->ids, ids)) {
> +	if (!nvme_ns_ids_equal(&ns->head->ids, &info->ids)) {
>  		dev_err(ns->ctrl->device,
>  			"identifiers changed for nsid %d\n", ns->head->ns_id);
> -		goto out_free_id;
> +		goto out;
>  	}
>  
> -	ret = nvme_update_ns_info(ns, id);
> -
> -out_free_id:
> -	kfree(id);
> +	ret = nvme_update_ns_info(ns, info);
>  out:
>  	/*
>  	 * Only remove the namespace if we got a fatal error back from the
> @@ -4287,57 +4320,44 @@ static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_ids *ids)
>  
>  static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
>  {
> -	struct nvme_ns_ids ids = { };
> -	struct nvme_id_ns_cs_indep *id;
> +	struct nvme_ns_info info = { .nsid = nsid };
>  	struct nvme_ns *ns;
> -	bool ready = true;
>  
> -	if (nvme_identify_ns_descs(ctrl, nsid, &ids))
> +	if (nvme_identify_ns_descs(ctrl, &info))
>  		return;
>  
> -	if (ids.csi != NVME_CSI_NVM && !nvme_multi_css(ctrl)) {
> +	if (info.ids.csi != NVME_CSI_NVM && !nvme_multi_css(ctrl)) {
>  		dev_warn(ctrl->device,
>  			"command set not reported for nsid: %d\n", nsid);
>  		return;
>  	}
>  
>  	/*
> -	 * Check if the namespace is ready.  If not ignore it, we will get an
> -	 * AEN once it becomes ready and restart the scan.
> +	 * If available try to use the Command Set Idependent Identify Namespace
> +	 * 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) &&
> -	    !nvme_identify_ns_cs_indep(ctrl, nsid, &id)) {
> -		ready = id->nstat & NVME_NSTAT_NRDY;
> -		kfree(id);
> +	if (ctrl->cap & NVME_CAP_CRMS_CRIMS) {
> +		if (nvme_ns_info_from_id_cs_indep(ctrl, &info))
> +			return;
> +	} else {
> +		if (nvme_ns_info_from_identify(ctrl, &info))
> +			return;
>  	}
>  
> -	if (!ready)
> +	/*
> +	 * Ignore the namespace if it is not ready. We will get an AEN once it
> +	 * becomes ready and restart the scan.
> +	 */
> +	if (!info.is_ready)
>  		return;
>  
>  	ns = nvme_find_get_ns(ctrl, nsid);
>  	if (ns) {
> -		nvme_validate_ns(ns, &ids);
> +		nvme_validate_ns(ns, &info);
>  		nvme_put_ns(ns);
> -		return;
> -	}
> -
> -	switch (ids.csi) {
> -	case NVME_CSI_NVM:
> -		nvme_alloc_ns(ctrl, nsid, &ids);
> -		break;
> -	case NVME_CSI_ZNS:
> -		if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED)) {
> -			dev_warn(ctrl->device,
> -				"nsid %u not supported without CONFIG_BLK_DEV_ZONED\n",
> -				nsid);
> -			break;
> -		}
> -		nvme_alloc_ns(ctrl, nsid, &ids);
> -		break;
> -	default:
> -		dev_warn(ctrl->device, "unknown csi %u for nsid %u\n",
> -			ids.csi, nsid);
> -		break;
> +	} else {
> +		nvme_alloc_ns(ctrl, &info);
>  	}
>  }
>  
> -- 
> 2.30.2
> 

LGTM
Reviewed-by: Joel Granados <j.granados@samsung.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/6] nvme: catch -ENODEV from nvme_revalidate_zones again
  2022-07-21  6:03 ` [PATCH 1/6] nvme: catch -ENODEV from nvme_revalidate_zones again Christoph Hellwig
@ 2022-07-21  9:53   ` Joel Granados
  0 siblings, 0 replies; 12+ messages in thread
From: Joel Granados @ 2022-07-21  9:53 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: kbusch, sagi, joshi.k, linux-nvme, gost.dev, k.jensen

[-- Attachment #1: Type: text/plain, Size: 2195 bytes --]

On Thu, Jul 21, 2022 at 08:03:15AM +0200, Christoph Hellwig wrote:
> nvme_revalidate_zones can also return -ENODEV if e.g. zone sizes aren't
> constant or not a power of two.  In that case we should jump to marking
> the gendisk hidden and only support pass through.
> 
> Fixes: 602e57c9799c ("nvme: also mark passthrough-only namespaces ready in nvme_update_ns_info")
> Reported-by: Joel Granados <j.granados@samsung.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  drivers/nvme/host/core.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 698e71680e6f3..2e1af9b5c8a91 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -1940,8 +1940,10 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
>  
>  	if (ns->head->ids.csi == NVME_CSI_ZNS) {
>  		ret = nvme_update_zone_info(ns, lbaf);
> -		if (ret)
> -			goto out_unfreeze;
> +		if (ret) {
> +			blk_mq_unfreeze_queue(ns->disk->queue);
> +			goto out;
> +		}
>  	}
>  
>  	set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) ||
> @@ -1952,7 +1954,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
>  	if (blk_queue_is_zoned(ns->queue)) {
>  		ret = nvme_revalidate_zones(ns);
>  		if (ret && !nvme_first_scan(ns->disk))
> -			return ret;
> +			goto out;
>  	}
>  
>  	if (nvme_ns_head_multipath(ns->head)) {
> @@ -1967,9 +1969,9 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
>  		disk_update_readahead(ns->head->disk);
>  		blk_mq_unfreeze_queue(ns->head->disk->queue);
>  	}
> -	return 0;
>  
> -out_unfreeze:
> +	ret = 0;
> +out:
>  	/*
>  	 * If probing fails due an unsupported feature, hide the block device,
>  	 * but still allow other access.
> @@ -1979,7 +1981,6 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
>  		set_bit(NVME_NS_READY, &ns->flags);
>  		ret = 0;
>  	}
> -	blk_mq_unfreeze_queue(ns->disk->queue);
>  	return ret;
>  }
>  
> -- 
> 2.30.2
> 

LGTM.
Reviewed-by: Joel Granados <j.granados@samsung.com>


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/6] nvme: generalize the nvme_multi_css check in nvme_scan_ns
  2022-07-21  6:03 ` [PATCH 3/6] nvme: generalize the nvme_multi_css check in nvme_scan_ns Christoph Hellwig
@ 2022-07-21  9:54   ` Joel Granados
  0 siblings, 0 replies; 12+ messages in thread
From: Joel Granados @ 2022-07-21  9:54 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: kbusch, sagi, joshi.k, linux-nvme, gost.dev, k.jensen,
	Javier González, Chaitanya Kulkarni

[-- Attachment #1: Type: text/plain, Size: 1728 bytes --]

On Thu, Jul 21, 2022 at 08:03:17AM +0200, Christoph Hellwig wrote:
> Check for multiple command set support early on an error out if is
> not supported when a !NVM command set namespace is found.  This
> prepares for adding command set independent passthrough support.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Javier González <javier.gonz@samsung.com>
> Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
> Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
> Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
> ---
>  drivers/nvme/host/core.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index af3b90ca9131d..5ba09d010daba 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -4295,6 +4295,12 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
>  	if (nvme_identify_ns_descs(ctrl, nsid, &ids))
>  		return;
>  
> +	if (ids.csi != NVME_CSI_NVM && !nvme_multi_css(ctrl)) {
> +		dev_warn(ctrl->device,
> +			"command set not reported for nsid: %d\n", nsid);
> +		return;
> +	}
> +
>  	/*
>  	 * Check if the namespace is ready.  If not ignore it, we will get an
>  	 * AEN once it becomes ready and restart the scan.
> @@ -4326,12 +4332,6 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
>  				nsid);
>  			break;
>  		}
> -		if (!nvme_multi_css(ctrl)) {
> -			dev_warn(ctrl->device,
> -				"command set not reported for nsid: %d\n",
> -				nsid);
> -			break;
> -		}
>  		nvme_alloc_ns(ctrl, nsid, &ids);
>  		break;
>  	default:
> -- 
> 2.30.2
> 
LGTM
Reviewed-by: Joel Granados <j.granados@samsung.com>


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/6] nvme: factor out a nvme_ns_is_readonly helper
  2022-07-21  6:03 ` [PATCH 5/6] nvme: factor out a nvme_ns_is_readonly helper Christoph Hellwig
@ 2022-07-21  9:54   ` Joel Granados
  0 siblings, 0 replies; 12+ messages in thread
From: Joel Granados @ 2022-07-21  9:54 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: kbusch, sagi, joshi.k, linux-nvme, gost.dev, k.jensen,
	Javier González, Chaitanya Kulkarni

[-- Attachment #1: Type: text/plain, Size: 3047 bytes --]

On Thu, Jul 21, 2022 at 08:03:19AM +0200, Christoph Hellwig wrote:
> Add a little helper to check if a namespace should be marked read-only
> that uses a new is_readonly flag in the nvme_ns_info structure.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Javier González <javier.gonz@samsung.com>
> Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
> Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
> Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
> ---
>  drivers/nvme/host/core.c | 15 ++++++++++-----
>  1 file changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 6169737c233b2..271c0de483a9b 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -36,6 +36,7 @@ struct nvme_ns_info {
>  	u32 nsid;
>  	__le32 anagrpid;
>  	bool is_shared;
> +	bool is_readonly;
>  	bool is_ready;
>  };
>  
> @@ -1447,6 +1448,7 @@ static int nvme_ns_info_from_identify(struct nvme_ctrl *ctrl,
>  		return ret;
>  	info->anagrpid = id->anagrpid;
>  	info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
> +	info->is_readonly = id->nsattr & NVME_NS_ATTR_RO;
>  	info->is_ready = true;
>  	if (ctrl->quirks & NVME_QUIRK_BOGUS_NID) {
>  		dev_info(ctrl->device,
> @@ -1482,6 +1484,7 @@ static int nvme_ns_info_from_id_cs_indep(struct nvme_ctrl *ctrl,
>  	if (!ret) {
>  		info->anagrpid = id->anagrpid;
>  		info->is_shared = id->nmic & NVME_NS_NMIC_SHARED;
> +		info->is_readonly = id->nsattr & NVME_NS_ATTR_RO;
>  		info->is_ready = id->nstat & NVME_NSTAT_NRDY;
>  	}
>  	kfree(id);
> @@ -1909,6 +1912,11 @@ static void nvme_update_disk_info(struct gendisk *disk,
>  					   ns->ctrl->max_zeroes_sectors);
>  }
>  
> +static bool nvme_ns_is_readonly(struct nvme_ns *ns, struct nvme_ns_info *info)
> +{
> +	return info->is_readonly || test_bit(NVME_NS_FORCE_RO, &ns->flags);
> +}
> +
>  static inline bool nvme_first_scan(struct gendisk *disk)
>  {
>  	/* nvme_alloc_ns() scans the disk prior to adding it */
> @@ -1974,8 +1982,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
>  		}
>  	}
>  
> -	set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) ||
> -		test_bit(NVME_NS_FORCE_RO, &ns->flags));
> +	set_disk_ro(ns->disk, nvme_ns_is_readonly(ns, info));
>  	set_bit(NVME_NS_READY, &ns->flags);
>  	blk_mq_unfreeze_queue(ns->disk->queue);
>  
> @@ -1988,9 +1995,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
>  	if (nvme_ns_head_multipath(ns->head)) {
>  		blk_mq_freeze_queue(ns->head->disk->queue);
>  		nvme_update_disk_info(ns->head->disk, ns, id);
> -		set_disk_ro(ns->head->disk,
> -			    (id->nsattr & NVME_NS_ATTR_RO) ||
> -				    test_bit(NVME_NS_FORCE_RO, &ns->flags));
> +		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);
> -- 
> 2.30.2
> 

LGTM
Reviewed-by: Joel Granados <j.granados@samsung.com>


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: enable generic interface (/dev/ngX) for unknown command sets v3
  2022-07-21  6:03 enable generic interface (/dev/ngX) for unknown command sets v3 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2022-07-21  6:03 ` [PATCH 6/6] nvme: enable generic interface (/dev/ngXnY) for unknown command sets Christoph Hellwig
@ 2022-07-21 22:17 ` Sagi Grimberg
  6 siblings, 0 replies; 12+ messages in thread
From: Sagi Grimberg @ 2022-07-21 22:17 UTC (permalink / raw)
  To: Christoph Hellwig, Joel Granados, kbusch
  Cc: joshi.k, linux-nvme, gost.dev, k.jensen


> Hi all,
> 
> this is a version of the patch from Joel rebased on a bunch of cleanups
> from me that I think make the layering a lot cleaner.  Let me know what
> everyone things.
> 
> Changes since v2:
>   - add a patch to fix a previous regression in handling of unsupported
>     ZNS configs

Woops, just noticed this one...

Still,
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-07-21 22:17 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-21  6:03 enable generic interface (/dev/ngX) for unknown command sets v3 Christoph Hellwig
2022-07-21  6:03 ` [PATCH 1/6] nvme: catch -ENODEV from nvme_revalidate_zones again Christoph Hellwig
2022-07-21  9:53   ` Joel Granados
2022-07-21  6:03 ` [PATCH 2/6] nvme: rename nvme_validate_or_alloc_ns to nvme_scan_ns Christoph Hellwig
2022-07-21  6:03 ` [PATCH 3/6] nvme: generalize the nvme_multi_css check in nvme_scan_ns Christoph Hellwig
2022-07-21  9:54   ` Joel Granados
2022-07-21  6:03 ` [PATCH 4/6] nvme: refactor namespace probing Christoph Hellwig
2022-07-21  9:36   ` Joel Granados
2022-07-21  6:03 ` [PATCH 5/6] nvme: factor out a nvme_ns_is_readonly helper Christoph Hellwig
2022-07-21  9:54   ` Joel Granados
2022-07-21  6:03 ` [PATCH 6/6] nvme: enable generic interface (/dev/ngXnY) for unknown command sets Christoph Hellwig
2022-07-21 22:17 ` enable generic interface (/dev/ngX) for unknown command sets v3 Sagi Grimberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.