[nautilus] directory: limit deep scount (folder contents and size) to one filesystem



commit a645da5f1043c59203fd194fe85b6976d75d2ece
Author: Phillip Susi <psusi ubuntu com>
Date:   Mon Dec 17 15:11:54 2012 +0100

    directory: limit deep scount (folder contents and size) to one filesystem
    
    When getting the size of the root directory, nautilus was descending
    into other filesystems including /proc, causing it to report nonsensical
    sizes.
    Store the fsid of the starting directory, and do not recurse into
    other mount points.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=629394
    https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/585472

 libnautilus-private/nautilus-directory-async.c |   43 +++++++++++++++++++++---
 1 files changed, 38 insertions(+), 5 deletions(-)
---
diff --git a/libnautilus-private/nautilus-directory-async.c b/libnautilus-private/nautilus-directory-async.c
index f1d53f3..6961ae0 100644
--- a/libnautilus-private/nautilus-directory-async.c
+++ b/libnautilus-private/nautilus-directory-async.c
@@ -135,6 +135,7 @@ struct DeepCountState {
 	GFile *deep_count_location;
 	GList *deep_count_subdirectories;
 	GArray *seen_deep_count_inodes;
+	char *fs_id;
 };
 
 
@@ -2579,6 +2580,7 @@ deep_count_one (DeepCountState *state,
 	NautilusFile *file;
 	GFile *subdir;
 	gboolean is_seen_inode;
+	const char *fs_id;
 
 	if (should_skip_file (NULL, info)) {
 		return;
@@ -2596,10 +2598,13 @@ deep_count_one (DeepCountState *state,
 		file->details->deep_directory_count += 1;
 
 		/* Record the fact that we have to descend into this directory. */
-
-		subdir = g_file_get_child (state->deep_count_location, g_file_info_get_name (info));
-		state->deep_count_subdirectories = g_list_prepend
-			(state->deep_count_subdirectories, subdir);
+		fs_id = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILESYSTEM);
+		if (g_strcmp0 (fs_id, state->fs_id) == 0) {
+			/* only if it is on the same filesystem */
+			subdir = g_file_get_child (state->deep_count_location, g_file_info_get_name (info));
+			state->deep_count_subdirectories = g_list_prepend
+				(state->deep_count_subdirectories, subdir);
+		}
 	} else {
 		/* Even non-regular files count as files. */
 		file->details->deep_file_count += 1;
@@ -2627,6 +2632,7 @@ deep_count_state_free (DeepCountState *state)
 	}
 	g_list_free_full (state->deep_count_subdirectories, g_object_unref);
 	g_array_free (state->seen_deep_count_inodes, TRUE);
+	g_free (state->fs_id);
 	g_free (state);
 }
 
@@ -2773,6 +2779,7 @@ deep_count_load (DeepCountState *state, GFile *location)
 					 G_FILE_ATTRIBUTE_STANDARD_SIZE ","
 					 G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN ","
 					 G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP ","
+					 G_FILE_ATTRIBUTE_ID_FILESYSTEM ","
 					 G_FILE_ATTRIBUTE_UNIX_INODE,
 					 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, /* flags */
 					 G_PRIORITY_LOW, /* prio */
@@ -2804,6 +2811,25 @@ deep_count_stop (NautilusDirectory *directory)
 }
 
 static void
+deep_count_got_info (GObject *source_object,
+		     GAsyncResult *res,
+		     gpointer user_data)
+{
+	GFileInfo *info;
+	const char *id;
+	GFile *file = (GFile *)source_object;
+	DeepCountState *state = (DeepCountState *)user_data;
+
+	info = g_file_query_info_finish (file, res, NULL);
+	if (info != NULL) {
+		id = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILESYSTEM);
+		state->fs_id = g_strdup (id);
+		g_object_unref (info);
+	}
+	deep_count_load (state, file);
+}
+
+static void
 deep_count_start (NautilusDirectory *directory,
 		  NautilusFile *file,
 		  gboolean *doing_io)
@@ -2846,11 +2872,18 @@ deep_count_start (NautilusDirectory *directory,
 	state->directory = directory;
 	state->cancellable = g_cancellable_new ();
 	state->seen_deep_count_inodes = g_array_new (FALSE, TRUE, sizeof (guint64));
+	state->fs_id = NULL;
 
 	directory->details->deep_count_in_progress = state;
 	
 	location = nautilus_file_get_location (file);
-	deep_count_load (state, location);
+	g_file_query_info_async (location,
+				 G_FILE_ATTRIBUTE_ID_FILESYSTEM,
+				 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+				 G_PRIORITY_DEFAULT,
+				 NULL,
+				 deep_count_got_info,
+				 state);
 	g_object_unref (location);
 }
 



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