diff options
Diffstat (limited to 'drivers/nvdimm/label.c')
-rw-r--r-- | drivers/nvdimm/label.c | 85 |
1 files changed, 47 insertions, 38 deletions
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index de66c02f6140..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", @@ -121,8 +135,7 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) memcpy(sig, nsindex[i]->sig, NSINDEX_SIG_LEN); if (memcmp(sig, NSINDEX_SIGNATURE, NSINDEX_SIG_LEN) != 0) { - dev_dbg(dev, "%s: nsindex%d signature invalid\n", - __func__, i); + dev_dbg(dev, "nsindex%d signature invalid\n", i); continue; } @@ -135,8 +148,8 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) labelsize = 128; if (labelsize != sizeof_namespace_label(ndd)) { - dev_dbg(dev, "%s: nsindex%d labelsize %d invalid\n", - __func__, i, nsindex[i]->labelsize); + dev_dbg(dev, "nsindex%d labelsize %d invalid\n", + i, nsindex[i]->labelsize); continue; } @@ -145,30 +158,28 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) sum = nd_fletcher64(nsindex[i], sizeof_namespace_index(ndd), 1); nsindex[i]->checksum = __cpu_to_le64(sum_save); if (sum != sum_save) { - dev_dbg(dev, "%s: nsindex%d checksum invalid\n", - __func__, i); + dev_dbg(dev, "nsindex%d checksum invalid\n", i); continue; } seq = __le32_to_cpu(nsindex[i]->seq); if ((seq & NSINDEX_SEQ_MASK) == 0) { - dev_dbg(dev, "%s: nsindex%d sequence: %#x invalid\n", - __func__, i, seq); + dev_dbg(dev, "nsindex%d sequence: %#x invalid\n", i, seq); continue; } /* sanity check the index against expected values */ if (__le64_to_cpu(nsindex[i]->myoff) != i * sizeof_namespace_index(ndd)) { - dev_dbg(dev, "%s: nsindex%d myoff: %#llx invalid\n", - __func__, i, (unsigned long long) + dev_dbg(dev, "nsindex%d myoff: %#llx invalid\n", + i, (unsigned long long) __le64_to_cpu(nsindex[i]->myoff)); continue; } if (__le64_to_cpu(nsindex[i]->otheroff) != (!i) * sizeof_namespace_index(ndd)) { - dev_dbg(dev, "%s: nsindex%d otheroff: %#llx invalid\n", - __func__, i, (unsigned long long) + dev_dbg(dev, "nsindex%d otheroff: %#llx invalid\n", + i, (unsigned long long) __le64_to_cpu(nsindex[i]->otheroff)); continue; } @@ -176,8 +187,7 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) size = __le64_to_cpu(nsindex[i]->mysize); if (size > sizeof_namespace_index(ndd) || size < sizeof(struct nd_namespace_index)) { - dev_dbg(dev, "%s: nsindex%d mysize: %#llx invalid\n", - __func__, i, size); + dev_dbg(dev, "nsindex%d mysize: %#llx invalid\n", i, size); continue; } @@ -185,9 +195,8 @@ static int __nd_label_validate(struct nvdimm_drvdata *ndd) if (nslot * sizeof_namespace_label(ndd) + 2 * sizeof_namespace_index(ndd) > ndd->nsarea.config_size) { - dev_dbg(dev, "%s: nsindex%d nslot: %u invalid, config_size: %#x\n", - __func__, i, nslot, - ndd->nsarea.config_size); + dev_dbg(dev, "nsindex%d nslot: %u invalid, config_size: %#x\n", + i, nslot, ndd->nsarea.config_size); continue; } valid[i] = true; @@ -356,8 +365,8 @@ static bool slot_valid(struct nvdimm_drvdata *ndd, sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1); nd_label->checksum = __cpu_to_le64(sum_save); if (sum != sum_save) { - dev_dbg(ndd->dev, "%s fail checksum. slot: %d expect: %#llx\n", - __func__, slot, sum); + dev_dbg(ndd->dev, "fail checksum. slot: %d expect: %#llx\n", + slot, sum); return false; } } @@ -422,8 +431,8 @@ int nd_label_active_count(struct nvdimm_drvdata *ndd) u64 dpa = __le64_to_cpu(nd_label->dpa); dev_dbg(ndd->dev, - "%s: slot%d invalid slot: %d dpa: %llx size: %llx\n", - __func__, slot, label_slot, dpa, size); + "slot%d invalid slot: %d dpa: %llx size: %llx\n", + slot, label_slot, dpa, size); continue; } count++; @@ -650,7 +659,7 @@ static int __pmem_label_update(struct nd_region *nd_region, slot = nd_label_alloc_slot(ndd); if (slot == UINT_MAX) return -ENXIO; - dev_dbg(ndd->dev, "%s: allocated: %d\n", __func__, slot); + dev_dbg(ndd->dev, "allocated: %d\n", slot); nd_label = to_label(ndd, slot); memset(nd_label, 0, sizeof_namespace_label(ndd)); @@ -678,7 +687,7 @@ static int __pmem_label_update(struct nd_region *nd_region, sum = nd_fletcher64(nd_label, sizeof_namespace_label(ndd), 1); nd_label->checksum = __cpu_to_le64(sum); } - nd_dbg_dpa(nd_region, ndd, res, "%s\n", __func__); + nd_dbg_dpa(nd_region, ndd, res, "\n"); /* update label */ offset = nd_label_offset(ndd, nd_label); @@ -700,7 +709,7 @@ static int __pmem_label_update(struct nd_region *nd_region, break; } if (victim) { - dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); + dev_dbg(ndd->dev, "free: %d\n", slot); slot = to_slot(ndd, victim->label); nd_label_free_slot(ndd, slot); victim->label = NULL; @@ -868,7 +877,7 @@ static int __blk_label_update(struct nd_region *nd_region, slot = nd_label_alloc_slot(ndd); if (slot == UINT_MAX) goto abort; - dev_dbg(ndd->dev, "%s: allocated: %d\n", __func__, slot); + dev_dbg(ndd->dev, "allocated: %d\n", slot); nd_label = to_label(ndd, slot); memset(nd_label, 0, sizeof_namespace_label(ndd)); @@ -928,7 +937,7 @@ static int __blk_label_update(struct nd_region *nd_region, /* free up now unused slots in the new index */ for_each_set_bit(slot, victim_map, victim_map ? nslot : 0) { - dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); + dev_dbg(ndd->dev, "free: %d\n", slot); nd_label_free_slot(ndd, slot); } @@ -1092,7 +1101,7 @@ static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid) active--; slot = to_slot(ndd, nd_label); nd_label_free_slot(ndd, slot); - dev_dbg(ndd->dev, "%s: free: %d\n", __func__, slot); + dev_dbg(ndd->dev, "free: %d\n", slot); list_move_tail(&label_ent->list, &list); label_ent->label = NULL; } @@ -1100,7 +1109,7 @@ static int del_labels(struct nd_mapping *nd_mapping, u8 *uuid) if (active == 0) { nd_mapping_free_labels(nd_mapping); - dev_dbg(ndd->dev, "%s: no more active labels\n", __func__); + dev_dbg(ndd->dev, "no more active labels\n"); } mutex_unlock(&nd_mapping->lock); |