in namespace_devs.c [536:586]
static void space_valid(struct nd_region *nd_region, struct nvdimm_drvdata *ndd,
struct nd_label_id *label_id, struct resource *prev,
struct resource *next, struct resource *exist,
resource_size_t n, struct resource *valid)
{
bool is_reserve = strcmp(label_id->id, "pmem-reserve") == 0;
bool is_pmem = strncmp(label_id->id, "pmem", 4) == 0;
unsigned long align;
align = nd_region->align / nd_region->ndr_mappings;
valid->start = ALIGN(valid->start, align);
valid->end = ALIGN_DOWN(valid->end + 1, align) - 1;
if (valid->start >= valid->end)
goto invalid;
if (is_reserve)
return;
if (!is_pmem) {
struct nd_mapping *nd_mapping = &nd_region->mapping[0];
struct nvdimm_bus *nvdimm_bus;
struct blk_alloc_info info = {
.nd_mapping = nd_mapping,
.available = nd_mapping->size,
.res = valid,
};
WARN_ON(!is_nd_blk(&nd_region->dev));
nvdimm_bus = walk_to_nvdimm_bus(&nd_region->dev);
device_for_each_child(&nvdimm_bus->dev, &info, alias_dpa_busy);
return;
}
/* allocation needs to be contiguous, so this is all or nothing */
if (resource_size(valid) < n)
goto invalid;
/* we've got all the space we need and no existing allocation */
if (!exist)
return;
/* allocation needs to be contiguous with the existing namespace */
if (valid->start == exist->end + 1
|| valid->end == exist->start - 1)
return;
invalid:
/* truncate @valid size to 0 */
valid->end = valid->start - 1;
}