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