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 | 69 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 13 deletions(-) v2: Get the 'write-infoblock all' path right [Ira] diff --git a/ndctl/namespace.c b/ndctl/namespace.c index 0550580..8aa5a42 100644 --- a/ndctl/namespace.c +++ b/ndctl/namespace.c @@ -175,7 +175,7 @@ OPT_STRING('m', "mode", ¶m.mode, "operation-mode", \ OPT_STRING('s', "size", ¶m.size, "size", \ "override the image size to instantiate the infoblock"), \ OPT_STRING('a', "align", ¶m.align, "align", \ - "specify the expected physical alignment (default: 2M)"), \ + "specify the expected physical alignment"), \ OPT_STRING('u', "uuid", ¶m.uuid, "uuid", \ "specify the uuid for the infoblock (default: autogenerate)"), \ OPT_STRING('M', "map", ¶m.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) { @@ -2013,9 +2022,40 @@ static int namespace_rw_infoblock(struct ndctl_namespace *ndns, } sprintf(path, "/dev/%s", ndctl_namespace_get_block_device(ndns)); - if (write) - rc = file_write_infoblock(path); - else + if (write) { + unsigned long long align; + bool align_provided = true; + + if (!param.align) { + align = ndctl_get_default_alignment(ndns); + + if (asprintf((char **)¶m.align, "%llu", align) < 0) { + rc = -EINVAL; + goto out; + } + align_provided = false; + } + + 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; + } + } + + if (!rc) + rc = file_write_infoblock(path); + + if (!align_provided) { + free((char *)param.align); + param.align = NULL; + } + } else rc = file_read_infoblock(path, ndns, ri_ctx); param.parent_uuid = save; out: @@ -2060,6 +2100,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]
