Skip to content

Commit fb47200

Browse files
committed
Fix blocking when listing or entering a network location with an
inaccessible host. A mounted network directory with a down host will cause stat to block for 10 seconds before reporting failure. In nemo, if that location is bookmarked, it can cause multiple freezes at startup. --- This is not a perfect fix - I don't think one is possible at the application level. Nemo will now check if a target's path is descended from a mounted network connection, and skip any operation involving stat. pros: - Nemo will no longer freeze at startup due a 'dangling' network mount. - Clicking on the bookmark will no longer freeze, but if the folder hasn't been explicitly accessed yet, there will be a delay of about 10s, then an error popup. Subsequent clicks will cause the error immediately. - Navigating to the folder's parent directory will *always* cause a 10s delay in loading that folder. The file list will not include the bad directory. con: - The places-sidebar will always show any bookmarked network folder as available/online (no triangle warning icon), whether actually available or not. ref: #3270 (maybe?), #3436, #1378.
1 parent 46313e6 commit fb47200

File tree

4 files changed

+94
-5
lines changed

4 files changed

+94
-5
lines changed

libnemo-private/nemo-action.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ nemo_action_new (const gchar *name,
952952
const gchar *prg_name = reverse ? deps[i] + 1 : deps[i];
953953

954954
if (g_path_is_absolute (prg_name)) {
955-
if (g_file_test (prg_name, G_FILE_TEST_EXISTS)) {
955+
if ((!nemo_path_is_network_safe (prg_name)) && g_file_test (prg_name, G_FILE_TEST_EXISTS)) {
956956
found = TRUE;
957957
}
958958
} else {
@@ -1657,7 +1657,7 @@ get_is_dir (NemoFile *file)
16571657

16581658
GFile *f = nemo_file_get_location (file);
16591659

1660-
if (g_file_is_native (f)) {
1660+
if (g_file_is_native (f) && (!nemo_location_is_network_safe (f))) {
16611661
gchar *path;
16621662

16631663
path = g_file_get_path (f);
@@ -1958,7 +1958,7 @@ get_visibility (NemoAction *action,
19581958
f = nemo_file_get_location (file);
19591959

19601960
if (g_file_is_native (f)) {
1961-
mount = g_file_find_enclosing_mount (f, NULL, NULL);
1961+
mount = nemo_get_mount_for_location_safe (f);
19621962
nemo_file_set_mount (file, mount);
19631963
}
19641964

libnemo-private/nemo-bookmark.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,8 @@ nemo_bookmark_uri_get_exists (NemoBookmark *bookmark)
743743

744744
path_name = g_file_get_path (bookmark->details->location);
745745

746-
if (g_file_is_native (bookmark->details->location) && g_file_test (path_name, G_FILE_TEST_EXISTS)) {
746+
if (g_file_is_native (bookmark->details->location) &&
747+
(!nemo_location_is_network_safe (bookmark->details->location)) && g_file_test (path_name, G_FILE_TEST_EXISTS)) {
747748
exists = TRUE;
748749
} else {
749750
g_signal_emit_by_name (bookmark, "location-mounted", bookmark->details->location, &exists);

libnemo-private/nemo-file-utilities.c

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1714,7 +1714,91 @@ nemo_user_is_root (void)
17141714
return elevated;
17151715
}
17161716

1717-
/* End copied section */
1717+
static gint
1718+
sort_by_length (GMount *a, GMount *b)
1719+
{
1720+
g_autoptr(GFile) a_root = g_mount_get_root (a);
1721+
g_autoptr(GFile) b_root = g_mount_get_root (b);
1722+
g_autofree gchar *a_uri = g_file_get_uri (a_root);
1723+
g_autofree gchar *b_uri = g_file_get_uri (b_root);
1724+
gint a_len = g_utf8_strlen (a_uri, -1);
1725+
gint b_len = g_utf8_strlen (b_uri, -1);
1726+
1727+
return b_len - a_len;
1728+
}
1729+
1730+
GMount *
1731+
nemo_get_mount_for_location_safe (GFile *location)
1732+
{
1733+
GVolumeMonitor *monitor;
1734+
GList *mounts = NULL;
1735+
GList *mount_iter;
1736+
GMount *ret = NULL;
1737+
1738+
1739+
monitor = g_volume_monitor_get ();
1740+
mounts = g_volume_monitor_get_mounts (monitor);
1741+
1742+
mounts = g_list_sort (mounts, (GCompareFunc) sort_by_length);
1743+
1744+
for (mount_iter = mounts; mount_iter != NULL; mount_iter = mount_iter->next) {
1745+
GMount *mount = G_MOUNT (mount_iter->data);
1746+
GFile *mount_location = g_mount_get_root (mount);
1747+
gchar *mount_root_uri = g_file_get_uri (mount_location);
1748+
gchar *location_uri = g_file_get_uri (location);
1749+
1750+
if (g_str_has_prefix (location_uri, mount_root_uri)) {
1751+
// Add a ref for our match, as it will lose one when the list is freed.
1752+
ret = g_object_ref (mount);
1753+
}
1754+
1755+
g_free (mount_root_uri);
1756+
g_free (location_uri);
1757+
g_object_unref (mount_location);
1758+
1759+
if (ret != NULL)
1760+
break;
1761+
}
1762+
1763+
g_list_free_full (mounts, (GDestroyNotify) g_object_unref);
1764+
g_object_unref (monitor);
1765+
1766+
return ret;
1767+
}
1768+
1769+
gboolean
1770+
nemo_location_is_network_safe (GFile *location)
1771+
{
1772+
GVolume *volume;
1773+
GMount *mount;
1774+
gboolean is_network = FALSE;
1775+
1776+
mount = nemo_get_mount_for_location_safe (location);
1777+
if (mount != NULL) {
1778+
volume = g_mount_get_volume (mount);
1779+
if (volume != NULL) {
1780+
g_autofree gchar *identifier = g_volume_get_identifier (volume, "class");
1781+
1782+
if (g_strcmp0 (identifier, "network") == 0) {
1783+
is_network = TRUE;
1784+
}
1785+
1786+
g_object_unref (volume);
1787+
}
1788+
1789+
g_object_unref (mount);
1790+
}
1791+
1792+
return is_network;
1793+
}
1794+
1795+
gboolean
1796+
nemo_path_is_network_safe (const gchar *path)
1797+
{
1798+
g_autoptr(GFile) location = g_file_new_for_path (path);
1799+
1800+
return nemo_location_is_network_safe (location);
1801+
}
17181802

17191803
#if !defined (NEMO_OMIT_SELF_CHECK)
17201804

libnemo-private/nemo-file-utilities.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,8 @@ gchar *nemo_get_best_guess_file_mimetype (const gchar *filename,
118118

119119
gboolean nemo_treating_root_as_normal (void);
120120
gboolean nemo_user_is_root (void);
121+
122+
GMount *nemo_get_mount_for_location_safe (GFile *location);
123+
gboolean nemo_location_is_network_safe (GFile *location);
124+
gboolean nemo_path_is_network_safe (const gchar *path);
121125
#endif /* NEMO_FILE_UTILITIES_H */

0 commit comments

Comments
 (0)