summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2018-06-01 13:41:53 +0200
committerOndrej Holy <oholy@redhat.com>2018-06-05 09:37:25 +0200
commitc246e332fd4bb7d88137b14ce6e69a02028d2a33 (patch)
treed17ed91f55a04e95d3fd078069797715ae7f60c3
parent66187c4c3ebb46bc842ced16fd86458f26d68f34 (diff)
downloadglib-c246e332fd4bb7d88137b14ce6e69a02028d2a33.tar.gz
glocalfile: Allow trashing only for locations supported by trash:///
New bugs appears periodically in nautilus/gvfs/glib components that not all trashed files are shown in trash:///. It used to be problem mostly for "bind mounts" and btrfs subvolumes only. Currently, it is also problem for nfs, cifs and other filesystems, which have been recently added by commmit 0d69462f on the list of system internal filesystems. This happens because the trash backend doesn't monitor files on system internal mounts. Such behavior is not against the trash-spec, however, we should be consistent within GNOME. This behavior has the nice side-effect that it solves issues with hangs on network filesystems: https://gitlab.gnome.org/GNOME/glib/issues/605, because those are currently on the system internal filesystem list. https://gitlab.gnome.org/GNOME/glib/issues/251
-rw-r--r--gio/glocalfile.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index 3cd0137d6..52e0ec294 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -1930,6 +1930,7 @@ g_local_file_trash (GFile *file,
{
uid_t uid;
char uid_str[32];
+ GUnixMountEntry *mount;
uid = geteuid ();
g_snprintf (uid_str, sizeof (uid_str), "%lu", (unsigned long)uid);
@@ -1942,7 +1943,21 @@ g_local_file_trash (GFile *file,
file, G_IO_ERROR_NOT_SUPPORTED);
return FALSE;
}
-
+
+ mount = g_unix_mount_at (topdir, NULL);
+ if (mount == NULL || g_unix_mount_is_system_internal (mount))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("Trashing on system internal mounts is not supported"));
+
+ g_clear_pointer (&mount, g_unix_mount_free);
+ g_free (topdir);
+
+ return FALSE;
+ }
+
+ g_clear_pointer (&mount, g_unix_mount_free);
+
/* Try looking for global trash dir $topdir/.Trash/$uid */
globaldir = g_build_filename (topdir, ".Trash", NULL);
if (g_lstat (globaldir, &global_stat) == 0 &&