[gvfs/gnome-3-8] MTP: Fail fast if in the middle of an unmount



commit 62dd53b7854ce65e9121b2283a6aa9a01e5281b4
Author: Philip Langdale <philipl overt org>
Date:   Sun Nov 24 09:12:37 2013 -0800

    MTP: Fail fast if in the middle of an unmount
    
    I've seen a ton of bug reports where the backend crashes due to
    operations executing after an unmount begins. I think it's a
    sufficient solution to check the unmount flag that we already have
    and then immediately abort the operation.
    
    Generally, this is only seen with operations that are initiated
    implicitly like do_query_info or do_enumerate, but I've added the
    protection to all operations for consistency.

 daemon/gvfsbackendmtp.c |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)
---
diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c
index b5e4b90..02059eb 100644
--- a/daemon/gvfsbackendmtp.c
+++ b/daemon/gvfsbackendmtp.c
@@ -105,6 +105,18 @@ DEBUG_ENUMERATE (const gchar *message, ...)
 #define PTP_ST_RemovableRAM                     0x0004
 
 
+#define FAIL_DURING_UNMOUNT() \
+  if (g_atomic_int_get (&G_VFS_BACKEND_MTP(backend)->unmount_started)) { \
+    DEBUG ("(I) aborting due to unmount"); \
+    g_vfs_job_failed_literal (G_VFS_JOB (job), \
+                              G_IO_ERROR, G_IO_ERROR_CLOSED, \
+                              _("The connection is closed")); \
+    goto exit; \
+  }
+
+
+
+
 /************************************************
  * Initialization
  ************************************************/
@@ -834,6 +846,8 @@ do_enumerate (GVfsBackend *backend,
 
   g_mutex_lock (&G_VFS_BACKEND_MTP (backend)->mutex);
 
+  FAIL_DURING_UNMOUNT();
+
   LIBMTP_mtpdevice_t *device;
   device = op_backend->device;
 
@@ -989,6 +1003,8 @@ do_query_info (GVfsBackend *backend,
   DEBUG ("(I) do_query_info (filename = %s) ", filename);
   g_mutex_lock (&G_VFS_BACKEND_MTP (backend)->mutex);
 
+  FAIL_DURING_UNMOUNT();
+
   gchar **elements = g_strsplit_set (filename, "/", -1);
   unsigned int ne = g_strv_length (elements);
 
@@ -1065,6 +1081,8 @@ do_query_fs_info (GVfsBackend *backend,
   gchar **elements = g_strsplit_set (filename, "/", -1);
   unsigned int ne = g_strv_length (elements);
 
+  FAIL_DURING_UNMOUNT();
+
   LIBMTP_mtpdevice_t *device;
   device = G_VFS_BACKEND_MTP (backend)->device;
 
@@ -1132,6 +1150,8 @@ do_make_directory (GVfsBackend *backend,
   gchar **elements = g_strsplit_set (filename, "/", -1);
   unsigned int ne = g_strv_length (elements);
 
+  FAIL_DURING_UNMOUNT();
+
   if (ne < 3) {
     g_vfs_job_failed_literal (G_VFS_JOB (job),
                               G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -1188,6 +1208,8 @@ do_pull (GVfsBackend *backend,
   gchar **elements = g_strsplit_set (source, "/", -1);
   unsigned int ne = g_strv_length (elements);
 
+  FAIL_DURING_UNMOUNT();
+
   if (ne < 3) {
     g_vfs_job_failed_literal (G_VFS_JOB (job),
                               G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE,
@@ -1263,6 +1285,8 @@ do_push (GVfsBackend *backend,
   gchar **elements = g_strsplit_set (destination, "/", -1);
   unsigned int ne = g_strv_length (elements);
 
+  FAIL_DURING_UNMOUNT();
+
   if (ne < 3) {
     g_vfs_job_failed_literal (G_VFS_JOB (job),
                               G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE,
@@ -1361,6 +1385,8 @@ do_delete (GVfsBackend *backend,
   gchar **elements = g_strsplit_set (filename, "/", -1);
   unsigned int ne = g_strv_length (elements);
 
+  FAIL_DURING_UNMOUNT();
+
   if (ne < 3) {
     g_vfs_job_failed_literal (G_VFS_JOB (job),
                               G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -1399,6 +1425,8 @@ do_set_display_name (GVfsBackend *backend,
   DEBUG ("(I) do_set_display_name '%s' --> '%s' ", filename, display_name);
   g_mutex_lock (&G_VFS_BACKEND_MTP (backend)->mutex);
 
+  FAIL_DURING_UNMOUNT();
+
   gchar **elements = g_strsplit_set (filename, "/", -1);
   unsigned int ne = g_strv_length (elements);
 
@@ -1444,6 +1472,8 @@ do_open_icon_for_read (GVfsBackend *backend,
   DEBUG ("(I) do_open_icon_for_read (%s)", icon_id);
   g_mutex_lock (&G_VFS_BACKEND_MTP (backend)->mutex);
 
+  FAIL_DURING_UNMOUNT();
+
   guint id = strtol (icon_id, NULL, 10);
 
   if (id > 0) {
@@ -1487,6 +1517,8 @@ do_open_icon_for_read (GVfsBackend *backend,
                       _("Malformed icon identifier '%s'"),
                       icon_id);
   }
+
+ exit:
   g_mutex_unlock (&G_VFS_BACKEND_MTP (backend)->mutex);
 
   DEBUG ("(I) do_open_icon_for_read done.");


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