Retrieve the basic geometry and identification attributes of a region.
Signed-off-by: Dan Williams <[email protected]>
---
daxctl/lib/libdaxctl-private.h | 3 +
daxctl/lib/libdaxctl.c | 93 +++++++++++++++++++++++++++++++---------
daxctl/lib/libdaxctl.sym | 14 ++++--
daxctl/libdaxctl.h | 2 +
4 files changed, 87 insertions(+), 25 deletions(-)
diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h
index a2924f1e93f5..2d17f40b6ea9 100644
--- a/daxctl/lib/libdaxctl-private.h
+++ b/daxctl/lib/libdaxctl-private.h
@@ -23,10 +23,13 @@ struct daxctl_region {
int id;
uuid_t uuid;
int refcount;
+ char *devname;
size_t buf_len;
void *region_buf;
int devices_init;
char *region_path;
+ unsigned int align;
+ unsigned long long size;
struct daxctl_ctx *ctx;
struct list_head devices;
};
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index 06605de85fc3..a40a84a3c1bb 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -197,6 +197,7 @@ DAXCTL_EXPORT void daxctl_region_unref(struct daxctl_region
*region)
free_dev(dev, ®ion->devices);
free(region->region_path);
free(region->region_buf);
+ free(region->devname);
free(region);
}
@@ -206,32 +207,68 @@ DAXCTL_EXPORT void daxctl_region_ref(struct daxctl_region
*region)
region->refcount++;
}
-DAXCTL_EXPORT struct daxctl_region *daxctl_new_region(struct daxctl_ctx *ctx,
- int id, uuid_t uuid, const char *path)
+static void *add_dax_region(void *parent, int id, const char *base)
{
+ char *path = calloc(1, strlen(base) + 100);
+ const char *attrs = "dax_region";
+ struct daxctl_ctx *ctx = parent;
struct daxctl_region *region;
+ char buf[SYSFS_ATTR_SIZE];
+
+ if (!path)
+ return NULL;
region = calloc(1, sizeof(*region));
if (!region)
- return NULL;
- region->ctx = ctx;
+ goto err_region;
+
region->id = id;
+ region->align = -1;
+ region->size = -1;
+ region->ctx = ctx;
region->refcount = 1;
- uuid_copy(region->uuid, uuid);
+ list_head_init(®ion->devices);
+ region->devname = strdup(devpath_to_devname(base));
+ sprintf(path, "%s/%s/size", base, attrs);
+ if (sysfs_read_attr(ctx, path, buf) == 0)
+ region->size = strtoull(buf, NULL, 0);
+
+ sprintf(path, "%s/%s/align", base, attrs);
+ if (sysfs_read_attr(ctx, path, buf) == 0)
+ region->align = strtoul(buf, NULL, 0);
+
+ sprintf(path, "%s/%s", base, attrs);
region->region_path = strdup(path);
- if (!region->region_path) {
- free(region);
- return NULL;
- }
+ if (!region->region_path)
+ goto err_read;
- 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_buf) {
- daxctl_region_unref(region);
+ region->region_buf = calloc(1, strlen(path) + REGION_BUF_SIZE);
+ if (!region->region_buf)
+ goto err_read;
+ region->buf_len = strlen(path) + REGION_BUF_SIZE;
+
+ free(path);
+ return region;
+
+ err_read:
+ free(region->region_buf);
+ free(region->region_path);
+ free(region);
+ err_region:
+ free(path);
+ return NULL;
+}
+
+DAXCTL_EXPORT struct daxctl_region *daxctl_new_region(struct daxctl_ctx *ctx,
+ int id, uuid_t uuid, const char *path)
+{
+ struct daxctl_region *region;
+
+ region = add_dax_region(ctx, id, path);
+ if (!region)
return NULL;
- }
+ uuid_copy(region->uuid, uuid);
dbg(ctx, "%s: %s\n", __func__, daxctl_region_get_devname(region));
@@ -302,9 +339,19 @@ DAXCTL_EXPORT int daxctl_region_get_id(struct
daxctl_region *region)
return region->id;
}
+DAXCTL_EXPORT unsigned int daxctl_region_get_align(struct daxctl_region
*region)
+{
+ return region->align;
+}
+
+DAXCTL_EXPORT unsigned long long daxctl_region_get_size(struct daxctl_region
*region)
+{
+ return region->size;
+}
+
DAXCTL_EXPORT const char *daxctl_region_get_devname(struct daxctl_region
*region)
{
- return devpath_to_devname(region->region_path);
+ return region->devname;
}
DAXCTL_EXPORT unsigned long long daxctl_region_get_available_size(
@@ -316,7 +363,7 @@ DAXCTL_EXPORT unsigned long long
daxctl_region_get_available_size(
int len = region->buf_len;
unsigned long long avail;
- if (snprintf(path, len, "%s/dax_region/available_size",
+ if (snprintf(path, len, "%s/available_size",
region->region_path) >= len) {
err(ctx, "%s: buffer too small!\n",
daxctl_region_get_devname(region));
@@ -341,7 +388,7 @@ DAXCTL_EXPORT struct daxctl_dev *daxctl_region_get_dev_seed(
char buf[SYSFS_ATTR_SIZE];
struct daxctl_dev *dev;
- if (snprintf(path, len, "%s/dax_region/seed", region->region_path) >=
len) {
+ if (snprintf(path, len, "%s/seed", region->region_path) >= len) {
err(ctx, "%s: buffer too small!\n",
daxctl_region_get_devname(region));
return NULL;
@@ -367,11 +414,15 @@ static void dax_devices_init(struct daxctl_region *region)
region->devices_init = 1;
sprintf(daxdev_fmt, "dax%d.", region->id);
- if (asprintf(®ion_path, "%s/dax", region->region_path) < 0)
- region_path = NULL;
- if (region_path)
+ region_path = strdup(region->region_path);
+ if (region_path) {
+ char *c = strrchr(region_path, '_');
+
+ /* convert <devpath>/dax_region to <devpath>/dax */
+ *c = '\0';
sysfs_device_parse(ctx, region_path, daxdev_fmt, region,
add_dax_dev);
+ }
free(region_path);
}
diff --git a/daxctl/lib/libdaxctl.sym b/daxctl/lib/libdaxctl.sym
index e74d75bf7847..eef97f2546c0 100644
--- a/daxctl/lib/libdaxctl.sym
+++ b/daxctl/lib/libdaxctl.sym
@@ -1,4 +1,4 @@
-LIBNDCTL_1 {
+LIBDAXCTL_1 {
global:
daxctl_get_userdata;
daxctl_set_userdata;
@@ -12,7 +12,7 @@ local:
*;
};
-LIBNDCTL_2 {
+LIBDAXCTL_2 {
global:
daxctl_region_unref;
daxctl_new_region;
@@ -29,11 +29,17 @@ global:
daxctl_dev_get_major;
daxctl_dev_get_minor;
daxctl_dev_get_size;
-} LIBNDCTL_1;
+} LIBDAXCTL_1;
LIBDAXCTL_3 {
global:
daxctl_region_get_available_size;
daxctl_region_get_devname;
daxctl_region_get_dev_seed;
-} LIBNDCTL_2;
+} LIBDAXCTL_2;
+
+LIBDAXCTL_4 {
+global:
+ daxctl_region_get_size;
+ daxctl_region_get_align;
+} LIBDAXCTL_3;
diff --git a/daxctl/libdaxctl.h b/daxctl/libdaxctl.h
index bb7aa363a605..42ed15b508e5 100644
--- a/daxctl/libdaxctl.h
+++ b/daxctl/libdaxctl.h
@@ -43,6 +43,8 @@ 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);
+unsigned long long daxctl_region_get_size(struct daxctl_region *region);
+unsigned int daxctl_region_get_align(struct daxctl_region *region);
const char *daxctl_region_get_devname(struct daxctl_region *region);
struct daxctl_dev *daxctl_region_get_dev_seed(struct daxctl_region *region);
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm