[glib/wip/oholy/cifs-splice: 1/2] gfile: Prevent hangs when copying on CIFS



commit 640488e7e19a546a6b9663575e00bf12724d454d
Author: Ondrej Holy <oholy redhat com>
Date:   Tue Apr 23 13:31:59 2019 +0200

    gfile: Prevent hangs when copying on CIFS
    
    Prevent usage of splice() on CIFS as it causes hangs in some cases,
    see https://bugzilla.kernel.org/show_bug.cgi?id=198349 for more info.
    
    Closes: https://gitlab.gnome.org/GNOME/glib/issues/1246

 gio/gfile.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
---
diff --git a/gio/gfile.c b/gio/gfile.c
index 24b136d80..8a99b7573 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -3188,6 +3188,10 @@ file_copy_fallback (GFile                  *source,
   const char *target;
   char *attrs_to_read;
   gboolean do_set_attributes = FALSE;
+  GFileInfo *fs_info = NULL;
+#ifdef HAVE_SPLICE
+  const gchar *fs_type;
+#endif
 
   /* need to know the file type */
   info = g_file_query_info (source,
@@ -3336,7 +3340,20 @@ file_copy_fallback (GFile                  *source,
 #endif
 
 #ifdef HAVE_SPLICE
-  if (G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out))
+  fs_info = g_file_query_filesystem_info (source,
+                                          G_FILE_ATTRIBUTE_FILESYSTEM_TYPE,
+                                          cancellable,
+                                          error);
+  fs_type = g_file_info_get_attribute_string (fs_info,
+                                              G_FILE_ATTRIBUTE_FILESYSTEM_TYPE);
+
+  /* Prevent usage of splice() on CIFS as it causes hangs in some cases, see:
+   * https://bugzilla.kernel.org/show_bug.cgi?id=198349
+   */
+  if (g_strcmp0 (fs_type, "cifs") != 0 &&
+      g_strcmp0 (fs_type, "smb") != 0 &&
+      g_strcmp0 (fs_type, "smb2") != 0 &&
+      G_IS_FILE_DESCRIPTOR_BASED (in) && G_IS_FILE_DESCRIPTOR_BASED (out))
     {
       GError *splice_err = NULL;
 
@@ -3398,6 +3415,7 @@ file_copy_fallback (GFile                  *source,
     }
 
   g_clear_object (&info);
+  g_clear_object (&fs_info);
 
   return ret;
 }


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