diff options
author | Ondrej Holy <oholy@redhat.com> | 2020-09-16 15:22:46 +0200 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2020-09-23 15:35:47 +0200 |
commit | f474ec1f72cb669bbc59c54c41e75d0f1c30ea75 (patch) | |
tree | 630c55fa3d48157f5fc4af5dd651019d1b406e37 /gio | |
parent | 9bc61def1f815948ea28d92b59f506d3b2024ea0 (diff) | |
download | glib-f474ec1f72cb669bbc59c54c41e75d0f1c30ea75.tar.gz |
gio-tool-trash: Prevent recursion to speed up emptying trashwip/oholy/trash-recursion
Emptying trash over `gio trash` 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...
See: https://gitlab.gnome.org/GNOME/nautilus/-/issues/1589
Diffstat (limited to 'gio')
-rw-r--r-- | gio/gio-tool-trash.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/gio/gio-tool-trash.c b/gio/gio-tool-trash.c index 4f9e3668a..3be63a9b7 100644 --- a/gio/gio-tool-trash.c +++ b/gio/gio-tool-trash.c @@ -40,6 +40,8 @@ delete_trash_file (GFile *file, gboolean del_file, gboolean del_children) GFile *child; GFileEnumerator *enumerator; + g_return_if_fail (g_file_has_uri_scheme (file, "trash")); + if (del_children) { enumerator = g_file_enumerate_children (file, @@ -53,7 +55,14 @@ delete_trash_file (GFile *file, gboolean del_file, gboolean del_children) while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) { child = g_file_get_child (file, g_file_info_get_name (info)); - delete_trash_file (child, TRUE, g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY); + + /* 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. + */ + delete_trash_file (child, TRUE, FALSE); + g_object_unref (child); g_object_unref (info); } |