Index: trunk/src/VBox/Additions/linux/sharedfolders/regops.c
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/regops.c	(revision 77958)
+++ trunk/src/VBox/Additions/linux/sharedfolders/regops.c	(revision 77959)
@@ -929,8 +929,9 @@
                     /* Check that we don't have signals pending before we issue the write, as
                        we'll only end up having to cancel the HGCM request 99% of the time: */
-                    if (!signal_pending(current))
+                    if (!signal_pending(current)) {
                         vrc = VbglR0SfHostReqWritePgLst(pSuperInfo->map.root, pReq, sf_r->Handle.hHost, offFile,
                                                         cbToWrite, cPagesToWrite);
-                    else
+                        sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
+                    } else
                         vrc = VERR_INTERRUPTED;
                     if (RT_SUCCESS(vrc)) {
@@ -1813,4 +1814,5 @@
              */
             rc = VbglR0SfHostReqWritePgLst(pSuperInfo->map.root, pReq, sf_r->Handle.hHost, offFile, cbChunk, cPages);
+            sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
             if (RT_SUCCESS(rc)) {
                 /*
@@ -1939,4 +1941,5 @@
                 int vrc = VbglR0SfHostReqWriteEmbedded(pSuperInfo->map.root, pReq, sf_r->Handle.hHost,
                                                        pos, (uint32_t)size);
+                sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
                 if (RT_SUCCESS(vrc)) {
                     cbRet = pReq->Parms.cb32Write.u.value32;
@@ -1973,5 +1976,6 @@
                     ssize_t cbRet;
                     int vrc = VbglR0SfHostReqWriteContig(pSuperInfo->map.root, pReq, sf_r->handle, pos,
-                                         (uint32_t)size, pvBounce, virt_to_phys(pvBounce));
+                                                         (uint32_t)size, pvBounce, virt_to_phys(pvBounce));
+                    sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
                     if (RT_SUCCESS(vrc)) {
                         cbRet = pReq->Parms.cb32Write.u.value32;
@@ -2636,4 +2640,5 @@
              */
             rc = VbglR0SfHostReqWritePgLst(pSuperInfo->map.root, pReq, sf_r->Handle.hHost, offFile, cbChunk, cPages);
+            sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
             SFLOGFLOW(("vbsf_reg_write_iter_locking: VbglR0SfHostReqWritePgLst -> %d (cbActual=%#x cbChunk=%#zx of %#zx cPages=%#zx offPage0=%#x\n",
                        rc, pReq->Parms.cb32Write.u.value32, cbChunk, cbToWrite, cPages, offPage0));
@@ -2794,4 +2799,5 @@
                     int vrc = VbglR0SfHostReqWriteEmbedded(pSuperInfo->map.root, pReq, sf_r->Handle.hHost,
                                                            offFile, (uint32_t)cbToWrite);
+                    sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
                     if (RT_SUCCESS(vrc)) {
                         cbRet = pReq->Parms.cb32Write.u.value32;
@@ -3549,4 +3555,5 @@
                                             cbToWrite,
                                             1 /*cPages*/);
+            sf_i->ModificationTimeAtOurLastWrite = sf_i->ModificationTime;
             AssertMsgStmt(pReq->Parms.cb32Write.u.value32 == cbToWrite || RT_FAILURE(vrc), /* lazy bird */
                           ("%#x vs %#x\n", pReq->Parms.cb32Write, cbToWrite),
Index: trunk/src/VBox/Additions/linux/sharedfolders/utils.c
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/utils.c	(revision 77958)
+++ trunk/src/VBox/Additions/linux/sharedfolders/utils.c	(revision 77959)
@@ -357,4 +357,6 @@
     vbsf_time_to_linux(&inode->i_mtime, &pObjInfo->ModificationTime);
     sf_i->BirthTime = pObjInfo->BirthTime;
+    sf_i->ModificationTime = pObjInfo->ModificationTime;
+    RTTimeSpecSetSeconds(&sf_i->ModificationTimeAtOurLastWrite, 0);
 }
 
@@ -369,5 +371,5 @@
 {
     PCSHFLFSOBJATTR pAttr = &pObjInfo->Attr;
-    int fMode;
+    int             fMode;
 
     TRACE();
@@ -426,8 +428,59 @@
     /*
      * Mark it as up to date.
+     * Best to do this before we start with any expensive map invalidation.
      */
     pInodeInfo->ts_up_to_date = jiffies;
     pInodeInfo->force_restat  = 0;
 
+    /*
+     * If the modification time changed, we may have to invalidate the page
+     * cache pages associated with this inode if we suspect the change was
+     * made by the host.  How supicious we are depends on the cache mode.
+     *
+     * Note! The invalidate_inode_pages() call is pretty weak.  It will _not_
+     *       touch pages that are already mapped into an address space, but it
+     *       will help if the file isn't currently mmap'ed or if we're in read
+     *       or read/write caching mode.
+     */
+    if (!RTTimeSpecIsEqual(&pInodeInfo->ModificationTime, &pObjInfo->ModificationTime)) {
+        if (RTFS_IS_FILE(pAttr->fMode)) {
+            bool fInvalidate;
+            if (pSuperInfo->enmCacheMode == kVbsfCacheMode_None) {
+                fInvalidate = true;      /* No-caching: always invalidate. */
+            } else {
+                /** @todo Seeing nano-seconds being chopped off by someone before we get
+                 *        here. weird weird weird.  Must be host side.   */
+                if (RTTimeSpecIsEqual(&pInodeInfo->ModificationTimeAtOurLastWrite, &pInodeInfo->ModificationTime)) {
+                    fInvalidate = false; /* Could be our write, so don't invalidate anything */
+                    RTTimeSpecSetSeconds(&pInodeInfo->ModificationTimeAtOurLastWrite, 0);
+                } else {
+                    /* RTLogBackdoorPrintf("vbsf_update_inode: Invalidating the mapping %s - %RU64 vs %RU64 vs %RU64\n",
+                       pInodeInfo->path->String.ach, RTTimeSpecGetNano(&pInodeInfo->ModificationTimeAtOurLastWrite),
+                       RTTimeSpecGetNano(&pInodeInfo->ModificationTime), RTTimeSpecGetNano(&pObjInfo->ModificationTime) ); */
+                    fInvalidate = true;  /* We haven't modified the file recently, so probably a host update. */
+                }
+            }
+            pInodeInfo->ModificationTime = pObjInfo->ModificationTime;
+
+            if (fInvalidate) {
+                struct address_space *mapping = pInode->i_mapping;
+                if (mapping && mapping->nrpages > 0) {
+                    SFLOGFLOW(("vbsf_update_inode: Invalidating the mapping (%s)\n", pInodeInfo->path->String.ach));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
+                    invalidate_mapping_pages(mapping, 0, ~(pgoff_t)0);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+                    invalidate_inode_pages(mapping);
+#else
+                    invalidate_inode_pages(pInode);
+#endif
+                }
+            }
+        } else
+            pInodeInfo->ModificationTime = pObjInfo->ModificationTime;
+    }
+
+    /*
+     * Done.
+     */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)
     if (!fInodeLocked)
@@ -462,5 +515,5 @@
                 if (!ok_to_fail)
                     LogFunc(("VbglR0SfHostReqCreate on %s: file does not exist: %d (caller=%s)\n",
-                         path->String.utf8, pReq->CreateParms.Result, caller));
+                             path->String.utf8, pReq->CreateParms.Result, caller));
                 rc = -ENOENT;
             }
@@ -1081,5 +1134,4 @@
              *       and ignore the dentry timestamp for positive entries.
              */
-            //struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(pInode);
             unsigned long const     cJiffiesAge = jiffies - vbsf_dentry_get_update_jiffies(dentry);
             struct vbsf_super_info *pSuperInfo  = VBSF_GET_SUPER_INFO(dentry->d_sb);
@@ -1088,5 +1140,5 @@
                 rc = 1;
             } else if (!vbsf_inode_revalidate_worker(dentry, true /*fForced*/, false /*fInodeLocked*/)) {
-                vbsf_dentry_set_update_jiffies(dentry, jiffies); /** @todo get jiffies from inode. */
+                vbsf_dentry_set_update_jiffies(dentry, jiffies);
                 SFLOGFLOW(("vbsf_dentry_revalidate: age: %lu vs. TTL %lu -> reval -> 1\n", cJiffiesAge, pSuperInfo->cJiffiesDirCacheTTL));
                 rc = 1;
Index: trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c	(revision 77958)
+++ trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.c	(revision 77959)
@@ -352,16 +352,15 @@
 {
     int rc = 0;
-/** @todo this needs sorting out between 3.19 and 4.11   */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
     /* Each new shared folder map gets a new uint64_t identifier,
      * allocated in sequence.  We ASSUME the sequence will not wrap. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
     static uint64_t s_u64Sequence = 0;
-    uint64_t u64CurrentSequence = ASMAtomicIncU64(&s_u64Sequence);
-#endif
+    uint64_t idSeqMine = ASMAtomicIncU64(&s_u64Sequence);
+# endif
     struct backing_dev_info *bdi;
 
 #  if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
-    rc = super_setup_bdi_name(sb, "vboxsf-%llu", (unsigned long long)u64CurrentSequence);
+    rc = super_setup_bdi_name(sb, "vboxsf-%llu", (unsigned long long)idSeqMine);
     if (!rc)
         bdi = sb->s_bdi;
@@ -411,5 +410,5 @@
 #  if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
     if (!rc)
-        rc = bdi_register(&pSuperInfo->bdi, NULL, "vboxsf-%llu", (unsigned long long)u64CurrentSequence);
+        rc = bdi_register(&pSuperInfo->bdi, NULL, "vboxsf-%llu", (unsigned long long)idSeqMine);
 #  endif /* >= 2.6.26 */
 # endif  /* 4.11.0 > version >= 2.6.24 */
Index: trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h	(revision 77958)
+++ trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h	(revision 77959)
@@ -221,4 +221,12 @@
     RTTIMESPEC              BirthTime;
 
+    /** @name Host modification detection stats.
+     *  @{  */
+    /** The raw modification time, for mapping invalidation purposes. */
+    RTTIMESPEC              ModificationTime;
+    /** Copy of ModificationTime from the last time we wrote to the the file. */
+    RTTIMESPEC              ModificationTimeAtOurLastWrite;
+    /** @} */
+
     /** handle valid if a file was created with vbsf_create_worker until it will
      * be opened with vbsf_reg_open()
