Linux: Fix builds on RHEL4
authorSimon Wilkinson <sxw@inf.ed.ac.uk>
Sat, 6 Mar 2010 11:21:06 +0000 (11:21 +0000)
committerDerrick Brashear <shadow@dementia.org>
Sat, 6 Mar 2010 13:32:52 +0000 (05:32 -0800)
RHEL4 has a very old 2.6 kernel (2.6.9), which predates the start of
the Linux git tree. When I started using page_offset, I mistakenly assumed
that everything in the initial commit to that tree was available in all
2.6 versions we care about. That isn't the case, sadly.

Secondly, the new readpage code uses zero_user_segments, which has only
been available in the mainline kernel since 2.6.25 (RHEL5 appears to have
a backport)

Implement local wrappers for both of these functions when configure can't
find them in the kernel we're building for.

These functions have been created independently of the Linux tree.
page_offset is a copy of the code we used before we replaced it.
zero_user_segments() is a first-principles implementation
of the function (which zeros a pair of memory ranges within a single page)

FIXES 126678

Change-Id: I622aec4d653567d5234e7a127b981e97468bbe7c
Reviewed-on: http://gerrit.openafs.org/1525
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Derrick Brashear <shadow@dementia.org>

acinclude.m4
src/afs/LINUX/osi_compat.h
src/cf/linux-test4.m4

index c083e27..2b37105 100644 (file)
@@ -812,6 +812,8 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
                  LINUX_HAVE_GRAB_CACHE_PAGE_WRITE_BEGIN
                 LINUX_HAVE_PAGEVEC_LRU_ADD_FILE
                 LINUX_HAVE_SPLICE_DIRECT_TO_ACTOR
+                LINUX_HAVE_PAGE_OFFSET
+                LINUX_HAVE_ZERO_USER_SEGMENTS
                  LINUX_STRUCT_TASK_HAS_CRED
                 LINUX_STRUCT_PROC_DIR_ENTRY_HAS_OWNER
                 LINUX_HAVE_KMEM_CACHE_T
index 5e52056..0b52019 100644 (file)
@@ -203,3 +203,30 @@ afs_linux_cred_is_current(afs_ucred_t *cred)
 # endif
 #endif
 #endif
+
+#ifndef HAVE_PAGE_OFFSET
+static inline loff_t
+page_offset(struct page *pp)
+{
+    return (((loff_t) pp->index) << PAGE_CACHE_SHIFT);
+}
+#endif
+
+#ifndef HAVE_ZERO_USER_SEGMENTS
+static inline void
+zero_user_segments(struct page *pp, unsigned int from1, unsigned int to1,
+                  unsigned int from2, unsigned int to2)
+{
+    void *base = kmap_atomic(pp, KM_USER0);
+
+    if (to1 > from1)
+       memset(base + from1, 0, to1 - from1);
+
+    if (to2 > from2)
+       memset(base + from2, 0, to2 - from2);
+
+    flush_dcache_page(pp);
+    kunmap_atomic(base, KM_USER0);
+}
+#endif
+
index 2420b7b..14cf9a6 100644 (file)
@@ -1231,3 +1231,29 @@ _bdi.name = NULL;],
     AC_DEFINE([STRUCT_BDI_HAS_NAME], 1, [define if struct backing_dev_info has a name member])
   fi])
 
+AC_DEFUN([LINUX_HAVE_ZERO_USER_SEGMENTS], [
+  AC_MSG_CHECKING([for zero_user_segments])
+  AC_CACHE_VAL([ac_cv_linux_have_zero_user_segments], [
+    AC_TRY_KBUILD(
+[#include <linux/highmem.h>],
+[zero_user_segments(NULL, 0, 0, 0, 0);],
+      ac_cv_linux_have_zero_user_segments=yes,
+      ac_cv_linux_have_zero_user_segments=no)])
+  AC_MSG_RESULT($ac_cv_linux_have_zero_user_segments)
+  if test "x$ac_cv_linux_have_zero_user_segments" = "xyes"; then
+    AC_DEFINE([HAVE_ZERO_USER_SEGMENTS], 1, [define if your kernel has the zero_user_segments function])
+  fi])
+
+AC_DEFUN([LINUX_HAVE_PAGE_OFFSET], [
+  AC_MSG_CHECKING([for page_offset])
+  AC_CACHE_VAL([ac_cv_linux_have_page_offset], [
+    AC_TRY_KBUILD(
+[#include <linux/pagemap.h>],
+[page_offset(NULL);],
+      ac_cv_linux_have_page_offset=yes,
+      ac_cv_linux_have_page_offset=no)])
+  AC_MSG_RESULT($ac_cv_linux_have_page_offset)
+  if test "x$ac_cv_linux_have_page_offset" = "xyes"; then
+    AC_DEFINE([HAVE_PAGE_OFFSET], 1, [define if your kernel has the page_offset function])
+  fi])
+