The default alignment for write-infoblock command is set to 2M. Change
that to use the platform's supported alignment or PAGE_SIZE. The first
supported alignment is taken as the default.

Signed-off-by: Santosh Sivaraj <[email protected]>
---
 ndctl/namespace.c | 56 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 46 insertions(+), 10 deletions(-)

diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 0550580..4f056b7 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -175,7 +175,7 @@ OPT_STRING('m', "mode", &param.mode, "operation-mode", \
 OPT_STRING('s', "size", &param.size, "size", \
        "override the image size to instantiate the infoblock"), \
 OPT_STRING('a', "align", &param.align, "align", \
-       "specify the expected physical alignment (default: 2M)"), \
+       "specify the expected physical alignment"), \
 OPT_STRING('u', "uuid", &param.uuid, "uuid", \
        "specify the uuid for the infoblock (default: autogenerate)"), \
 OPT_STRING('M', "map", &param.map, "memmap-location", \
@@ -325,23 +325,15 @@ static int set_defaults(enum device_action action)
                                        sysconf(_SC_PAGE_SIZE));
                        rc = -EINVAL;
                }
-       } else if (action == ACTION_WRITE_INFOBLOCK)
-               param.align = "2M";
+       }
 
        if (param.size) {
                unsigned long long size = parse_size64(param.size);
-               unsigned long long align = parse_size64(param.align);
 
                if (size == ULLONG_MAX) {
                        error("failed to parse namespace size '%s'\n",
                                        param.size);
                        rc = -EINVAL;
-               } else if (action == ACTION_WRITE_INFOBLOCK
-                               && align < ULLONG_MAX
-                               && !IS_ALIGNED(size, align)) {
-                       error("--size=%s not aligned to %s\n", param.size,
-                                       param.align);
-                       rc = -EINVAL;
                }
        }
 
@@ -1982,6 +1974,23 @@ out:
        return rc;
 }
 
+static unsigned long ndctl_get_default_alignment(struct ndctl_namespace *ndns)
+{
+       unsigned long long align = 0;
+       struct ndctl_dax *dax = ndctl_namespace_get_dax(ndns);
+       struct ndctl_pfn *pfn = ndctl_namespace_get_pfn(ndns);
+
+       if (ndctl_namespace_get_mode(ndns) == NDCTL_NS_MODE_FSDAX && pfn)
+               align = ndctl_pfn_get_supported_alignment(pfn, 1);
+       else if (ndctl_namespace_get_mode(ndns) == NDCTL_NS_MODE_DEVDAX && dax)
+               align = ndctl_dax_get_supported_alignment(dax, 1);
+
+       if (!align)
+               align =  sysconf(_SC_PAGE_SIZE);
+
+       return align;
+}
+
 static int namespace_rw_infoblock(struct ndctl_namespace *ndns,
                struct read_infoblock_ctx *ri_ctx, int write)
 {
@@ -1992,12 +2001,36 @@ static int namespace_rw_infoblock(struct 
ndctl_namespace *ndns,
        const char *save;
        const char *cmd = write ? "write-infoblock" : "read-infoblock";
        const char *devname = ndctl_namespace_get_devname(ndns);
+       unsigned long long align;
 
        if (ndctl_namespace_is_active(ndns)) {
                pr_verbose("%s: %s enabled, must be disabled\n", cmd, devname);
                return -EBUSY;
        }
 
+       if (write) {
+               if (!param.align) {
+                       align = ndctl_get_default_alignment(ndns);
+
+                       if (asprintf((char **)&param.align, "%llu", align) < 0) 
{
+                               rc = -EINVAL;
+                               goto out;
+                       }
+               }
+
+               if (param.size) {
+                       unsigned long long size = parse_size64(param.size);
+                       align = parse_size64(param.align);
+
+                       if (align < ULLONG_MAX && !IS_ALIGNED(size, align)) {
+                               error("--size=%s not aligned to %s\n", 
param.size,
+                                     param.align);
+                               rc = -EINVAL;
+                               goto out;
+                       }
+               }
+       }
+
        ndctl_namespace_set_raw_mode(ndns, 1);
        rc = ndctl_namespace_enable(ndns);
        if (rc < 0) {
@@ -2060,6 +2093,9 @@ static int do_xaction_namespace(const char *namespace,
        }
 
        if (action == ACTION_WRITE_INFOBLOCK && !namespace) {
+               if (!param.align)
+                       param.align = "2M";
+
                rc = file_write_infoblock(param.outfile);
                if (rc >= 0)
                        (*processed)++;
-- 
2.26.2
_______________________________________________
Linux-nvdimm mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to