@@ -518,6 +518,11 @@ DAXCTL_EXPORT struct daxctl_region *daxctl_dev_get_region(struct daxctl_dev *dev
return dev->region;
}
+DAXCTL_EXPORT struct daxctl_ctx *daxctl_dev_get_ctx(struct daxctl_dev *dev)
+{
+ return daxctl_region_get_ctx(dev->region);
+}
+
DAXCTL_EXPORT int daxctl_dev_get_id(struct daxctl_dev *dev)
{
return dev->id;
@@ -542,3 +547,24 @@ DAXCTL_EXPORT unsigned long long daxctl_dev_get_size(struct daxctl_dev *dev)
{
return dev->size;
}
+
+DAXCTL_EXPORT int daxctl_dev_set_size(struct daxctl_dev *dev,
+ unsigned long long size)
+{
+ struct daxctl_ctx *ctx = daxctl_dev_get_ctx(dev);
+ char *path = dev->dev_buf;
+ int len = dev->buf_len;
+ char buf[SYSFS_ATTR_SIZE];
+
+ if (snprintf(path, len, "%s/size", dev->dev_path) >= len) {
+ err(ctx, "%s: buffer too small!\n",
+ daxctl_dev_get_devname(dev));
+ return -ENXIO;
+ }
+
+ sprintf(buf, "%#llx\n", size);
+ if (sysfs_write_attr(ctx, path, buf) != 0)
+ return -ENXIO;
+ dev->size = size;
+ return 0;
+}
@@ -44,4 +44,6 @@ global:
daxctl_region_get_align;
daxctl_region_get_first;
daxctl_region_get_next;
+ daxctl_dev_set_size;
+ daxctl_dev_get_ctx;
} LIBDAXCTL_3;
@@ -54,11 +54,13 @@ struct daxctl_dev;
struct daxctl_dev *daxctl_dev_get_first(struct daxctl_region *region);
struct daxctl_dev *daxctl_dev_get_next(struct daxctl_dev *dev);
struct daxctl_region *daxctl_dev_get_region(struct daxctl_dev *dev);
+struct daxctl_ctx *daxctl_dev_get_ctx(struct daxctl_dev *dev);
int daxctl_dev_get_id(struct daxctl_dev *dev);
const char *daxctl_dev_get_devname(struct daxctl_dev *dev);
int daxctl_dev_get_major(struct daxctl_dev *dev);
int daxctl_dev_get_minor(struct daxctl_dev *dev);
unsigned long long daxctl_dev_get_size(struct daxctl_dev *dev);
+int daxctl_dev_set_size(struct daxctl_dev *dev, unsigned long long size);
#define daxctl_dev_foreach(region, dev) \
for (dev = daxctl_dev_get_first(region); \
@@ -705,6 +705,39 @@ static int validate_dax(struct ndctl_dax *dax)
goto out;
}
+ if (ndctl_test_attempt(test, KERNEL_VERSION(4, 10, 0))) {
+ unsigned long long size;
+ struct daxctl_dev *active = NULL;
+
+ daxctl_dev_foreach(dax_region, dax_dev)
+ if (dax_dev != seed) {
+ active = dax_dev;
+ break;
+ }
+
+ if (!active) {
+ fprintf(stderr, "%s: failed to find active dax_dev\n",
+ devname);
+ return -ENXIO;
+ }
+
+ if (daxctl_dev_get_size(dax_dev)
+ != daxctl_region_get_size(dax_region)) {
+ fprintf(stderr, "%s: expected size: %#llx got %#llx\n",
+ devname, daxctl_region_get_size(dax_region),
+ daxctl_dev_get_size(dax_dev));
+ return -ENXIO;
+ }
+
+ size = daxctl_region_get_align(dax_region);
+ rc = daxctl_dev_set_size(dax_dev, size);
+ if (rc || daxctl_dev_get_size(dax_dev) != size) {
+ fprintf(stderr, "%s: failed set size rc: %d size: %#llx\n",
+ devname, rc, size);
+ return -ENXIO;
+ }
+ }
+
sprintf(devpath, "/dev/%s", daxctl_dev_get_devname(dax_dev));
fd = open(devpath, O_RDWR);
if (fd < 0) {
Starting with v4.10 the kernel allows resizing device-dax instances. Signed-off-by: Dan Williams <dan.j.williams@intel.com> --- daxctl/lib/libdaxctl.c | 26 ++++++++++++++++++++++++++ daxctl/lib/libdaxctl.sym | 2 ++ daxctl/libdaxctl.h | 2 ++ test/libndctl.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+)