- Add patch for reverse mapping FUSE paths (bgo #530654)

This commit is contained in:
David Zeuthen 2008-10-01 18:18:09 +00:00
parent e9948031ce
commit c5fea7243b
2 changed files with 383 additions and 1 deletions

View File

@ -0,0 +1,375 @@
--- trunk/common/gvfsdaemonprotocol.h 2008/09/01 21:22:15 1922
+++ trunk/common/gvfsdaemonprotocol.h 2008/09/26 10:44:37 2031
@@ -12,6 +12,7 @@
#define G_VFS_DBUS_MOUNTTRACKER_INTERFACE "org.gtk.vfs.MountTracker"
#define G_VFS_DBUS_MOUNTTRACKER_PATH "/org/gtk/vfs/mounttracker"
#define G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT "lookupMount"
+#define G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT_BY_FUSE_PATH "lookupMountByFusePath"
#define G_VFS_DBUS_MOUNTTRACKER_OP_MOUNT_LOCATION "mountLocation"
#define G_VFS_DBUS_MOUNTTRACKER_OP_LIST_MOUNTS "listMounts"
#define G_VFS_DBUS_MOUNTTRACKER_OP_REGISTER_MOUNT "registerMount"
--- trunk/client/gdaemonvfs.h 2008/01/31 16:54:22 1214
+++ trunk/client/gdaemonvfs.h 2008/09/26 10:44:37 2031
@@ -60,6 +60,8 @@
GMountInfo * _g_daemon_vfs_get_mount_info_sync (GMountSpec *spec,
const char *path,
GError **error);
+GMountInfo * _g_daemon_vfs_get_mount_info_by_fuse_sync (const char *fuse_path,
+ char **mount_path);
GMountSpec * _g_daemon_vfs_get_mount_spec_for_path (GMountSpec *spec,
const char *path,
const char *new_path);
--- trunk/client/gdaemonvfs.c 2008/09/23 19:16:06 2021
+++ trunk/client/gdaemonvfs.c 2008/09/26 10:44:37 2031
@@ -55,6 +55,8 @@
GVfs *wrapped_vfs;
GList *mount_cache;
+ GFile *fuse_root;
+
GHashTable *from_uri_hash;
GHashTable *to_uri_hash;
@@ -287,6 +289,7 @@
const char * const *schemes, * const *mount_types;
GVfsUriMapper *mapper;
GList *modules;
+ char *file;
int i;
bindtextdomain (GETTEXT_PACKAGE, GVFS_LOCALEDIR);
@@ -319,6 +322,10 @@
vfs->wrapped_vfs = g_vfs_get_local ();
+ file = g_build_filename (g_get_home_dir(), ".gvfs", NULL);
+ vfs->fuse_root = g_vfs_get_file_for_path (vfs->wrapped_vfs, file);
+ g_free (file);
+
dbus_connection_set_exit_on_disconnect (vfs->async_bus, FALSE);
_g_dbus_connection_integrate_with_main (vfs->async_bus);
@@ -357,13 +364,42 @@
return g_object_new (G_TYPE_DAEMON_VFS, NULL);
}
+/* This unrefs file if its changed */
+static GFile *
+convert_fuse_path (GVfs *vfs,
+ GFile *file)
+{
+ GFile *fuse_root;
+ char *fuse_path, *mount_path;
+ GMountInfo *mount_info;
+
+ fuse_root = ((GDaemonVfs *)vfs)->fuse_root;
+ if (g_file_has_prefix (file, fuse_root))
+ {
+ fuse_path = g_file_get_path (file);
+ mount_info = _g_daemon_vfs_get_mount_info_by_fuse_sync (fuse_path, &mount_path);
+ g_free (fuse_path);
+ if (mount_info)
+ {
+ g_object_unref (file);
+ /* TODO: Do we need to look at the prefix of the mount_spec? */
+ file = g_daemon_file_new (mount_info->mount_spec, mount_path);
+ g_free (mount_path);
+ g_mount_info_unref (mount_info);
+ }
+ }
+ return file;
+}
+
static GFile *
g_daemon_vfs_get_file_for_path (GVfs *vfs,
const char *path)
{
- /* TODO: detect fuse paths and convert to daemon vfs GFiles */
+ GFile *file;
- return g_vfs_get_file_for_path (G_DAEMON_VFS (vfs)->wrapped_vfs, path);
+ file = g_vfs_get_file_for_path (G_DAEMON_VFS (vfs)->wrapped_vfs, path);
+ file = convert_fuse_path (vfs, file);
+ return file;
}
static GFile *
@@ -711,6 +747,41 @@
return info;
}
+static GMountInfo *
+lookup_mount_info_by_fuse_path_in_cache (const char *fuse_path,
+ char **mount_path)
+{
+ GMountInfo *info;
+ GList *l;
+
+ G_LOCK (mount_cache);
+ info = NULL;
+ for (l = the_vfs->mount_cache; l != NULL; l = l->next)
+ {
+ GMountInfo *mount_info = l->data;
+
+ if (mount_info->fuse_mountpoint != NULL &&
+ g_str_has_prefix (fuse_path, mount_info->fuse_mountpoint))
+ {
+ int len = strlen (mount_info->fuse_mountpoint);
+ if (fuse_path[len] == 0 ||
+ fuse_path[len] == '/')
+ {
+ if (fuse_path[len] == 0)
+ *mount_path = g_strdup ("/");
+ else
+ *mount_path = g_strdup (fuse_path + len);
+ info = g_mount_info_ref (mount_info);
+ break;
+ }
+ }
+ }
+ G_UNLOCK (mount_cache);
+
+ return info;
+}
+
+
void
_g_daemon_vfs_invalidate_dbus_id (const char *dbus_id)
{
@@ -908,6 +979,71 @@
return info;
}
+GMountInfo *
+_g_daemon_vfs_get_mount_info_by_fuse_sync (const char *fuse_path,
+ char **mount_path)
+{
+ GMountInfo *info;
+ DBusConnection *conn;
+ DBusMessage *message, *reply;
+ DBusMessageIter iter;
+ DBusError derror;
+ int len;
+
+ info = lookup_mount_info_by_fuse_path_in_cache (fuse_path,
+ mount_path);
+ if (info != NULL)
+ return info;
+
+ conn = _g_dbus_connection_get_sync (NULL, NULL);
+ if (conn == NULL)
+ return NULL;
+
+ message =
+ dbus_message_new_method_call (G_VFS_DBUS_DAEMON_NAME,
+ G_VFS_DBUS_MOUNTTRACKER_PATH,
+ G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
+ G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT_BY_FUSE_PATH);
+ dbus_message_set_auto_start (message, TRUE);
+
+ dbus_message_iter_init_append (message, &iter);
+ _g_dbus_message_iter_append_cstring (&iter, fuse_path);
+
+ dbus_error_init (&derror);
+ reply = dbus_connection_send_with_reply_and_block (conn, message, -1, &derror);
+ dbus_message_unref (message);
+ if (!reply)
+ {
+ dbus_error_free (&derror);
+ return NULL;
+ }
+
+ info = handler_lookup_mount_reply (reply, NULL);
+ dbus_message_unref (reply);
+
+ if (info)
+ {
+ if (info->fuse_mountpoint)
+ {
+ len = strlen (info->fuse_mountpoint);
+ if (fuse_path[len] == 0)
+ *mount_path = g_strdup ("/");
+ else
+ *mount_path = g_strdup (fuse_path + len);
+ }
+ else
+ {
+ /* This could happen if we race with the gvfs fuse mount
+ * at startup of gvfsd... */
+ g_mount_info_unref (info);
+ info = NULL;
+ }
+ }
+
+
+ return info;
+}
+
static GFile *
g_daemon_vfs_parse_name (GVfs *vfs,
const char *parse_name)
@@ -917,8 +1053,8 @@
if (g_path_is_absolute (parse_name) ||
*parse_name == '~')
{
- /* TODO: detect fuse paths and convert to daemon vfs GFiles ? */
file = g_vfs_parse_name (G_DAEMON_VFS (vfs)->wrapped_vfs, parse_name);
+ file = convert_fuse_path (vfs, file);
}
else
{
--- trunk/daemon/mount.c 2008/08/02 11:00:07 1847
+++ trunk/daemon/mount.c 2008/09/26 10:44:37 2031
@@ -43,7 +43,8 @@
char *icon;
char *prefered_filename_encoding;
gboolean user_visible;
-
+ char *fuse_mountpoint; /* Always set, even if fuse not availible */
+
/* Daemon object ref */
char *dbus_id;
char *object_path;
@@ -100,6 +101,32 @@
}
static VfsMount *
+find_vfs_mount_by_fuse_path (const char *fuse_path)
+{
+ GList *l;
+
+ if (!fuse_available)
+ return NULL;
+
+ for (l = mounts; l != NULL; l = l->next)
+ {
+ VfsMount *mount = l->data;
+
+ if (mount->fuse_mountpoint != NULL &&
+ g_str_has_prefix (fuse_path, mount->fuse_mountpoint))
+ {
+ int len = strlen (mount->fuse_mountpoint);
+ if (fuse_path[len] == 0 ||
+ fuse_path[len] == '/')
+ return mount;
+ }
+ }
+
+ return NULL;
+}
+
+
+static VfsMount *
match_vfs_mount (GMountSpec *match)
{
GList *l;
@@ -160,6 +187,7 @@
g_free (mount->stable_name);
g_free (mount->x_content_types);
g_free (mount->icon);
+ g_free (mount->fuse_mountpoint);
g_free (mount->prefered_filename_encoding);
g_free (mount->dbus_id);
g_free (mount->object_path);
@@ -223,21 +251,10 @@
&user_visible))
_g_dbus_oom ();
-
- fuse_mountpoint = NULL;
- if (fuse_available && mount->user_visible)
- {
- char *fs_name;
-
- /* Keep in sync with fuse daemon */
- fs_name = g_uri_escape_string (mount->stable_name, "+@#$., ", TRUE);
-
- fuse_mountpoint = g_build_filename (g_get_home_dir(), ".gvfs", fs_name, NULL);
- }
-
- if (fuse_mountpoint == NULL)
- fuse_mountpoint = g_strdup ("");
+ fuse_mountpoint = "";
+ if (fuse_available && mount->fuse_mountpoint)
+ fuse_mountpoint = mount->fuse_mountpoint;
_g_dbus_message_iter_append_cstring (&struct_iter, fuse_mountpoint);
g_mount_spec_to_dbus (&struct_iter, mount->mount_spec);
@@ -699,6 +716,16 @@
mount->dbus_id = g_strdup (id);
mount->object_path = g_strdup (obj_path);
mount->mount_spec = mount_spec;
+
+ if (user_visible)
+ {
+ char *fs_name;
+
+ /* Keep in sync with fuse daemon */
+ fs_name = g_uri_escape_string (mount->stable_name, "+@#$., ", TRUE);
+
+ mount->fuse_mountpoint = g_build_filename (g_get_home_dir(), ".gvfs", fs_name, NULL);
+ }
mounts = g_list_prepend (mounts, mount);
@@ -835,6 +862,48 @@
}
static void
+lookup_mount_by_fuse_path (DBusConnection *connection,
+ DBusMessage *message)
+{
+ VfsMount *mount;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ char *fuse_path;
+
+ dbus_message_iter_init (message, &iter);
+
+ reply = NULL;
+ if (_g_dbus_message_iter_get_args (&iter, NULL,
+ G_DBUS_TYPE_CSTRING, &fuse_path,
+ 0))
+ {
+ mount = find_vfs_mount_by_fuse_path (fuse_path);
+
+ if (mount == NULL)
+ reply = _dbus_message_new_gerror (message,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_MOUNTED,
+ _("The specified location is not mounted"));
+ else
+ {
+ reply = dbus_message_new_method_return (message);
+ if (reply)
+ {
+ dbus_message_iter_init_append (reply, &iter);
+ vfs_mount_to_dbus (mount, &iter);
+ }
+ }
+ }
+ else
+ reply = dbus_message_new_error (message,
+ DBUS_ERROR_INVALID_ARGS,
+ "Invalid arguments");
+
+ if (reply != NULL)
+ dbus_connection_send (connection, reply, NULL);
+}
+
+static void
list_mounts (DBusConnection *connection,
DBusMessage *message)
{
@@ -1084,6 +1153,10 @@
lookup_mount (connection, message, TRUE);
else if (dbus_message_is_method_call (message,
G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
+ G_VFS_DBUS_MOUNTTRACKER_OP_LOOKUP_MOUNT_BY_FUSE_PATH))
+ lookup_mount_by_fuse_path (connection, message);
+ else if (dbus_message_is_method_call (message,
+ G_VFS_DBUS_MOUNTTRACKER_INTERFACE,
G_VFS_DBUS_MOUNTTRACKER_OP_LIST_MOUNTS))
list_mounts (connection, message);
else if (dbus_message_is_method_call (message,

View File

@ -1,7 +1,7 @@
Summary: Backends for the gio framework in GLib Summary: Backends for the gio framework in GLib
Name: gvfs Name: gvfs
Version: 1.0.1 Version: 1.0.1
Release: 3%{?dist} Release: 4%{?dist}
License: LGPLv2+ License: LGPLv2+
Group: System Environment/Libraries Group: System Environment/Libraries
URL: http://www.gtk.org URL: http://www.gtk.org
@ -35,6 +35,9 @@ Patch2: gvfs-obexftp-updated-apis-3.patch
# From upstream svn # From upstream svn
Patch3: fix-mounting.patch Patch3: fix-mounting.patch
# http://bugzilla.gnome.org/show_bug.cgi?id=530654
Patch4: gvfs-1.1.1-reverse-map-fuse-paths.patch
%description %description
The gvfs package provides backend implementations for the gio The gvfs package provides backend implementations for the gio
framework in GLib. It includes ftp, sftp, cifs. framework in GLib. It includes ftp, sftp, cifs.
@ -118,6 +121,7 @@ media players (Media Transfer Protocol) to applications using gvfs.
%patch1 -p0 -b .archive-integration %patch1 -p0 -b .archive-integration
%patch2 -p0 -b .bluez-ods %patch2 -p0 -b .bluez-ods
%patch3 -p1 -b .fix-mounting %patch3 -p1 -b .fix-mounting
%patch4 -p1 -b .reverse-map-fuse-paths.patch
%build %build
@ -255,6 +259,9 @@ update-desktop-database &> /dev/null ||:
%changelog %changelog
* Wed Oct 1 2008 David Zeuthen <davidz@redhat.com> - 1.0.1-4
- Add patch for reverse mapping FUSE paths (bgo #530654)
* Mon Sep 29 2008 Matthias Clasen <mclasen@redhat.com> - 1.0.1-3 * Mon Sep 29 2008 Matthias Clasen <mclasen@redhat.com> - 1.0.1-3
- Fix mounting - Fix mounting