[nautilus/wip/oholy/trash-recursion: 7/7] file-operation: Prevent recursion to speed up emptying trash




commit 36e505c12ce7057e444d929c96ac810ce85192e7
Author: Ondrej Holy <oholy redhat com>
Date:   Wed Sep 16 12:48:30 2020 +0200

    file-operation: Prevent recursion to speed up emptying trash
    
    Emptying trash within Nautilus is a bit slow in comparison to plain
    `rm -r`. On my system, it took about 3 min to empty the trash with a
    folder containing 600 000 files, which is not ideal as `rm -r` call
    took just a few seconds. I found that `g_file_delete` is implemented
    differently for locations provided by the trash backend. The trash
    backend prevents modifications of trashed content thus the delete
    operation is allowed only for the top-level files and folders. So it
    is not necessary to recursive delete all files as the permission
    denied error is returned anyway. Let's call `g_file_delete` only for
    top-level items, which reduces the time necessary for emptying trash
    from minutes to seconds...
    
    Fixes: https://gitlab.gnome.org/GNOME/nautilus/-/issues/1589

 src/nautilus-file-operations.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
---
diff --git a/src/nautilus-file-operations.c b/src/nautilus-file-operations.c
index c61c3d9ef..3adf3b54c 100644
--- a/src/nautilus-file-operations.c
+++ b/src/nautilus-file-operations.c
@@ -7898,6 +7898,15 @@ delete_trash_file (CommonJob *job,
 
     if (del_children)
     {
+        gboolean should_recurse;
+
+        /* The g_file_delete operation works differently for locations provided
+         * by the trash backend as it prevents modifications of trashed items
+         * For that reason, it is enough to call g_file_delete on top-level
+         * items only.
+         */
+        should_recurse = !g_file_has_uri_scheme (file, "trash");
+
         enumerator = g_file_enumerate_children (file,
                                                 G_FILE_ATTRIBUTE_STANDARD_NAME ","
                                                 G_FILE_ATTRIBUTE_STANDARD_TYPE,
@@ -7909,10 +7918,13 @@ delete_trash_file (CommonJob *job,
             while (!job_aborted (job) &&
                    (info = g_file_enumerator_next_file (enumerator, job->cancellable, NULL)) != NULL)
             {
+                gboolean is_dir;
+
                 child = g_file_get_child (file,
                                           g_file_info_get_name (info));
-                delete_trash_file (job, child, TRUE,
-                                   g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+                is_dir = (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY);
+
+                delete_trash_file (job, child, TRUE, should_recurse && is_dir);
                 g_object_unref (child);
                 g_object_unref (info);
             }


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