diff mbox series

[ndctl,3/5] ndctl/dimm: Add offset and size options to {read, write, zero}-labels

Message ID 155183605525.191625.7383205178321396418.stgit@dwillia2-desk3.amr.corp.intel.com (mailing list archive)
State New, archived
Headers show
Series ndctl: Optimize label operations | expand

Commit Message

Dan Williams March 6, 2019, 1:34 a.m. UTC
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                           |   45 ++++++++++++++++++++++++--------
 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, 83 insertions(+), 20 deletions(-)

Comments

Verma, Vishal L March 22, 2019, 9:49 p.m. UTC | #1
On Tue, 2019-03-05 at 17:34 -0800, Dan Williams wrote:
> 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                           |   45 ++++++++++++++++++++++++--------
>  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, 83 insertions(+), 20 deletions(-)
> 

[..]

> diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
> index 5a17f0b63b80..1304017d5e3b 100644
> --- a/ndctl/lib/private.h
> +++ b/ndctl/lib/private.h
> @@ -241,9 +241,6 @@ struct ndctl_namespace {
>   *
>   * A command may only specify one of @source, or @iter.total_buf, not both.
>   */
> -enum {
> -	READ, WRITE,
> -};

This fails to build as libndctl.c now needs to include util/util.h..
Stale version perhaps? (Patch 4 in the series also fails to apply
cleanly)

>  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);
>
Dan Williams March 22, 2019, 10:21 p.m. UTC | #2
On Fri, Mar 22, 2019 at 2:49 PM Verma, Vishal L
<vishal.l.verma@intel.com> wrote:
>
>
> On Tue, 2019-03-05 at 17:34 -0800, Dan Williams wrote:
> > 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                           |   45 ++++++++++++++++++++++++--------
> >  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, 83 insertions(+), 20 deletions(-)
> >
>
> [..]
>
> > diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
> > index 5a17f0b63b80..1304017d5e3b 100644
> > --- a/ndctl/lib/private.h
> > +++ b/ndctl/lib/private.h
> > @@ -241,9 +241,6 @@ struct ndctl_namespace {
> >   *
> >   * A command may only specify one of @source, or @iter.total_buf, not both.
> >   */
> > -enum {
> > -     READ, WRITE,
> > -};
>
> This fails to build as libndctl.c now needs to include util/util.h..
> Stale version perhaps? (Patch 4 in the series also fails to apply
> cleanly)

Hmm, ok I'll resend. It probably depends on something in the
read-infoblock patch that needs to be fixed up.
diff mbox series

Patch

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 5edada678c9c..478e0fea3afc 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 master_pass;
@@ -76,7 +78,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,
@@ -298,15 +300,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;
@@ -342,9 +346,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) {
@@ -353,7 +357,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
@@ -380,9 +384,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) {
@@ -393,7 +397,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);
 
@@ -1072,18 +1076,31 @@  OPT_BOOLEAN('o', "overwrite", &param.overwrite, \
 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(),
@@ -1150,6 +1167,12 @@  static int dimm_action(int argc, const char **argv, struct ndctl_ctx *ctx,
 		return -EINVAL;
 	}
 
+	if (action == action_read && param.json && (param.len || param.offset)) {
+		fprintf(stderr, "--size and --offset are incompatible with --json\n");
+		usage_with_options(u, options);
+		return -EINVAL;
+	}
+
 	if (param.json) {
 		actx.jdimms = json_object_new_array();
 		if (!actx.jdimms)
@@ -1284,7 +1307,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 5a17f0b63b80..1304017d5e3b 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -241,9 +241,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);