Subject: limit deep search ( folder contents count and size ) to one filesystem
Author: Phillip Susi <psusi@ubuntu.com>
Description: 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.
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/nautilus/+bug/585472
Bug: https://bugzilla.gnome.org/show_bug.cgi?id=629394


Index: b/libnautilus-private/nautilus-directory-async.c
===================================================================
--- a/libnautilus-private/nautilus-directory-async.c
+++ b/libnautilus-private/nautilus-directory-async.c
@@ -134,6 +134,7 @@
 	GFile *deep_count_location;
 	GList *deep_count_subdirectories;
 	GArray *seen_deep_count_inodes;
+	char *fs_id;
 };
 
 
@@ -2666,6 +2667,7 @@
 	NautilusFile *file;
 	GFile *subdir;
 	gboolean is_seen_inode;
+	const char *id;
 
 	if (should_skip_file (NULL, info)) {
 		return;
@@ -2683,10 +2685,13 @@
 		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);
+		id = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILESYSTEM);
+		if (id && state->fs_id && strcmp (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;
@@ -2714,6 +2719,7 @@
 	}
 	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);
 }
 
@@ -2860,6 +2866,7 @@
 					 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 */
@@ -2897,7 +2904,9 @@
 {
 	GFile *location;
 	DeepCountState *state;
-	
+	GFileInfo *info;
+	const char *id;
+
 	if (directory->details->deep_count_in_progress != NULL) {
 		*doing_io = TRUE;
 		return;
@@ -2937,6 +2946,17 @@
 	directory->details->deep_count_in_progress = state;
 	
 	location = nautilus_file_get_location (file);
+	state->fs_id = NULL;
+	info = g_file_query_info (location,
+				  G_FILE_ATTRIBUTE_ID_FILESYSTEM,
+				  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+				  NULL, NULL);
+	if (info) {
+		id = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILESYSTEM);
+		if (id)
+			state->fs_id = g_strdup (id);
+		g_object_unref (info);
+	}
 	deep_count_load (state, location);
 	g_object_unref (location);
 }
