A DAX device may require a page size different than getpagesize().

Signed-off-by: Haozhong Zhang <haozhong.zh...@intel.com>
---
 include/qemu/osdep.h | 10 ++++++++++
 util/mmap-alloc.c    |  6 ++++++
 util/osdep.c         | 23 +++++++++++++++++++++++
 3 files changed, 39 insertions(+)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 7f26af371e..51aca88f0d 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -479,4 +479,14 @@ pid_t qemu_fork(Error **errp);
  */
 bool qemu_fd_is_dev_dax(int fd);
 
+/**
+ * qemu_get_dev_dax_align:
+ *
+ * Get the suggested alignment of a DAX device descried by @fd.
+ *
+ * Return a non-zero suggested alignment on success; return 0 if @fd
+ * does not describe a DAX device, or if it fails to get alignment
+ * of the DAX device.
+ */
+size_t qemu_get_dev_dax_align(int fd);
 #endif
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 3ec029a9ea..2d8af64b44 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -25,8 +25,14 @@ size_t qemu_fd_getpagesize(int fd)
 #ifdef CONFIG_LINUX
     struct statfs fs;
     int ret;
+    size_t align;
 
     if (fd != -1) {
+        align = qemu_get_dev_dax_align(fd);
+        if (align) {
+            return align;
+        }
+
         do {
             ret = fstatfs(fd, &fs);
         } while (ret != 0 && errno == EINTR);
diff --git a/util/osdep.c b/util/osdep.c
index 02881f96bc..e7837d30b4 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -532,3 +532,26 @@ bool qemu_fd_is_dev_dax(int fd)
 
     return is_dax;
 }
+
+size_t qemu_get_dev_dax_align(int fd)
+{
+    size_t align = 0;
+
+#ifdef __linux__
+    char buf[12];
+    ssize_t len;
+
+    if (!qemu_fd_is_dev_dax(fd)) {
+        return 0;
+    }
+    len = qemu_dev_dax_sysfs_read(fd, "device/align", buf, sizeof(buf));
+    if (len <= 0) {
+        return 0;
+    }
+    if (qemu_strtosz(buf, NULL, &align) < 0) {
+        align = 0;
+    }
+#endif /* __linux__ */
+
+    return align;
+}
-- 
2.11.0


Reply via email to