[gnome-disk-utility/gnome-3-26] Keep FS mounted while growing partition (string freeze)



commit e7f5d17ceb6cc78c99a54de6c8c6d76663a8603c
Author: Kai Lüke <kailueke riseup net>
Date:   Fri Sep 29 16:32:35 2017 +0900

    Keep FS mounted while growing partition (string freeze)
    
    Growing the partition for offline resize caused
    a rediscovery in UDisks to led to GVFs automount
    which lets the Disks filesystem resize call fail.
    
    A good solution is to keep the filesystem mounted
    while growing the partition, as it is done in the
    online resize already. This way there will be no
    rediscovery and automount, and the filesystem can
    be unmounted afterwards to be grown. From this point
    there will be no automount coming because the partition
    size is not touched anymore.
    
    Same as on master except for only reusing translated
    strings by taking shorter error messages.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=788326

 src/disks/gduresizedialog.c |  192 ++++++++++++++++++++++++++++++++-----------
 1 files changed, 142 insertions(+), 50 deletions(-)
---
diff --git a/src/disks/gduresizedialog.c b/src/disks/gduresizedialog.c
index c224bcc..ade48db 100644
--- a/src/disks/gduresizedialog.c
+++ b/src/disks/gduresizedialog.c
@@ -513,22 +513,24 @@ part_resize_cb_online_next_fs_resize (UDisksPartition  *partition,
 }
 
 static void
-part_resize_cb_offline_next_fs_resize (UDisksPartition  *partition,
-                                       GAsyncResult     *res,
-                                       ResizeDialogData *data)
+fs_repair_cb_offline_next_grow (UDisksFilesystem *filesystem,
+                                GAsyncResult     *res,
+                                ResizeDialogData *data)
 {
   GError *error = NULL;
+  gboolean success = FALSE;
 
-  if (!udisks_partition_call_resize_finish (partition, res, &error))
+  if (!udisks_filesystem_call_repair_finish (filesystem, &success, res, &error) || !success)
     {
       gdu_utils_show_error (GTK_WINDOW (data->window),
-                            _("Error resizing partition"),
+                            _("Error repairing filesystem"),
                             error);
       g_error_free (error);
       resize_dialog_data_unref (data);
     }
   else
     {
+      /* growing: next is to resize filesystem, then run repair again */
       udisks_filesystem_call_resize (data->filesystem, get_size (data),
                                      g_variant_new ("a{sv}", NULL), NULL,
                                      (GAsyncReadyCallback) fs_resize_cb_offline_next_repair, data);
@@ -536,6 +538,57 @@ part_resize_cb_offline_next_fs_resize (UDisksPartition  *partition,
 }
 
 static void
+ensure_unused_cb_offline_next_repair (GObject      *source_object,
+                                      GAsyncResult *res,
+                                      gpointer      user_data)
+{
+  ResizeDialogData *data = user_data;
+  GError *error = NULL;
+
+  if (!gdu_utils_ensure_unused_finish (data->client, res, &error))
+    {
+      gdu_utils_show_error (GTK_WINDOW (data->window),
+                            _("Error unmounting filesystem"),
+                            error);
+
+      g_error_free (error);
+      resize_dialog_data_unref (data);
+    }
+  else
+    {
+      udisks_filesystem_call_repair (data->filesystem,
+                                     g_variant_new ("a{sv}", NULL), NULL,
+                                     (GAsyncReadyCallback) fs_repair_cb_offline_next_grow, data);
+    }
+}
+
+static void
+part_resize_cb_offline_next_fs_unmount (UDisksPartition  *partition,
+                                        GAsyncResult     *res,
+                                        ResizeDialogData *data)
+{
+  GError *error = NULL;
+
+  if (!udisks_partition_call_resize_finish (partition, res, &error))
+    {
+      gdu_utils_show_error (GTK_WINDOW (data->window),
+                            _("Error resizing partition"),
+                            error);
+      g_error_free (error);
+      resize_dialog_data_unref (data);
+    }
+  else
+    {
+      gdu_utils_ensure_unused (data->client,
+                               GTK_WINDOW (data->window),
+                               data->object,
+                               ensure_unused_cb_offline_next_repair,
+                               NULL,
+                               data);
+    }
+}
+
+static void
 fs_resize_cb_online_next_part_resize (UDisksFilesystem *filesystem,
                                       GAsyncResult     *res,
                                       ResizeDialogData *data)
@@ -582,7 +635,7 @@ fs_resize_cb_offline_next_fs_repair (UDisksFilesystem *filesystem,
 }
 
 static void
-fs_repair_cb_offline_next_resize (UDisksFilesystem *filesystem,
+fs_repair_cb_offline_next_shrink (UDisksFilesystem *filesystem,
                                   GAsyncResult     *res,
                                   ResizeDialogData *data)
 {
@@ -599,20 +652,10 @@ fs_repair_cb_offline_next_resize (UDisksFilesystem *filesystem,
     }
   else
     {
-      if (is_shrinking (data))
-        {
-          /* shrinking: next is to resize filesystem, run repair, then resize partition */
-          udisks_filesystem_call_resize (data->filesystem, get_size (data),
-                                         g_variant_new ("a{sv}", NULL), NULL,
-                                         (GAsyncReadyCallback) fs_resize_cb_offline_next_fs_repair, data);
-        }
-      else
-        {
-          /* growing: next is to resize partition, then resize filesystem, run repair */
-          udisks_partition_call_resize (data->partition, get_size (data),
-                                        g_variant_new ("a{sv}", NULL), NULL,
-                                        (GAsyncReadyCallback) part_resize_cb_offline_next_fs_resize, data);
-        }
+      /* shrinking: next is to resize filesystem, run repair again, then resize partition */
+      udisks_filesystem_call_resize (data->filesystem, get_size (data),
+                                     g_variant_new ("a{sv}", NULL), NULL,
+                                     (GAsyncReadyCallback) fs_resize_cb_offline_next_fs_repair, data);
     }
 }
 
@@ -636,18 +679,6 @@ online_resize_no_repair (ResizeDialogData *data)
 }
 
 static void
-offline_resize_with_repair (ResizeDialogData *data)
-{
-  /* partition and filesystem resize:
-   * if growing fs-repair, part-resize, fs-resize, fs-repair
-   * if shrinking fs-repair, fs-resize, fs-repair, part-resize
-   */
-  udisks_filesystem_call_repair (data->filesystem,
-                                 g_variant_new ("a{sv}", NULL), NULL,
-                                 (GAsyncReadyCallback) fs_repair_cb_offline_next_resize, data);
-}
-
-static void
 unmount_cb (GObject      *source_object,
             GAsyncResult *res,
             gpointer      user_data)
@@ -666,7 +697,75 @@ unmount_cb (GObject      *source_object,
     }
   else
     {
-      offline_resize_with_repair (data);
+      /* shrinking partition and filesystem:
+       * fs-repair, fs-resize, fs-repair, part-resize
+       */
+      udisks_filesystem_call_repair (data->filesystem,
+                                     g_variant_new ("a{sv}", NULL), NULL,
+                                     (GAsyncReadyCallback) fs_repair_cb_offline_next_shrink, data);
+    }
+}
+
+static void
+resize (ResizeDialogData *data)
+{
+  gboolean shrinking;
+
+  shrinking = is_shrinking (data);
+
+  if ((!(data->support & ONLINE_SHRINK) && shrinking) ||
+      (!(data->support & ONLINE_GROW) && !shrinking))
+    {
+      if (shrinking)
+        {
+          gdu_utils_ensure_unused (data->client,
+                                   GTK_WINDOW (data->window),
+                                   data->object,
+                                   unmount_cb,
+                                   NULL,
+                                   data);
+        }
+      else
+        {
+          /* The offline grow case still needs the FS to be mounted during
+           * the partition resize to prevent any race conditions with GVFs
+           * automount but will unmount as soon as FS repair and resize take place:
+           * part-resize, fs-repair, fs-resize, fs-repair
+           */
+          udisks_partition_call_resize (data->partition, get_size (data),
+                                        g_variant_new ("a{sv}", NULL), NULL,
+                                        (GAsyncReadyCallback) part_resize_cb_offline_next_fs_unmount, data);
+        }
+    }
+  else
+    {
+      online_resize_no_repair (data);
+    }
+}
+
+static void
+mount_cb (UDisksFilesystem *filesystem,
+          GAsyncResult     *res,
+          gpointer          user_data)
+{
+  ResizeDialogData *data = (ResizeDialogData *) user_data;
+  GError *error = NULL;
+
+  if (!udisks_filesystem_call_mount_finish (filesystem,
+                                            NULL, /* out_mount_path */
+                                            res,
+                                            &error))
+    {
+      gdu_utils_show_error (GTK_WINDOW (data->window),
+                            _("Error mounting filesystem"),
+                            error);
+
+      g_error_free (error);
+      resize_dialog_data_unref (data);
+    }
+  else
+    {
+      resize (data);
     }
 }
 
@@ -861,34 +960,27 @@ gdu_resize_dialog_show (GduWindow    *window,
 
   if (gtk_dialog_run (GTK_DIALOG (data->dialog)) == GTK_RESPONSE_APPLY)
     {
-      gboolean shrinking;
-
-      shrinking = is_shrinking (data);
-
       gtk_widget_hide (data->dialog);
       g_clear_pointer (&data->dialog, gtk_widget_destroy);
 
       if (data->filesystem != NULL)
         {
+          gboolean offline_shrink;
+
           mount_points = udisks_filesystem_get_mount_points (data->filesystem);
+          /* prevent the case of mounting when directly unmount would follow */
+          offline_shrink = !(data->support & ONLINE_SHRINK) && is_shrinking (data);
 
-          if (g_strv_length ((gchar **) mount_points) == 0)
-            {
-              offline_resize_with_repair (data);
-            }
-          else if ((!(data->support & ONLINE_SHRINK) && shrinking) ||
-                   (!(data->support & ONLINE_GROW) && !shrinking))
+          if (g_strv_length ((gchar **) mount_points) == 0 && !offline_shrink)
             {
-              gdu_utils_ensure_unused (data->client,
-                                       GTK_WINDOW (window),
-                                       object,
-                                       unmount_cb,
-                                       NULL,
-                                       data);
+              /* FS was unmounted by the user while the dialog stayed open */
+              udisks_filesystem_call_mount (data->filesystem,
+                                            g_variant_new ("a{sv}", NULL), NULL,
+                                            (GAsyncReadyCallback) mount_cb, data);
             }
           else
             {
-              online_resize_no_repair (data);
+              resize (data);
             }
         }
       else


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]