I have made the following changes intended for :
  CE:Adaptation:x86-generic / virtualbox

Please review and accept or decline.
BOSS has already run some checks on this request.
See the "Messages from BOSS" section below.

https://build.pub.meego.com//request/show/7849

Thank You,
rbraakman

[This message was auto-generated]

---

Request # 7849:

Messages from BOSS:
     WARNING check_package_is_complete_sources (virtualbox) failed: No dsc file 
found
Extra source files: boss.conf, vbox-slow-logging.diff, virtualbox.changes_suse. 

State: review at 2013-02-11T19:22:58 by bossbot

Reviews:
       accepted by bossbot : Prechecks succeeded.
       new for CE-maintainers : Please replace this text with a review and 
approve/reject the review (not the SR). BOSS will take care of the rest

Changes:
  submit: home:rbraakman:branches:CE:Adaptation:x86-generic / virtualbox -> 
CE:Adaptation:x86-generic / virtualbox
  
changes files:
--------------
--- virtualbox.changes
+++ virtualbox.changes
@@ -0,0 +1,8 @@
+* Fri Feb 01 2013  Richard Braakman <[email protected]> - 4.2.4
+- Ensure build failure if guest modules do not compile
+- [vboxsf]
+  Bugfixes to shared folders module
+  Enable writable mmap (needed by zypper, building kernel, probably more)
+  Performance improvements, it is now about 40% slower than guest-native
+  Use page cache when reading
+

new:
----
  vbox-handles.diff
  vbox-less-restat.diff
  vbox-mmap-02.diff
  vbox-mmap.diff
  vbox-pagecache.diff
  vbox-physread.diff
  vbox-readpages.diff
  vbox-slow-logging.diff

spec files:
-----------
--- virtualbox.spec
+++ virtualbox.spec
@@ -109,6 +109,13 @@
 Patch103:       vbox-disable-updates.diff
 #use pie/fPIE for setuid binaries (bnc#743143) 
 Patch104:       vbox-fpie.diff
+Patch201:       vbox-less-restat.diff
+Patch202:       vbox-handles.diff
+Patch203:       vbox-physread.diff
+Patch204:       vbox-mmap.diff
+Patch205:       vbox-mmap-02.diff
+Patch206:       vbox-pagecache.diff
+Patch207:       vbox-readpages.diff
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 #PreReq:         pwdutils permissions
 Requires:       %{name}-host-kmp = %version
@@ -171,7 +178,13 @@
 #Y%patch101
 %patch103
 %patch104 -p1
-#Y%patch105 -p1
+%patch201 -p1
+%patch202 -p1
+%patch203 -p1
+%patch204 -p1
+%patch205 -p1
+%patch206 -p1
+%patch207 -p1
 #copy user manual
 %__cp %{S:1} UserManual.pdf
 #copy kbuild config
@@ -258,6 +271,11 @@
 for module_name in modules_build_dir/*/.
 do
     %__make -C $KERNEL_DIR modules_install M=$(dirname $PWD/$module_name)
+    if [ ! -f "$INSTALL_MOD_PATH"/lib/modules/*/vbox/$(basename $(dirname 
$module_name)).* ]
+    then
+        echo "Failed to build $module_name"
+        exit 1
+    fi
 done
 # Clean up spurious stuff
 rm -f %{buildroot}/lib/modules/*/modules.*

other changes:
--------------

++++++ vbox-handles.diff (new)
--- vbox-handles.diff
+++ vbox-handles.diff
@@ -0,0 +1,215 @@
+commit 3fbf480c55f1a6e7049d333c48fdb0ecb550e99b
+Author: Richard Braakman <[email protected]>
+Date:   Thu Jan 31 01:15:25 2013 +0200
+
+    vboxsf: make sure writepage still works after concurrent open/close
+
+diff --git a/src/VBox/Additions/linux/sharedfolders/dirops.c 
b/src/VBox/Additions/linux/sharedfolders/dirops.c
+index d0d7b85..5e32135 100644
+--- a/src/VBox/Additions/linux/sharedfolders/dirops.c
++++ b/src/VBox/Additions/linux/sharedfolders/dirops.c
+@@ -358,8 +358,10 @@ static struct dentry *sf_lookup(struct inode *parent, 
struct dentry *dentry
+             err = -ENOMEM;
+             goto fail1;
+         }
++        INIT_LIST_HEAD(&sf_new_i->handles);
+         sf_new_i->handle = SHFL_HANDLE_NIL;
+         sf_new_i->force_reread = 0;
++        sf_new_i->force_restat = 0;
+ 
+         ino = iunique(parent->i_sb, 1);
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+@@ -458,6 +460,7 @@ static int sf_instantiate(struct inode *parent, struct 
dentry *dentry,
+ #else
+     dentry->d_op = &sf_dentry_ops;
+ #endif
++    INIT_LIST_HEAD(&sf_new_i->handles);
+     sf_new_i->force_restat = 0;
+     sf_new_i->force_reread = 0;
+ 
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index 1ba03e3..db1641b 100644
+--- a/src/VBox/Additions/linux/sharedfolders/regops.c
++++ b/src/VBox/Additions/linux/sharedfolders/regops.c
+@@ -294,21 +294,6 @@ static int sf_reg_open(struct inode *inode, struct file 
*file)
+         return -ENOMEM;
+     }
+ 
+-    /* Already open? */
+-    if (sf_i->handle != SHFL_HANDLE_NIL)
+-    {
+-        /*
+-         * This inode was created with sf_create_aux(). Check the CreateFlags:
+-         * O_CREAT, O_TRUNC: inherent true (file was just created). Not sure
+-         * about the access flags (SHFL_CF_ACCESS_*).
+-         */
+-        sf_r->handle = sf_i->handle;
+-        sf_i->handle = SHFL_HANDLE_NIL;
+-        sf_i->file = file;
+-        file->private_data = sf_r;
+-        return 0;
+-    }
+-
+     RT_ZERO(params);
+     params.Handle = SHFL_HANDLE_NIL;
+     /* We check the value of params.Handle afterwards to find out if
+@@ -371,6 +356,19 @@ static int sf_reg_open(struct inode *inode, struct file 
*file)
+         params.CreateFlags |= SHFL_CF_ACCESS_APPEND;
+     }
+ 
++    /* Already open? */
++    if (sf_i->handle != SHFL_HANDLE_NIL)
++    {
++        /*
++         * This inode was created with sf_create_aux(). Check the CreateFlags:
++         * O_CREAT, O_TRUNC: inherent true (file was just created). Not sure
++         * about the access flags (SHFL_CF_ACCESS_*).
++         */
++        sf_r->handle = sf_i->handle;
++        sf_i->handle = SHFL_HANDLE_NIL;
++        goto out;
++    }
++
+     params.Info.Attr.fMode = inode->i_mode;
+     LogFunc(("sf_reg_open: calling vboxCallCreate, file %s, flags=%#x, %#x\n",
+               sf_i->path->String.utf8 , file->f_flags, params.CreateFlags));
+@@ -404,7 +402,10 @@ static int sf_reg_open(struct inode *inode, struct file 
*file)
+         sf_init_inode(sf_g, inode, &params.Info);
+ 
+     sf_r->handle = params.Handle;
+-    sf_i->file = file;
++  out:
++    sf_r->createflags = params.CreateFlags;
++    INIT_LIST_HEAD(&sf_r->head);
++    list_add(&sf_r->head, &sf_i->handles);
+     file->private_data = sf_r;
+     return rc_linux;
+ }
+@@ -440,14 +441,16 @@ static int sf_reg_release(struct inode *inode, struct 
file *file)
+         && filemap_fdatawrite(inode->i_mapping) != -EIO)
+         filemap_fdatawait(inode->i_mapping);
+ #endif
++
++    list_del(&sf_r->head);
++
+     rc = vboxCallClose(&client_handle, &sf_g->map, sf_r->handle);
+     if (RT_FAILURE(rc))
+         LogFunc(("vboxCallClose failed rc=%Rrc\n", rc));
+ 
+-    kfree(sf_r);
+-    sf_i->file = NULL;
+     sf_i->handle = SHFL_HANDLE_NIL;
+     file->private_data = NULL;
++    kfree(sf_r);
+     return 0;
+ }
+ 
+@@ -600,6 +603,26 @@ struct inode_operations sf_reg_iops =
+ 
+ 
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
++/* Helper function to pick a suitable handle for pagecache operations.
++ * It picks the most recently opened handle for this inode that has the
++ * requested flags (SHFL_CF_ACCESS_READ or SHFL_CF_ACCESS_WRITE).
++ * Handles with SHFL_CF_ACCESS_APPEND are not suitable for paged use
++ * so they are always skipped.
++ */
++static struct sf_reg_info *sf_select_handle(struct inode *inode, u32 flags)
++{
++    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
++    struct sf_reg_info *sf_r;
++
++    list_for_each_entry(sf_r, &sf_i->handles, head)
++    {
++        if (   sf_r->handle != SHFL_HANDLE_NIL
++            && (sf_r->createflags & (flags | SHFL_CF_ACCESS_APPEND)) == flags)
++            return sf_r;
++    }
++    return NULL;
++}
++
+ static int sf_readpage(struct file *file, struct page *page)
+ {
+     struct inode *inode = file->f_dentry->d_inode;
+@@ -636,9 +659,7 @@ sf_writepage(struct page *page, struct writeback_control 
*wbc)
+     struct address_space *mapping = page->mapping;
+     struct inode *inode = mapping->host;
+     struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+-    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+-    struct file *file = sf_i->file;
+-    struct sf_reg_info *sf_r = file->private_data;
++    struct sf_reg_info *sf_r;
+     char *buf;
+     uint32_t nwritten = PAGE_SIZE;
+     int end_index = inode->i_size >> PAGE_SHIFT;
+@@ -647,6 +668,15 @@ sf_writepage(struct page *page, struct writeback_control 
*wbc)
+ 
+     TRACE();
+ 
++    sf_r = sf_select_handle(inode, SHFL_CF_ACCESS_WRITE);
++    if (unlikely(!sf_r))
++    {
++        /* At least the handle of whoever wrote to the page should
++         * still be available; see the wait in sf_reg_release() */
++        WARN_ONCE(1, "vboxsf: could not find handle for writepage");
++        return -EBADF;
++    }
++
+     if (page->index >= end_index)
+         nwritten = inode->i_size & (PAGE_SIZE-1);
+ 
+diff --git a/src/VBox/Additions/linux/sharedfolders/vfsmod.c 
b/src/VBox/Additions/linux/sharedfolders/vfsmod.c
+index 3c55136..79097c5 100644
+--- a/src/VBox/Additions/linux/sharedfolders/vfsmod.c
++++ b/src/VBox/Additions/linux/sharedfolders/vfsmod.c
+@@ -237,6 +237,7 @@ static int sf_read_super_aux(struct super_block *sb, void 
*data, int flags)
+         goto fail1;
+     }
+ 
++    INIT_LIST_HEAD(&sf_i->handles);
+     sf_i->handle = SHFL_HANDLE_NIL;
+     sf_i->path = kmalloc(sizeof(SHFLSTRING) + 1, GFP_KERNEL);
+     if (!sf_i->path)
+@@ -372,6 +373,7 @@ static void sf_clear_inode(struct inode *inode)
+     if (!sf_i)
+         return;
+ 
++    WARN_ON(!list_empty(&sf_i->handles));
+     BUG_ON(!sf_i->path);
+     kfree(sf_i->path);
+     kfree(sf_i);
+@@ -394,6 +396,7 @@ static void sf_evict_inode(struct inode *inode)
+     if (!sf_i)
+         return;
+ 
++    WARN_ON(!list_empty(&sf_i->handles));
+     BUG_ON(!sf_i->path);
+     kfree(sf_i->path);
+     kfree(sf_i);
+diff --git a/src/VBox/Additions/linux/sharedfolders/vfsmod.h 
b/src/VBox/Additions/linux/sharedfolders/vfsmod.h
+index 6a20eb7..c7df740 100644
+--- a/src/VBox/Additions/linux/sharedfolders/vfsmod.h
++++ b/src/VBox/Additions/linux/sharedfolders/vfsmod.h
+@@ -58,11 +58,11 @@ struct sf_inode_info
+     int force_restat;
+     /* directory content changed, update the whole directory on next 
sf_getdent */
+     int force_reread;
+-    /* file structure, only valid between open() and release() */
+-    struct file *file;
+     /* handle valid if a file was created with sf_create_aux until it will
(16 more lines skipped)

++++++ vbox-less-restat.diff (new)
--- vbox-less-restat.diff
+++ vbox-less-restat.diff
@@ -0,0 +1,71 @@
+commit bce05d945b143926548b8f8d289dfa3ec02f3788
+Author: Richard Braakman <[email protected]>
+Date:   Fri Jan 25 11:33:47 2013 +0200
+
+    linux sharedfolders: remove redundant statting
+    
+    There's no need to force a restat right after filling a new inode with stat
+    information. Also, open() can use the stat info it gets with the handle
+    instead of statting again.
+    
+    In addition, sf_inode_revalidate should actually set force_restat back to 0
+    when statting.
+
+diff --git a/src/VBox/Additions/linux/sharedfolders/dirops.c 
b/src/VBox/Additions/linux/sharedfolders/dirops.c
+index f7f558a..d0d7b85 100644
+--- a/src/VBox/Additions/linux/sharedfolders/dirops.c
++++ b/src/VBox/Additions/linux/sharedfolders/dirops.c
+@@ -458,7 +458,7 @@ static int sf_instantiate(struct inode *parent, struct 
dentry *dentry,
+ #else
+     dentry->d_op = &sf_dentry_ops;
+ #endif
+-    sf_new_i->force_restat = 1;
++    sf_new_i->force_restat = 0;
+     sf_new_i->force_reread = 0;
+ 
+     d_instantiate(dentry, inode);
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index 37adbcb..1ba03e3 100644
+--- a/src/VBox/Additions/linux/sharedfolders/regops.c
++++ b/src/VBox/Additions/linux/sharedfolders/regops.c
+@@ -302,7 +302,6 @@ static int sf_reg_open(struct inode *inode, struct file 
*file)
+          * O_CREAT, O_TRUNC: inherent true (file was just created). Not sure
+          * about the access flags (SHFL_CF_ACCESS_*).
+          */
+-        sf_i->force_restat = 1;
+         sf_r->handle = sf_i->handle;
+         sf_i->handle = SHFL_HANDLE_NIL;
+         sf_i->file = file;
+@@ -378,6 +377,7 @@ static int sf_reg_open(struct inode *inode, struct file 
*file)
+     rc = vboxCallCreate(&client_handle, &sf_g->map, sf_i->path, &params);
+     if (RT_FAILURE(rc))
+     {
++        sf_i->force_restat = 1;
+         LogFunc(("vboxCallCreate failed flags=%d,%#x rc=%Rrc\n",
+                   file->f_flags, params.CreateFlags, rc));
+         kfree(sf_r);
+@@ -398,9 +398,11 @@ static int sf_reg_open(struct inode *inode, struct file 
*file)
+             default:
+                 break;
+         }
++        sf_i->force_restat = 1;
+     }
++    else
++        sf_init_inode(sf_g, inode, &params.Info);
+ 
+-    sf_i->force_restat = 1;
+     sf_r->handle = params.Handle;
+     sf_i->file = file;
+     file->private_data = sf_r;
+diff --git a/src/VBox/Additions/linux/sharedfolders/utils.c 
b/src/VBox/Additions/linux/sharedfolders/utils.c
+index aa9c396..7ba8276 100644
+--- a/src/VBox/Additions/linux/sharedfolders/utils.c
++++ b/src/VBox/Additions/linux/sharedfolders/utils.c
+@@ -238,6 +238,7 @@ int sf_inode_revalidate(struct dentry *dentry)
+             return 0;
+     }
+ 
++    sf_i->force_restat = 0;
+     err = sf_stat(__func__, sf_g, sf_i->path, &info, 1);
+     if (err)
+         return err;

++++++ vbox-mmap-02.diff (new)
--- vbox-mmap-02.diff
+++ vbox-mmap-02.diff
@@ -0,0 +1,53 @@
+commit 7d8a6d68c286e3544645a54d5fcc14f1de7b16f4
+Author: Richard Braakman <[email protected]>
+Date:   Fri Feb 1 00:18:24 2013 +0200
+
+    sharedfolders bugfix: set access read/write even if some bits already set
+    
+    In sf_reg_open(), a file opened with O_TRUNC|O_RDWR wouldn't get the
+    SHFL_CF_ACCESS_READ flag because of the logic that skipped processing
+    the O_RDWR after seeing O_TRUNC. This is wrong, and it shows up with
+    the new pagecache code because the handle is not flagged as readable.
+
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index c3b314e..c39fc97 100644
+--- a/src/VBox/Additions/linux/sharedfolders/regops.c
++++ b/src/VBox/Additions/linux/sharedfolders/regops.c
+@@ -341,25 +341,22 @@ static int sf_reg_open(struct inode *inode, struct file 
*file)
+         }
+     }
+ 
+-    if (!(params.CreateFlags & SHFL_CF_ACCESS_READWRITE))
++    switch (file->f_flags & O_ACCMODE)
+     {
+-        switch (file->f_flags & O_ACCMODE)
+-        {
+-            case O_RDONLY:
+-                params.CreateFlags |= SHFL_CF_ACCESS_READ;
+-                break;
++        case O_RDONLY:
++            params.CreateFlags |= SHFL_CF_ACCESS_READ;
++            break;
+ 
+-            case O_WRONLY:
+-                params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
+-                break;
++        case O_WRONLY:
++            params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
++            break;
+ 
+-            case O_RDWR:
+-                params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
+-                break;
++        case O_RDWR:
++            params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
++            break;
+ 
+-            default:
+-                BUG ();
+-        }
++        default:
++            BUG ();
+     }
+ 
+     if (file->f_flags & O_APPEND)

++++++ vbox-mmap.diff (new)
--- vbox-mmap.diff
+++ vbox-mmap.diff
@@ -0,0 +1,123 @@
+commit c1e45e725b91bc4e03d7e3acc94673ea7b16d762
+Author: Richard Braakman <[email protected]>
+Date:   Tue Jan 29 21:48:13 2013 +0200
+
+    [vboxsf] support writable mmap
+    
+    This is mainly so that guest processes can use the shared folder as a 
backing
+    for database files and such. Don't expect coherence if a file is 
simultaneously
+    mmapped on the host and guest sides.
+
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index a0586bd..c3b314e 100644
+--- a/src/VBox/Additions/linux/sharedfolders/regops.c
++++ b/src/VBox/Additions/linux/sharedfolders/regops.c
+@@ -16,7 +16,7 @@
+  */
+ 
+ /*
+- * Limitations: only COW memory mapping is supported
++ * Limitations: MAP_SHARED mmap does not notice changes made on the host.
+  */
+ 
+ #include "vfsmod.h"
+@@ -501,7 +501,7 @@ static struct page *sf_reg_nopage(struct vm_area_struct 
*vma, unsigned long vadd
+     /* Don't use GFP_HIGHUSER as long as sf_reg_read_aux() calls 
vboxCallRead()
+      * which works on virtual addresses. On Linux cannot reliably determine 
the
+      * physical address for high memory, see rtR0MemObjNativeLockKernel(). */
+-    page = alloc_page(GFP_USER);
++    page = find_or_create_page(inode->i_mapping, vmf->pgoff, GFP_USER);
+     if (!page) {
+         LogRelFunc(("failed to allocate page\n"));
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+@@ -522,7 +522,8 @@ static struct page *sf_reg_nopage(struct vm_area_struct 
*vma, unsigned long vadd
+     if (err)
+     {
+         kunmap(page);
+-        put_page(page);
++        unlock_page(page);
++        page_cache_release(page);
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+         return VM_FAULT_SIGBUS;
+ #else
+@@ -546,7 +547,9 @@ static struct page *sf_reg_nopage(struct vm_area_struct 
*vma, unsigned long vadd
+         memset(buf + nread, 0, PAGE_SIZE - nread);
+ 
+     flush_dcache_page(page);
++    SetPageUptodate(page);
+     kunmap(page);
++    unlock_page(page);
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+     vmf->page = page;
+     return 0;
+@@ -556,24 +559,51 @@ static struct page *sf_reg_nopage(struct vm_area_struct 
*vma, unsigned long vadd
+ #endif
+ }
+ 
++/**
++ * Prepare for a mmap page to be made writable.
++ * Check that the page is still there, and lock it if necessary to keep it 
there.
++ * Part of MAP_SHARED support.
++ *
++ * @returns VM_FAULT_LOCKED if the page is ready, otherwise VM_FAULT_NOPAGE.
++ */
++static int sf_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
++{
++    struct page *page = vmf->page;
++    struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
++    loff_t size;
++
++    TRACE();
++
++    lock_page(page);
++    size = i_size_read(inode);
++    if (page->mapping != inode->i_mapping || page_offset(page) > size)
++    {
++        /* file was truncated */
++        unlock_page(page);
++        return VM_FAULT_NOPAGE;
++    }
++
++    wait_on_page_writeback(page);
++    return VM_FAULT_LOCKED;
++}
++
+ static struct vm_operations_struct sf_vma_ops =
+ {
+ #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
+-    .fault = sf_reg_fault
++    .fault = sf_reg_fault,
+ #else
+-     .nopage = sf_reg_nopage
++     .nopage = sf_reg_nopage,
+ #endif
++    .page_mkwrite = sf_page_mkwrite
+ };
+ 
+ static int sf_reg_mmap(struct file *file, struct vm_area_struct *vma)
+ {
+-    TRACE();
+-    if (vma->vm_flags & VM_SHARED)
+-    {
+-        LogFunc(("shared mmapping not available\n"));
+-        return -EINVAL;
+-    }
++    struct sf_reg_info *sf_r = file->private_data;
+ 
++    TRACE();
++    if (sf_r->createflags & SHFL_CF_ACCESS_APPEND)
++        return -EINVAL; /* can't simulate page operations */
+     vma->vm_ops = &sf_vma_ops;
+     return 0;
+ }
+@@ -701,8 +731,8 @@ sf_writepage(struct page *page, struct writeback_control 
*wbc)
+         goto out;
+     }
+ 
+-    if (off > inode->i_size)
+-        inode->i_size = off;
++    if (off + nwritten > inode->i_size)
++        inode->i_size = off + nwritten;
+ 
+     if (PageError(page))
+         ClearPageError(page);

++++++ vbox-pagecache.diff (new)
--- vbox-pagecache.diff
+++ vbox-pagecache.diff
@@ -0,0 +1,205 @@
+commit ee6ca84b247485b40c375ebb7e29a046446374df
+Author: Richard Braakman <[email protected]>
+Date:   Thu Jan 31 19:19:22 2013 +0200
+
+    sharedfolders: read() from page cache
+
+diff --git a/src/VBox/Additions/linux/sharedfolders/dirops.c 
b/src/VBox/Additions/linux/sharedfolders/dirops.c
+index 5e32135..1ed25dc 100644
+--- a/src/VBox/Additions/linux/sharedfolders/dirops.c
++++ b/src/VBox/Additions/linux/sharedfolders/dirops.c
+@@ -450,9 +450,9 @@ static int sf_instantiate(struct inode *parent, struct 
dentry *dentry,
+         goto fail1;
+     }
+ 
++    SET_INODE_INFO(inode, sf_new_i);
+     sf_init_inode(sf_g, inode, info);
+     sf_new_i->path = path;
+-    SET_INODE_INFO(inode, sf_new_i);
+ 
+     dentry->d_time = jiffies;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index c39fc97..37849cf 100644
+--- a/src/VBox/Additions/linux/sharedfolders/regops.c
++++ b/src/VBox/Additions/linux/sharedfolders/regops.c
+@@ -147,6 +147,13 @@ static ssize_t sf_reg_read(struct file *file, char *buf, 
size_t size, loff_t *of
+     if (!size)
+         return 0;
+ 
++    /* Try reading from the page cache */
++    if (sf_r->generation == inode->i_generation)
++        return do_sync_read(file, buf, size, off);
++    else
++        printk("vboxsf: doing direct read, generation %u != %u\n",
++               sf_r->generation, inode->i_generation);
++
+     tmp = alloc_bounce_buffer(&tmp_size, size, __PRETTY_FUNCTION__);
+     if (!tmp)
+         return -ENOMEM;
+@@ -265,6 +272,18 @@ static ssize_t sf_reg_write(struct file *file, const char 
*buf, size_t size, lof
+             break;
+     }
+ 
++    /* force-invalidate the corresponding part of the page cache */
++    err = invalidate_inode_pages2_range(inode->i_mapping,
++                *off >> PAGE_CACHE_SHIFT,
++                (*off + total_bytes_written - 1) >> PAGE_CACHE_SHIFT);
++    if (err)
++    {
++        printk("vboxsf: could not invalidate inode page cache for %s\n",
++               sf_i->path->String.utf8);
++        /** @todo fall back on pagecache write here? */
++        inode->i_generation++; /* disable pagecache reads for current fds */
++    }
++
+     *off += total_bytes_written;
+     if (*off > inode->i_size)
+         inode->i_size = *off;
+@@ -408,11 +427,15 @@ static int sf_reg_open(struct inode *inode, struct file 
*file)
+         sf_i->force_restat = 1;
+     }
+     else
++    {
++        sf_revalidate_mapping(inode, &params.Info);
+         sf_init_inode(sf_g, inode, &params.Info);
++    }
+ 
+     sf_r->handle = params.Handle;
+   out:
+     sf_r->createflags = params.CreateFlags;
++    sf_r->generation = inode->i_generation;
+     INIT_LIST_HEAD(&sf_r->head);
+     list_add(&sf_r->head, &sf_i->handles);
+     file->private_data = sf_r;
+@@ -674,6 +697,15 @@ static int sf_readpage(struct file *file, struct page 
*page)
+ 
+     TRACE();
+ 
++    sf_r = sf_select_handle(inode, SHFL_CF_ACCESS_READ);
++    if (unlikely(!sf_r))
++    {
++        struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
++        WARN(1, "vboxsf: could not find handle for readpage for %s",
++             sf_i->path->String.utf8);
++        sf_r = file->private_data;
++    }
++
+     buf = kmap(page);
+     ret = sf_reg_read_aux(__func__, sf_g, sf_r, buf, &nread, off);
+     if (ret)
+diff --git a/src/VBox/Additions/linux/sharedfolders/utils.c 
b/src/VBox/Additions/linux/sharedfolders/utils.c
+index 7ba8276..d2be0c5 100644
+--- a/src/VBox/Additions/linux/sharedfolders/utils.c
++++ b/src/VBox/Additions/linux/sharedfolders/utils.c
+@@ -71,6 +71,7 @@ static void sf_timespec_from_ftime(RTTIMESPEC *ts, struct 
timespec *tv)
+ void sf_init_inode(struct sf_glob_info *sf_g, struct inode *inode,
+                    PSHFLFSOBJINFO info)
+ {
++    struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
+     PSHFLFSOBJATTR attr;
+     int mode;
+ 
+@@ -159,6 +160,49 @@ void sf_init_inode(struct sf_glob_info *sf_g, struct 
inode *inode,
+     sf_ftime_from_timespec(&inode->i_atime, &info->AccessTime);
+     sf_ftime_from_timespec(&inode->i_ctime, &info->ChangeTime);
+     sf_ftime_from_timespec(&inode->i_mtime, &info->ModificationTime);
++
++    if (attr->enmAdditional == SHFLFSOBJATTRADD_UNIX)
++    {
++        sf_i->host_dev = attr->u.Unix.INodeIdDevice;
++        sf_i->host_ino = attr->u.Unix.INodeId;
++    }
++}
++
++/* Check if the host-side inode is likely to have had content changes,
++ * so that we should throw away the cached pages. */
++void sf_revalidate_mapping(struct inode *inode, PSHFLFSOBJINFO info)
++{
++    struct timespec mtime;
++    PSHFLFSOBJATTR attr = &info->Attr;
++
++    TRACE();
++
++    if (i_size_read(inode) != info->cbObject)
++    {
++        spin_lock(&inode->i_lock);
++        truncate_setsize(inode, info->cbObject);
++        spin_unlock(&inode->i_lock);
++        goto out_invalid;
++    }
++
++    sf_ftime_from_timespec(&mtime, &info->ModificationTime);
++    if (timespec_compare(&inode->i_mtime, &mtime))
++        goto out_invalid;
++
++    if (attr->enmAdditional == SHFLFSOBJATTRADD_UNIX)
++    {
++        struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
++        if (   (sf_i->host_dev && sf_i->host_dev != 
attr->u.Unix.INodeIdDevice)
++            || (sf_i->host_ino && sf_i->host_ino != attr->u.Unix.INodeId))
++            goto out_invalid;
++    }
++
++    return;
++
++  out_invalid:
++    invalidate_inode_pages2(inode->i_mapping);
++    inode->i_generation++;
++    return;
+ }
+ 
+ int sf_stat(const char *caller, struct sf_glob_info *sf_g,
+@@ -244,6 +288,7 @@ int sf_inode_revalidate(struct dentry *dentry)
+         return err;
+ 
+     dentry->d_time = jiffies;
++    sf_revalidate_mapping(dentry->d_inode, &info);
+     sf_init_inode(sf_g, dentry->d_inode, &info);
+     return 0;
+ }
+diff --git a/src/VBox/Additions/linux/sharedfolders/vfsmod.c 
b/src/VBox/Additions/linux/sharedfolders/vfsmod.c
+index 79097c5..ef4daa9 100644
+--- a/src/VBox/Additions/linux/sharedfolders/vfsmod.c
++++ b/src/VBox/Additions/linux/sharedfolders/vfsmod.c
+@@ -300,8 +300,8 @@ static int sf_read_super_aux(struct super_block *sb, void 
*data, int flags)
+         goto fail4;
+     }
+ 
+-    sf_init_inode(sf_g, iroot, &fsinfo);
+     SET_INODE_INFO(iroot, sf_i);
++    sf_init_inode(sf_g, iroot, &fsinfo);
+ 
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 25)
+     unlock_new_inode(iroot);
+diff --git a/src/VBox/Additions/linux/sharedfolders/vfsmod.h 
b/src/VBox/Additions/linux/sharedfolders/vfsmod.h
+index c7df740..62fb489 100644
+--- a/src/VBox/Additions/linux/sharedfolders/vfsmod.h
++++ b/src/VBox/Additions/linux/sharedfolders/vfsmod.h
+@@ -63,6 +63,10 @@ struct sf_inode_info
+     SHFLHANDLE handle;
+     /* list of sf_reg_info for open files, most recent first */
+     struct list_head handles;
++    /* identification of host-side inode, to detect if it changed */
++    /* these can be 0 if not known yet */
++    RTINODE host_ino;
++    RTDEV host_dev;
+ };
+ 
+ struct sf_dir_info
+@@ -84,6 +88,7 @@ struct sf_reg_info
+     SHFLHANDLE handle;
+     u32 createflags; /* SHFL_CF_ flags for this handle */
+     struct list_head head; /* starts at sf_i->handles */
++    u32 generation;
+ };
+ 
+ /* globals */
+@@ -103,6 +108,7 @@ extern void sf_init_inode(struct sf_glob_info *sf_g, 
struct inode *inode,
+ extern int  sf_stat(const char *caller, struct sf_glob_info *sf_g,
(6 more lines skipped)

++++++ vbox-physread.diff (new)
--- vbox-physread.diff
+++ vbox-physread.diff
@@ -0,0 +1,230 @@
+commit 1d3a5cd2f8d4d061e7aa82f08a3470a074f1f66b
+Author: Richard Braakman <[email protected]>
+Date:   Sun Feb 3 11:30:43 2013 +0200
+
+    vboxsf: speed up reads by using multipage transfers
+
+diff --git 
a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c 
b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
+index 03af236..b49e217 100644
+--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
++++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.c
+@@ -524,6 +524,53 @@ DECLVBGL(int) VbglR0SfWritePhysCont(PVBSFCLIENT pClient, 
PVBSFMAP pMap, SHFLHAND
+ 
+ }
+ 
++DECLVBGL(int) VbglR0SfReadPhysCont(PVBSFCLIENT pClient, PVBSFMAP pMap, 
SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer, RTCCPHYS PhysBuffer)
++{
++    uint32_t            cbToRead = *pcbBuffer;
++    uint32_t            cPages   = RT_ALIGN_32((PhysBuffer & 
PAGE_OFFSET_MASK) + cbToRead, PAGE_SIZE) >> PAGE_SHIFT;
++    uint32_t            cbData   = sizeof(VBoxSFRead) + 
RT_UOFFSETOF(HGCMPageListInfo, aPages[cPages]);
++    VBoxSFRead         *pData    = (VBoxSFRead *)RTMemTmpAlloc(cbData);
++    HGCMPageListInfo   *pPgLst   = (HGCMPageListInfo *)(pData + 1);
++    uint32_t            iPage;
++    int                 rc;
++
++    if (RT_UNLIKELY(!pData))
++        return VERR_NO_TMP_MEMORY;
++
++    VBOX_INIT_CALL(&pData->callInfo, READ, pClient);
++
++    pData->root.type                      = VMMDevHGCMParmType_32bit;
++    pData->root.u.value32                 = pMap->root;
++
++    pData->handle.type                    = VMMDevHGCMParmType_64bit;
++    pData->handle.u.value64               = hFile;
++    pData->offset.type                    = VMMDevHGCMParmType_64bit;
++    pData->offset.u.value64               = offset;
++    pData->cb.type                        = VMMDevHGCMParmType_32bit;
++    pData->cb.u.value32                   = cbToRead;
++    pData->buffer.type                    = VMMDevHGCMParmType_PageList;
++    pData->buffer.u.PageList.size         = cbToRead;
++    pData->buffer.u.PageList.offset       = sizeof(VBoxSFRead);
++
++    pPgLst->flags = VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST;
++    pPgLst->offFirstPage = (uint16_t)(PhysBuffer & PAGE_OFFSET_MASK);
++    pPgLst->cPages = cPages;
++    PhysBuffer &= ~(RTCCPHYS)PAGE_OFFSET_MASK;
++    for (iPage = 0; iPage < cPages; iPage++, PhysBuffer += PAGE_SIZE)
++        pPgLst->aPages[iPage] = PhysBuffer;
++
++    rc = VbglHGCMCall (pClient->handle, &pData->callInfo, cbData);
++    if (RT_SUCCESS (rc))
++    {
++        rc = pData->callInfo.result;
++        *pcbBuffer = pData->cb.u.value32;
++    }
++
++    RTMemTmpFree(pData);
++    return rc;
++
++}
++
+ DECLVBGL(int) vboxCallFlush(PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE 
hFile)
+ {
+     int rc = VINF_SUCCESS;
+diff --git 
a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h 
b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h
+index 3947a13..4d7e4a9 100644
+--- a/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h
++++ b/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR0LibSharedFolders.h
+@@ -174,6 +174,7 @@ DECLVBGL(int) vboxCallFlush (PVBSFCLIENT pClient, PVBSFMAP 
pMap, SHFLHANDLE hFil
+ DECLVBGL(int) vboxCallRead (PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE 
hFile, uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked);
+ DECLVBGL(int) vboxCallWrite (PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE 
hFile, uint64_t offset, uint32_t *pcbBuffer, uint8_t *pBuffer, bool fLocked);
+ DECLVBGL(int) VbglR0SfWritePhysCont(PVBSFCLIENT pClient, PVBSFMAP pMap, 
SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer, RTCCPHYS PhysBuffer);
++DECLVBGL(int) VbglR0SfReadPhysCont(PVBSFCLIENT pClient, PVBSFMAP pMap, 
SHFLHANDLE hFile, uint64_t offset, uint32_t *pcbBuffer, RTCCPHYS PhysBuffer);
+ 
+ DECLVBGL(int) vboxCallLock (PVBSFCLIENT pClient, PVBSFMAP pMap, SHFLHANDLE 
hFile, uint64_t offset, uint64_t cbSize, uint32_t fLock);
+ 
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index db1641b..a0586bd 100644
+--- a/src/VBox/Additions/linux/sharedfolders/regops.c
++++ b/src/VBox/Additions/linux/sharedfolders/regops.c
+@@ -21,8 +21,8 @@
+ 
+ #include "vfsmod.h"
+ 
+-static void *alloc_bounce_buffer(size_t *tmp_sizep, PRTCCPHYS physp, size_t
+-                                 xfer_size, const char *caller)
++static void *
++alloc_bounce_buffer(size_t *tmp_sizep, size_t xfer_size, const char *caller)
+ {
+     size_t tmp_size;
+     void *tmp;
+@@ -45,7 +45,6 @@ static void *alloc_bounce_buffer(size_t *tmp_sizep, 
PRTCCPHYS physp, size_t
+     }
+ 
+     *tmp_sizep = tmp_size;
+-    *physp = virt_to_phys(tmp);
+     return tmp;
+ }
+ 
+@@ -56,37 +55,61 @@ static void free_bounce_buffer(void *tmp)
+ 
+ 
+ /* fops */
++
++/* Input buf must be physically contiguous memory */
+ static int sf_reg_read_aux(const char *caller, struct sf_glob_info *sf_g,
+                            struct sf_reg_info *sf_r, void *buf,
+                            uint32_t *nread, uint64_t pos)
+ {
+-    /** @todo bird: yes, kmap() and kmalloc() input only. Since the buffer is
+-     *        contiguous in physical memory (kmalloc or single page), we 
should
+-     *        use a physical address here to speed things up. */
+-    int rc = vboxCallRead(&client_handle, &sf_g->map, sf_r->handle,
+-                          pos, nread, buf, false /* already locked? */);
+-    if (RT_FAILURE(rc))
++    if (VbglR0CanUsePhysPageList())
++    {
++        int rc = VbglR0SfReadPhysCont(&client_handle, &sf_g->map, 
sf_r->handle,
++                                      pos, nread, virt_to_phys(buf));
++        if (RT_FAILURE(rc))
++        {
++            LogFunc(("VbglR0SfReadPhysCont failed. caller=%s, rc=%Rrc\n",
++                     caller, rc));
++            return -EPROTO;
++        }
++    }
++    else
+     {
+-        LogFunc(("vboxCallRead failed. caller=%s, rc=%Rrc\n", caller, rc));
+-        return -EPROTO;
++        int rc = vboxCallRead(&client_handle, &sf_g->map, sf_r->handle,
++                              pos, nread, buf, false /* already locked? */);
++        if (RT_FAILURE(rc))
++        {
++            LogFunc(("vboxCallRead failed. caller=%s, rc=%Rrc\n", caller, 
rc));
++            return -EPROTO;
++        }
+     }
+     return 0;
+ }
+ 
++/* Input buf must be physically contiguous memory */
+ static int sf_reg_write_aux(const char *caller, struct sf_glob_info *sf_g,
+                             struct sf_reg_info *sf_r, void *buf,
+                             uint32_t *nwritten, uint64_t pos)
+ {
+-    /** @todo bird: yes, kmap() and kmalloc() input only. Since the buffer is
+-     *        contiguous in physical memory (kmalloc or single page), we 
should
+-     *        use a physical address here to speed things up. */
+-    int rc = vboxCallWrite(&client_handle, &sf_g->map, sf_r->handle,
+-                           pos, nwritten, buf, false /* already locked? */);
+-    if (RT_FAILURE(rc))
++    if (VbglR0CanUsePhysPageList())
+     {
+-        LogFunc(("vboxCallWrite failed. caller=%s, rc=%Rrc\n",
+-                    caller, rc));
+-        return -EPROTO;
++        int rc = VbglR0SfWritePhysCont(&client_handle, &sf_g->map, 
sf_r->handle,
++                                    pos, nwritten, virt_to_phys(buf));
++        if (RT_FAILURE(rc))
++        {
++            LogFunc(("VbglR0SfWritePhysCont failed. caller=%s, rc=%Rrc\n",
++                     caller, rc));
++            return -EPROTO;
++        }
++    }
++    else
++    {
++        int rc = vboxCallWrite(&client_handle, &sf_g->map, sf_r->handle,
++                           pos, nwritten, buf, false /* already locked? */);
++        if (RT_FAILURE(rc))
++        {
++            LogFunc(("vboxCallWrite failed. caller=%s, rc=%Rrc\n", caller, 
rc));
++            return -EPROTO;
++        }
+     }
+     return 0;
+ }
+@@ -104,7 +127,6 @@ static ssize_t sf_reg_read(struct file *file, char *buf, 
size_t size, loff_t *of
+ {
+     int err;
+     void *tmp;
+-    RTCCPHYS tmp_phys;
+     size_t tmp_size;
+     size_t left = size;
+     ssize_t total_bytes_read = 0;
+@@ -125,7 +147,7 @@ static ssize_t sf_reg_read(struct file *file, char *buf, 
size_t size, loff_t *of
+     if (!size)
+         return 0;
+ 
+-    tmp = alloc_bounce_buffer(&tmp_size, &tmp_phys, size, 
__PRETTY_FUNCTION__);
++    tmp = alloc_bounce_buffer(&tmp_size, size, __PRETTY_FUNCTION__);
+     if (!tmp)
+         return -ENOMEM;
+ 
+@@ -179,7 +201,6 @@ static ssize_t sf_reg_write(struct file *file, const char 
*buf, size_t size, lof
+ {
+     int err;
+     void *tmp;
(31 more lines skipped)

++++++ vbox-readpages.diff (new)
--- vbox-readpages.diff
+++ vbox-readpages.diff
@@ -0,0 +1,114 @@
+commit 2e991b96673cb5f6f2093a7ccbc94e403aad46d7
+Author: Richard Braakman <[email protected]>
+Date:   Sun Feb 3 02:38:15 2013 +0200
+
+    vboxsf: implement readpages() for efficiency
+
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index 37849cf..e9b2ace 100644
+--- a/src/VBox/Additions/linux/sharedfolders/regops.c
++++ b/src/VBox/Additions/linux/sharedfolders/regops.c
+@@ -689,7 +689,7 @@ static int sf_readpage(struct file *file, struct page 
*page)
+ {
+     struct inode *inode = file->f_dentry->d_inode;
+     struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
+-    struct sf_reg_info *sf_r = file->private_data;
++    struct sf_reg_info *sf_r;
+     uint32_t nread = PAGE_SIZE;
+     char *buf;
+     loff_t off = ((loff_t)page->index) << PAGE_SHIFT;
+@@ -724,6 +724,87 @@ static int sf_readpage(struct file *file, struct page 
*page)
+     return 0;
+ }
+ 
++/*
++ * Read a list of pages into the page cache.
++ * This is only used for readahead, so it's ok to give up.
++ * The caller will fall back on readpage() for the important pages.
++ */
++static int sf_readpages(struct file *file, struct address_space *mapping,
++                        struct list_head *pages, unsigned nr_pages)
++{
++    struct inode *inode = file->f_dentry->d_inode;
++    struct sf_glob_info *sf_g = GET_GLOB_INFO(inode->i_sb);
++    struct sf_reg_info *sf_r;
++    struct page *physbuf = 0;
++    int bufsize;
++    pgoff_t buf_startindex = 0;
++    pgoff_t pages_in_buf = 0;
++    int err = 0;
++
++    TRACE();
++
++    if (nr_pages <= 1)
++        return 0; /* either nothing to do or not worth batching */
++
++    sf_r = sf_select_handle(inode, SHFL_CF_ACCESS_READ);
++    if (unlikely(!sf_r))
++    {
++        struct sf_inode_info *sf_i = GET_INODE_INFO(inode);
++        WARN(1, "vboxsf: could not find handle for readpages for %s",
++             sf_i->path->String.utf8);
++        sf_r = file->private_data;
++    }
++
++    /*
++     * Performance really depends on the number of calls we make to the host, 
so
++     * allocate a physically contiguous buffer to read multiple pages per 
call.
++     */
++    /* first try to get everything in one read */
++    bufsize = PAGE_SIZE * (list_entry(pages->next, struct page, lru)->index
++                           - list_entry(pages->prev, struct page, 
lru)->index);
++    if (bufsize > 32 * PAGE_SIZE)
++        bufsize = 32 * PAGE_SIZE;  /* don't go crazy though */
++
++    physbuf = alloc_pages_exact(bufsize, GFP_KERNEL);
++    if (!physbuf)
++        return -ENOMEM; /* Memory pressure - best not to readahead at all */
++
++    while (!list_empty(pages))
++    {
++        struct page *page = list_first_entry(pages, struct page, lru);
++        loff_t off = (loff_t) page->index << PAGE_SHIFT;
++        list_del(&page->lru);
++        if (add_to_page_cache_lru(page, mapping, page->index, GFP_KERNEL))
++        {
++            page_cache_release(page);
++            continue;
++        }
++        page_cache_release(page);
++
++        /* read the next chunk if needed */
++        if (page->index >= buf_startindex + pages_in_buf)
++        {
++            uint32_t nread = bufsize;
++            err = sf_reg_read_aux(__func__, sf_g, sf_r, physbuf, &nread, off);
++            if (err || nread == 0)
++                break;
++            buf_startindex = page->index;
++            pages_in_buf = nread >> PAGE_SHIFT;
++            /* fix up possible partial page at end */
++            if (nread != PAGE_ALIGN(nread))
++            {
++                pages_in_buf++;
++                memset(physbuf + nread, 0, (pages_in_buf << PAGE_SHIFT) - 
nread);
++            }
++        }
++        copy_page(page_address(page),
++                  physbuf + ((page->index - buf_startindex) << PAGE_SHIFT));
++    }
++
++    free_pages_exact(physbuf, bufsize);
++    return err;
++}
++
+ static int
+ sf_writepage(struct page *page, struct writeback_control *wbc)
+ {
+@@ -828,5 +909,6 @@ struct address_space_operations sf_reg_aops =
+     .prepare_write = simple_prepare_write,
+     .commit_write  = simple_commit_write,
+ # endif
++    .readpages     = sf_readpages,
+ };
+ #endif

++++++ vbox-slow-logging.diff (new)
--- vbox-slow-logging.diff
+++ vbox-slow-logging.diff
@@ -0,0 +1,47 @@
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index c39fc97..7f73a67 100644
+--- a/src/VBox/Additions/linux/sharedfolders/regops.c
++++ b/src/VBox/Additions/linux/sharedfolders/regops.c
+@@ -63,6 +63,8 @@ static int sf_reg_read_aux(const char *caller, struct 
sf_glob_info *sf_g,
+ {
+     if (VbglR0CanUsePhysPageList())
+     {
++        TRACE();
++        printk("vboxsf starting phys read\n");
+         int rc = VbglR0SfReadPhysCont(&client_handle, &sf_g->map, 
sf_r->handle,
+                                       pos, nread, virt_to_phys(buf));
+         if (RT_FAILURE(rc))
+@@ -71,6 +73,7 @@ static int sf_reg_read_aux(const char *caller, struct 
sf_glob_info *sf_g,
+                      caller, rc));
+             return -EPROTO;
+         }
++        printk("vboxsf ended phys read\n");
+     }
+     else
+     {
+diff --git a/src/VBox/Additions/linux/sharedfolders/vfsmod.h 
b/src/VBox/Additions/linux/sharedfolders/vfsmod.h
+index c7df740..043c478 100644
+--- a/src/VBox/Additions/linux/sharedfolders/vfsmod.h
++++ b/src/VBox/Additions/linux/sharedfolders/vfsmod.h
+@@ -157,5 +157,21 @@ int sf_get_volume_info(struct super_block 
*sb,STRUCT_STATFS *stat);
+ # define SET_INODE_INFO(i, sf_i) (i)->u.generic_ip = sf_i
+ #endif
+ 
++#undef LogFunc
++#define LogFunc__(format, args...) do { \
++    if (strstr(format, "%Rrc")) { \
++        char *printkformat = kstrdup("%s: " format, GFP_KERNEL); \
++        char *p = printkformat; \
++        while ((p = strstr(p, "%Rrc"))) \
++            p[1] = 'd'; \
++        printk(printkformat, __func__, ##args); \
++        kfree(printkformat); \
++    } else { \
++        printk("%s: " format, __func__, ##args); \
++    } \
++} while (0)
++/* This strips the extra parentheses that are used with the real LogFunc */
++#define LogFunc(...) LogFunc__ __VA_ARGS__
++
+ #endif
+ 



Reply via email to