diff options
author | Alexander Larsson <alexl@redhat.com> | 2012-08-23 22:05:55 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2012-08-23 22:05:55 +0200 |
commit | 9d4b1312a802fffb22696c54c9b7b96ff82f9161 (patch) | |
tree | dbc2b42d868f577063cc3fa590a162753ae3e88f /daemon/mount.c | |
parent | c3309dfdf5c3d60c6666a8a8883990ccdab383ae (diff) | |
download | gvfs-9d4b1312a802fffb22696c54c9b7b96ff82f9161.tar.gz |
Fix races when mounting the same mount in parallel.
Whenever we get ALREADY_MOUNTED during a mount we just treat
it as a success.
This fixes for instance multiple parallel calls to automounted
mounts like http.
Diffstat (limited to 'daemon/mount.c')
-rw-r--r-- | daemon/mount.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/daemon/mount.c b/daemon/mount.c index 1703bcfc..a736cde4 100644 --- a/daemon/mount.c +++ b/daemon/mount.c @@ -286,6 +286,9 @@ dbus_mount_reply (GVfsDBusMountable *proxy, g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) && !data->spawned) spawn_mount (data); + else if (g_error_matches (error, G_IO_ERROR, + G_IO_ERROR_ALREADY_MOUNTED)) + mount_finish (data, NULL); else { g_warning ("dbus_mount_reply: Error from org.gtk.vfs.Mountable.mount(): %s", error->message); @@ -350,18 +353,33 @@ spawn_mount_handle_spawned (GVfsDBusSpawner *object, GDBusMethodInvocation *invocation, gboolean arg_succeeded, const gchar *arg_error_message, + guint arg_error_code, gpointer user_data) { MountData *data = user_data; - GError *error; + GError *error = NULL; g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (data->spawner)); - + if (!arg_succeeded) { - g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, arg_error_message); - mount_finish (data, error); - g_error_free (error); + if (arg_error_code == G_IO_ERROR_ALREADY_MOUNTED && + data->mountable->dbus_name != NULL) + { + /* This means the spawn failed since someone already owned the name. + It might not strictly be mounted yet, as the mount might not + be registred yet. So, to avoid races we ask the new owner of + the name to mount. It'll typically return an ALREADY_MOUNTED + error which we treat as success. + */ + mountable_mount_with_name (data, data->mountable->dbus_name); + } + else + { + g_set_error_literal (&error, G_IO_ERROR, arg_error_code, arg_error_message); + mount_finish (data, error); + g_error_free (error); + } } else { |