rpms/gvfs/devel gdu-0010-show-user-mountable-fstab-entries.patch, NONE, 1.1 gdu-0011-Bug-576083-pre-unmount-signals-not-being-trigger.patch, NONE, 1.1 gdu-0012-use-new-gnome-disk-utility-API-to-hide-unwanted-devi.patch, NONE, 1.1 gdu-0013-pass-the-flush-mount-option-for-vfat.patch, NONE, 1.1 gvfs.spec, 1.125, 1.126

David Zeuthen davidz at fedoraproject.org
Wed Apr 15 19:25:26 UTC 2009


Author: davidz

Update of /cvs/pkgs/rpms/gvfs/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18627

Modified Files:
	gvfs.spec 
Added Files:
	gdu-0010-show-user-mountable-fstab-entries.patch 
	gdu-0011-Bug-576083-pre-unmount-signals-not-being-trigger.patch 
	gdu-0012-use-new-gnome-disk-utility-API-to-hide-unwanted-devi.patch 
	gdu-0013-pass-the-flush-mount-option-for-vfat.patch 
Log Message:
* Wed Apr 15 2009 David Zeuthen <davidz at redhat.com> - 1.2.2-3
- Sync with the gdu-volume-monitor branch



gdu-0010-show-user-mountable-fstab-entries.patch:

--- NEW FILE gdu-0010-show-user-mountable-fstab-entries.patch ---
>From 0f7a44dd0eac01f9783879af4ca3d3fe4a53af14 Mon Sep 17 00:00:00 2001
From: David Zeuthen <davidz at redhat.com>
Date: Mon, 13 Apr 2009 10:57:38 -0400
Subject: [PATCH 10/13] show user-mountable fstab entries

Show all entries from /etc/fstab for which

 - the entry is user mountable
 - the mount point is in /media or $HOME
 - if it's a /dev file make sure it exists and is not handled
   by DeviceKit-disks already

For example this /etc/fstab entry

 "quad.local:/media/FusionMedia /media/FusionMedia nfs defaults,users     0 0"

makes Nautilus display this when unmounted

 http://people.freedesktop.org/~david/gvfs-user-mountable-fstab-entries.png

and these GVolume and GMount objects to appear when mounted

 Volume(0): FusionMedia
   Type: GProxyVolume (GProxyVolumeMonitorGdu)
   themed icons:  [folder-remote]  [folder]
   can_mount=1
   can_eject=0
   Mount(0): FusionMedia -> file:///media/FusionMedia
     Type: GProxyMount (GProxyVolumeMonitorGdu)
     themed icons:  [folder-remote]  [folder]
     can_unmount=1
     can_eject=0
     is_shadowed=0

This should resolve http://bugzilla.gnome.org/show_bug.cgi?id=536292
---
 monitor/gdu/ggdumount.c         |   29 +++-
 monitor/gdu/ggduvolume.c        |  374 ++++++++++++++++++++++++++++++++++++---
 monitor/gdu/ggduvolume.h        |    7 +-
 monitor/gdu/ggduvolumemonitor.c |  174 ++++++++++++++++++-
 4 files changed, 548 insertions(+), 36 deletions(-)

diff --git a/monitor/gdu/ggdumount.c b/monitor/gdu/ggdumount.c
index 27c22d9..e074a20 100644
--- a/monitor/gdu/ggdumount.c
+++ b/monitor/gdu/ggdumount.c
@@ -696,8 +696,13 @@ g_gdu_mount_unmount (GMount              *_mount,
 {
   GGduMount *mount = G_GDU_MOUNT (_mount);
   GSimpleAsyncResult *simple;
+  GduPresentable *gdu_volume;
 
-  if (mount->volume == NULL)
+  gdu_volume = NULL;
+  if (mount->volume != NULL)
+    gdu_volume = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
+
+  if (mount->volume == NULL || gdu_volume == NULL)
     {
       gchar *argv[] = {"umount", NULL, NULL};
 
@@ -710,7 +715,7 @@ g_gdu_mount_unmount (GMount              *_mount,
 
       eject_unmount_do (_mount, cancellable, callback, user_data, argv);
     }
-  else
+  else if (gdu_volume != NULL)
     {
       simple = g_simple_async_result_new (G_OBJECT (mount),
                                           callback,
@@ -726,18 +731,25 @@ g_gdu_mount_unmount (GMount              *_mount,
       else
         {
           GduDevice *device;
-          GduPresentable *volume;
 
           /* TODO: honor flags */
 
-          volume = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
-          device = gdu_presentable_get_device (volume);
-
+          device = gdu_presentable_get_device (gdu_volume);
           gdu_device_op_filesystem_unmount (device, unmount_cb, simple);
-
           g_object_unref (device);
         }
     }
+  else
+    {
+      simple = g_simple_async_result_new_error (G_OBJECT (mount),
+                                                callback,
+                                                user_data,
+                                                G_IO_ERROR,
+                                                G_IO_ERROR_FAILED,
+                                                _("Operation not supported by backend"));
+      g_simple_async_result_complete (simple);
+      g_object_unref (simple);
+    }
 }
 
 static gboolean
@@ -855,7 +867,8 @@ g_gdu_mount_guess_content_type_sync (GMount              *_mount,
     {
       GduPresentable *presentable;
       presentable = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
-      device = gdu_presentable_get_device (presentable);
+      if (presentable != NULL)
+        device = gdu_presentable_get_device (presentable);
     }
 
   /* doesn't make sense to probe blank discs - look at the disc type instead */
diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c
index 6779f0f..49494a1 100644
--- a/monitor/gdu/ggduvolume.c
+++ b/monitor/gdu/ggduvolume.c
@@ -35,12 +35,22 @@
 #include "ggduvolume.h"
 #include "ggdumount.h"
 
+/* for BUFSIZ */
+#include <stdio.h>
+
 #include "polkit.h"
 
 typedef struct MountOpData MountOpData;
 
 static void cancel_pending_mount_op (MountOpData *data);
 
+static void g_gdu_volume_mount_unix_mount_point (GGduVolume          *volume,
+                                                 GMountMountFlags     flags,
+                                                 GMountOperation     *mount_operation,
+                                                 GCancellable        *cancellable,
+                                                 GAsyncReadyCallback  callback,
+                                                 gpointer             user_data);
+
 struct _GGduVolume
 {
   GObject parent;
@@ -49,8 +59,12 @@ struct _GGduVolume
   GGduMount      *mount;          /* owned by volume monitor */
   GGduDrive      *drive;          /* owned by volume monitor */
 
+  /* only set if constructed via new() */
   GduVolume *gdu_volume;
 
+  /* only set if constructed via new_for_unix_mount_point() */
+  GUnixMountPoint *unix_mount_point;
+
   /* if the volume is encrypted, this is != NULL when unlocked */
   GduVolume *cleartext_gdu_volume;
 
@@ -60,7 +74,7 @@ struct _GGduVolume
    */
   MountOpData *pending_mount_op;
 
-  /* the following members need to be set upon construction */
+  /* the following members need to be set upon construction, see constructors and update_volume() */
   GIcon *icon;
   GFile *activation_root;
   gchar *name;
@@ -110,6 +124,11 @@ g_gdu_volume_finalize (GObject *object)
       g_object_unref (volume->gdu_volume);
     }
 
+  if (volume->unix_mount_point != NULL)
+    {
+      g_unix_mount_point_free (volume->unix_mount_point);
+    }
+
   if (volume->cleartext_gdu_volume != NULL)
     {
       g_signal_handlers_disconnect_by_func (volume->cleartext_gdu_volume, gdu_cleartext_volume_removed, volume);
@@ -174,6 +193,30 @@ update_volume (GGduVolume *volume)
 
   /* ---------------------------------------------------------------------------------------------------- */
 
+  /* if the volume is a fstab mount point, get the data from there */
+  if (volume->unix_mount_point != NULL)
+    {
+      volume->can_mount = TRUE;
+      volume->should_automount = FALSE;
+
+      g_free (volume->device_file);
+      volume->device_file = g_strdup (g_unix_mount_point_get_device_path (volume->unix_mount_point));
+
+      if (volume->icon != NULL)
+        g_object_unref (volume->icon);
+      if (g_strcmp0 (g_unix_mount_point_get_fs_type (volume->unix_mount_point), "nfs") == 0)
+        volume->icon = g_themed_icon_new_with_default_fallbacks ("folder-remote");
+      else
+        volume->icon = g_unix_mount_point_guess_icon (volume->unix_mount_point);
+
+      g_free (volume->name);
+      volume->name = g_unix_mount_point_guess_name (volume->unix_mount_point);
+
+      //volume->can_eject = g_unix_mount_point_guess_can_eject (volume->unix_mount_point);
+
+      goto update_done;
+    }
+
   /* in with the new */
   device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
   pool = gdu_device_get_pool (device);
@@ -347,6 +390,8 @@ update_volume (GGduVolume *volume)
 
   /* ---------------------------------------------------------------------------------------------------- */
 
+ update_done:
+
   /* compute whether something changed */
   changed = !((old_can_mount == volume->can_mount) &&
               (old_should_automount == volume->should_automount) &&
@@ -412,6 +457,23 @@ gdu_cleartext_volume_job_changed (GduPresentable *presentable,
 }
 
 GGduVolume *
+g_gdu_volume_new_for_unix_mount_point (GVolumeMonitor   *volume_monitor,
+                                       GUnixMountPoint  *unix_mount_point)
+{
+  GGduVolume *volume;
+
+  volume = g_object_new (G_TYPE_GDU_VOLUME, NULL);
+  volume->volume_monitor = volume_monitor;
+  g_object_add_weak_pointer (G_OBJECT (volume_monitor), (gpointer) &(volume->volume_monitor));
+
+  volume->unix_mount_point = unix_mount_point;
+
+  update_volume (volume);
+
+  return volume;
+}
+
+GGduVolume *
 g_gdu_volume_new (GVolumeMonitor   *volume_monitor,
                   GduVolume        *gdu_volume,
                   GGduDrive        *drive,
@@ -1084,6 +1146,18 @@ g_gdu_volume_mount (GVolume             *_volume,
   pool = NULL;
   device = NULL;
 
+  /* for fstab mounts, call the native mount command */
+  if (volume->unix_mount_point != NULL)
+    {
+      g_gdu_volume_mount_unix_mount_point (volume,
+                                           flags,
+                                           mount_operation,
+                                           cancellable,
+                                           callback,
+                                           user_data);
+      goto out;
+    }
+
   if (volume->pending_mount_op != NULL)
     {
       simple = g_simple_async_result_new_error (G_OBJECT (volume),
@@ -1204,7 +1278,7 @@ g_gdu_volume_mount_finish (GVolume       *volume,
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
 
-  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_gdu_volume_mount);
+  //g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_gdu_volume_mount);
 
   return !g_simple_async_result_propagate_error (simple, error);
 }
@@ -1212,6 +1286,247 @@ g_gdu_volume_mount_finish (GVolume       *volume,
 /* ---------------------------------------------------------------------------------------------------- */
 
 typedef struct {
+  GGduVolume *volume;
+  GAsyncReadyCallback callback;
+  gpointer user_data;
+  GCancellable *cancellable;
+  int error_fd;
+  GIOChannel *error_channel;
+  guint error_channel_source_id;
+  GString *error_string;
+
+  guint wait_for_mount_timeout_id;
+  gulong wait_for_mount_changed_signal_handler_id;
+} MountPointOp;
+
+static void
+mount_point_op_free (MountPointOp *data)
+{
+  if (data->error_channel_source_id > 0)
+    g_source_remove (data->error_channel_source_id);
+  if (data->error_channel != NULL)
+    g_io_channel_unref (data->error_channel);
+  if (data->error_string != NULL)
+    g_string_free (data->error_string, TRUE);
+  if (data->error_fd > 0)
+    close (data->error_fd);
+  g_free (data);
+}
+
+static void
+mount_point_op_changed_cb (GVolume *volume,
+                           gpointer user_data)
+{
+  MountPointOp *data = user_data;
+  GSimpleAsyncResult *simple;
+
+  /* keep waiting if the mount hasn't appeared */
+  if (data->volume->mount == NULL)
+    goto out;
+
+  simple = g_simple_async_result_new (G_OBJECT (data->volume),
+                                      data->callback,
+                                      data->user_data,
+                                      NULL);
+  /* complete in idle to make sure the mount is added before we return */
+  g_simple_async_result_complete_in_idle (simple);
+  g_object_unref (simple);
+
+  g_signal_handler_disconnect (data->volume, data->wait_for_mount_changed_signal_handler_id);
+  g_source_remove (data->wait_for_mount_timeout_id);
+
+  mount_point_op_free (data);
+
+ out:
+  ;
+}
+
+static gboolean
+mount_point_op_never_appeared_cb (gpointer user_data)
+{
+  MountPointOp *data = user_data;
+  GSimpleAsyncResult *simple;
+
+  simple = g_simple_async_result_new_error (G_OBJECT (data->volume),
+                                            data->callback,
+                                            data->user_data,
+                                            G_IO_ERROR,
+                                            G_IO_ERROR_FAILED,
+                                            "Timeout waiting for mount to appear");
+  g_simple_async_result_complete (simple);
+  g_object_unref (simple);
+
+  g_signal_handler_disconnect (data->volume, data->wait_for_mount_changed_signal_handler_id);
+  g_source_remove (data->wait_for_mount_timeout_id);
+
+  mount_point_op_free (data);
+
+  return FALSE;
+}
+
+static void
+mount_point_op_cb (GPid pid, gint status, gpointer user_data)
+{
+  MountPointOp *data = user_data;
+  GSimpleAsyncResult *simple;
+
+  g_spawn_close_pid (pid);
+
+  if (WEXITSTATUS (status) != 0)
+    {
+      GError *error;
+      error = g_error_new_literal (G_IO_ERROR,
+                                   G_IO_ERROR_FAILED,
+                                   data->error_string->str);
+      simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume),
+                                                     data->callback,
+                                                     data->user_data,
+                                                     error);
+      g_error_free (error);
+      g_simple_async_result_complete (simple);
+      g_object_unref (simple);
+      mount_point_op_free (data);
+    }
+  else
+    {
+      /* wait for the GMount to appear - this is to honor this requirement
+       *
+       *  "If the mount operation succeeded, g_volume_get_mount() on
+       *   volume is guaranteed to return the mount right after calling
+       *   this function; there's no need to listen for the
+       *   'mount-added' signal on GVolumeMonitor."
+       *
+       * So we set up a signal handler waiting for it to appear. We also set up
+       * a timer for handling the case when it never appears.
+       */
+      if (data->volume->mount == NULL)
+        {
+          /* no need to ref, GSimpleAsyncResult has a ref on data->volume */
+          data->wait_for_mount_timeout_id = g_timeout_add (5 * 1000,
+                                            mount_point_op_never_appeared_cb,
+                                            data);
+          data->wait_for_mount_changed_signal_handler_id = g_signal_connect (data->volume,
+                                                                             "changed",
+                                                                             G_CALLBACK (mount_point_op_changed_cb),
+                                                                             data);
+        }
+      else
+        {
+          /* have the mount already, finish up */
+          simple = g_simple_async_result_new (G_OBJECT (data->volume),
+                                              data->callback,
+                                              data->user_data,
+                                              NULL);
+          g_simple_async_result_complete (simple);
+          g_object_unref (simple);
+          mount_point_op_free (data);
+        }
+    }
+}
+
+static gboolean
+mount_point_op_read_error (GIOChannel *channel,
+                           GIOCondition condition,
+                           gpointer user_data)
+{
+  MountPointOp *data = user_data;
+  gchar buf[BUFSIZ];
+  gsize bytes_read;
+  GError *error;
+  GIOStatus status;
+
+  error = NULL;
+read:
+  status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error);
+  if (status == G_IO_STATUS_NORMAL)
+   {
+     g_string_append_len (data->error_string, buf, bytes_read);
+     if (bytes_read == sizeof (buf))
+        goto read;
+   }
+  else if (status == G_IO_STATUS_EOF)
+    {
+      g_string_append_len (data->error_string, buf, bytes_read);
+    }
+  else if (status == G_IO_STATUS_ERROR)
+    {
+      if (data->error_string->len > 0)
+        g_string_append (data->error_string, "\n");
+
+      g_string_append (data->error_string, error->message);
+      g_error_free (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+g_gdu_volume_mount_unix_mount_point (GGduVolume          *volume,
+                                     GMountMountFlags     flags,
+                                     GMountOperation     *mount_operation,
+                                     GCancellable        *cancellable,
+                                     GAsyncReadyCallback  callback,
+                                     gpointer             user_data)
+{
+  MountPointOp *data;
+  GPid child_pid;
+  GError *error;
+  const gchar *argv[] = {"mount", NULL, NULL};
+
+  argv[1] = g_unix_mount_point_get_mount_path (volume->unix_mount_point);
+
+  data = g_new0 (MountPointOp, 1);
+  data->volume = volume;
+  data->callback = callback;
+  data->user_data = user_data;
+  data->cancellable = cancellable;
+
+  error = NULL;
+  if (!g_spawn_async_with_pipes (NULL,         /* working dir */
+                                 (gchar **) argv,
+                                 NULL,         /* envp */
+                                 G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
+                                 NULL,         /* child_setup */
+                                 NULL,         /* user_data for child_setup */
+                                 &child_pid,
+                                 NULL,         /* standard_input */
+                                 NULL,         /* standard_output */
+                                 &(data->error_fd),
+                                 &error))
+    {
+      g_assert (error != NULL);
+      goto handle_error;
+    }
+
+  data->error_string = g_string_new ("");
+
+  data->error_channel = g_io_channel_unix_new (data->error_fd);
+  g_io_channel_set_flags (data->error_channel, G_IO_FLAG_NONBLOCK, &error);
+  if (error != NULL)
+    goto handle_error;
+
+  data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, mount_point_op_read_error, data);
+  g_child_watch_add (child_pid, mount_point_op_cb, data);
+
+handle_error:
+  if (error != NULL)
+    {
+      GSimpleAsyncResult *simple;
+      simple = g_simple_async_result_new_from_error (G_OBJECT (data->volume),
+                                                     data->callback,
+                                                     data->user_data,
+                                                     error);
+      g_simple_async_result_complete (simple);
+      g_object_unref (simple);
+
+      mount_point_op_free (data);
+    }
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
+typedef struct {
   GObject *object;
   GAsyncReadyCallback callback;
   gpointer user_data;
@@ -1300,19 +1615,22 @@ g_gdu_volume_get_identifier (GVolume     *_volume,
 
   id = NULL;
 
-  device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
+  if (volume->gdu_volume != NULL)
+    {
+      device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
 
-  label = gdu_device_id_get_label (device);
-  uuid = gdu_device_id_get_uuid (device);
+      label = gdu_device_id_get_label (device);
+      uuid = gdu_device_id_get_uuid (device);
 
-  g_object_unref (device);
+      g_object_unref (device);
 
-  if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0)
-    id = g_strdup (volume->device_file);
-  else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_LABEL) == 0)
-    id = strlen (label) > 0 ? g_strdup (label) : NULL;
-  else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0)
-    id = strlen (uuid) > 0 ? g_strdup (uuid) : NULL;
+      if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE) == 0)
+        id = g_strdup (volume->device_file);
+      else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_LABEL) == 0)
+        id = strlen (label) > 0 ? g_strdup (label) : NULL;
+      else if (strcmp (kind, G_VOLUME_IDENTIFIER_KIND_UUID) == 0)
+        id = strlen (uuid) > 0 ? g_strdup (uuid) : NULL;
+    }
 
   return id;
 }
@@ -1326,19 +1644,21 @@ g_gdu_volume_enumerate_identifiers (GVolume *_volume)
   const gchar *label;
   const gchar *uuid;
 
-  device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
-
-  label = gdu_device_id_get_label (device);
-  uuid = gdu_device_id_get_uuid (device);
-
-  g_object_unref (device);
-
   p = g_ptr_array_new ();
-  g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
-  if (strlen (label) > 0)
-    g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL));
-  if (strlen (uuid) > 0)
-    g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID));
+
+  if (volume->gdu_volume != NULL)
+    {
+      device = gdu_presentable_get_device (GDU_PRESENTABLE (volume->gdu_volume));
+      label = gdu_device_id_get_label (device);
+      uuid = gdu_device_id_get_uuid (device);
+      g_object_unref (device);
+
+      g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE));
+      if (strlen (label) > 0)
+        g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_LABEL));
+      if (strlen (uuid) > 0)
+        g_ptr_array_add (p, g_strdup (G_VOLUME_IDENTIFIER_KIND_UUID));
+    }
 
   g_ptr_array_add (p, NULL);
 
@@ -1452,3 +1772,9 @@ g_gdu_volume_get_presentable_with_cleartext (GGduVolume *volume)
 
   return GDU_PRESENTABLE (ret);
 }
+
+GUnixMountPoint *
+g_gdu_volume_get_unix_mount_point (GGduVolume *volume)
+{
+  return volume->unix_mount_point;
+}
diff --git a/monitor/gdu/ggduvolume.h b/monitor/gdu/ggduvolume.h
index 8fd7358..a230d28 100644
--- a/monitor/gdu/ggduvolume.h
+++ b/monitor/gdu/ggduvolume.h
@@ -50,6 +50,9 @@ GGduVolume *g_gdu_volume_new            (GVolumeMonitor   *volume_monitor,
                                          GGduDrive        *drive,
                                          GFile            *activation_root);
 
+GGduVolume *g_gdu_volume_new_for_unix_mount_point (GVolumeMonitor   *volume_monitor,
+                                                   GUnixMountPoint  *unix_mount_point);
+
 void        g_gdu_volume_set_mount      (GGduVolume       *volume,
                                          GGduMount        *mount);
 void        g_gdu_volume_unset_mount    (GGduVolume       *volume,
@@ -69,10 +72,12 @@ gboolean    g_gdu_volume_has_uuid       (GGduVolume       *volume,
 gboolean   g_gdu_volume_has_device_file (GGduVolume      *volume,
                                          const gchar     *device_file);
 
-GduPresentable *g_gdu_volume_get_presentable (GGduVolume      *volume);
+GduPresentable *g_gdu_volume_get_presentable (GGduVolume *volume);
 
 GduPresentable *g_gdu_volume_get_presentable_with_cleartext (GGduVolume *volume);
 
+GUnixMountPoint *g_gdu_volume_get_unix_mount_point (GGduVolume *volume);
+
 G_END_DECLS
 
 #endif /* __G_GDU_VOLUME_H__ */
diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
index caa25a0..67e2ec0 100644
--- a/monitor/gdu/ggduvolumemonitor.c
+++ b/monitor/gdu/ggduvolumemonitor.c
@@ -51,6 +51,7 @@ struct _GGduVolumeMonitor {
 
   GList *drives;
   GList *volumes;
+  GList *fstab_volumes;
   GList *mounts;
 
   /* we keep volumes/mounts for blank and audio discs separate to handle e.g. mixed discs properly */
@@ -80,6 +81,9 @@ static void update_drives            (GGduVolumeMonitor *monitor,
 static void update_volumes           (GGduVolumeMonitor *monitor,
                                       GList **added_volumes,
                                       GList **removed_volumes);
+static void update_fstab_volumes     (GGduVolumeMonitor *monitor,
+                                      GList **added_volumes,
+                                      GList **removed_volumes);
 static void update_mounts            (GGduVolumeMonitor *monitor,
                                       GList **added_mounts,
                                       GList **removed_mounts);
@@ -135,6 +139,7 @@ g_gdu_volume_monitor_finalize (GObject *object)
   g_list_free (monitor->last_mounts);
 
   list_free (monitor->drives);
+  list_free (monitor->fstab_volumes);
   list_free (monitor->volumes);
   list_free (monitor->mounts);
 
@@ -171,6 +176,8 @@ get_volumes (GVolumeMonitor *volume_monitor)
   monitor = G_GDU_VOLUME_MONITOR (volume_monitor);
 
   l = g_list_copy (monitor->volumes);
+  ll = g_list_copy (monitor->fstab_volumes);
+  l = g_list_concat (l, ll);
   ll = g_list_copy (monitor->disc_volumes);
   l = g_list_concat (l, ll);
 
@@ -211,6 +218,13 @@ get_volume_for_uuid (GVolumeMonitor *volume_monitor, const char *uuid)
         goto found;
     }
 
+  for (l = monitor->fstab_volumes; l != NULL; l = l->next)
+    {
+      volume = l->data;
+      if (g_gdu_volume_has_uuid (volume, uuid))
+        goto found;
+    }
+
   for (l = monitor->disc_volumes; l != NULL; l = l->next)
     {
       volume = l->data;
@@ -549,14 +563,49 @@ find_volume_for_mount_path (GGduVolumeMonitor *monitor,
   for (l = monitor->volumes; l != NULL; l = l->next)
     {
       GGduVolume *volume = l->data;
+      if (g_gdu_volume_has_mount_path (volume, mount_path))
+        {
+          found = volume;
+          goto out;
+        }
+    }
 
+  for (l = monitor->fstab_volumes; l != NULL; l = l->next)
+    {
+      GGduVolume *volume = l->data;
       if (g_gdu_volume_has_mount_path (volume, mount_path))
         {
           found = volume;
-          break;
+          goto out;
         }
     }
 
+ out:
+  return found;
+}
+
+static GGduVolume *
+find_volume_for_unix_mount_point (GGduVolumeMonitor *monitor,
+                                  GUnixMountPoint   *unix_mount_point)
+{
+  GList *l;
+  GGduVolume *found;
+
+  found = NULL;
+  for (l = monitor->fstab_volumes; l != NULL; l = l->next)
+    {
+      GGduVolume *volume = l->data;
+      GUnixMountPoint *volume_mount_point;
+
+      volume_mount_point = g_gdu_volume_get_unix_mount_point (volume);
+      if (g_unix_mount_point_compare (unix_mount_point, volume_mount_point) == 0)
+        {
+          found = volume;
+          goto out;
+        }
+    }
+
+ out:
   return found;
 }
 
@@ -859,6 +908,7 @@ update_all (GGduVolumeMonitor *monitor,
 
   update_drives (monitor, &added_drives, &removed_drives);
   update_volumes (monitor, &added_volumes, &removed_volumes);
+  update_fstab_volumes (monitor, &added_volumes, &removed_volumes);
   update_mounts (monitor, &added_mounts, &removed_mounts);
   update_discs (monitor,
                 &added_volumes, &removed_volumes,
@@ -935,16 +985,34 @@ find_volume_for_device_file (GGduVolumeMonitor *monitor,
                             const gchar       *device_file)
 {
   GList *l;
+  GGduVolume *ret;
 
+  ret = NULL;
   for (l = monitor->volumes; l != NULL; l = l->next)
     {
       GGduVolume *volume = G_GDU_VOLUME (l->data);
 
       if (g_gdu_volume_has_device_file (volume, device_file))
-        return volume;
+        {
+          ret = volume;
+          goto out;
+        }
     }
 
-  return NULL;
+  ret = NULL;
+  for (l = monitor->fstab_volumes; l != NULL; l = l->next)
+    {
+      GGduVolume *volume = G_GDU_VOLUME (l->data);
+
+      if (g_gdu_volume_has_device_file (volume, device_file))
+        {
+          ret = volume;
+          goto out;
+        }
+    }
+
+ out:
+  return ret;
 }
 
 static GGduDrive *
@@ -1189,6 +1257,106 @@ update_volumes (GGduVolumeMonitor *monitor,
 }
 
 static void
+update_fstab_volumes (GGduVolumeMonitor *monitor,
+                      GList **added_volumes,
+                      GList **removed_volumes)
+{
+  GList *fstab_mount_points;
+  GList *cur_fstab_mount_points;
+  GList *new_fstab_mount_points;
+  GList *removed, *added;
+  GList *l;
+  GGduVolume *volume;
+
+  fstab_mount_points = g_unix_mount_points_get (NULL);
+
+  cur_fstab_mount_points = NULL;
+  for (l = monitor->fstab_volumes; l != NULL; l = l->next)
+    cur_fstab_mount_points = g_list_prepend (cur_fstab_mount_points, g_gdu_volume_get_unix_mount_point (G_GDU_VOLUME (l->data)));
+
+  new_fstab_mount_points = NULL;
+  for (l = fstab_mount_points; l != NULL; l = l->next)
+    {
+      GUnixMountPoint *mount_point = l->data;
+      const gchar *device_file;
+
+      /* only show user mountable mount points */
+      if (!g_unix_mount_point_is_user_mountable (mount_point))
+        continue;
+
+      /* only show stuff that can be mounted in user-visible locations */
+      if (!_g_unix_mount_point_guess_should_display (mount_point))
+        continue;
+
+      /* ignore mount point if the device doesn't exist or is handled by DeviceKit-disks */
+      device_file = g_unix_mount_point_get_device_path (mount_point);
+      if (g_str_has_prefix (device_file, "/dev/"))
+        {
+          gchar resolved_path[PATH_MAX];
+          GduDevice *device;
+
+          /* doesn't exist */
+          if (realpath (device_file, resolved_path) != 0)
+            continue;
+
+          /* is handled by DKD */
+          device = gdu_pool_get_by_device_file (monitor->pool, resolved_path);
+          if (device != NULL)
+            {
+              g_object_unref (device);
+              continue;
+            }
+        }
+
+      new_fstab_mount_points = g_list_prepend (new_fstab_mount_points, mount_point);
+    }
+
+  diff_sorted_lists (cur_fstab_mount_points,
+                     new_fstab_mount_points, (GCompareFunc) g_unix_mount_point_compare,
+                     &added, &removed);
+
+  for (l = removed; l != NULL; l = l->next)
+    {
+      GUnixMountPoint *mount_point = l->data;
+      volume = find_volume_for_unix_mount_point (monitor, mount_point);
+      if (volume != NULL)
+        {
+          g_gdu_volume_removed (volume);
+          monitor->fstab_volumes = g_list_remove (monitor->fstab_volumes, volume);
+          *removed_volumes = g_list_prepend (*removed_volumes, volume);
+          /*g_debug ("removed volume for /etc/fstab mount point %s", g_unix_mount_point_get_mount_path (mount_point));*/
+        }
+    }
+
+  for (l = added; l != NULL; l = l->next)
+    {
+      GUnixMountPoint *mount_point = l->data;
+
+      volume = g_gdu_volume_new_for_unix_mount_point (G_VOLUME_MONITOR (monitor), mount_point);
+      if (volume != NULL)
+        {
+          /* steal mount_point since g_gdu_volume_new_for_unix_mount_point() takes ownership of it */
+          fstab_mount_points = g_list_remove (fstab_mount_points, mount_point);
+          monitor->fstab_volumes = g_list_prepend (monitor->fstab_volumes, volume);
+          *added_volumes = g_list_prepend (*added_volumes, g_object_ref (volume));
+          /*g_debug ("added volume for /etc/fstab mount point %s", g_unix_mount_point_get_mount_path (mount_point));*/
+        }
+      else
+        {
+          g_unix_mount_point_free (mount_point);
+        }
+    }
+
+  g_list_free (added);
+  g_list_free (removed);
+
+  g_list_free (cur_fstab_mount_points);
+
+  g_list_foreach (fstab_mount_points, (GFunc) g_unix_mount_point_free, NULL);
+  g_list_free (fstab_mount_points);
+}
+
+static void
 update_mounts (GGduVolumeMonitor *monitor,
                GList **added_mounts,
                GList **removed_mounts)
-- 
1.6.2.2


gdu-0011-Bug-576083-pre-unmount-signals-not-being-trigger.patch:

--- NEW FILE gdu-0011-Bug-576083-pre-unmount-signals-not-being-trigger.patch ---
>From 8d9fc8a777fb1b00ae371e276a14416a0987f4af Mon Sep 17 00:00:00 2001
From: David Zeuthen <davidz at redhat.com>
Date: Mon, 13 Apr 2009 14:20:15 -0400
Subject: [PATCH 11/13] =?utf-8?q?Bug=20576083=20=E2=80=93=20pre-unmount=20signals=20not=20being=20triggered?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

Basically emit GVolumeMonitor::mount-pre-unmount on the volume monitor
and retry unmount operation a couple of times.
---
 monitor/gdu/ggdumount.c |  177 +++++++++++++++++++++++++++++++++++++---------
 1 files changed, 142 insertions(+), 35 deletions(-)

diff --git a/monitor/gdu/ggdumount.c b/monitor/gdu/ggdumount.c
index e074a20..78088d5 100644
--- a/monitor/gdu/ggdumount.c
+++ b/monitor/gdu/ggdumount.c
@@ -38,6 +38,9 @@
 #include "ggdumount.h"
 #include "ggduvolume.h"
 
+#define BUSY_UNMOUNT_NUM_ATTEMPTS              5
+#define BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS 500
+
 struct _GGduMount
 {
   GObject parent;
@@ -451,26 +454,52 @@ g_gdu_mount_can_eject (GMount *_mount)
 
 typedef struct {
   GMount *mount;
+
+  gchar **argv;
+  guint num_attempts_left;
+
   GAsyncReadyCallback callback;
   gpointer user_data;
   GCancellable *cancellable;
+
   int error_fd;
   GIOChannel *error_channel;
   guint error_channel_source_id;
   GString *error_string;
-} UnmountEjectOp;
+
+} UnmountOp;
+
+static gboolean unmount_attempt (UnmountOp *data);
 
 static void
-eject_unmount_cb (GPid pid, gint status, gpointer user_data)
+unmount_cb (GPid pid, gint status, gpointer user_data)
 {
-  UnmountEjectOp *data = user_data;
+  UnmountOp *data = user_data;
   GSimpleAsyncResult *simple;
 
+  g_spawn_close_pid (pid);
+
   if (WEXITSTATUS (status) != 0)
     {
       GError *error;
+      gint error_code;
+
+      error_code = G_IO_ERROR_FAILED;
+      /* we may want to add more strstr() checks here depending on what unmount helper is being used etc... */
+      if (data->error_string->str != NULL && strstr (data->error_string->str, "is busy") != NULL)
+        error_code = G_IO_ERROR_BUSY;
+
+      if (error_code == G_IO_ERROR_BUSY && data->num_attempts_left > 0)
+        {
+          g_timeout_add (BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS,
+                         (GSourceFunc) unmount_attempt,
+                         data);
+          data->num_attempts_left -= 1;
+          goto out;
+        }
+
       error = g_error_new_literal (G_IO_ERROR,
-                                   G_IO_ERROR_FAILED,
+                                   error_code,
                                    data->error_string->str);
       simple = g_simple_async_result_new_from_error (G_OBJECT (data->mount),
                                                      data->callback,
@@ -493,16 +522,19 @@ eject_unmount_cb (GPid pid, gint status, gpointer user_data)
   g_io_channel_unref (data->error_channel);
   g_string_free (data->error_string, TRUE);
   close (data->error_fd);
-  g_spawn_close_pid (pid);
+  g_strfreev (data->argv);
   g_free (data);
+
+ out:
+  ;
 }
 
 static gboolean
-eject_unmount_read_error (GIOChannel *channel,
-                          GIOCondition condition,
-                          gpointer user_data)
+unmount_read_error (GIOChannel *channel,
+                    GIOCondition condition,
+                    gpointer user_data)
 {
-  UnmountEjectOp *data = user_data;
+  UnmountOp *data = user_data;
   gchar buf[BUFSIZ];
   gsize bytes_read;
   GError *error;
@@ -532,26 +564,15 @@ read:
   return TRUE;
 }
 
-static void
-eject_unmount_do (GMount              *mount,
-                  GCancellable        *cancellable,
-                  GAsyncReadyCallback  callback,
-                  gpointer             user_data,
-                  char               **argv)
+static gboolean
+unmount_attempt (UnmountOp *data)
 {
-  UnmountEjectOp *data;
   GPid child_pid;
   GError *error;
 
-  data = g_new0 (UnmountEjectOp, 1);
-  data->mount = mount;
-  data->callback = callback;
-  data->user_data = user_data;
-  data->cancellable = cancellable;
-
   error = NULL;
   if (!g_spawn_async_with_pipes (NULL,         /* working dir */
-                                 argv,
+                                 data->argv,
                                  NULL,         /* envp */
                                  G_SPAWN_DO_NOT_REAP_CHILD|G_SPAWN_SEARCH_PATH,
                                  NULL,         /* child_setup */
@@ -572,8 +593,8 @@ eject_unmount_do (GMount              *mount,
   if (error != NULL)
     goto handle_error;
 
-  data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, eject_unmount_read_error, data);
-  g_child_watch_add (child_pid, eject_unmount_cb, data);
+  data->error_channel_source_id = g_io_add_watch (data->error_channel, G_IO_IN, unmount_read_error, data);
+  g_child_watch_add (child_pid, unmount_cb, data);
 
 handle_error:
 
@@ -596,6 +617,28 @@ handle_error:
       g_error_free (error);
       g_free (data);
     }
+
+  return FALSE;
+}
+
+static void
+unmount_do (GMount              *mount,
+            GCancellable        *cancellable,
+            GAsyncReadyCallback  callback,
+            gpointer             user_data,
+            char               **argv)
+{
+  UnmountOp *data;
+
+  data = g_new0 (UnmountOp, 1);
+  data->mount = mount;
+  data->callback = callback;
+  data->user_data = user_data;
+  data->cancellable = cancellable;
+  data->num_attempts_left = BUSY_UNMOUNT_NUM_ATTEMPTS;
+  data->argv = g_strdupv (argv);
+
+  unmount_attempt (data);
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
@@ -619,19 +662,54 @@ luks_lock_cb (GduDevice *device,
   g_object_unref (simple);
 }
 
+static gboolean gdu_unmount_attempt (GSimpleAsyncResult *simple);
+
 static void
-unmount_cb (GduDevice *device,
-            GError    *error,
-            gpointer   user_data)
+gdu_unmount_cb (GduDevice *device,
+                GError    *error,
+                gpointer   user_data)
 {
   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (user_data);
 
   if (error != NULL)
     {
+      gint error_code;
+
+      /*g_debug ("domain=%s error_code=%d '%s'", g_quark_to_string (error->domain), error->code, error->message);*/
+
+      error_code = G_IO_ERROR_FAILED;
+      if (error->domain == GDU_ERROR && error->code == GDU_ERROR_BUSY)
+        error_code = G_IO_ERROR_BUSY;
+
       /* We could handle PolicyKit integration here but this action is allowed by default
        * and this won't be needed when porting to PolicyKit 1.0 anyway
        */
-      g_simple_async_result_set_from_error (simple, error);
+
+      if (error_code == G_IO_ERROR_BUSY)
+        {
+          guint num_attempts_left;
+
+          num_attempts_left = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (simple), "num-attempts-left"));
+
+          if (num_attempts_left > 0)
+            {
+              num_attempts_left -= 1;
+              g_object_set_data (G_OBJECT (simple),
+                                 "num-attempts-left",
+                                 GUINT_TO_POINTER (num_attempts_left));
+
+              g_timeout_add (BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS,
+                             (GSourceFunc) gdu_unmount_attempt,
+                             simple);
+              goto out;
+            }
+        }
+
+      g_simple_async_result_set_error (simple,
+                                       G_IO_ERROR,
+                                       error_code,
+                                       "%s",
+                                       error->message);
       g_error_free (error);
       g_simple_async_result_complete (simple);
       g_object_unref (simple);
@@ -687,6 +765,17 @@ unmount_cb (GduDevice *device,
   ;
 }
 
+static gboolean
+gdu_unmount_attempt (GSimpleAsyncResult *simple)
+{
+  GduDevice *device;
+
+  /* TODO: honor flags */
+  device = g_object_get_data (G_OBJECT (simple), "gdu-device");
+  gdu_device_op_filesystem_unmount (device, gdu_unmount_cb, simple);
+  return FALSE;
+}
+
 static void
 g_gdu_mount_unmount (GMount              *_mount,
                      GMountUnmountFlags   flags,
@@ -698,6 +787,21 @@ g_gdu_mount_unmount (GMount              *_mount,
   GSimpleAsyncResult *simple;
   GduPresentable *gdu_volume;
 
+  /* emit the ::mount-pre-unmount signal */
+  g_signal_emit_by_name (mount->volume_monitor, "mount-pre-unmount", mount);
+
+  /* If we end up with G_IO_ERROR_BUSY, try again BUSY_UNMOUNT_NUM_ATTEMPTS times
+   * waiting BUSY_UNMOUNT_MS_DELAY_BETWEEN_ATTEMPTS milliseconds between each
+   * attempt.
+   *
+   * This is to give other processes recieving the ::mount-pre-unmount signal some
+   * time to close file descriptors.
+   *
+   * TODO: Unfortunately this code is a bit messy because we take two different
+   *       codepaths depending on whether we use GDU or the native unmount command.
+   *       It would be good to clean this up.
+   */
+
   gdu_volume = NULL;
   if (mount->volume != NULL)
     gdu_volume = g_gdu_volume_get_presentable_with_cleartext (mount->volume);
@@ -713,7 +817,7 @@ g_gdu_mount_unmount (GMount              *_mount,
       else
         argv[1] = mount->device_file;
 
-      eject_unmount_do (_mount, cancellable, callback, user_data, argv);
+      unmount_do (_mount, cancellable, callback, user_data, argv);
     }
   else if (gdu_volume != NULL)
     {
@@ -722,6 +826,10 @@ g_gdu_mount_unmount (GMount              *_mount,
                                           user_data,
                                           NULL);
 
+      g_object_set_data (G_OBJECT (simple),
+                         "num-attempts-left",
+                         GUINT_TO_POINTER (BUSY_UNMOUNT_NUM_ATTEMPTS));
+
       if (mount->is_burn_mount)
         {
           /* burn mounts are really never mounted... */
@@ -731,12 +839,9 @@ g_gdu_mount_unmount (GMount              *_mount,
       else
         {
           GduDevice *device;
-
-          /* TODO: honor flags */
-
           device = gdu_presentable_get_device (gdu_volume);
-          gdu_device_op_filesystem_unmount (device, unmount_cb, simple);
-          g_object_unref (device);
+          g_object_set_data_full (G_OBJECT (simple), "gdu-device", device, g_object_unref);
+          gdu_unmount_attempt (simple);
         }
     }
   else
@@ -760,6 +865,8 @@ g_gdu_mount_unmount_finish (GMount       *mount,
   return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error);
 }
 
+/* ---------------------------------------------------------------------------------------------------- */
+
 typedef struct {
   GObject *object;
   GAsyncReadyCallback callback;
-- 
1.6.2.2


gdu-0012-use-new-gnome-disk-utility-API-to-hide-unwanted-devi.patch:

--- NEW FILE gdu-0012-use-new-gnome-disk-utility-API-to-hide-unwanted-devi.patch ---
>From 2bce9f36bd365be284c10af6a1f74c6120adc3e8 Mon Sep 17 00:00:00 2001
From: David Zeuthen <davidz at redhat.com>
Date: Wed, 15 Apr 2009 11:33:36 -0400
Subject: [PATCH 12/13] use new gnome-disk-utility API to hide unwanted devices

This is to resolve bugs like

 https://bugzilla.redhat.com/show_bug.cgi?id=495170
---
 monitor/gdu/ggduvolumemonitor.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/monitor/gdu/ggduvolumemonitor.c b/monitor/gdu/ggduvolumemonitor.c
index 67e2ec0..2c1f727 100644
--- a/monitor/gdu/ggduvolumemonitor.c
+++ b/monitor/gdu/ggduvolumemonitor.c
@@ -720,6 +720,12 @@ should_mount_be_ignored (GduPool *pool, GduDevice *d)
 
   ret = FALSE;
 
+  if (gdu_device_get_presentation_hide (d))
+    {
+      ret = TRUE;
+      goto out;
+    }
+
   mount_path = gdu_device_get_mount_path (d);
   if (mount_path == NULL || strlen (mount_path) == 0)
     goto out;
@@ -751,6 +757,9 @@ should_volume_be_ignored (GduPool *pool, GduVolume *volume, GList *fstab_mount_p
 
   device = gdu_presentable_get_device (GDU_PRESENTABLE (volume));
 
+  if (gdu_device_get_presentation_hide (device))
+    goto out;
+
   usage = gdu_device_id_get_usage (device);
   type = gdu_device_id_get_type (device);
 
@@ -824,6 +833,9 @@ should_drive_be_ignored (GduPool *pool, GduDrive *d, GList *fstab_mount_points)
       goto out;
     }
 
+  if (gdu_device_get_presentation_hide (device))
+    goto out;
+
   has_volumes = FALSE;
   all_volumes_are_ignored = TRUE;
 
-- 
1.6.2.2


gdu-0013-pass-the-flush-mount-option-for-vfat.patch:

--- NEW FILE gdu-0013-pass-the-flush-mount-option-for-vfat.patch ---
>From 7fd9061afbd0ec4664adb17aed706e12fd5f3eee Mon Sep 17 00:00:00 2001
From: David Zeuthen <davidz at redhat.com>
Date: Wed, 15 Apr 2009 14:41:27 -0400
Subject: [PATCH 13/13] pass the 'flush' mount option for vfat

This mount option makes the vfat filesystem driver flush data more
often. As a consequence

 1. users never get to see the gnome-disk-utility notification daemon
    dialog just added

     http://people.freedesktop.org/~david/gdu-unmount-busy-1.png

    but that's useful for other filesystems as well.

 2. The Nautilus copy dialog stays up until things are on the disk

We do this in gvfs rather than DeviceKit-disks because in some
scenarios 'flush' may be unwanted and there is currently no way to
turn it off (e.g. no 'noflush' or 'flush=0' option).

Ideally the kernel would get this kind of thing right by itself.
---
 monitor/gdu/ggduvolume.c |   36 +++++++++++++++++++++++++++++++++---
 1 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/monitor/gdu/ggduvolume.c b/monitor/gdu/ggduvolume.c
index 49494a1..871a1c5 100644
--- a/monitor/gdu/ggduvolume.c
+++ b/monitor/gdu/ggduvolume.c
@@ -648,6 +648,27 @@ g_gdu_volume_get_mount (GVolume *volume)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
+static gchar **
+get_mount_options (GduDevice *device)
+{
+  gchar **ret;
+
+  /* one day we might read this from user settings */
+  if (g_strcmp0 (gdu_device_id_get_usage (device), "filesystem") == 0 &&
+      g_strcmp0 (gdu_device_id_get_type (device), "vfat") == 0)
+    {
+      ret = g_new0 (gchar *, 2);
+      ret[0] = g_strdup ("flush");
+      ret[1] = NULL;
+    }
+  else
+    ret = NULL;
+
+  return ret;
+}
+
+/* ---------------------------------------------------------------------------------------------------- */
+
 struct MountOpData
 {
   GGduVolume *volume;
@@ -735,8 +756,11 @@ mount_obtain_authz_cb (GObject *source_object,
     }
   else
     {
+      gchar **mount_options;
       /* got the authz, now try again */
-      gdu_device_op_filesystem_mount (data->device_to_mount, mount_cb, data);
+      mount_options = get_mount_options (data->device_to_mount);
+      gdu_device_op_filesystem_mount (data->device_to_mount, mount_options, mount_cb, data);
+      g_strfreev (mount_options);
       goto out;
     }
 
@@ -842,7 +866,10 @@ mount_cleartext_device (MountOpData *data,
     }
   else
     {
-      gdu_device_op_filesystem_mount (data->device_to_mount, mount_cb, data);
+      gchar **mount_options;
+      mount_options = get_mount_options (data->device_to_mount);
+      gdu_device_op_filesystem_mount (data->device_to_mount, mount_options, mount_cb, data);
+      g_strfreev (mount_options);
     }
 
   g_object_unref (pool);
@@ -1260,8 +1287,11 @@ g_gdu_volume_mount (GVolume             *_volume,
     }
   else
     {
+      gchar **mount_options;
       data->device_to_mount = g_object_ref (device);
-      gdu_device_op_filesystem_mount (data->device_to_mount, mount_cb, data);
+      mount_options = get_mount_options (data->device_to_mount);
+      gdu_device_op_filesystem_mount (data->device_to_mount, mount_options, mount_cb, data);
+      g_strfreev (mount_options);
     }
 
  out:
-- 
1.6.2.2



Index: gvfs.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gvfs/devel/gvfs.spec,v
retrieving revision 1.125
retrieving revision 1.126
diff -u -r1.125 -r1.126
--- gvfs.spec	13 Apr 2009 19:16:30 -0000	1.125
+++ gvfs.spec	15 Apr 2009 19:24:55 -0000	1.126
@@ -1,7 +1,7 @@
 Summary: Backends for the gio framework in GLib
 Name: gvfs
 Version: 1.2.2
-Release: 2%{?dist}
+Release: 3%{?dist}
 License: LGPLv2+
 Group: System Environment/Libraries
 URL: http://www.gtk.org
@@ -57,6 +57,13 @@
 # https://bugzilla.redhat.com/show_bug.cgi?id=495152
 Patch108: gdu-0008-ignore-drives-without-volumes.patch
 Patch109: gdu-0009-never-ignore-drives-without-media.patch
+# http://bugzilla.gnome.org/show_bug.cgi?id=536292
+Patch110: gdu-0010-show-user-mountable-fstab-entries.patch
+# http://bugzilla.gnome.org/show_bug.cgi?id=576083
+Patch111: gdu-0011-Bug-576083-pre-unmount-signals-not-being-trigger.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=495170
+Patch112: gdu-0012-use-new-gnome-disk-utility-API-to-hide-unwanted-devi.patch
+Patch113: gdu-0013-pass-the-flush-mount-option-for-vfat.patch
 
 %description
 The gvfs package provides backend implementations for the gio
@@ -152,6 +159,10 @@
 %patch107 -p1 -b .gdu-always-eject
 %patch108 -p1 -b .gdu-ignore-drives-without-volumes
 %patch109 -p1 -b .gdu-never-ignore-drives-without-media
+%patch110 -p1 -b .gdu-user-mountable-fstab-entries
+%patch111 -p1 -b .gdu-pre-unmount-signals
+%patch112 -p1 -b .gdu-unwanted-devices
+%patch113 -p1 -b .gdu-vfat-flush
 
 %build
 
@@ -295,6 +306,9 @@
 
 
 %changelog
+* Wed Apr 15 2009 David Zeuthen <davidz at redhat.com> - 1.2.2-3
+- Sync with the gdu-volume-monitor branch
+
 * Mon Apr 13 2009 Alexander Larsson <alexl at redhat.com> - 1.2.2-2
 - Add ssh-auth-sock patch from svn
 




More information about the fedora-extras-commits mailing list