summaryrefslogtreecommitdiffstats
path: root/drivers/nvdimm/label.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvdimm/label.c')
-rw-r--r--drivers/nvdimm/label.c340
1 files changed, 0 insertions, 340 deletions
diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c
index 5ec9a4023df9..8c972bcb2ac3 100644
--- a/drivers/nvdimm/label.c
+++ b/drivers/nvdimm/label.c
@@ -968,326 +968,6 @@ static int __pmem_label_update(struct nd_region *nd_region,
return rc;
}
-static bool is_old_resource(struct resource *res, struct resource **list, int n)
-{
- int i;
-
- if (res->flags & DPA_RESOURCE_ADJUSTED)
- return false;
- for (i = 0; i < n; i++)
- if (res == list[i])
- return true;
- return false;
-}
-
-static struct resource *to_resource(struct nvdimm_drvdata *ndd,
- struct nd_namespace_label *nd_label)
-{
- struct resource *res;
-
- for_each_dpa_resource(ndd, res) {
- if (res->start != nsl_get_dpa(ndd, nd_label))
- continue;
- if (resource_size(res) != nsl_get_rawsize(ndd, nd_label))
- continue;
- return res;
- }
-
- return NULL;
-}
-
-/*
- * Use the presence of the type_guid as a flag to determine isetcookie
- * usage and nlabel + position policy for blk-aperture namespaces.
- */
-static void nsl_set_blk_isetcookie(struct nvdimm_drvdata *ndd,
- struct nd_namespace_label *nd_label,
- u64 isetcookie)
-{
- if (efi_namespace_label_has(ndd, type_guid)) {
- nsl_set_isetcookie(ndd, nd_label, isetcookie);
- return;
- }
- nsl_set_isetcookie(ndd, nd_label, 0); /* N/A */
-}
-
-bool nsl_validate_blk_isetcookie(struct nvdimm_drvdata *ndd,
- struct nd_namespace_label *nd_label,
- u64 isetcookie)
-{
- if (!efi_namespace_label_has(ndd, type_guid))
- return true;
-
- if (nsl_get_isetcookie(ndd, nd_label) != isetcookie) {
- dev_dbg(ndd->dev, "expect cookie %#llx got %#llx\n", isetcookie,
- nsl_get_isetcookie(ndd, nd_label));
- return false;
- }
-
- return true;
-}
-
-static void nsl_set_blk_nlabel(struct nvdimm_drvdata *ndd,
- struct nd_namespace_label *nd_label, int nlabel,
- bool first)
-{
- if (!efi_namespace_label_has(ndd, type_guid)) {
- nsl_set_nlabel(ndd, nd_label, 0); /* N/A */
- return;
- }
- nsl_set_nlabel(ndd, nd_label, first ? nlabel : 0xffff);
-}
-
-static void nsl_set_blk_position(struct nvdimm_drvdata *ndd,
- struct nd_namespace_label *nd_label,
- bool first)
-{
- if (!efi_namespace_label_has(ndd, type_guid)) {
- nsl_set_position(ndd, nd_label, 0);
- return;
- }
- nsl_set_position(ndd, nd_label, first ? 0 : 0xffff);
-}
-
-/*
- * 1/ Account all the labels that can be freed after this update
- * 2/ Allocate and write the label to the staging (next) index
- * 3/ Record the resources in the namespace device
- */
-static int __blk_label_update(struct nd_region *nd_region,
- struct nd_mapping *nd_mapping, struct nd_namespace_blk *nsblk,
- int num_labels)
-{
- int i, alloc, victims, nfree, old_num_resources, nlabel, rc = -ENXIO;
- struct nd_interleave_set *nd_set = nd_region->nd_set;
- struct nd_namespace_common *ndns = &nsblk->common;
- struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
- struct nd_namespace_label *nd_label;
- struct nd_label_ent *label_ent, *e;
- struct nd_namespace_index *nsindex;
- unsigned long *free, *victim_map = NULL;
- struct resource *res, **old_res_list;
- struct nd_label_id label_id;
- int min_dpa_idx = 0;
- LIST_HEAD(list);
- u32 nslot, slot;
-
- if (!preamble_next(ndd, &nsindex, &free, &nslot))
- return -ENXIO;
-
- old_res_list = nsblk->res;
- nfree = nd_label_nfree(ndd);
- old_num_resources = nsblk->num_resources;
- nd_label_gen_id(&label_id, nsblk->uuid, NSLABEL_FLAG_LOCAL);
-
- /*
- * We need to loop over the old resources a few times, which seems a
- * bit inefficient, but we need to know that we have the label
- * space before we start mutating the tracking structures.
- * Otherwise the recovery method of last resort for userspace is
- * disable and re-enable the parent region.
- */
- alloc = 0;
- for_each_dpa_resource(ndd, res) {
- if (strcmp(res->name, label_id.id) != 0)
- continue;
- if (!is_old_resource(res, old_res_list, old_num_resources))
- alloc++;
- }
-
- victims = 0;
- if (old_num_resources) {
- /* convert old local-label-map to dimm-slot victim-map */
- victim_map = bitmap_zalloc(nslot, GFP_KERNEL);
- if (!victim_map)
- return -ENOMEM;
-
- /* mark unused labels for garbage collection */
- for_each_clear_bit_le(slot, free, nslot) {
- nd_label = to_label(ndd, slot);
- if (!nsl_uuid_equal(ndd, nd_label, nsblk->uuid))
- continue;
- res = to_resource(ndd, nd_label);
- if (res && is_old_resource(res, old_res_list,
- old_num_resources))
- continue;
- slot = to_slot(ndd, nd_label);
- set_bit(slot, victim_map);
- victims++;
- }
- }
-
- /* don't allow updates that consume the last label */
- if (nfree - alloc < 0 || nfree - alloc + victims < 1) {
- dev_info(&nsblk->common.dev, "insufficient label space\n");
- bitmap_free(victim_map);
- return -ENOSPC;
- }
- /* from here on we need to abort on error */
-
-
- /* assign all resources to the namespace before writing the labels */
- nsblk->res = NULL;
- nsblk->num_resources = 0;
- for_each_dpa_resource(ndd, res) {
- if (strcmp(res->name, label_id.id) != 0)
- continue;
- if (!nsblk_add_resource(nd_region, ndd, nsblk, res->start)) {
- rc = -ENOMEM;
- goto abort;
- }
- }
-
- /* release slots associated with any invalidated UUIDs */
- mutex_lock(&nd_mapping->lock);
- list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list)
- if (test_and_clear_bit(ND_LABEL_REAP, &label_ent->flags)) {
- reap_victim(nd_mapping, label_ent);
- list_move(&label_ent->list, &list);
- }
- mutex_unlock(&nd_mapping->lock);
-
- /*
- * Find the resource associated with the first label in the set
- * per the v1.2 namespace specification.
- */
- for (i = 0; i < nsblk->num_resources; i++) {
- struct resource *min = nsblk->res[min_dpa_idx];
-
- res = nsblk->res[i];
- if (res->start < min->start)
- min_dpa_idx = i;
- }
-
- for (i = 0; i < nsblk->num_resources; i++) {
- size_t offset;
-
- res = nsblk->res[i];
- if (is_old_resource(res, old_res_list, old_num_resources))
- continue; /* carry-over */
- slot = nd_label_alloc_slot(ndd);
- if (slot == UINT_MAX) {
- rc = -ENXIO;
- goto abort;
- }
- dev_dbg(ndd->dev, "allocated: %d\n", slot);
-
- nd_label = to_label(ndd, slot);
- memset(nd_label, 0, sizeof_namespace_label(ndd));
- nsl_set_uuid(ndd, nd_label, nsblk->uuid);
- nsl_set_name(ndd, nd_label, nsblk->alt_name);
- nsl_set_flags(ndd, nd_label, NSLABEL_FLAG_LOCAL);
-
- nsl_set_blk_nlabel(ndd, nd_label, nsblk->num_resources,
- i == min_dpa_idx);
- nsl_set_blk_position(ndd, nd_label, i == min_dpa_idx);
- nsl_set_blk_isetcookie(ndd, nd_label, nd_set->cookie2);
-
- nsl_set_dpa(ndd, nd_label, res->start);
- nsl_set_rawsize(ndd, nd_label, resource_size(res));
- nsl_set_lbasize(ndd, nd_label, nsblk->lbasize);
- nsl_set_slot(ndd, nd_label, slot);
- nsl_set_type_guid(ndd, nd_label, &nd_set->type_guid);
- nsl_set_claim_class(ndd, nd_label, ndns->claim_class);
- nsl_calculate_checksum(ndd, nd_label);
-
- /* update label */
- offset = nd_label_offset(ndd, nd_label);
- rc = nvdimm_set_config_data(ndd, offset, nd_label,
- sizeof_namespace_label(ndd));
- if (rc < 0)
- goto abort;
- }
-
- /* free up now unused slots in the new index */
- for_each_set_bit(slot, victim_map, victim_map ? nslot : 0) {
- dev_dbg(ndd->dev, "free: %d\n", slot);
- nd_label_free_slot(ndd, slot);
- }
-
- /* update index */
- rc = nd_label_write_index(ndd, ndd->ns_next,
- nd_inc_seq(__le32_to_cpu(nsindex->seq)), 0);
- if (rc)
- goto abort;
-
- /*
- * Now that the on-dimm labels are up to date, fix up the tracking
- * entries in nd_mapping->labels
- */
- nlabel = 0;
- mutex_lock(&nd_mapping->lock);
- list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) {
- nd_label = label_ent->label;
- if (!nd_label)
- continue;
- nlabel++;
- if (!nsl_uuid_equal(ndd, nd_label, nsblk->uuid))
- continue;
- nlabel--;
- list_move(&label_ent->list, &list);
- label_ent->label = NULL;
- }
- list_splice_tail_init(&list, &nd_mapping->labels);
- mutex_unlock(&nd_mapping->lock);
-
- if (nlabel + nsblk->num_resources > num_labels) {
- /*
- * Bug, we can't end up with more resources than
- * available labels
- */
- WARN_ON_ONCE(1);
- rc = -ENXIO;
- goto out;
- }
-
- mutex_lock(&nd_mapping->lock);
- label_ent = list_first_entry_or_null(&nd_mapping->labels,
- typeof(*label_ent), list);
- if (!label_ent) {
- WARN_ON(1);
- mutex_unlock(&nd_mapping->lock);
- rc = -ENXIO;
- goto out;
- }
- for_each_clear_bit_le(slot, free, nslot) {
- nd_label = to_label(ndd, slot);
- if (!nsl_uuid_equal(ndd, nd_label, nsblk->uuid))
- continue;
- res = to_resource(ndd, nd_label);
- res->flags &= ~DPA_RESOURCE_ADJUSTED;
- dev_vdbg(&nsblk->common.dev, "assign label slot: %d\n", slot);
- list_for_each_entry_from(label_ent, &nd_mapping->labels, list) {
- if (label_ent->label)
- continue;
- label_ent->label = nd_label;
- nd_label = NULL;
- break;
- }
- if (nd_label)
- dev_WARN(&nsblk->common.dev,
- "failed to track label slot%d\n", slot);
- }
- mutex_unlock(&nd_mapping->lock);
-
- out:
- kfree(old_res_list);
- bitmap_free(victim_map);
- return rc;
-
- abort:
- /*
- * 1/ repair the allocated label bitmap in the index
- * 2/ restore the resource list
- */
- nd_label_copy(ndd, nsindex, to_current_namespace_index(ndd));
- kfree(nsblk->res);
- nsblk->res = old_res_list;
- nsblk->num_resources = old_num_resources;
- old_res_list = NULL;
- goto out;
-}
-
static int init_labels(struct nd_mapping *nd_mapping, int num_labels)
{
int i, old_num_labels = 0;
@@ -1425,26 +1105,6 @@ int nd_pmem_namespace_label_update(struct nd_region *nd_region,
return 0;
}
-int nd_blk_namespace_label_update(struct nd_region *nd_region,
- struct nd_namespace_blk *nsblk, resource_size_t size)
-{
- struct nd_mapping *nd_mapping = &nd_region->mapping[0];
- struct resource *res;
- int count = 0;
-
- if (size == 0)
- return del_labels(nd_mapping, nsblk->uuid);
-
- for_each_dpa_resource(to_ndd(nd_mapping), res)
- count++;
-
- count = init_labels(nd_mapping, count);
- if (count < 0)
- return count;
-
- return __blk_label_update(nd_region, nd_mapping, nsblk, count);
-}
-
int __init nd_label_init(void)
{
WARN_ON(guid_parse(NVDIMM_BTT_GUID, &nvdimm_btt_guid));