[gnome-disk-utility] Disable auto-clear before operations needing unmount
- From: Ondrej Holy <oholy src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-disk-utility] Disable auto-clear before operations needing unmount
- Date: Tue, 2 May 2017 07:26:12 +0000 (UTC)
commit 4ea9260a2025b4832aa904cd6a48f5976d10c2cd
Author: Kai Lüke <kailueke riseup net>
Date: Sun Apr 30 15:14:30 2017 +0200
Disable auto-clear before operations needing unmount
For some actions the volume is ensured to be unmounted before
the action is started. The auto-clear of loop devices has to
be disabled because otherwise the whole device is gone after the
unmount and then the planned action fails with an error.
This is now handled by deactivating auto-clear if the last used
volume of a device is going to be unmounted.
https://bugzilla.gnome.org/show_bug.cgi?id=780865
src/libgdu/gduutils.c | 86 +++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 79 insertions(+), 7 deletions(-)
---
diff --git a/src/libgdu/gduutils.c b/src/libgdu/gduutils.c
index 16640bc..2574355 100644
--- a/src/libgdu/gduutils.c
+++ b/src/libgdu/gduutils.c
@@ -895,7 +895,8 @@ static gboolean
gdu_utils_is_in_use_full (UDisksClient *client,
UDisksObject *object,
UDisksFilesystem **filesystem_to_unmount_out,
- UDisksEncrypted **encrypted_to_lock_out)
+ UDisksEncrypted **encrypted_to_lock_out,
+ gboolean *last_out)
{
UDisksFilesystem *filesystem_to_unmount = NULL;
UDisksEncrypted *encrypted_to_lock = NULL;
@@ -907,6 +908,7 @@ gdu_utils_is_in_use_full (UDisksClient *client,
GList *l;
GList *objects_to_check = NULL;
gboolean ret = FALSE;
+ gboolean last = TRUE;
drive = udisks_object_get_drive (object);
if (drive != NULL)
@@ -979,9 +981,14 @@ gdu_utils_is_in_use_full (UDisksClient *client,
const gchar *const *mount_points = udisks_filesystem_get_mount_points (filesystem_for_object);
if (g_strv_length ((gchar **) mount_points) > 0)
{
+ if (ret)
+ {
+ last = FALSE;
+ break;
+ }
+
filesystem_to_unmount = g_object_ref (filesystem_for_object);
ret = TRUE;
- goto victim_found;
}
}
@@ -993,14 +1000,21 @@ gdu_utils_is_in_use_full (UDisksClient *client,
if (cleartext != NULL)
{
g_object_unref (cleartext);
+
+ if (ret)
+ {
+ last = FALSE;
+ break;
+ }
+
encrypted_to_lock = g_object_ref (encrypted_for_object);
ret = TRUE;
- goto victim_found;
}
}
- }
- victim_found:
+ if (ret && last_out == NULL)
+ break;
+ }
if (filesystem_to_unmount_out != NULL)
{
@@ -1012,6 +1026,8 @@ gdu_utils_is_in_use_full (UDisksClient *client,
*encrypted_to_lock_out = (encrypted_to_lock != NULL) ?
g_object_ref (encrypted_to_lock) : NULL;
}
+ if (last_out != NULL)
+ *last_out = last;
g_clear_object (&partition_table);
g_list_free_full (partitions, g_object_unref);
@@ -1029,7 +1045,7 @@ gboolean
gdu_utils_is_in_use (UDisksClient *client,
UDisksObject *object)
{
- return gdu_utils_is_in_use_full (client, object, NULL, NULL);
+ return gdu_utils_is_in_use_full (client, object, NULL, NULL, NULL);
}
/* ---------------------------------------------------------------------------------------------------- */
@@ -1115,15 +1131,71 @@ unuse_lock_cb (UDisksEncrypted *encrypted,
}
static void
+unuse_set_autoclear_cb (UDisksLoop *loop,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ UnuseData *data = user_data;
+ GError *error = NULL;
+
+ if (!udisks_loop_call_set_autoclear_finish (loop,
+ res,
+ &error))
+ {
+ unuse_data_complete (data,
+ _("Error disabling autoclear for loop device"),
+ error);
+ }
+ else
+ {
+ unuse_data_iterate (data);
+ }
+}
+
+static void
unuse_data_iterate (UnuseData *data)
{
UDisksObject *object;
UDisksFilesystem *filesystem_to_unmount = NULL;
UDisksEncrypted *encrypted_to_lock = NULL;
+ UDisksLoop *loop;
+ UDisksBlock *block;
+ gboolean last;
object = UDISKS_OBJECT (data->object_iter->data);
gdu_utils_is_in_use_full (data->client, object,
- &filesystem_to_unmount, &encrypted_to_lock);
+ &filesystem_to_unmount, &encrypted_to_lock, NULL);
+ block = udisks_object_peek_block (object);
+
+ if (block != NULL && (filesystem_to_unmount != NULL || encrypted_to_lock != NULL))
+ {
+ loop = udisks_client_get_loop_for_block (data->client, block);
+
+ if (loop != NULL)
+ {
+ if (udisks_loop_get_autoclear (loop))
+ {
+ gdu_utils_is_in_use_full (data->client,
+ UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE
(loop))),
+ NULL, NULL, &last);
+ if (last)
+ {
+ udisks_loop_call_set_autoclear (loop,
+ FALSE,
+ g_variant_new ("a{sv}", NULL),
+ data->cancellable,
+ (GAsyncReadyCallback) unuse_set_autoclear_cb,
+ data);
+ g_object_unref (loop);
+ g_clear_object (&encrypted_to_lock);
+ g_clear_object (&filesystem_to_unmount);
+ return;
+ }
+ }
+
+ g_object_unref (loop);
+ }
+ }
if (filesystem_to_unmount != NULL)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]