[nautilus] Don't verify symlinked target for I/O operations



commit f83d19ac913964240515338e8858977cf6632157
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Wed Sep 12 18:09:04 2012 +0200

    Don't verify symlinked target for I/O operations
    
    Nautilus verifies the destination for free space, read-only ability
    and such. This however doesn't work for symlink pointing to a directory.
    
    Internally (in gio) we call statfs() but that actually stats the fs the
    symlink is on, instead of the place symlink is pointing to. This appears
    to be a limitation of POSIX statfs().
    
    To work around this limitation, let's disable these extra checks when
    destination is a folder and symlinked.
    
    The bug manifestation are false error messages preventing to create a file
    or directory when parent fs is read-only but contains a symlink to rw fs
    which is the desired destination.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=844713

 libnautilus-private/nautilus-file-operations.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)
---
diff --git a/libnautilus-private/nautilus-file-operations.c b/libnautilus-private/nautilus-file-operations.c
index 5fb3043..4adf054 100644
--- a/libnautilus-private/nautilus-file-operations.c
+++ b/libnautilus-private/nautilus-file-operations.c
@@ -2743,6 +2743,7 @@ verify_destination (CommonJob *job,
 	char *primary, *secondary, *details;
 	int response;
 	GFileType file_type;
+	gboolean dest_is_symlink = FALSE;
 
 	if (dest_fs_id) {
 		*dest_fs_id = NULL;
@@ -2754,7 +2755,7 @@ verify_destination (CommonJob *job,
 	info = g_file_query_info (dest, 
 				  G_FILE_ATTRIBUTE_STANDARD_TYPE","
 				  G_FILE_ATTRIBUTE_ID_FILESYSTEM,
-				  0,
+				  dest_is_symlink ? G_FILE_QUERY_INFO_NONE : G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
 				  job->cancellable,
 				  &error);
 
@@ -2796,6 +2797,12 @@ verify_destination (CommonJob *job,
 	}
 
 	file_type = g_file_info_get_file_type (info);
+	if (!dest_is_symlink && file_type == G_FILE_TYPE_SYMBOLIC_LINK) {
+		/* Record that destination is a symlink and do real stat() once again */
+		dest_is_symlink = TRUE;
+		g_object_unref (info);
+		goto retry;
+	}
 
 	if (dest_fs_id) {
 		*dest_fs_id =
@@ -2821,6 +2828,11 @@ verify_destination (CommonJob *job,
 		return;
 	}
 	
+	if (dest_is_symlink) {
+		/* We can't reliably statfs() destination if it's a symlink, thus not doing any further checks. */
+		return;
+	}
+	
 	fsinfo = g_file_query_filesystem_info (dest,
 					       G_FILE_ATTRIBUTE_FILESYSTEM_FREE","
 					       G_FILE_ATTRIBUTE_FILESYSTEM_READONLY,



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