@@ -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.
@@ -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", ¶m.overwrite, \
OPT_BOOLEAN('m', "master-passphrase", ¶m.master_pass, \
"use master passphrase")
+#define LABEL_OPTIONS() \
+OPT_UINTEGER('s', "size", ¶m.len, "number of label bytes to operate"), \
+OPT_UINTEGER('O', "offset", ¶m.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,
@@ -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)
{
@@ -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;
@@ -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;
@@ -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,
@@ -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);
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(-)