rpms/open-vm-tools-kmod/devel open-vm-tools-130226-vmhgfs.patch, NONE, 1.1

Denis Leroy denis at rpmfusion.org
Sat Dec 20 13:33:50 CET 2008


Author: denis

Update of /cvs/free/rpms/open-vm-tools-kmod/devel
In directory se02.es.rpmfusion.net:/tmp/cvs-serv535

Added Files:
	open-vm-tools-130226-vmhgfs.patch 
Log Message:
Update to upstream 130226. Added new kernel module pvscsi. Added patch for vmhgfs compile

open-vm-tools-130226-vmhgfs.patch:

--- NEW FILE open-vm-tools-130226-vmhgfs.patch ---
--- modules/linux/vmhgfs/page.c
+++ modules/linux/vmhgfs/page.c
@@ -48,6 +48,15 @@
                            struct page *page,
                            unsigned pageFrom,
                            unsigned pageTo);
+static void HgfsDoWriteBegin(struct page *page,
+                             unsigned pageFrom,
+                             unsigned pageTo);
+static int HgfsDoWriteEnd(struct file *file,
+                          struct page *page,
+                          unsigned pageFrom,
+                          unsigned pageTo,
+                          loff_t writeTo,
+                          unsigned copied);
 
 /* HGFS address space operations. */
 static int HgfsReadpage(struct file *file,
@@ -58,6 +67,31 @@
 #else
 static int HgfsWritepage(struct page *page);
 #endif
+
+/*
+ * Write aop interface has changed in 2.6.28. Specifically,
+ * the page locking semantics and requirement to handle
+ * short writes. We already handle short writes, so no major
+ * changes needed. write_begin is expected to return a locked
+ * page and write_end is expected to unlock the page and drop
+ * the reference before returning.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+static int HgfsWriteBegin(struct file *file,
+                          struct address_space *mapping,
+                          loff_t pos,
+                          unsigned len,
+                          unsigned flags,
+                          struct page **page,
+                          void **clientData);
+static int HgfsWriteEnd(struct file *file,
+                        struct address_space *mapping,
+                        loff_t pos,
+                        unsigned len,
+                        unsigned copied,
+                        struct page *page,
+                        void *clientData);
+#else
 static int HgfsPrepareWrite(struct file *file,
                             struct page *page,
                             unsigned pageFrom,
@@ -66,13 +100,19 @@
                            struct page *page,
                            unsigned pageFrom,
                            unsigned pageTo);
+#endif
 
 /* HGFS address space operations structure. */
 struct address_space_operations HgfsAddressSpaceOperations = {
    .readpage      = HgfsReadpage,
    .writepage     = HgfsWritepage,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+   .write_begin   = HgfsWriteBegin,
+   .write_end     = HgfsWriteEnd,
+#else
    .prepare_write = HgfsPrepareWrite,
    .commit_write  = HgfsCommitWrite,
+#endif
 #ifdef HGFS_ENABLE_WRITEBACK
    .set_page_dirty = __set_page_dirty_nobuffers,
 #endif
@@ -684,14 +724,14 @@
 /*
  *-----------------------------------------------------------------------------
  *
- * HgfsPrepareWrite --
+ * HgfsDoWriteBegin --
  *
- *      Called by the generic write path to set up a write request for a page.
- *      We're expected to do any pre-allocation and housekeeping prior to
- *      receiving the write.
+ *      Helper function for HgfsWriteBegin / HgfsPrepareWrite.
+ *
+ *      Initialize the page if the file is to be appended.
  *
  * Results:
- *      Always zero.
+ *      None.
  *
  * Side effects:
  *      None.
@@ -699,12 +739,12 @@
  *-----------------------------------------------------------------------------
  */
 
-static int
-HgfsPrepareWrite(struct file *file,  // IN: Ignored
-                 struct page *page,  // IN: Page to prepare
-                 unsigned pageFrom,  // IN: Beginning page offset
-                 unsigned pageTo)    // IN: Ending page offset
+static void
+HgfsDoWriteBegin(struct page *page,         // IN: Page to be written
+                 unsigned pageFrom,         // IN: Starting page offset
+                 unsigned pageTo)           // IN: Ending page offset
 {
+   ASSERT(page);
 #ifdef HGFS_ENABLE_WRITEBACK
    loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
    loff_t currentFileSize = compat_i_size_read(page->mapping->host);
@@ -728,6 +768,35 @@
       flush_dcache_page(page);
    }
 #endif
+}
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsPrepareWrite --
+ *
+ *      Called by the generic write path to set up a write request for a page.
+ *      We're expected to do any pre-allocation and housekeeping prior to
+ *      receiving the write.
+ *
+ * Results:
+ *      Always zero.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+HgfsPrepareWrite(struct file *file,  // IN: Ignored
+                 struct page *page,  // IN: Page to prepare
+                 unsigned pageFrom,  // IN: Beginning page offset
+                 unsigned pageTo)    // IN: Ending page offset
+{
+   HgfsDoWriteBegin(page, pageFrom, pageTo);
 
    /*
     * Prior to 2.4.10, our caller expected to call page_address(page) between
@@ -744,48 +813,94 @@
    return 0;
 }
 
+#else
+
 
 /*
  *-----------------------------------------------------------------------------
  *
- * HgfsCommitWrite --
+ * HgfsWriteBegin --
+ *
+ *      Called by the generic write path to set up a write request for a page.
+ *      We're expected to do any pre-allocation and housekeeping prior to
+ *      receiving the write.
  *
- *    This function is the more common write path for HGFS, called from
- *    generic_file_buffered_write. It is much simpler for us than
- *    HgfsWritepage above: the caller has obtained a reference to the page
- *    and will unlock it when we're done. And we don't need to worry about
- *    properly marking the writeback bit, either. See mm/filemap.c in the
- *    kernel for details about how we are called.
+ *      This function is expected to return a locked page.
  *
  * Results:
- *    Zero on succes, non-zero on error.
+ *      Zero on success, non-zero error otherwise.
  *
  * Side effects:
- *    None.
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+HgfsWriteBegin(struct file *file,             // IN: File to be written
+               struct address_space *mapping, // IN: Mapping
+               loff_t pos,                    // IN: File position
+               unsigned len,                  // IN: Bytes to be written
+               unsigned flags,                // IN: Write flags
+               struct page **pagePtr,         // OUT: Locked page
+               void **clientData)             // OUT: Opaque to pass to write_end, unused
+{
+   pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+   unsigned pageFrom = pos & (PAGE_CACHE_SHIFT - 1);
+   unsigned pageTo = pos + len;
+   struct page *page;
+
+   page = __grab_cache_page(mapping, index);
+   if (page == NULL) {
+      return -ENOMEM;
+   }
+   *pagePtr = page;
+
+   HgfsDoWriteBegin(page, pageFrom, pageTo);
+   return 0;
+}
+#endif
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsDoWriteEnd --
+ *
+ *      Helper function for HgfsWriteEnd.
+ *
+ *      This function updates the inode->i_size, conditionally marks the page
+ *      updated and carries out the actual write in case of partial page writes.
+ *
+ * Results:
+ *      Zero on succes, non-zero on error.
+ *
+ * Side effects:
+ *      None.
  *
  *-----------------------------------------------------------------------------
  */
 
 static int
-HgfsCommitWrite(struct file *file, // IN: File we're writing to
-                struct page *page, // IN: Page we're writing from
-                unsigned pageFrom, // IN: Beginning page offset
-                unsigned pageTo)   // IN: Ending page offset
+HgfsDoWriteEnd(struct file *file, // IN: File we're writing to
+               struct page *page, // IN: Page we're writing from
+               unsigned pageFrom, // IN: Starting page offset
+               unsigned pageTo,   // IN: Ending page offset
+               loff_t writeTo,    // IN: File position to write to
+               unsigned copied)   // IN: Number of bytes copied to the page
 {
    HgfsHandle handle;
    struct inode *inode;
    loff_t currentFileSize;
    loff_t offset;
-   loff_t writeTo;
 
    ASSERT(file);
    ASSERT(page);
    inode = page->mapping->host;
    currentFileSize = compat_i_size_read(inode);
    offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
-   writeTo = offset + pageTo;
 
-   /* See coment in HgfsPrepareWrite. */
+   /* See comment in HgfsPrepareWrite. */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
    kunmap(page);
 #endif
@@ -795,14 +910,14 @@
    }
 
    /* We wrote a complete page, so it is up to date. */
-   if ((pageTo - pageFrom) == PAGE_CACHE_SIZE) {
+   if (copied == PAGE_CACHE_SIZE) {
       SetPageUptodate(page);
    }
 
 #ifdef HGFS_ENABLE_WRITEBACK
    /*
     * Check if this is a partial write to a new page, which was
-    * initialized in HgfsPrepareWrite.
+    * initialized in HgfsDoWriteBegin.
     */
    if ((offset >= currentFileSize) ||
        ((pageFrom == 0) && (writeTo >= currentFileSize))) {
@@ -821,13 +936,109 @@
    /*
     * We've recieved a partial write to page that is not uptodate, so
     * do the write now while the page is still locked.  Another
-    * alternative would be to read the page in HgfsPrepareWrite, which
+    * alternative would be to read the page in HgfsDoWriteBegin, which
     * would make it uptodate (ie a complete cached page).
     */
    handle = FILE_GET_FI_P(file)->handle;
-   LOG(6, (KERN_DEBUG "VMware hgfs: HgfsCommitWrite: writing to handle %u\n",
+   LOG(6, (KERN_DEBUG "VMware hgfs: %s: writing to handle %u\n", __FUNCTION__,
            handle));
    return HgfsDoWritepage(handle, page, pageFrom, pageTo);
 }
 
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsCommitWrite --
+ *
+ *      This function is the more common write path for HGFS, called from
+ *      generic_file_buffered_write. It is much simpler for us than
+ *      HgfsWritepage above: the caller has obtained a reference to the page
+ *      and will unlock it when we're done. And we don't need to worry about
+ *      properly marking the writeback bit, either. See mm/filemap.c in the
+ *      kernel for details about how we are called.
+ *
+ * Results:
+ *      Zero on succes, non-zero on error.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+HgfsCommitWrite(struct file *file,    // IN: File to write
+                struct page *page,    // IN: Page to write from
+                unsigned pageFrom,    // IN: Starting page offset
+                unsigned pageTo)      // IN: Ending page offset
+{
+   loff_t offset;
+   loff_t writeTo;
+   unsigned copied;
+
+   ASSERT(page);
+   ASSERT(file);
+
+   offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
+   writeTo = offset + pageTo;
+   copied = pageTo - pageFrom;
+
+   return HgfsDoWriteEnd(file, page, pageFrom, pageTo, writeTo, copied);
+}
+
+#else
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HgfsWriteEnd --
+ *
+ *      This function is the more common write path for HGFS, called from
+ *      generic_file_buffered_write. It is much simpler for us than
+ *      HgfsWritepage above: write_begin has obtained a reference to the page
+ *      and we will unlock it when we're done. And we don't need to worry about
+ *      properly marking the writeback bit, either. See mm/filemap.c in the
+ *      kernel for details about how we are called.
+ *
+ *      This function should unlock the page and reduce the refcount.
+ *
+ * Results:
+ *      Number of bytes written or negative error
+ *
+ * Side effects:
+ *      Unlocks the page and drops the reference.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+HgfsWriteEnd(struct file *file,              // IN: File to write
+             struct address_space *mapping,  // IN: Mapping
+             loff_t pos,                     // IN: File position
+             unsigned len,                   // IN: len passed from write_begin
+             unsigned copied,                // IN: Number of actually copied bytes
+             struct page *page,              // IN: Page to write from
+             void *clientData)               // IN: From write_begin, unused.
+{
+   unsigned pageFrom = pos & (PAGE_CACHE_SIZE - 1);
+   unsigned pageTo = pageFrom + copied;
+   loff_t writeTo = pos + copied;
+   int ret;
+
+   ASSERT(file);
+   ASSERT(mapping);
+   ASSERT(page);
+
+   ret = HgfsDoWriteEnd(file, page, pageFrom, pageTo, writeTo, copied);
+   if (ret == 0) {
+      ret = copied;
+   }
+
+   compat_unlock_page(page);
+   page_cache_release(page);
+   return ret;
+}
+#endif




More information about the rpmfusion-commits mailing list