diff mbox

[3/4] ndctl, create-namespace: use seed device to check dax alignment

Message ID 20170427091454.17412-3-oohall@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Oliver O'Halloran April 27, 2017, 9:14 a.m. UTC
The alignments supported by a dax or pfn device are depend on the fault
granularities supported by the kernel. Currently we just assume this
means 4K, 2M and 1G alignments are allowed, but now what we can query
the supported values from the seed namespace we should use that instead.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
 ndctl/builtin-xaction-namespace.c | 79 +++++++++++++++++++++------------------
 1 file changed, 42 insertions(+), 37 deletions(-)
diff mbox

Patch

diff --git a/ndctl/builtin-xaction-namespace.c b/ndctl/builtin-xaction-namespace.c
index 46d651e86153..4fdf50ef785a 100644
--- a/ndctl/builtin-xaction-namespace.c
+++ b/ndctl/builtin-xaction-namespace.c
@@ -397,7 +397,7 @@  static int validate_namespace_options(struct ndctl_region *region,
 		struct ndctl_namespace *ndns, struct parsed_parameters *p)
 {
 	const char *region_name = ndctl_region_get_devname(region);
-	unsigned long long size_align, units = 1;
+	unsigned long long size_align = 0, units = 1;
 	unsigned int ways;
 	int rc = 0;
 
@@ -460,57 +460,62 @@  static int validate_namespace_options(struct ndctl_region *region,
 
 		p->align = parse_size64(param.align);
 
-		if (p->mode == NDCTL_NS_MODE_MEMORY && p->align != SZ_2M
-				&& (!pfn || !ndctl_pfn_has_align(pfn))) {
+		if (p->mode == NDCTL_NS_MODE_MEMORY) {
+			if (!pfn) {
+				debug("%s does not support memory mode\n",
+					region_name);
+				return -EAGAIN;
+			}
+
 			/*
 			 * Initial pfn device support in the kernel
 			 * supported a 2M default alignment when
 			 * ndctl_pfn_has_align() returns false.
 			 */
-			debug("%s not support 'align' for memory mode\n",
+			if (p->align != SZ_2M && !ndctl_pfn_has_align(pfn)) {
+				debug("%s not support 'align' for memory mode\n",
 					region_name);
-			return -EAGAIN;
-		} else if (p->mode == NDCTL_NS_MODE_DAX
-				&& (!dax || !ndctl_dax_has_align(dax))) {
+				return -EAGAIN;
+			}
+
+			if (param.align_default)
+				p->align = ndctl_pfn_def_align(pfn);
+
+			if (!ndctl_pfn_supports_align(pfn, p->align)) {
+				error("unsupported alignment for memory mode: %s\n",
+					param.align);
+				return -EINVAL;
+			}
+
+			size_align = p->align;
+		} else if (p->mode == NDCTL_NS_MODE_DAX) {
 			/*
 			 * Unlike the pfn case, we require the kernel to
 			 * have 'align' support for device-dax.
 			 */
-			debug("%s not support 'align' for dax mode\n",
-					region_name);
-			return -EAGAIN;
-		} else if (!param.align_default
-				&& (p->mode == NDCTL_NS_MODE_SAFE
-					|| p->mode == NDCTL_NS_MODE_RAW)) {
-			/*
-			 * Specifying an alignment has no effect for
-			 * raw, or btt mode namespaces.
-			 */
+			if (!dax || !ndctl_dax_has_align(dax)) {
+				debug("%s not support 'align' for dax mode\n",
+						region_name);
+				return -EAGAIN;
+			}
+
+			if (param.align_default)
+				p->align = ndctl_dax_def_align(dax);
+
+			if (!ndctl_dax_supports_align(dax, p->align)) {
+				error("unsupported alignment for dax mode: %s\n",
+					param.align);
+				return -EINVAL;
+			}
+
+			size_align = p->align;
+		} else if (!param.align_default) {
+			/* in other cases the user should not supply an alignment */
 			error("%s mode does not support setting an alignment\n",
 					p->mode == NDCTL_NS_MODE_SAFE
 					? "sector" : "raw");
 			return -ENXIO;
 		}
-
-		switch (p->align) {
-		case SZ_4K:
-		case SZ_2M:
-		case SZ_1G:
-			break;
-		default:
-			error("unsupported align: %s\n", param.align);
-			return -ENXIO;
-		}
-
-		/*
-		 * 'raw' and 'sector' mode namespaces don't support an
-		 * alignment attribute.
-		 */
-		if (p->mode == NDCTL_NS_MODE_MEMORY
-				|| p->mode == NDCTL_NS_MODE_DAX)
-			size_align = p->align;
-		else
-			size_align = SZ_4K;
 	}
 
 	/* (re-)validate that the size satisfies the alignment */