anitazha / rpms / ndctl

Forked from rpms/ndctl 2 years ago
Clone
Jeff Moyer 2c91dc
From 7e98977c10ad5f4baf5e3bc4d5b4b2fd733a8b7e Mon Sep 17 00:00:00 2001
Jeff Moyer 2c91dc
From: Jingqi Liu <jingqi.liu@intel.com>
Jeff Moyer 2c91dc
Date: Thu, 8 Jul 2021 16:14:46 +0800
Jeff Moyer 2c91dc
Subject: [PATCH 027/217] ndctl/dimm: Fix label index block calculations
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
The following bug is caused by setting the size of Label Index Block
Jeff Moyer 2c91dc
to a fixed 256 bytes.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Use the following Qemu command to start a Guest with 2MB label-size:
Jeff Moyer 2c91dc
	-object memory-backend-file,id=mem1,share=on,mem-path=/dev/dax1.1,size=14G,align=2M
Jeff Moyer 2c91dc
	-device nvdimm,memdev=mem1,id=nv1,label-size=2M
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
There is a namespace in the Guest as follows:
Jeff Moyer 2c91dc
	$ ndctl list
Jeff Moyer 2c91dc
	[
Jeff Moyer 2c91dc
	  {
Jeff Moyer 2c91dc
	    "dev":"namespace0.0",
Jeff Moyer 2c91dc
	    "mode":"devdax",
Jeff Moyer 2c91dc
	    "map":"dev",
Jeff Moyer 2c91dc
	    "size":14780727296,
Jeff Moyer 2c91dc
	    "uuid":"58ad5282-5a16-404f-b8ee-e28b4c784eb8",
Jeff Moyer 2c91dc
	    "chardev":"dax0.0",
Jeff Moyer 2c91dc
	    "align":2097152,
Jeff Moyer 2c91dc
	    "name":"namespace0.0"
Jeff Moyer 2c91dc
	  }
Jeff Moyer 2c91dc
	]
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Fail to read labels. The result is as follows:
Jeff Moyer 2c91dc
	$ ndctl read-labels -u nmem0
Jeff Moyer 2c91dc
	[
Jeff Moyer 2c91dc
	]
Jeff Moyer 2c91dc
	read 0 nmem
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
If using the following Qemu command to start the Guest with 128K
Jeff Moyer 2c91dc
label-size, this label can be read correctly.
Jeff Moyer 2c91dc
	-object memory-backend-file,id=mem1,share=on,mem-path=/dev/dax1.1,size=14G,align=2M
Jeff Moyer 2c91dc
	-device nvdimm,memdev=mem1,id=nv1,label-size=128K
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
The size of a Label Index Block depends on how many label slots fit into
Jeff Moyer 2c91dc
the label storage area. The minimum size of an index block is 256 bytes
Jeff Moyer 2c91dc
and the size must be a multiple of 256 bytes. For a storage area of 128KB,
Jeff Moyer 2c91dc
the corresponding Label Index Block size is 256 bytes. But if the label
Jeff Moyer 2c91dc
storage area is not 128KB, the Label Index Block size should not be 256 bytes.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Namespace Label Index Block appears twice at the top of the label storage area.
Jeff Moyer 2c91dc
Following the two index blocks, an array for storing labels takes up the
Jeff Moyer 2c91dc
remainder of the label storage area.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
For obtaining the size of Namespace Index Block, we also cannot rely on
Jeff Moyer 2c91dc
the field of 'mysize' in this index block since it might be corrupted.
Jeff Moyer 2c91dc
Similar to the linux kernel, we use sizeof_namespace_index() to get the size
Jeff Moyer 2c91dc
of Namespace Index Block. Then we can also correctly calculate the starting
Jeff Moyer 2c91dc
offset of the following namespace labels.
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
Link: https://lore.kernel.org/r/20210708081446.14323-1-jingqi.liu@intel.com
Jeff Moyer 2c91dc
Suggested-by: Dan Williams <dan.j.williams@intel.com>
Jeff Moyer 2c91dc
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Jeff Moyer 2c91dc
Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
Jeff Moyer 2c91dc
Signed-off-by: Jingqi Liu <jingqi.liu@intel.com>
Jeff Moyer 2c91dc
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Jeff Moyer 2c91dc
---
Jeff Moyer 2c91dc
 ndctl/dimm.c           | 19 +++++++++++++++----
Jeff Moyer 2c91dc
 ndctl/lib/dimm.c       |  5 +++++
Jeff Moyer 2c91dc
 ndctl/lib/libndctl.sym |  1 +
Jeff Moyer 2c91dc
 ndctl/libndctl.h       |  1 +
Jeff Moyer 2c91dc
 4 files changed, 22 insertions(+), 4 deletions(-)
Jeff Moyer 2c91dc
Jeff Moyer 2c91dc
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
Jeff Moyer 2c91dc
index 09ce49e..1d2d9a2 100644
Jeff Moyer 2c91dc
--- a/ndctl/dimm.c
Jeff Moyer 2c91dc
+++ b/ndctl/dimm.c
Jeff Moyer 2c91dc
@@ -94,13 +94,18 @@ static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
Jeff Moyer 2c91dc
 	struct json_object *jarray = json_object_new_array();
Jeff Moyer 2c91dc
 	struct json_object *jlabel = NULL;
Jeff Moyer 2c91dc
 	struct namespace_label nslabel;
Jeff Moyer 2c91dc
+	unsigned int nsindex_size;
Jeff Moyer 2c91dc
 	unsigned int slot = -1;
Jeff Moyer 2c91dc
 	ssize_t offset;
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 	if (!jarray)
Jeff Moyer 2c91dc
 		return NULL;
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
-	for (offset = NSINDEX_ALIGN * 2; offset < size;
Jeff Moyer 2c91dc
+	nsindex_size = ndctl_dimm_sizeof_namespace_index(dimm);
Jeff Moyer 2c91dc
+	if (nsindex_size == 0)
Jeff Moyer 2c91dc
+		return NULL;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	for (offset = nsindex_size * 2; offset < size;
Jeff Moyer 2c91dc
 			offset += ndctl_dimm_sizeof_namespace_label(dimm)) {
Jeff Moyer 2c91dc
 		ssize_t len = min_t(ssize_t,
Jeff Moyer 2c91dc
 				ndctl_dimm_sizeof_namespace_label(dimm),
Jeff Moyer 2c91dc
@@ -204,17 +209,23 @@ static struct json_object *dump_label_json(struct ndctl_dimm *dimm,
Jeff Moyer 2c91dc
 	return jarray;
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
-static struct json_object *dump_index_json(struct ndctl_cmd *cmd_read, ssize_t size)
Jeff Moyer 2c91dc
+static struct json_object *dump_index_json(struct ndctl_dimm *dimm,
Jeff Moyer 2c91dc
+		struct ndctl_cmd *cmd_read, ssize_t size)
Jeff Moyer 2c91dc
 {
Jeff Moyer 2c91dc
 	struct json_object *jarray = json_object_new_array();
Jeff Moyer 2c91dc
 	struct json_object *jindex = NULL;
Jeff Moyer 2c91dc
 	struct namespace_index nsindex;
Jeff Moyer 2c91dc
+	unsigned int nsindex_size;
Jeff Moyer 2c91dc
 	ssize_t offset;
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 	if (!jarray)
Jeff Moyer 2c91dc
 		return NULL;
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
-	for (offset = 0; offset < NSINDEX_ALIGN * 2; offset += NSINDEX_ALIGN) {
Jeff Moyer 2c91dc
+	nsindex_size = ndctl_dimm_sizeof_namespace_index(dimm);
Jeff Moyer 2c91dc
+	if (nsindex_size == 0)
Jeff Moyer 2c91dc
+		return NULL;
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
+	for (offset = 0; offset < nsindex_size * 2; offset += nsindex_size) {
Jeff Moyer 2c91dc
 		ssize_t len = min_t(ssize_t, sizeof(nsindex), size - offset);
Jeff Moyer 2c91dc
 		struct json_object *jobj;
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
@@ -288,7 +299,7 @@ static struct json_object *dump_json(struct ndctl_dimm *dimm,
Jeff Moyer 2c91dc
 		goto err;
Jeff Moyer 2c91dc
 	json_object_object_add(jdimm, "dev", jobj);
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
-	jindex = dump_index_json(cmd_read, size);
Jeff Moyer 2c91dc
+	jindex = dump_index_json(dimm, cmd_read, size);
Jeff Moyer 2c91dc
 	if (!jindex)
Jeff Moyer 2c91dc
 		goto err;
Jeff Moyer 2c91dc
 	json_object_object_add(jdimm, "index", jindex);
Jeff Moyer 2c91dc
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
Jeff Moyer 2c91dc
index c045cbe..9e36e28 100644
Jeff Moyer 2c91dc
--- a/ndctl/lib/dimm.c
Jeff Moyer 2c91dc
+++ b/ndctl/lib/dimm.c
Jeff Moyer 2c91dc
@@ -256,6 +256,11 @@ static int __label_validate(struct nvdimm_data *ndd)
Jeff Moyer 2c91dc
 	return -EINVAL;
Jeff Moyer 2c91dc
 }
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
+NDCTL_EXPORT unsigned int ndctl_dimm_sizeof_namespace_index(struct ndctl_dimm *dimm)
Jeff Moyer 2c91dc
+{
Jeff Moyer 2c91dc
+	return sizeof_namespace_index(&dimm->ndd);
Jeff Moyer 2c91dc
+}
Jeff Moyer 2c91dc
+
Jeff Moyer 2c91dc
 /*
Jeff Moyer 2c91dc
  * If the dimm labels have not been previously validated this routine
Jeff Moyer 2c91dc
  * will make up a default size. Otherwise, it will pick the size based
Jeff Moyer 2c91dc
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
Jeff Moyer 2c91dc
index 58afb74..5ee73b7 100644
Jeff Moyer 2c91dc
--- a/ndctl/lib/libndctl.sym
Jeff Moyer 2c91dc
+++ b/ndctl/lib/libndctl.sym
Jeff Moyer 2c91dc
@@ -454,4 +454,5 @@ LIBNDCTL_25 {
Jeff Moyer 2c91dc
 
Jeff Moyer 2c91dc
 LIBNDCTL_26 {
Jeff Moyer 2c91dc
 	ndctl_bus_nfit_translate_spa;
Jeff Moyer 2c91dc
+	ndctl_dimm_sizeof_namespace_index;
Jeff Moyer 2c91dc
 } LIBNDCTL_25;
Jeff Moyer 2c91dc
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
Jeff Moyer 2c91dc
index 87d07b7..df109bb 100644
Jeff Moyer 2c91dc
--- a/ndctl/libndctl.h
Jeff Moyer 2c91dc
+++ b/ndctl/libndctl.h
Jeff Moyer 2c91dc
@@ -337,6 +337,7 @@ int ndctl_dimm_init_labels(struct ndctl_dimm *dimm,
Jeff Moyer 2c91dc
 		enum ndctl_namespace_version v);
Jeff Moyer 2c91dc
 unsigned long ndctl_dimm_get_available_labels(struct ndctl_dimm *dimm);
Jeff Moyer 2c91dc
 unsigned int ndctl_dimm_sizeof_namespace_label(struct ndctl_dimm *dimm);
Jeff Moyer 2c91dc
+unsigned int ndctl_dimm_sizeof_namespace_index(struct ndctl_dimm *dimm);
Jeff Moyer 2c91dc
 unsigned int ndctl_cmd_cfg_size_get_size(struct ndctl_cmd *cfg_size);
Jeff Moyer 2c91dc
 ssize_t ndctl_cmd_cfg_read_get_data(struct ndctl_cmd *cfg_read, void *buf,
Jeff Moyer 2c91dc
 		unsigned int len, unsigned int offset);
Jeff Moyer 2c91dc
-- 
Jeff Moyer 2c91dc
2.27.0
Jeff Moyer 2c91dc