lustre/autoconf/lustre-core.m4 |   19 ++++++++++++
 lustre/llite/llite_mmap.c      |   60 ++++++++++++++++++++-------------------
 2 files changed, 50 insertions(+), 29 deletions(-)

diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4
index 09a7eac..d574d38 100644
--- a/lustre/autoconf/lustre-core.m4
+++ b/lustre/autoconf/lustre-core.m4
@@ -1583,6 +1583,24 @@ LB_LINUX_TRY_COMPILE([
 #
 # 2.6.27
 #
+AC_DEFUN([LC_PGMKWRITE_USE_PAGE],
+[AC_MSG_CHECKING([kernel .page_mkwrite uses struct page *])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+        #include <linux/mm.h>
+],[
+        ((struct vm_operations_struct *)0)->page_mkwrite((struct vm_area_struct *)0, (struct page *)0);
+], [
+        AC_MSG_RESULT([yes])
+        AC_DEFINE(HAVE_PGMKWRITE_USE_PAGE, 1,
+                [kernel vm_operation_struct.page_mkwrite uses struct page* as second parameter])
+],[
+        AC_MSG_RESULT([no])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+
 AC_DEFUN([LC_INODE_PERMISION_2ARGS],
 [AC_MSG_CHECKING([inode_operations->permission has two args])
 LB_LINUX_TRY_COMPILE([
@@ -2337,6 +2355,7 @@ AC_DEFUN([LC_PROG_LINUX],
          LC_FS_STRUCT_USE_PATH
 
          # 2.6.27
+         LC_PGMKWRITE_USE_PAGE
          LC_INODE_PERMISION_2ARGS
          LC_FILE_REMOVE_SUID
          LC_TRYLOCKPAGE
diff --git a/lustre/llite/llite_mmap.c b/lustre/llite/llite_mmap.c
index fd324ca..58dbaf7 100644
--- a/lustre/llite/llite_mmap.c
+++ b/lustre/llite/llite_mmap.c
@@ -334,35 +334,6 @@ out_err:
         RETURN(page);
 }
 
-static int ll_page_mkwrite(struct vm_area_struct *vma, struct page *vmpage)
-{
-        int count = 0;
-        bool printed = false;
-        bool retry;
-        int result;
-
-        do {
-                retry = false;
-                result = ll_page_mkwrite0(vma, vmpage, &retry);
-
-                if (!printed && ++count > 16) {
-                        CWARN("app(%s): the page %lu of file %lu is under heavy"
-                              " contention.\n",
-                              current->comm, page_index(vmpage),
-                              vma->vm_file->f_dentry->d_inode->i_ino);
-                        printed = true;
-                }
-        } while (retry);
-
-        if (result == 0)
-                unlock_page(vmpage);
-        else if (result == -ENODATA)
-                result = 0; /* kernel will know truncate has happened and
-                             * retry */
-
-        return result;
-}
-
 #else
 /**
  * Lustre implementation of a vm_operations_struct::fault() method, called by
@@ -457,7 +428,38 @@ restart:
         }
         return result;
 }
+#endif
 
+#ifdef HAVE_PGMKWRITE_USE_PAGE
+static int ll_page_mkwrite(struct vm_area_struct *vma, struct page *vmpage)
+{
+        int count = 0;
+        bool printed = false;
+        bool retry;
+        int result;
+
+        do {
+                retry = false;
+                result = ll_page_mkwrite0(vma, vmpage, &retry);
+
+                if (!printed && ++count > 16) {
+                        CWARN("app(%s): the page %lu of file %lu is under heavy"
+                              " contention.\n",
+                              current->comm, page_index(vmpage),
+                              vma->vm_file->f_dentry->d_inode->i_ino);
+                        printed = true;
+                }
+        } while (retry);
+
+        if (result == 0)
+                unlock_page(vmpage);
+        else if (result == -ENODATA)
+                result = 0; /* kernel will know truncate has happened and
+                             * retry */
+
+        return result;
+}
+#else
 static int ll_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
 {
         int count = 0;