From patchwork Wed Mar 6 01:34:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Williams X-Patchwork-Id: 10840307 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3BA9717E0 for ; Wed, 6 Mar 2019 01:46:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 246622D07F for ; Wed, 6 Mar 2019 01:46:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 181C12D09F; Wed, 6 Mar 2019 01:46:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6E9C72D07F for ; Wed, 6 Mar 2019 01:46:55 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 66BF2211D56B6; Tue, 5 Mar 2019 17:46:55 -0800 (PST) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.100; helo=mga07.intel.com; envelope-from=dan.j.williams@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D4821211D56AB for ; Tue, 5 Mar 2019 17:46:53 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Mar 2019 17:46:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.58,446,1544515200"; d="scan'208";a="119938921" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.16]) by orsmga007.jf.intel.com with ESMTP; 05 Mar 2019 17:46:52 -0800 Subject: [ndctl PATCH 3/5] ndctl/dimm: Add offset and size options to {read, write, zero}-labels From: Dan Williams To: linux-nvdimm@lists.01.org Date: Tue, 05 Mar 2019 17:34:15 -0800 Message-ID: <155183605525.191625.7383205178321396418.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <155183603979.191625.11689546261255336448.stgit@dwillia2-desk3.amr.corp.intel.com> References: <155183603979.191625.11689546261255336448.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.18-2-gc94f MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Allow for more precision in label utilities, i.e. stop operating over the entire label area. Signed-off-by: Dan Williams --- 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/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", ¶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 [..] []"); 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);