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/7789

Thank You,
rbraakman

[This message was auto-generated]

---

Request # 7789:

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

State: review at 2013-02-01T10:39:53 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,7 @@
+* 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
+

new:
----
  vbox-fix-restat.diff
  vbox-handles.diff
  vbox-less-restat.diff
  vbox-mmap.diff

spec files:
-----------
--- virtualbox.spec
+++ virtualbox.spec
@@ -109,6 +109,10 @@
 Patch103:       vbox-disable-updates.diff
 #use pie/fPIE for setuid binaries (bnc#743143) 
 Patch104:       vbox-fpie.diff
+Patch201:       vbox-fix-restat.diff
+Patch202:       vbox-less-restat.diff
+Patch203:       vbox-handles.diff
+Patch204:       vbox-mmap.diff
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 #PreReq:         pwdutils permissions
 Requires:       %{name}-host-kmp = %version
@@ -171,7 +175,10 @@
 #Y%patch101
 %patch103
 %patch104 -p1
-#Y%patch105 -p1
+%patch201 -p1
+%patch202 -p1
+%patch203 -p1
+%patch204 -p1
 #copy user manual
 %__cp %{S:1} UserManual.pdf
 #copy kbuild config
@@ -258,6 +265,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-fix-restat.diff (new)
--- vbox-fix-restat.diff
+++ vbox-fix-restat.diff
@@ -0,0 +1,18 @@
+commit 96893793b5d3636198b36f531d328970ce40331d
+Author: Richard Braakman <[email protected]>
+Date:   Fri Jan 25 11:33:47 2013 +0200
+
+    Bugfix: set force_restat back to 0 when restatting
+
+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-handles.diff (new)
--- vbox-handles.diff
+++ vbox-handles.diff
@@ -0,0 +1,215 @@
+commit 6dfd0c7549b3406e0bd94c6417ba590249f7f60e
+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,56 @@
+commit 05d5aa0d4f45d2a60ce22a0b2d5df8353429d744
+Author: Richard Braakman <[email protected]>
+Date:   Tue Jan 29 14:57:49 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.
+
+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;

++++++ vbox-mmap.diff (new)
--- vbox-mmap.diff
+++ vbox-mmap.diff
@@ -0,0 +1,151 @@
+diff --git a/src/VBox/Additions/linux/sharedfolders/regops.c 
b/src/VBox/Additions/linux/sharedfolders/regops.c
+index db1641b..094d277 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"
+@@ -329,25 +329,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)
+@@ -489,7 +486,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)
+@@ -510,7 +507,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
+@@ -534,7 +532,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;
+@@ -544,24 +544,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;
+ }
+@@ -689,8 +716,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);



Reply via email to