From 28c39786927ad683f56c031d80a5c06f5b5b9aea Mon Sep 17 00:00:00 2001 From: Marius Vollmer Date: Tue, 5 Apr 2022 11:23:23 +0300 Subject: [PATCH] lvm2: Only install results of most recently started udpates Fixes #966 --- modules/lvm2/udiskslinuxmodulelvm2.c | 13 ++++++++++++- modules/lvm2/udiskslinuxvolumegroupobject.c | 12 ++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/modules/lvm2/udiskslinuxmodulelvm2.c b/modules/lvm2/udiskslinuxmodulelvm2.c index 8e1ea13aec..77ecf94a6d 100644 --- a/modules/lvm2/udiskslinuxmodulelvm2.c +++ b/modules/lvm2/udiskslinuxmodulelvm2.c @@ -59,6 +59,8 @@ struct _UDisksLinuxModuleLVM2 { gint delayed_update_id; gboolean coldplug_done; + + guint32 update_epoch; }; typedef struct _UDisksLinuxModuleLVM2Class UDisksLinuxModuleLVM2Class; @@ -86,6 +88,7 @@ udisks_linux_module_lvm2_constructed (GObject *object) module->name_to_volume_group = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); module->coldplug_done = FALSE; + module->update_epoch = 0; if (G_OBJECT_CLASS (udisks_linux_module_lvm2_parent_class)->constructed) G_OBJECT_CLASS (udisks_linux_module_lvm2_parent_class)->constructed (object); @@ -221,6 +224,12 @@ lvm_update_vgs (GObject *source_obj, gpointer key, value; const gchar *vg_name; + if (GPOINTER_TO_UINT (user_data) != module->update_epoch) + { + vgs_pvs_data_free (data); + return; + } + if (! data) { if (error) @@ -303,11 +312,13 @@ lvm_update (UDisksLinuxModuleLVM2 *module) { GTask *task; + module->update_epoch++; + /* the callback (lvm_update_vgs) is called in the default main loop (context) */ task = g_task_new (module, NULL /* cancellable */, lvm_update_vgs, - NULL /* callback_data */); + GUINT_TO_POINTER (module->update_epoch)); /* holds a reference to 'task' until it is finished */ g_task_run_in_thread (task, (GTaskThreadFunc) vgs_task_func); diff --git a/modules/lvm2/udiskslinuxvolumegroupobject.c b/modules/lvm2/udiskslinuxvolumegroupobject.c index ce941cb250..ead08de7b1 100644 --- a/modules/lvm2/udiskslinuxvolumegroupobject.c +++ b/modules/lvm2/udiskslinuxvolumegroupobject.c @@ -66,6 +66,7 @@ struct _UDisksLinuxVolumeGroupObject gchar *name; GHashTable *logical_volumes; + guint32 update_epoch; guint32 poll_epoch; guint poll_timeout_id; gboolean poll_requested; @@ -99,6 +100,7 @@ static void crypttab_changed (UDisksCrypttabMonitor *monitor, typedef struct { BDLVMVGdata *vg_info; GSList *vg_pvs; + guint32 epoch; } VGUpdateData; static void @@ -183,6 +185,7 @@ udisks_linux_volume_group_object_set_property (GObject *__object, static void udisks_linux_volume_group_object_init (UDisksLinuxVolumeGroupObject *object) { + object->update_epoch = 0; object->poll_epoch = 0; object->poll_timeout_id = 0; object->poll_requested = FALSE; @@ -575,6 +578,12 @@ update_vg (GObject *source_obj, BDLVMVGdata *vg_info = data->vg_info; GSList *vg_pvs = data->vg_pvs; + if (data->epoch != object->update_epoch) + { + lv_list_free (lvs); + return; + } + /* free the data container (but not 'vg_info' and 'vg_pvs') */ g_free (data); @@ -711,8 +720,11 @@ udisks_linux_volume_group_object_update (UDisksLinuxVolumeGroupObject *object, B gchar *vg_name = g_strdup (vg_info->name); GTask *task = NULL; + object->update_epoch++; + data->vg_info = vg_info; data->vg_pvs = pvs; + data->epoch = object->update_epoch; /* the callback (update_vg) is called in the default main loop (context) */ task = g_task_new (g_object_ref (object), NULL /* cancellable */, update_vg, data /* callback_data */);