From d4b68f5d77ce7c387c69d7b738a5fc564a4d8ea7 Mon Sep 17 00:00:00 2001 From: Phillip Susi Date: Thu, 25 Sep 2014 11:50:03 +0200 Subject: limit deep scount (folder contents and size) to one filesystem Closes https://github.com/mate-desktop/caja/issues/194 Thanks to monsta to have suggested this solution Original GNOME commit: https://git.gnome.org/browse/nautilus/commit/?id=a645da5f1043c59203fd194fe85b6976d75d2ece 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 --- libcaja-private/caja-directory-async.c | 43 ++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/libcaja-private/caja-directory-async.c b/libcaja-private/caja-directory-async.c index 2375b3ee..d5d97cf0 100644 --- a/libcaja-private/caja-directory-async.c +++ b/libcaja-private/caja-directory-async.c @@ -148,6 +148,7 @@ struct DeepCountState GFile *deep_count_location; GList *deep_count_subdirectories; GArray *seen_deep_count_inodes; + char *fs_id; }; @@ -2957,6 +2958,7 @@ deep_count_one (DeepCountState *state, CajaFile *file; GFile *subdir; gboolean is_seen_inode; + const char *fs_id; if (should_skip_file (NULL, info)) { @@ -2978,9 +2980,13 @@ deep_count_one (DeepCountState *state, /* 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 { @@ -3014,6 +3020,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); } @@ -3173,6 +3180,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 */ @@ -3206,6 +3214,26 @@ deep_count_stop (CajaDirectory *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 (CajaDirectory *directory, CajaFile *file, @@ -3253,11 +3281,18 @@ deep_count_start (CajaDirectory *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 = caja_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); } -- cgit v1.2.1