linux-nvme.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] nvmet: configfs code clenaup and fix
@ 2020-04-19 23:52 Chaitanya Kulkarni
  2020-04-19 23:52 ` [PATCH 1/6] nvmet: add generic type-name mapping Chaitanya Kulkarni
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Chaitanya Kulkarni @ 2020-04-19 23:52 UTC (permalink / raw)
  To: linux-nvme; +Cc: sagi, Chaitanya Kulkarni, hch

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 2057 bytes --]

Hi,

Over a period of time, configfs added different attributes and groups.
These groups and attributes have common type to name mapping
functionality with code and identical structures (see [1], [2] & [3]).
Where [1] and [2] adds a different structure which can be made generic
and can be resued by [3].

This patch-series adds a new generic structure for type to name mapping
which then used in the [1], [2] and [3] to align the code for 
consistency with removing the code duplication of
struct nvmet_transport name and struct nvmet_ana_state_names.
We also introduce a pattern with for-loop-compare-success-return with
type name map.

In short we address following points :-

1. Introducing generic type (identifier) to name (string) structure
   nvmet_type_name_map, by removing the private per attribute
   specific structures (nvmet_transport_name & nvmet_ana_state_names)
   for defining the type to name mapping.
2. Keeping the code consistent with the use of for loop and type-name
   struct array iteration instead of the duplicating strings in if/else
   latter and switch.
3. Having consistent coding pattern for type-name
   for-loop-check-success-return so that future introduction(s) of per
   attribute type-name will not add inconsistencies.

Regards,
Chaitanya

[1] struct nvmet_transport_name :- 
commit <a5d18612295a0>("nvmet: refactor configfs transport type handling")
[2] struct nvmet_ana_state_names :- 
commit <62ac0d32f74ea>("nvmet: support configuring ANA groups")
[3] nvmet_addr_adrfam_[store|show] :-
commit <a07b4970f464f>(" nvmet: add a generic NVMe target")

Chaitanya Kulkarni (6):
  nvmet: add generic type-name mapping
  nvmet: use type-name map for address family
  nvmet: use type-name map for ana states
  nvmet: use type-name map for address treq
  nvmet: centralize port enable access for configfs
  nvmet: align addrfam list to spec

 drivers/nvme/target/configfs.c | 225 +++++++++++++++++----------------
 include/linux/nvme.h           |   2 +
 2 files changed, 116 insertions(+), 111 deletions(-)

-- 
2.22.1



[-- Attachment #2: Type: text/plain, Size: 158 bytes --]

_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* [PATCH 1/6] nvmet: add generic type-name mapping
  2020-04-19 23:52 [PATCH 0/6] nvmet: configfs code clenaup and fix Chaitanya Kulkarni
@ 2020-04-19 23:52 ` Chaitanya Kulkarni
  2020-04-19 23:52 ` [PATCH 2/6] nvmet: use type-name map for address family Chaitanya Kulkarni
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Chaitanya Kulkarni @ 2020-04-19 23:52 UTC (permalink / raw)
  To: linux-nvme; +Cc: sagi, Chaitanya Kulkarni, hch

This patch adds a new type to name mapping generic structure. It
replaces nvmet_transport_name with new generic mapping structure
nvmet_transport. This also removes the goto required for the found case
in nvmet_addr_trtype_store() and adds
for-loop-compare-success-return pattern.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 drivers/nvme/target/configfs.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 58cabd7b6fc5..cbe3d7568860 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -20,10 +20,12 @@ static const struct config_item_type nvmet_subsys_type;
 static LIST_HEAD(nvmet_ports_list);
 struct list_head *nvmet_ports = &nvmet_ports_list;
 
-static const struct nvmet_transport_name {
+struct nvmet_type_name_map {
 	u8		type;
 	const char	*name;
-} nvmet_transport_names[] = {
+};
+
+static struct nvmet_type_name_map nvmet_transport[] = {
 	{ NVMF_TRTYPE_RDMA,	"rdma" },
 	{ NVMF_TRTYPE_FC,	"fc" },
 	{ NVMF_TRTYPE_TCP,	"tcp" },
@@ -254,10 +256,9 @@ static ssize_t nvmet_addr_trtype_show(struct config_item *item,
 	struct nvmet_port *port = to_nvmet_port(item);
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
-		if (port->disc_addr.trtype != nvmet_transport_names[i].type)
-			continue;
-		return sprintf(page, "%s\n", nvmet_transport_names[i].name);
+	for (i = 0; i < ARRAY_SIZE(nvmet_transport); i++) {
+		if (port->disc_addr.trtype == nvmet_transport[i].type)
+			return sprintf(page, "%s\n", nvmet_transport[i].name);
 	}
 
 	return sprintf(page, "\n");
@@ -282,19 +283,18 @@ static ssize_t nvmet_addr_trtype_store(struct config_item *item,
 		return -EACCES;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(nvmet_transport_names); i++) {
-		if (sysfs_streq(page, nvmet_transport_names[i].name))
-			goto found;
+	for (i = 0; i < ARRAY_SIZE(nvmet_transport); i++) {
+		if (sysfs_streq(page, nvmet_transport[i].name)) {
+			memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
+			port->disc_addr.trtype = nvmet_transport[i].type;
+			if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
+				nvmet_port_init_tsas_rdma(port);
+			return count;
+		}
 	}
 
 	pr_err("Invalid value '%s' for trtype\n", page);
 	return -EINVAL;
-found:
-	memset(&port->disc_addr.tsas, 0, NVMF_TSAS_SIZE);
-	port->disc_addr.trtype = nvmet_transport_names[i].type;
-	if (port->disc_addr.trtype == NVMF_TRTYPE_RDMA)
-		nvmet_port_init_tsas_rdma(port);
-	return count;
 }
 
 CONFIGFS_ATTR(nvmet_, addr_trtype);
-- 
2.22.1


_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* [PATCH 2/6] nvmet: use type-name map for address family
  2020-04-19 23:52 [PATCH 0/6] nvmet: configfs code clenaup and fix Chaitanya Kulkarni
  2020-04-19 23:52 ` [PATCH 1/6] nvmet: add generic type-name mapping Chaitanya Kulkarni
@ 2020-04-19 23:52 ` Chaitanya Kulkarni
  2020-04-19 23:52 ` [PATCH 3/6] nvmet: use type-name map for ana states Chaitanya Kulkarni
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Chaitanya Kulkarni @ 2020-04-19 23:52 UTC (permalink / raw)
  To: linux-nvme; +Cc: sagi, Chaitanya Kulkarni, hch

Currently nvmet_addr_adrfam_[store|show]() uses switch and if else
ladder for address family to string and reverse mapping which also
repeats the strings in show and store function.

With addtion of generic nvmet_type_name_map structure we can now
get rid of the switch and if else ladder and use ans string duplication
and use for-loop-compare-success-return pattern similar to previous
patch.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 drivers/nvme/target/configfs.c | 50 +++++++++++++++++-----------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index cbe3d7568860..67e8d53c714d 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -32,31 +32,36 @@ static struct nvmet_type_name_map nvmet_transport[] = {
 	{ NVMF_TRTYPE_LOOP,	"loop" },
 };
 
+static const struct nvmet_type_name_map nvmet_addr_family[] = {
+	{ NVMF_ADDR_FAMILY_PCI,	"pcie" },
+	{ NVMF_ADDR_FAMILY_IP4,	"ipv4" },
+	{ NVMF_ADDR_FAMILY_IP6,	"ipv6" },
+	{ NVMF_ADDR_FAMILY_IB,	"ib" },
+	{ NVMF_ADDR_FAMILY_FC,	"fc" },
+};
+
 /*
  * nvmet_port Generic ConfigFS definitions.
  * Used in any place in the ConfigFS tree that refers to an address.
  */
-static ssize_t nvmet_addr_adrfam_show(struct config_item *item,
-		char *page)
+static ssize_t nvmet_addr_adrfam_show(struct config_item *item, char *page)
 {
-	switch (to_nvmet_port(item)->disc_addr.adrfam) {
-	case NVMF_ADDR_FAMILY_IP4:
-		return sprintf(page, "ipv4\n");
-	case NVMF_ADDR_FAMILY_IP6:
-		return sprintf(page, "ipv6\n");
-	case NVMF_ADDR_FAMILY_IB:
-		return sprintf(page, "ib\n");
-	case NVMF_ADDR_FAMILY_FC:
-		return sprintf(page, "fc\n");
-	default:
-		return sprintf(page, "\n");
+	u8 adrfam = to_nvmet_port(item)->disc_addr.adrfam;
+	int i;
+
+	for (i = 1; i < ARRAY_SIZE(nvmet_addr_family); i++) {
+		if (nvmet_addr_family[i].type == adrfam)
+			return sprintf(page, "%s\n", nvmet_addr_family[i].name);
 	}
+
+	return sprintf(page, "\n");
 }
 
 static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
 		const char *page, size_t count)
 {
 	struct nvmet_port *port = to_nvmet_port(item);
+	int i;
 
 	if (port->enabled) {
 		pr_err("Cannot modify address while enabled\n");
@@ -64,20 +69,15 @@ static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
 		return -EACCES;
 	}
 
-	if (sysfs_streq(page, "ipv4")) {
-		port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP4;
-	} else if (sysfs_streq(page, "ipv6")) {
-		port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IP6;
-	} else if (sysfs_streq(page, "ib")) {
-		port->disc_addr.adrfam = NVMF_ADDR_FAMILY_IB;
-	} else if (sysfs_streq(page, "fc")) {
-		port->disc_addr.adrfam = NVMF_ADDR_FAMILY_FC;
-	} else {
-		pr_err("Invalid value '%s' for adrfam\n", page);
-		return -EINVAL;
+	for (i = 1; i < ARRAY_SIZE(nvmet_addr_family); i++) {
+		if (sysfs_streq(page, nvmet_addr_family[i].name)) {
+			port->disc_addr.adrfam = i;
+			return count;
+		}
 	}
 
-	return count;
+	pr_err("Invalid value '%s' for adrfam\n", page);
+	return -EINVAL;
 }
 
 CONFIGFS_ATTR(nvmet_, addr_adrfam);
-- 
2.22.1


_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* [PATCH 3/6] nvmet: use type-name map for ana states
  2020-04-19 23:52 [PATCH 0/6] nvmet: configfs code clenaup and fix Chaitanya Kulkarni
  2020-04-19 23:52 ` [PATCH 1/6] nvmet: add generic type-name mapping Chaitanya Kulkarni
  2020-04-19 23:52 ` [PATCH 2/6] nvmet: use type-name map for address family Chaitanya Kulkarni
@ 2020-04-19 23:52 ` Chaitanya Kulkarni
  2020-04-22  8:31   ` Christoph Hellwig
  2020-04-19 23:52 ` [PATCH 4/6] nvmet: use type-name map for address treq Chaitanya Kulkarni
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 10+ messages in thread
From: Chaitanya Kulkarni @ 2020-04-19 23:52 UTC (permalink / raw)
  To: linux-nvme; +Cc: sagi, Chaitanya Kulkarni, hch

Now that we have a generic type to name map for configfs, get rid of
the nvmet_ana_state_names structure and replace it with
nvmet_type_name_map. This also now allows us to get rid of the found
goto label which exists in current code and align code with
for-loop-compare-success-return pattern.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 drivers/nvme/target/configfs.c | 37 ++++++++++++++++------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 67e8d53c714d..bb0810f28541 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -1149,10 +1149,7 @@ static const struct config_item_type nvmet_referrals_type = {
 	.ct_group_ops	= &nvmet_referral_group_ops,
 };
 
-static struct {
-	enum nvme_ana_state	state;
-	const char		*name;
-} nvmet_ana_state_names[] = {
+struct nvmet_type_name_map nvmet_ana_state[] = {
 	{ NVME_ANA_OPTIMIZED,		"optimized" },
 	{ NVME_ANA_NONOPTIMIZED,	"non-optimized" },
 	{ NVME_ANA_INACCESSIBLE,	"inaccessible" },
@@ -1167,10 +1164,9 @@ static ssize_t nvmet_ana_group_ana_state_show(struct config_item *item,
 	enum nvme_ana_state state = grp->port->ana_state[grp->grpid];
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(nvmet_ana_state_names); i++) {
-		if (state != nvmet_ana_state_names[i].state)
-			continue;
-		return sprintf(page, "%s\n", nvmet_ana_state_names[i].name);
+	for (i = 0; i < ARRAY_SIZE(nvmet_ana_state); i++) {
+		if (state == nvmet_ana_state[i].type)
+			return sprintf(page, "%s\n", nvmet_ana_state[i].name);
 	}
 
 	return sprintf(page, "\n");
@@ -1180,24 +1176,25 @@ static ssize_t nvmet_ana_group_ana_state_store(struct config_item *item,
 		const char *page, size_t count)
 {
 	struct nvmet_ana_group *grp = to_ana_group(item);
+	enum nvme_ana_state *ana_state = grp->port->ana_state;
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(nvmet_ana_state_names); i++) {
-		if (sysfs_streq(page, nvmet_ana_state_names[i].name))
-			goto found;
+	for (i = 0; i < ARRAY_SIZE(nvmet_ana_state); i++) {
+		if (sysfs_streq(page, nvmet_ana_state[i].name)) {
+			u8 state = nvmet_ana_state[i].type;
+
+			down_write(&nvmet_ana_sem);
+			/* makes static type checker happy */
+			ana_state[grp->grpid] = (enum nvme_ana_state) state;
+			nvmet_ana_chgcnt++;
+			up_write(&nvmet_ana_sem);
+			nvmet_port_send_ana_event(grp->port);
+			return count;
+		}
 	}
 
 	pr_err("Invalid value '%s' for ana_state\n", page);
 	return -EINVAL;
-
-found:
-	down_write(&nvmet_ana_sem);
-	grp->port->ana_state[grp->grpid] = nvmet_ana_state_names[i].state;
-	nvmet_ana_chgcnt++;
-	up_write(&nvmet_ana_sem);
-
-	nvmet_port_send_ana_event(grp->port);
-	return count;
 }
 
 CONFIGFS_ATTR(nvmet_ana_group_, ana_state);
-- 
2.22.1


_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* [PATCH 4/6] nvmet: use type-name map for address treq
  2020-04-19 23:52 [PATCH 0/6] nvmet: configfs code clenaup and fix Chaitanya Kulkarni
                   ` (2 preceding siblings ...)
  2020-04-19 23:52 ` [PATCH 3/6] nvmet: use type-name map for ana states Chaitanya Kulkarni
@ 2020-04-19 23:52 ` Chaitanya Kulkarni
  2020-04-19 23:52 ` [PATCH 5/6] nvmet: centralize port enable access for configfs Chaitanya Kulkarni
  2020-04-19 23:52 ` [PATCH 6/6] nvmet: align addrfam list to spec Chaitanya Kulkarni
  5 siblings, 0 replies; 10+ messages in thread
From: Chaitanya Kulkarni @ 2020-04-19 23:52 UTC (permalink / raw)
  To: linux-nvme; +Cc: sagi, Chaitanya Kulkarni, hch

Currently nvmet_addr_treq_[store|show]() uses switch and if else
ladder for address transport requirements to string and reverse
mapping. With addtion of the generic nvmet_type_name_map structure
we can get rid of the switch and if else ladder with string duplication
and use for-loop-compare-success-return pattern which aligns with the
existing code.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 drivers/nvme/target/configfs.c | 48 ++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index bb0810f28541..883348f7699a 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -145,20 +145,24 @@ static ssize_t nvmet_addr_traddr_store(struct config_item *item,
 
 CONFIGFS_ATTR(nvmet_, addr_traddr);
 
-static ssize_t nvmet_addr_treq_show(struct config_item *item,
-		char *page)
+static const struct nvmet_type_name_map nvmet_addr_treq[] = {
+	{ NVMF_TREQ_NOT_SPECIFIED,	"not specified" },
+	{ NVMF_TREQ_REQUIRED,		"required" },
+	{ NVMF_TREQ_NOT_REQUIRED,	"not required" },
+};
+
+static ssize_t nvmet_addr_treq_show(struct config_item *item, char *page)
 {
-	switch (to_nvmet_port(item)->disc_addr.treq &
-		NVME_TREQ_SECURE_CHANNEL_MASK) {
-	case NVMF_TREQ_NOT_SPECIFIED:
-		return sprintf(page, "not specified\n");
-	case NVMF_TREQ_REQUIRED:
-		return sprintf(page, "required\n");
-	case NVMF_TREQ_NOT_REQUIRED:
-		return sprintf(page, "not required\n");
-	default:
-		return sprintf(page, "\n");
+	u8 treq = to_nvmet_port(item)->disc_addr.treq &
+		NVME_TREQ_SECURE_CHANNEL_MASK;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(nvmet_addr_treq); i++) {
+		if (treq == nvmet_addr_treq[i].type)
+			return sprintf(page, "%s\n", nvmet_addr_treq[i].name);
 	}
+
+	return sprintf(page, "\n");
 }
 
 static ssize_t nvmet_addr_treq_store(struct config_item *item,
@@ -166,6 +170,7 @@ static ssize_t nvmet_addr_treq_store(struct config_item *item,
 {
 	struct nvmet_port *port = to_nvmet_port(item);
 	u8 treq = port->disc_addr.treq & ~NVME_TREQ_SECURE_CHANNEL_MASK;
+	int i;
 
 	if (port->enabled) {
 		pr_err("Cannot modify address while enabled\n");
@@ -173,19 +178,16 @@ static ssize_t nvmet_addr_treq_store(struct config_item *item,
 		return -EACCES;
 	}
 
-	if (sysfs_streq(page, "not specified")) {
-		treq |= NVMF_TREQ_NOT_SPECIFIED;
-	} else if (sysfs_streq(page, "required")) {
-		treq |= NVMF_TREQ_REQUIRED;
-	} else if (sysfs_streq(page, "not required")) {
-		treq |= NVMF_TREQ_NOT_REQUIRED;
-	} else {
-		pr_err("Invalid value '%s' for treq\n", page);
-		return -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(nvmet_addr_treq); i++) {
+		if (sysfs_streq(page, nvmet_addr_treq[i].name)) {
+			treq |= nvmet_addr_treq[i].type;
+			port->disc_addr.treq = treq;
+			return count;
+		}
 	}
-	port->disc_addr.treq = treq;
 
-	return count;
+	pr_err("Invalid value '%s' for treq\n", page);
+	return -EINVAL;
 }
 
 CONFIGFS_ATTR(nvmet_, addr_treq);
-- 
2.22.1


_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* [PATCH 5/6] nvmet: centralize port enable access for configfs
  2020-04-19 23:52 [PATCH 0/6] nvmet: configfs code clenaup and fix Chaitanya Kulkarni
                   ` (3 preceding siblings ...)
  2020-04-19 23:52 ` [PATCH 4/6] nvmet: use type-name map for address treq Chaitanya Kulkarni
@ 2020-04-19 23:52 ` Chaitanya Kulkarni
  2020-04-22  8:32   ` Christoph Hellwig
  2020-04-19 23:52 ` [PATCH 6/6] nvmet: align addrfam list to spec Chaitanya Kulkarni
  5 siblings, 1 reply; 10+ messages in thread
From: Chaitanya Kulkarni @ 2020-04-19 23:52 UTC (permalink / raw)
  To: linux-nvme; +Cc: sagi, Chaitanya Kulkarni, hch

The configfs attributes which are supposed to set when port is disable
such as addr[addrfam|portid|traddr|treq|trsvcid|inline_data_size|trtype]
has repetitive check and generic error message printing.

This patch creates centralize helper to check and print an error
message that also accepts caller as a parameter with added
locking. This makes error message easy to parse for the user, removes
the duplicate code, uses appropriate locks and makes it available for
futures such scenarios.

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 drivers/nvme/target/configfs.c | 58 ++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 28 deletions(-)

diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 883348f7699a..80a7b669b581 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -40,6 +40,29 @@ static const struct nvmet_type_name_map nvmet_addr_family[] = {
 	{ NVMF_ADDR_FAMILY_FC,	"fc" },
 };
 
+static bool nvmet_is_port_enabled(struct nvmet_port *p, const char *caller)
+{
+	bool enabled;
+
+	/*
+	 * Right now port->enabled is accessed in follwoing two code paths
+	 * which are protected by the nvmet_config_sem :-
+	 * 1. nvmet_subsys allow/drop link() -> nvmet_port_enable/disable()
+	 *    setting port->enabled true/false respectively.
+	 * 2. nvmet_referral_enable/disable() -> nvmet_port_enable/disable()
+	 *    setting port->enabled true/false respectively.
+	 * Use read nvmet_config_sem when reading enable condition.
+	 */
+	down_read(&nvmet_config_sem);
+	enabled = p->enabled;
+	up_read(&nvmet_config_sem);
+
+	if (enabled)
+		pr_err("Disable port '%u' before changing attribute in %s\n",
+				le16_to_cpu(p->disc_addr.portid), caller);
+	return enabled;
+}
+
 /*
  * nvmet_port Generic ConfigFS definitions.
  * Used in any place in the ConfigFS tree that refers to an address.
@@ -63,11 +86,8 @@ static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
 	struct nvmet_port *port = to_nvmet_port(item);
 	int i;
 
-	if (port->enabled) {
-		pr_err("Cannot modify address while enabled\n");
-		pr_err("Disable the address before modifying\n");
+	if (nvmet_is_port_enabled(port, __func__))
 		return -EACCES;
-	}
 
 	for (i = 1; i < ARRAY_SIZE(nvmet_addr_family); i++) {
 		if (sysfs_streq(page, nvmet_addr_family[i].name)) {
@@ -102,11 +122,8 @@ static ssize_t nvmet_addr_portid_store(struct config_item *item,
 		return -EINVAL;
 	}
 
-	if (port->enabled) {
-		pr_err("Cannot modify address while enabled\n");
-		pr_err("Disable the address before modifying\n");
+	if (nvmet_is_port_enabled(port, __func__))
 		return -EACCES;
-	}
 	port->disc_addr.portid = cpu_to_le16(portid);
 	return count;
 }
@@ -132,11 +149,8 @@ static ssize_t nvmet_addr_traddr_store(struct config_item *item,
 		return -EINVAL;
 	}
 
-	if (port->enabled) {
-		pr_err("Cannot modify address while enabled\n");
-		pr_err("Disable the address before modifying\n");
+	if (nvmet_is_port_enabled(port, __func__))
 		return -EACCES;
-	}
 
 	if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1)
 		return -EINVAL;
@@ -172,11 +186,8 @@ static ssize_t nvmet_addr_treq_store(struct config_item *item,
 	u8 treq = port->disc_addr.treq & ~NVME_TREQ_SECURE_CHANNEL_MASK;
 	int i;
 
-	if (port->enabled) {
-		pr_err("Cannot modify address while enabled\n");
-		pr_err("Disable the address before modifying\n");
+	if (nvmet_is_port_enabled(port, __func__))
 		return -EACCES;
-	}
 
 	for (i = 0; i < ARRAY_SIZE(nvmet_addr_treq); i++) {
 		if (sysfs_streq(page, nvmet_addr_treq[i].name)) {
@@ -210,11 +221,8 @@ static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
 		pr_err("Invalid value '%s' for trsvcid\n", page);
 		return -EINVAL;
 	}
-	if (port->enabled) {
-		pr_err("Cannot modify address while enabled\n");
-		pr_err("Disable the address before modifying\n");
+	if (nvmet_is_port_enabled(port, __func__))
 		return -EACCES;
-	}
 
 	if (sscanf(page, "%s\n", port->disc_addr.trsvcid) != 1)
 		return -EINVAL;
@@ -237,11 +245,8 @@ static ssize_t nvmet_param_inline_data_size_store(struct config_item *item,
 	struct nvmet_port *port = to_nvmet_port(item);
 	int ret;
 
-	if (port->enabled) {
-		pr_err("Cannot modify inline_data_size while port enabled\n");
-		pr_err("Disable the port before modifying\n");
+	if (nvmet_is_port_enabled(port, __func__))
 		return -EACCES;
-	}
 	ret = kstrtoint(page, 0, &port->inline_data_size);
 	if (ret) {
 		pr_err("Invalid value '%s' for inline_data_size\n", page);
@@ -279,11 +284,8 @@ static ssize_t nvmet_addr_trtype_store(struct config_item *item,
 	struct nvmet_port *port = to_nvmet_port(item);
 	int i;
 
-	if (port->enabled) {
-		pr_err("Cannot modify address while enabled\n");
-		pr_err("Disable the address before modifying\n");
+	if (nvmet_is_port_enabled(port, __func__))
 		return -EACCES;
-	}
 
 	for (i = 0; i < ARRAY_SIZE(nvmet_transport); i++) {
 		if (sysfs_streq(page, nvmet_transport[i].name)) {
-- 
2.22.1


_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* [PATCH 6/6] nvmet: align addrfam list to spec
  2020-04-19 23:52 [PATCH 0/6] nvmet: configfs code clenaup and fix Chaitanya Kulkarni
                   ` (4 preceding siblings ...)
  2020-04-19 23:52 ` [PATCH 5/6] nvmet: centralize port enable access for configfs Chaitanya Kulkarni
@ 2020-04-19 23:52 ` Chaitanya Kulkarni
  5 siblings, 0 replies; 10+ messages in thread
From: Chaitanya Kulkarni @ 2020-04-19 23:52 UTC (permalink / raw)
  To: linux-nvme; +Cc: sagi, Chaitanya Kulkarni, hch

With reference to the NVMeOF Specification (page 44, Figure 38)
discovery log page entry provides address family field. We do set the
transport type field but the adrfam field is not set when using loop
transport and also it doesn't have support in the nvme-cli. So when
reading discovery log page with a loop transport it leads to confusing
output.

As per the spec for adrfam value 254 is reserved for Intra Host
Transport i.e. loopback), we add a required macro in the protocol
header file, set default port disc addr entry's adrfam to
NVMF_ADDR_FAMILY_MAX, and update nvmet_addr_family configfs array for
show/store attribute.

Without this patch, setting adrfam to (ipv4/ipv6/ib/fc/loop/" ") we get
following output for nvme discover command from nvme-cli which is
confusing.
#grep -e adrfam -e trtype without_adrfam_loop_patch.log
trtype:  loop
adrfam:  ipv4
trtype:  loop
adrfam:  ipv6
trtype:  loop
adrfam:  infiniband
trtype:  loop
adrfam:  fibre-channel
trtype:  loop		# ${CFGFS_HOME}/nvmet/ports/1/addr_adrfam = loop
adrfam:  pci            # <----- pci for loop
trtype:  loop		# ${CFGFS_HOME}/nvmet/ports/1/addr_adrfam = " "
adrfam:  pci            # <----- pci for unrecognized

This patch fixes above output :-
# grep -e adrfam -e trtype with_adrfam_loop_patch.log
trtype:  loop
adrfam:  ipv4
trtype:  loop
adrfam:  ipv6
trtype:  loop
adrfam:  infiniband
trtype:  loop
adrfam:  fibre-channel
trtype:  loop           # ${CFGFS_HOME}/nvmet/ports/1/addr_adrfam = loop
adrfam:  loop           # <----- loop for loop
trtype:  loop		# ${CFGFS_HOME}/config/nvmet/ports/adrfam = " "
adrfam:  unrecognized   # <----- unrecognized when invalid value

Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
 drivers/nvme/target/configfs.c | 14 ++++++++------
 include/linux/nvme.h           |  2 ++
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 80a7b669b581..42486f86787a 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -33,11 +33,12 @@ static struct nvmet_type_name_map nvmet_transport[] = {
 };
 
 static const struct nvmet_type_name_map nvmet_addr_family[] = {
-	{ NVMF_ADDR_FAMILY_PCI,	"pcie" },
-	{ NVMF_ADDR_FAMILY_IP4,	"ipv4" },
-	{ NVMF_ADDR_FAMILY_IP6,	"ipv6" },
-	{ NVMF_ADDR_FAMILY_IB,	"ib" },
-	{ NVMF_ADDR_FAMILY_FC,	"fc" },
+	{ NVMF_ADDR_FAMILY_PCI,		"pcie" },
+	{ NVMF_ADDR_FAMILY_IP4,		"ipv4" },
+	{ NVMF_ADDR_FAMILY_IP6,		"ipv6" },
+	{ NVMF_ADDR_FAMILY_IB,		"ib" },
+	{ NVMF_ADDR_FAMILY_FC,		"fc" },
+	{ NVMF_ADDR_FAMILY_LOOP,	"loop" },
 };
 
 static bool nvmet_is_port_enabled(struct nvmet_port *p, const char *caller)
@@ -91,7 +92,7 @@ static ssize_t nvmet_addr_adrfam_store(struct config_item *item,
 
 	for (i = 1; i < ARRAY_SIZE(nvmet_addr_family); i++) {
 		if (sysfs_streq(page, nvmet_addr_family[i].name)) {
-			port->disc_addr.adrfam = i;
+			port->disc_addr.adrfam = nvmet_addr_family[i].type;
 			return count;
 		}
 	}
@@ -1347,6 +1348,7 @@ static struct config_group *nvmet_ports_make(struct config_group *group,
 	port->inline_data_size = -1;	/* < 0 == let the transport choose */
 
 	port->disc_addr.portid = cpu_to_le16(portid);
+	port->disc_addr.adrfam = NVMF_ADDR_FAMILY_MAX;
 	port->disc_addr.treq = NVMF_TREQ_DISABLE_SQFLOW;
 	config_group_init_type_name(&port->group, name, &nvmet_port_type);
 
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index 3d5189f46cb1..2d978d0cbde6 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -38,6 +38,8 @@ enum {
 	NVMF_ADDR_FAMILY_IP6	= 2,	/* IP6 */
 	NVMF_ADDR_FAMILY_IB	= 3,	/* InfiniBand */
 	NVMF_ADDR_FAMILY_FC	= 4,	/* Fibre Channel */
+	NVMF_ADDR_FAMILY_LOOP	= 254,	/* Reserved for host usage */
+	NVMF_ADDR_FAMILY_MAX,
 };
 
 /* Transport Type codes for Discovery Log Page entry TRTYPE field */
-- 
2.22.1


_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* Re: [PATCH 3/6] nvmet: use type-name map for ana states
  2020-04-19 23:52 ` [PATCH 3/6] nvmet: use type-name map for ana states Chaitanya Kulkarni
@ 2020-04-22  8:31   ` Christoph Hellwig
  0 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2020-04-22  8:31 UTC (permalink / raw)
  To: Chaitanya Kulkarni; +Cc: sagi, linux-nvme, hch

On Sun, Apr 19, 2020 at 04:52:39PM -0700, Chaitanya Kulkarni wrote:
> Now that we have a generic type to name map for configfs, get rid of
> the nvmet_ana_state_names structure and replace it with
> nvmet_type_name_map. This also now allows us to get rid of the found
> goto label which exists in current code and align code with
> for-loop-compare-success-return pattern.

I actually much prefer the goto that keeps the success path out
of deep indentation.  Same for the other patch that does the same
move.

_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* Re: [PATCH 5/6] nvmet: centralize port enable access for configfs
  2020-04-19 23:52 ` [PATCH 5/6] nvmet: centralize port enable access for configfs Chaitanya Kulkarni
@ 2020-04-22  8:32   ` Christoph Hellwig
  2020-04-23  6:07     ` Chaitanya Kulkarni
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2020-04-22  8:32 UTC (permalink / raw)
  To: Chaitanya Kulkarni; +Cc: sagi, linux-nvme, hch

> +static bool nvmet_is_port_enabled(struct nvmet_port *p, const char *caller)
> +{
> +	bool enabled;
> +
> +	/*
> +	 * Right now port->enabled is accessed in follwoing two code paths
> +	 * which are protected by the nvmet_config_sem :-
> +	 * 1. nvmet_subsys allow/drop link() -> nvmet_port_enable/disable()
> +	 *    setting port->enabled true/false respectively.
> +	 * 2. nvmet_referral_enable/disable() -> nvmet_port_enable/disable()
> +	 *    setting port->enabled true/false respectively.
> +	 * Use read nvmet_config_sem when reading enable condition.
> +	 */
> +	down_read(&nvmet_config_sem);
> +	enabled = p->enabled;
> +	up_read(&nvmet_config_sem);

Taking a lock around checking a single scalar value is rather pointless.

_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

* Re: [PATCH 5/6] nvmet: centralize port enable access for configfs
  2020-04-22  8:32   ` Christoph Hellwig
@ 2020-04-23  6:07     ` Chaitanya Kulkarni
  0 siblings, 0 replies; 10+ messages in thread
From: Chaitanya Kulkarni @ 2020-04-23  6:07 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: sagi, linux-nvme

On 4/22/20 1:32 AM, Christoph Hellwig wrote:
> Taking a lock around checking a single scalar value is rather pointless.

Thanks for the comments, will remove this is V2.


_______________________________________________
linux-nvme mailing list
linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

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

end of thread, other threads:[~2020-04-23  6:07 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-19 23:52 [PATCH 0/6] nvmet: configfs code clenaup and fix Chaitanya Kulkarni
2020-04-19 23:52 ` [PATCH 1/6] nvmet: add generic type-name mapping Chaitanya Kulkarni
2020-04-19 23:52 ` [PATCH 2/6] nvmet: use type-name map for address family Chaitanya Kulkarni
2020-04-19 23:52 ` [PATCH 3/6] nvmet: use type-name map for ana states Chaitanya Kulkarni
2020-04-22  8:31   ` Christoph Hellwig
2020-04-19 23:52 ` [PATCH 4/6] nvmet: use type-name map for address treq Chaitanya Kulkarni
2020-04-19 23:52 ` [PATCH 5/6] nvmet: centralize port enable access for configfs Chaitanya Kulkarni
2020-04-22  8:32   ` Christoph Hellwig
2020-04-23  6:07     ` Chaitanya Kulkarni
2020-04-19 23:52 ` [PATCH 6/6] nvmet: align addrfam list to spec Chaitanya Kulkarni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).