summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gio/glocalfile.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/gio/glocalfile.c b/gio/glocalfile.c
index 354ac7c8c..c9b6c2009 100644
--- a/gio/glocalfile.c
+++ b/gio/glocalfile.c
@@ -1908,6 +1908,7 @@ g_local_file_trash (GFile *file,
char *original_name, *original_name_escaped;
int i;
char *data;
+ char *path;
gboolean is_homedir_trash;
char *delete_time = NULL;
int fd;
@@ -1932,6 +1933,24 @@ g_local_file_trash (GFile *file,
is_homedir_trash = FALSE;
trashdir = NULL;
+
+ /* On overlayfs, a file's st_dev will be different to the home directory's.
+ * We still want to create our trash directory under the home directory, so
+ * instead we should stat the directory that the file we're deleting is in as
+ * this will have the same st_dev.
+ */
+ if (!S_ISDIR (file_stat.st_mode))
+ {
+ path = g_path_get_dirname (local->filename);
+ /* If the parent is a symlink to a different device then it might have
+ * st_dev equal to the home directory's, in which case we will end up
+ * trying to rename across a filesystem boundary, which doesn't work. So
+ * we use g_stat here instead of g_lstat, to know where the symlink
+ * points to. */
+ g_stat (path, &file_stat);
+ g_free (path);
+ }
+
if (file_stat.st_dev == home_stat.st_dev)
{
is_homedir_trash = TRUE;