[shotwell] Use old-style file copy if library is on remote fs



commit 3b010ca59f8930e5daec68858a521a3518028702
Author: Jens Georg <mail jensge org>
Date:   Sat Jun 3 13:27:17 2017 +0200

    Use old-style file copy if library is on remote fs
    
    Especially on vboxfs backed bz NTFS we have an issue that the
    hiddenfile/rename mechanism of GIO breaks
    
    https://bugzilla.gnome.org/show_bug.cgi?id=760868

 src/LibraryFiles.vala            |   66 +++++++++++++++++++++++++++++++++++++-
 src/MediaDataRepresentation.vala |    1 +
 src/main.vala                    |    2 +
 3 files changed, 68 insertions(+), 1 deletions(-)
---
diff --git a/src/LibraryFiles.vala b/src/LibraryFiles.vala
index 20d43ab..26d618b 100644
--- a/src/LibraryFiles.vala
+++ b/src/LibraryFiles.vala
@@ -6,6 +6,22 @@
 
 namespace LibraryFiles {
 
+static bool use_fallback_copy_func = false;
+
+public void select_copy_function() {
+    var import_dir = AppDirs.get_import_dir();
+
+    try {
+       var info = import_dir.query_filesystem_info("filesystem::type", null);
+       use_fallback_copy_func = info.get_attribute_as_string("filesystem::type") == "nfs";
+    } catch (Error error) {
+        critical ("Failed to query fs type: %s", error.message);
+       use_fallback_copy_func = true;
+    }
+
+    info ("Using fallback copy: %s", use_fallback_copy_func.to_string());
+}
+
 // This method uses global::generate_unique_file_at in order to "claim" a file in the filesystem.
 // Thus, when the method returns success a file may exist already, and should be overwritten.
 //
@@ -79,7 +95,11 @@ private File duplicate(File src, FileProgressCallback? progress_callback, bool b
         LibraryMonitor.blacklist_file(dest, "LibraryFiles.duplicate");
     
     try {
-        src.copy(dest, FileCopyFlags.ALL_METADATA | FileCopyFlags.OVERWRITE, null, progress_callback);
+        if (use_fallback_copy_func) {
+            fallback_copy(src, dest, progress_callback);
+        } else {
+            src.copy(dest, FileCopyFlags.ALL_METADATA | FileCopyFlags.OVERWRITE, null, progress_callback);
+        }
         if (blacklist)
             LibraryMonitor.unblacklist_file(dest);
     } catch (Error err) {
@@ -101,4 +121,48 @@ private File duplicate(File src, FileProgressCallback? progress_callback, bool b
     
     return dest;
 }
+
+public void fallback_copy(File? src, File? dst, FileProgressCallback? callback) throws Error {
+    if (src == null || dst == null) {
+        return;
+    }
+
+    var f = FileStream.open(src.get_path(), "rb");
+    if (f != null) {
+        f.seek(0, FileSeek.END);
+        var size = f.tell();
+        f.seek(0, FileSeek.SET);
+        debug ("Copying %s to %s, size is %ld", src.get_path(), dst.get_path(), size);
+
+        var g = FileStream.open(dst.get_path(), "wb");
+        if (g != null) {
+            uint8 buffer[4096];
+            size_t written = 0;
+
+            while (!f.eof()) {
+                var len = f.read(buffer);
+                if (len > 0) {
+                    var out_len = g.write(buffer[0:len]);
+                    if (out_len < 0) {
+                        critical("Failed to write to file %s: %m", dst.get_path());
+                        throw new IOError.FAILED("Failed to write to %s", dst.get_path());
+                    }
+                    written += len;
+
+                    if (callback != null)
+                        callback (written, size);
+                } else if (len < 0) {
+                    critical("Failed to read from file %s: %m", src.get_path());
+                    throw new IOError.FAILED("Failed to read from %s", src.get_path());
+                }
+            }
+        } else {
+            critical ("Failed to open %s: %m", dst.get_path());
+            throw new IOError.FAILED("Failed to open %s", dst.get_path());
+        }
+    } else {
+        critical ("Failed to open %s: %m", src.get_path());
+        throw new IOError.FAILED("Failed to open %s", src.get_path());
+    }
+}
 }
diff --git a/src/MediaDataRepresentation.vala b/src/MediaDataRepresentation.vala
index 484404c..1afd851 100644
--- a/src/MediaDataRepresentation.vala
+++ b/src/MediaDataRepresentation.vala
@@ -781,6 +781,7 @@ public class MediaCollectionRegistry {
         LibraryMonitor replacement = new LibraryMonitor(import_dir, true,
             !CommandlineOptions.no_runtime_monitoring);
         LibraryMonitorPool.get_instance().replace(replacement, LIBRARY_MONITOR_START_DELAY_MSEC);
+        LibraryFiles.select_copy_function();
     }
     
     public static MediaCollectionRegistry get_instance() {
diff --git a/src/main.vala b/src/main.vala
index 610bf0a..6449d95 100644
--- a/src/main.vala
+++ b/src/main.vala
@@ -117,6 +117,8 @@ void library_exec(string[] mounts) {
     
     ThumbnailCache.init();
     Tombstone.init();
+
+    LibraryFiles.select_copy_function();
     
     if (aggregate_monitor != null)
         aggregate_monitor.next_step("LibraryPhoto.init");


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