@@ -18,10 +18,13 @@
/**
* struct daxctl_region - container for dax_devices
*/
+#define REGION_BUF_SIZE 50
struct daxctl_region {
int id;
uuid_t uuid;
int refcount;
+ size_t buf_len;
+ void *region_buf;
int devices_init;
char *region_path;
struct daxctl_ctx *ctx;
@@ -191,10 +191,11 @@ DAXCTL_EXPORT void daxctl_region_unref(struct daxctl_region *region)
return;
ctx = region->ctx;
- info(ctx, "region%d released\n", region->id);
+ dbg(ctx, "%s: %s\n", __func__, daxctl_region_get_devname(region));
list_for_each_safe(®ion->devices, dev, _d, list)
free_dev(dev, ®ion->devices);
free(region->region_path);
+ free(region->region_buf);
free(region);
}
@@ -208,7 +209,6 @@ DAXCTL_EXPORT struct daxctl_region *daxctl_new_region(struct daxctl_ctx *ctx,
int id, uuid_t uuid, const char *path)
{
struct daxctl_region *region;
- char *region_path;
region = calloc(1, sizeof(*region));
if (!region)
@@ -217,16 +217,18 @@ DAXCTL_EXPORT struct daxctl_region *daxctl_new_region(struct daxctl_ctx *ctx,
region->id = id;
region->refcount = 1;
uuid_copy(region->uuid, uuid);
- if (asprintf(®ion_path, "%s/dax", path) < 0)
- region_path = NULL;
- region->region_path = region_path;
+ region->region_path = strdup(path);
list_head_init(®ion->devices);
+ region->buf_len = strlen(region->region_path) + REGION_BUF_SIZE;
+ region->region_buf = calloc(1, region->buf_len);
- if (!region->region_path) {
+ if (!region->region_path || !region->region_buf) {
daxctl_region_unref(region);
region = NULL;
}
+ dbg(ctx, "%s: %s\n", __func__, daxctl_region_get_devname(region));
+
return region;
}
@@ -295,18 +297,53 @@ DAXCTL_EXPORT int daxctl_region_get_id(struct daxctl_region *region)
return region->id;
}
+DAXCTL_EXPORT const char *daxctl_region_get_devname(struct daxctl_region *region)
+{
+ return devpath_to_devname(region->region_path);
+}
+
+DAXCTL_EXPORT unsigned long long daxctl_region_get_available_size(
+ struct daxctl_region *region)
+{
+ struct daxctl_ctx *ctx = daxctl_region_get_ctx(region);
+ char *path = region->region_buf;
+ char buf[SYSFS_ATTR_SIZE], *end;
+ int len = region->buf_len;
+ unsigned long long avail;
+
+ if (snprintf(path, len, "%s/dax_region/available_size",
+ region->region_path) >= len) {
+ err(ctx, "%s: buffer too small!\n",
+ daxctl_region_get_devname(region));
+ return 0;
+ }
+
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ return 0;
+
+ avail = strtoull(buf, &end, 0);
+ if (buf[0] && *end == '\0')
+ return avail;
+ return 0;
+}
+
static void dax_devices_init(struct daxctl_region *region)
{
struct daxctl_ctx *ctx = daxctl_region_get_ctx(region);
char daxdev_fmt[50];
+ char *region_path;
if (region->devices_init)
return;
region->devices_init = 1;
sprintf(daxdev_fmt, "dax%d.", region->id);
- sysfs_device_parse(ctx, region->region_path, daxdev_fmt, region,
- add_dax_dev);
+ if (asprintf(®ion_path, "%s/dax", region->region_path) < 0)
+ region_path = NULL;
+ if (region_path)
+ sysfs_device_parse(ctx, region_path, daxdev_fmt, region,
+ add_dax_dev);
+ free(region_path);
}
DAXCTL_EXPORT struct daxctl_dev *daxctl_dev_get_first(struct daxctl_region *region)
@@ -30,3 +30,9 @@ global:
daxctl_dev_get_minor;
daxctl_dev_get_size;
} LIBNDCTL_1;
+
+LIBDAXCTL_3 {
+global:
+ daxctl_region_get_available_size;
+ daxctl_region_get_devname;
+} LIBNDCTL_2;
@@ -41,6 +41,9 @@ void daxctl_region_unref(struct daxctl_region *region);
void daxctl_region_get_uuid(struct daxctl_region *region, uuid_t uu);
int daxctl_region_get_id(struct daxctl_region *region);
struct daxctl_ctx *daxctl_region_get_ctx(struct daxctl_region *region);
+unsigned long long daxctl_region_get_available_size(
+ struct daxctl_region *region);
+const char *daxctl_region_get_devname(struct daxctl_region *region);
struct daxctl_dev;
struct daxctl_dev *daxctl_dev_get_first(struct daxctl_region *region);
Retrieve the available_size attribute for a given dax_region. As a side effect this rework region->region_path to carry the actual path without the "dax" class prefix for finding child device-dax instances. Signed-off-by: Dan Williams <dan.j.williams@intel.com> --- daxctl/lib/libdaxctl-private.h | 3 ++ daxctl/lib/libdaxctl.c | 53 ++++++++++++++++++++++++++++++++++------ daxctl/lib/libdaxctl.sym | 6 +++++ daxctl/libdaxctl.h | 3 ++ 4 files changed, 57 insertions(+), 8 deletions(-)