nvdimm.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation
@ 2019-07-27 21:39 Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 01/26] ndctl/dimm: Add 'flags' field to read-labels output Dan Williams
                   ` (25 more replies)
  0 siblings, 26 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:39 UTC (permalink / raw)
  To: linux-nvdimm

Changes since v1 [1]:
- Fix up the --human option for 'read-labels' and 'read-infoblock' to
  imply --json (Vishal)

- Add a man page for 'read-infoblock' and update 'read-labels' man page.
  (Vishal)

[1]: https://lists.01.org/pipermail/linux-nvdimm/2019-February/019916.html

---

What follows is random assortment of ndctl improvements that have been
hiding out in my private tree. There was a v1 "[ndctl PATCH 0/8]
Improve support + testing for labels + info-blocks " back in February,
but the patch kit has tripled in size since then. There was also a major
change in direction on improving the situation around 'section
collision' handling. Rather than more local libnvdimm hacks the problem
was solved at the source in the memory hotplug code with 'sub-section
memory hotplug' support merged for v5.3-rc1. That results in the
previous patch "ndctl/test: Test inter-region collision handling " being
abandoned in favor of "ndctl/test: Exercise sub-section sized namespace
creation/deletion".

In the course of developing that test and addressing Jane's concerns
with ndctl create-namespace behavior, a few more fixups relative to
minimum namespace size are also included.

Other miscellaneous items included in this set:

- A device-mapper unit test to catch simple device-mapper support
  regressions.
- A simple fixup to the monitor to allow it to be suspended (Ctrl+Z)


Given the size and random topics I am open to merging these piecemeal,
or out of order if something needs to be deferred for more fixups.

---

Dan Williams (26):
      ndctl/dimm: Add 'flags' field to read-labels output
      ndctl/dimm: Add --human support to read-labels
      ndctl/build: Drop -Wpointer-arith
      ndctl/namespace: Add read-infoblock command
      ndctl/test: Update dax-dev to handle multiple e820 ranges
      ndctl/test: Make dax.sh more robust vs small namespaces
      ndctl/namespace: Always zero info-blocks
      ndctl/dimm: Support small label reads/writes
      ndctl/dimm: Minimize data-transfer for init-labels
      ndctl/dimm: Add offset and size options to {read,write,zero}-labels
      ndctl/dimm: Limit read-labels with --index option
      ndctl/namespace: Minimize label data transfer for autolabel
      ndctl/namespace: Disable autorecovery of create-namespace failures
      ndctl/namespace: Handle 'create-namespace' in label-less mode
      ndctl/dimm: Fix init-labels success reporting
      ndctl/test: Fix device-dax bus-model detection
      ndctl/test: Checkout device-mapper + dax operation
      ndctl/test: Exercise sub-section sized namespace creation/deletion
      ndctl/namespace: Kill off the legacy mode names
      ndctl/namespace: Introduce mode-to-name and name-to-mode helpers
      ndctl/namespace: Validate namespace size within validate_namespace_options()
      ndctl/namespace: Clarify 16M minimum size requirement
      ndctl/namespace: Report ENOSPC when regions are full
      ndctl/test: Regression test 'failed to track'
      ndctl/namespace: Continue region search on 'missing seed' event
      ndctl/monitor: Allow monitor to be manually moved to the background


 Documentation/ndctl/Makefile.am                |    3 
 Documentation/ndctl/labels-options.txt         |    9 
 Documentation/ndctl/ndctl-create-namespace.txt |    9 
 Documentation/ndctl/ndctl-read-infoblock.txt   |   94 ++++
 Documentation/ndctl/ndctl-read-labels.txt      |    7 
 configure.ac                                   |    1 
 ndctl/action.h                                 |    1 
 ndctl/builtin.h                                |    1 
 ndctl/check.c                                  |   20 -
 ndctl/dimm.c                                   |  111 +++-
 ndctl/lib/dimm.c                               |   85 +++
 ndctl/lib/libndctl.c                           |  111 ++++
 ndctl/lib/libndctl.sym                         |    5 
 ndctl/lib/private.h                            |    4 
 ndctl/libndctl.h                               |   10 
 ndctl/monitor.c                                |    4 
 ndctl/namespace.c                              |  600 ++++++++++++++++++++----
 ndctl/namespace.h                              |   51 ++
 ndctl/ndctl.c                                  |    1 
 test/Makefile.am                               |    5 
 test/core.c                                    |   10 
 test/dax-dev.c                                 |   17 +
 test/dax.sh                                    |    4 
 test/dm.sh                                     |   75 +++
 test/libndctl.c                                |    6 
 test/sub-section.sh                            |   78 +++
 test/track-uuid.sh                             |   41 ++
 util/filter.c                                  |   46 +-
 util/filter.h                                  |    3 
 util/fletcher.h                                |    1 
 util/json.c                                    |    4 
 util/size.h                                    |    1 
 util/util.h                                    |    4 
 33 files changed, 1221 insertions(+), 201 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-read-infoblock.txt
 create mode 100755 test/dm.sh
 create mode 100755 test/sub-section.sh
 create mode 100755 test/track-uuid.sh
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 01/26] ndctl/dimm: Add 'flags' field to read-labels output
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
@ 2019-07-27 21:39 ` Dan Williams
  2019-08-02 18:01   ` Verma, Vishal L
  2019-07-27 21:39 ` [ndctl PATCH v2 02/26] ndctl/dimm: Add --human support to read-labels Dan Williams
                   ` (24 subsequent siblings)
  25 siblings, 1 reply; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:39 UTC (permalink / raw)
  To: linux-nvdimm

Recent discussions on some platform implementations setting the LOCAL
bit in namespace labels makes it apparent that this field should be
decoded in the json representation.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/dimm.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index b2b09b6aa9a2..8946dc74fe41 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -141,6 +141,11 @@ static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
 			break;
 		json_object_object_add(jlabel, "nlabel", jobj);
 
+		jobj = json_object_new_int64(le64_to_cpu(nslabel.flags));
+		if (!jobj)
+			break;
+		json_object_object_add(jlabel, "flags", jobj);
+
 		jobj = json_object_new_int64(le64_to_cpu(nslabel.isetcookie));
 		if (!jobj)
 			break;

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 02/26] ndctl/dimm: Add --human support to read-labels
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 01/26] ndctl/dimm: Add 'flags' field to read-labels output Dan Williams
@ 2019-07-27 21:39 ` Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 03/26] ndctl/build: Drop -Wpointer-arith Dan Williams
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:39 UTC (permalink / raw)
  To: linux-nvdimm

Allow for easier comparisons between 'read-labels' output and list.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/ndctl/ndctl-read-labels.txt |    7 +++++++
 ndctl/dimm.c                              |   20 ++++++++++++--------
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/Documentation/ndctl/ndctl-read-labels.txt b/Documentation/ndctl/ndctl-read-labels.txt
index 0127e15f0721..756713ee12d7 100644
--- a/Documentation/ndctl/ndctl-read-labels.txt
+++ b/Documentation/ndctl/ndctl-read-labels.txt
@@ -27,6 +27,13 @@ include::labels-options.txt[]
 	parse the label data into json assuming the 'NVDIMM Namespace
 	Specification' format.
 
+-u::
+--human::
+	enable json output and convert number formats to human readable
+	strings, for example show the size in terms of "KB", "MB", "GB", etc
+	instead of a signed 64-bit numbers per the JSON interchange
+	format (implies --json).
+
 include::../copyright.txt[]
 
 SEE ALSO
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 8946dc74fe41..5f05a75f00eb 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -51,6 +51,7 @@ static struct parameters {
 	bool overwrite;
 	bool zero_key;
 	bool master_pass;
+	bool human;
 	bool force;
 	bool json;
 	bool verbose;
@@ -80,7 +81,7 @@ static int action_zero(struct ndctl_dimm *dimm, struct action_context *actx)
 }
 
 static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
-		struct ndctl_cmd *cmd_read, ssize_t size)
+		struct ndctl_cmd *cmd_read, ssize_t size, unsigned long flags)
 {
 	struct json_object *jarray = json_object_new_array();
 	struct json_object *jlabel = NULL;
@@ -141,12 +142,13 @@ static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
 			break;
 		json_object_object_add(jlabel, "nlabel", jobj);
 
-		jobj = json_object_new_int64(le64_to_cpu(nslabel.flags));
+		jobj = util_json_object_hex(le32_to_cpu(nslabel.flags), flags);
 		if (!jobj)
 			break;
 		json_object_object_add(jlabel, "flags", jobj);
 
-		jobj = json_object_new_int64(le64_to_cpu(nslabel.isetcookie));
+		jobj = util_json_object_hex(le64_to_cpu(nslabel.isetcookie),
+				flags);
 		if (!jobj)
 			break;
 		json_object_object_add(jlabel, "isetcookie", jobj);
@@ -156,12 +158,12 @@ static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
 			break;
 		json_object_object_add(jlabel, "lbasize", jobj);
 
-		jobj = json_object_new_int64(le64_to_cpu(nslabel.dpa));
+		jobj = util_json_object_hex(le64_to_cpu(nslabel.dpa), flags);
 		if (!jobj)
 			break;
 		json_object_object_add(jlabel, "dpa", jobj);
 
-		jobj = json_object_new_int64(le64_to_cpu(nslabel.rawsize));
+		jobj = util_json_object_size(le64_to_cpu(nslabel.rawsize), flags);
 		if (!jobj)
 			break;
 		json_object_object_add(jlabel, "rawsize", jobj);
@@ -266,6 +268,7 @@ static struct json_object *dump_index_json(struct ndctl_cmd *cmd_read, ssize_t s
 static struct json_object *dump_json(struct ndctl_dimm *dimm,
 		struct ndctl_cmd *cmd_read, ssize_t size)
 {
+	unsigned long flags = param.human ? UTIL_JSON_HUMAN : 0;
 	struct json_object *jdimm = json_object_new_object();
 	struct json_object *jlabel, *jobj, *jindex;
 
@@ -274,7 +277,7 @@ static struct json_object *dump_json(struct ndctl_dimm *dimm,
 	jindex = dump_index_json(cmd_read, size);
 	if (!jindex)
 		goto err_jindex;
-	jlabel = dump_label_json(dimm, cmd_read, size);
+	jlabel = dump_label_json(dimm, cmd_read, size, flags);
 	if (!jlabel)
 		goto err_jlabel;
 
@@ -1046,7 +1049,8 @@ OPT_BOOLEAN('v',"verbose", &param.verbose, "turn on debug")
 #define READ_OPTIONS() \
 OPT_STRING('o', "output", &param.outfile, "output-file", \
 	"filename to write label area contents"), \
-OPT_BOOLEAN('j', "json", &param.json, "parse label data into json")
+OPT_BOOLEAN('j', "json", &param.json, "parse label data into json"), \
+OPT_BOOLEAN('u', "human", &param.human, "use human friendly number formats (implies --json)")
 
 #define WRITE_OPTIONS() \
 OPT_STRING('i', "input", &param.infile, "input-file", \
@@ -1156,7 +1160,7 @@ static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
 		return -EINVAL;
 	}
 
-	if (param.json) {
+	if (param.json || param.human) {
 		actx.jdimms = json_object_new_array();
 		if (!actx.jdimms)
 			return -ENOMEM;

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 03/26] ndctl/build: Drop -Wpointer-arith
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 01/26] ndctl/dimm: Add 'flags' field to read-labels output Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 02/26] ndctl/dimm: Add --human support to read-labels Dan Williams
@ 2019-07-27 21:39 ` Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 04/26] ndctl/namespace: Add read-infoblock command Dan Williams
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:39 UTC (permalink / raw)
  To: linux-nvdimm

It is common kernel practice to do pointer arithmetic on (void *). Drop
this warning for ndctl.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 configure.ac |    1 -
 1 file changed, 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 6dca96eda395..4737cfff77f2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -207,7 +207,6 @@ my_CFLAGS="\
 -Wmissing-declarations \
 -Wmissing-prototypes \
 -Wnested-externs \
--Wpointer-arith \
 -Wshadow \
 -Wsign-compare \
 -Wstrict-prototypes \

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 04/26] ndctl/namespace: Add read-infoblock command
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (2 preceding siblings ...)
  2019-07-27 21:39 ` [ndctl PATCH v2 03/26] ndctl/build: Drop -Wpointer-arith Dan Williams
@ 2019-07-27 21:39 ` Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 05/26] ndctl/test: Update dax-dev to handle multiple e820 ranges Dan Williams
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:39 UTC (permalink / raw)
  To: linux-nvdimm

Namespaces may contain an info-block that correlates with the possible
modes of a namespace: 'sector', 'fsdax', or 'devdax'. Provide a command
that can temporarily convert the namespace into 'raw' mode to read the
info-block.

Also, similar to 'read-labels' provide a facility to decode the
info-block into json.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/ndctl/Makefile.am              |    3 
 Documentation/ndctl/ndctl-read-infoblock.txt |   94 ++++++
 ndctl/action.h                               |    1 
 ndctl/builtin.h                              |    1 
 ndctl/check.c                                |   20 -
 ndctl/namespace.c                            |  401 ++++++++++++++++++++++++++
 ndctl/namespace.h                            |   51 +++
 ndctl/ndctl.c                                |    1 
 util/fletcher.h                              |    1 
 util/size.h                                  |    1 
 10 files changed, 552 insertions(+), 22 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-read-infoblock.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index fb46d7c87938..ef22f6de390e 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -55,7 +55,8 @@ man1_MANS = \
 	ndctl-freeze-security.1 \
 	ndctl-sanitize-dimm.1 \
 	ndctl-load-keys.1 \
-	ndctl-wait-overwrite.1
+	ndctl-wait-overwrite.1 \
+	ndctl-read-infoblock.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-read-infoblock.txt b/Documentation/ndctl/ndctl-read-infoblock.txt
new file mode 100644
index 000000000000..92ae95befd38
--- /dev/null
+++ b/Documentation/ndctl/ndctl-read-infoblock.txt
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-read-infoblock(1)
+=======================
+
+NAME
+----
+ndctl-read-infoblock - read and optionally parse the info-block a namespace
+
+SYNOPSIS
+--------
+[verse]
+'ndctl read-infoblock' <namespace0.0> [<namespace1.0>..<namespaceN.Y>] [<options>]
+
+DESCRIPTION
+-----------
+As described in the theory of operation section of
+linkndctl:ndctl-create-namespace[1], the raw capacity of a namespace may
+encapsulate a personality, or mode of operation. Specifically, the mode
+may be set to one of "sector", "fsdax", and "devdax". Each of those
+modes is defined by an info-block format that uniquely identifies the
+mode of operation. The read-infoblock command knows the location
+(relative to the start of the namespace) and field definition of those
+data structures.
+
+Note that unlike a partition table info-block is not exposed by default,
+so the namespace needs to be disabled before the info-block can be
+accessed.
+
+EXAMPLE
+-------
+
+[verse]
+# ndctl disable-namespace namespace0.0
+disabled 1 namespace
+# ndctl read-infoblock -j namespace0.0
+[
+  {
+    "dev":"namespace0.0",
+    "signature":"NVDIMM_PFN_INFO",
+    "uuid":"56b11990-66b1-4d91-9cac-ca084c051259",
+    "parent_uuid":"00000000-0000-0000-0000-000000000000",
+    "flags":0,
+    "version":"1.3",
+    "dataoff":69206016,
+    "npfns":1031680,
+    "mode":2,
+    "start_pad":0,
+    "end_trunc":0,
+    "align":2097152
+  }
+]
+
+
+OPTIONS
+-------
+<namespace(s)>::
+	One or more 'namespaceX.Y' device names. The keyword 'all' can be specified to
+	operate on every namespace in the system, optionally filtered by bus id (see
+        --bus= option), or region id (see --region= option).
+
+-V::
+--verify::
+	Attempt to validate that the info-block is self consistent by
+	validating the embedded checksum, and that info-block formats
+	that contain a 'parent-uuid' attribute also match the base-uuid
+	of the namespace.
+
+-o::
+--output::
+	Output file
+
+-j::
+--json::
+	Parse the info-block data into json.
+-u::
+--human::
+	Enable json output and convert number formats to human readable
+	strings, for example show the size in terms of "KB", "MB", "GB", etc
+	instead of a signed 64-bit numbers per the JSON interchange
+	format (implies --json).
+
+-r::
+--region=::
+include::xable-region-options.txt[]
+
+
+include::../copyright.txt[]
+
+SEE ALSO
+--------
+linkndctl:ndctl-create-namespace[1],
+http://www.uefi.org/sites/default/files/resources/UEFI_Spec_2_7.pdf[UEFI NVDIMM Label Protocol]
+
diff --git a/ndctl/action.h b/ndctl/action.h
index 50da010ae826..636524c01f20 100644
--- a/ndctl/action.h
+++ b/ndctl/action.h
@@ -14,5 +14,6 @@ enum device_action {
 	ACTION_WAIT,
 	ACTION_START,
 	ACTION_CLEAR,
+	ACTION_READ_INFOBLOCK,
 };
 #endif /* __NDCTL_ACTION_H__ */
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 94ab3177e9b6..aa41ad01a84c 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -8,6 +8,7 @@ int cmd_create_nfit(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_enable_namespace(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_create_namespace(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_destroy_namespace(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_read_infoblock(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_disable_namespace(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_check_namespace(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_clear_errors(int argc, const char **argv, struct ndctl_ctx *ctx);
diff --git a/ndctl/check.c b/ndctl/check.c
index 8a7125053865..3b384c091af5 100644
--- a/ndctl/check.c
+++ b/ndctl/check.c
@@ -297,24 +297,6 @@ static int btt_log_read(struct arena_info *a, u32 lane, struct log_entry *ent)
 	return 0;
 }
 
-static int btt_checksum_verify(struct btt_sb *btt_sb)
-{
-	uint64_t sum;
-	le64 sum_save;
-
-	BUILD_BUG_ON(sizeof(struct btt_sb) != SZ_4K);
-
-	sum_save = btt_sb->checksum;
-	btt_sb->checksum = 0;
-	sum = fletcher64(btt_sb, sizeof(*btt_sb), 1);
-	if (sum != sum_save)
-		return 1;
-	/* restore the checksum in the buffer */
-	btt_sb->checksum = sum_save;
-
-	return 0;
-}
-
 /*
  * Never pass a mmapped buffer to this as it will attempt to write to
  * the buffer, and we want writes to only happened in a controlled fashion.
@@ -330,7 +312,7 @@ static int btt_info_verify(struct btt_chk *bttc, struct btt_sb *btt_sb)
 		if (uuid_compare(bttc->parent_uuid, btt_sb->parent_uuid) != 0)
 			return -ENXIO;
 
-	if (btt_checksum_verify(btt_sb))
+	if (!verify_infoblock_checksum((union info_block *) btt_sb))
 		return -ENXIO;
 
 	return 0;
diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 58a9e3c53474..9eec313c2d5b 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -21,6 +21,7 @@
 
 #include <ndctl.h>
 #include "action.h"
+#include "namespace.h"
 #include <sys/stat.h>
 #include <uuid/uuid.h>
 #include <sys/types.h>
@@ -41,6 +42,9 @@ static struct parameters {
 	bool do_scan;
 	bool mode_default;
 	bool autolabel;
+	bool verify;
+	bool human;
+	bool json;
 	const char *bus;
 	const char *map;
 	const char *type;
@@ -52,6 +56,8 @@ static struct parameters {
 	const char *reconfig;
 	const char *sector_size;
 	const char *align;
+	const char *outfile;
+	const char *infile;
 } param = {
 	.autolabel = true,
 };
@@ -80,6 +86,13 @@ struct parsed_parameters {
 	bool autolabel;
 };
 
+#define pr_verbose(fmt, ...) \
+	({if (verbose) { \
+		fprintf(stderr, fmt, ##__VA_ARGS__); \
+	} else { \
+		do { } while (0); \
+	}})
+
 #define debug(fmt, ...) \
 	({if (verbose) { \
 		fprintf(stderr, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__); \
@@ -124,6 +137,16 @@ OPT_BOOLEAN('f', "force", &force, "check namespace even if currently active")
 #define CLEAR_OPTIONS() \
 OPT_BOOLEAN('s', "scrub", &scrub, "run a scrub to find latent errors")
 
+#define READ_INFOBLOCK_OPTIONS() \
+OPT_FILENAME('o', "output", &param.outfile, "output-file", \
+	"filename to write info-block contents"), \
+OPT_FILENAME('i', "input", &param.infile, "input-file", \
+	"filename to read info-block instead of a namespace"), \
+OPT_BOOLEAN('V', "verify", &param.verify, \
+	"validate parent uuid, and info-block checksum" ), \
+OPT_BOOLEAN('j', "json", &param.json, "parse label data into json"), \
+OPT_BOOLEAN('u', "human", &param.human, "use human friendly number formats (implies --json)")
+
 static const struct option base_options[] = {
 	BASE_OPTIONS(),
 	OPT_END(),
@@ -154,6 +177,12 @@ static const struct option clear_options[] = {
 	OPT_END(),
 };
 
+static const struct option read_infoblock_options[] = {
+	BASE_OPTIONS(),
+	READ_INFOBLOCK_OPTIONS(),
+	OPT_END(),
+};
+
 static int set_defaults(enum device_action mode)
 {
 	int rc = 0;
@@ -298,18 +327,30 @@ static const char *parse_namespace_options(int argc, const char **argv,
 			case ACTION_CLEAR:
 				action_string = "clear errors for";
 				break;
+			case ACTION_READ_INFOBLOCK:
+				action_string = "read-infoblock";
+				break;
 			default:
 				action_string = "<>";
 				break;
 		}
-		error("specify a namespace to %s, or \"all\"\n", action_string);
-		rc = -EINVAL;
+
+		if ((mode == ACTION_READ_INFOBLOCK && !param.infile)
+				|| mode != ACTION_READ_INFOBLOCK) {
+			error("specify a namespace to %s, or \"all\"\n", action_string);
+			rc = -EINVAL;
+		}
 	}
 	for (i = mode == ACTION_CREATE ? 0 : 1; i < argc; i++) {
 		error("unknown extra parameter \"%s\"\n", argv[i]);
 		rc = -EINVAL;
 	}
 
+	if (mode == ACTION_READ_INFOBLOCK && param.infile && argc) {
+		error("specify a namespace, or --file, not both\n");
+		rc = -EINVAL;
+	}
+
 	if (rc) {
 		usage_with_options(u, options);
 		return NULL; /* we won't return from usage_with_options() */
@@ -1313,10 +1354,319 @@ static int namespace_clear_bb(struct ndctl_namespace *ndns)
 	return 0;
 }
 
+struct read_infoblock_ctx {
+	struct json_object *jblocks;
+	FILE *f_out;
+};
+
+#define parse_field(sb, field)						\
+	jobj = json_object_new_int(le32_to_cpu((sb)->field));		\
+	if (!jobj)							\
+		goto err;						\
+	json_object_object_add(jblock, #field, jobj);
+
+#define parse_hex(sb, field, sz)						\
+	jobj = util_json_object_hex(le##sz##_to_cpu((sb)->field), flags);	\
+	if (!jobj)								\
+		goto err;							\
+	json_object_object_add(jblock, #field, jobj);
+
+
+static json_object *btt_parse(struct btt_sb *btt_sb, struct ndctl_namespace *ndns,
+		const char *path, unsigned long flags)
+{
+	uuid_t uuid;
+	char str[40];
+	struct json_object *jblock, *jobj;
+	const char *cmd = "read-info-block";
+	const bool verify = param.verify;
+
+	if (verify && !verify_infoblock_checksum((union info_block *) btt_sb)) {
+		pr_verbose("%s: %s checksum verification failed\n", cmd, __func__);
+		return NULL;
+	}
+
+	if (ndns) {
+		ndctl_namespace_get_uuid(ndns, uuid);
+		if (verify && !uuid_is_null(uuid) && memcmp(uuid, btt_sb->parent_uuid,
+					sizeof(uuid) != 0)) {
+			pr_verbose("%s: %s uuid verification failed\n", cmd, __func__);
+			return NULL;
+		}
+	}
+
+	jblock = json_object_new_object();
+	if (!jblock)
+		return NULL;
+
+	if (ndns) {
+		jobj = json_object_new_string(ndctl_namespace_get_devname(ndns));
+		if (!jobj)
+			goto err;
+		json_object_object_add(jblock, "dev", jobj);
+	} else {
+		jobj = json_object_new_string(path);
+		if (!jobj)
+			goto err;
+		json_object_object_add(jblock, "file", jobj);
+	}
+
+	jobj = json_object_new_string((char *) btt_sb->signature);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "signature", jobj);
+
+	uuid_unparse((void *) btt_sb->uuid, str);
+	jobj = json_object_new_string(str);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "uuid", jobj);
+
+	uuid_unparse((void *) btt_sb->parent_uuid, str);
+	jobj = json_object_new_string(str);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "parent_uuid", jobj);
+
+	jobj = util_json_object_hex(le32_to_cpu(btt_sb->flags), flags);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "flags", jobj);
+
+	if (snprintf(str, 4, "%d.%d", btt_sb->version_major,
+				btt_sb->version_minor) >= 4)
+		goto err;
+	jobj = json_object_new_string(str);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "version", jobj);
+
+	parse_field(btt_sb, external_lbasize);
+	parse_field(btt_sb, external_nlba);
+	parse_field(btt_sb, internal_lbasize);
+	parse_field(btt_sb, internal_nlba);
+	parse_field(btt_sb, nfree);
+	parse_field(btt_sb, infosize);
+	parse_hex(btt_sb, nextoff, 64);
+	parse_hex(btt_sb, dataoff, 64);
+	parse_hex(btt_sb, mapoff, 64);
+	parse_hex(btt_sb, logoff, 64);
+	parse_hex(btt_sb, info2off, 64);
+
+	return jblock;
+err:
+	pr_verbose("%s: failed to create json representation\n", cmd);
+	json_object_put(jblock);
+	return NULL;
+}
+
+static json_object *pfn_parse(struct pfn_sb *pfn_sb, struct ndctl_namespace *ndns,
+		const char *path, unsigned long flags)
+{
+	uuid_t uuid;
+	char str[40];
+	struct json_object *jblock, *jobj;
+	const char *cmd = "read-info-block";
+	const bool verify = param.verify;
+
+	if (verify && !verify_infoblock_checksum((union info_block *) pfn_sb)) {
+		pr_verbose("%s: %s checksum verification failed\n", cmd, __func__);
+		return NULL;
+	}
+
+	if (ndns) {
+		ndctl_namespace_get_uuid(ndns, uuid);
+		if (verify && !uuid_is_null(uuid) && memcmp(uuid, pfn_sb->parent_uuid,
+					sizeof(uuid) != 0)) {
+			pr_verbose("%s: %s uuid verification failed\n", cmd, __func__);
+			return NULL;
+		}
+	}
+
+	jblock = json_object_new_object();
+	if (!jblock)
+		return NULL;
+
+	if (ndns) {
+		jobj = json_object_new_string(ndctl_namespace_get_devname(ndns));
+		if (!jobj)
+			goto err;
+		json_object_object_add(jblock, "dev", jobj);
+	} else {
+		jobj = json_object_new_string(path);
+		if (!jobj)
+			goto err;
+		json_object_object_add(jblock, "file", jobj);
+	}
+
+	jobj = json_object_new_string((char *) pfn_sb->signature);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "signature", jobj);
+
+	uuid_unparse((void *) pfn_sb->uuid, str);
+	jobj = json_object_new_string(str);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "uuid", jobj);
+
+	uuid_unparse((void *) pfn_sb->parent_uuid, str);
+	jobj = json_object_new_string(str);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "parent_uuid", jobj);
+
+	jobj = util_json_object_hex(le32_to_cpu(pfn_sb->flags), flags);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "flags", jobj);
+
+	if (snprintf(str, 4, "%d.%d", pfn_sb->version_major,
+				pfn_sb->version_minor) >= 4)
+		goto err;
+	jobj = json_object_new_string(str);
+	if (!jobj)
+		goto err;
+	json_object_object_add(jblock, "version", jobj);
+
+	parse_hex(pfn_sb, dataoff, 64);
+	parse_hex(pfn_sb, npfns, 64);
+	parse_field(pfn_sb, mode);
+	parse_hex(pfn_sb, start_pad, 32);
+	parse_hex(pfn_sb, end_trunc, 32);
+	parse_hex(pfn_sb, align, 32);
+
+	return jblock;
+err:
+	pr_verbose("%s: failed to create json representation\n", cmd);
+	json_object_put(jblock);
+	return NULL;
+}
+
+#define INFOBLOCK_SZ SZ_8K
+
+static int parse_namespace_infoblock(char *_buf, struct ndctl_namespace *ndns,
+		const char *path, struct read_infoblock_ctx *ri_ctx)
+{
+	int rc;
+	void *buf = _buf;
+	unsigned long flags = param.human ? UTIL_JSON_HUMAN : 0;
+	struct btt_sb *btt1_sb = buf + SZ_4K, *btt2_sb = buf;
+	struct json_object *jblock = NULL, *jblocks = ri_ctx->jblocks;
+	struct pfn_sb *pfn_sb = buf + SZ_4K, *dax_sb = buf + SZ_4K;
+
+	if (!param.json && !param.human) {
+		rc = fwrite(buf, 1, INFOBLOCK_SZ, ri_ctx->f_out);
+		if (rc != INFOBLOCK_SZ)
+			return -EIO;
+		fflush(ri_ctx->f_out);
+		return 0;
+	}
+
+	if (!jblocks) {
+		jblocks = json_object_new_array();
+		if (!jblocks)
+			return -ENOMEM;
+		ri_ctx->jblocks = jblocks;
+	}
+
+	if (memcmp(btt1_sb->signature, BTT_SIG, BTT_SIG_LEN) == 0) {
+		jblock = btt_parse(btt1_sb, ndns, path, flags);
+		if (jblock)
+			json_object_array_add(jblocks, jblock);
+	}
+
+	if (memcmp(btt2_sb->signature, BTT_SIG, BTT_SIG_LEN) == 0) {
+		jblock = btt_parse(btt2_sb, ndns, path, flags);
+		if (jblock)
+			json_object_array_add(jblocks, jblock);
+	}
+
+	if (memcmp(pfn_sb->signature, PFN_SIG, PFN_SIG_LEN) == 0) {
+		jblock = pfn_parse(pfn_sb, ndns, path, flags);
+		if (jblock)
+			json_object_array_add(jblocks, jblock);
+	}
+
+	if (memcmp(dax_sb->signature, DAX_SIG, PFN_SIG_LEN) == 0) {
+		jblock = pfn_parse(dax_sb, ndns, path, flags);
+		if (jblock)
+			json_object_array_add(jblocks, jblock);
+	}
+
+	return 0;
+}
+
+static int file_read_infoblock(const char *path, struct ndctl_namespace *ndns,
+		struct read_infoblock_ctx *ri_ctx)
+{
+	const char *devname = ndns ? ndctl_namespace_get_devname(ndns) : "";
+	const char *cmd = "read-info-block";
+	void *buf = NULL;
+	int fd = -1, rc;
+
+	buf = calloc(1, INFOBLOCK_SZ);
+	if (!buf)
+		return -ENOMEM;
+
+	fd = open(path, O_RDONLY|O_EXCL);
+	if (fd < 0) {
+		pr_verbose("%s: %s failed to open %s: %s\n",
+				cmd, devname, path, strerror(errno));
+		rc = -errno;
+		goto out;
+	}
+
+	rc = read(fd, buf, INFOBLOCK_SZ);
+	if (rc < 0) {
+		pr_verbose("%s: %s failed to read %s: %s\n",
+				cmd, devname, path, strerror(errno));
+		rc = -errno;
+		goto out;
+	}
+
+	rc = parse_namespace_infoblock(buf, ndns, path, ri_ctx);
+out:
+	free(buf);
+	if (fd >= 0)
+		close(fd);
+	return rc;
+}
+
+static int namespace_read_infoblock(struct ndctl_namespace *ndns,
+		struct read_infoblock_ctx *ri_ctx)
+{
+	int rc;
+	char path[50];
+	const char *cmd = "read-info-block";
+	const char *devname = ndctl_namespace_get_devname(ndns);
+
+	if (ndctl_namespace_is_active(ndns)) {
+		pr_verbose("%s: %s enabled, must be disabled\n", cmd, devname);
+		return -EBUSY;
+	}
+
+	ndctl_namespace_set_raw_mode(ndns, 1);
+	rc = ndctl_namespace_enable(ndns);
+	if (rc < 0) {
+		pr_verbose("%s: %s failed to enable\n", cmd, devname);
+		goto out;
+	}
+
+	sprintf(path, "/dev/%s", ndctl_namespace_get_block_device(ndns));
+	rc = file_read_infoblock(path, ndns, ri_ctx);
+
+out:
+	ndctl_namespace_set_raw_mode(ndns, 0);
+	ndctl_namespace_disable_invalidate(ndns);
+	return rc;
+}
+
 static int do_xaction_namespace(const char *namespace,
 		enum device_action action, struct ndctl_ctx *ctx,
 		int *processed)
 {
+	struct read_infoblock_ctx ri_ctx = { 0 };
 	struct ndctl_namespace *ndns, *_n;
 	struct ndctl_region *region;
 	const char *ndns_name;
@@ -1325,6 +1675,26 @@ static int do_xaction_namespace(const char *namespace,
 
 	*processed = 0;
 
+	if (action == ACTION_READ_INFOBLOCK) {
+		if (!param.outfile)
+			ri_ctx.f_out = stdout;
+		else {
+			ri_ctx.f_out = fopen(param.outfile, "w+");
+			if (!ri_ctx.f_out) {
+				fprintf(stderr, "failed to open: %s: (%s)\n",
+						param.outfile, strerror(errno));
+				return -errno;
+			}
+		}
+
+		if (param.infile) {
+			rc = file_read_infoblock(param.infile, NULL, &ri_ctx);
+			if (ri_ctx.jblocks)
+				util_display_json_array(ri_ctx.f_out, ri_ctx.jblocks, 0);
+			return rc;
+		}
+	}
+
 	if (!namespace && action != ACTION_CREATE)
 		return rc;
 
@@ -1403,6 +1773,11 @@ static int do_xaction_namespace(const char *namespace,
 					if (rc == 0)
 						*processed = 1;
 					return rc;
+				case ACTION_READ_INFOBLOCK:
+					rc = namespace_read_infoblock(ndns, &ri_ctx);
+					if (rc == 0)
+						(*processed)++;
+					break;
 				default:
 					rc = -EINVAL;
 					break;
@@ -1411,6 +1786,12 @@ static int do_xaction_namespace(const char *namespace,
 		}
 	}
 
+	if (ri_ctx.jblocks)
+		util_display_json_array(ri_ctx.f_out, ri_ctx.jblocks, 0);
+
+	if (ri_ctx.f_out && ri_ctx.f_out != stdout)
+		fclose(ri_ctx.f_out);
+
 	return rc;
 }
 
@@ -1523,3 +1904,19 @@ int cmd_clear_errors(int argc , const char **argv, struct ndctl_ctx *ctx)
 			cleared == 1 ? "" : "s");
 	return rc;
 }
+
+int cmd_read_infoblock(int argc , const char **argv, struct ndctl_ctx *ctx)
+{
+	char *xable_usage = "ndctl read-info-block <namespace> [<options>]";
+	const char *namespace = parse_namespace_options(argc, argv,
+			ACTION_READ_INFOBLOCK, read_infoblock_options,
+			xable_usage);
+	int read, rc;
+
+	rc = do_xaction_namespace(namespace, ACTION_READ_INFOBLOCK, ctx, &read);
+	if (rc < 0)
+		fprintf(stderr, "error checking namespaces: %s\n",
+				strerror(-rc));
+	fprintf(stderr, "read %d namespace%s\n", read, read == 1 ? "" : "s");
+	return rc;
+}
diff --git a/ndctl/namespace.h b/ndctl/namespace.h
index bc210857642f..861dfbfa5127 100644
--- a/ndctl/namespace.h
+++ b/ndctl/namespace.h
@@ -13,7 +13,9 @@
 #ifndef __NDCTL_NAMESPACE_H__
 #define __NDCTL_NAMESPACE_H__
 #include <sys/types.h>
+#include <util/util.h>
 #include <util/size.h>
+#include <util/fletcher.h>
 #include <ccan/endian/endian.h>
 #include <ccan/short_types/short_types.h>
 
@@ -202,4 +204,53 @@ struct arena_map {
 	struct btt_sb *info2;
 	size_t info2_len;
 };
+
+#define PFN_SIG_LEN 16
+#define PFN_SIG "NVDIMM_PFN_INFO\0"
+#define DAX_SIG "NVDIMM_DAX_INFO\0"
+
+struct pfn_sb {
+	u8 signature[PFN_SIG_LEN];
+	u8 uuid[16];
+	u8 parent_uuid[16];
+	le32 flags;
+	le16 version_major;
+	le16 version_minor;
+	le64 dataoff; /* relative to namespace_base + start_pad */
+	le64 npfns;
+	le32 mode;
+	/* minor-version-1 additions for section alignment */
+	le32 start_pad;
+	le32 end_trunc;
+	/* minor-version-2 record the base alignment of the mapping */
+	le32 align;
+	u8 padding[4000];
+	le64 checksum;
+};
+
+union info_block {
+	struct pfn_sb pfn_sb;
+	struct btt_sb btt_sb;
+};
+
+static inline bool verify_infoblock_checksum(union info_block *sb)
+{
+	uint64_t sum;
+	le64 sum_save;
+
+	BUILD_BUG_ON(sizeof(union info_block) != SZ_4K);
+
+	/* all infoblocks share the btt_sb layout for checksum */
+	sum_save = sb->btt_sb.checksum;
+	sb->btt_sb.checksum = 0;
+	sum = fletcher64(&sb->btt_sb, sizeof(*sb), 1);
+	if (sum != sum_save)
+		return false;
+	/* restore the checksum in the buffer */
+	sb->btt_sb.checksum = sum_save;
+
+	return true;
+}
+
+
 #endif /* __NDCTL_NAMESPACE_H__ */
diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c
index 6c4975c9f841..5c9c424dcae6 100644
--- a/ndctl/ndctl.c
+++ b/ndctl/ndctl.c
@@ -73,6 +73,7 @@ static struct cmd_struct commands[] = {
 	{ "disable-namespace", { cmd_disable_namespace } },
 	{ "create-namespace", { cmd_create_namespace } },
 	{ "destroy-namespace", { cmd_destroy_namespace } },
+	{ "read-infoblock",  { cmd_read_infoblock } },
 	{ "check-namespace", { cmd_check_namespace } },
 	{ "clear-errors", { cmd_clear_errors } },
 	{ "enable-region", { cmd_enable_region } },
diff --git a/util/fletcher.h b/util/fletcher.h
index 54e2ecf5d6ed..8fccac4ec758 100644
--- a/util/fletcher.h
+++ b/util/fletcher.h
@@ -1,6 +1,7 @@
 #ifndef _NDCTL_FLETCHER_H_
 #define _NDCTL_FLETCHER_H_
 
+#include <stdbool.h>
 #include <ccan/endian/endian.h>
 #include <ccan/short_types/short_types.h>
 
diff --git a/util/size.h b/util/size.h
index 34fac58d6945..2426fef74b3c 100644
--- a/util/size.h
+++ b/util/size.h
@@ -16,6 +16,7 @@
 
 #define SZ_1K     0x00000400
 #define SZ_4K     0x00001000
+#define SZ_8K     0x00002000
 #define SZ_1M     0x00100000
 #define SZ_2M     0x00200000
 #define SZ_4M     0x00400000

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 05/26] ndctl/test: Update dax-dev to handle multiple e820 ranges
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (3 preceding siblings ...)
  2019-07-27 21:39 ` [ndctl PATCH v2 04/26] ndctl/namespace: Add read-infoblock command Dan Williams
@ 2019-07-27 21:39 ` Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 06/26] ndctl/test: Make dax.sh more robust vs small namespaces Dan Williams
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:39 UTC (permalink / raw)
  To: linux-nvdimm

Establish a convention that the first, lowest-index, region on the e820
bus always enables in fsdax mode without need for an nd_pfn instance.
This is in preparation for a defining a collision test that requires
multiple section-mis-aligned regions defined by memmap=nn!ss.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/dax-dev.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/test/dax-dev.c b/test/dax-dev.c
index 0183b7af2052..49ccaa334e31 100644
--- a/test/dax-dev.c
+++ b/test/dax-dev.c
@@ -33,17 +33,28 @@ struct ndctl_namespace *ndctl_get_test_dev(struct ndctl_ctx *ctx)
 	struct ndctl_bus *bus;
 	struct ndctl_dax *dax;
 	struct ndctl_pfn *pfn;
-	struct ndctl_region *region;
 	struct ndctl_namespace *ndns;
 	enum ndctl_namespace_mode mode;
+	struct ndctl_region *region, *min = NULL;
 
 	bus = ndctl_bus_get_by_provider(ctx, "e820");
 	if (!bus)
 		goto out;
 
-	region = ndctl_region_get_first(bus);
-	if (!region)
+	ndctl_region_foreach(bus, region) {
+		if (!min) {
+			min = region;
+			continue;
+		}
+		if (ndctl_region_get_id(region) < ndctl_region_get_id(min))
+			min = region;
+	}
+	if (!min)
 		goto out;
+	region = min;
+
+	/* attempt to re-enable the region if a previous test disabled it */
+	ndctl_region_enable(region);
 
 	ndns = ndctl_namespace_get_first(region);
 	if (!ndns)

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 06/26] ndctl/test: Make dax.sh more robust vs small namespaces
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (4 preceding siblings ...)
  2019-07-27 21:39 ` [ndctl PATCH v2 05/26] ndctl/test: Update dax-dev to handle multiple e820 ranges Dan Williams
@ 2019-07-27 21:39 ` Dan Williams
  2019-07-27 21:39 ` [ndctl PATCH v2 07/26] ndctl/namespace: Always zero info-blocks Dan Williams
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:39 UTC (permalink / raw)
  To: linux-nvdimm

If the namespace returned by test/dax-dev is too small ext4 may default
to a 1K block-size. A 1K block-size precludes dax operation, so force a
4K block-size in all cases.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/dax.sh |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/dax.sh b/test/dax.sh
index d38fd01acb07..e703e1222dee 100755
--- a/test/dax.sh
+++ b/test/dax.sh
@@ -47,7 +47,7 @@ json=$($NDCTL list -N -n $dev)
 eval $(json2var <<< "$json")
 rc=1
 
-mkfs.ext4 /dev/$blockdev
+mkfs.ext4 -b 4096 /dev/$blockdev
 mount /dev/$blockdev $MNT -o dax
 fallocate -l 1GiB $MNT/$FILE
 run_test
@@ -59,7 +59,7 @@ eval $(json2var <<< "$json")
 [ $mode != "fsdax" ] && echo "fail: $LINENO" &&  exit 1
 
 #note the blockdev returned from ndctl create-namespace lacks the /dev prefix
-mkfs.ext4 /dev/$blockdev
+mkfs.ext4 -b 4096 /dev/$blockdev
 mount /dev/$blockdev $MNT -o dax
 fallocate -l 1GiB $MNT/$FILE
 run_test

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 07/26] ndctl/namespace: Always zero info-blocks
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (5 preceding siblings ...)
  2019-07-27 21:39 ` [ndctl PATCH v2 06/26] ndctl/test: Make dax.sh more robust vs small namespaces Dan Williams
@ 2019-07-27 21:39 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 08/26] ndctl/dimm: Support small label reads/writes Dan Williams
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:39 UTC (permalink / raw)
  To: linux-nvdimm

Do not gate zeroing on whether a namespace is claimed by a personality.
The namespace might not have been able to be claimed due to info-block
corruption.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/namespace.c |   15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 9eec313c2d5b..645aa14882bb 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -930,9 +930,6 @@ static int namespace_destroy(struct ndctl_region *region,
 		struct ndctl_namespace *ndns)
 {
 	const char *devname = ndctl_namespace_get_devname(ndns);
-	struct ndctl_pfn *pfn = ndctl_namespace_get_pfn(ndns);
-	struct ndctl_dax *dax = ndctl_namespace_get_dax(ndns);
-	struct ndctl_btt *btt = ndctl_namespace_get_btt(ndns);
 	bool did_zero = false;
 	int rc;
 
@@ -954,13 +951,11 @@ static int namespace_destroy(struct ndctl_region *region,
 
 	ndctl_namespace_set_enforce_mode(ndns, NDCTL_NS_MODE_RAW);
 
-	if (pfn || btt || dax) {
-		rc = zero_info_block(ndns);
-		if (rc < 0)
-			return rc;
-		if (rc == 0)
-			did_zero = true;
-	}
+	rc = zero_info_block(ndns);
+	if (rc < 0)
+		return rc;
+	if (rc == 0)
+		did_zero = true;
 
 	switch (ndctl_namespace_get_type(ndns)) {
         case ND_DEVICE_NAMESPACE_PMEM:

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 08/26] ndctl/dimm: Support small label reads/writes
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (6 preceding siblings ...)
  2019-07-27 21:39 ` [ndctl PATCH v2 07/26] ndctl/namespace: Always zero info-blocks Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 09/26] ndctl/dimm: Minimize data-transfer for init-labels Dan Williams
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

The initial ndctl label read/write implementation assumed that label
read / writes were relatively inexpensive, but that assumption is
invalid in practice. The process of reading a full label area can take
10s of seconds. Implement ndctl_cmd_cfg_{read,write}_set_extent() to
trim the label read/write commands to a range smaller than the full
label area.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/lib/libndctl.c   |  107 +++++++++++++++++++++++++++++++++++++++++-------
 ndctl/lib/libndctl.sym |    2 +
 ndctl/lib/private.h    |    1 
 ndctl/libndctl.h       |    4 ++
 4 files changed, 99 insertions(+), 15 deletions(-)

diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 81e155171c8c..c1ecdd8c9c61 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -2582,6 +2582,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_read(struct ndctl_cmd *cfg
 	cmd->get_data->in_offset = 0;
 	cmd->get_data->in_length = cfg_size->get_size->max_xfer;
 	cmd->firmware_status = &cmd->get_data->status;
+	cmd->iter.init_offset = 0;
 	cmd->iter.offset = &cmd->get_data->in_offset;
 	cmd->iter.xfer = &cmd->get_data->in_length;
 	cmd->iter.max_xfer = cfg_size->get_size->max_xfer;
@@ -2593,10 +2594,43 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_read(struct ndctl_cmd *cfg
 		free(cmd);
 		return NULL;
 	}
+	cmd->source = cfg_size;
+	ndctl_cmd_ref(cfg_size);
 
 	return cmd;
 }
 
+static void iter_set_extent(struct ndctl_cmd_iter *iter, unsigned int len,
+		unsigned int offset)
+{
+	iter->init_offset = offset;
+	*iter->offset = offset;
+	*iter->xfer = min(iter->max_xfer, len);
+	iter->total_xfer = len;
+}
+
+NDCTL_EXPORT int ndctl_cmd_cfg_read_set_extent(struct ndctl_cmd *cfg_read,
+		unsigned int len, unsigned int offset)
+{
+	struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(cfg_read));
+	struct ndctl_cmd *cfg_size = cfg_read->source;
+
+	if (cfg_read->type != ND_CMD_GET_CONFIG_DATA
+			|| cfg_read->status <= 0) {
+		dbg(ctx, "expected unsubmitted cfg_read command\n");
+		return -EINVAL;
+	}
+
+	if (offset + len > cfg_size->get_size->config_size) {
+		dbg(ctx, "read %d from %d exceeds %d\n", len, offset,
+				cfg_size->get_size->config_size);
+		return -EINVAL;
+	}
+
+	iter_set_extent(&cfg_read->iter, len, offset);
+	return 0;
+}
+
 NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_write(struct ndctl_cmd *cfg_read)
 {
 	struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(cfg_read));
@@ -2632,10 +2666,11 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_write(struct ndctl_cmd *cf
 	cmd->type = ND_CMD_SET_CONFIG_DATA;
 	cmd->size = size;
 	cmd->status = 1;
-	cmd->set_data->in_offset = 0;
+	cmd->set_data->in_offset = cfg_read->iter.init_offset;
 	cmd->set_data->in_length = cfg_read->iter.max_xfer;
 	cmd->firmware_status = (u32 *) (cmd->cmd_buf
 		+ sizeof(struct nd_cmd_set_config_hdr) + cfg_read->iter.max_xfer);
+	cmd->iter.init_offset = cfg_read->iter.init_offset;
 	cmd->iter.offset = &cmd->set_data->in_offset;
 	cmd->iter.xfer = &cmd->set_data->in_length;
 	cmd->iter.max_xfer = cfg_read->iter.max_xfer;
@@ -2657,18 +2692,33 @@ NDCTL_EXPORT unsigned int ndctl_cmd_cfg_size_get_size(struct ndctl_cmd *cfg_size
 	return 0;
 }
 
+static ssize_t iter_access(struct ndctl_cmd_iter *iter, unsigned int len,
+		unsigned int offset)
+{
+	if (offset < iter->init_offset
+			|| offset > iter->init_offset + iter->total_xfer
+			|| len + offset < len)
+		return -EINVAL;
+	if (len + offset > iter->init_offset + iter->total_xfer)
+		len = iter->total_xfer - offset;
+	return len;
+}
+
 NDCTL_EXPORT ssize_t ndctl_cmd_cfg_read_get_data(struct ndctl_cmd *cfg_read,
-		void *buf, unsigned int len, unsigned int offset)
+		void *buf, unsigned int _len, unsigned int offset)
 {
+	struct ndctl_cmd_iter *iter;
+	ssize_t len;
+
 	if (cfg_read->type != ND_CMD_GET_CONFIG_DATA || cfg_read->status > 0)
 		return -EINVAL;
 	if (cfg_read->status < 0)
 		return cfg_read->status;
-	if (offset > cfg_read->iter.total_xfer || len + offset < len)
-		return -EINVAL;
-	if (len + offset > cfg_read->iter.total_xfer)
-		len = cfg_read->iter.total_xfer - offset;
-	memcpy(buf, cfg_read->iter.total_buf + offset, len);
+
+	iter = &cfg_read->iter;
+	len = iter_access(&cfg_read->iter, _len, offset);
+	if (len >= 0)
+		memcpy(buf, iter->total_buf + offset, len);
 	return len;
 }
 
@@ -2681,29 +2731,56 @@ NDCTL_EXPORT ssize_t ndctl_cmd_cfg_read_get_size(struct ndctl_cmd *cfg_read)
 	return cfg_read->iter.total_xfer;
 }
 
+NDCTL_EXPORT int ndctl_cmd_cfg_write_set_extent(struct ndctl_cmd *cfg_write,
+		unsigned int len, unsigned int offset)
+{
+	struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(cfg_write));
+	struct ndctl_cmd *cfg_size, *cfg_read;
+
+	if (cfg_write->type != ND_CMD_SET_CONFIG_DATA
+			|| cfg_write->status <= 0) {
+		dbg(ctx, "expected unsubmitted cfg_write command\n");
+		return -EINVAL;
+	}
+
+	cfg_read = cfg_write->source;
+	cfg_size = cfg_read->source;
+
+	if (offset + len > cfg_size->get_size->config_size) {
+		dbg(ctx, "write %d from %d exceeds %d\n", len, offset,
+				cfg_size->get_size->config_size);
+		return -EINVAL;
+	}
+
+	iter_set_extent(&cfg_write->iter, len, offset);
+	return 0;
+}
+
 NDCTL_EXPORT ssize_t ndctl_cmd_cfg_write_set_data(struct ndctl_cmd *cfg_write,
-		void *buf, unsigned int len, unsigned int offset)
+		void *buf, unsigned int _len, unsigned int offset)
 {
+	ssize_t len;
+
 	if (cfg_write->type != ND_CMD_SET_CONFIG_DATA || cfg_write->status < 1)
 		return -EINVAL;
 	if (cfg_write->status < 0)
 		return cfg_write->status;
-	if (offset > cfg_write->iter.total_xfer || len + offset < len)
-		return -EINVAL;
-	if (len + offset > cfg_write->iter.total_xfer)
-		len = cfg_write->iter.total_xfer - offset;
-	memcpy(cfg_write->iter.total_buf + offset, buf, len);
+	len = iter_access(&cfg_write->iter, _len, offset);
+	if (len >= 0)
+		memcpy(cfg_write->iter.total_buf + offset, buf, len);
 	return len;
 }
 
 NDCTL_EXPORT ssize_t ndctl_cmd_cfg_write_zero_data(struct ndctl_cmd *cfg_write)
 {
+	struct ndctl_cmd_iter *iter = &cfg_write->iter;
+
 	if (cfg_write->type != ND_CMD_SET_CONFIG_DATA || cfg_write->status < 1)
 		return -EINVAL;
 	if (cfg_write->status < 0)
 		return cfg_write->status;
-	memset(cfg_write->iter.total_buf, 0, cfg_write->iter.total_xfer);
-	return cfg_write->iter.total_xfer;
+	memset(iter->total_buf + iter->init_offset, 0, iter->total_xfer);
+	return iter->total_xfer;
 }
 
 NDCTL_EXPORT void ndctl_cmd_unref(struct ndctl_cmd *cmd)
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 297f03d7ae39..e79b31c71ae6 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -409,4 +409,6 @@ global:
 LIBNDCTL_20 {
 global:
 	ndctl_bus_poll_scrub_completion;
+	ndctl_cmd_cfg_read_set_extent;
+	ndctl_cmd_cfg_write_set_extent;
 } LIBNDCTL_19;
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 2ddc1d2c34f8..3fc0290ff6a7 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -254,6 +254,7 @@ struct ndctl_cmd {
 	int status;
 	u32 *firmware_status;
 	struct ndctl_cmd_iter {
+		u32 init_offset;
 		u32 *offset;
 		u32 *xfer; /* pointer to xfer length in cmd */
 		u8 *data; /* pointer to the data buffer location in cmd */
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index e378802ee4c1..310814fe924c 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -321,6 +321,10 @@ unsigned int ndctl_cmd_cfg_size_get_size(struct ndctl_cmd *cfg_size);
 ssize_t ndctl_cmd_cfg_read_get_data(struct ndctl_cmd *cfg_read, void *buf,
 		unsigned int len, unsigned int offset);
 ssize_t ndctl_cmd_cfg_read_get_size(struct ndctl_cmd *cfg_read);
+int ndctl_cmd_cfg_read_set_extent(struct ndctl_cmd *cfg_read,
+		unsigned int len, unsigned int offset);
+int ndctl_cmd_cfg_write_set_extent(struct ndctl_cmd *cfg_write,
+		unsigned int len, unsigned int offset);
 ssize_t ndctl_cmd_cfg_write_set_data(struct ndctl_cmd *cfg_write, void *buf,
 		unsigned int len, unsigned int offset);
 ssize_t ndctl_cmd_cfg_write_zero_data(struct ndctl_cmd *cfg_write);

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 09/26] ndctl/dimm: Minimize data-transfer for init-labels
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (7 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 08/26] ndctl/dimm: Support small label reads/writes Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 10/26] ndctl/dimm: Add offset and size options to {read, write, zero}-labels Dan Williams
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

Currently init-labels implementation reads the entire namespace-label
capacity, initializes just the namespace index, and then writes the
entire label capacity. It turns out that DIMM label-area access methods
can be exceedingly slow.

For example, the time to read the entire label area on a single dimm:
2s, but the time to just read the index block space: 45ms.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/dimm.c           |    2 +-
 ndctl/lib/dimm.c       |   53 +++++++++++++++++++++++++++++++++++++++++++++---
 ndctl/lib/libndctl.sym |    1 +
 ndctl/libndctl.h       |    1 +
 4 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 5f05a75f00eb..be03d9b810bd 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -982,7 +982,7 @@ static int __action_init(struct ndctl_dimm *dimm,
 	struct ndctl_cmd *cmd_read;
 	int rc;
 
-	cmd_read = ndctl_dimm_read_labels(dimm);
+	cmd_read = ndctl_dimm_read_label_index(dimm);
 	if (!cmd_read)
 		return -ENXIO;
 
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 22cf4e10b56c..9c5a34e542c3 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -370,14 +370,15 @@ static struct namespace_label *label_base(struct nvdimm_data *ndd)
 	return (struct namespace_label *) base;
 }
 
-static void init_ndd(struct nvdimm_data *ndd, struct ndctl_cmd *cmd_read)
+static void init_ndd(struct nvdimm_data *ndd, struct ndctl_cmd *cmd_read,
+		struct ndctl_cmd *cmd_size)
 {
 	ndctl_cmd_unref(ndd->cmd_read);
 	memset(ndd, 0, sizeof(*ndd));
 	ndd->cmd_read = cmd_read;
 	ndctl_cmd_ref(cmd_read);
 	ndd->data = cmd_read->iter.total_buf;
-	ndd->config_size = cmd_read->iter.total_xfer;
+	ndd->config_size = cmd_size->get_size->config_size;
 	ndd->ns_current = -1;
 	ndd->ns_next = -1;
 }
@@ -490,6 +491,52 @@ NDCTL_EXPORT int ndctl_dimm_validate_labels(struct ndctl_dimm *dimm)
 	return label_validate(&dimm->ndd);
 }
 
+NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_label_index(struct ndctl_dimm *dimm)
+{
+        struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
+        struct ndctl_cmd *cmd_size, *cmd_read;
+	struct nvdimm_data *ndd = &dimm->ndd;
+        int rc;
+
+        rc = ndctl_bus_wait_probe(bus);
+        if (rc < 0)
+                return NULL;
+
+        cmd_size = ndctl_dimm_cmd_new_cfg_size(dimm);
+        if (!cmd_size)
+                return NULL;
+        rc = ndctl_cmd_submit_xlat(cmd_size);
+        if (rc < 0)
+                goto out_size;
+
+        cmd_read = ndctl_dimm_cmd_new_cfg_read(cmd_size);
+        if (!cmd_read)
+                goto out_size;
+	/*
+	 * To calc the namespace index size use the minimum label
+	 * size which corresponds to the maximum namespace index size.
+	 */
+	init_ndd(ndd, cmd_read, cmd_size);
+	ndd->nslabel_size = 128;
+	rc = ndctl_cmd_cfg_read_set_extent(cmd_read,
+			sizeof_namespace_index(ndd) * 2, 0);
+	if (rc < 0)
+		goto out_size;
+
+        rc = ndctl_cmd_submit_xlat(cmd_read);
+        if (rc < 0)
+                goto out_read;
+	ndctl_cmd_unref(cmd_size);
+
+	return cmd_read;
+
+ out_read:
+        ndctl_cmd_unref(cmd_read);
+ out_size:
+        ndctl_cmd_unref(cmd_size);
+        return NULL;
+}
+
 NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_labels(struct ndctl_dimm *dimm)
 {
         struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
@@ -515,7 +562,7 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_labels(struct ndctl_dimm *dimm)
                 goto out_read;
 	ndctl_cmd_unref(cmd_size);
 
-	init_ndd(&dimm->ndd, cmd_read);
+	init_ndd(&dimm->ndd, cmd_read, cmd_size);
 
 	return cmd_read;
 
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index e79b31c71ae6..3cd431a90e55 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -411,4 +411,5 @@ global:
 	ndctl_bus_poll_scrub_completion;
 	ndctl_cmd_cfg_read_set_extent;
 	ndctl_cmd_cfg_write_set_extent;
+	ndctl_dimm_read_label_index;
 } LIBNDCTL_19;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 310814fe924c..8aa4b8bbe6c2 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -308,6 +308,7 @@ struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_read(struct ndctl_cmd *cfg_size);
 struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_write(struct ndctl_cmd *cfg_read);
 int ndctl_dimm_zero_labels(struct ndctl_dimm *dimm);
 struct ndctl_cmd *ndctl_dimm_read_labels(struct ndctl_dimm *dimm);
+struct ndctl_cmd *ndctl_dimm_read_label_index(struct ndctl_dimm *dimm);
 int ndctl_dimm_validate_labels(struct ndctl_dimm *dimm);
 enum ndctl_namespace_version {
 	NDCTL_NS_VERSION_1_1,

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 10/26] ndctl/dimm: Add offset and size options to {read, write, zero}-labels
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (8 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 09/26] ndctl/dimm: Minimize data-transfer for init-labels Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 11/26] ndctl/dimm: Limit read-labels with --index option Dan Williams
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

Allow for more precision in label utilities, i.e. stop operating over
the entire label area.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/ndctl/labels-options.txt |    9 ++++++
 ndctl/dimm.c                           |   49 ++++++++++++++++++++++++--------
 ndctl/lib/dimm.c                       |   36 ++++++++++++++++++++----
 ndctl/lib/libndctl.sym                 |    2 +
 ndctl/lib/private.h                    |    3 --
 ndctl/libndctl.h                       |    4 +++
 util/util.h                            |    4 +++
 7 files changed, 86 insertions(+), 21 deletions(-)

diff --git a/Documentation/ndctl/labels-options.txt b/Documentation/ndctl/labels-options.txt
index 539ace079557..4aee37969fd5 100644
--- a/Documentation/ndctl/labels-options.txt
+++ b/Documentation/ndctl/labels-options.txt
@@ -5,6 +5,15 @@
 	operate on every dimm in the system, optionally filtered by bus id (see
         --bus= option).
 
+-s::
+--size=::
+	Limit the operation to the given number of bytes. A size of 0
+	indicates to operate over the entire label capacity.
+
+-O::
+--offset=::
+	Begin the operation at the given offset into the label area.
+
 -b::
 --bus=::
 	Limit operation to memory devices (dimms) that are on the given bus.
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index be03d9b810bd..603e112f9568 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -47,6 +47,8 @@ static struct parameters {
 	const char *infile;
 	const char *labelversion;
 	const char *kek;
+	unsigned len;
+	unsigned offset;
 	bool crypto_erase;
 	bool overwrite;
 	bool zero_key;
@@ -77,7 +79,7 @@ static int action_enable(struct ndctl_dimm *dimm, struct action_context *actx)
 
 static int action_zero(struct ndctl_dimm *dimm, struct action_context *actx)
 {
-	return ndctl_dimm_zero_labels(dimm);
+	return ndctl_dimm_zero_label_extent(dimm, param.len, param.offset);
 }
 
 static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
@@ -299,15 +301,17 @@ static struct json_object *dump_json(struct ndctl_dimm *dimm,
 	return NULL;
 }
 
-static int rw_bin(FILE *f, struct ndctl_cmd *cmd, ssize_t size, int rw)
+static int rw_bin(FILE *f, struct ndctl_cmd *cmd, ssize_t size,
+		unsigned int start_offset, int rw)
 {
 	char buf[4096];
 	ssize_t offset, write = 0;
 
-	for (offset = 0; offset < size; offset += sizeof(buf)) {
+	for (offset = start_offset; offset < start_offset + size;
+			offset += sizeof(buf)) {
 		ssize_t len = min_t(ssize_t, sizeof(buf), size - offset), rc;
 
-		if (rw) {
+		if (rw == WRITE) {
 			len = fread(buf, 1, len, f);
 			if (len == 0)
 				break;
@@ -343,9 +347,9 @@ static int action_write(struct ndctl_dimm *dimm, struct action_context *actx)
 		return -EBUSY;
 	}
 
-	cmd_read = ndctl_dimm_read_labels(dimm);
+	cmd_read = ndctl_dimm_read_label_extent(dimm, param.len, param.offset);
 	if (!cmd_read)
-		return -ENXIO;
+		return -EINVAL;
 
 	cmd_write = ndctl_dimm_cmd_new_cfg_write(cmd_read);
 	if (!cmd_write) {
@@ -354,7 +358,7 @@ static int action_write(struct ndctl_dimm *dimm, struct action_context *actx)
 	}
 
 	size = ndctl_cmd_cfg_read_get_size(cmd_read);
-	rc = rw_bin(actx->f_in, cmd_write, size, 1);
+	rc = rw_bin(actx->f_in, cmd_write, size, param.offset, WRITE);
 
 	/*
 	 * If the dimm is already disabled the kernel is not holding a cached
@@ -381,9 +385,9 @@ static int action_read(struct ndctl_dimm *dimm, struct action_context *actx)
 	ssize_t size;
 	int rc = 0;
 
-	cmd_read = ndctl_dimm_read_labels(dimm);
+	cmd_read = ndctl_dimm_read_label_extent(dimm, param.len, param.offset);
 	if (!cmd_read)
-		return -ENXIO;
+		return -EINVAL;
 
 	size = ndctl_cmd_cfg_read_get_size(cmd_read);
 	if (actx->jdimms) {
@@ -394,7 +398,7 @@ static int action_read(struct ndctl_dimm *dimm, struct action_context *actx)
 		else
 			rc = -ENOMEM;
 	} else
-		rc = rw_bin(actx->f_out, cmd_read, size, 0);
+		rc = rw_bin(actx->f_out, cmd_read, size, param.offset, READ);
 
 	ndctl_cmd_unref(cmd_read);
 
@@ -1082,18 +1086,31 @@ OPT_BOOLEAN('z', "zero-key", &param.zero_key, \
 OPT_BOOLEAN('m', "master-passphrase", &param.master_pass, \
 		"use master passphrase")
 
+#define LABEL_OPTIONS() \
+OPT_UINTEGER('s', "size", &param.len, "number of label bytes to operate"), \
+OPT_UINTEGER('O', "offset", &param.offset, \
+	"offset into the label area to start operation")
+
 static const struct option read_options[] = {
 	BASE_OPTIONS(),
+	LABEL_OPTIONS(),
 	READ_OPTIONS(),
 	OPT_END(),
 };
 
 static const struct option write_options[] = {
 	BASE_OPTIONS(),
+	LABEL_OPTIONS(),
 	WRITE_OPTIONS(),
 	OPT_END(),
 };
 
+static const struct option zero_options[] = {
+	BASE_OPTIONS(),
+	LABEL_OPTIONS(),
+	OPT_END(),
+};
+
 static const struct option update_options[] = {
 	BASE_OPTIONS(),
 	UPDATE_OPTIONS(),
@@ -1136,6 +1153,7 @@ static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
 		NULL
 	};
 	unsigned long id;
+	bool json = false;
 
         argc = parse_options(argc, argv, options, u, 0);
 
@@ -1160,7 +1178,14 @@ static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
 		return -EINVAL;
 	}
 
-	if (param.json || param.human) {
+	json = param.json || param.human;
+	if (action == action_read && json && (param.len || param.offset)) {
+		fprintf(stderr, "--size and --offset are incompatible with --json\n");
+		usage_with_options(u, options);
+		return -EINVAL;
+	}
+
+	if (json) {
 		actx.jdimms = json_object_new_array();
 		if (!actx.jdimms)
 			return -ENOMEM;
@@ -1294,7 +1319,7 @@ int cmd_read_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
 
 int cmd_zero_labels(int argc, const char **argv, struct ndctl_ctx *ctx)
 {
-	int count = dimm_action(argc, argv, ctx, action_zero, base_options,
+	int count = dimm_action(argc, argv, ctx, action_zero, zero_options,
 			"ndctl zero-labels <nmem0> [<nmem1>..<nmemN>] [<options>]");
 
 	fprintf(stderr, "zeroed %d nmem%s\n", count >= 0 ? count : 0,
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 9c5a34e542c3..28b1dfb0bdfa 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -537,7 +537,8 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_label_index(struct ndctl_dimm *di
         return NULL;
 }
 
-NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_labels(struct ndctl_dimm *dimm)
+NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_label_extent(
+		struct ndctl_dimm *dimm, unsigned int len, unsigned int offset)
 {
         struct ndctl_bus *bus = ndctl_dimm_get_bus(dimm);
         struct ndctl_cmd *cmd_size, *cmd_read;
@@ -557,13 +558,25 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_labels(struct ndctl_dimm *dimm)
         cmd_read = ndctl_dimm_cmd_new_cfg_read(cmd_size);
         if (!cmd_read)
                 goto out_size;
+
+	/*
+	 * For ndctl_read_labels() compat, enable subsequent calls that
+	 * will manipulate labels
+	 */
+	if (len == 0 && offset == 0)
+		init_ndd(&dimm->ndd, cmd_read, cmd_size);
+
+	if (len == 0)
+		len = cmd_size->get_size->config_size;
+	rc = ndctl_cmd_cfg_read_set_extent(cmd_read, len, offset);
+	if (rc < 0)
+		goto out_size;
+
         rc = ndctl_cmd_submit_xlat(cmd_read);
         if (rc < 0)
                 goto out_read;
 	ndctl_cmd_unref(cmd_size);
 
-	init_ndd(&dimm->ndd, cmd_read, cmd_size);
-
 	return cmd_read;
 
  out_read:
@@ -573,15 +586,21 @@ NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_labels(struct ndctl_dimm *dimm)
         return NULL;
 }
 
-NDCTL_EXPORT int ndctl_dimm_zero_labels(struct ndctl_dimm *dimm)
+NDCTL_EXPORT struct ndctl_cmd *ndctl_dimm_read_labels(struct ndctl_dimm *dimm)
+{
+	return ndctl_dimm_read_label_extent(dimm, 0, 0);
+}
+
+NDCTL_EXPORT int ndctl_dimm_zero_label_extent(struct ndctl_dimm *dimm,
+		unsigned int len, unsigned int offset)
 {
 	struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
 	struct ndctl_cmd *cmd_read, *cmd_write;
 	int rc;
 
-	cmd_read = ndctl_dimm_read_labels(dimm);
+	cmd_read = ndctl_dimm_read_label_extent(dimm, len, offset);
 	if (!cmd_read)
-		return -ENXIO;
+		return -EINVAL;
 
 	if (ndctl_dimm_is_active(dimm)) {
 		dbg(ctx, "%s: regions active, abort label write\n",
@@ -623,6 +642,11 @@ NDCTL_EXPORT int ndctl_dimm_zero_labels(struct ndctl_dimm *dimm)
 	return rc;
 }
 
+NDCTL_EXPORT int ndctl_dimm_zero_labels(struct ndctl_dimm *dimm)
+{
+	return ndctl_dimm_zero_label_extent(dimm, 0, 0);
+}
+
 NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels(
 		struct ndctl_dimm *dimm)
 {
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 3cd431a90e55..895fb358c43a 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -412,4 +412,6 @@ global:
 	ndctl_cmd_cfg_read_set_extent;
 	ndctl_cmd_cfg_write_set_extent;
 	ndctl_dimm_read_label_index;
+	ndctl_dimm_read_label_extent;
+	ndctl_dimm_zero_label_extent;
 } LIBNDCTL_19;
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index 3fc0290ff6a7..1f6a01c55377 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -242,9 +242,6 @@ struct ndctl_namespace {
  *
  * A command may only specify one of @source, or @iter.total_buf, not both.
  */
-enum {
-	READ, WRITE,
-};
 struct ndctl_cmd {
 	struct ndctl_dimm *dimm;
 	struct ndctl_bus *bus;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 8aa4b8bbe6c2..c9d0dc120d3b 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -307,8 +307,12 @@ struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_size(struct ndctl_dimm *dimm);
 struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_read(struct ndctl_cmd *cfg_size);
 struct ndctl_cmd *ndctl_dimm_cmd_new_cfg_write(struct ndctl_cmd *cfg_read);
 int ndctl_dimm_zero_labels(struct ndctl_dimm *dimm);
+int ndctl_dimm_zero_label_extent(struct ndctl_dimm *dimm,
+		unsigned int len, unsigned int offset);
 struct ndctl_cmd *ndctl_dimm_read_labels(struct ndctl_dimm *dimm);
 struct ndctl_cmd *ndctl_dimm_read_label_index(struct ndctl_dimm *dimm);
+struct ndctl_cmd *ndctl_dimm_read_label_extent(struct ndctl_dimm *dimm,
+		unsigned int len, unsigned int offset);
 int ndctl_dimm_validate_labels(struct ndctl_dimm *dimm);
 enum ndctl_namespace_version {
 	NDCTL_NS_VERSION_1_1,
diff --git a/util/util.h b/util/util.h
index 001707e8b159..54c6ef18b6d7 100644
--- a/util/util.h
+++ b/util/util.h
@@ -73,6 +73,10 @@
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
 
+enum {
+	READ, WRITE,
+};
+
 static inline const char *skip_prefix(const char *str, const char *prefix)
 {
         size_t len = strlen(prefix);

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 11/26] ndctl/dimm: Limit read-labels with --index option
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (9 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 10/26] ndctl/dimm: Add offset and size options to {read, write, zero}-labels Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 12/26] ndctl/namespace: Minimize label data transfer for autolabel Dan Williams
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

Provide a capability to limit the read-labels payload to just the
index-block data space.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/dimm.c |   43 +++++++++++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 603e112f9568..c7ad621367e9 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -55,6 +55,7 @@ static struct parameters {
 	bool master_pass;
 	bool human;
 	bool force;
+	bool index;
 	bool json;
 	bool verbose;
 } param = {
@@ -276,27 +277,26 @@ static struct json_object *dump_json(struct ndctl_dimm *dimm,
 
 	if (!jdimm)
 		return NULL;
-	jindex = dump_index_json(cmd_read, size);
-	if (!jindex)
-		goto err_jindex;
-	jlabel = dump_label_json(dimm, cmd_read, size, flags);
-	if (!jlabel)
-		goto err_jlabel;
 
 	jobj = json_object_new_string(ndctl_dimm_get_devname(dimm));
 	if (!jobj)
-		goto err_jobj;
-
+		goto err;
 	json_object_object_add(jdimm, "dev", jobj);
+
+	jindex = dump_index_json(cmd_read, size);
+	if (!jindex)
+		goto err;
 	json_object_object_add(jdimm, "index", jindex);
+	if (param.index)
+		return jdimm;
+
+	jlabel = dump_label_json(dimm, cmd_read, size, flags);
+	if (!jlabel)
+		goto err;
 	json_object_object_add(jdimm, "label", jlabel);
-	return jdimm;
 
- err_jobj:
-	json_object_put(jlabel);
- err_jlabel:
-	json_object_put(jindex);
- err_jindex:
+	return jdimm;
+err:
 	json_object_put(jdimm);
 	return NULL;
 }
@@ -385,7 +385,11 @@ static int action_read(struct ndctl_dimm *dimm, struct action_context *actx)
 	ssize_t size;
 	int rc = 0;
 
-	cmd_read = ndctl_dimm_read_label_extent(dimm, param.len, param.offset);
+	if (param.index)
+		cmd_read = ndctl_dimm_read_label_index(dimm);
+	else
+		cmd_read = ndctl_dimm_read_label_extent(dimm, param.len,
+				param.offset);
 	if (!cmd_read)
 		return -EINVAL;
 
@@ -1054,7 +1058,8 @@ OPT_BOOLEAN('v',"verbose", &param.verbose, "turn on debug")
 OPT_STRING('o', "output", &param.outfile, "output-file", \
 	"filename to write label area contents"), \
 OPT_BOOLEAN('j', "json", &param.json, "parse label data into json"), \
-OPT_BOOLEAN('u', "human", &param.human, "use human friendly number formats (implies --json)")
+OPT_BOOLEAN('u', "human", &param.human, "use human friendly number formats (implies --json)"), \
+OPT_BOOLEAN('I', "index", &param.index, "limit read to the index block area")
 
 #define WRITE_OPTIONS() \
 OPT_STRING('i', "input", &param.infile, "input-file", \
@@ -1185,6 +1190,12 @@ static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
 		return -EINVAL;
 	}
 
+	if (param.index && param.len) {
+		fprintf(stderr, "pick either --size, or --index, not both\n");
+		usage_with_options(u, options);
+		return -EINVAL;
+	}
+
 	if (json) {
 		actx.jdimms = json_object_new_array();
 		if (!actx.jdimms)

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 12/26] ndctl/namespace: Minimize label data transfer for autolabel
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (10 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 11/26] ndctl/dimm: Limit read-labels with --index option Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 13/26] ndctl/namespace: Disable autorecovery of create-namespace failures Dan Williams
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

Use the new ndctl_dimm_read_label_index() helper to minimize the amount
of label I/O needed to execute an autolabel event.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/namespace.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 645aa14882bb..a3963d79831a 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -1029,7 +1029,7 @@ retry:
 		int num_labels, avail;
 
 		ndctl_cmd_unref(cmd_read);
-		cmd_read = ndctl_dimm_read_labels(dimm);
+		cmd_read = ndctl_dimm_read_label_index(dimm);
 		if (!cmd_read)
 			continue;
 

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 13/26] ndctl/namespace: Disable autorecovery of create-namespace failures
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (11 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 12/26] ndctl/namespace: Minimize label data transfer for autolabel Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 14/26] ndctl/namespace: Handle 'create-namespace' in label-less mode Dan Williams
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

Add an option to disable the behavior of cleaning up namespaces that
failed creation. This is useful for doing forensics on the label and
info-block state after the failure with assurances that the kernel has
not made further modifications.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 Documentation/ndctl/ndctl-create-namespace.txt |    9 +++++++++
 ndctl/namespace.c                              |   13 +++++++++----
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/Documentation/ndctl/ndctl-create-namespace.txt b/Documentation/ndctl/ndctl-create-namespace.txt
index 343733dedfd9..ed936c87e483 100644
--- a/Documentation/ndctl/ndctl-create-namespace.txt
+++ b/Documentation/ndctl/ndctl-create-namespace.txt
@@ -203,6 +203,15 @@ OPTIONS
 	ndctl init-labels all
 	ndctl enable-region all
 
+-R::
+--autorecover::
+--no-autorecover::
+	By default, if a namespace creation attempt fails, ndctl will
+	cleanup the partially initialized namespace. Use
+	--no-autorecover to disable this behavior for debug and
+	development scenarios where it useful to have the label and
+	info-block state preserved after a failure.
+
 -v::
 --verbose::
 	Emit debug messages for the namespace creation process
diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index a3963d79831a..58fec194ab94 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -43,6 +43,7 @@ static struct parameters {
 	bool mode_default;
 	bool autolabel;
 	bool verify;
+	bool autorecover;
 	bool human;
 	bool json;
 	const char *bus;
@@ -60,6 +61,7 @@ static struct parameters {
 	const char *infile;
 } param = {
 	.autolabel = true,
+	.autorecover = true,
 };
 
 void builtin_xaction_namespace_reset(void)
@@ -84,6 +86,7 @@ struct parsed_parameters {
 	unsigned long sector_size;
 	unsigned long align;
 	bool autolabel;
+	bool autorecover;
 };
 
 #define pr_verbose(fmt, ...) \
@@ -127,7 +130,8 @@ OPT_STRING('t', "type", &param.type, "type", \
 OPT_STRING('a', "align", &param.align, "align", \
 	"specify the namespace alignment in bytes (default: 2M)"), \
 OPT_BOOLEAN('f', "force", &force, "reconfigure namespace even if currently active"), \
-OPT_BOOLEAN('L', "autolabel", &param.autolabel, "automatically initialize labels")
+OPT_BOOLEAN('L', "autolabel", &param.autolabel, "automatically initialize labels"), \
+OPT_BOOLEAN('R', "autorecover", &param.autorecover, "automatically cleanup on failure")
 
 #define CHECK_OPTIONS() \
 OPT_BOOLEAN('R', "repair", &repair, "perform metadata repairs"), \
@@ -444,7 +448,7 @@ static int setup_namespace(struct ndctl_region *region,
 			try(ndctl_pfn, set_align, pfn, p->align);
 		try(ndctl_pfn, set_namespace, pfn, ndns);
 		rc = ndctl_pfn_enable(pfn);
-		if (rc)
+		if (rc && p->autorecover)
 			ndctl_pfn_set_namespace(pfn, NULL);
 	} else if (p->mode == NDCTL_NS_MODE_DAX) {
 		struct ndctl_dax *dax = ndctl_region_get_dax_seed(region);
@@ -455,7 +459,7 @@ static int setup_namespace(struct ndctl_region *region,
 		try(ndctl_dax, set_align, dax, p->align);
 		try(ndctl_dax, set_namespace, dax, ndns);
 		rc = ndctl_dax_enable(dax);
-		if (rc)
+		if (rc && p->autorecover)
 			ndctl_dax_set_namespace(dax, NULL);
 	} else if (p->mode == NDCTL_NS_MODE_SAFE) {
 		struct ndctl_btt *btt = ndctl_region_get_btt_seed(region);
@@ -798,6 +802,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 
 
 	p->autolabel = param.autolabel;
+	p->autorecover = param.autorecover;
 
 	return 0;
 }
@@ -852,7 +857,7 @@ static int namespace_create(struct ndctl_region *region)
 	}
 
 	rc = setup_namespace(region, ndns, &p);
-	if (rc) {
+	if (rc && p.autorecover) {
 		ndctl_namespace_set_enforce_mode(ndns, NDCTL_NS_MODE_RAW);
 		ndctl_namespace_delete(ndns);
 	}

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 14/26] ndctl/namespace: Handle 'create-namespace' in label-less mode
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (12 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 13/26] ndctl/namespace: Disable autorecovery of create-namespace failures Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-08-21 12:56   ` Michal Suchánek
  2019-07-27 21:40 ` [ndctl PATCH v2 15/26] ndctl/dimm: Fix init-labels success reporting Dan Williams
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

A common confusion with ndctl is that 'create-namespace' does not work
in the label-less case. In the label-less case there is no capacity to
allocate as the size if already hard-coded by the region boundary.

However, users typically do something like the following in the
label-less case:

    # ndctl list
    {
      "dev":"namespace1.0",
      "mode":"raw",
      "size":"127.00 GiB (136.37 GB)",
      "sector_size":512,
      "blockdev":"pmem1"
    }

    # ndctl destroy-namespace namespace1.0 -f
    destroyed 1 namespace

    # ndctl create-namespace
    failed to create namespace: Resource temporarily unavailable

In other words they destroy the raw mode namespace that they don't want,
and seek to create a new default configuration namespace. Since there is
no "available_capacity" in the label-less case the 'create' attempt
fails.

Fix this by recognizing that the user wants a default sized namespace
and just reconfigure the raw namespace.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/namespace.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 58fec194ab94..e5a2b1341cdb 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -837,9 +837,13 @@ static int namespace_create(struct ndctl_region *region)
 		return -EAGAIN;
 	}
 
-	available = ndctl_region_get_max_available_extent(region);
-	if (available == ULLONG_MAX)
-		available = ndctl_region_get_available_size(region);
+	if (ndctl_region_get_nstype(region) == ND_DEVICE_NAMESPACE_IO)
+		available = ndctl_region_get_size(region);
+	else {
+		available = ndctl_region_get_max_available_extent(region);
+		if (available == ULLONG_MAX)
+			available = ndctl_region_get_available_size(region);
+	}
 	if (!available || p.size > available) {
 		debug("%s: insufficient capacity size: %llx avail: %llx\n",
 			devname, p.size, available);

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 15/26] ndctl/dimm: Fix init-labels success reporting
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (13 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 14/26] ndctl/namespace: Handle 'create-namespace' in label-less mode Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 16/26] ndctl/test: Fix device-dax bus-model detection Dan Williams
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

When a DIMM is disabled due to a label parsing issue "ndctl init-labels"
mis-reports the status of the init-labels command:

    # ndctl init-labels all -f
    initialized 1 nmem
    [root@dwillia2-dev ndctl]# ndctl list -Di
    [
      {
        "dev":"nmem1",
        "id":"8680-57341200",
        "handle":2,
        "phys_id":0,
        "state":"disabled"
      },
      {
        "dev":"nmem0",
        "id":"8680-56341200",
        "handle":1,
        "phys_id":0
      }
    ]
    # ndctl init-labels nmem1 -f
    initialized 1020 nmems

Catch any positive return from action_init() as success:

    # ndctl init-labels all -f
    initialized 2 nmems
    # ndctl init-labels nmem1 -f
    initialized 1 nmem

Reported-by: Jane Chu <jane.chu@oracle.com>

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/dimm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index c7ad621367e9..5e6fa19bab15 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -1035,7 +1035,7 @@ static int __action_init(struct ndctl_dimm *dimm,
 
  out:
 	ndctl_cmd_unref(cmd_read);
-	return rc;
+	return rc >= 0 ? 0 : rc;
 }
 
 static int action_init(struct ndctl_dimm *dimm, struct action_context *actx)

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 16/26] ndctl/test: Fix device-dax bus-model detection
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (14 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 15/26] ndctl/dimm: Fix init-labels success reporting Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 17/26] ndctl/test: Checkout device-mapper + dax operation Dan Williams
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

Don't look for bus-model patches on pre-v5.1 kernels.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/core.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/test/core.c b/test/core.c
index b9e3bbf7d7a9..888f5d8c0e42 100644
--- a/test/core.c
+++ b/test/core.c
@@ -168,6 +168,16 @@ int nfit_test_init(struct kmod_ctx **ctx, struct kmod_module **mod,
 				&& !ndctl_test_attempt(test,
 					KERNEL_VERSION(4, 7, 0)))
 			continue;
+
+		/*
+		 * Skip device-dax bus-model modules on pre-v5.1
+		 */
+		if ((strstr(name, "dax_pmem_core")
+				|| strstr(name, "dax_pmem_compat"))
+				&& !ndctl_test_attempt(test,
+					KERNEL_VERSION(5, 1, 0)))
+			continue;
+
 retry:
 		rc = kmod_module_new_from_name(*ctx, name, mod);
 		if (rc) {

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 17/26] ndctl/test: Checkout device-mapper + dax operation
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (15 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 16/26] ndctl/test: Fix device-dax bus-model detection Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:40 ` [ndctl PATCH v2 18/26] ndctl/test: Exercise sub-section sized namespace creation/deletion Dan Williams
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

Given recent kernel changes broke the device-mapper use case, introduce
a basic unit test to prevent this from regressing in the future.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/Makefile.am |    1 +
 test/dm.sh       |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100755 test/dm.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index 874c4bbfaa90..2a1e03d26f6c 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -49,6 +49,7 @@ TESTS +=\
 	dax.sh \
 	device-dax \
 	device-dax-fio.sh \
+	dm.sh \
 	mmap.sh
 
 if ENABLE_KEYUTILS
diff --git a/test/dm.sh b/test/dm.sh
new file mode 100755
index 000000000000..fb498c95a29b
--- /dev/null
+++ b/test/dm.sh
@@ -0,0 +1,75 @@
+#!/bin/bash -x
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2015-2019 Intel Corporation. All rights reserved.
+
+set -e
+
+SKIP=77
+FAIL=1
+SUCCESS=0
+
+. ./common
+
+MNT=test_dax_mnt
+TEST_DM_PMEM=/dev/mapper/test_pmem
+NAME=$(basename $TEST_DM_PMEM)
+
+mkdir -p $MNT
+
+TEST_SIZE=$((1<<30))
+
+rc=$FAIL
+cleanup() {
+	if [ $rc -ne $SUCCESS ]; then
+		echo "test/dm.sh: failed at line $1"
+	fi
+	if mountpoint -q $MNT; then
+		umount $MNT
+	fi
+
+	if [ -L $TEST_DM_PMEM ]; then
+		dmsetup remove $TEST_DM_PMEM
+	fi
+	rmdir $MNT
+	# opportunistic cleanup, not fatal if these fail
+	namespaces=$($NDCTL list -N | jq -r ".[] | select(.name==\"$NAME\") | .dev")
+	for i in $namespaces
+	do
+		if ! $NDCTL destroy-namespace -f $i; then
+			echo "test/sub-section.sh: cleanup() failed to destroy $i"
+		fi
+	done
+	exit $rc
+}
+
+trap 'err $LINENO cleanup' ERR
+
+dev="x"
+json=$($NDCTL create-namespace -b ACPI.NFIT -s $TEST_SIZE -t pmem -m fsdax -n "$NAME")
+eval $(echo $json | json2var )
+[ $dev = "x" ] && echo "fail: $LINENO" && exit 1
+[ $mode != "fsdax" ] && echo "fail: $LINENO" &&  exit 1
+
+pmem0=/dev/$blockdev
+size0=$((size/512))
+
+json=$($NDCTL create-namespace -b ACPI.NFIT -s $TEST_SIZE -t pmem -m fsdax -n "$NAME")
+eval $(echo $json | json2var )
+[ $dev = "x" ] && echo "fail: $LINENO" && exit 1
+[ $mode != "fsdax" ] && echo "fail: $LINENO" &&  exit 1
+
+pmem1=/dev/$blockdev
+size1=$((size/512))
+
+cat <<EOF |
+0 $size0 linear $pmem0 0
+$size0 $size1 linear $pmem1 0
+EOF
+dmsetup create $(basename $NAME)
+
+mkfs.ext4 -b 4096 $TEST_DM_PMEM
+mount -o dax $TEST_DM_PMEM $MNT
+umount $MNT
+
+rc=$SUCCESS
+cleanup $LINENO

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 18/26] ndctl/test: Exercise sub-section sized namespace creation/deletion
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (16 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 17/26] ndctl/test: Checkout device-mapper + dax operation Dan Williams
@ 2019-07-27 21:40 ` Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 19/26] ndctl/namespace: Kill off the legacy mode names Dan Williams
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:40 UTC (permalink / raw)
  To: linux-nvdimm

For kernels that have removed the section-aligned namespace constraint
validate that multiple namespaces can be created / deleted that collide
within a given section.

While this test acts on the ACPI.NFIT bus it is not marked "destructive"
because it only operates in available capacity and marks each namespace
created with a unique volume name ("subsection-test").

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/Makefile.am    |    1 +
 test/sub-section.sh |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)
 create mode 100755 test/sub-section.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index 2a1e03d26f6c..decc8377258a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -45,6 +45,7 @@ if ENABLE_DESTRUCTIVE
 TESTS +=\
 	blk-ns \
 	pmem-ns \
+	sub-section.sh \
 	dax-dev \
 	dax.sh \
 	device-dax \
diff --git a/test/sub-section.sh b/test/sub-section.sh
new file mode 100755
index 000000000000..c624fbdb2ce0
--- /dev/null
+++ b/test/sub-section.sh
@@ -0,0 +1,78 @@
+#!/bin/bash -x
+
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2015-2019 Intel Corporation. All rights reserved.
+
+set -e
+
+SKIP=77
+FAIL=1
+SUCCESS=0
+
+. ./common
+
+check_min_kver "5.3" || do_skip "may lack align sub-section hotplug support"
+
+MNT=test_dax_mnt
+mkdir -p $MNT
+
+TEST_SIZE=$((16<<20))
+MIN_AVAIL=$((TEST_SIZE*4))
+MAX_NS=10
+NAME="subsection-test"
+
+ndctl list -N | jq -r ".[] | select(.name==\"subsection-test\") | .dev"
+
+rc=$FAIL
+cleanup() {
+	if [ $rc -ne $SUCCESS ]; then
+		echo "test/sub-section.sh: failed at line $1"
+	fi
+	if mountpoint -q $MNT; then
+		umount $MNT
+	fi
+	rmdir $MNT
+	# opportunistic cleanup, not fatal if these fail
+	namespaces=$($NDCTL list -N | jq -r ".[] | select(.name==\"$NAME\") | .dev")
+	for i in $namespaces
+	do
+		if ! $NDCTL destroy-namespace -f $i; then
+			echo "test/sub-section.sh: cleanup() failed to destroy $i"
+		fi
+	done
+	exit $rc
+}
+
+trap 'err $LINENO cleanup' ERR
+
+json=$($NDCTL list -R -b ACPI.NFIT)
+region=$(echo $json | jq -r "[.[] | select(.available_size >= $MIN_AVAIL)][0].dev")
+avail=$(echo $json | jq -r "[.[] | select(.available_size >= $MIN_AVAIL)][0].available_size")
+if [ -z $region ]; then
+	exit $SKIP
+fi
+
+iter=$((avail/TEST_SIZE))
+if [ $iter -gt $MAX_NS ]; then
+	iter=$MAX_NS;
+fi
+
+for i in $(seq 1 $iter)
+do
+	json=$($NDCTL create-namespace -s $TEST_SIZE --no-autorecover -r $region -n "$NAME")
+	dev=$(echo $json | jq -r ".blockdev")
+	mkfs.ext4 -b 4096 /dev/$dev
+	mount -o dax /dev/$dev $MNT
+	umount $MNT
+done
+
+namespaces=$($NDCTL list -N | jq -r ".[] | select(.name==\"$NAME\") | .dev")
+for i in $namespaces
+do
+	$NDCTL disable-namespace $i
+	$NDCTL enable-namespace $i
+	$NDCTL destroy-namespace $i -f
+done
+
+rc=$SUCCESS
+cleanup $LINENO

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 19/26] ndctl/namespace: Kill off the legacy mode names
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (17 preceding siblings ...)
  2019-07-27 21:40 ` [ndctl PATCH v2 18/26] ndctl/test: Exercise sub-section sized namespace creation/deletion Dan Williams
@ 2019-07-27 21:41 ` Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 20/26] ndctl/namespace: Introduce mode-to-name and name-to-mode helpers Dan Williams
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:41 UTC (permalink / raw)
  To: linux-nvdimm

The command line interface switched to "fsdax", "devdax", and "sector"
for the mode names. Kill off the remaining instances of "memory", "dax",
and "safe".

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/lib/libndctl.c |    4 ++-
 ndctl/libndctl.h     |    1 +
 ndctl/namespace.c    |   66 +++++++++++++++++++++++++-------------------------
 test/libndctl.c      |    6 ++---
 util/filter.c        |    4 ++-
 util/json.c          |    4 ++-
 6 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index c1ecdd8c9c61..e81d64dc8aa8 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -3405,7 +3405,7 @@ static const char *enforce_id_to_name(enum ndctl_namespace_mode mode)
 {
 	static const char *id_to_name[] = {
 		[NDCTL_NS_MODE_MEMORY] = "pfn",
-		[NDCTL_NS_MODE_SAFE] = "btt", /* TODO: convert to btt2 */
+		[NDCTL_NS_MODE_SECTOR] = "btt", /* TODO: convert to btt2 */
 		[NDCTL_NS_MODE_RAW] = "",
 		[NDCTL_NS_MODE_DAX] = "dax",
 		[NDCTL_NS_MODE_UNKNOWN] = "<unknown>",
@@ -3728,7 +3728,7 @@ NDCTL_EXPORT enum ndctl_namespace_mode ndctl_namespace_get_mode(
 	if (strcmp("raw", buf) == 0)
 		return NDCTL_NS_MODE_RAW;
 	if (strcmp("safe", buf) == 0)
-		return NDCTL_NS_MODE_SAFE;
+		return NDCTL_NS_MODE_SECTOR;
 	return -ENXIO;
 }
 
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index c9d0dc120d3b..f3f2ef66c5a8 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -472,6 +472,7 @@ enum ndctl_namespace_mode {
 	NDCTL_NS_MODE_MEMORY,
 	NDCTL_NS_MODE_FSDAX = NDCTL_NS_MODE_MEMORY,
 	NDCTL_NS_MODE_SAFE,
+	NDCTL_NS_MODE_SECTOR = NDCTL_NS_MODE_SAFE,
 	NDCTL_NS_MODE_RAW,
 	NDCTL_NS_MODE_DAX,
 	NDCTL_NS_MODE_DEVDAX = NDCTL_NS_MODE_DAX,
diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index e5a2b1341cdb..f958726a994d 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -225,9 +225,9 @@ static int set_defaults(enum device_action mode)
 		}
 	} else if (!param.reconfig && param.type) {
 		if (strcmp(param.type, "pmem") == 0)
-			param.mode = "memory";
+			param.mode = "fsdax";
 		else
-			param.mode = "safe";
+			param.mode = "sector";
 		param.mode_default = true;
 	}
 
@@ -242,9 +242,9 @@ static int set_defaults(enum device_action mode)
 		}
 
 		if (!param.reconfig && param.mode
-				&& strcmp(param.mode, "memory") != 0
-				&& strcmp(param.mode, "dax") != 0) {
-			error("--map only valid for an dax mode pmem namespace\n");
+				&& strcmp(param.mode, "fsdax") != 0
+				&& strcmp(param.mode, "devdax") != 0) {
+			error("--map only valid for an devdax mode pmem namespace\n");
 			rc = -EINVAL;
 		}
 	} else if (!param.reconfig)
@@ -252,8 +252,8 @@ static int set_defaults(enum device_action mode)
 
 	/* check for incompatible mode and type combinations */
 	if (param.type && param.mode && strcmp(param.type, "blk") == 0
-			&& (strcmp(param.mode, "memory") == 0
-				|| strcmp(param.mode, "dax") == 0)) {
+			&& (strcmp(param.mode, "fsdax") == 0
+				|| strcmp(param.mode, "devdax") == 0)) {
 		error("only 'pmem' namespaces support dax operation\n");
 		rc = -ENXIO;
 	}
@@ -377,7 +377,7 @@ do { \
 static bool do_setup_pfn(struct ndctl_namespace *ndns,
 		struct parsed_parameters *p)
 {
-	if (p->mode != NDCTL_NS_MODE_MEMORY)
+	if (p->mode != NDCTL_NS_MODE_FSDAX)
 		return false;
 
 	/*
@@ -385,7 +385,7 @@ static bool do_setup_pfn(struct ndctl_namespace *ndns,
 	 * instance, and a pfn device is required to place the memmap
 	 * array in device memory.
 	 */
-	if (!ndns || ndctl_namespace_get_mode(ndns) != NDCTL_NS_MODE_MEMORY
+	if (!ndns || ndctl_namespace_get_mode(ndns) != NDCTL_NS_MODE_FSDAX
 			|| p->loc == NDCTL_PFN_LOC_PMEM)
 		return true;
 
@@ -419,7 +419,7 @@ static int setup_namespace(struct ndctl_region *region,
 		if (i < num)
 			try(ndctl_namespace, set_sector_size, ndns,
 					p->sector_size);
-		else if (p->mode == NDCTL_NS_MODE_SAFE)
+		else if (p->mode == NDCTL_NS_MODE_SECTOR)
 			/* pass, the btt sector_size will override */;
 		else if (p->sector_size != 512) {
 			error("%s: sector_size: %ld not supported\n",
@@ -450,7 +450,7 @@ static int setup_namespace(struct ndctl_region *region,
 		rc = ndctl_pfn_enable(pfn);
 		if (rc && p->autorecover)
 			ndctl_pfn_set_namespace(pfn, NULL);
-	} else if (p->mode == NDCTL_NS_MODE_DAX) {
+	} else if (p->mode == NDCTL_NS_MODE_DEVDAX) {
 		struct ndctl_dax *dax = ndctl_region_get_dax_seed(region);
 
 		try(ndctl_dax, set_uuid, dax, uuid);
@@ -461,7 +461,7 @@ static int setup_namespace(struct ndctl_region *region,
 		rc = ndctl_dax_enable(dax);
 		if (rc && p->autorecover)
 			ndctl_dax_set_namespace(dax, NULL);
-	} else if (p->mode == NDCTL_NS_MODE_SAFE) {
+	} else if (p->mode == NDCTL_NS_MODE_SECTOR) {
 		struct ndctl_btt *btt = ndctl_region_get_btt_seed(region);
 
 		/*
@@ -560,28 +560,28 @@ static int validate_namespace_options(struct ndctl_region *region,
 
 	if (param.mode) {
 		if (strcmp(param.mode, "memory") == 0)
-			p->mode = NDCTL_NS_MODE_MEMORY;
+			p->mode = NDCTL_NS_MODE_FSDAX;
 		else if (strcmp(param.mode, "sector") == 0)
-			p->mode = NDCTL_NS_MODE_SAFE;
+			p->mode = NDCTL_NS_MODE_SECTOR;
 		else if (strcmp(param.mode, "safe") == 0)
-			p->mode = NDCTL_NS_MODE_SAFE;
+			p->mode = NDCTL_NS_MODE_SECTOR;
 		else if (strcmp(param.mode, "dax") == 0)
-			p->mode = NDCTL_NS_MODE_DAX;
+			p->mode = NDCTL_NS_MODE_DEVDAX;
 		else
 			p->mode = NDCTL_NS_MODE_RAW;
 
 		if (ndctl_region_get_type(region) != ND_DEVICE_REGION_PMEM
-				&& (p->mode == NDCTL_NS_MODE_MEMORY
-					|| p->mode == NDCTL_NS_MODE_DAX)) {
+				&& (p->mode == NDCTL_NS_MODE_FSDAX
+					|| p->mode == NDCTL_NS_MODE_DEVDAX)) {
 			debug("blk %s does not support %s mode\n", region_name,
-					p->mode == NDCTL_NS_MODE_MEMORY
+					p->mode == NDCTL_NS_MODE_FSDAX
 					? "fsdax" : "devdax");
 			return -EAGAIN;
 		}
 	} else if (ndns)
 		p->mode = ndctl_namespace_get_mode(ndns);
 
-	if (p->mode == NDCTL_NS_MODE_MEMORY) {
+	if (p->mode == NDCTL_NS_MODE_FSDAX) {
 		pfn = ndctl_region_get_pfn_seed(region);
 		if (!pfn && param.mode_default) {
 			debug("%s fsdax mode not available\n", region_name);
@@ -590,7 +590,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 		/*
 		 * NB: We only fail validation if a pfn-specific option is used
 		 */
-	} else if (p->mode == NDCTL_NS_MODE_DAX) {
+	} else if (p->mode == NDCTL_NS_MODE_DEVDAX) {
 		dax = ndctl_region_get_dax_seed(region);
 		if (!dax) {
 			error("Kernel does not support devdax mode\n");
@@ -602,7 +602,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 		int i, alignments;
 
 		switch (p->mode) {
-		case NDCTL_NS_MODE_MEMORY:
+		case NDCTL_NS_MODE_FSDAX:
 			if (!pfn) {
 				error("Kernel does not support setting an alignment in fsdax mode\n");
 				return -EINVAL;
@@ -611,13 +611,13 @@ static int validate_namespace_options(struct ndctl_region *region,
 			alignments = ndctl_pfn_get_num_alignments(pfn);
 			break;
 
-		case NDCTL_NS_MODE_DAX:
+		case NDCTL_NS_MODE_DEVDAX:
 			alignments = ndctl_dax_get_num_alignments(dax);
 			break;
 
 		default:
 			error("%s mode does not support setting an alignment\n",
-					p->mode == NDCTL_NS_MODE_SAFE
+					p->mode == NDCTL_NS_MODE_SECTOR
 					? "sector" : "raw");
 			return -ENXIO;
 		}
@@ -626,7 +626,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 		for (i = 0; i < alignments; i++) {
 			uint64_t a;
 
-			if (p->mode == NDCTL_NS_MODE_MEMORY)
+			if (p->mode == NDCTL_NS_MODE_FSDAX)
 				a = ndctl_pfn_get_supported_alignment(pfn, i);
 			else
 				a = ndctl_dax_get_supported_alignment(dax, i);
@@ -645,7 +645,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 		 * one. If we don't then use PAGE_SIZE so the size_align
 		 * checking works.
 		 */
-		if (p->mode == NDCTL_NS_MODE_MEMORY) {
+		if (p->mode == NDCTL_NS_MODE_FSDAX) {
 			/*
 			 * The initial pfn device support in the kernel didn't
 			 * have the 'align' sysfs attribute and assumed a 2MB
@@ -656,7 +656,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 				p->align = ndctl_pfn_get_align(pfn);
 			else
 				p->align = SZ_2M;
-		} else if (p->mode == NDCTL_NS_MODE_DAX) {
+		} else if (p->mode == NDCTL_NS_MODE_DEVDAX) {
 			/*
 			 * device dax mode was added after the align attribute
 			 * so checking for it is unnecessary.
@@ -717,7 +717,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 
 		p->sector_size = parse_size64(param.sector_size);
 		btt = ndctl_region_get_btt_seed(region);
-		if (p->mode == NDCTL_NS_MODE_SAFE) {
+		if (p->mode == NDCTL_NS_MODE_SECTOR) {
 			if (!btt) {
 				debug("%s: does not support 'sector' mode\n",
 						region_name);
@@ -757,7 +757,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 		 * sector size, otherwise fall back to what the
 		 * namespace supports.
 		 */
-		if (btt && p->mode == NDCTL_NS_MODE_SAFE)
+		if (btt && p->mode == NDCTL_NS_MODE_SECTOR)
 			p->sector_size = ndctl_btt_get_sector_size(btt);
 		else
 			p->sector_size = ndctl_namespace_get_sector_size(ndns);
@@ -784,14 +784,14 @@ static int validate_namespace_options(struct ndctl_region *region,
 		else
 			p->loc = NDCTL_PFN_LOC_PMEM;
 
-		if (ndns && p->mode != NDCTL_NS_MODE_MEMORY
-			&& p->mode != NDCTL_NS_MODE_DAX) {
+		if (ndns && p->mode != NDCTL_NS_MODE_FSDAX
+			&& p->mode != NDCTL_NS_MODE_DEVDAX) {
 			debug("%s: --map= only valid for fsdax mode namespace\n",
 				ndctl_namespace_get_devname(ndns));
 			return -EINVAL;
 		}
-	} else if (p->mode == NDCTL_NS_MODE_MEMORY
-			|| p->mode == NDCTL_NS_MODE_DAX)
+	} else if (p->mode == NDCTL_NS_MODE_FSDAX
+			|| p->mode == NDCTL_NS_MODE_DEVDAX)
 		p->loc = NDCTL_PFN_LOC_PMEM;
 
 	if (!pfn && do_setup_pfn(ndns, p)) {
diff --git a/test/libndctl.c b/test/libndctl.c
index 02bb9ccaa465..daddbf919b79 100644
--- a/test/libndctl.c
+++ b/test/libndctl.c
@@ -1080,7 +1080,7 @@ static int check_btt_create(struct ndctl_region *region, struct ndctl_namespace
 		devname = ndctl_btt_get_devname(btt);
 		ndctl_btt_set_uuid(btt, btt_s->uuid);
 		ndctl_btt_set_sector_size(btt, btt_s->sector_sizes[i]);
-		rc = ndctl_namespace_set_enforce_mode(ndns, NDCTL_NS_MODE_SAFE);
+		rc = ndctl_namespace_set_enforce_mode(ndns, NDCTL_NS_MODE_SECTOR);
 		if (ndctl_test_attempt(test, KERNEL_VERSION(4, 13, 0)) && rc < 0) {
 			fprintf(stderr, "%s: failed to enforce btt mode\n", devname);
 			goto err;
@@ -1100,7 +1100,7 @@ static int check_btt_create(struct ndctl_region *region, struct ndctl_namespace
 		/* prior to v4.5 the mode attribute did not exist */
 		if (ndctl_test_attempt(test, KERNEL_VERSION(4, 5, 0))) {
 			mode = ndctl_namespace_get_mode(ndns);
-			if (mode >= 0 && mode != NDCTL_NS_MODE_SAFE)
+			if (mode >= 0 && mode != NDCTL_NS_MODE_SECTOR)
 				fprintf(stderr, "%s: expected safe mode got: %d\n",
 						devname, mode);
 		}
@@ -1474,7 +1474,7 @@ static int check_btt_autodetect(struct ndctl_bus *bus,
 
 	mode = ndctl_namespace_get_enforce_mode(ndns);
 	if (ndctl_test_attempt(test, KERNEL_VERSION(4, 13, 0))
-			&& mode != NDCTL_NS_MODE_SAFE) {
+			&& mode != NDCTL_NS_MODE_SECTOR) {
 		fprintf(stderr, "%s expected enforce_mode btt\n", devname);
 		return -ENXIO;
 	}
diff --git a/util/filter.c b/util/filter.c
index 1734bce537f1..ce6239fbac3b 100644
--- a/util/filter.c
+++ b/util/filter.c
@@ -345,9 +345,9 @@ static enum ndctl_namespace_mode mode_to_type(const char *mode)
 	else if (strcasecmp(mode, "fsdax") == 0)
 		return NDCTL_NS_MODE_MEMORY;
 	else if (strcasecmp(mode, "sector") == 0)
-		return NDCTL_NS_MODE_SAFE;
+		return NDCTL_NS_MODE_SECTOR;
 	else if (strcasecmp(mode, "safe") == 0)
-		return NDCTL_NS_MODE_SAFE;
+		return NDCTL_NS_MODE_SECTOR;
 	else if (strcasecmp(mode, "dax") == 0)
 		return NDCTL_NS_MODE_DAX;
 	else if (strcasecmp(mode, "devdax") == 0)
diff --git a/util/json.c b/util/json.c
index babdc8c47565..3e171e7672ae 100644
--- a/util/json.c
+++ b/util/json.c
@@ -904,7 +904,7 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns,
 		jobj = json_object_new_string("devdax");
 		loc = ndctl_dax_get_location(dax);
 		break;
-	case NDCTL_NS_MODE_SAFE:
+	case NDCTL_NS_MODE_SECTOR:
 		if (!btt)
 			goto err;
 		jobj = json_object_new_string("sector");
@@ -920,7 +920,7 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns,
 	if (jobj)
 		json_object_object_add(jndns, "mode", jobj);
 
-	if ((mode != NDCTL_NS_MODE_SAFE) && (mode != NDCTL_NS_MODE_RAW)) {
+	if ((mode != NDCTL_NS_MODE_SECTOR) && (mode != NDCTL_NS_MODE_RAW)) {
 		jobj = json_object_new_string(locations[loc]);
 		if (jobj)
 			json_object_object_add(jndns, "map", jobj);

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 20/26] ndctl/namespace: Introduce mode-to-name and name-to-mode helpers
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (18 preceding siblings ...)
  2019-07-27 21:41 ` [ndctl PATCH v2 19/26] ndctl/namespace: Kill off the legacy mode names Dan Williams
@ 2019-07-27 21:41 ` Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 21/26] ndctl/namespace: Validate namespace size within validate_namespace_options() Dan Williams
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:41 UTC (permalink / raw)
  To: linux-nvdimm

Before open coding yet another translation between modes and their text
name, introduce a util_nsmode() and util_nsmode_name() helpers.

Consolidate the existing mode_to_type() helper into the new common /
public util.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/namespace.c |   39 +++++++--------------------------------
 util/filter.c     |   42 +++++++++++++++++++++++++++---------------
 util/filter.h     |    3 +++
 3 files changed, 37 insertions(+), 47 deletions(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index f958726a994d..43a5fccac491 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -205,21 +205,7 @@ static int set_defaults(enum device_action mode)
 		param.type = "pmem";
 
 	if (param.mode) {
-		if (strcmp(param.mode, "safe") == 0)
-			/* pass */;
-		else if (strcmp(param.mode, "sector") == 0)
-		      param.mode = "safe"; /* pass */
-		else if (strcmp(param.mode, "memory") == 0)
-		      /* pass */;
-		else if (strcmp(param.mode, "fsdax") == 0)
-			param.mode = "memory"; /* pass */
-		else if (strcmp(param.mode, "raw") == 0)
-		      /* pass */;
-		else if (strcmp(param.mode, "dax") == 0)
-		      /* pass */;
-		else if (strcmp(param.mode, "devdax") == 0)
-			param.mode = "dax"; /* pass */
-		else {
+		if (util_nsmode(param.mode) == NDCTL_NS_MODE_UNKNOWN) {
 			error("invalid mode '%s'\n", param.mode);
 			rc = -EINVAL;
 		}
@@ -285,7 +271,7 @@ static int set_defaults(enum device_action mode)
 			rc = -EINVAL;
 		}
 	} else if (((param.type && strcmp(param.type, "blk") == 0)
-			|| (param.mode && strcmp(param.mode, "safe") == 0))) {
+			|| util_nsmode(param.mode) == NDCTL_NS_MODE_SECTOR)) {
 		/* default sector size for blk-type or safe-mode */
 		param.sector_size = "4096";
 	}
@@ -559,23 +545,12 @@ static int validate_namespace_options(struct ndctl_region *region,
 	}
 
 	if (param.mode) {
-		if (strcmp(param.mode, "memory") == 0)
-			p->mode = NDCTL_NS_MODE_FSDAX;
-		else if (strcmp(param.mode, "sector") == 0)
-			p->mode = NDCTL_NS_MODE_SECTOR;
-		else if (strcmp(param.mode, "safe") == 0)
-			p->mode = NDCTL_NS_MODE_SECTOR;
-		else if (strcmp(param.mode, "dax") == 0)
-			p->mode = NDCTL_NS_MODE_DEVDAX;
-		else
-			p->mode = NDCTL_NS_MODE_RAW;
-
+		p->mode = util_nsmode(param.mode);
 		if (ndctl_region_get_type(region) != ND_DEVICE_REGION_PMEM
 				&& (p->mode == NDCTL_NS_MODE_FSDAX
 					|| p->mode == NDCTL_NS_MODE_DEVDAX)) {
 			debug("blk %s does not support %s mode\n", region_name,
-					p->mode == NDCTL_NS_MODE_FSDAX
-					? "fsdax" : "devdax");
+					util_nsmode_name(p->mode));
 			return -EAGAIN;
 		}
 	} else if (ndns)
@@ -593,7 +568,8 @@ static int validate_namespace_options(struct ndctl_region *region,
 	} else if (p->mode == NDCTL_NS_MODE_DEVDAX) {
 		dax = ndctl_region_get_dax_seed(region);
 		if (!dax) {
-			error("Kernel does not support devdax mode\n");
+			error("Kernel does not support %s mode\n",
+					util_nsmode_name(p->mode));
 			return -ENODEV;
 		}
 	}
@@ -617,8 +593,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 
 		default:
 			error("%s mode does not support setting an alignment\n",
-					p->mode == NDCTL_NS_MODE_SECTOR
-					? "sector" : "raw");
+					util_nsmode_name(p->mode));
 			return -ENXIO;
 		}
 
diff --git a/util/filter.c b/util/filter.c
index ce6239fbac3b..e4b1885b26f8 100644
--- a/util/filter.c
+++ b/util/filter.c
@@ -335,29 +335,41 @@ struct daxctl_dev *util_daxctl_dev_filter(struct daxctl_dev *dev,
 	return NULL;
 }
 
-static enum ndctl_namespace_mode mode_to_type(const char *mode)
+enum ndctl_namespace_mode util_nsmode(const char *mode)
 {
 	if (!mode)
-		return -ENXIO;
-
+		return NDCTL_NS_MODE_UNKNOWN;
 	if (strcasecmp(mode, "memory") == 0)
-		return NDCTL_NS_MODE_MEMORY;
-	else if (strcasecmp(mode, "fsdax") == 0)
-		return NDCTL_NS_MODE_MEMORY;
-	else if (strcasecmp(mode, "sector") == 0)
+		return NDCTL_NS_MODE_FSDAX;
+	if (strcasecmp(mode, "fsdax") == 0)
+		return NDCTL_NS_MODE_FSDAX;
+	if (strcasecmp(mode, "sector") == 0)
 		return NDCTL_NS_MODE_SECTOR;
-	else if (strcasecmp(mode, "safe") == 0)
+	if (strcasecmp(mode, "safe") == 0)
 		return NDCTL_NS_MODE_SECTOR;
-	else if (strcasecmp(mode, "dax") == 0)
-		return NDCTL_NS_MODE_DAX;
-	else if (strcasecmp(mode, "devdax") == 0)
-		return NDCTL_NS_MODE_DAX;
-	else if (strcasecmp(mode, "raw") == 0)
+	if (strcasecmp(mode, "dax") == 0)
+		return NDCTL_NS_MODE_DEVDAX;
+	if (strcasecmp(mode, "devdax") == 0)
+		return NDCTL_NS_MODE_DEVDAX;
+	if (strcasecmp(mode, "raw") == 0)
 		return NDCTL_NS_MODE_RAW;
 
 	return NDCTL_NS_MODE_UNKNOWN;
 }
 
+const char *util_nsmode_name(enum ndctl_namespace_mode mode)
+{
+	static const char *modes[] = {
+		[NDCTL_NS_MODE_FSDAX] = "fsdax",
+		[NDCTL_NS_MODE_DEVDAX] = "devdax",
+		[NDCTL_NS_MODE_RAW] = "raw",
+		[NDCTL_NS_MODE_SECTOR] = "sector",
+		[NDCTL_NS_MODE_UNKNOWN] = "unknown",
+	};
+
+	return modes[mode];
+}
+
 int util_filter_walk(struct ndctl_ctx *ctx, struct util_filter_ctx *fctx,
 		struct util_filter_params *param)
 {
@@ -380,7 +392,7 @@ int util_filter_walk(struct ndctl_ctx *ctx, struct util_filter_ctx *fctx,
 			type = ND_DEVICE_REGION_BLK;
 	}
 
-	if (mode_to_type(param->mode) == NDCTL_NS_MODE_UNKNOWN) {
+	if (param->mode && util_nsmode(param->mode) == NDCTL_NS_MODE_UNKNOWN) {
 		error("invalid mode: '%s'\n", param->mode);
 		return -EINVAL;
 	}
@@ -458,7 +470,7 @@ int util_filter_walk(struct ndctl_ctx *ctx, struct util_filter_ctx *fctx,
 					continue;
 
 				mode = ndctl_namespace_get_mode(ndns);
-				if (param->mode && mode_to_type(param->mode) != mode)
+				if (param->mode && util_nsmode(param->mode) != mode)
 					continue;
 
 				fctx->filter_namespace(ndns, fctx);
diff --git a/util/filter.h b/util/filter.h
index c2cdddf5be54..55f78f2a4cf7 100644
--- a/util/filter.h
+++ b/util/filter.h
@@ -38,6 +38,9 @@ struct ndctl_region *util_region_filter_by_namespace(struct ndctl_region *region
 struct daxctl_dev *util_daxctl_dev_filter(struct daxctl_dev *dev,
 		const char *ident);
 
+enum ndctl_namespace_mode util_nsmode(const char *mode);
+const char *util_nsmode_name(enum ndctl_namespace_mode mode);
+
 struct json_object;
 
 /* json object hierarchy for the util_filter_walk() performed by cmd_list() */

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 21/26] ndctl/namespace: Validate namespace size within validate_namespace_options()
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (19 preceding siblings ...)
  2019-07-27 21:41 ` [ndctl PATCH v2 20/26] ndctl/namespace: Introduce mode-to-name and name-to-mode helpers Dan Williams
@ 2019-07-27 21:41 ` Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 22/26] ndctl/namespace: Clarify 16M minimum size requirement Dan Williams
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:41 UTC (permalink / raw)
  To: linux-nvdimm

Currently validate_namespace_options() handles default option conversion
for every namespace attribute except size. Move default size validation
internal to that helper in advance of teaching ndctl to require
namespace be at least 16M in size to host a metadata personality /
address abstraction.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/namespace.c |   50 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 17 deletions(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 43a5fccac491..69900c4e4e60 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -489,6 +489,29 @@ static int is_namespace_active(struct ndctl_namespace *ndns)
 		|| ndctl_namespace_get_btt(ndns));
 }
 
+static int validate_available_capacity(struct ndctl_region *region,
+		struct parsed_parameters *p)
+{
+	unsigned long long available;
+
+	if (ndctl_region_get_nstype(region) == ND_DEVICE_NAMESPACE_IO)
+		available = ndctl_region_get_size(region);
+	else {
+		available = ndctl_region_get_max_available_extent(region);
+		if (available == ULLONG_MAX)
+			available = ndctl_region_get_available_size(region);
+	}
+	if (!available || p->size > available) {
+		debug("%s: insufficient capacity size: %llx avail: %llx\n",
+			ndctl_region_get_devname(region), p->size, available);
+		return -EAGAIN;
+	}
+
+	if (p->size == 0)
+		p->size = available;
+	return 0;
+}
+
 /*
  * validate_namespace_options - init parameters for setup_namespace
  * @region: parent of the namespace to create / reconfigure
@@ -526,6 +549,16 @@ static int validate_namespace_options(struct ndctl_region *region,
 	else if (ndns)
 		p->size = ndctl_namespace_get_size(ndns);
 
+	/*
+	 * Validate available capacity in the create case, in the
+	 * reconfigure case the capacity is already allocated.
+	 */
+	if (!ndns) {
+		rc = validate_available_capacity(region, p);
+		if (rc)
+			return rc;
+	}
+
 	if (param.uuid) {
 		if (uuid_parse(param.uuid, p->uuid) != 0) {
 			debug("%s: invalid uuid\n", __func__);
@@ -797,7 +830,6 @@ static struct ndctl_namespace *region_get_namespace(struct ndctl_region *region)
 static int namespace_create(struct ndctl_region *region)
 {
 	const char *devname = ndctl_region_get_devname(region);
-	unsigned long long available;
 	struct ndctl_namespace *ndns;
 	struct parsed_parameters p;
 	int rc;
@@ -812,22 +844,6 @@ static int namespace_create(struct ndctl_region *region)
 		return -EAGAIN;
 	}
 
-	if (ndctl_region_get_nstype(region) == ND_DEVICE_NAMESPACE_IO)
-		available = ndctl_region_get_size(region);
-	else {
-		available = ndctl_region_get_max_available_extent(region);
-		if (available == ULLONG_MAX)
-			available = ndctl_region_get_available_size(region);
-	}
-	if (!available || p.size > available) {
-		debug("%s: insufficient capacity size: %llx avail: %llx\n",
-			devname, p.size, available);
-		return -EAGAIN;
-	}
-
-	if (p.size == 0)
-		p.size = available;
-
 	ndns = region_get_namespace(region);
 	if (!ndns || is_namespace_active(ndns)) {
 		debug("%s: no %s namespace seed\n", devname,

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 22/26] ndctl/namespace: Clarify 16M minimum size requirement
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (20 preceding siblings ...)
  2019-07-27 21:41 ` [ndctl PATCH v2 21/26] ndctl/namespace: Validate namespace size within validate_namespace_options() Dan Williams
@ 2019-07-27 21:41 ` Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 23/26] ndctl/namespace: Report ENOSPC when regions are full Dan Williams
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:41 UTC (permalink / raw)
  To: linux-nvdimm

The kernel enforces a minimum size for any "claimed" namespace i.e. any
namespace that is wrapped in an address abstraction like the btt or
devdax. The "no such device or address" default print is confusing, so
replace with an explicit error message.

Reported-by: Jane Chu <jane.chu@oracle.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/namespace.c |   21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 69900c4e4e60..75ea366574f8 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -534,6 +534,7 @@ static int validate_namespace_options(struct ndctl_region *region,
 	unsigned long long size_align, units = 1, resource;
 	struct ndctl_pfn *pfn = NULL;
 	struct ndctl_dax *dax = NULL;
+	bool default_size = false;
 	unsigned int ways;
 	int rc = 0;
 
@@ -548,10 +549,13 @@ static int validate_namespace_options(struct ndctl_region *region,
 		p->size = __parse_size64(param.size, &units);
 	else if (ndns)
 		p->size = ndctl_namespace_get_size(ndns);
+	else
+		default_size = true;
 
 	/*
 	 * Validate available capacity in the create case, in the
-	 * reconfigure case the capacity is already allocated.
+	 * reconfigure case the capacity is already allocated. A default
+	 * size will be established from available capacity.
 	 */
 	if (!ndns) {
 		rc = validate_available_capacity(region, p);
@@ -719,6 +723,21 @@ static int validate_namespace_options(struct ndctl_region *region,
 		return -EINVAL;
 	}
 
+	/*
+	 * Catch attempts to create sub-16M namespaces to match the
+	 * kernel's restriction (see nd_namespace_store())
+	 */
+	if (p->size < SZ_16M && p->mode != NDCTL_NS_MODE_RAW) {
+		if (default_size) {
+			debug("%s: insufficient capacity for mode: %s\n",
+					region_name, util_nsmode_name(p->mode));
+			return -EAGAIN;
+		}
+		error("'--size=' must be >= 16MiB for '%s' mode\n",
+				util_nsmode_name(p->mode));
+		return -EINVAL;
+	}
+
 	if (param.sector_size) {
 		struct ndctl_btt *btt;
 		int num, i;

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 23/26] ndctl/namespace: Report ENOSPC when regions are full
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (21 preceding siblings ...)
  2019-07-27 21:41 ` [ndctl PATCH v2 22/26] ndctl/namespace: Clarify 16M minimum size requirement Dan Williams
@ 2019-07-27 21:41 ` Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 24/26] ndctl/test: Regression test 'failed to track' Dan Williams
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:41 UTC (permalink / raw)
  To: linux-nvdimm

The create-namespace error message:

    failed to create namespace: Resource temporarily unavailable

...is misleading because the lack of capacity is permanent until the
user frees up space.

Trap EAGAIN and translate to ENOSPC in case the region capacity search
fails:

    failed to create namespace: No space left on device

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/namespace.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 75ea366574f8..f215f77a94e1 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -1806,6 +1806,15 @@ static int do_xaction_namespace(const char *namespace,
 	if (ri_ctx.f_out && ri_ctx.f_out != stdout)
 		fclose(ri_ctx.f_out);
 
+	if (action == ACTION_CREATE && rc == -EAGAIN) {
+		/*
+		 * Namespace creation searched through all candidate
+		 * regions and all of them said "nope, I don't have
+		 * enough capacity", so report -ENOSPC
+		 */
+		rc = -ENOSPC;
+	}
+
 	return rc;
 }
 

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 24/26] ndctl/test: Regression test 'failed to track'
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (22 preceding siblings ...)
  2019-07-27 21:41 ` [ndctl PATCH v2 23/26] ndctl/namespace: Report ENOSPC when regions are full Dan Williams
@ 2019-07-27 21:41 ` Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 25/26] ndctl/namespace: Continue region search on 'missing seed' event Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 26/26] ndctl/monitor: Allow monitor to be manually moved to the background Dan Williams
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:41 UTC (permalink / raw)
  To: linux-nvdimm

Exercise the failing condition behind kernel commit c4703ce11c23
"libnvdimm/namespace: Fix label tracking error", i.e. rename (change
uuid) allocated namespace capacity.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 test/Makefile.am   |    3 ++-
 test/track-uuid.sh |   41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)
 create mode 100755 test/track-uuid.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index decc8377258a..782b01cc4a97 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -25,7 +25,8 @@ TESTS =\
 	inject-smart.sh \
 	monitor.sh \
 	max_available_extent_ns.sh \
-	pfn-meta-errors.sh
+	pfn-meta-errors.sh \
+	track-uuid.sh
 
 check_PROGRAMS =\
 	libndctl \
diff --git a/test/track-uuid.sh b/test/track-uuid.sh
new file mode 100755
index 000000000000..ece11193f01d
--- /dev/null
+++ b/test/track-uuid.sh
@@ -0,0 +1,41 @@
+#!/bin/bash -Ex
+
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+blockdev=""
+rc=77
+
+. ./common
+
+set -e
+trap 'err $LINENO' ERR
+
+# setup (reset nfit_test dimms)
+modprobe nfit_test
+$NDCTL disable-region -b $NFIT_TEST_BUS0 all
+$NDCTL zero-labels -b $NFIT_TEST_BUS0 all
+$NDCTL enable-region -b $NFIT_TEST_BUS0 all
+
+rc=1
+
+# create a fsdax namespace and clear errors (if any)
+dev="x"
+json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m raw)
+eval "$(echo "$json" | json2var)"
+[ $dev = "x" ] && echo "fail: $LINENO" && exit 1
+
+$NDCTL disable-namespace $dev
+# On broken kernels this reassignment of capacity triggers a warning
+# with the following signature, and results in ENXIO.
+#     WARNING: CPU: 11 PID: 1378 at drivers/nvdimm/label.c:721 __pmem_label_update+0x55d/0x570 [libnvdimm]
+#     Call Trace:
+#      nd_pmem_namespace_label_update+0xd6/0x160 [libnvdimm]
+#      uuid_store+0x15c/0x170 [libnvdimm]
+#      kernfs_fop_write+0xf0/0x1a0
+#      __vfs_write+0x26/0x150
+uuidgen > /sys/bus/nd/devices/$dev/uuid
+$NDCTL enable-namespace $dev
+
+_cleanup
+exit 0

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 25/26] ndctl/namespace: Continue region search on 'missing seed' event
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (23 preceding siblings ...)
  2019-07-27 21:41 ` [ndctl PATCH v2 24/26] ndctl/test: Regression test 'failed to track' Dan Williams
@ 2019-07-27 21:41 ` Dan Williams
  2019-07-27 21:41 ` [ndctl PATCH v2 26/26] ndctl/monitor: Allow monitor to be manually moved to the background Dan Williams
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:41 UTC (permalink / raw)
  To: linux-nvdimm

Consider a scenario where one region is in an error state but another is
not:

    # ndctl list -Ru
    [
      {
        "dev":"region3",
        "size":"127.00 GiB (136.37 GB)",
        "available_size":0,
        "max_available_extent":0,
        "type":"pmem",
        "persistence_domain":"unknown"
      },
      {
        "dev":"region2",
        "size":"127.00 GiB (136.37 GB)",
        "available_size":"127.00 GiB (136.37 GB)",
        "max_available_extent":"127.00 GiB (136.37 GB)",
        "type":"pmem",
        "iset_id":"0xba90120012b4dc",
        "persistence_domain":"unknown"
      }
    ]

    # ndctl create-namespace -m devdax -v
    [..]
    namespace_create:887: region3: no idle namespace seed
    failed to create namespace: No such device

Instead of failing when probing region3 for capacity, fallback to
region2.

    # ndctl create-namespace -m devdax
    {
      "dev":"namespace2.0",
      "mode":"devdax",
      "map":"dev",
      "size":"125.01 GiB (134.23 GB)",
      "uuid":"c3fa7d2f-6c20-4762-9aa8-627d06275e03",
      "daxregion":{
        "id":2,
        "size":"125.01 GiB (134.23 GB)",
        "align":2097152,
        "devices":[
          {
            "chardev":"dax2.0",
            "size":"125.01 GiB (134.23 GB)"
          }
        ]
      },
      "align":2097152
    }

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/namespace.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index f215f77a94e1..bbc9107c6baa 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -867,7 +867,7 @@ static int namespace_create(struct ndctl_region *region)
 	if (!ndns || is_namespace_active(ndns)) {
 		debug("%s: no %s namespace seed\n", devname,
 				ndns ? "idle" : "available");
-		return -ENODEV;
+		return -EAGAIN;
 	}
 
 	rc = setup_namespace(region, ndns, &p);

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* [ndctl PATCH v2 26/26] ndctl/monitor: Allow monitor to be manually moved to the background
  2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
                   ` (24 preceding siblings ...)
  2019-07-27 21:41 ` [ndctl PATCH v2 25/26] ndctl/namespace: Continue region search on 'missing seed' event Dan Williams
@ 2019-07-27 21:41 ` Dan Williams
  25 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-07-27 21:41 UTC (permalink / raw)
  To: linux-nvdimm

Currently attempting to place the monitor into the background results in
an epoll error:

    # ndctl monitor -b nfit_test.0
    ^Z
    [1]+  Stopped                 ndctl monitor -b nfit_test.0
    # bg
    [1]+ ndctl monitor -b nfit_test.0 &
    epoll_wait error

This error is simply a wakeup from a signal EINTR, so allow the monitor
to continue assuming the signal is not fatal.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 ndctl/monitor.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ndctl/monitor.c b/ndctl/monitor.c
index 6829a6b28b58..88adf3e5d6ff 100644
--- a/ndctl/monitor.c
+++ b/ndctl/monitor.c
@@ -357,8 +357,8 @@ static int monitor_event(struct ndctl_ctx *ctx,
 	while (1) {
 		did_fail = 0;
 		nfds = epoll_wait(epollfd, events, mfa->num_dimm, -1);
-		if (nfds <= 0) {
-			err(&monitor, "epoll_wait error\n");
+		if (nfds <= 0 && errno != EINTR) {
+			err(&monitor, "epoll_wait error: (%s)\n", strerror(errno));
 			rc = -errno;
 			goto out;
 		}

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* Re: [ndctl PATCH v2 01/26] ndctl/dimm: Add 'flags' field to read-labels output
  2019-07-27 21:39 ` [ndctl PATCH v2 01/26] ndctl/dimm: Add 'flags' field to read-labels output Dan Williams
@ 2019-08-02 18:01   ` Verma, Vishal L
  2019-08-02 18:19     ` Dan Williams
  0 siblings, 1 reply; 32+ messages in thread
From: Verma, Vishal L @ 2019-08-02 18:01 UTC (permalink / raw)
  To: Williams, Dan J, linux-nvdimm


On Sat, 2019-07-27 at 14:39 -0700, Dan Williams wrote:
> Recent discussions on some platform implementations setting the LOCAL
> bit in namespace labels makes it apparent that this field should be
> decoded in the json representation.
> 
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  ndctl/dimm.c |    5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/ndctl/dimm.c b/ndctl/dimm.c
> index b2b09b6aa9a2..8946dc74fe41 100644
> --- a/ndctl/dimm.c
> +++ b/ndctl/dimm.c
> @@ -141,6 +141,11 @@ static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
>  			break;
>  		json_object_object_add(jlabel, "nlabel", jobj);
>  
> +		jobj = json_object_new_int64(le64_to_cpu(nslabel.flags));

Should we print this in hex instead?

> +		if (!jobj)
> +			break;
> +		json_object_object_add(jlabel, "flags", jobj);
> +
>  		jobj = json_object_new_int64(le64_to_cpu(nslabel.isetcookie));
>  		if (!jobj)
>  			break;
> 

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* Re: [ndctl PATCH v2 01/26] ndctl/dimm: Add 'flags' field to read-labels output
  2019-08-02 18:01   ` Verma, Vishal L
@ 2019-08-02 18:19     ` Dan Williams
  0 siblings, 0 replies; 32+ messages in thread
From: Dan Williams @ 2019-08-02 18:19 UTC (permalink / raw)
  To: Verma, Vishal L; +Cc: linux-nvdimm

On Fri, Aug 2, 2019 at 11:01 AM Verma, Vishal L
<vishal.l.verma@intel.com> wrote:
>
>
> On Sat, 2019-07-27 at 14:39 -0700, Dan Williams wrote:
> > Recent discussions on some platform implementations setting the LOCAL
> > bit in namespace labels makes it apparent that this field should be
> > decoded in the json representation.
> >
> > Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> > ---
> >  ndctl/dimm.c |    5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/ndctl/dimm.c b/ndctl/dimm.c
> > index b2b09b6aa9a2..8946dc74fe41 100644
> > --- a/ndctl/dimm.c
> > +++ b/ndctl/dimm.c
> > @@ -141,6 +141,11 @@ static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
> >                       break;
> >               json_object_object_add(jlabel, "nlabel", jobj);
> >
> > +             jobj = json_object_new_int64(le64_to_cpu(nslabel.flags));
>
> Should we print this in hex instead?

Ah, yes.

/me goes to check why he didn't do this finds that this support
arrives in the next patch that adds --human support to read-labels.

So it's there in "ndctl/dimm: Add --human support to read-labels"
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* Re: [ndctl PATCH v2 14/26] ndctl/namespace: Handle 'create-namespace' in label-less mode
  2019-07-27 21:40 ` [ndctl PATCH v2 14/26] ndctl/namespace: Handle 'create-namespace' in label-less mode Dan Williams
@ 2019-08-21 12:56   ` Michal Suchánek
  2019-08-21 18:03     ` Verma, Vishal L
  0 siblings, 1 reply; 32+ messages in thread
From: Michal Suchánek @ 2019-08-21 12:56 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-nvdimm

Hello,

this patch is marked as superseded in the patchwork.

What is the intended replacement?

Thanks

Michal

On Sat, 27 Jul 2019 14:40:36 -0700
Dan Williams <dan.j.williams@intel.com> wrote:

> A common confusion with ndctl is that 'create-namespace' does not work
> in the label-less case. In the label-less case there is no capacity to
> allocate as the size if already hard-coded by the region boundary.
> 
> However, users typically do something like the following in the
> label-less case:
> 
>     # ndctl list
>     {
>       "dev":"namespace1.0",
>       "mode":"raw",
>       "size":"127.00 GiB (136.37 GB)",
>       "sector_size":512,
>       "blockdev":"pmem1"
>     }
> 
>     # ndctl destroy-namespace namespace1.0 -f
>     destroyed 1 namespace
> 
>     # ndctl create-namespace
>     failed to create namespace: Resource temporarily unavailable
> 
> In other words they destroy the raw mode namespace that they don't want,
> and seek to create a new default configuration namespace. Since there is
> no "available_capacity" in the label-less case the 'create' attempt
> fails.
> 
> Fix this by recognizing that the user wants a default sized namespace
> and just reconfigure the raw namespace.
> 
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  ndctl/namespace.c |   10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/ndctl/namespace.c b/ndctl/namespace.c
> index 58fec194ab94..e5a2b1341cdb 100644
> --- a/ndctl/namespace.c
> +++ b/ndctl/namespace.c
> @@ -837,9 +837,13 @@ static int namespace_create(struct ndctl_region *region)
>  		return -EAGAIN;
>  	}
>  
> -	available = ndctl_region_get_max_available_extent(region);
> -	if (available == ULLONG_MAX)
> -		available = ndctl_region_get_available_size(region);
> +	if (ndctl_region_get_nstype(region) == ND_DEVICE_NAMESPACE_IO)
> +		available = ndctl_region_get_size(region);
> +	else {
> +		available = ndctl_region_get_max_available_extent(region);
> +		if (available == ULLONG_MAX)
> +			available = ndctl_region_get_available_size(region);
> +	}
>  	if (!available || p.size > available) {
>  		debug("%s: insufficient capacity size: %llx avail: %llx\n",
>  			devname, p.size, available);

_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* Re: [ndctl PATCH v2 14/26] ndctl/namespace: Handle 'create-namespace' in label-less mode
  2019-08-21 12:56   ` Michal Suchánek
@ 2019-08-21 18:03     ` Verma, Vishal L
  2019-08-21 18:19       ` Michal Suchánek
  0 siblings, 1 reply; 32+ messages in thread
From: Verma, Vishal L @ 2019-08-21 18:03 UTC (permalink / raw)
  To: Williams, Dan J, msuchanek; +Cc: linux-nvdimm

On Wed, 2019-08-21 at 14:56 +0200, Michal Suchánek wrote:
> Hello,
> 
> this patch is marked as superseded in the patchwork.
> 
> What is the intended replacement?
> 

Hi Michal,

The patch was superseded by v3 of the series, and is present in the
latest release (v66):

7966c92 ndctl/namespace: Handle 'create-namespace' in label-less mode

	-Vishal
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

* Re: [ndctl PATCH v2 14/26] ndctl/namespace: Handle 'create-namespace' in label-less mode
  2019-08-21 18:03     ` Verma, Vishal L
@ 2019-08-21 18:19       ` Michal Suchánek
  0 siblings, 0 replies; 32+ messages in thread
From: Michal Suchánek @ 2019-08-21 18:19 UTC (permalink / raw)
  To: Verma, Vishal L; +Cc: linux-nvdimm

On Wed, 21 Aug 2019 18:03:18 +0000
"Verma, Vishal L" <vishal.l.verma@intel.com> wrote:

> On Wed, 2019-08-21 at 14:56 +0200, Michal Suchánek wrote:
> > Hello,
> > 
> > this patch is marked as superseded in the patchwork.
> > 
> > What is the intended replacement?
> >   
> 
> Hi Michal,
> 
> The patch was superseded by v3 of the series, and is present in the
> latest release (v66):
> 
> 7966c92 ndctl/namespace: Handle 'create-namespace' in label-less mode
> 
> 	-Vishal

I see, it was already merged as part of updated series. Missed that.

Thanks

Michal
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

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

end of thread, other threads:[~2019-08-21 18:20 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-27 21:39 [ndctl PATCH v2 00/26] Improvements for namespace creation/interrogation Dan Williams
2019-07-27 21:39 ` [ndctl PATCH v2 01/26] ndctl/dimm: Add 'flags' field to read-labels output Dan Williams
2019-08-02 18:01   ` Verma, Vishal L
2019-08-02 18:19     ` Dan Williams
2019-07-27 21:39 ` [ndctl PATCH v2 02/26] ndctl/dimm: Add --human support to read-labels Dan Williams
2019-07-27 21:39 ` [ndctl PATCH v2 03/26] ndctl/build: Drop -Wpointer-arith Dan Williams
2019-07-27 21:39 ` [ndctl PATCH v2 04/26] ndctl/namespace: Add read-infoblock command Dan Williams
2019-07-27 21:39 ` [ndctl PATCH v2 05/26] ndctl/test: Update dax-dev to handle multiple e820 ranges Dan Williams
2019-07-27 21:39 ` [ndctl PATCH v2 06/26] ndctl/test: Make dax.sh more robust vs small namespaces Dan Williams
2019-07-27 21:39 ` [ndctl PATCH v2 07/26] ndctl/namespace: Always zero info-blocks Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 08/26] ndctl/dimm: Support small label reads/writes Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 09/26] ndctl/dimm: Minimize data-transfer for init-labels Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 10/26] ndctl/dimm: Add offset and size options to {read, write, zero}-labels Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 11/26] ndctl/dimm: Limit read-labels with --index option Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 12/26] ndctl/namespace: Minimize label data transfer for autolabel Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 13/26] ndctl/namespace: Disable autorecovery of create-namespace failures Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 14/26] ndctl/namespace: Handle 'create-namespace' in label-less mode Dan Williams
2019-08-21 12:56   ` Michal Suchánek
2019-08-21 18:03     ` Verma, Vishal L
2019-08-21 18:19       ` Michal Suchánek
2019-07-27 21:40 ` [ndctl PATCH v2 15/26] ndctl/dimm: Fix init-labels success reporting Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 16/26] ndctl/test: Fix device-dax bus-model detection Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 17/26] ndctl/test: Checkout device-mapper + dax operation Dan Williams
2019-07-27 21:40 ` [ndctl PATCH v2 18/26] ndctl/test: Exercise sub-section sized namespace creation/deletion Dan Williams
2019-07-27 21:41 ` [ndctl PATCH v2 19/26] ndctl/namespace: Kill off the legacy mode names Dan Williams
2019-07-27 21:41 ` [ndctl PATCH v2 20/26] ndctl/namespace: Introduce mode-to-name and name-to-mode helpers Dan Williams
2019-07-27 21:41 ` [ndctl PATCH v2 21/26] ndctl/namespace: Validate namespace size within validate_namespace_options() Dan Williams
2019-07-27 21:41 ` [ndctl PATCH v2 22/26] ndctl/namespace: Clarify 16M minimum size requirement Dan Williams
2019-07-27 21:41 ` [ndctl PATCH v2 23/26] ndctl/namespace: Report ENOSPC when regions are full Dan Williams
2019-07-27 21:41 ` [ndctl PATCH v2 24/26] ndctl/test: Regression test 'failed to track' Dan Williams
2019-07-27 21:41 ` [ndctl PATCH v2 25/26] ndctl/namespace: Continue region search on 'missing seed' event Dan Williams
2019-07-27 21:41 ` [ndctl PATCH v2 26/26] ndctl/monitor: Allow monitor to be manually moved to the background Dan Williams

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).