Index: trunk/src/VBox/Additions/linux/sharedfolders/regops.c
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/regops.c	(revision 77964)
+++ trunk/src/VBox/Additions/linux/sharedfolders/regops.c	(revision 77966)
@@ -76,4 +76,8 @@
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 12)
+# define PageUptodate(a_pPage) Page_Uptodate(a_pPage)
+#endif
+
 
 /*********************************************************************************************************************************
@@ -127,5 +131,5 @@
 *********************************************************************************************************************************/
 DECLINLINE(void) vbsf_put_page(struct page *pPage);
-DECLINLINE(void) vbsf_unlock_user_pages(struct page **papPages, size_t cPages, bool fSetDirty, bool fLockPgHack);
+static void vbsf_unlock_user_pages(struct page **papPages, size_t cPages, bool fSetDirty, bool fLockPgHack);
 static void vbsf_reg_write_sync_page_cache(struct address_space *mapping, loff_t offFile, uint32_t cbRange,
                                            uint8_t const *pbSrcBuf, struct page **papSrcPages,
@@ -530,4 +534,26 @@
 *   Misc                                                                                                                         *
 *********************************************************************************************************************************/
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 6)
+/** Any writable mappings? */
+DECLINLINE(bool) mapping_writably_mapped(struct address_space const *mapping)
+{
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 6)
+    return !list_empty(mapping->i_mmap_shared);
+# else
+    return mapping->i_mmap_shared != NULL;
+# endif
+}
+#endif
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 12)
+/** Missing in 2.4.x, so just stub it for now. */
+DECLINLINE(bool) PageWriteback(struct page const *page)
+{
+    return false;
+}
+#endif
+
 
 /**
@@ -1273,4 +1299,5 @@
     {
         struct page *pPage = papPages[cPages];
+        Assert((ssize_t)cPages >= 0);
         if (fSetDirty && !PageReserved(pPage))
             SetPageDirty(pPage);
@@ -1393,5 +1420,5 @@
 # else
     struct task_struct *pTask = current;
-    size_t cPagesLocked;
+    ssize_t cPagesLocked;
     down_read(&pTask->mm->mmap_sem);
     cPagesLocked = get_user_pages(pTask, pTask->mm, uPtrFrom, cPages, fWrite, 1 /*force*/, papPages, NULL);
@@ -1521,4 +1548,5 @@
             rc = VbglR0SfHostReqReadPgLst(pSuperInfo->map.root, pReq, sf_r->Handle.hHost, offFile, cbChunk, cPages);
 
+            Assert(cPages <= cMaxPages);
             vbsf_unlock_user_pages(papPages, cPages, true /*fSetDirty*/, fLockPgHack);
 
@@ -1565,4 +1593,5 @@
     if (pReq)
         VbglR0PhysHeapFree(pReq);
+    SFLOGFLOW(("vbsf_reg_read: returns %zd (%#zx), *off=%RX64 [lock]\n", cbRet, cbRet, *off));
     return cbRet;
 }
@@ -1627,4 +1656,5 @@
                     cbRet = -EPROTO;
                 VbglR0PhysHeapFree(pReq);
+                SFLOGFLOW(("vbsf_reg_read: returns %zd (%#zx), *off=%RX64 [embed]\n", cbRet, cbRet, *off));
                 return cbRet;
             }
@@ -1656,4 +1686,5 @@
                 VbglR0PhysHeapFree(pReq);
                 kfree(pvBounce);
+                SFLOGFLOW(("vbsf_reg_read: returns %zd (%#zx), *off=%RX64 [bounce]\n", cbRet, cbRet, *off));
                 return cbRet;
             }
@@ -1825,4 +1856,5 @@
                 vbsf_reg_write_sync_page_cache(inode->i_mapping, offFile, cbActual, NULL /*pbKrnlBuf*/,
                                                papPages, (uintptr_t)buf & PAGE_OFFSET_MASK, cPages);
+                Assert(cPages <= cMaxPages);
                 vbsf_unlock_user_pages(papPages, cPages, false /*fSetDirty*/, fLockPgHack);
 
@@ -1869,4 +1901,5 @@
     if (pReq)
         VbglR0PhysHeapFree(pReq);
+    SFLOGFLOW(("vbsf_reg_write: returns %zd (%#zx), *off=%RX64 [lock]\n", cbRet, cbRet, *off));
     return cbRet;
 }
@@ -1959,4 +1992,5 @@
 
             VbglR0PhysHeapFree(pReq);
+            SFLOGFLOW(("vbsf_reg_write: returns %zd (%#zx), *off=%RX64 [embed]\n", cbRet, cbRet, *off));
             return cbRet;
         }
@@ -1993,4 +2027,5 @@
                     VbglR0PhysHeapFree(pReq);
                     kfree(pvBounce);
+                    SFLOGFLOW(("vbsf_reg_write: returns %zd (%#zx), *off=%RX64 [bounce]\n", cbRet, cbRet, *off));
                     return cbRet;
                 }
@@ -1998,4 +2033,5 @@
             } else {
                 kfree(pvBounce);
+                SFLOGFLOW(("vbsf_reg_write: returns -EFAULT, *off=%RX64 [bounce]\n", *off));
                 return -EFAULT;
             }
@@ -3449,9 +3485,6 @@
 
 /*********************************************************************************************************************************
-*   Address Space Operations on Regular Files (for mmap)                                                                         *
+*   Address Space Operations on Regular Files (for mmap, sendfile, direct I/O)                                                   *
 *********************************************************************************************************************************/
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
 
 /**
@@ -3527,5 +3560,9 @@
  * fashion.
  */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 52)
 static int vbsf_writepage(struct page *page, struct writeback_control *wbc)
+#else
+static int vbsf_writepage(struct page *page)
+#endif
 {
     struct address_space   *mapping = page->mapping;
@@ -3536,5 +3573,5 @@
 
     SFLOGFLOW(("vbsf_writepage: inode=%p page=%p off=%#llx pHandle=%p (%#llx)\n",
-               inode, page,(uint64_t)page->index << PAGE_SHIFT, pHandle, pHandle->hHost));
+               inode, page, (uint64_t)page->index << PAGE_SHIFT, pHandle, pHandle ? pHandle->hHost : 0));
 
     if (pHandle) {
@@ -3585,4 +3622,5 @@
         if (s_cCalls++ < 16)
             printk("vbsf_writepage: no writable handle for %s..\n", sf_i->path->String.ach);
+        SetPageError(page);
         err = -EPROTO;
     }
@@ -3592,5 +3630,5 @@
 
 
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
 /**
  * Called when writing thru the page cache (which we shouldn't be doing).
@@ -3609,42 +3647,44 @@
         RTLogBackdoorPrintf("vboxsf: Unexpected call to vbsf_write_begin(pos=%#llx len=%#x flags=%#x)!  Please report.\n",
                     (unsigned long long)pos, len, flags);
-#  ifdef WARN_ON
+# ifdef WARN_ON
         WARN_ON(1);
-#  endif
+# endif
     }
     return simple_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
 }
-# endif /* KERNEL_VERSION >= 2.6.24 */
-
-
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10)
+#endif /* KERNEL_VERSION >= 2.6.24 */
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10)
 /**
  * This is needed to make open accept O_DIRECT as well as dealing with direct
  * I/O requests if we don't intercept them earlier.
  */
-#  if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)
 static ssize_t vbsf_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
-#  elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
 static ssize_t vbsf_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t offset)
-#  elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
 static ssize_t vbsf_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t offset)
-#  elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 6)
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 6)
 static ssize_t vbsf_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t offset, unsigned long nr_segs)
-#  elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 55)
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 55)
 static int vbsf_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t offset, unsigned long nr_segs)
-#  elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 41)
 static int vbsf_direct_IO(int rw, struct file *file, const struct iovec *iov, loff_t offset, unsigned long nr_segs)
-#  elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 35)
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 35)
 static int vbsf_direct_IO(int rw, struct inode *inode, const struct iovec *iov, loff_t offset, unsigned long nr_segs)
-#  elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 26)
+# elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 26)
 static int vbsf_direct_IO(int rw, struct inode *inode, char *buf, loff_t offset, size_t count)
-#  else
-static int vbsf_direct_IO(int rw, struct inode *inode, struct kiobuf *, unsigned long, int)
-#  endif
+# elif LINUX_VERSION_CODE == KERNEL_VERSION(2, 4, 21) && defined(I_NEW) /* RHEL3 Frankenkernel.  */
+static int vbsf_direct_IO(int rw, struct file *file, struct kiobuf *buf, unsigned long whatever1, int whatever2)
+# else
+static int vbsf_direct_IO(int rw, struct inode *inode, struct kiobuf *buf, unsigned long whatever1, int whatever2)
+# endif
 {
     TRACE();
     return -EINVAL;
 }
-# endif
+#endif
 
 /**
@@ -3657,19 +3697,18 @@
     .writepage      = vbsf_writepage,
     /** @todo Need .writepages if we want msync performance...  */
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 12)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 12)
     .set_page_dirty = __set_page_dirty_buffers,
-# endif
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
     .write_begin    = vbsf_write_begin,
     .write_end      = simple_write_end,
-# else
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 45)
     .prepare_write  = simple_prepare_write,
     .commit_write   = simple_commit_write,
-# endif
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10)
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 10)
     .direct_IO      = vbsf_direct_IO,
-# endif
+#endif
 };
 
-#endif /* LINUX_VERSION_CODE >= 2.6.0 */
-
+
Index: trunk/src/VBox/Additions/linux/sharedfolders/utils.c
===================================================================
--- trunk/src/VBox/Additions/linux/sharedfolders/utils.c	(revision 77964)
+++ trunk/src/VBox/Additions/linux/sharedfolders/utils.c	(revision 77966)
@@ -307,10 +307,4 @@
     sf_i->force_restat  = 0;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
-    inode->i_mapping->a_ops = &vbsf_reg_aops;
-# if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 19, 0)
-    inode->i_mapping->backing_dev_info = &pSuperInfo->bdi; /* This is needed for mmap. */
-# endif
-#endif
     if (RTFS_IS_DIRECTORY(pAttr->fMode)) {
         inode->i_mode = sf_file_mode_to_linux(pAttr->fMode, pSuperInfo->dmode, pSuperInfo->dmask, S_IFDIR);
@@ -332,4 +326,9 @@
         inode->i_op = &vbsf_reg_iops;
         inode->i_fop = &vbsf_reg_fops;
+        inode->i_mapping->a_ops = &vbsf_reg_aops;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 17) \
+ && LINUX_VERSION_CODE <  KERNEL_VERSION(4, 0, 0)
+        inode->i_mapping->backing_dev_info = &pSuperInfo->bdi; /* This is needed for mmap. */
+#endif
         set_nlink(inode, 1);
     }
@@ -815,5 +814,8 @@
          */
         unsigned fAttrs = iattr->ia_valid;
-        if (   (fAttrs & ~ATTR_FILE) == (ATTR_SIZE | ATTR_MTIME | ATTR_CTIME)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 15)
+        fAttrs &= ~ATTR_FILE;
+#endif
+        if (   fAttrs == (ATTR_SIZE | ATTR_MTIME | ATTR_CTIME)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
             || (fAttrs & (ATTR_OPEN | ATTR_SIZE)) == (ATTR_OPEN | ATTR_SIZE)
