Skip to content

Commit

Permalink
[RFC] create-namespace: Add percentage option
Browse files Browse the repository at this point in the history
The size option of the create-namespace command can now take a percentage of
the total region size as the desired size. E.g. :

ndctl create-namespace  -s 50%

will create a namespace using half of the total region size, assuming
there is enough available capacity in the region for the request.

Only whole percentages are correctly parsed at the moment e.g. 12%, but
not 12.5%.

Sizes that result in a misaligned size with regards to region alignment
(default 16MB) are rounded down, unless the rounded-up size would result
in using the full remaining region capacity available.

Fixes: pmem#199
Signed-off-by: Vasilis Liaskovitis <[email protected]>
  • Loading branch information
vliaskov committed Jun 21, 2022
1 parent dd58d43 commit 15a5482
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
64 changes: 64 additions & 0 deletions ndctl/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,64 @@ static int validate_available_capacity(struct ndctl_region *region,
return 0;
}

static int validate_available_percentage(struct ndctl_region *region,
struct parsed_parameters *p)
{
unsigned long long available, max, pct;
unsigned long region_align;

pct = p->size;

if (p->size == 0) {
debug("%s: non-zero percentage of total region size required for namespace creation\n",
ndctl_region_get_devname(region));
return -EINVAL;
}

max = ndctl_region_get_size(region);

if (ndctl_region_get_nstype(region) == ND_DEVICE_NAMESPACE_IO)
available = ndctl_region_get_size(region);
else {
available = ndctl_region_get_max_available_extent(region);
if (available == ULLONG_MAX)
available = ndctl_region_get_available_size(region);
}

/* percentage is expressed in terms of the total region size */
p->size = (unsigned long long) (max * ((double) pct / 100));

region_align = ndctl_region_get_align(region);
if (p->size % region_align) {
/* only round up if rounded up size would use the available region capacity */
if (p->size + region_align - (p->size % region_align) == available) {
debug("%s: percentage %llu of total region size: %#llx results in unaligned size: %#llx (align setting %#lx) rounding up to size: %#llx\n",
ndctl_region_get_devname(region), pct, max,
p->size, region_align,
p->size + region_align - (p->size % region_align));
p->size += region_align - (p->size % region_align);
}
/* otherwise round down */
else {
debug("%s: percentage %llu of total region size: %#llx results in unaligned size: %#llx (align setting %#lx) rounding down to size: %#llx\n",
ndctl_region_get_devname(region), pct, max,
p->size, region_align,
p->size & (~(region_align - 1)));
p->size &= ~(region_align - 1);
}
}

if (!available || p->size > available) {
debug("%s: insufficient capacity size: %llx avail: %llx\n",
ndctl_region_get_devname(region), p->size, available);
return -EAGAIN;
}

debug("%s: percentage requested: %llu of total region size: %llx size requested: %llx avail: %llx\n",
ndctl_region_get_devname(region), pct, max, p->size, available);
return 0;
}

/*
* validate_namespace_options - init parameters for setup_namespace
* @region: parent of the namespace to create / reconfigure
Expand Down Expand Up @@ -671,6 +729,12 @@ static int validate_namespace_options(struct ndctl_region *region,
else
default_size = true;

if (units == SZ_PCT) {
rc = validate_available_percentage(region, p);
if (rc)
return rc;
}

/*
* Validate available capacity in the create case, in the
* reconfigure case the capacity is already allocated. A default
Expand Down
5 changes: 5 additions & 0 deletions util/size.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ unsigned long long __parse_size64(const char *str, unsigned long long *units)
val *= SZ_1T;
end++;
break;
case '%':
if (units)
*units = SZ_PCT;
end++;
break;
default:
if (units)
*units = 1;
Expand Down
1 change: 1 addition & 0 deletions util/size.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#define SZ_256M 0x10000000
#define SZ_1G 0x40000000
#define SZ_1T 0x10000000000ULL
#define SZ_PCT 0x0

unsigned long long parse_size64(const char *str);
unsigned long long __parse_size64(const char *str, unsigned long long *units);
Expand Down

0 comments on commit 15a5482

Please sign in to comment.