in namespace_devs.c [1885:1936]
static int select_pmem_id(struct nd_region *nd_region, const uuid_t *pmem_id)
{
int i;
if (!pmem_id)
return -ENODEV;
for (i = 0; i < nd_region->ndr_mappings; i++) {
struct nd_mapping *nd_mapping = &nd_region->mapping[i];
struct nvdimm_drvdata *ndd = to_ndd(nd_mapping);
struct nd_namespace_label *nd_label = NULL;
u64 hw_start, hw_end, pmem_start, pmem_end;
struct nd_label_ent *label_ent;
lockdep_assert_held(&nd_mapping->lock);
list_for_each_entry(label_ent, &nd_mapping->labels, list) {
nd_label = label_ent->label;
if (!nd_label)
continue;
if (nsl_uuid_equal(ndd, nd_label, pmem_id))
break;
nd_label = NULL;
}
if (!nd_label) {
WARN_ON(1);
return -EINVAL;
}
/*
* Check that this label is compliant with the dpa
* range published in NFIT
*/
hw_start = nd_mapping->start;
hw_end = hw_start + nd_mapping->size;
pmem_start = nsl_get_dpa(ndd, nd_label);
pmem_end = pmem_start + nsl_get_rawsize(ndd, nd_label);
if (pmem_start >= hw_start && pmem_start < hw_end
&& pmem_end <= hw_end && pmem_end > hw_start)
/* pass */;
else {
dev_dbg(&nd_region->dev, "%s invalid label for %pUb\n",
dev_name(ndd->dev),
nsl_uuid_raw(ndd, nd_label));
return -EINVAL;
}
/* move recently validated label to the front of the list */
list_move(&label_ent->list, &nd_mapping->labels);
}
return 0;
}