@@ -31,6 +31,7 @@
#include <ccan/build_assert/build_assert.h>
#include <ndctl.h>
+#include <util/size.h>
#include <util/sysfs.h>
#include <ndctl/libndctl.h>
#include <ndctl/namespace.h>
@@ -237,6 +238,7 @@ struct ndctl_pfn {
int buf_len;
uuid_t uuid;
int id, generation;
+ struct ndctl_lbasize alignments;
};
struct ndctl_dax {
@@ -4781,6 +4783,18 @@ static void *__add_pfn(struct ndctl_pfn *pfn, const char *pfn_base)
else
pfn->size = strtoull(buf, NULL, 0);
+ /*
+ * If the kernel doesn't provide the supported_alignments sysfs
+ * attribute then it's safe to assume that we are running on x86
+ * which will always support 2MB and 4KB alignments.
+ */
+ sprintf(path, "%s/supported_alignments", pfn_base);
+ if (sysfs_read_attr(ctx, path, buf) < 0)
+ sprintf(buf, "%d %d", SZ_4K, SZ_2M);
+
+ if (parse_lbasize_supported(ctx, pfn_base, buf, &pfn->alignments) < 0)
+ goto err_read;
+
free(path);
return pfn;
@@ -5015,6 +5029,22 @@ NDCTL_EXPORT int ndctl_pfn_set_align(struct ndctl_pfn *pfn, unsigned long align)
return 0;
}
+NDCTL_EXPORT unsigned int ndctl_pfn_get_num_alignments(struct ndctl_pfn *pfn)
+{
+ return pfn->alignments.num;
+}
+
+NDCTL_EXPORT int ndctl_pfn_get_supported_alignment(struct ndctl_pfn *pfn, int i)
+{
+ if (pfn->alignments.num == 0)
+ return 0;
+
+ if (i < 0 || i > pfn->alignments.num)
+ return UINT_MAX;
+ else
+ return pfn->alignments.supported[i];
+}
+
NDCTL_EXPORT int ndctl_pfn_set_namespace(struct ndctl_pfn *pfn,
struct ndctl_namespace *ndns)
{
@@ -5237,6 +5267,16 @@ NDCTL_EXPORT unsigned long ndctl_dax_get_align(struct ndctl_dax *dax)
return ndctl_pfn_get_align(&dax->pfn);
}
+NDCTL_EXPORT unsigned int ndctl_dax_get_num_alignments(struct ndctl_dax *dax)
+{
+ return ndctl_pfn_get_num_alignments(&dax->pfn);
+}
+
+NDCTL_EXPORT int ndctl_dax_get_supported_alignment(struct ndctl_dax *dax, int i)
+{
+ return ndctl_pfn_get_supported_alignment(&dax->pfn, i);
+}
+
NDCTL_EXPORT int ndctl_dax_has_align(struct ndctl_dax *dax)
{
return ndctl_pfn_has_align(&dax->pfn);
@@ -385,3 +385,10 @@ global:
ndctl_namespace_get_next_badblock;
ndctl_dimm_get_dirty_shutdown;
} LIBNDCTL_17;
+
+LIBNDCTL_19 {
+ ndctl_pfn_get_supported_alignment;
+ ndctl_pfn_get_num_alignments;
+ ndctl_dax_get_supported_alignment;
+ ndctl_dax_get_num_alignments;
+} LIBNDCTL_18;
@@ -681,6 +681,12 @@ enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct ndctl_cmd *cmd);
struct ndctl_cmd *ndctl_dimm_cmd_new_ack_shutdown_count(struct ndctl_dimm *dimm);
int ndctl_dimm_fw_update_supported(struct ndctl_dimm *dimm);
+unsigned int ndctl_pfn_get_num_alignments(struct ndctl_pfn *pfn);
+int ndctl_pfn_get_supported_alignment(struct ndctl_pfn *pfn, int i);
+
+unsigned int ndctl_dax_get_num_alignments(struct ndctl_dax *dax);
+int ndctl_dax_get_supported_alignment(struct ndctl_dax *dax, int i);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
Newer kernels provide the "supported_alignments" sysfs attribute that indicates what alignments can be used with a PFN or DAX namespace. This patch adds the plumbing inside of libndctl to allow users to query this information through using: ndctl_{dax|pfn}_get_supported_alignment(), and ndctl_{dax|pfn}_get_num_alignments() Signed-off-by: Oliver O'Halloran <oohall@gmail.com> --- ndctl/lib/libndctl.c | 40 ++++++++++++++++++++++++++++++++++++++++ ndctl/lib/libndctl.sym | 7 +++++++ ndctl/libndctl.h | 6 ++++++ 3 files changed, 53 insertions(+)