Index: trunk/src/VBox/Additions/linux/sharedfolders/dirops.c
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/dirops.c	(revision 77872)
+++ trunk/src/VBox/Additions/linux/sharedfolders/dirops.c	(revision 77873)
@@ -118,5 +118,5 @@
                  */
                 /** @todo do more to invalidate dentry and inode here. */
-                vbsf_dentry_set_update_jiffies(dentry, jiffies + INT_MAX / 2);
+                vbsf_dentry_invalidate_ttl(dentry);
                 sf_i->force_restat = true;
                 rc = -ENOENT;
@@ -564,5 +564,5 @@
     .read           = generic_read_dir,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
-    .llseek       = generic_file_llseek
+    .llseek         = generic_file_llseek
 #endif
 };
@@ -1124,8 +1124,10 @@
                 rc = 0;
             } else if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND) {
+                /* Probably deleted on the host while the guest had it cached, so don't complain: */
                 LogFunc(("(%d): VbglR0SfRemove(%s) failed rc=%Rrc; calling d_drop on %p\n",
                          fDirectory, path->String.ach, rc, dentry));
+                sf_parent_i->force_restat = true;
                 d_drop(dentry);
-                rc = 0; /** @todo ??? */
+                rc = 0;
             } else {
                 LogFunc(("(%d): VbglR0SfRemove(%s) failed rc=%Rrc\n", fDirectory, path->String.ach, rc));
@@ -1241,5 +1243,5 @@
                                    pOldPath->String.ach, pNewPath->String.ach, fRename, rc));
                         if (rc == VERR_IS_A_DIRECTORY || rc == VERR_IS_A_FILE)
-                            vbsf_dentry_set_update_jiffies(old_dentry, jiffies + INT_MAX / 2);
+                            vbsf_dentry_invalidate_ttl(old_dentry);
                         rc = -RTErrConvertToErrno(rc);
                     }
@@ -1323,6 +1325,9 @@
                         SFLOGFLOW(("vbsf_inode_symlink: Successfully created '%s' -> '%s'\n", pPath->String.ach, pTarget->String.ach));
                         pPath = NULL; /* consumed by inode */
+                        vbsf_dentry_chain_increase_ttl(dentry);
                     } else {
                         SFLOGFLOW(("vbsf_inode_symlink: Failed to create inode for '%s': %d\n", pPath->String.ach, rc));
+                        vbsf_dentry_chain_increase_parent_ttl(dentry);
+                        vbsf_dentry_invalidate_ttl(dentry);
                     }
                 } else {
Index: trunk/src/VBox/Additions/linux/sharedfolders/lnkops.c
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/lnkops.c	(revision 77872)
+++ trunk/src/VBox/Additions/linux/sharedfolders/lnkops.c	(revision 77873)
@@ -128,4 +128,5 @@
                 rc = vbsf_symlink_nls_convert(sf_g, pszTarget, PAGE_SIZE);
                 if (rc == 0) {
+                    vbsf_dentry_chain_increase_ttl(dentry);
                     set_delayed_call(done, kfree_link, pszTarget);
                     return pszTarget;
@@ -164,6 +165,8 @@
             SFLOGFLOW(("vbsf_readlink: %s -> %*s\n", sf_i->path->String.ach, pszTarget));
             rc = vbsf_symlink_nls_convert(sf_g, pszTarget, PAGE_SIZE);
-            if (rc == 0)
+            if (rc == 0) {
+                vbsf_dentry_chain_increase_ttl(dentry);
                 rc = vfs_readlink(dentry, buffer, len, pszTarget);
+            }
         } else {
             SFLOGFLOW(("vbsf_readlink: VbglR0SfHostReqReadLinkContigSimple failed on '%s': %Rrc\n", sf_i->path->String.ach, rc));
@@ -209,4 +212,5 @@
                  * using the buffer we pass it here.
                  */
+                vbsf_dentry_chain_increase_ttl(dentry);
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
                 *cookie = pszTarget;
Index: trunk/src/VBox/Additions/linux/sharedfolders/regops.c
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/regops.c	(revision 77872)
+++ trunk/src/VBox/Additions/linux/sharedfolders/regops.c	(revision 77873)
@@ -58,5 +58,7 @@
 #endif
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
+# define iter_is_iovec(a_pIter) ( !((a_pIter)->type & ITER_KVEC) )
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0)
 # define iter_is_iovec(a_pIter) ( !((a_pIter)->type & (ITER_KVEC | ITER_BVEC)) )
 #endif
@@ -74,5 +76,26 @@
 *   Structures and Typedefs                                                                                                      *
 *********************************************************************************************************************************/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
+struct vbsf_iov_iter {
+    unsigned int        type;
+    unsigned int        v_write : 1;
+    size_t              iov_offset;
+    size_t              nr_segs;
+    struct iovec const *iov;
+# ifdef VBOX_STRICT
+    struct iovec const * const iov_org;
+    size_t              const nr_segs_org;
+# endif
+};
+# ifdef VBOX_STRICT
+#  define VBSF_IOV_ITER_INITIALIZER(a_cSegs, a_pIov, a_fWrite) { 0, a_fWrite, 0, a_cSegs, a_pIov, a_pIov, a_cSegs }
+# else
+#  define VBSF_IOV_ITER_INITIALIZER(a_cSegs, a_pIov, a_fWrite) { 0, a_fWrite, 0, a_cSegs, a_pIov }
+# endif
+# define ITER_KVEC 1
+# define iov_iter vbsf_iov_iter
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 /** Used by vbsf_iter_lock_pages() to keep the first page of the next segment. */
 struct vbsf_iter_stash {
@@ -94,4 +117,240 @@
 
 
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+DECLINLINE(void) vbsf_unlock_user_pages(struct page **papPages, size_t cPages, bool fSetDirty, bool fLockPgHack);
+
+
+/*********************************************************************************************************************************
+*   Provide more recent uio.h functionality to older kernels.                                                                    *
+*********************************************************************************************************************************/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+
+# undef  iov_iter_count
+# define iov_iter_count(a_pIter)                vbsf_iov_iter_count(a_pIter)
+static size_t vbsf_iov_iter_count(struct vbsf_iov_iter const *iter)
+{
+    size_t              cbRet = 0;
+    size_t              cLeft = iter->nr_segs;
+    struct iovec const *iov   = iter->iov;
+    while (cLeft-- > 0) {
+        cbRet += iov->iov_len;
+        iov++;
+    }
+    return cbRet - iter->iov_offset;
+}
+
+
+# undef  iov_iter_single_seg_count
+# define iov_iter_single_seg_count(a_pIter)     vbsf_iov_iter_single_seg_count(a_pIter)
+static size_t vbsf_iov_iter_single_seg_count(struct vbsf_iov_iter const *iter)
+{
+    if (iter->nr_segs > 0)
+        return iter->iov->iov_len - iter->iov_offset;
+    return 0;
+}
+
+
+# undef  iov_iter_advance
+# define iov_iter_advance(a_pIter, a_cbSkip)    vbsf_iov_iter_advance(a_pIter, a_cbSkip)
+static void vbsf_iov_iter_advance(struct vbsf_iov_iter *iter, size_t cbSkip)
+{
+    SFLOG2(("vbsf_iov_iter_advance: cbSkip=%#zx\n", cbSkip));
+    if (iter->nr_segs > 0) {
+        size_t const cbLeftCur = iter->iov->iov_len - iter->iov_offset;
+        Assert(iter->iov_offset <= iter->iov->iov_len);
+        if (cbLeftCur > cbSkip) {
+            iter->iov_offset += cbSkip;
+        } else {
+            cbSkip -= cbLeftCur;
+            iter->iov_offset = 0;
+            iter->iov++;
+            iter->nr_segs--;
+            while (iter->nr_segs > 0) {
+                size_t const cbSeg = iter->iov->iov_len;
+                if (cbSeg > cbSkip) {
+                    iter->iov_offset = cbSkip;
+                    break;
+                }
+                cbSkip -= cbSeg;
+                iter->iov++;
+                iter->nr_segs--;
+            }
+        }
+    }
+}
+
+
+# undef  iov_iter_get_pages
+# define iov_iter_get_pages(a_pIter, a_papPages, a_cbMax, a_cMaxPages, a_poffPg0) \
+    vbsf_iov_iter_get_pages(a_pIter, a_papPages, a_cbMax, a_cMaxPages, a_poffPg0)
+static ssize_t vbsf_iov_iter_get_pages(struct vbsf_iov_iter *iter, struct page **papPages,
+                                       size_t cbMax, unsigned cMaxPages, size_t *poffPg0)
+{
+    while (iter->nr_segs > 0) {
+        size_t const cbLeft = iter->iov->iov_len - iter->iov_offset;
+        Assert(iter->iov->iov_len >= iter->iov_offset);
+        if (cbLeft > 0) {
+            uintptr_t           uPtrFrom   = (uintptr_t)iter->iov->iov_base + iter->iov_offset;
+            size_t              offPg0     = *poffPg0 = uPtrFrom & PAGE_OFFSET_MASK;
+            size_t              cPagesLeft = RT_ALIGN_Z(offPg0 + cbLeft, PAGE_SIZE) >> PAGE_SHIFT;
+            size_t              cPages     = RT_MIN(cPagesLeft, cMaxPages);
+            struct task_struct *pTask      = current;
+            size_t              cPagesLocked;
+
+            down_read(&pTask->mm->mmap_sem);
+            cPagesLocked = get_user_pages(pTask, pTask->mm, uPtrFrom, cPages, iter->v_write, 1 /*force*/, papPages, NULL);
+            up_read(&pTask->mm->mmap_sem);
+            if (cPagesLocked == cPages) {
+                size_t cbRet = (cPages << PAGE_SHIFT) - offPg0;
+                if (cPages == cPagesLeft) {
+                    size_t offLastPg = (uPtrFrom + cbLeft) & PAGE_OFFSET_MASK;
+                    if (offLastPg)
+                        cbRet -= PAGE_SIZE - offLastPg;
+                }
+                Assert(cbRet <= cbLeft);
+                return cbRet;
+            }
+            if (cPagesLocked > 0)
+                vbsf_unlock_user_pages(papPages, cPagesLocked, false /*fSetDirty*/, false /*fLockPgHack*/);
+            return -EFAULT;
+        }
+        iter->iov_offset = 0;
+        iter->iov++;
+        iter->nr_segs--;
+    }
+    AssertFailed();
+    return 0;
+}
+
+
+# undef  iov_iter_truncate
+# define iov_iter_truncate(iter, cbNew)         vbsf_iov_iter_truncate(iter, cbNew)
+static void vbsf_iov_iter_truncate(struct vbsf_iov_iter *iter, size_t cbNew)
+{
+    /* we have no counter or stuff, so it's a no-op. */
+    RT_NOREF(iter, cbNew);
+}
+
+
+# undef  iov_iter_revert
+# define iov_iter_revert(a_pIter, a_cbRewind) vbsf_iov_iter_revert(a_pIter, a_cbRewind)
+void vbsf_iov_iter_revert(struct vbsf_iov_iter *iter, size_t cbRewind)
+{
+    SFLOG2(("vbsf_iov_iter_revert: cbRewind=%#zx\n", cbRewind));
+    if (iter->iov_offset > 0) {
+        if (cbRewind <= iter->iov_offset) {
+            iter->iov_offset -= cbRewind;
+            return;
+        }
+        cbRewind -= iter->iov_offset;
+        iter->iov_offset = 0;
+    }
+
+    while (cbRewind > 0) {
+        struct iovec const *pIov  = --iter->iov;
+        size_t const        cbSeg = pIov->iov_len;
+        iter->nr_segs++;
+
+        Assert((uintptr_t)pIov >= (uintptr_t)iter->iov_org);
+        Assert(iter->nr_segs <= iter->iter->nr_segs_org);
+
+        if (cbRewind <= cbSeg) {
+            iter->iov_offset = cbSeg - cbRewind;
+            break;
+        }
+        cbRewind -= cbSeg;
+    }
+}
+
+#endif /* 2.6.19 <= linux < 3.16.0 */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
+
+static size_t copy_from_iter(uint8_t *pbDst, size_t cbToCopy, struct iov_iter *pSrcIter)
+{
+    size_t const cbTotal = cbToCopy;
+    Assert(iov_iter_count(pSrcIter) >= cbToCopy);
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+    if (pSrcIter->type & ITER_BVEC) {
+        while (cbToCopy > 0) {
+            size_t const offPage    = (uintptr_t)pbDst & PAGE_OFFSET_MASK;
+            size_t const cbThisCopy = RT_MIN(PAGE_SIZE - offPage, cbToCopy);
+            struct page *pPage      = rtR0MemObjLinuxVirtToPage(pbDst);
+            size_t       cbCopied   = copy_page_from_iter(pPage, offPage, cbThisCopy, pSrcIter);
+            AssertStmt(cbCopied <= cbThisCopy, cbCopied = cbThisCopy);
+            pbDst    += cbCopied;
+            cbToCopy -= cbCopied;
+            if (cbCopied != cbToCopy)
+                break;
+        }
+    } else
+# endif
+    {
+        while (cbToCopy > 0) {
+            size_t cbThisCopy = iov_iter_single_seg_count(pSrcIter);
+            if (cbThisCopy > 0) {
+                if (cbThisCopy > cbToCopy)
+                    cbThisCopy = cbToCopy;
+                if (pSrcIter->type & ITER_KVEC)
+                    memcpy(pbDst, (void *)pSrcIter->iov->iov_base + pSrcIter->iov_offset, cbThisCopy);
+                else if (!copy_from_user(pbDst, pSrcIter->iov->iov_base + pSrcIter->iov_offset, cbThisCopy))
+                    break;
+                pbDst    += cbThisCopy;
+                cbToCopy -= cbThisCopy;
+            }
+            iov_iter_advance(pSrcIter, cbThisCopy);
+        }
+    }
+    return cbTotal - cbToCopy;
+}
+
+
+static size_t copy_to_iter(uint8_t const *pbSrc, size_t cbToCopy, struct iov_iter *pDstIter)
+{
+    size_t const cbTotal = cbToCopy;
+    Assert(iov_iter_count(pDstIter) >= cbToCopy);
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+    if (pDstIter->type & ITER_BVEC) {
+        while (cbToCopy > 0) {
+            size_t const offPage    = (uintptr_t)pbSrc & PAGE_OFFSET_MASK;
+            size_t const cbThisCopy = RT_MIN(PAGE_SIZE - offPage, cbToCopy);
+            struct page *pPage      = rtR0MemObjLinuxVirtToPage((void *)pbSrc);
+            size_t       cbCopied   = copy_page_to_iter(pPage, offPage, cbThisCopy, pDstIter);
+            AssertStmt(cbCopied <= cbThisCopy, cbCopied = cbThisCopy);
+            pbSrc    += cbCopied;
+            cbToCopy -= cbCopied;
+            if (cbCopied != cbToCopy)
+                break;
+        }
+    } else
+# endif
+    {
+        while (cbToCopy > 0) {
+            size_t cbThisCopy = iov_iter_single_seg_count(pDstIter);
+            if (cbThisCopy > 0) {
+                if (cbThisCopy > cbToCopy)
+                    cbThisCopy = cbToCopy;
+                if (pDstIter->type & ITER_KVEC)
+                    memcpy((void *)pDstIter->iov->iov_base + pDstIter->iov_offset, pbSrc, cbThisCopy);
+                else if (!copy_to_user(pDstIter->iov->iov_base + pDstIter->iov_offset, pbSrc, cbThisCopy)) {
+                    break;
+                }
+                pbSrc    += cbThisCopy;
+                cbToCopy -= cbThisCopy;
+            }
+            iov_iter_advance(pDstIter, cbThisCopy);
+        }
+    }
+    return cbTotal - cbToCopy;
+}
+
+#endif /* 3.16.0 <= linux < 3.18.0 */
+
+
+
+/*********************************************************************************************************************************
+*   Handle management                                                                                                            *
+*********************************************************************************************************************************/
 
 /**
@@ -237,4 +496,9 @@
 }
 
+
+
+/*********************************************************************************************************************************
+*   Pipe / splice stuff for 2.6.23 >= linux < 2.6.31 (figure out why we need this)                                               *
+*********************************************************************************************************************************/
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) \
@@ -390,4 +654,9 @@
 
 #endif /* 2.6.23 <= LINUX_VERSION_CODE < 2.6.31 */
+
+
+/*********************************************************************************************************************************
+*   File operations on regular files                                                                                             *
+*********************************************************************************************************************************/
 
 /**
@@ -561,5 +830,5 @@
     size_t cPagesLocked;
     down_read(&pTask->mm->mmap_sem);
-    cPagesLocked = get_user_pages(current, current->mm, uPtrFrom, cPages, fWrite, 1 /*force*/, papPages, NULL);
+    cPagesLocked = get_user_pages(pTask, pTask->mm, uPtrFrom, cPages, fWrite, 1 /*force*/, papPages, NULL);
     up_read(&pTask->mm->mmap_sem);
 # endif
@@ -1167,82 +1436,5 @@
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0)
-/*
- * Hide missing uio.h functionality in older kernsl.
- */
-
-static size_t copy_from_iter(uint8_t *pbDst, size_t cbToCopy, struct iov_iter *pSrcIter)
-{
-    size_t const cbTotal = cbToCopy;
-    Assert(iov_iter_count(pSrcIter) >= cbToCopy);
-    if (pSrcIter->type & ITER_BVEC) {
-        while (cbToCopy > 0) {
-            size_t const offPage    = (uintptr_t)pbDst & PAGE_OFFSET_MASK;
-            size_t const cbThisCopy = RT_MIN(PAGE_SIZE - offPage, cbToCopy);
-            struct page *pPage      = rtR0MemObjLinuxVirtToPage(pbDst);
-            size_t       cbCopied   = copy_page_from_iter(pPage, offPage, cbThisCopy, pSrcIter);
-            AssertStmt(cbCopied <= cbThisCopy, cbCopied = cbThisCopy);
-            pbDst    += cbCopied;
-            cbToCopy -= cbCopied;
-            if (cbCopied != cbToCopy)
-                break;
-        }
-    } else {
-        while (cbToCopy > 0) {
-            size_t cbThisCopy = iov_iter_single_seg_count(pSrcIter);
-            if (cbThisCopy > 0) {
-                if (cbThisCopy > cbToCopy)
-                    cbThisCopy = cbToCopy;
-                if (pSrcIter->type & ITER_KVEC)
-                    memcpy(pbDst, (void *)pSrcIter->iov->iov_base + pSrcIter->iov_offset, cbThisCopy);
-                else if (!copy_from_user(pbDst, pSrcIter->iov->iov_base + pSrcIter->iov_offset, cbThisCopy))
-                    break;
-                pbDst    += cbThisCopy;
-                cbToCopy -= cbThisCopy;
-            }
-            iov_iter_advance(pSrcIter, cbThisCopy);
-        }
-    }
-    return cbTotal - cbToCopy;
-}
-
-static size_t copy_to_iter(uint8_t const *pbSrc, size_t cbToCopy, struct iov_iter *pDstIter)
-{
-    size_t const cbTotal = cbToCopy;
-    Assert(iov_iter_count(pDstIter) >= cbToCopy);
-    if (pDstIter->type & ITER_BVEC) {
-        while (cbToCopy > 0) {
-            size_t const offPage    = (uintptr_t)pbSrc & PAGE_OFFSET_MASK;
-            size_t const cbThisCopy = RT_MIN(PAGE_SIZE - offPage, cbToCopy);
-            struct page *pPage      = rtR0MemObjLinuxVirtToPage((void *)pbSrc);
-            size_t       cbCopied   = copy_page_to_iter(pPage, offPage, cbThisCopy, pDstIter);
-            AssertStmt(cbCopied <= cbThisCopy, cbCopied = cbThisCopy);
-            pbSrc    += cbCopied;
-            cbToCopy -= cbCopied;
-            if (cbCopied != cbToCopy)
-                break;
-        }
-    } else {
-        while (cbToCopy > 0) {
-            size_t cbThisCopy = iov_iter_single_seg_count(pDstIter);
-            if (cbThisCopy > 0) {
-                if (cbThisCopy > cbToCopy)
-                    cbThisCopy = cbToCopy;
-                if (pDstIter->type & ITER_KVEC)
-                    memcpy((void *)pDstIter->iov->iov_base + pDstIter->iov_offset, pbSrc, cbThisCopy);
-                else if (!copy_to_user(pDstIter->iov->iov_base + pDstIter->iov_offset, pbSrc, cbThisCopy)) {
-                    break;
-                }
-                pbSrc    += cbThisCopy;
-                cbToCopy -= cbThisCopy;
-            }
-            iov_iter_advance(pDstIter, cbThisCopy);
-        }
-    }
-    return cbTotal - cbToCopy;
-}
-
-#endif /* 3.16.0 >= linux < 3.18.0 */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 
 /**
@@ -1504,5 +1696,5 @@
     }
 
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) || LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
     iov_iter_revert(iter, cbToRewind + cbExtra);
     return true;
@@ -1534,5 +1726,7 @@
 {
     size_t cPages;
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
     if (iter_is_iovec(iter) || (iter->type & ITER_KVEC)) {
+#endif
         const struct iovec *pCurIov    = iter->iov;
         size_t              cLeft      = iter->nr_segs;
@@ -1592,5 +1786,6 @@
         if (cPagesSpan > cPages)
             cPages = cPagesSpan;
-    } else  {
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+    } else {
         /* Won't bother with accurate counts for the next two types, just make
            some rough estimates (does pipes have segments?): */
@@ -1598,4 +1793,5 @@
         cPages = (iov_iter_count(iter) + (PAGE_SIZE * 2 - 2) * cSegs) >> PAGE_SHIFT;
     }
+# endif
     SFLOGFLOW(("vbsf_iter_max_span_of_pages: returns %#zx\n", cPages));
     return cPages;
@@ -1729,6 +1925,14 @@
  * @param   iter        The I/O vector iterator describing the buffer.
  */
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
 static ssize_t vbsf_reg_read_iter(struct kiocb *kio, struct iov_iter *iter)
-{
+# else
+static ssize_t vbsf_reg_aio_read(struct kiocb *kio, const struct iovec *iov, unsigned long cSegs, loff_t offFile)
+# endif
+{
+# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
+    struct vbsf_iov_iter    fake_iter = VBSF_IOV_ITER_INITIALIZER(cSegs, iov, 0 /*write*/);
+    struct vbsf_iov_iter   *iter      = &fake_iter;
+# endif
     size_t                  cbToRead = iov_iter_count(iter);
     struct inode           *inode    = VBSF_GET_F_DENTRY(kio->ki_filp)->d_inode;
@@ -1754,6 +1958,11 @@
      * mappings around with any kind of pages loaded.
      */
-    if (vbsf_should_use_cached_read(kio->ki_filp, mapping, sf_g))
+    if (vbsf_should_use_cached_read(kio->ki_filp, mapping, sf_g)) {
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
         return generic_file_read_iter(kio, iter);
+# else
+        return generic_file_aio_read(kio, iov, cSegs, offFile);
+# endif
+    }
 
     /*
@@ -1929,5 +2138,4 @@
 
 
-
 /**
  * Write from I/O vector iterator.
@@ -1937,6 +2145,14 @@
  * @param   iter        The I/O vector iterator describing the buffer.
  */
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
 static ssize_t vbsf_reg_write_iter(struct kiocb *kio, struct iov_iter *iter)
-{
+# else
+static ssize_t vbsf_reg_aio_write(struct kiocb *kio, const struct iovec *iov, unsigned long cSegs, loff_t offFile)
+# endif
+{
+# if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
+    struct vbsf_iov_iter    fake_iter = VBSF_IOV_ITER_INITIALIZER(cSegs, iov, 1 /*write*/);
+    struct vbsf_iov_iter   *iter      = &fake_iter;
+# endif
     size_t                  cbToWrite = iov_iter_count(iter);
     struct inode           *inode     = VBSF_GET_F_DENTRY(kio->ki_filp)->d_inode;
@@ -1946,5 +2162,7 @@
     struct vbsf_reg_info   *sf_r      = kio->ki_filp->private_data;
     struct vbsf_super_info *sf_g      = VBSF_GET_SUPER_INFO(inode->i_sb);
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
     loff_t                  offFile   = kio->ki_pos;
+# endif
 
     SFLOGFLOW(("vbsf_reg_write_iter: inode=%p file=%p size=%#zx off=%#llx type=%#x\n",
@@ -1957,9 +2175,9 @@
     /** @todo This should be handled by the host, it returning the new file
      *        offset when appending.  We may have an outdated i_size value here! */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
     if (kio->ki_flags & IOCB_APPEND)
-#else
+# else
     if (kio->ki_filp->f_flags & O_APPEND)
-#endif
+# endif
         kio->ki_pos = offFile = i_size_read(inode);
 
@@ -1985,11 +2203,11 @@
         && mapping->nrpages > 0
         && mapping_writably_mapped(mapping)) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
         int err = filemap_fdatawait_range(mapping, offFile, offFile + cbToWrite - 1);
         if (err)
             return err;
-#else
+# else
         /** @todo ... */
-#endif
+# endif
     }
 
@@ -2038,5 +2256,5 @@
 }
 
-#endif /* >= 3.16.0 */
+#endif /* >= 2.6.19 */
 
 /**
@@ -2127,7 +2345,7 @@
     struct vbsf_super_info *sf_g = VBSF_GET_SUPER_INFO(inode->i_sb);
     struct vbsf_inode_info *sf_i = VBSF_GET_INODE_INFO(inode);
-    struct vbsf_reg_info *sf_r;
-    struct dentry *dentry = VBSF_GET_F_DENTRY(file);
-    VBOXSFCREATEREQ *pReq;
+    struct dentry          *dentry = VBSF_GET_F_DENTRY(file);
+    struct vbsf_reg_info   *sf_r;
+    VBOXSFCREATEREQ        *pReq;
 
     SFLOGFLOW(("vbsf_reg_open: inode=%p file=%p flags=%#x %s\n", inode, file, file->f_flags, sf_i ? sf_i->path->String.ach : NULL));
@@ -2265,4 +2483,5 @@
 }
 
+
 /**
  * Wrapper around generic/default seek function that ensures that we've got
@@ -2299,4 +2518,5 @@
 #endif
 }
+
 
 /**
@@ -2416,4 +2636,5 @@
 }
 #endif /* > 4.5 */
+
 
 #ifdef SFLOG_ENABLED
@@ -2596,4 +2817,7 @@
     .read_iter       = vbsf_reg_read_iter,
     .write_iter      = vbsf_reg_write_iter,
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+    .aio_read        = vbsf_reg_aio_read,
+    .aio_write       = vbsf_reg_aio_write,
 #endif
     .release         = vbsf_reg_release,
@@ -2603,15 +2827,13 @@
     .mmap            = generic_file_mmap,
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
-# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
 /** @todo This code is known to cause caching of data which should not be
- * cached.  Investigate. */
+ * cached.  Investigate --
+ * bird: Part of this was using generic page cache functions for
+ * implementing .aio_read/write.  Fixed that (see above). */
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23)
     .splice_read     = vbsf_splice_read,
 # else
     .sendfile        = generic_file_sendfile,
-# endif
-    .aio_read        = generic_file_aio_read,
-    .aio_write       = generic_file_aio_write,
 # endif
 #endif
@@ -2623,12 +2845,22 @@
 };
 
+
+/**
+ * Inodes operations for regular files.
+ */
 struct inode_operations vbsf_reg_iops = {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 18)
-    .getattr = vbsf_inode_getattr,
+    .getattr    = vbsf_inode_getattr,
 #else
     .revalidate = vbsf_inode_revalidate,
 #endif
-    .setattr = vbsf_inode_setattr,
+    .setattr    = vbsf_inode_setattr,
 };
+
+
+
+/*********************************************************************************************************************************
+*   Address Space Operations on Regular Files (for mmap)                                                                         *
+*********************************************************************************************************************************/
 
 
@@ -2769,4 +3001,5 @@
     return err;
 }
+
 
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
@@ -2794,4 +3027,5 @@
 }
 # endif /* KERNEL_VERSION >= 2.6.24 */
+
 
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10)
@@ -2831,6 +3065,6 @@
  */
 struct address_space_operations vbsf_reg_aops = {
-    .readpage = vbsf_readpage,
-    .writepage = vbsf_writepage,
+    .readpage       = vbsf_readpage,
+    .writepage      = vbsf_writepage,
     /** @todo Need .writepages if we want msync performance...  */
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 12)
@@ -2838,12 +3072,12 @@
 # endif
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-    .write_begin = vbsf_write_begin,
-    .write_end = simple_write_end,
+    .write_begin    = vbsf_write_begin,
+    .write_end      = simple_write_end,
 # else
-    .prepare_write = simple_prepare_write,
-    .commit_write = simple_commit_write,
+    .prepare_write  = simple_prepare_write,
+    .commit_write   = simple_commit_write,
 # endif
 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10)
-    .direct_IO = vbsf_direct_IO,
+    .direct_IO      = vbsf_direct_IO,
 # endif
 };
Index: trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h	(revision 77872)
+++ trunk/src/VBox/Additions/linux/sharedfolders/vfsmod.h	(revision 77873)
@@ -356,7 +356,17 @@
 
 /**
+ * Invalidates the update TTL for the given directory entry so that it is
+ * revalidate the next time it is used.
+ * @param   pDirEntry   The directory entry cache entry to invalidate.
+ */
+DECLINLINE(void) vbsf_dentry_invalidate_ttl(struct dentry *pDirEntry)
+{
+    vbsf_dentry_set_update_jiffies(pDirEntry, jiffies - INT32_MAX / 2);
+}
+
+/**
  * Increase the time-to-live of @a pDirEntry and all ancestors.
- * @param   pDirEntry           The directory entry cache entry which ancestors
- *                  we should increase the TTL for.
+ * @param   pDirEntry   The directory entry cache entry which ancestors
+ *                      we should increase the TTL for.
  */
 DECLINLINE(void) vbsf_dentry_chain_increase_ttl(struct dentry *pDirEntry)
@@ -375,6 +385,6 @@
 /**
  * Increase the time-to-live of all ancestors.
- * @param   pDirEntry           The directory entry cache entry which ancestors
- *                  we should increase the TTL for.
+ * @param   pDirEntry   The directory entry cache entry which ancestors
+ *                      we should increase the TTL for.
  */
 DECLINLINE(void) vbsf_dentry_chain_increase_parent_ttl(struct dentry *pDirEntry)
