[gvfs/wip/udisks2: 5/5] udisks2: implement mount and unmount methods



commit c5df9130880549f29bd183860b6fe32640898ccc
Author: David Zeuthen <davidz redhat com>
Date:   Wed Sep 28 15:35:49 2011 -0400

    udisks2: implement mount and unmount methods
    
    Signed-off-by: David Zeuthen <davidz redhat com>

 monitor/udisks2/gvfsudisks2drive.c         |    2 +-
 monitor/udisks2/gvfsudisks2mount.c         |  379 +++++++++++++++++++++++++++-
 monitor/udisks2/gvfsudisks2mount.h         |    4 +-
 monitor/udisks2/gvfsudisks2volume.c        |  159 +++++++++++-
 monitor/udisks2/gvfsudisks2volumemonitor.c |   16 +-
 monitor/udisks2/gvfsudisks2volumemonitor.h |    1 +
 6 files changed, 544 insertions(+), 17 deletions(-)
---
diff --git a/monitor/udisks2/gvfsudisks2drive.c b/monitor/udisks2/gvfsudisks2drive.c
index d5e3a38..b83af8e 100644
--- a/monitor/udisks2/gvfsudisks2drive.c
+++ b/monitor/udisks2/gvfsudisks2drive.c
@@ -166,7 +166,7 @@ update_drive (GVfsUDisks2Drive *drive)
   if (drive->is_media_removable)
     {
       drive->has_media = (udisks_drive_get_size (drive->udisks_drive) > 0);
-      drive->can_eject = TRUE;
+      drive->can_eject = FALSE; // TODO: set to TRUE when eject() has been implemented
     }
   else
     {
diff --git a/monitor/udisks2/gvfsudisks2mount.c b/monitor/udisks2/gvfsudisks2mount.c
index 6f049bb..6d82b61 100644
--- a/monitor/udisks2/gvfsudisks2mount.c
+++ b/monitor/udisks2/gvfsudisks2mount.c
@@ -27,6 +27,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <stdlib.h>
 
 #include <glib.h>
 #include <glib/gi18n-lib.h>
@@ -421,12 +422,11 @@ gvfs_udisks2_mount_has_uuid (GVfsUDisks2Mount *_mount,
   return g_strcmp0 (mount->uuid, uuid) == 0;
 }
 
-gboolean
-gvfs_udisks2_mount_has_mount_path (GVfsUDisks2Mount *_mount,
-                                   const gchar      *mount_path)
+const gchar *
+gvfs_udisks2_mount_get_mount_path (GVfsUDisks2Mount *_mount)
 {
   GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
-  return g_strcmp0 (mount->mount_path, mount_path) == 0;
+  return mount->mount_path;
 }
 
 static GDrive *
@@ -478,6 +478,375 @@ gvfs_udisks2_mount_can_eject (GMount *_mount)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+static GArray *
+get_busy_processes (const gchar* const *mount_points)
+{
+  GArray *processes;
+  guint n;
+
+  processes = g_array_new (FALSE, FALSE, sizeof (GPid));
+
+  for (n = 0; mount_points != NULL && mount_points[n] != NULL; n++)
+    {
+      const gchar *mount_point = mount_points[n];
+      const gchar *lsof_argv[] = {"lsof", "-t", NULL, NULL};
+      gchar *standard_output = NULL;
+      const gchar *p;
+      gint exit_status;
+      GError *error;
+
+      lsof_argv[2] = mount_point;
+
+      error = NULL;
+      if (!g_spawn_sync (NULL,       /* working_directory */
+                         (gchar **) lsof_argv,
+                         NULL,       /* envp */
+                         G_SPAWN_SEARCH_PATH,
+                         NULL,       /* child_setup */
+                         NULL,       /* user_data */
+                         &standard_output,
+                         NULL,       /* standard_error */
+                         &exit_status,
+                         &error))
+        {
+          g_warning ("Error launching lsof(1): %s (%s, %d)",
+                     error->message, g_quark_to_string (error->domain), error->code);
+          goto cont_loop;
+        }
+      if (!(WIFEXITED (exit_status) && WEXITSTATUS (exit_status) == 0))
+        {
+          g_warning ("lsof(1) didn't exit normally");
+          goto cont_loop;
+        }
+
+      p = standard_output;
+      while (TRUE)
+        {
+          GPid pid;
+          gchar *endp;
+
+          if (*p == '\0')
+            break;
+
+          pid = strtol (p, &endp, 10);
+
+          if (pid == 0 && p == endp)
+            break;
+
+          g_array_append_val (processes, pid);
+
+          p = endp;
+        }
+    cont_loop:
+      g_free (standard_output);
+    }
+  return processes;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct
+{
+  GSimpleAsyncResult *simple;
+
+  GVfsUDisks2Mount *mount;
+
+  GCancellable *cancellable;
+  gulong cancelled_handler_id;
+  gboolean is_cancelled;
+
+  GMountOperation *mount_operation;
+  GMountUnmountFlags flags;
+
+  gulong mount_op_reply_handler_id;
+  guint retry_unmount_timer_id;
+
+} UnmountData;
+
+static void
+unmount_data_free (UnmountData *data)
+{
+  g_object_unref (data->simple);
+
+  if (data->mount_op_reply_handler_id > 0)
+    {
+      /* make the operation dialog go away */
+      g_signal_emit_by_name (data->mount_operation, "aborted");
+      g_signal_handler_disconnect (data->mount_operation, data->mount_op_reply_handler_id);
+    }
+  if (data->retry_unmount_timer_id > 0)
+    {
+      g_source_remove (data->retry_unmount_timer_id);
+      data->retry_unmount_timer_id = 0;
+    }
+
+  g_clear_object (&data->mount);
+  if (data->cancelled_handler_id != 0)
+    g_signal_handler_disconnect (data->cancellable, data->cancelled_handler_id);
+  g_clear_object (&data->cancellable);
+  g_clear_object (&data->mount_operation);
+
+  g_free (data);
+}
+
+static void unmount_do (UnmountData *data, gboolean force);
+
+static gboolean
+on_retry_timer_cb (gpointer user_data)
+{
+  UnmountData *data = user_data;
+
+  if (data->retry_unmount_timer_id == 0)
+    goto out;
+
+  /* we're removing the timeout */
+  data->retry_unmount_timer_id = 0;
+
+  /* timeout expired => try again */
+  unmount_do (data, FALSE);
+
+ out:
+  return FALSE; /* remove timeout */
+}
+
+static void
+on_mount_op_reply (GMountOperation       *mount_operation,
+                   GMountOperationResult result,
+                   gpointer              user_data)
+{
+  UnmountData *data = user_data;
+  gint choice;
+
+  /* disconnect the signal handler */
+  g_warn_if_fail (data->mount_op_reply_handler_id != 0);
+  g_signal_handler_disconnect (data->mount_operation,
+                               data->mount_op_reply_handler_id);
+  data->mount_op_reply_handler_id = 0;
+
+  choice = g_mount_operation_get_choice (mount_operation);
+
+  if (result == G_MOUNT_OPERATION_ABORTED ||
+      (result == G_MOUNT_OPERATION_HANDLED && choice == 1))
+    {
+      /* don't show an error dialog here */
+      g_simple_async_result_set_error (data->simple,
+                                       G_IO_ERROR,
+                                       G_IO_ERROR_FAILED_HANDLED,
+                                       "GMountOperation aborted (user should never see this "
+                                       "error since it is G_IO_ERROR_FAILED_HANDLED)");
+      g_simple_async_result_complete_in_idle (data->simple);
+      unmount_data_free (data);
+    }
+  else if (result == G_MOUNT_OPERATION_HANDLED)
+    {
+      /* user chose force unmount => try again with force_unmount==TRUE */
+      unmount_do (data, TRUE);
+    }
+  else
+    {
+      /* result == G_MOUNT_OPERATION_UNHANDLED => GMountOperation instance doesn't
+       * support :show-processes signal
+       */
+      g_simple_async_result_set_error (data->simple,
+                                       G_IO_ERROR,
+                                       G_IO_ERROR_BUSY,
+                                       _("One or more programs are preventing the unmount operation."));
+      g_simple_async_result_complete_in_idle (data->simple);
+      unmount_data_free (data);
+    }
+}
+
+static void
+unmount_cb (GObject       *source_object,
+            GAsyncResult  *res,
+            gpointer       user_data)
+{
+  UDisksFilesystem *filesystem = UDISKS_FILESYSTEM (source_object);
+  UnmountData *data = user_data;
+  GError *error;
+
+  error = NULL;
+  if (!udisks_filesystem_call_unmount_finish (filesystem,
+                                              res,
+                                              &error))
+    {
+      /* translate to UDisksError to GIOError and strip D-Bus error information */
+      if (error->domain == UDISKS_ERROR && error->code == UDISKS_ERROR_DEVICE_BUSY)
+        error->code = G_IO_ERROR_BUSY;
+      else
+        error->code = G_IO_ERROR_FAILED;
+      error->domain = G_IO_ERROR;
+      g_dbus_error_strip_remote_error (error);
+
+      /* if the user passed in a GMountOperation, then do the GMountOperation::show-processes dance ... */
+      if (error->code == G_IO_ERROR_BUSY && data->mount_operation != NULL)
+        {
+          GArray *processes;
+          const gchar *choices[3] = {NULL, NULL, NULL};
+          const gchar *message;
+
+          /* TODO: get processes */
+          processes = get_busy_processes (udisks_filesystem_get_mount_points (filesystem));
+
+          if (data->mount_op_reply_handler_id == 0)
+            {
+              data->mount_op_reply_handler_id = g_signal_connect (data->mount_operation,
+                                                                  "reply",
+                                                                  G_CALLBACK (on_mount_op_reply),
+                                                                  data);
+            }
+          choices[0] = _("Unmount Anyway");
+          choices[1] = _("Cancel");
+          message = _("Volume is busy\n"
+                      "One or more applications are keeping the volume busy.");
+          g_signal_emit_by_name (data->mount_operation,
+                                 "show-processes",
+                                 message,
+                                 processes,
+                                 choices);
+          /* set up a timer to try unmounting every two seconds - this will also
+           * update the list of busy processes
+           */
+          if (data->retry_unmount_timer_id == 0)
+            {
+              data->retry_unmount_timer_id = g_timeout_add_seconds (2,
+                                                                    on_retry_timer_cb,
+                                                                    data);
+            }
+          goto out;
+        }
+      else
+        {
+          g_simple_async_result_take_error (data->simple, error);
+          g_simple_async_result_complete (data->simple);
+        }
+    }
+  else
+    {
+      gvfs_udisks2_volume_monitor_update (data->mount->monitor);
+      g_simple_async_result_complete (data->simple);
+    }
+
+  unmount_data_free (data);
+ out:
+  ;
+}
+
+static void
+unmount_do (UnmountData *data,
+            gboolean     force)
+{
+  UDisksBlock *block;
+  UDisksFilesystem *filesystem;
+  GVariantBuilder builder;
+
+  if (data->mount->volume != NULL)
+    {
+      block = gvfs_udisks2_volume_get_block (data->mount->volume);
+    }
+  else
+    {
+      g_simple_async_result_set_error (data->simple,
+                                       G_IO_ERROR,
+                                       G_IO_ERROR_FAILED,
+                                       "Don't know how to unmount non-udisks object yet (TODO)");
+      g_simple_async_result_complete (data->simple);
+      unmount_data_free (data);
+      goto out;
+    }
+
+  filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (block))));
+  if (filesystem == NULL)
+    {
+      g_simple_async_result_set_error (data->simple,
+                                       G_IO_ERROR,
+                                       G_IO_ERROR_FAILED,
+                                       "No filesystem interface on D-Bus object");
+      g_simple_async_result_complete (data->simple);
+      unmount_data_free (data);
+      goto out;
+    }
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+  if (data->mount_operation == NULL)
+    {
+      g_variant_builder_add (&builder,
+                             "{sv}",
+                             "auth.no_user_interaction", g_variant_new_boolean (TRUE));
+    }
+  if (force || data->flags & G_MOUNT_UNMOUNT_FORCE)
+    {
+      g_variant_builder_add (&builder,
+                             "{sv}",
+                             "force", g_variant_new_boolean (TRUE));
+    }
+  udisks_filesystem_call_unmount (filesystem,
+                                  g_variant_builder_end (&builder),
+                                  data->cancellable,
+                                  unmount_cb,
+                                  data);
+
+ out:
+  ;
+}
+
+static void
+gvfs_udisks2_mount_unmount_with_operation (GMount              *_mount,
+                                           GMountUnmountFlags   flags,
+                                           GMountOperation     *mount_operation,
+                                           GCancellable        *cancellable,
+                                           GAsyncReadyCallback  callback,
+                                           gpointer             user_data)
+{
+  GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (_mount);
+  UnmountData *data;
+
+  /* first emit the ::mount-pre-unmount signal */
+  g_signal_emit_by_name (mount->monitor, "mount-pre-unmount", mount);
+
+  data = g_new0 (UnmountData, 1);
+  data->simple = g_simple_async_result_new (G_OBJECT (mount),
+                                            callback,
+                                            user_data,
+                                            gvfs_udisks2_mount_unmount_with_operation);
+  data->mount = g_object_ref (mount);
+  data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
+  data->mount_operation = mount_operation != NULL ? g_object_ref (mount_operation) : NULL;
+  data->flags = flags;
+
+  unmount_do (data, FALSE);
+}
+
+static gboolean
+gvfs_udisks2_mount_unmount_with_operation_finish (GMount        *mount,
+                                                  GAsyncResult  *result,
+                                                  GError       **error)
+{
+  return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+static void
+gvfs_udisks2_mount_unmount (GMount              *mount,
+                            GMountUnmountFlags   flags,
+                            GCancellable        *cancellable,
+                            GAsyncReadyCallback  callback,
+                            gpointer             user_data)
+{
+  gvfs_udisks2_mount_unmount_with_operation (mount, flags, NULL, cancellable, callback, user_data);
+}
+
+static gboolean
+gvfs_udisks2_mount_unmount_finish (GMount        *mount,
+                                   GAsyncResult  *result,
+                                   GError       **error)
+{
+  return gvfs_udisks2_mount_unmount_with_operation_finish (mount, result, error);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 static void
 gvfs_udisks2_mount_mount_iface_init (GMountIface *iface)
 {
@@ -489,11 +858,11 @@ gvfs_udisks2_mount_mount_iface_init (GMountIface *iface)
   iface->get_volume = gvfs_udisks2_mount_get_volume;
   iface->can_unmount = gvfs_udisks2_mount_can_unmount;
   iface->can_eject = gvfs_udisks2_mount_can_eject;
-#if 0
   iface->unmount = gvfs_udisks2_mount_unmount;
   iface->unmount_finish = gvfs_udisks2_mount_unmount_finish;
   iface->unmount_with_operation = gvfs_udisks2_mount_unmount_with_operation;
   iface->unmount_with_operation_finish = gvfs_udisks2_mount_unmount_with_operation_finish;
+#if 0
   iface->eject = gvfs_udisks2_mount_eject;
   iface->eject_finish = gvfs_udisks2_mount_eject_finish;
   iface->eject_with_operation = gvfs_udisks2_mount_eject_with_operation;
diff --git a/monitor/udisks2/gvfsudisks2mount.h b/monitor/udisks2/gvfsudisks2mount.h
index 03b7769..dd16564 100644
--- a/monitor/udisks2/gvfsudisks2mount.h
+++ b/monitor/udisks2/gvfsudisks2mount.h
@@ -42,8 +42,6 @@ GVfsUDisks2Mount *gvfs_udisks2_mount_new            (GVfsUDisks2VolumeMonitor *m
                                                      GVfsUDisks2Volume        *volume);
 void              gvfs_udisks2_mount_unmounted      (GVfsUDisks2Mount         *mount);
 
-gboolean          gvfs_udisks2_mount_has_mount_path (GVfsUDisks2Mount         *mount,
-                                                     const gchar              *mount_path);
 gboolean          gvfs_udisks2_mount_has_uuid       (GVfsUDisks2Mount         *mount,
                                                      const gchar              *uuid);
 
@@ -52,6 +50,8 @@ void              gvfs_udisks2_mount_unset_volume   (GVfsUDisks2Mount         *m
 gboolean          gvfs_udisks2_mount_has_volume     (GVfsUDisks2Mount         *mount,
                                                      GVfsUDisks2Volume        *volume);
 
+const gchar      *gvfs_udisks2_mount_get_mount_path (GVfsUDisks2Mount         *mount);
+
 G_END_DECLS
 
 #endif /* __GVFS_UDISKS2_MOUNT_H__ */
diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c
index 8d2e0a8..440bd99 100644
--- a/monitor/udisks2/gvfsudisks2volume.c
+++ b/monitor/udisks2/gvfsudisks2volume.c
@@ -42,6 +42,11 @@ struct _GVfsUDisks2VolumeClass
   GObjectClass parent_class;
 };
 
+struct MountData;
+typedef struct MountData MountData;
+
+static void mount_cancel_pending_op (MountData *data);
+
 struct _GVfsUDisks2Volume
 {
   GObject parent;
@@ -61,6 +66,12 @@ struct _GVfsUDisks2Volume
   gchar *uuid;
   gboolean can_mount;
   gboolean should_automount;
+
+  /* If a mount operation is in progress, then pending_mount_op is != NULL. This
+   * is used to cancel the operation to make possible authentication dialogs go
+   * away.
+   */
+  MountData *mount_pending_op;
 };
 
 static void gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface);
@@ -120,7 +131,7 @@ static void
 emit_changed (GVfsUDisks2Volume *volume)
 {
   g_signal_emit_by_name (volume, "changed");
-  g_signal_emit_by_name (volume->monitor, "volume_changed", volume);
+  g_signal_emit_by_name (volume->monitor, "volume-changed", volume);
 }
 
 static UDisksDrive *
@@ -299,11 +310,8 @@ gvfs_udisks2_volume_new (GVfsUDisks2VolumeMonitor   *monitor,
 void
 gvfs_udisks2_volume_removed (GVfsUDisks2Volume *volume)
 {
-#if 0
-TODO
-  if (volume->pending_mount_op != NULL)
-    cancel_pending_mount_op (volume->pending_mount_op);
-#endif
+  if (volume->mount_pending_op != NULL)
+    mount_cancel_pending_op (volume->mount_pending_op);
 
   if (volume->mount != NULL)
     {
@@ -491,6 +499,143 @@ gvfs_udisks2_volume_get_activation_root (GVolume *_volume)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+struct MountData
+{
+  GSimpleAsyncResult *simple;
+
+  GVfsUDisks2Volume *volume;
+
+  GCancellable *cancellable;
+
+  GMountOperation *mount_operation;
+};
+
+static void
+mount_data_free (MountData *data)
+{
+  g_object_unref (data->simple);
+
+  g_clear_object (&data->volume);
+  g_clear_object (&data->cancellable);
+  g_clear_object (&data->mount_operation);
+  g_free (data);
+}
+
+static void
+mount_cancel_pending_op (MountData *data)
+{
+  g_debug ("woot, cancelling");
+  /* send an ::aborted signal to make the dialog go away */
+  if (data->mount_operation != NULL)
+    g_signal_emit_by_name (data->mount_operation, "aborted");
+  g_cancellable_cancel (data->cancellable);
+}
+
+static void
+mount_cb (GObject       *source_object,
+          GAsyncResult  *res,
+          gpointer       user_data)
+{
+  MountData *data = user_data;
+  gchar *mount_path;
+  GError *error;
+
+  /* we are no longer pending */
+  data->volume->mount_pending_op = NULL;
+
+  error = NULL;
+  if (!udisks_filesystem_call_mount_finish (UDISKS_FILESYSTEM (source_object),
+                                            &mount_path,
+                                            res,
+                                            &error))
+    {
+      g_simple_async_result_take_error (data->simple, error);
+      g_simple_async_result_complete (data->simple);
+    }
+  else
+    {
+      gvfs_udisks2_volume_monitor_update (data->volume->monitor);
+      g_simple_async_result_complete (data->simple);
+      g_free (mount_path);
+    }
+  mount_data_free (data);
+}
+
+static void
+gvfs_udisks2_volume_mount (GVolume             *_volume,
+                           GMountMountFlags     flags,
+                           GMountOperation     *mount_operation,
+                           GCancellable        *cancellable,
+                           GAsyncReadyCallback  callback,
+                           gpointer             user_data)
+{
+  GVfsUDisks2Volume *volume = GVFS_UDISKS2_VOLUME (_volume);
+  UDisksFilesystem *filesystem;
+  GVariantBuilder builder;
+  MountData *data;
+
+  data = g_new0 (MountData, 1);
+  data->simple = g_simple_async_result_new (G_OBJECT (volume),
+                                            callback,
+                                            user_data,
+                                            gvfs_udisks2_volume_mount);
+  data->volume = g_object_ref (volume);
+
+  if (volume->mount_pending_op != NULL)
+    {
+      g_simple_async_result_set_error (data->simple,
+                                       G_IO_ERROR,
+                                       G_IO_ERROR_FAILED,
+                                       "A mount operation is already pending");
+      g_simple_async_result_complete (data->simple);
+      mount_data_free (data);
+      goto out;
+    }
+
+  filesystem = udisks_object_peek_filesystem (UDISKS_OBJECT (g_dbus_interface_get_object (G_DBUS_INTERFACE (volume->block))));
+  if (filesystem == NULL)
+    {
+      g_simple_async_result_set_error (data->simple,
+                                       G_IO_ERROR,
+                                       G_IO_ERROR_FAILED,
+                                       "No filesystem interface on D-Bus object");
+      g_simple_async_result_complete (data->simple);
+      mount_data_free (data);
+      goto out;
+    }
+
+  data->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL;
+  data->mount_operation = mount_operation != NULL ? g_object_ref (mount_operation) : NULL;
+  volume->mount_pending_op = data;
+
+  g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
+  if (data->mount_operation == NULL)
+    {
+      g_variant_builder_add (&builder,
+                             "{sv}",
+                             "auth.no_user_interaction", g_variant_new_boolean (TRUE));
+    }
+  udisks_filesystem_call_mount (filesystem,
+                                g_variant_builder_end (&builder),
+                                data->cancellable,
+                                mount_cb,
+                                data);
+
+ out:
+  ;
+}
+
+static gboolean
+gvfs_udisks2_volume_mount_finish (GVolume       *volume,
+                                  GAsyncResult  *result,
+                                  GError       **error)
+{
+  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+  return !g_simple_async_result_propagate_error (simple, error);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 static void
 gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface)
 {
@@ -506,9 +651,9 @@ gvfs_udisks2_volume_volume_iface_init (GVolumeIface *iface)
   iface->enumerate_identifiers = gvfs_udisks2_volume_enumerate_identifiers;
   iface->get_identifier = gvfs_udisks2_volume_get_identifier;
 
-#if 0
   iface->mount_fn = gvfs_udisks2_volume_mount;
   iface->mount_finish = gvfs_udisks2_volume_mount_finish;
+#if 0
   iface->eject = gvfs_udisks2_volume_eject;
   iface->eject_finish = gvfs_udisks2_volume_eject_finish;
   iface->eject_with_operation = gvfs_udisks2_volume_eject_with_operation;
diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.c b/monitor/udisks2/gvfsudisks2volumemonitor.c
index 0b14f2e..4c2df40 100644
--- a/monitor/udisks2/gvfsudisks2volumemonitor.c
+++ b/monitor/udisks2/gvfsudisks2volumemonitor.c
@@ -275,7 +275,7 @@ get_mount_for_mount_path (const gchar  *mount_path,
       for (l = monitor->mounts; l != NULL; l = l->next)
         {
           GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (l->data);
-          if (gvfs_udisks2_mount_has_mount_path (mount, mount_path))
+          if (g_strcmp0 (gvfs_udisks2_mount_get_mount_path (mount), mount_path) == 0)
             {
               ret = g_object_ref (mount);
               goto out;
@@ -397,6 +397,16 @@ gvfs_udisks2_volume_monitor_get_udisks_client (GVfsUDisks2VolumeMonitor *monitor
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+void
+gvfs_udisks2_volume_monitor_update (GVfsUDisks2VolumeMonitor *monitor)
+{
+  g_return_if_fail (GVFS_IS_UDISKS2_VOLUME_MONITOR (monitor));
+  udisks_client_settle (monitor->client);
+  update_all (monitor, TRUE);
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 static UDisksClient *
 get_udisks_client_sync (GError **error)
 {
@@ -809,7 +819,7 @@ find_mount_by_mount_path (GVfsUDisks2VolumeMonitor *monitor,
   for (l = monitor->mounts; l != NULL; l = l->next)
     {
       GVfsUDisks2Mount *mount = GVFS_UDISKS2_MOUNT (l->data);
-      if (gvfs_udisks2_mount_has_mount_path (mount, mount_path))
+      if (g_strcmp0 (gvfs_udisks2_mount_get_mount_path (mount), mount_path) == 0)
         {
           ret = mount;
           goto out;
@@ -1034,6 +1044,7 @@ update_mounts (GVfsUDisks2VolumeMonitor  *monitor,
           gvfs_udisks2_mount_unmounted (mount);
           monitor->mounts = g_list_remove (monitor->mounts, mount);
           *removed_mounts = g_list_prepend (*removed_mounts, g_object_ref (mount));
+          g_debug ("removed mount at %s", gvfs_udisks2_mount_get_mount_path (mount));
           g_object_unref (mount);
         }
     }
@@ -1050,6 +1061,7 @@ update_mounts (GVfsUDisks2VolumeMonitor  *monitor,
         {
           monitor->mounts = g_list_prepend (monitor->mounts, mount);
           *added_mounts = g_list_prepend (*added_mounts, g_object_ref (mount));
+          g_debug ("added mount at %s for %p", gvfs_udisks2_mount_get_mount_path (mount), volume);
         }
     }
 
diff --git a/monitor/udisks2/gvfsudisks2volumemonitor.h b/monitor/udisks2/gvfsudisks2volumemonitor.h
index a152743..c08d58e 100644
--- a/monitor/udisks2/gvfsudisks2volumemonitor.h
+++ b/monitor/udisks2/gvfsudisks2volumemonitor.h
@@ -46,6 +46,7 @@ typedef struct _GVfsUDisks2Mount GVfsUDisks2Mount;
 GType           gvfs_udisks2_volume_monitor_get_type          (void) G_GNUC_CONST;
 GVolumeMonitor *gvfs_udisks2_volume_monitor_new               (void);
 UDisksClient   *gvfs_udisks2_volume_monitor_get_udisks_client (GVfsUDisks2VolumeMonitor *monitor);
+void            gvfs_udisks2_volume_monitor_update            (GVfsUDisks2VolumeMonitor *monitor);
 
 G_END_DECLS
 



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