[RFC PATCH v1 07/17] vmstate: Create and save ptr marker in same function

Fabiano Rosas posted 17 patches 1 week, 2 days ago
[RFC PATCH v1 07/17] vmstate: Create and save ptr marker in same function
Posted by Fabiano Rosas 1 week, 2 days ago
Move the creation of the pointer marker along with the vmstate_save
call that writes it to the stream.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
 migration/vmstate.c | 78 ++++++++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 39 deletions(-)

diff --git a/migration/vmstate.c b/migration/vmstate.c
index a190c3f63f..0975d10793 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -54,36 +54,6 @@ vmstate_field_exists(const VMStateDescription *vmsd, const VMStateField *field,
     return result;
 }
 
-/*
- * Create a ptr marker field when there's a NULL pointer detected in the
- * array of a VMS_ARRAY_OF_POINTER VMSD field.  It's needed because we
- * can't dereference the NULL pointer.
- */
-static const VMStateField *
-vmsd_create_ptr_marker_field(const VMStateField *field)
-{
-    VMStateField *fake = g_new0(VMStateField, 1);
-
-    /* It can only happen on an array of pointers! */
-    assert(field->flags & VMS_ARRAY_OF_POINTER);
-
-    /* Some of fake's properties should match the original's */
-    fake->name = field->name;
-    fake->version_id = field->version_id;
-
-    /* Do not need "field_exists" check as it always exists (which is null) */
-    fake->field_exists = NULL;
-
-    /* See vmstate_info_nullptr - use 1 byte to represent nullptr */
-    fake->size = 1;
-    fake->info = &vmstate_info_ptr_marker;
-    fake->flags = VMS_SINGLE;
-
-    /* All the rest fields shouldn't matter.. */
-
-    return (const VMStateField *)fake;
-}
-
 static int vmstate_n_elems(void *opaque, const VMStateField *field)
 {
     int n_elems = 1;
@@ -592,6 +562,42 @@ vmstate_save_field_with_vmdesc(QEMUFile *f, void *pv, size_t size,
     return ok;
 }
 
+/*
+ * Create a ptr marker field to precede an element of a
+ * VMS_ARRAY_OF_POINTER VMSD field. This indicates whether the
+ * following element is a NULL pointer or a valid pointer. This is
+ * used to know whether a pointer needs to be followed when loading
+ * the data.
+ */
+static bool vmstate_ptr_marker_save(QEMUFile *f, void *opaque,
+                                    const VMStateDescription *vmsd,
+                                    const VMStateField *field,
+                                    JSONWriter *vmdesc,
+                                    int i, int max, Error **errp)
+{
+    g_autofree VMStateField *fake = g_new0(VMStateField, 1);
+
+    /* It can only happen on an array of pointers! */
+    assert(field->flags & VMS_ARRAY_OF_POINTER);
+
+    /* Some of fake's properties should match the original's */
+    fake->name = field->name;
+    fake->version_id = field->version_id;
+
+    /* Do not need "field_exists" check as it always exists */
+    fake->field_exists = NULL;
+
+    /* use 1 byte for the marker */
+    fake->size = 1;
+    fake->info = &vmstate_info_ptr_marker;
+    fake->flags = VMS_SINGLE;
+
+    /* All the rest fields shouldn't matter.. */
+
+    return vmstate_save_field_with_vmdesc(f, opaque, field->size, vmsd, fake,
+                                          vmdesc, i, max, errp);
+}
+
 static bool vmstate_save_vmsd_v(QEMUFile *f, const VMStateDescription *vmsd,
                                 void *opaque, JSONWriter *vmdesc,
                                 int version_id, Error **errp)
@@ -635,7 +641,6 @@ static bool vmstate_save_vmsd_v(QEMUFile *f, const VMStateDescription *vmsd,
                 int max_elems = n_elems - i;
 
                 if (field->flags & VMS_ARRAY_OF_POINTER) {
-                    const VMStateField *inner_field;
                     bool use_marker_field, is_null, use_dynamic_array;
 
                     assert(curr_elem);
@@ -688,14 +693,9 @@ static bool vmstate_save_vmsd_v(QEMUFile *f, const VMStateDescription *vmsd,
                     }
 
                     if (use_marker_field) {
-                        inner_field = vmsd_create_ptr_marker_field(field);
-
-                        ok = vmstate_save_field_with_vmdesc(
-                            f, curr_elem, 1, vmsd, inner_field,
-                            use_vmdesc ? vmdesc : NULL, i, max_elems, errp);
-
-                        g_clear_pointer((gpointer *)&inner_field, g_free);
-
+                        ok = vmstate_ptr_marker_save(f, curr_elem, vmsd, field,
+                                                     use_vmdesc ? vmdesc : NULL,
+                                                     i, max_elems, errp);
                         if (!ok) {
                             goto out;
                         }
-- 
2.51.0