libnvdimm, label: fix index block size calculation

The old calculation assumed that the label space was 128k and the label
size is 128. With v1.2 labels where the label size is 256 this
calculation will return zero. We are saved by the fact that the
nsindex_size is always pre-initialized from a previous 128 byte
assumption and we are lucky that the index sizes turn out the same.

Fix this going forward in case we start encountering different
geometries of label areas besides 128k.

Since the label size can change from one call to the next, drop the
caching of nsindex_size.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
Dan Williams 2017-08-29 18:28:18 -07:00
parent f13d2b61e5
commit 0288176869
2 changed files with 16 additions and 14 deletions

View File

@ -45,12 +45,14 @@ unsigned sizeof_namespace_label(struct nvdimm_drvdata *ndd)
return ndd->nslabel_size; return ndd->nslabel_size;
} }
int nvdimm_num_label_slots(struct nvdimm_drvdata *ndd)
{
return ndd->nsarea.config_size / (sizeof_namespace_label(ndd) + 1);
}
size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd) size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd)
{ {
u32 index_span; u32 nslot, space, size;
if (ndd->nsindex_size)
return ndd->nsindex_size;
/* /*
* The minimum index space is 512 bytes, with that amount of * The minimum index space is 512 bytes, with that amount of
@ -60,16 +62,16 @@ size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd)
* starts to waste space at larger config_sizes, but it's * starts to waste space at larger config_sizes, but it's
* unlikely we'll ever see anything but 128K. * unlikely we'll ever see anything but 128K.
*/ */
index_span = ndd->nsarea.config_size / (sizeof_namespace_label(ndd) + 1); nslot = nvdimm_num_label_slots(ndd);
index_span /= NSINDEX_ALIGN * 2; space = ndd->nsarea.config_size - nslot * sizeof_namespace_label(ndd);
ndd->nsindex_size = index_span * NSINDEX_ALIGN; size = ALIGN(sizeof(struct nd_namespace_index) + DIV_ROUND_UP(nslot, 8),
NSINDEX_ALIGN) * 2;
if (size <= space)
return size / 2;
return ndd->nsindex_size; dev_err(ndd->dev, "label area (%d) too small to host (%d byte) labels\n",
} ndd->nsarea.config_size, sizeof_namespace_label(ndd));
return 0;
int nvdimm_num_label_slots(struct nvdimm_drvdata *ndd)
{
return ndd->nsarea.config_size / (sizeof_namespace_label(ndd) + 1);
} }
static int __nd_label_validate(struct nvdimm_drvdata *ndd) static int __nd_label_validate(struct nvdimm_drvdata *ndd)

View File

@ -42,7 +42,7 @@ struct nd_poison {
struct nvdimm_drvdata { struct nvdimm_drvdata {
struct device *dev; struct device *dev;
int nsindex_size, nslabel_size; int nslabel_size;
struct nd_cmd_get_config_size nsarea; struct nd_cmd_get_config_size nsarea;
void *data; void *data;
int ns_current, ns_next; int ns_current, ns_next;