in bus.c [962:1033]
static ssize_t dev_dax_resize(struct dax_region *dax_region,
struct dev_dax *dev_dax, resource_size_t size)
{
resource_size_t avail = dax_region_avail_size(dax_region), to_alloc;
resource_size_t dev_size = dev_dax_size(dev_dax);
struct resource *region_res = &dax_region->res;
struct device *dev = &dev_dax->dev;
struct resource *res, *first;
resource_size_t alloc = 0;
int rc;
if (dev->driver)
return -EBUSY;
if (size == dev_size)
return 0;
if (size > dev_size && size - dev_size > avail)
return -ENOSPC;
if (size < dev_size)
return dev_dax_shrink(dev_dax, size);
to_alloc = size - dev_size;
if (dev_WARN_ONCE(dev, !alloc_is_aligned(dev_dax, to_alloc),
"resize of %pa misaligned\n", &to_alloc))
return -ENXIO;
/*
* Expand the device into the unused portion of the region. This
* may involve adjusting the end of an existing resource, or
* allocating a new resource.
*/
retry:
first = region_res->child;
if (!first)
return alloc_dev_dax_range(dev_dax, dax_region->res.start, to_alloc);
rc = -ENOSPC;
for (res = first; res; res = res->sibling) {
struct resource *next = res->sibling;
/* space at the beginning of the region */
if (res == first && res->start > dax_region->res.start) {
alloc = min(res->start - dax_region->res.start, to_alloc);
rc = alloc_dev_dax_range(dev_dax, dax_region->res.start, alloc);
break;
}
alloc = 0;
/* space between allocations */
if (next && next->start > res->end + 1)
alloc = min(next->start - (res->end + 1), to_alloc);
/* space at the end of the region */
if (!alloc && !next && res->end < region_res->end)
alloc = min(region_res->end - res->end, to_alloc);
if (!alloc)
continue;
if (adjust_ok(dev_dax, res)) {
rc = adjust_dev_dax_range(dev_dax, res, resource_size(res) + alloc);
break;
}
rc = alloc_dev_dax_range(dev_dax, res->end + 1, alloc);
break;
}
if (rc)
return rc;
to_alloc -= alloc;
if (to_alloc)
goto retry;
return 0;
}