Tomas Bzatek 98e299
From 2c4324b658931882bfb664e05673cd5c9082429d Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Fri, 7 Oct 2022 15:42:44 +0200
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Rework the disconnect device topology crawl
Tomas Bzatek 98e299
Tomas Bzatek 98e299
This is more sane regarding to memory ownership and
Tomas Bzatek 98e299
the scanned topology tree.
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-fabrics.c | 93 +++++++++++++++++----------------
Tomas Bzatek 98e299
 tests/nvme_test.py              |  2 +-
Tomas Bzatek 98e299
 2 files changed, 50 insertions(+), 45 deletions(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-fabrics.c b/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
index 20ed57f5d..26e2fa6ec 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
@@ -281,6 +281,47 @@ gboolean bd_nvme_connect (const gchar *subsysnqn, const gchar *transport, const
Tomas Bzatek 98e299
     return TRUE;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+static gboolean _disconnect (const gchar *subsysnqn, const gchar *path, GError **error, gboolean *found) {
Tomas Bzatek 98e299
+    nvme_root_t root;
Tomas Bzatek 98e299
+    nvme_host_t host;
Tomas Bzatek 98e299
+    nvme_subsystem_t subsys;
Tomas Bzatek 98e299
+    nvme_ctrl_t ctrl;
Tomas Bzatek 98e299
+    int ret;
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+    root = nvme_create_root (NULL, -1);
Tomas Bzatek 98e299
+    if (root == NULL) {
Tomas Bzatek 98e299
+        g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_FAILED,
Tomas Bzatek 98e299
+                     "Failed to create topology root: %s",
Tomas Bzatek 98e299
+                     strerror_l (errno, _C_LOCALE));
Tomas Bzatek 98e299
+        return FALSE;
Tomas Bzatek 98e299
+    }
Tomas Bzatek 98e299
+    ret = nvme_scan_topology (root, NULL, NULL);
Tomas Bzatek 98e299
+    if (ret < 0) {
Tomas Bzatek 98e299
+        g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_FAILED,
Tomas Bzatek 98e299
+                     "Failed to scan topology: %s",
Tomas Bzatek 98e299
+                     strerror_l (errno, _C_LOCALE));
Tomas Bzatek 98e299
+        nvme_free_tree (root);
Tomas Bzatek 98e299
+        return FALSE;
Tomas Bzatek 98e299
+    }
Tomas Bzatek 98e299
+    nvme_for_each_host (root, host)
Tomas Bzatek 98e299
+        nvme_for_each_subsystem (host, subsys)
Tomas Bzatek 98e299
+            if (!subsysnqn || g_strcmp0 (nvme_subsystem_get_nqn (subsys), subsysnqn) == 0)
Tomas Bzatek 98e299
+                nvme_subsystem_for_each_ctrl (subsys, ctrl)
Tomas Bzatek 98e299
+                    if (!path || g_strcmp0 (nvme_ctrl_get_name (ctrl), path) == 0) {
Tomas Bzatek 98e299
+                        ret = nvme_disconnect_ctrl (ctrl);
Tomas Bzatek 98e299
+                        if (ret != 0) {
Tomas Bzatek 98e299
+                            g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_FAILED,
Tomas Bzatek 98e299
+                                         "Error disconnecting the controller: %s",
Tomas Bzatek 98e299
+                                         strerror_l (errno, _C_LOCALE));
Tomas Bzatek 98e299
+                            nvme_free_tree (root);
Tomas Bzatek 98e299
+                            return FALSE;
Tomas Bzatek 98e299
+                        }
Tomas Bzatek 98e299
+                        *found = TRUE;
Tomas Bzatek 98e299
+                    }
Tomas Bzatek 98e299
+    nvme_free_tree (root);
Tomas Bzatek 98e299
+    return TRUE;
Tomas Bzatek 98e299
+}
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
 /**
Tomas Bzatek 98e299
  * bd_nvme_disconnect:
Tomas Bzatek 98e299
  * @subsysnqn: The name of the NVMe subsystem to disconnect.
Tomas Bzatek 98e299
@@ -296,37 +337,16 @@ gboolean bd_nvme_connect (const gchar *subsysnqn, const gchar *transport, const
Tomas Bzatek 98e299
  * Tech category: %BD_NVME_TECH_FABRICS-%BD_NVME_TECH_MODE_INITIATOR
Tomas Bzatek 98e299
  */
Tomas Bzatek 98e299
 gboolean bd_nvme_disconnect (const gchar *subsysnqn, GError **error) {
Tomas Bzatek 98e299
-    nvme_root_t root;
Tomas Bzatek 98e299
-    nvme_host_t host;
Tomas Bzatek 98e299
-    nvme_subsystem_t subsys;
Tomas Bzatek 98e299
-    nvme_ctrl_t ctrl;
Tomas Bzatek 98e299
     gboolean found = FALSE;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    root = nvme_scan (NULL);
Tomas Bzatek 98e299
-    nvme_init_logging (root, -1, false, false);
Tomas Bzatek 98e299
-    nvme_for_each_host (root, host)
Tomas Bzatek 98e299
-        nvme_for_each_subsystem (host, subsys)
Tomas Bzatek 98e299
-            if (g_strcmp0 (nvme_subsystem_get_nqn (subsys), subsysnqn) == 0)
Tomas Bzatek 98e299
-                nvme_subsystem_for_each_ctrl (subsys, ctrl) {
Tomas Bzatek 98e299
-                    int ret;
Tomas Bzatek 98e299
-
Tomas Bzatek 98e299
-                    ret = nvme_disconnect_ctrl (ctrl);
Tomas Bzatek 98e299
-                    if (ret != 0) {
Tomas Bzatek 98e299
-                        g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_FAILED,
Tomas Bzatek 98e299
-                                     "Error disconnecting the controller: %s",
Tomas Bzatek 98e299
-                                     strerror_l (errno, _C_LOCALE));
Tomas Bzatek 98e299
-                        nvme_free_tree (root);
Tomas Bzatek 98e299
-                        return FALSE;
Tomas Bzatek 98e299
-                    }
Tomas Bzatek 98e299
-                    found = TRUE;
Tomas Bzatek 98e299
-                }
Tomas Bzatek 98e299
-    nvme_free_tree (root);
Tomas Bzatek 98e299
+    if (!_disconnect (subsysnqn, NULL, error, &found))
Tomas Bzatek 98e299
+        return FALSE;
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
     if (!found) {
Tomas Bzatek 98e299
         g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_NO_MATCH,
Tomas Bzatek 98e299
                      "No subsystems matching '%s' NQN found.", subsysnqn);
Tomas Bzatek 98e299
         return FALSE;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
-
Tomas Bzatek 98e299
     return TRUE;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -344,36 +364,21 @@ gboolean bd_nvme_disconnect (const gchar *subsysnqn, GError **error) {
Tomas Bzatek 98e299
  * Tech category: %BD_NVME_TECH_FABRICS-%BD_NVME_TECH_MODE_INITIATOR
Tomas Bzatek 98e299
  */
Tomas Bzatek 98e299
 gboolean bd_nvme_disconnect_by_path (const gchar *path, GError **error) {
Tomas Bzatek 98e299
-    nvme_root_t root;
Tomas Bzatek 98e299
-    nvme_ctrl_t ctrl;
Tomas Bzatek 98e299
     const gchar *p;
Tomas Bzatek 98e299
-    int ret;
Tomas Bzatek 98e299
+    gboolean found = FALSE;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     p = path;
Tomas Bzatek 98e299
     if (g_str_has_prefix (p, "/dev/"))
Tomas Bzatek 98e299
         p += 5;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    root = nvme_scan (NULL);
Tomas Bzatek 98e299
-    nvme_init_logging (root, -1, false, false);
Tomas Bzatek 98e299
-    ctrl = nvme_scan_ctrl (root, p);
Tomas Bzatek 98e299
-    if (!ctrl) {
Tomas Bzatek 98e299
-        g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_NO_MATCH,
Tomas Bzatek 98e299
-                     "Unable to match a NVMeoF controller for the specified block device %s.",
Tomas Bzatek 98e299
-                     path);
Tomas Bzatek 98e299
-        nvme_free_tree (root);
Tomas Bzatek 98e299
+    if (!_disconnect (NULL, p, error, &found))
Tomas Bzatek 98e299
         return FALSE;
Tomas Bzatek 98e299
-    }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    ret = nvme_disconnect_ctrl (ctrl);
Tomas Bzatek 98e299
-    if (ret != 0) {
Tomas Bzatek 98e299
-        g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_FAILED,
Tomas Bzatek 98e299
-                     "Error disconnecting the controller: %s",
Tomas Bzatek 98e299
-                     strerror_l (errno, _C_LOCALE));
Tomas Bzatek 98e299
-        nvme_free_tree (root);
Tomas Bzatek 98e299
+    if (!found) {
Tomas Bzatek 98e299
+        g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_NO_MATCH,
Tomas Bzatek 98e299
+                     "No controllers matching the %s device name found.", path);
Tomas Bzatek 98e299
         return FALSE;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
-    nvme_free_tree (root);
Tomas Bzatek 98e299
-
Tomas Bzatek 98e299
     return TRUE;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
diff --git a/tests/nvme_test.py b/tests/nvme_test.py
Tomas Bzatek 98e299
index f205e5391..696d594c9 100644
Tomas Bzatek 98e299
--- a/tests/nvme_test.py
Tomas Bzatek 98e299
+++ b/tests/nvme_test.py
Tomas Bzatek 98e299
@@ -387,7 +387,7 @@ def test_connect_single_ns(self):
Tomas Bzatek 98e299
         # disconnect
Tomas Bzatek 98e299
         with self.assertRaisesRegexp(GLib.GError, r"No subsystems matching '.*' NQN found."):
Tomas Bzatek 98e299
             BlockDev.nvme_disconnect(self.SUBNQN + "xx")
Tomas Bzatek 98e299
-        with self.assertRaisesRegexp(GLib.GError, r"Unable to match a NVMeoF controller for the specified block device /dev/nvme.*xx"):
Tomas Bzatek 98e299
+        with self.assertRaisesRegexp(GLib.GError, r"No controllers matching the /dev/nvme.*xx device name found."):
Tomas Bzatek 98e299
             BlockDev.nvme_disconnect_by_path(ctrls[0] + "xx")
Tomas Bzatek 98e299
         # should disconnect both connections as long the SUBNQN matches
Tomas Bzatek 98e299
         BlockDev.nvme_disconnect(self.SUBNQN)
Tomas Bzatek 98e299
From ac1e0c50dd7bab21a7837c806b82bf34090127d1 Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Sun, 5 Feb 2023 21:51:42 +0100
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Strip trailing whitespaces from subsysnqn when matching
Tomas Bzatek 98e299
 the device tree
Tomas Bzatek 98e299
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-fabrics.c | 9 ++++++++-
Tomas Bzatek 98e299
 1 file changed, 8 insertions(+), 1 deletion(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-fabrics.c b/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
index 5cc7f670d..27f6ed444 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
@@ -721,6 +721,12 @@ gchar ** bd_nvme_find_ctrls_for_ns (const gchar *ns_sysfs_path, const gchar *sub
Tomas Bzatek 98e299
     nvme_ctrl_t c;
Tomas Bzatek 98e299
     nvme_ns_t n;
Tomas Bzatek 98e299
     char realp[PATH_MAX];
Tomas Bzatek 98e299
+    gchar *subsysnqn_p;
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+    /* libnvme strips trailing spaces and newlines when reading values from sysfs */
Tomas Bzatek 98e299
+    subsysnqn_p = g_strdup (subsysnqn);
Tomas Bzatek 98e299
+    if (subsysnqn_p)
Tomas Bzatek 98e299
+        g_strchomp (subsysnqn_p);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     ptr_array = g_ptr_array_new ();
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -736,7 +742,7 @@ gchar ** bd_nvme_find_ctrls_for_ns (const gchar *ns_sysfs_path, const gchar *sub
Tomas Bzatek 98e299
         nvme_for_each_subsystem (h, s) {
Tomas Bzatek 98e299
             gboolean found = FALSE;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-            if (subsysnqn && g_strcmp0 (nvme_subsystem_get_nqn (s), subsysnqn) != 0)
Tomas Bzatek 98e299
+            if (subsysnqn && g_strcmp0 (nvme_subsystem_get_nqn (s), subsysnqn_p) != 0)
Tomas Bzatek 98e299
                 continue;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
             nvme_subsystem_for_each_ctrl (s, c)
Tomas Bzatek 98e299
@@ -767,6 +773,7 @@ gchar ** bd_nvme_find_ctrls_for_ns (const gchar *ns_sysfs_path, const gchar *sub
Tomas Bzatek 98e299
         }
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     nvme_free_tree (root);
Tomas Bzatek 98e299
+    g_free (subsysnqn_p);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     g_ptr_array_add (ptr_array, NULL);  /* trailing NULL element */
Tomas Bzatek 98e299
     return (gchar **) g_ptr_array_free (ptr_array, FALSE);
Tomas Bzatek 98e299
From 29b4defc50451dd54f1a7a988b92bdf5fadb22df Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Mon, 6 Feb 2023 11:29:43 +0100
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Return NULL in case the supported NVMe revision is not
Tomas Bzatek 98e299
 reported
Tomas Bzatek 98e299
Tomas Bzatek 98e299
...as is often the case for older, pre-1.2 NVMe devices.
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/lib/plugin_apis/nvme.api | 2 +-
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-info.c | 2 ++
Tomas Bzatek 98e299
 src/plugins/nvme/nvme.h      | 2 +-
Tomas Bzatek 98e299
 3 files changed, 4 insertions(+), 2 deletions(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/lib/plugin_apis/nvme.api b/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
index 7bc2cf9ef..6e73870e5 100644
Tomas Bzatek 98e299
--- a/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
+++ b/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
@@ -142,7 +142,7 @@ GType bd_nvme_controller_info_get_type ();
Tomas Bzatek 98e299
  * @model_number: The model number.
Tomas Bzatek 98e299
  * @serial_number: The serial number.
Tomas Bzatek 98e299
  * @firmware_ver: The currently active firmware revision.
Tomas Bzatek 98e299
- * @nvme_ver: The NVM Express base specification that the controller implementation supports.
Tomas Bzatek 98e299
+ * @nvme_ver: The NVM Express base specification that the controller implementation supports or %NULL when not reported by the device.
Tomas Bzatek 98e299
  * @features: features and capabilities present for this controller, see #BDNVMEControllerFeature.
Tomas Bzatek 98e299
  * @controller_type: The controller type.
Tomas Bzatek 98e299
  * @selftest_ext_time: Extended Device Self-test Time, if #BD_NVME_CTRL_FEAT_SELFTEST is supported then this field
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-info.c b/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
index ec5cae332..23ee8afde 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
@@ -401,6 +401,8 @@ static gchar *decode_nvme_rev (guint32 ver) {
Tomas Bzatek 98e299
     if (mjr >= 2 || mnr >= 2)
Tomas Bzatek 98e299
         ter = ver & 0xFF;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+    if (mjr == 0 && mnr == 0)
Tomas Bzatek 98e299
+        return NULL;
Tomas Bzatek 98e299
     if (ter == 0)
Tomas Bzatek 98e299
         return g_strdup_printf ("%u.%u", mjr, mnr);
Tomas Bzatek 98e299
     else
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme.h b/src/plugins/nvme/nvme.h
Tomas Bzatek 98e299
index ad456a82e..fa6f6abcc 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme.h
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme.h
Tomas Bzatek 98e299
@@ -129,7 +129,7 @@ typedef enum {
Tomas Bzatek 98e299
  * @model_number: The model number.
Tomas Bzatek 98e299
  * @serial_number: The serial number.
Tomas Bzatek 98e299
  * @firmware_ver: The currently active firmware revision.
Tomas Bzatek 98e299
- * @nvme_ver: The NVM Express base specification that the controller implementation supports.
Tomas Bzatek 98e299
+ * @nvme_ver: The NVM Express base specification that the controller implementation supports or %NULL when not reported by the device.
Tomas Bzatek 98e299
  * @features: features and capabilities present for this controller, see #BDNVMEControllerFeature.
Tomas Bzatek 98e299
  * @controller_type: The controller type.
Tomas Bzatek 98e299
  * @selftest_ext_time: Extended Device Self-test Time, if #BD_NVME_CTRL_FEAT_SELFTEST is supported then this field
Tomas Bzatek 98e299
From 5a709aa3475ee083237c3faf4fff8c316767bd71 Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Wed, 26 Apr 2023 18:39:57 +0200
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Add support for ENVME_CONNECT_CONNREFUSED
Tomas Bzatek 98e299
Tomas Bzatek 98e299
Requires libnvme-1.3
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 configure.ac                  | 2 +-
Tomas Bzatek 98e299
 src/lib/plugin_apis/nvme.api  | 2 ++
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-error.c | 3 +++
Tomas Bzatek 98e299
 src/plugins/nvme/nvme.h       | 2 ++
Tomas Bzatek 98e299
 4 files changed, 8 insertions(+), 1 deletion(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/configure.ac b/configure.ac
Tomas Bzatek 98e299
index 727465c9b..16fe3a0c2 100644
Tomas Bzatek 98e299
--- a/configure.ac
Tomas Bzatek 98e299
+++ b/configure.ac
Tomas Bzatek 98e299
@@ -238,7 +238,7 @@ AS_IF([test "x$with_nvdimm" != "xno"],
Tomas Bzatek 98e299
       [])
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 AS_IF([test "x$with_nvme" != "xno"],
Tomas Bzatek 98e299
-      [LIBBLOCKDEV_PKG_CHECK_MODULES([NVME], [libnvme >= 1.2])],
Tomas Bzatek 98e299
+      [LIBBLOCKDEV_PKG_CHECK_MODULES([NVME], [libnvme >= 1.3])],
Tomas Bzatek 98e299
       [])
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 AS_IF([test "x$with_vdo" != "xno"],
Tomas Bzatek 98e299
diff --git a/src/lib/plugin_apis/nvme.api b/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
index 6e73870e5..1099da7db 100644
Tomas Bzatek 98e299
--- a/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
+++ b/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
@@ -31,6 +31,7 @@ GQuark bd_nvme_error_quark (void) {
Tomas Bzatek 98e299
  * @BD_NVME_ERROR_CONNECT_ADDRINUSE: HostNQN already in use.
Tomas Bzatek 98e299
  * @BD_NVME_ERROR_CONNECT_NODEV: Invalid interface.
Tomas Bzatek 98e299
  * @BD_NVME_ERROR_CONNECT_OPNOTSUPP: Operation not supported.
Tomas Bzatek 98e299
+ * @BD_NVME_ERROR_CONNECT_REFUSED: Connection refused.
Tomas Bzatek 98e299
  */
Tomas Bzatek 98e299
 /* BpG-skip-end */
Tomas Bzatek 98e299
 typedef enum {
Tomas Bzatek 98e299
@@ -51,6 +52,7 @@ typedef enum {
Tomas Bzatek 98e299
     BD_NVME_ERROR_CONNECT_ADDRINUSE,
Tomas Bzatek 98e299
     BD_NVME_ERROR_CONNECT_NODEV,
Tomas Bzatek 98e299
     BD_NVME_ERROR_CONNECT_OPNOTSUPP,
Tomas Bzatek 98e299
+    BD_NVME_ERROR_CONNECT_REFUSED,
Tomas Bzatek 98e299
 } BDNVMEError;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 typedef enum {
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-error.c b/src/plugins/nvme/nvme-error.c
Tomas Bzatek 98e299
index cb95a46dc..4bd4d7712 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-error.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-error.c
Tomas Bzatek 98e299
@@ -137,6 +137,9 @@ void _nvme_fabrics_errno_to_gerror (int result, int _errno, GError **error)
Tomas Bzatek 98e299
             case ENVME_CONNECT_OPNOTSUPP:
Tomas Bzatek 98e299
                 code = BD_NVME_ERROR_CONNECT_OPNOTSUPP;
Tomas Bzatek 98e299
                 break;
Tomas Bzatek 98e299
+            case ENVME_CONNECT_CONNREFUSED:
Tomas Bzatek 98e299
+                code = BD_NVME_ERROR_CONNECT_REFUSED;
Tomas Bzatek 98e299
+                break;
Tomas Bzatek 98e299
             default:
Tomas Bzatek 98e299
                 code = BD_NVME_ERROR_CONNECT;
Tomas Bzatek 98e299
         }
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme.h b/src/plugins/nvme/nvme.h
Tomas Bzatek 98e299
index 438d66334..afd41b267 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme.h
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme.h
Tomas Bzatek 98e299
@@ -27,6 +27,7 @@ GQuark bd_nvme_error_quark (void);
Tomas Bzatek 98e299
  * @BD_NVME_ERROR_CONNECT_ADDRINUSE: HostNQN already in use.
Tomas Bzatek 98e299
  * @BD_NVME_ERROR_CONNECT_NODEV: Invalid interface.
Tomas Bzatek 98e299
  * @BD_NVME_ERROR_CONNECT_OPNOTSUPP: Operation not supported.
Tomas Bzatek 98e299
+ * @BD_NVME_ERROR_CONNECT_REFUSED: Connection refused.
Tomas Bzatek 98e299
  */
Tomas Bzatek 98e299
 typedef enum {
Tomas Bzatek 98e299
     BD_NVME_ERROR_TECH_UNAVAIL,
Tomas Bzatek 98e299
@@ -46,6 +47,7 @@ typedef enum {
Tomas Bzatek 98e299
     BD_NVME_ERROR_CONNECT_ADDRINUSE,
Tomas Bzatek 98e299
     BD_NVME_ERROR_CONNECT_NODEV,
Tomas Bzatek 98e299
     BD_NVME_ERROR_CONNECT_OPNOTSUPP,
Tomas Bzatek 98e299
+    BD_NVME_ERROR_CONNECT_REFUSED,
Tomas Bzatek 98e299
 } BDNVMEError;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 typedef enum {
Tomas Bzatek 98e299
From b19600de73233317cd9de68dba356ec4bb80a0f3 Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Thu, 27 Apr 2023 17:32:25 +0200
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Add support for 'keyring' and 'tls_key' fabrics
Tomas Bzatek 98e299
 attributes
Tomas Bzatek 98e299
Tomas Bzatek 98e299
Requires libnvme-1.4
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 configure.ac                    |  5 ++++-
Tomas Bzatek 98e299
 src/lib/plugin_apis/nvme.api    |  2 ++
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-fabrics.c | 21 +++++++++++++++++++++
Tomas Bzatek 98e299
 3 files changed, 27 insertions(+), 1 deletion(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/configure.ac b/configure.ac
Tomas Bzatek 98e299
index 16fe3a0c2..12d007a53 100644
Tomas Bzatek 98e299
--- a/configure.ac
Tomas Bzatek 98e299
+++ b/configure.ac
Tomas Bzatek 98e299
@@ -238,7 +238,10 @@ AS_IF([test "x$with_nvdimm" != "xno"],
Tomas Bzatek 98e299
       [])
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 AS_IF([test "x$with_nvme" != "xno"],
Tomas Bzatek 98e299
-      [LIBBLOCKDEV_PKG_CHECK_MODULES([NVME], [libnvme >= 1.3])],
Tomas Bzatek 98e299
+      [LIBBLOCKDEV_PKG_CHECK_MODULES([NVME], [libnvme >= 1.3])
Tomas Bzatek 98e299
+      AS_IF([$PKG_CONFIG --atleast-version=1.4 libnvme],
Tomas Bzatek 98e299
+            [AC_DEFINE([HAVE_LIBNVME_1_4])], [])
Tomas Bzatek 98e299
+      ],
Tomas Bzatek 98e299
       [])
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 AS_IF([test "x$with_vdo" != "xno"],
Tomas Bzatek 98e299
diff --git a/src/lib/plugin_apis/nvme.api b/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
index 1099da7db..667dbe9e0 100644
Tomas Bzatek 98e299
--- a/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
+++ b/src/lib/plugin_apis/nvme.api
Tomas Bzatek 98e299
@@ -1415,6 +1415,8 @@ gboolean bd_nvme_set_host_id (const gchar *host_id, GError **error);
Tomas Bzatek 98e299
  * - `"data_digest"`: Generates/verifies data digest (TCP). Boolean value.
Tomas Bzatek 98e299
  * - `"tls"`: Enable TLS encryption (TCP). Boolean value.
Tomas Bzatek 98e299
  * - `"hostsymname"`: TP8010: NVMe host symbolic name.
Tomas Bzatek 98e299
+ * - `"keyring"`: Keyring to store and lookup keys. String value.
Tomas Bzatek 98e299
+ * - `"tls_key"`: TLS PSK for the connection. String value.
Tomas Bzatek 98e299
  *
Tomas Bzatek 98e299
  * Boolean values can be expressed by "0"/"1", "on"/"off" or "True"/"False" case-insensitive
Tomas Bzatek 98e299
  * strings. Failed numerical or boolean string conversions will result in the option being ignored.
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-fabrics.c b/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
index 27f6ed444..0c64fb513 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
@@ -125,6 +125,25 @@ static void parse_extra_args (const BDExtraArg **extra, struct nvme_fabrics_conf
Tomas Bzatek 98e299
         else
Tomas Bzatek 98e299
         if (g_strcmp0 ((*extra_i)->opt, "tls") == 0)
Tomas Bzatek 98e299
             SAFE_BOOL_CONV (cfg->tls)
Tomas Bzatek 98e299
+#ifdef HAVE_LIBNVME_1_4
Tomas Bzatek 98e299
+        else
Tomas Bzatek 98e299
+        if (g_strcmp0 ((*extra_i)->opt, "keyring") == 0) {
Tomas Bzatek 98e299
+            int keyring;
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+            keyring = nvme_lookup_keyring ((*extra_i)->val);
Tomas Bzatek 98e299
+            if (keyring) {
Tomas Bzatek 98e299
+                cfg->keyring = keyring;
Tomas Bzatek 98e299
+                nvme_set_keyring (cfg->keyring);
Tomas Bzatek 98e299
+            }
Tomas Bzatek 98e299
+        } else
Tomas Bzatek 98e299
+        if (g_strcmp0 ((*extra_i)->opt, "tls_key") == 0) {
Tomas Bzatek 98e299
+            int key;
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+            key = nvme_lookup_key ("psk", (*extra_i)->val);
Tomas Bzatek 98e299
+            if (key)
Tomas Bzatek 98e299
+                cfg->tls_key = key;
Tomas Bzatek 98e299
+        }
Tomas Bzatek 98e299
+#endif
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 #undef SAFE_INT_CONV
Tomas Bzatek 98e299
@@ -179,6 +198,8 @@ static void parse_extra_args (const BDExtraArg **extra, struct nvme_fabrics_conf
Tomas Bzatek 98e299
  * - `"data_digest"`: Generates/verifies data digest (TCP). Boolean value.
Tomas Bzatek 98e299
  * - `"tls"`: Enable TLS encryption (TCP). Boolean value.
Tomas Bzatek 98e299
  * - `"hostsymname"`: TP8010: NVMe host symbolic name.
Tomas Bzatek 98e299
+ * - `"keyring"`: Keyring to store and lookup keys. String value.
Tomas Bzatek 98e299
+ * - `"tls_key"`: TLS PSK for the connection. String value.
Tomas Bzatek 98e299
  *
Tomas Bzatek 98e299
  * Boolean values can be expressed by "0"/"1", "on"/"off" or "True"/"False" case-insensitive
Tomas Bzatek 98e299
  * strings. Failed numerical or boolean string conversions will result in the option being ignored.
Tomas Bzatek 98e299
From 941448f5ec9f465266e1baf5de23e36692a17274 Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Thu, 27 Apr 2023 19:05:00 +0200
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Fix 128-bit int conversion
Tomas Bzatek 98e299
Tomas Bzatek 98e299
Still using target 64-bit int and expecting overflow. This change
Tomas Bzatek 98e299
at least handles endianness conversion properly.
Tomas Bzatek 98e299
Tomas Bzatek 98e299
Futher experiments reveal shortcomings during gobject-introspection
Tomas Bzatek 98e299
data type translation so until 128-bit int is properly supported
Tomas Bzatek 98e299
throughout the stack, we can only hope numbers won't be that high.
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-info.c | 17 ++++++++++++++---
Tomas Bzatek 98e299
 1 file changed, 14 insertions(+), 3 deletions(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-info.c b/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
index 23ee8afde..bbc7de4f2 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
@@ -365,15 +365,26 @@ BDNVMESanitizeLog * bd_nvme_sanitize_log_copy (BDNVMESanitizeLog *log) {
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-static guint64 int128_to_guint64 (__u8 *data)
Tomas Bzatek 98e299
+/* can't use real __int128 due to gobject-introspection */
Tomas Bzatek 98e299
+static guint64 int128_to_guint64 (__u8 data[16])
Tomas Bzatek 98e299
 {
Tomas Bzatek 98e299
     int i;
Tomas Bzatek 98e299
+    __u8 d[16];
Tomas Bzatek 98e299
     guint64 result = 0;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    /* FIXME: would overflow, need to find 128-bit int */
Tomas Bzatek 98e299
+    /* endianness conversion */
Tomas Bzatek 98e299
+#if G_BYTE_ORDER == G_BIG_ENDIAN
Tomas Bzatek 98e299
+    for (i = 0; i < 16; i++)
Tomas Bzatek 98e299
+        d[i] = data[15 - i];
Tomas Bzatek 98e299
+#else
Tomas Bzatek 98e299
+    memcpy (d, data, sizeof (d));
Tomas Bzatek 98e299
+#endif
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+    /* FIXME: would overflow */
Tomas Bzatek 98e299
+    /* https://github.com/linux-nvme/libnvme/issues/475 */
Tomas Bzatek 98e299
     for (i = 0; i < 16; i++) {
Tomas Bzatek 98e299
         result *= 256;
Tomas Bzatek 98e299
-        result += data[15 - i];
Tomas Bzatek 98e299
+        result += d[15 - i];
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     return result;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
From 5f118338e52a9096fdbac5ee9aa9c1e43f8b038b Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Vojtech Trefny <vtrefny@redhat.com>
Tomas Bzatek 98e299
Date: Fri, 23 Jun 2023 13:05:24 +0200
Tomas Bzatek 98e299
Subject: [PATCH] docs: Change NVMe plugin description to be consistent with
Tomas Bzatek 98e299
 other plugins
Tomas Bzatek 98e299
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/plugins/nvme/nvme.c | 2 +-
Tomas Bzatek 98e299
 1 file changed, 1 insertion(+), 1 deletion(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme.c b/src/plugins/nvme/nvme.c
Tomas Bzatek 98e299
index c0f4759de..c319f088c 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme.c
Tomas Bzatek 98e299
@@ -36,7 +36,7 @@
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 /**
Tomas Bzatek 98e299
  * SECTION: nvme
Tomas Bzatek 98e299
- * @short_description: NVMe device reporting and management.
Tomas Bzatek 98e299
+ * @short_description: plugin for NVMe device reporting and management
Tomas Bzatek 98e299
  * @title: NVMe
Tomas Bzatek 98e299
  * @include: nvme.h
Tomas Bzatek 98e299
  *
Tomas Bzatek 98e299
From 0f91582182f1680e979ff5b6e0d7c48a19917abc Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Thu, 29 Jun 2023 14:42:41 +0200
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Mark private symbols as hidden
Tomas Bzatek 98e299
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-private.h | 3 +++
Tomas Bzatek 98e299
 1 file changed, 3 insertions(+)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-private.h b/src/plugins/nvme/nvme-private.h
Tomas Bzatek 98e299
index 3d4b2a996..8b6d13253 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-private.h
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-private.h
Tomas Bzatek 98e299
@@ -16,10 +16,13 @@
Tomas Bzatek 98e299
 #define _C_LOCALE (locale_t) 0
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 /* nvme-error.c */
Tomas Bzatek 98e299
+G_GNUC_INTERNAL
Tomas Bzatek 98e299
 void _nvme_status_to_error (gint status, gboolean fabrics, GError **error);
Tomas Bzatek 98e299
+G_GNUC_INTERNAL
Tomas Bzatek 98e299
 void _nvme_fabrics_errno_to_gerror (int result, int _errno, GError **error);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 /* nvme-info.c */
Tomas Bzatek 98e299
+G_GNUC_INTERNAL
Tomas Bzatek 98e299
 gint _open_dev (const gchar *device, GError **error);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 #endif  /* BD_NVME_PRIVATE */
Tomas Bzatek 98e299
From ddfb806da578541c7a5a0947e29b81e33f594b11 Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Tue, 8 Aug 2023 16:51:26 +0200
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Use interim buffer for nvme_get_log_sanitize()
Tomas Bzatek 98e299
Tomas Bzatek 98e299
Certain drives tend to return more data than expected resulting
Tomas Bzatek 98e299
in stack corruption. Use an interim buffer large enough to handle
Tomas Bzatek 98e299
the excess bytes.
Tomas Bzatek 98e299
Tomas Bzatek 98e299
https://github.com/storaged-project/udisks/issues/1152
Tomas Bzatek 98e299
https://github.com/linux-nvme/libnvme/issues/684
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-info.c | 25 +++++++++++++++----------
Tomas Bzatek 98e299
 1 file changed, 15 insertions(+), 10 deletions(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-info.c b/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
index bbc7de4f2..2a3d87cff 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
@@ -1026,7 +1026,8 @@ BDNVMESelfTestLog * bd_nvme_get_self_test_log (const gchar *device, GError **err
Tomas Bzatek 98e299
 BDNVMESanitizeLog * bd_nvme_get_sanitize_log (const gchar *device, GError **error) {
Tomas Bzatek 98e299
     int ret;
Tomas Bzatek 98e299
     int fd;
Tomas Bzatek 98e299
-    struct nvme_sanitize_log_page sanitize_log = ZERO_INIT;
Tomas Bzatek 98e299
+    char buf[65536] = ZERO_INIT;
Tomas Bzatek 98e299
+    struct nvme_sanitize_log_page *sanitize_log;
Tomas Bzatek 98e299
     BDNVMESanitizeLog *log;
Tomas Bzatek 98e299
     __u16 sstat;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -1036,7 +1037,7 @@ BDNVMESanitizeLog * bd_nvme_get_sanitize_log (const gchar *device, GError **erro
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* send the NVME_LOG_LID_SANITIZE ioctl */
Tomas Bzatek 98e299
-    ret = nvme_get_log_sanitize (fd, FALSE /* rae */, &sanitize_log);
Tomas Bzatek 98e299
+    ret = nvme_get_log_sanitize (fd, FALSE /* rae */, (struct nvme_sanitize_log_page *) &buf;;
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Get Log Page - Sanitize Status Log command error: ");
Tomas Bzatek 98e299
@@ -1045,12 +1046,16 @@ BDNVMESanitizeLog * bd_nvme_get_sanitize_log (const gchar *device, GError **erro
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     close (fd);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    sstat = GUINT16_FROM_LE (sanitize_log.sstat);
Tomas Bzatek 98e299
+    /* need to use interim buffer that is large enough for broken drives
Tomas Bzatek 98e299
+     * returning more data than expected
Tomas Bzatek 98e299
+     */
Tomas Bzatek 98e299
+    sanitize_log = (struct nvme_sanitize_log_page *) &buf;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     log = g_new0 (BDNVMESanitizeLog, 1);
Tomas Bzatek 98e299
     log->sanitize_progress = 0;
Tomas Bzatek 98e299
+    sstat = GUINT16_FROM_LE (sanitize_log->sstat);
Tomas Bzatek 98e299
     if ((sstat & NVME_SANITIZE_SSTAT_STATUS_MASK) == NVME_SANITIZE_SSTAT_STATUS_IN_PROGESS)
Tomas Bzatek 98e299
-        log->sanitize_progress = ((gdouble) GUINT16_FROM_LE (sanitize_log.sprog) * 100) / 0x10000;
Tomas Bzatek 98e299
+        log->sanitize_progress = ((gdouble) GUINT16_FROM_LE (sanitize_log->sprog) * 100) / 0x10000;
Tomas Bzatek 98e299
     log->global_data_erased = sstat & NVME_SANITIZE_SSTAT_GLOBAL_DATA_ERASED;
Tomas Bzatek 98e299
     log->overwrite_passes = (sstat >> NVME_SANITIZE_SSTAT_COMPLETED_PASSES_SHIFT) & NVME_SANITIZE_SSTAT_COMPLETED_PASSES_MASK;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -1073,12 +1078,12 @@ BDNVMESanitizeLog * bd_nvme_get_sanitize_log (const gchar *device, GError **erro
Tomas Bzatek 98e299
             break;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    log->time_for_overwrite = (GUINT32_FROM_LE (sanitize_log.eto) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log.eto);
Tomas Bzatek 98e299
-    log->time_for_block_erase = (GUINT32_FROM_LE (sanitize_log.etbe) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log.etbe);
Tomas Bzatek 98e299
-    log->time_for_crypto_erase = (GUINT32_FROM_LE (sanitize_log.etce) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log.etce);
Tomas Bzatek 98e299
-    log->time_for_overwrite_nd = (GUINT32_FROM_LE (sanitize_log.etond) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log.etond);
Tomas Bzatek 98e299
-    log->time_for_block_erase_nd = (GUINT32_FROM_LE (sanitize_log.etbend) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log.etbend);
Tomas Bzatek 98e299
-    log->time_for_crypto_erase_nd = (GUINT32_FROM_LE (sanitize_log.etcend) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log.etcend);
Tomas Bzatek 98e299
+    log->time_for_overwrite = (GUINT32_FROM_LE (sanitize_log->eto) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log->eto);
Tomas Bzatek 98e299
+    log->time_for_block_erase = (GUINT32_FROM_LE (sanitize_log->etbe) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log->etbe);
Tomas Bzatek 98e299
+    log->time_for_crypto_erase = (GUINT32_FROM_LE (sanitize_log->etce) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log->etce);
Tomas Bzatek 98e299
+    log->time_for_overwrite_nd = (GUINT32_FROM_LE (sanitize_log->etond) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log->etond);
Tomas Bzatek 98e299
+    log->time_for_block_erase_nd = (GUINT32_FROM_LE (sanitize_log->etbend) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log->etbend);
Tomas Bzatek 98e299
+    log->time_for_crypto_erase_nd = (GUINT32_FROM_LE (sanitize_log->etcend) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log->etcend);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     return log;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
From c9c3740e20dc891bddb3cfea79e589ad2bf4419f Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Wed, 16 Aug 2023 16:03:11 +0200
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Generate HostID when missing
Tomas Bzatek 98e299
Tomas Bzatek 98e299
Newer kernels tend to refuse connection when no HostID is supplied.
Tomas Bzatek 98e299
Even non-matching UUIDs within HostNQN/HostID seems to be working
Tomas Bzatek 98e299
fine with kernel 6.5-rc6.
Tomas Bzatek 98e299
Tomas Bzatek 98e299
This should bring us closer to the new HostNQN <--> HostID
Tomas Bzatek 98e299
mapping validation introduced in kernel-6.5.
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-fabrics.c | 41 +++++++++++++++++++++++++--------
Tomas Bzatek 98e299
 1 file changed, 32 insertions(+), 9 deletions(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-fabrics.c b/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
index c79d9e6de..1877845f2 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-fabrics.c
Tomas Bzatek 98e299
@@ -161,7 +161,7 @@ static void parse_extra_args (const BDExtraArg **extra, struct nvme_fabrics_conf
Tomas Bzatek 98e299
  * @host_iface: (nullable): The network interface used on the host to connect to the Controller (e.g. IP `eth1`, `enp2s0`). This forces the connection to be made on a specific interface instead of letting the system decide.
Tomas Bzatek 98e299
  * @host_nqn: (nullable): Overrides the default Host NQN that identifies the NVMe Host. If this option is %NULL, the default is read from `/etc/nvme/hostnqn` first.
Tomas Bzatek 98e299
  *                        If that does not exist, the autogenerated NQN value from the NVMe Host kernel module is used next. The Host NQN uniquely identifies the NVMe Host.
Tomas Bzatek 98e299
- * @host_id: (nullable): User-defined host UUID or %NULL to use default (as defined in `/etc/nvme/hostid`)
Tomas Bzatek 98e299
+ * @host_id: (nullable): User-defined host UUID or %NULL to use default (as defined in `/etc/nvme/hostid`).
Tomas Bzatek 98e299
  * @extra: (nullable) (array zero-terminated=1): Additional arguments.
Tomas Bzatek 98e299
  * @error: (out) (nullable): Place to store error (if any).
Tomas Bzatek 98e299
  *
Tomas Bzatek 98e299
@@ -244,18 +244,41 @@ gboolean bd_nvme_connect (const gchar *subsysnqn, const gchar *transport, const
Tomas Bzatek 98e299
         return FALSE;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    /* parse extra arguments */
Tomas Bzatek 98e299
-    nvmf_default_config (&cfg;;
Tomas Bzatek 98e299
-    parse_extra_args (extra, &cfg, &config_file, &hostkey, &ctrlkey, &hostsymname);
Tomas Bzatek 98e299
-
Tomas Bzatek 98e299
+    /* HostNQN checks */
Tomas Bzatek 98e299
     host_nqn_val = g_strdup (host_nqn);
Tomas Bzatek 98e299
+    host_id_val = g_strdup (host_id);
Tomas Bzatek 98e299
     if (host_nqn_val == NULL)
Tomas Bzatek 98e299
         host_nqn_val = nvmf_hostnqn_from_file ();
Tomas Bzatek 98e299
-    if (host_nqn_val == NULL)
Tomas Bzatek 98e299
-        host_nqn_val = nvmf_hostnqn_generate ();
Tomas Bzatek 98e299
-    host_id_val = g_strdup (host_id);
Tomas Bzatek 98e299
     if (host_id_val == NULL)
Tomas Bzatek 98e299
         host_id_val = nvmf_hostid_from_file ();
Tomas Bzatek 98e299
+    if (host_nqn_val == NULL)
Tomas Bzatek 98e299
+        host_nqn_val = nvmf_hostnqn_generate ();
Tomas Bzatek 98e299
+    if (host_nqn_val == NULL) {
Tomas Bzatek 98e299
+        g_set_error_literal (error, BD_NVME_ERROR, BD_NVME_ERROR_INVALID_ARGUMENT,
Tomas Bzatek 98e299
+                             "Could not determine HostNQN");
Tomas Bzatek 98e299
+        g_free (host_nqn_val);
Tomas Bzatek 98e299
+        g_free (host_id_val);
Tomas Bzatek 98e299
+        return FALSE;
Tomas Bzatek 98e299
+    }
Tomas Bzatek 98e299
+    if (host_id_val == NULL) {
Tomas Bzatek 98e299
+        /* derive hostid from hostnqn, newer kernels refuse empty hostid */
Tomas Bzatek 98e299
+        host_id_val = g_strrstr (host_nqn_val, "uuid:");
Tomas Bzatek 98e299
+        if (host_id_val)
Tomas Bzatek 98e299
+            host_id_val = g_strdup (host_id_val + strlen ("uuid:"));
Tomas Bzatek 98e299
+        /* TODO: in theory generating arbitrary uuid might work as a fallback */
Tomas Bzatek 98e299
+    }
Tomas Bzatek 98e299
+    if (host_id_val == NULL) {
Tomas Bzatek 98e299
+        g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_INVALID_ARGUMENT,
Tomas Bzatek 98e299
+                     "Could not determine HostID value from HostNQN '%s'",
Tomas Bzatek 98e299
+                     host_nqn_val);
Tomas Bzatek 98e299
+        g_free (host_nqn_val);
Tomas Bzatek 98e299
+        g_free (host_id_val);
Tomas Bzatek 98e299
+        return FALSE;
Tomas Bzatek 98e299
+    }
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+    /* parse extra arguments */
Tomas Bzatek 98e299
+    nvmf_default_config (&cfg;;
Tomas Bzatek 98e299
+    parse_extra_args (extra, &cfg, &config_file, &hostkey, &ctrlkey, &hostsymname);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     root = nvme_scan (config_file);
Tomas Bzatek 98e299
     g_assert (root != NULL);
Tomas Bzatek 98e299
@@ -263,7 +286,7 @@ gboolean bd_nvme_connect (const gchar *subsysnqn, const gchar *transport, const
Tomas Bzatek 98e299
     host = nvme_lookup_host (root, host_nqn_val, host_id_val);
Tomas Bzatek 98e299
     if (host == NULL) {
Tomas Bzatek 98e299
         g_set_error (error, BD_NVME_ERROR, BD_NVME_ERROR_FAILED,
Tomas Bzatek 98e299
-                     "Unable to lookup host for nqn '%s' and id '%s'",
Tomas Bzatek 98e299
+                     "Unable to lookup host for HostNQN '%s' and HostID '%s'",
Tomas Bzatek 98e299
                      host_nqn_val, host_id_val);
Tomas Bzatek 98e299
         g_free (host_nqn_val);
Tomas Bzatek 98e299
         g_free (host_id_val);
Tomas Bzatek 98e299
From 2ae0d949eb87142b0212e5953a0e5ad1a146ed6b Mon Sep 17 00:00:00 2001
Tomas Bzatek 98e299
From: Tomas Bzatek <tbzatek@redhat.com>
Tomas Bzatek 98e299
Date: Thu, 5 Oct 2023 17:27:57 +0200
Tomas Bzatek 98e299
Subject: [PATCH] nvme: Rework memory allocation for device ioctls
Tomas Bzatek 98e299
Tomas Bzatek 98e299
Make sure to provide pagesize-aligned and large enough buffer
Tomas Bzatek 98e299
for ioctls that may involve DMA buffer mapping.
Tomas Bzatek 98e299
---
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-info.c    | 311 +++++++++++++++++++-------------
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-op.c      |  30 ++-
Tomas Bzatek 98e299
 src/plugins/nvme/nvme-private.h |   2 +
Tomas Bzatek 98e299
 3 files changed, 204 insertions(+), 139 deletions(-)
Tomas Bzatek 98e299
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-info.c b/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
index 2a3d87cff..eaf77473c 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-info.c
Tomas Bzatek 98e299
@@ -402,6 +402,21 @@ gint _open_dev (const gchar *device, GError **error) {
Tomas Bzatek 98e299
     return fd;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+/* backported from nvme-cli: https://github.com/linux-nvme/nvme-cli/pull/2051 */
Tomas Bzatek 98e299
+#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+void *_nvme_alloc (size_t len)
Tomas Bzatek 98e299
+{
Tomas Bzatek 98e299
+    size_t _len = ROUND_UP (len, 0x1000);
Tomas Bzatek 98e299
+    void *p;
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+    if (posix_memalign ((void *) &p, getpagesize (), _len))
Tomas Bzatek 98e299
+        return NULL;
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+    memset (p, 0, _len);
Tomas Bzatek 98e299
+    return p;
Tomas Bzatek 98e299
+}
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
 static gchar *decode_nvme_rev (guint32 ver) {
Tomas Bzatek 98e299
     guint16 mjr;
Tomas Bzatek 98e299
     guint8 mnr, ter = 0;
Tomas Bzatek 98e299
@@ -452,7 +467,7 @@ static gboolean _nvme_a_is_zero (const __u8 a[], int len) {
Tomas Bzatek 98e299
 BDNVMEControllerInfo * bd_nvme_get_controller_info (const gchar *device, GError **error) {
Tomas Bzatek 98e299
     int ret;
Tomas Bzatek 98e299
     int fd;
Tomas Bzatek 98e299
-    struct nvme_id_ctrl ctrl_id = ZERO_INIT;
Tomas Bzatek 98e299
+    struct nvme_id_ctrl *ctrl_id;
Tomas Bzatek 98e299
     BDNVMEControllerInfo *info;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* open the block device */
Tomas Bzatek 98e299
@@ -460,53 +475,56 @@ BDNVMEControllerInfo * bd_nvme_get_controller_info (const gchar *device, GError
Tomas Bzatek 98e299
     if (fd < 0)
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+    ctrl_id = _nvme_alloc (sizeof (struct nvme_id_ctrl));
Tomas Bzatek 98e299
+    g_warn_if_fail (ctrl_id != NULL);
Tomas Bzatek 98e299
     /* send the NVME_IDENTIFY_CNS_CTRL ioctl */
Tomas Bzatek 98e299
-    ret = nvme_identify_ctrl (fd, &ctrl_id);
Tomas Bzatek 98e299
+    ret = nvme_identify_ctrl (fd, ctrl_id);
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Identify Controller command error: ");
Tomas Bzatek 98e299
         close (fd);
Tomas Bzatek 98e299
+        free (ctrl_id);
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     close (fd);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     info = g_new0 (BDNVMEControllerInfo, 1);
Tomas Bzatek 98e299
-    if ((ctrl_id.cmic & NVME_CTRL_CMIC_MULTI_PORT) == NVME_CTRL_CMIC_MULTI_PORT)
Tomas Bzatek 98e299
+    if ((ctrl_id->cmic & NVME_CTRL_CMIC_MULTI_PORT) == NVME_CTRL_CMIC_MULTI_PORT)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_MULTIPORT;
Tomas Bzatek 98e299
-    if ((ctrl_id.cmic & NVME_CTRL_CMIC_MULTI_CTRL) == NVME_CTRL_CMIC_MULTI_CTRL)
Tomas Bzatek 98e299
+    if ((ctrl_id->cmic & NVME_CTRL_CMIC_MULTI_CTRL) == NVME_CTRL_CMIC_MULTI_CTRL)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_MULTICTRL;
Tomas Bzatek 98e299
-    if ((ctrl_id.cmic & NVME_CTRL_CMIC_MULTI_SRIOV) == NVME_CTRL_CMIC_MULTI_SRIOV)
Tomas Bzatek 98e299
+    if ((ctrl_id->cmic & NVME_CTRL_CMIC_MULTI_SRIOV) == NVME_CTRL_CMIC_MULTI_SRIOV)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_SRIOV;
Tomas Bzatek 98e299
-    if ((ctrl_id.cmic & NVME_CTRL_CMIC_MULTI_ANA_REPORTING) == NVME_CTRL_CMIC_MULTI_ANA_REPORTING)
Tomas Bzatek 98e299
+    if ((ctrl_id->cmic & NVME_CTRL_CMIC_MULTI_ANA_REPORTING) == NVME_CTRL_CMIC_MULTI_ANA_REPORTING)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_ANA_REPORTING;
Tomas Bzatek 98e299
-    if ((ctrl_id.nvmsr & NVME_CTRL_NVMSR_NVMESD) == NVME_CTRL_NVMSR_NVMESD)
Tomas Bzatek 98e299
+    if ((ctrl_id->nvmsr & NVME_CTRL_NVMSR_NVMESD) == NVME_CTRL_NVMSR_NVMESD)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_STORAGE_DEVICE;
Tomas Bzatek 98e299
-    if ((ctrl_id.nvmsr & NVME_CTRL_NVMSR_NVMEE) == NVME_CTRL_NVMSR_NVMEE)
Tomas Bzatek 98e299
+    if ((ctrl_id->nvmsr & NVME_CTRL_NVMSR_NVMEE) == NVME_CTRL_NVMSR_NVMEE)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_ENCLOSURE;
Tomas Bzatek 98e299
-    if ((ctrl_id.mec & NVME_CTRL_MEC_PCIEME) == NVME_CTRL_MEC_PCIEME)
Tomas Bzatek 98e299
+    if ((ctrl_id->mec & NVME_CTRL_MEC_PCIEME) == NVME_CTRL_MEC_PCIEME)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_MGMT_PCIE;
Tomas Bzatek 98e299
-    if ((ctrl_id.mec & NVME_CTRL_MEC_SMBUSME) == NVME_CTRL_MEC_SMBUSME)
Tomas Bzatek 98e299
+    if ((ctrl_id->mec & NVME_CTRL_MEC_SMBUSME) == NVME_CTRL_MEC_SMBUSME)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_MGMT_SMBUS;
Tomas Bzatek 98e299
-    info->pci_vendor_id = GUINT16_FROM_LE (ctrl_id.vid);
Tomas Bzatek 98e299
-    info->pci_subsys_vendor_id = GUINT16_FROM_LE (ctrl_id.ssvid);
Tomas Bzatek 98e299
-    info->ctrl_id = GUINT16_FROM_LE (ctrl_id.cntlid);
Tomas Bzatek 98e299
-    if (!_nvme_a_is_zero (ctrl_id.fguid, sizeof (ctrl_id.fguid)))
Tomas Bzatek 98e299
-        info->fguid = _uuid_to_str (ctrl_id.fguid);
Tomas Bzatek 98e299
-    info->model_number = g_strndup (ctrl_id.mn, sizeof (ctrl_id.mn));
Tomas Bzatek 98e299
+    info->pci_vendor_id = GUINT16_FROM_LE (ctrl_id->vid);
Tomas Bzatek 98e299
+    info->pci_subsys_vendor_id = GUINT16_FROM_LE (ctrl_id->ssvid);
Tomas Bzatek 98e299
+    info->ctrl_id = GUINT16_FROM_LE (ctrl_id->cntlid);
Tomas Bzatek 98e299
+    if (!_nvme_a_is_zero (ctrl_id->fguid, sizeof (ctrl_id->fguid)))
Tomas Bzatek 98e299
+        info->fguid = _uuid_to_str (ctrl_id->fguid);
Tomas Bzatek 98e299
+    info->model_number = g_strndup (ctrl_id->mn, sizeof (ctrl_id->mn));
Tomas Bzatek 98e299
     g_strstrip (info->model_number);
Tomas Bzatek 98e299
-    info->serial_number = g_strndup (ctrl_id.sn, sizeof (ctrl_id.sn));
Tomas Bzatek 98e299
+    info->serial_number = g_strndup (ctrl_id->sn, sizeof (ctrl_id->sn));
Tomas Bzatek 98e299
     g_strstrip (info->serial_number);
Tomas Bzatek 98e299
-    info->firmware_ver = g_strndup (ctrl_id.fr, sizeof (ctrl_id.fr));
Tomas Bzatek 98e299
+    info->firmware_ver = g_strndup (ctrl_id->fr, sizeof (ctrl_id->fr));
Tomas Bzatek 98e299
     g_strstrip (info->firmware_ver);
Tomas Bzatek 98e299
-    info->nvme_ver = decode_nvme_rev (GUINT32_FROM_LE (ctrl_id.ver));
Tomas Bzatek 98e299
+    info->nvme_ver = decode_nvme_rev (GUINT32_FROM_LE (ctrl_id->ver));
Tomas Bzatek 98e299
     /* TODO: vwci: VPD Write Cycle Information */
Tomas Bzatek 98e299
-    if ((ctrl_id.oacs & NVME_CTRL_OACS_FORMAT) == NVME_CTRL_OACS_FORMAT)
Tomas Bzatek 98e299
+    if ((ctrl_id->oacs & NVME_CTRL_OACS_FORMAT) == NVME_CTRL_OACS_FORMAT)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_FORMAT;
Tomas Bzatek 98e299
-    if ((ctrl_id.oacs & NVME_CTRL_OACS_NS_MGMT) == NVME_CTRL_OACS_NS_MGMT)
Tomas Bzatek 98e299
+    if ((ctrl_id->oacs & NVME_CTRL_OACS_NS_MGMT) == NVME_CTRL_OACS_NS_MGMT)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_NS_MGMT;
Tomas Bzatek 98e299
-    if ((ctrl_id.oacs & NVME_CTRL_OACS_SELF_TEST) == NVME_CTRL_OACS_SELF_TEST)
Tomas Bzatek 98e299
+    if ((ctrl_id->oacs & NVME_CTRL_OACS_SELF_TEST) == NVME_CTRL_OACS_SELF_TEST)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_SELFTEST;
Tomas Bzatek 98e299
-    switch (ctrl_id.cntrltype) {
Tomas Bzatek 98e299
+    switch (ctrl_id->cntrltype) {
Tomas Bzatek 98e299
         case NVME_CTRL_CNTRLTYPE_IO:
Tomas Bzatek 98e299
             info->controller_type = BD_NVME_CTRL_TYPE_IO;
Tomas Bzatek 98e299
             break;
Tomas Bzatek 98e299
@@ -519,36 +537,37 @@ BDNVMEControllerInfo * bd_nvme_get_controller_info (const gchar *device, GError
Tomas Bzatek 98e299
         default:
Tomas Bzatek 98e299
             info->controller_type = BD_NVME_CTRL_TYPE_UNKNOWN;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
-    info->hmb_pref_size = GUINT32_FROM_LE (ctrl_id.hmpre) * 4096LL;
Tomas Bzatek 98e299
-    info->hmb_min_size = GUINT32_FROM_LE (ctrl_id.hmmin) * 4096LL;
Tomas Bzatek 98e299
-    info->size_total = int128_to_guint64 (ctrl_id.tnvmcap);
Tomas Bzatek 98e299
-    info->size_unalloc = int128_to_guint64 (ctrl_id.unvmcap);
Tomas Bzatek 98e299
-    info->selftest_ext_time = GUINT16_FROM_LE (ctrl_id.edstt);
Tomas Bzatek 98e299
+    info->hmb_pref_size = GUINT32_FROM_LE (ctrl_id->hmpre) * 4096LL;
Tomas Bzatek 98e299
+    info->hmb_min_size = GUINT32_FROM_LE (ctrl_id->hmmin) * 4096LL;
Tomas Bzatek 98e299
+    info->size_total = int128_to_guint64 (ctrl_id->tnvmcap);
Tomas Bzatek 98e299
+    info->size_unalloc = int128_to_guint64 (ctrl_id->unvmcap);
Tomas Bzatek 98e299
+    info->selftest_ext_time = GUINT16_FROM_LE (ctrl_id->edstt);
Tomas Bzatek 98e299
     /* TODO: lpa: Log Page Attributes - NVME_CTRL_LPA_PERSETENT_EVENT: Persistent Event log */
Tomas Bzatek 98e299
-    if ((ctrl_id.dsto & NVME_CTRL_DSTO_ONE_DST) == NVME_CTRL_DSTO_ONE_DST)
Tomas Bzatek 98e299
+    if ((ctrl_id->dsto & NVME_CTRL_DSTO_ONE_DST) == NVME_CTRL_DSTO_ONE_DST)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_SELFTEST_SINGLE;
Tomas Bzatek 98e299
-    if ((ctrl_id.sanicap & NVME_CTRL_SANICAP_CES) == NVME_CTRL_SANICAP_CES)
Tomas Bzatek 98e299
+    if ((ctrl_id->sanicap & NVME_CTRL_SANICAP_CES) == NVME_CTRL_SANICAP_CES)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_SANITIZE_CRYPTO;
Tomas Bzatek 98e299
-    if ((ctrl_id.sanicap & NVME_CTRL_SANICAP_BES) == NVME_CTRL_SANICAP_BES)
Tomas Bzatek 98e299
+    if ((ctrl_id->sanicap & NVME_CTRL_SANICAP_BES) == NVME_CTRL_SANICAP_BES)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_SANITIZE_BLOCK;
Tomas Bzatek 98e299
-    if ((ctrl_id.sanicap & NVME_CTRL_SANICAP_OWS) == NVME_CTRL_SANICAP_OWS)
Tomas Bzatek 98e299
+    if ((ctrl_id->sanicap & NVME_CTRL_SANICAP_OWS) == NVME_CTRL_SANICAP_OWS)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_SANITIZE_OVERWRITE;
Tomas Bzatek 98e299
     /* struct nvme_id_ctrl.nn: If the &struct nvme_id_ctrl.mnan field is cleared to 0h,
Tomas Bzatek 98e299
      * then the struct nvme_id_ctrl.nn field also indicates the maximum number of namespaces
Tomas Bzatek 98e299
      * supported by the NVM subsystem.
Tomas Bzatek 98e299
      */
Tomas Bzatek 98e299
-    info->num_namespaces = GUINT32_FROM_LE (ctrl_id.mnan) == 0 ? GUINT32_FROM_LE (ctrl_id.nn) : GUINT32_FROM_LE (ctrl_id.mnan);
Tomas Bzatek 98e299
-    if ((ctrl_id.fna & NVME_CTRL_FNA_FMT_ALL_NAMESPACES) == NVME_CTRL_FNA_FMT_ALL_NAMESPACES)
Tomas Bzatek 98e299
+    info->num_namespaces = GUINT32_FROM_LE (ctrl_id->mnan) == 0 ? GUINT32_FROM_LE (ctrl_id->nn) : GUINT32_FROM_LE (ctrl_id->mnan);
Tomas Bzatek 98e299
+    if ((ctrl_id->fna & NVME_CTRL_FNA_FMT_ALL_NAMESPACES) == NVME_CTRL_FNA_FMT_ALL_NAMESPACES)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_FORMAT_ALL_NS;
Tomas Bzatek 98e299
-    if ((ctrl_id.fna & NVME_CTRL_FNA_SEC_ALL_NAMESPACES) == NVME_CTRL_FNA_SEC_ALL_NAMESPACES)
Tomas Bzatek 98e299
+    if ((ctrl_id->fna & NVME_CTRL_FNA_SEC_ALL_NAMESPACES) == NVME_CTRL_FNA_SEC_ALL_NAMESPACES)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_SECURE_ERASE_ALL_NS;
Tomas Bzatek 98e299
-    if ((ctrl_id.fna & NVME_CTRL_FNA_CRYPTO_ERASE) == NVME_CTRL_FNA_CRYPTO_ERASE)
Tomas Bzatek 98e299
+    if ((ctrl_id->fna & NVME_CTRL_FNA_CRYPTO_ERASE) == NVME_CTRL_FNA_CRYPTO_ERASE)
Tomas Bzatek 98e299
         info->features |= BD_NVME_CTRL_FEAT_SECURE_ERASE_CRYPTO;
Tomas Bzatek 98e299
     /* TODO: enum nvme_id_ctrl_oncs: NVME_CTRL_ONCS_WRITE_UNCORRECTABLE, NVME_CTRL_ONCS_WRITE_ZEROES... */
Tomas Bzatek 98e299
     /* TODO: nwpc: Namespace Write Protection Capabilities */
Tomas Bzatek 98e299
-    info->subsysnqn = g_strndup (ctrl_id.subnqn, sizeof (ctrl_id.subnqn));
Tomas Bzatek 98e299
+    info->subsysnqn = g_strndup (ctrl_id->subnqn, sizeof (ctrl_id->subnqn));
Tomas Bzatek 98e299
     g_strstrip (info->subsysnqn);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+    free (ctrl_id);
Tomas Bzatek 98e299
     return info;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -572,10 +591,10 @@ BDNVMENamespaceInfo *bd_nvme_get_namespace_info (const gchar *device, GError **e
Tomas Bzatek 98e299
     int ret_ns_ind = -1;
Tomas Bzatek 98e299
     int fd;
Tomas Bzatek 98e299
     __u32 nsid = 0;
Tomas Bzatek 98e299
-    struct nvme_id_ctrl ctrl_id = ZERO_INIT;
Tomas Bzatek 98e299
-    struct nvme_id_ns ns_info = ZERO_INIT;
Tomas Bzatek 98e299
-    struct nvme_id_independent_id_ns ns_info_ind = ZERO_INIT;
Tomas Bzatek 98e299
-    uint8_t desc[NVME_IDENTIFY_DATA_SIZE] = ZERO_INIT;
Tomas Bzatek 98e299
+    struct nvme_id_ctrl *ctrl_id;
Tomas Bzatek 98e299
+    struct nvme_id_ns *ns_info;
Tomas Bzatek 98e299
+    struct nvme_id_independent_id_ns *ns_info_ind = NULL;
Tomas Bzatek 98e299
+    struct nvme_ns_id_desc *descs = NULL;
Tomas Bzatek 98e299
     guint8 flbas;
Tomas Bzatek 98e299
     guint i;
Tomas Bzatek 98e299
     guint len;
Tomas Bzatek 98e299
@@ -597,44 +616,55 @@ BDNVMENamespaceInfo *bd_nvme_get_namespace_info (const gchar *device, GError **e
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* send the NVME_IDENTIFY_CNS_NS ioctl */
Tomas Bzatek 98e299
-    ret = nvme_identify_ns (fd, nsid, &ns_info);
Tomas Bzatek 98e299
+    ns_info = _nvme_alloc (sizeof (struct nvme_id_ns));
Tomas Bzatek 98e299
+    g_warn_if_fail (ns_info != NULL);
Tomas Bzatek 98e299
+    ret = nvme_identify_ns (fd, nsid, ns_info);
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Identify Namespace command error: ");
Tomas Bzatek 98e299
         close (fd);
Tomas Bzatek 98e299
+        free (ns_info);
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* send the NVME_IDENTIFY_CNS_CTRL ioctl */
Tomas Bzatek 98e299
-    ret_ctrl = nvme_identify_ctrl (fd, &ctrl_id);
Tomas Bzatek 98e299
+    ctrl_id = _nvme_alloc (sizeof (struct nvme_id_ctrl));
Tomas Bzatek 98e299
+    g_warn_if_fail (ctrl_id != NULL);
Tomas Bzatek 98e299
+    ret_ctrl = nvme_identify_ctrl (fd, ctrl_id);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* send the NVME_IDENTIFY_CNS_NS_DESC_LIST ioctl, NVMe 1.3 */
Tomas Bzatek 98e299
-    if (ret_ctrl == 0 && GUINT32_FROM_LE (ctrl_id.ver) >= 0x10300)
Tomas Bzatek 98e299
-        ret_desc = nvme_identify_ns_descs (fd, nsid, (struct nvme_ns_id_desc *) &desc);
Tomas Bzatek 98e299
+    if (ret_ctrl == 0 && GUINT32_FROM_LE (ctrl_id->ver) >= 0x10300) {
Tomas Bzatek 98e299
+        descs = _nvme_alloc (NVME_IDENTIFY_DATA_SIZE);
Tomas Bzatek 98e299
+        g_warn_if_fail (descs != NULL);
Tomas Bzatek 98e299
+        ret_desc = nvme_identify_ns_descs (fd, nsid, descs);
Tomas Bzatek 98e299
+    }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* send the NVME_IDENTIFY_CNS_CSI_INDEPENDENT_ID_NS ioctl, NVMe 2.0 */
Tomas Bzatek 98e299
-    if (ret_ctrl == 0 && GUINT32_FROM_LE (ctrl_id.ver) >= 0x20000)
Tomas Bzatek 98e299
-        ret_ns_ind = nvme_identify_independent_identify_ns (fd, nsid, &ns_info_ind);
Tomas Bzatek 98e299
+    if (ret_ctrl == 0 && GUINT32_FROM_LE (ctrl_id->ver) >= 0x20000) {
Tomas Bzatek 98e299
+        ns_info_ind = _nvme_alloc (sizeof (struct nvme_id_independent_id_ns));
Tomas Bzatek 98e299
+        g_warn_if_fail (ns_info_ind != NULL);
Tomas Bzatek 98e299
+        ret_ns_ind = nvme_identify_independent_identify_ns (fd, nsid, ns_info_ind);
Tomas Bzatek 98e299
+    }
Tomas Bzatek 98e299
     close (fd);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     info = g_new0 (BDNVMENamespaceInfo, 1);
Tomas Bzatek 98e299
     info->nsid = nsid;
Tomas Bzatek 98e299
-    info->nsize = GUINT64_FROM_LE (ns_info.nsze);
Tomas Bzatek 98e299
-    info->ncap = GUINT64_FROM_LE (ns_info.ncap);
Tomas Bzatek 98e299
-    info->nuse = GUINT64_FROM_LE (ns_info.nuse);
Tomas Bzatek 98e299
-    if ((ns_info.nsfeat & NVME_NS_FEAT_THIN) == NVME_NS_FEAT_THIN)
Tomas Bzatek 98e299
+    info->nsize = GUINT64_FROM_LE (ns_info->nsze);
Tomas Bzatek 98e299
+    info->ncap = GUINT64_FROM_LE (ns_info->ncap);
Tomas Bzatek 98e299
+    info->nuse = GUINT64_FROM_LE (ns_info->nuse);
Tomas Bzatek 98e299
+    if ((ns_info->nsfeat & NVME_NS_FEAT_THIN) == NVME_NS_FEAT_THIN)
Tomas Bzatek 98e299
         info->features |= BD_NVME_NS_FEAT_THIN;
Tomas Bzatek 98e299
-    if ((ns_info.nmic & NVME_NS_NMIC_SHARED) == NVME_NS_NMIC_SHARED)
Tomas Bzatek 98e299
+    if ((ns_info->nmic & NVME_NS_NMIC_SHARED) == NVME_NS_NMIC_SHARED)
Tomas Bzatek 98e299
         info->features |= BD_NVME_NS_FEAT_MULTIPATH_SHARED;
Tomas Bzatek 98e299
-    if ((ns_info.fpi & NVME_NS_FPI_SUPPORTED) == NVME_NS_FPI_SUPPORTED)
Tomas Bzatek 98e299
+    if ((ns_info->fpi & NVME_NS_FPI_SUPPORTED) == NVME_NS_FPI_SUPPORTED)
Tomas Bzatek 98e299
         info->features |= BD_NVME_NS_FEAT_FORMAT_PROGRESS;
Tomas Bzatek 98e299
-    info->format_progress_remaining = ns_info.fpi & NVME_NS_FPI_REMAINING;
Tomas Bzatek 98e299
-    /* TODO: what the ns_info.nvmcap really stands for? */
Tomas Bzatek 98e299
-    info->write_protected = (ns_info.nsattr & NVME_NS_NSATTR_WRITE_PROTECTED) == NVME_NS_NSATTR_WRITE_PROTECTED;
Tomas Bzatek 98e299
+    info->format_progress_remaining = ns_info->fpi & NVME_NS_FPI_REMAINING;
Tomas Bzatek 98e299
+    /* TODO: what the ns_info->nvmcap really stands for? */
Tomas Bzatek 98e299
+    info->write_protected = (ns_info->nsattr & NVME_NS_NSATTR_WRITE_PROTECTED) == NVME_NS_NSATTR_WRITE_PROTECTED;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     if (ret_desc == 0) {
Tomas Bzatek 98e299
         for (i = 0; i < NVME_IDENTIFY_DATA_SIZE; i += len) {
Tomas Bzatek 98e299
-            struct nvme_ns_id_desc *d = (void *) desc + i;
Tomas Bzatek 98e299
+            struct nvme_ns_id_desc *d = descs + i;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
             if (!d->nidl)
Tomas Bzatek 98e299
                 break;
Tomas Bzatek 98e299
@@ -661,29 +691,29 @@ BDNVMENamespaceInfo *bd_nvme_get_namespace_info (const gchar *device, GError **e
Tomas Bzatek 98e299
         }
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    if (info->nguid == NULL && !_nvme_a_is_zero (ns_info.nguid, sizeof (ns_info.nguid))) {
Tomas Bzatek 98e299
-        info->nguid = g_malloc0 (sizeof (ns_info.nguid) * 2 + 1);
Tomas Bzatek 98e299
-        for (i = 0; i < sizeof (ns_info.nguid); i++)
Tomas Bzatek 98e299
-            snprintf (info->nguid + i * 2, 3, "%02x", ns_info.nguid[i]);
Tomas Bzatek 98e299
+    if (info->nguid == NULL && !_nvme_a_is_zero (ns_info->nguid, sizeof (ns_info->nguid))) {
Tomas Bzatek 98e299
+        info->nguid = g_malloc0 (sizeof (ns_info->nguid) * 2 + 1);
Tomas Bzatek 98e299
+        for (i = 0; i < sizeof (ns_info->nguid); i++)
Tomas Bzatek 98e299
+            snprintf (info->nguid + i * 2, 3, "%02x", ns_info->nguid[i]);
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
-    if (info->eui64 == NULL && !_nvme_a_is_zero (ns_info.eui64, sizeof (ns_info.eui64))) {
Tomas Bzatek 98e299
-        info->eui64 = g_malloc0 (sizeof (ns_info.eui64) * 2 + 1);
Tomas Bzatek 98e299
-        for (i = 0; i < sizeof (ns_info.eui64); i++)
Tomas Bzatek 98e299
-            snprintf (info->eui64 + i * 2, 3, "%02x", ns_info.eui64[i]);
Tomas Bzatek 98e299
+    if (info->eui64 == NULL && !_nvme_a_is_zero (ns_info->eui64, sizeof (ns_info->eui64))) {
Tomas Bzatek 98e299
+        info->eui64 = g_malloc0 (sizeof (ns_info->eui64) * 2 + 1);
Tomas Bzatek 98e299
+        for (i = 0; i < sizeof (ns_info->eui64); i++)
Tomas Bzatek 98e299
+            snprintf (info->eui64 + i * 2, 3, "%02x", ns_info->eui64[i]);
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     if (ret_ns_ind == 0) {
Tomas Bzatek 98e299
-        if ((ns_info_ind.nsfeat & 1 << 4) == 1 << 4)
Tomas Bzatek 98e299
+        if ((ns_info_ind->nsfeat & 1 << 4) == 1 << 4)
Tomas Bzatek 98e299
             info->features |= BD_NVME_NS_FEAT_ROTATIONAL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* translate the LBA Format array */
Tomas Bzatek 98e299
     ptr_array = g_ptr_array_new ();
Tomas Bzatek 98e299
-    nvme_id_ns_flbas_to_lbaf_inuse (ns_info.flbas, &flbas);
Tomas Bzatek 98e299
-    for (i = 0; i <= ns_info.nlbaf + ns_info.nulbaf; i++) {
Tomas Bzatek 98e299
+    nvme_id_ns_flbas_to_lbaf_inuse (ns_info->flbas, &flbas);
Tomas Bzatek 98e299
+    for (i = 0; i <= ns_info->nlbaf + ns_info->nulbaf; i++) {
Tomas Bzatek 98e299
         BDNVMELBAFormat *lbaf = g_new0 (BDNVMELBAFormat, 1);
Tomas Bzatek 98e299
-        lbaf->data_size = 1 << ns_info.lbaf[i].ds;
Tomas Bzatek 98e299
-        lbaf->metadata_size = GUINT16_FROM_LE (ns_info.lbaf[i].ms);
Tomas Bzatek 98e299
-        lbaf->relative_performance = ns_info.lbaf[i].rp + 1;
Tomas Bzatek 98e299
+        lbaf->data_size = 1 << ns_info->lbaf[i].ds;
Tomas Bzatek 98e299
+        lbaf->metadata_size = GUINT16_FROM_LE (ns_info->lbaf[i].ms);
Tomas Bzatek 98e299
+        lbaf->relative_performance = ns_info->lbaf[i].rp + 1;
Tomas Bzatek 98e299
         g_ptr_array_add (ptr_array, lbaf);
Tomas Bzatek 98e299
         if (i == flbas) {
Tomas Bzatek 98e299
             info->current_lba_format.data_size = lbaf->data_size;
Tomas Bzatek 98e299
@@ -694,6 +724,10 @@ BDNVMENamespaceInfo *bd_nvme_get_namespace_info (const gchar *device, GError **e
Tomas Bzatek 98e299
     g_ptr_array_add (ptr_array, NULL);  /* trailing NULL element */
Tomas Bzatek 98e299
     info->lba_formats = (BDNVMELBAFormat **) g_ptr_array_free (ptr_array, FALSE);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+    free (ctrl_id);
Tomas Bzatek 98e299
+    free (ns_info);
Tomas Bzatek 98e299
+    free (ns_info_ind);
Tomas Bzatek 98e299
+    free (descs);
Tomas Bzatek 98e299
     return info;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -714,8 +748,8 @@ BDNVMESmartLog * bd_nvme_get_smart_log (const gchar *device, GError **error) {
Tomas Bzatek 98e299
     int ret;
Tomas Bzatek 98e299
     int ret_identify;
Tomas Bzatek 98e299
     int fd;
Tomas Bzatek 98e299
-    struct nvme_id_ctrl ctrl_id = ZERO_INIT;
Tomas Bzatek 98e299
-    struct nvme_smart_log smart_log = ZERO_INIT;
Tomas Bzatek 98e299
+    struct nvme_id_ctrl *ctrl_id;
Tomas Bzatek 98e299
+    struct nvme_smart_log *smart_log;
Tomas Bzatek 98e299
     BDNVMESmartLog *log;
Tomas Bzatek 98e299
     guint i;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -724,59 +758,66 @@ BDNVMESmartLog * bd_nvme_get_smart_log (const gchar *device, GError **error) {
Tomas Bzatek 98e299
     if (fd < 0)
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    /* send the NVME_IDENTIFY_CNS_NS + NVME_IDENTIFY_CNS_CTRL ioctl */
Tomas Bzatek 98e299
-    ret_identify = nvme_identify_ctrl (fd, &ctrl_id);
Tomas Bzatek 98e299
+    /* send the NVME_IDENTIFY_CNS_CTRL ioctl */
Tomas Bzatek 98e299
+    ctrl_id = _nvme_alloc (sizeof (struct nvme_id_ctrl));
Tomas Bzatek 98e299
+    g_warn_if_fail (ctrl_id != NULL);
Tomas Bzatek 98e299
+    ret_identify = nvme_identify_ctrl (fd, ctrl_id);
Tomas Bzatek 98e299
     if (ret_identify != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret_identify, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Identify Controller command error: ");
Tomas Bzatek 98e299
         close (fd);
Tomas Bzatek 98e299
+        free (ctrl_id);
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* send the NVME_LOG_LID_SMART ioctl */
Tomas Bzatek 98e299
-    ret = nvme_get_log_smart (fd, NVME_NSID_ALL, FALSE /* rae */, &smart_log);
Tomas Bzatek 98e299
+    smart_log = _nvme_alloc (sizeof (struct nvme_smart_log));
Tomas Bzatek 98e299
+    g_warn_if_fail (smart_log != NULL);
Tomas Bzatek 98e299
+    ret = nvme_get_log_smart (fd, NVME_NSID_ALL, FALSE /* rae */, smart_log);
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Get Log Page - SMART / Health Information Log command error: ");
Tomas Bzatek 98e299
         close (fd);
Tomas Bzatek 98e299
+        free (ctrl_id);
Tomas Bzatek 98e299
+        free (smart_log);
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     close (fd);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     log = g_new0 (BDNVMESmartLog, 1);
Tomas Bzatek 98e299
-    if ((smart_log.critical_warning & NVME_SMART_CRIT_SPARE) == NVME_SMART_CRIT_SPARE)
Tomas Bzatek 98e299
+    if ((smart_log->critical_warning & NVME_SMART_CRIT_SPARE) == NVME_SMART_CRIT_SPARE)
Tomas Bzatek 98e299
         log->critical_warning |= BD_NVME_SMART_CRITICAL_WARNING_SPARE;
Tomas Bzatek 98e299
-    if ((smart_log.critical_warning & NVME_SMART_CRIT_TEMPERATURE) == NVME_SMART_CRIT_TEMPERATURE)
Tomas Bzatek 98e299
+    if ((smart_log->critical_warning & NVME_SMART_CRIT_TEMPERATURE) == NVME_SMART_CRIT_TEMPERATURE)
Tomas Bzatek 98e299
         log->critical_warning |= BD_NVME_SMART_CRITICAL_WARNING_TEMPERATURE;
Tomas Bzatek 98e299
-    if ((smart_log.critical_warning & NVME_SMART_CRIT_DEGRADED) == NVME_SMART_CRIT_DEGRADED)
Tomas Bzatek 98e299
+    if ((smart_log->critical_warning & NVME_SMART_CRIT_DEGRADED) == NVME_SMART_CRIT_DEGRADED)
Tomas Bzatek 98e299
         log->critical_warning |= BD_NVME_SMART_CRITICAL_WARNING_DEGRADED;
Tomas Bzatek 98e299
-    if ((smart_log.critical_warning & NVME_SMART_CRIT_MEDIA) == NVME_SMART_CRIT_MEDIA)
Tomas Bzatek 98e299
+    if ((smart_log->critical_warning & NVME_SMART_CRIT_MEDIA) == NVME_SMART_CRIT_MEDIA)
Tomas Bzatek 98e299
         log->critical_warning |= BD_NVME_SMART_CRITICAL_WARNING_READONLY;
Tomas Bzatek 98e299
-    if ((smart_log.critical_warning & NVME_SMART_CRIT_VOLATILE_MEMORY) == NVME_SMART_CRIT_VOLATILE_MEMORY)
Tomas Bzatek 98e299
+    if ((smart_log->critical_warning & NVME_SMART_CRIT_VOLATILE_MEMORY) == NVME_SMART_CRIT_VOLATILE_MEMORY)
Tomas Bzatek 98e299
         log->critical_warning |= BD_NVME_SMART_CRITICAL_WARNING_VOLATILE_MEM;
Tomas Bzatek 98e299
-    if ((smart_log.critical_warning & NVME_SMART_CRIT_PMR_RO) == NVME_SMART_CRIT_PMR_RO)
Tomas Bzatek 98e299
+    if ((smart_log->critical_warning & NVME_SMART_CRIT_PMR_RO) == NVME_SMART_CRIT_PMR_RO)
Tomas Bzatek 98e299
         log->critical_warning |= BD_NVME_SMART_CRITICAL_WARNING_PMR_READONLY;
Tomas Bzatek 98e299
-    log->avail_spare = smart_log.avail_spare;
Tomas Bzatek 98e299
-    log->spare_thresh = smart_log.spare_thresh;
Tomas Bzatek 98e299
-    log->percent_used = smart_log.percent_used;
Tomas Bzatek 98e299
-    log->total_data_read = int128_to_guint64 (smart_log.data_units_read) * 1000 * 512;
Tomas Bzatek 98e299
-    log->total_data_written = int128_to_guint64 (smart_log.data_units_written) * 1000 * 512;
Tomas Bzatek 98e299
-    log->ctrl_busy_time = int128_to_guint64 (smart_log.ctrl_busy_time);
Tomas Bzatek 98e299
-    log->power_cycles = int128_to_guint64 (smart_log.power_cycles);
Tomas Bzatek 98e299
-    log->power_on_hours = int128_to_guint64 (smart_log.power_on_hours);
Tomas Bzatek 98e299
-    log->unsafe_shutdowns = int128_to_guint64 (smart_log.unsafe_shutdowns);
Tomas Bzatek 98e299
-    log->media_errors = int128_to_guint64 (smart_log.media_errors);
Tomas Bzatek 98e299
-    log->num_err_log_entries = int128_to_guint64 (smart_log.num_err_log_entries);
Tomas Bzatek 98e299
-
Tomas Bzatek 98e299
-    log->temperature = (smart_log.temperature[1] << 8) | smart_log.temperature[0];
Tomas Bzatek 98e299
-    for (i = 0; i < G_N_ELEMENTS (smart_log.temp_sensor); i++)
Tomas Bzatek 98e299
-        log->temp_sensors[i] = GUINT16_FROM_LE (smart_log.temp_sensor[i]);
Tomas Bzatek 98e299
-    log->warning_temp_time = GUINT32_FROM_LE (smart_log.warning_temp_time);
Tomas Bzatek 98e299
-    log->critical_temp_time = GUINT32_FROM_LE (smart_log.critical_comp_time);
Tomas Bzatek 98e299
+    log->avail_spare = smart_log->avail_spare;
Tomas Bzatek 98e299
+    log->spare_thresh = smart_log->spare_thresh;
Tomas Bzatek 98e299
+    log->percent_used = smart_log->percent_used;
Tomas Bzatek 98e299
+    log->total_data_read = int128_to_guint64 (smart_log->data_units_read) * 1000 * 512;
Tomas Bzatek 98e299
+    log->total_data_written = int128_to_guint64 (smart_log->data_units_written) * 1000 * 512;
Tomas Bzatek 98e299
+    log->ctrl_busy_time = int128_to_guint64 (smart_log->ctrl_busy_time);
Tomas Bzatek 98e299
+    log->power_cycles = int128_to_guint64 (smart_log->power_cycles);
Tomas Bzatek 98e299
+    log->power_on_hours = int128_to_guint64 (smart_log->power_on_hours);
Tomas Bzatek 98e299
+    log->unsafe_shutdowns = int128_to_guint64 (smart_log->unsafe_shutdowns);
Tomas Bzatek 98e299
+    log->media_errors = int128_to_guint64 (smart_log->media_errors);
Tomas Bzatek 98e299
+    log->num_err_log_entries = int128_to_guint64 (smart_log->num_err_log_entries);
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
+    log->temperature = (smart_log->temperature[1] << 8) | smart_log->temperature[0];
Tomas Bzatek 98e299
+    for (i = 0; i < G_N_ELEMENTS (smart_log->temp_sensor); i++)
Tomas Bzatek 98e299
+        log->temp_sensors[i] = GUINT16_FROM_LE (smart_log->temp_sensor[i]);
Tomas Bzatek 98e299
+    log->warning_temp_time = GUINT32_FROM_LE (smart_log->warning_temp_time);
Tomas Bzatek 98e299
+    log->critical_temp_time = GUINT32_FROM_LE (smart_log->critical_comp_time);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     if (ret_identify == 0) {
Tomas Bzatek 98e299
-        log->wctemp = GUINT16_FROM_LE (ctrl_id.wctemp);
Tomas Bzatek 98e299
-        log->cctemp = GUINT16_FROM_LE (ctrl_id.cctemp);
Tomas Bzatek 98e299
+        log->wctemp = GUINT16_FROM_LE (ctrl_id->wctemp);
Tomas Bzatek 98e299
+        log->cctemp = GUINT16_FROM_LE (ctrl_id->cctemp);
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* FIXME: intentionally not providing Host Controlled Thermal Management attributes
Tomas Bzatek 98e299
@@ -784,6 +825,8 @@ BDNVMESmartLog * bd_nvme_get_smart_log (const gchar *device, GError **error) {
Tomas Bzatek 98e299
      *        Power State attributes. Subject to re-evaluation in the future.
Tomas Bzatek 98e299
      */
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+    free (ctrl_id);
Tomas Bzatek 98e299
+    free (smart_log);
Tomas Bzatek 98e299
     return log;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -810,7 +853,7 @@ BDNVMEErrorLogEntry ** bd_nvme_get_error_log_entries (const gchar *device, GErro
Tomas Bzatek 98e299
     int ret;
Tomas Bzatek 98e299
     int fd;
Tomas Bzatek 98e299
     guint elpe;
Tomas Bzatek 98e299
-    struct nvme_id_ctrl ctrl_id = ZERO_INIT;
Tomas Bzatek 98e299
+    struct nvme_id_ctrl *ctrl_id;
Tomas Bzatek 98e299
     struct nvme_error_log_page *err_log;
Tomas Bzatek 98e299
     GPtrArray *ptr_array;
Tomas Bzatek 98e299
     guint i;
Tomas Bzatek 98e299
@@ -821,23 +864,29 @@ BDNVMEErrorLogEntry ** bd_nvme_get_error_log_entries (const gchar *device, GErro
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* find out the maximum number of error log entries as reported by the controller */
Tomas Bzatek 98e299
-    ret = nvme_identify_ctrl (fd, &ctrl_id);
Tomas Bzatek 98e299
+    ctrl_id = _nvme_alloc (sizeof (struct nvme_id_ctrl));
Tomas Bzatek 98e299
+    g_warn_if_fail (ctrl_id != NULL);
Tomas Bzatek 98e299
+    ret = nvme_identify_ctrl (fd, ctrl_id);
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Identify Controller command error: ");
Tomas Bzatek 98e299
         close (fd);
Tomas Bzatek 98e299
+        free (ctrl_id);
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+    elpe = ctrl_id->elpe + 1;
Tomas Bzatek 98e299
+    free (ctrl_id);
Tomas Bzatek 98e299
+
Tomas Bzatek 98e299
     /* send the NVME_LOG_LID_ERROR ioctl */
Tomas Bzatek 98e299
-    elpe = ctrl_id.elpe + 1;
Tomas Bzatek 98e299
-    err_log = g_new0 (struct nvme_error_log_page, elpe);
Tomas Bzatek 98e299
+    err_log = _nvme_alloc (sizeof (struct nvme_error_log_page) * elpe);
Tomas Bzatek 98e299
+    g_warn_if_fail (err_log != NULL);
Tomas Bzatek 98e299
     ret = nvme_get_log_error (fd, elpe, FALSE /* rae */, err_log);
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Get Log Page - Error Information Log Entry command error: ");
Tomas Bzatek 98e299
-        g_free (err_log);
Tomas Bzatek 98e299
         close (fd);
Tomas Bzatek 98e299
+        free (err_log);
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     close (fd);
Tomas Bzatek 98e299
@@ -863,7 +912,7 @@ BDNVMEErrorLogEntry ** bd_nvme_get_error_log_entries (const gchar *device, GErro
Tomas Bzatek 98e299
         }
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     g_ptr_array_add (ptr_array, NULL);  /* trailing NULL element */
Tomas Bzatek 98e299
-    g_free (err_log);
Tomas Bzatek 98e299
+    free (err_log);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     return (BDNVMEErrorLogEntry **) g_ptr_array_free (ptr_array, FALSE);
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
@@ -885,7 +934,7 @@ BDNVMEErrorLogEntry ** bd_nvme_get_error_log_entries (const gchar *device, GErro
Tomas Bzatek 98e299
 BDNVMESelfTestLog * bd_nvme_get_self_test_log (const gchar *device, GError **error) {
Tomas Bzatek 98e299
     int ret;
Tomas Bzatek 98e299
     int fd;
Tomas Bzatek 98e299
-    struct nvme_self_test_log self_test_log = ZERO_INIT;
Tomas Bzatek 98e299
+    struct nvme_self_test_log *self_test_log;
Tomas Bzatek 98e299
     BDNVMESelfTestLog *log;
Tomas Bzatek 98e299
     GPtrArray *ptr_array;
Tomas Bzatek 98e299
     guint i;
Tomas Bzatek 98e299
@@ -896,17 +945,20 @@ BDNVMESelfTestLog * bd_nvme_get_self_test_log (const gchar *device, GError **err
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* send the NVME_LOG_LID_DEVICE_SELF_TEST ioctl */
Tomas Bzatek 98e299
-    ret = nvme_get_log_device_self_test (fd, &self_test_log);
Tomas Bzatek 98e299
+    self_test_log = _nvme_alloc (sizeof (struct nvme_self_test_log));
Tomas Bzatek 98e299
+    g_warn_if_fail (self_test_log != NULL);
Tomas Bzatek 98e299
+    ret = nvme_get_log_device_self_test (fd, self_test_log);
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Get Log Page - Device Self-test Log command error: ");
Tomas Bzatek 98e299
         close (fd);
Tomas Bzatek 98e299
+        free (self_test_log);
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     close (fd);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     log = g_new0 (BDNVMESelfTestLog, 1);
Tomas Bzatek 98e299
-    switch (self_test_log.current_operation & NVME_ST_CURR_OP_MASK) {
Tomas Bzatek 98e299
+    switch (self_test_log->current_operation & NVME_ST_CURR_OP_MASK) {
Tomas Bzatek 98e299
         case NVME_ST_CURR_OP_NOT_RUNNING:
Tomas Bzatek 98e299
             log->current_operation = BD_NVME_SELF_TEST_ACTION_NOT_RUNNING;
Tomas Bzatek 98e299
             break;
Tomas Bzatek 98e299
@@ -921,8 +973,8 @@ BDNVMESelfTestLog * bd_nvme_get_self_test_log (const gchar *device, GError **err
Tomas Bzatek 98e299
         default:
Tomas Bzatek 98e299
             log->current_operation = BD_NVME_SELF_TEST_ACTION_VENDOR_SPECIFIC;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
-    if ((self_test_log.current_operation & NVME_ST_CURR_OP_MASK) > 0)
Tomas Bzatek 98e299
-        log->current_operation_completion = self_test_log.completion & NVME_ST_CURR_OP_CMPL_MASK;
Tomas Bzatek 98e299
+    if ((self_test_log->current_operation & NVME_ST_CURR_OP_MASK) > 0)
Tomas Bzatek 98e299
+        log->current_operation_completion = self_test_log->completion & NVME_ST_CURR_OP_CMPL_MASK;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     ptr_array = g_ptr_array_new ();
Tomas Bzatek 98e299
     for (i = 0; i < NVME_LOG_ST_MAX_RESULTS; i++) {
Tomas Bzatek 98e299
@@ -930,8 +982,8 @@ BDNVMESelfTestLog * bd_nvme_get_self_test_log (const gchar *device, GError **err
Tomas Bzatek 98e299
         guint8 dsts;
Tomas Bzatek 98e299
         guint8 code;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-        dsts = self_test_log.result[i].dsts & NVME_ST_RESULT_MASK;
Tomas Bzatek 98e299
-        code = self_test_log.result[i].dsts >> NVME_ST_CODE_SHIFT;
Tomas Bzatek 98e299
+        dsts = self_test_log->result[i].dsts & NVME_ST_RESULT_MASK;
Tomas Bzatek 98e299
+        code = self_test_log->result[i].dsts >> NVME_ST_CODE_SHIFT;
Tomas Bzatek 98e299
         if (dsts == NVME_ST_RESULT_NOT_USED)
Tomas Bzatek 98e299
             continue;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -987,21 +1039,22 @@ BDNVMESelfTestLog * bd_nvme_get_self_test_log (const gchar *device, GError **err
Tomas Bzatek 98e299
                 g_warning ("Unhandled self-test log entry action code: %d", code);
Tomas Bzatek 98e299
                 entry->action = BD_NVME_SELF_TEST_ACTION_VENDOR_SPECIFIC;
Tomas Bzatek 98e299
         }
Tomas Bzatek 98e299
-        entry->segment = self_test_log.result[i].seg;
Tomas Bzatek 98e299
-        entry->power_on_hours = GUINT64_FROM_LE (self_test_log.result[i].poh);
Tomas Bzatek 98e299
-        if (self_test_log.result[i].vdi & NVME_ST_VALID_DIAG_INFO_NSID)
Tomas Bzatek 98e299
-            entry->nsid = GUINT32_FROM_LE (self_test_log.result[i].nsid);
Tomas Bzatek 98e299
-        if (self_test_log.result[i].vdi & NVME_ST_VALID_DIAG_INFO_FLBA)
Tomas Bzatek 98e299
-            entry->failing_lba = GUINT64_FROM_LE (self_test_log.result[i].flba);
Tomas Bzatek 98e299
-        if ((self_test_log.result[i].vdi & NVME_ST_VALID_DIAG_INFO_SC) &&
Tomas Bzatek 98e299
-            (self_test_log.result[i].vdi & NVME_ST_VALID_DIAG_INFO_SCT))
Tomas Bzatek 98e299
-            _nvme_status_to_error ((self_test_log.result[i].sct & 7) << 8 | self_test_log.result[i].sc,
Tomas Bzatek 98e299
+        entry->segment = self_test_log->result[i].seg;
Tomas Bzatek 98e299
+        entry->power_on_hours = GUINT64_FROM_LE (self_test_log->result[i].poh);
Tomas Bzatek 98e299
+        if (self_test_log->result[i].vdi & NVME_ST_VALID_DIAG_INFO_NSID)
Tomas Bzatek 98e299
+            entry->nsid = GUINT32_FROM_LE (self_test_log->result[i].nsid);
Tomas Bzatek 98e299
+        if (self_test_log->result[i].vdi & NVME_ST_VALID_DIAG_INFO_FLBA)
Tomas Bzatek 98e299
+            entry->failing_lba = GUINT64_FROM_LE (self_test_log->result[i].flba);
Tomas Bzatek 98e299
+        if ((self_test_log->result[i].vdi & NVME_ST_VALID_DIAG_INFO_SC) &&
Tomas Bzatek 98e299
+            (self_test_log->result[i].vdi & NVME_ST_VALID_DIAG_INFO_SCT))
Tomas Bzatek 98e299
+            _nvme_status_to_error ((self_test_log->result[i].sct & 7) << 8 | self_test_log->result[i].sc,
Tomas Bzatek 98e299
                                    FALSE, &entry->status_code_error);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
         g_ptr_array_add (ptr_array, entry);
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     g_ptr_array_add (ptr_array, NULL);
Tomas Bzatek 98e299
     log->entries = (BDNVMESelfTestLogEntry **) g_ptr_array_free (ptr_array, FALSE);
Tomas Bzatek 98e299
+    free (self_test_log);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     return log;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
@@ -1026,7 +1079,6 @@ BDNVMESelfTestLog * bd_nvme_get_self_test_log (const gchar *device, GError **err
Tomas Bzatek 98e299
 BDNVMESanitizeLog * bd_nvme_get_sanitize_log (const gchar *device, GError **error) {
Tomas Bzatek 98e299
     int ret;
Tomas Bzatek 98e299
     int fd;
Tomas Bzatek 98e299
-    char buf[65536] = ZERO_INIT;
Tomas Bzatek 98e299
     struct nvme_sanitize_log_page *sanitize_log;
Tomas Bzatek 98e299
     BDNVMESanitizeLog *log;
Tomas Bzatek 98e299
     __u16 sstat;
Tomas Bzatek 98e299
@@ -1037,20 +1089,18 @@ BDNVMESanitizeLog * bd_nvme_get_sanitize_log (const gchar *device, GError **erro
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* send the NVME_LOG_LID_SANITIZE ioctl */
Tomas Bzatek 98e299
-    ret = nvme_get_log_sanitize (fd, FALSE /* rae */, (struct nvme_sanitize_log_page *) &buf;;
Tomas Bzatek 98e299
+    sanitize_log = _nvme_alloc (sizeof (struct nvme_sanitize_log_page));
Tomas Bzatek 98e299
+    g_warn_if_fail (sanitize_log != NULL);
Tomas Bzatek 98e299
+    ret = nvme_get_log_sanitize (fd, FALSE /* rae */, sanitize_log);
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Get Log Page - Sanitize Status Log command error: ");
Tomas Bzatek 98e299
         close (fd);
Tomas Bzatek 98e299
+        free (sanitize_log);
Tomas Bzatek 98e299
         return NULL;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
     close (fd);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    /* need to use interim buffer that is large enough for broken drives
Tomas Bzatek 98e299
-     * returning more data than expected
Tomas Bzatek 98e299
-     */
Tomas Bzatek 98e299
-    sanitize_log = (struct nvme_sanitize_log_page *) &buf;
Tomas Bzatek 98e299
-
Tomas Bzatek 98e299
     log = g_new0 (BDNVMESanitizeLog, 1);
Tomas Bzatek 98e299
     log->sanitize_progress = 0;
Tomas Bzatek 98e299
     sstat = GUINT16_FROM_LE (sanitize_log->sstat);
Tomas Bzatek 98e299
@@ -1085,5 +1135,6 @@ BDNVMESanitizeLog * bd_nvme_get_sanitize_log (const gchar *device, GError **erro
Tomas Bzatek 98e299
     log->time_for_block_erase_nd = (GUINT32_FROM_LE (sanitize_log->etbend) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log->etbend);
Tomas Bzatek 98e299
     log->time_for_crypto_erase_nd = (GUINT32_FROM_LE (sanitize_log->etcend) == 0xffffffff) ? -1 : (gint64) GUINT32_FROM_LE (sanitize_log->etcend);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
+    free (sanitize_log);
Tomas Bzatek 98e299
     return log;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-op.c b/src/plugins/nvme/nvme-op.c
Tomas Bzatek 98e299
index c9e92697c..dbef4f3a2 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-op.c
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-op.c
Tomas Bzatek 98e299
@@ -116,30 +116,37 @@ gboolean bd_nvme_device_self_test (const gchar *device, BDNVMESelfTestAction act
Tomas Bzatek 98e299
 /* returns 0xff in case of error (the NVMe standard defines total of 16 flba records) */
Tomas Bzatek 98e299
 static __u8 find_lbaf_for_size (int fd, __u32 nsid, guint16 lba_data_size, guint16 metadata_size, GError **error) {
Tomas Bzatek 98e299
     int ret;
Tomas Bzatek 98e299
-    struct nvme_id_ns ns_info = ZERO_INIT;
Tomas Bzatek 98e299
+    struct nvme_id_ns *ns_info;
Tomas Bzatek 98e299
     __u8 flbas = 0;
Tomas Bzatek 98e299
     guint i;
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* TODO: find first attached namespace instead of hardcoding NSID = 1 */
Tomas Bzatek 98e299
-    ret = nvme_identify_ns (fd, nsid == 0xffffffff ? 1 : nsid, &ns_info);
Tomas Bzatek 98e299
+    ns_info = _nvme_alloc (sizeof (struct nvme_id_ns));
Tomas Bzatek 98e299
+    g_warn_if_fail (ns_info != NULL);
Tomas Bzatek 98e299
+    ret = nvme_identify_ns (fd, nsid == 0xffffffff ? 1 : nsid, ns_info);
Tomas Bzatek 98e299
     if (ret != 0) {
Tomas Bzatek 98e299
         _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
         g_prefix_error (error, "NVMe Identify Namespace command error: ");
Tomas Bzatek 98e299
+        free (ns_info);
Tomas Bzatek 98e299
         return 0xff;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* return currently used lbaf */
Tomas Bzatek 98e299
     if (lba_data_size == 0) {
Tomas Bzatek 98e299
-       nvme_id_ns_flbas_to_lbaf_inuse (ns_info.flbas, &flbas);
Tomas Bzatek 98e299
-       return flbas;
Tomas Bzatek 98e299
+        nvme_id_ns_flbas_to_lbaf_inuse (ns_info->flbas, &flbas);
Tomas Bzatek 98e299
+        free (ns_info);
Tomas Bzatek 98e299
+        return flbas;
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
-    for (i = 0; i <= ns_info.nlbaf + ns_info.nulbaf; i++)
Tomas Bzatek 98e299
-        if (1UL << ns_info.lbaf[i].ds == lba_data_size && GUINT16_FROM_LE (ns_info.lbaf[i].ms) == metadata_size)
Tomas Bzatek 98e299
+    for (i = 0; i <= ns_info->nlbaf + ns_info->nulbaf; i++)
Tomas Bzatek 98e299
+        if (1UL << ns_info->lbaf[i].ds == lba_data_size && GUINT16_FROM_LE (ns_info->lbaf[i].ms) == metadata_size) {
Tomas Bzatek 98e299
+            free (ns_info);
Tomas Bzatek 98e299
             return i;
Tomas Bzatek 98e299
+        }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     g_set_error_literal (error, BD_NVME_ERROR, BD_NVME_ERROR_INVALID_ARGUMENT,
Tomas Bzatek 98e299
                          "Couldn't match desired LBA data block size in a device supported LBA format data sizes");
Tomas Bzatek 98e299
+    free (ns_info);
Tomas Bzatek 98e299
     return 0xff;
Tomas Bzatek 98e299
 }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
@@ -176,7 +183,7 @@ static __u8 find_lbaf_for_size (int fd, __u32 nsid, guint16 lba_data_size, guint
Tomas Bzatek 98e299
 gboolean bd_nvme_format (const gchar *device, guint16 lba_data_size, guint16 metadata_size, BDNVMEFormatSecureErase secure_erase, GError **error) {
Tomas Bzatek 98e299
     int ret;
Tomas Bzatek 98e299
     gboolean ctrl_device = FALSE;
Tomas Bzatek 98e299
-    struct nvme_id_ctrl ctrl_id = ZERO_INIT;
Tomas Bzatek 98e299
+    struct nvme_id_ctrl *ctrl_id;
Tomas Bzatek 98e299
     struct nvme_format_nvm_args args = {
Tomas Bzatek 98e299
         .args_size = sizeof(args),
Tomas Bzatek 98e299
         .result = NULL,
Tomas Bzatek 98e299
@@ -207,11 +214,14 @@ gboolean bd_nvme_format (const gchar *device, guint16 lba_data_size, guint16 met
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* check the FNA controller bit when formatting a single namespace */
Tomas Bzatek 98e299
     if (! ctrl_device) {
Tomas Bzatek 98e299
-        ret = nvme_identify_ctrl (args.fd, &ctrl_id);
Tomas Bzatek 98e299
+        ctrl_id = _nvme_alloc (sizeof (struct nvme_id_ctrl));
Tomas Bzatek 98e299
+        g_warn_if_fail (ctrl_id != NULL);
Tomas Bzatek 98e299
+        ret = nvme_identify_ctrl (args.fd, ctrl_id);
Tomas Bzatek 98e299
         if (ret != 0) {
Tomas Bzatek 98e299
             _nvme_status_to_error (ret, FALSE, error);
Tomas Bzatek 98e299
             g_prefix_error (error, "NVMe Identify Controller command error: ");
Tomas Bzatek 98e299
             close (args.fd);
Tomas Bzatek 98e299
+            free (ctrl_id);
Tomas Bzatek 98e299
             return FALSE;
Tomas Bzatek 98e299
         }
Tomas Bzatek 98e299
         /* from nvme-cli:
Tomas Bzatek 98e299
@@ -219,14 +229,16 @@ gboolean bd_nvme_format (const gchar *device, guint16 lba_data_size, guint16 met
Tomas Bzatek 98e299
          * attributes and a format (excluding secure erase) of any namespace results in a
Tomas Bzatek 98e299
          * format of all namespaces.
Tomas Bzatek 98e299
          */
Tomas Bzatek 98e299
-        if ((ctrl_id.fna & NVME_CTRL_FNA_FMT_ALL_NAMESPACES) == NVME_CTRL_FNA_FMT_ALL_NAMESPACES) {
Tomas Bzatek 98e299
+        if ((ctrl_id->fna & NVME_CTRL_FNA_FMT_ALL_NAMESPACES) == NVME_CTRL_FNA_FMT_ALL_NAMESPACES) {
Tomas Bzatek 98e299
             /* tell user that it would format other namespaces and that bd_nvme_format()
Tomas Bzatek 98e299
              * should be called on a controller device instead */
Tomas Bzatek 98e299
             g_set_error_literal (error, BD_NVME_ERROR, BD_NVME_ERROR_WOULD_FORMAT_ALL_NS,
Tomas Bzatek 98e299
                          "The NVMe controller indicates it would format all namespaces.");
Tomas Bzatek 98e299
             close (args.fd);
Tomas Bzatek 98e299
+            free (ctrl_id);
Tomas Bzatek 98e299
             return FALSE;
Tomas Bzatek 98e299
         }
Tomas Bzatek 98e299
+        free (ctrl_id);
Tomas Bzatek 98e299
     }
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
     /* find out the desired LBA data format index */
Tomas Bzatek 98e299
diff --git a/src/plugins/nvme/nvme-private.h b/src/plugins/nvme/nvme-private.h
Tomas Bzatek 98e299
index 8b6d13253..0d15fbb64 100644
Tomas Bzatek 98e299
--- a/src/plugins/nvme/nvme-private.h
Tomas Bzatek 98e299
+++ b/src/plugins/nvme/nvme-private.h
Tomas Bzatek 98e299
@@ -24,5 +24,7 @@ void _nvme_fabrics_errno_to_gerror (int result, int _errno, GError **error);
Tomas Bzatek 98e299
 /* nvme-info.c */
Tomas Bzatek 98e299
 G_GNUC_INTERNAL
Tomas Bzatek 98e299
 gint _open_dev (const gchar *device, GError **error);
Tomas Bzatek 98e299
+G_GNUC_INTERNAL
Tomas Bzatek 98e299
+void *_nvme_alloc (size_t len);
Tomas Bzatek 98e299
 
Tomas Bzatek 98e299
 #endif  /* BD_NVME_PRIVATE */