diff options
| -rw-r--r-- | drivers/nvdimm/label.c | 34 | 
1 files changed, 24 insertions, 10 deletions
| diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index c858cfadea40..1d28cd656536 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -45,9 +45,27 @@ unsigned sizeof_namespace_label(struct nvdimm_drvdata *ndd)  	return ndd->nslabel_size;  } +static size_t __sizeof_namespace_index(u32 nslot) +{ +	return ALIGN(sizeof(struct nd_namespace_index) + DIV_ROUND_UP(nslot, 8), +			NSINDEX_ALIGN); +} + +static int __nvdimm_num_label_slots(struct nvdimm_drvdata *ndd, +		size_t index_size) +{ +	return (ndd->nsarea.config_size - index_size * 2) / +			sizeof_namespace_label(ndd); +} +  int nvdimm_num_label_slots(struct nvdimm_drvdata *ndd)  { -	return ndd->nsarea.config_size / (sizeof_namespace_label(ndd) + 1); +	u32 tmp_nslot, n; + +	tmp_nslot = ndd->nsarea.config_size / sizeof_namespace_label(ndd); +	n = __sizeof_namespace_index(tmp_nslot) / NSINDEX_ALIGN; + +	return __nvdimm_num_label_slots(ndd, NSINDEX_ALIGN * n);  }  size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd) @@ -55,18 +73,14 @@ size_t sizeof_namespace_index(struct nvdimm_drvdata *ndd)  	u32 nslot, space, size;  	/* -	 * The minimum index space is 512 bytes, with that amount of -	 * index we can describe ~1400 labels which is less than a byte -	 * of overhead per label.  Round up to a byte of overhead per -	 * label and determine the size of the index region.  Yes, this -	 * starts to waste space at larger config_sizes, but it's -	 * unlikely we'll ever see anything but 128K. +	 * Per UEFI 2.7, the minimum size of the Label Storage Area is large +	 * enough to hold 2 index blocks and 2 labels.  The minimum index +	 * block size is 256 bytes, and the minimum label size is 256 bytes.  	 */  	nslot = nvdimm_num_label_slots(ndd);  	space = ndd->nsarea.config_size - nslot * sizeof_namespace_label(ndd); -	size = ALIGN(sizeof(struct nd_namespace_index) + DIV_ROUND_UP(nslot, 8), -			NSINDEX_ALIGN) * 2; -	if (size <= space) +	size = __sizeof_namespace_index(nslot) * 2; +	if (size <= space && nslot >= 2)  		return size / 2;  	dev_err(ndd->dev, "label area (%d) too small to host (%d byte) labels\n", | 
