[glib] gio/gunixmounts.c: Don't use mtime to monitor mounts on /proc/



commit c1a31c3aaa16d5335468a0d488e95feb905f7e73
Author: Nelson Benítez León <nbenitezl+gnome gmail com>
Date:   Fri Sep 8 21:42:14 2017 +0500

    gio/gunixmounts.c:  Don't use mtime to monitor mounts on /proc/
    
    Fix get_mounts_timestamp() to not use a stat'ed mtime for /proc/ files.
    Instead, use mount_poller_time if /proc/ watch is running, or otherwise
    return a new generated timestamp to always assume mounts-changed, which
    is safer than previous behaviour of always assuming mounts-not-changed
    (as mtime never changes for /proc/ files when queried from the same
    process).
    
    We say it's safer because allows caches depending on:
    
    g_unix_mounts_get(&time_read)
    g_unix_mounts_changed_since()
    
    to drop possibly outdated/duplicated values, as that was the case for the
    GIO mounts cache used in gio/glocalfile.c which provides mount info for
    g_file_query_filesystem_info() call, as described in below referenced bug.
    
    This fix complements related commit bd9e266e116cd39bb5c674eeb74eb55449793e7f
    
    https://bugzilla.gnome.org/show_bug.cgi?id=787731

 gio/gunixmounts.c |   33 +++++++++++++++++++++++++++++----
 1 files changed, 29 insertions(+), 4 deletions(-)
---
diff --git a/gio/gunixmounts.c b/gio/gunixmounts.c
index ce6a2fc..781aeee 100644
--- a/gio/gunixmounts.c
+++ b/gio/gunixmounts.c
@@ -148,6 +148,7 @@ G_DEFINE_BOXED_TYPE (GUnixMountPoint, g_unix_mount_point,
 
 static GList *_g_get_unix_mounts (void);
 static GList *_g_get_unix_mount_points (void);
+static gboolean proc_mounts_watch_is_running (void);
 
 static guint64 mount_poller_time = 0;
 
@@ -1368,15 +1369,26 @@ get_mounts_timestamp (void)
   struct stat buf;
 
   monitor_file = get_mtab_monitor_file ();
-  if (monitor_file)
+  /* Don't return mtime for /proc/ files */
+  if (monitor_file && !g_str_has_prefix (monitor_file, "/proc/"))
     {
       if (stat (monitor_file, &buf) == 0)
         return (guint64)buf.st_mtime;
     }
-  else
+  else if (proc_mounts_watch_is_running ())
     {
+      /* it's being monitored by poll, so return mount_poller_time */
       return mount_poller_time;
     }
+  else
+    {
+      /* Case of /proc/ file not being monitored - Be on the safe side and
+       * send a new timestamp to force g_unix_mounts_changed_since() to
+       * return TRUE so any application caches depending on it (like eg.
+       * the one in GIO) get invalidated and don't hold possibly outdated
+       * data - see Bug 787731 */
+     return (guint64) g_get_monotonic_time ();
+    }
   return 0;
 }
 
@@ -1566,6 +1578,13 @@ static GFileMonitor          *mtab_monitor;
 static GSource               *proc_mounts_watch_source;
 static GList                 *mount_poller_mounts;
 
+static gboolean
+proc_mounts_watch_is_running (void)
+{
+  return proc_mounts_watch_source != NULL &&
+         !g_source_is_destroyed (proc_mounts_watch_source);
+}
+
 static void
 fstab_file_changed (GFileMonitor      *monitor,
                     GFile             *file,
@@ -1602,7 +1621,10 @@ proc_mounts_changed (GIOChannel   *channel,
                      gpointer      user_data)
 {
   if (cond & G_IO_ERR)
-    g_context_specific_group_emit (&mount_monitor_group, signals[MOUNTS_CHANGED]);
+    {
+      mount_poller_time = (guint64) g_get_monotonic_time ();
+      g_context_specific_group_emit (&mount_monitor_group, signals[MOUNTS_CHANGED]);
+    }
 
   return TRUE;
 }
@@ -1652,7 +1674,10 @@ mount_monitor_stop (void)
     }
 
   if (proc_mounts_watch_source != NULL)
-    g_source_destroy (proc_mounts_watch_source);
+    {
+      g_source_destroy (proc_mounts_watch_source);
+      proc_mounts_watch_source = NULL;
+    }
 
   if (mtab_monitor)
     {


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