+# LC_CANCEL_DIRTY_PAGE
+# 2.6.20 introduse cancel_dirty_page instead of
+# clear_page_dirty.
+AC_DEFUN([LC_CANCEL_DIRTY_PAGE],
+[AC_MSG_CHECKING([kernel has cancel_dirty_page])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/page-flags.h>
+],[
+ cancel_dirty_page(NULL, 0);
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CANCEL_DIRTY_PAGE, 1,
+ [kernel has cancel_dirty_page instead of clear_page_dirty])
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
+#
+# LC_PAGE_CONSTANT
+#
+# In order to support raid5 zerocopy patch, we have to patch the kernel to make
+# it support constant page, which means the page won't be modified during the
+# IO.
+#
+AC_DEFUN([LC_PAGE_CONSTANT],
+[AC_MSG_CHECKING([if kernel have PageConstant defined])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/page-flags.h>
+],[
+ #ifndef PG_constant
+ #error "Have no raid5 zcopy patch"
+ #endif
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PAGE_CONSTANT, 1, [kernel have PageConstant supported])
+],[
+ AC_MSG_RESULT(no);
+])
+])
+
+# RHEL5 in FS-cache patch rename PG_checked flag
+# into PG_fs_misc
+AC_DEFUN([LC_PG_FS_MISC],
+[AC_MSG_CHECKING([kernel has PG_fs_misc])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/page-flags.h>
+],[
+ #ifndef PG_fs_misc
+ #error PG_fs_misc not defined in kernel
+ #endif
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PG_FS_MISC, 1,
+ [is kernel have PG_fs_misc])
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
+# RHEL5 PageChecked and SetPageChecked defined
+AC_DEFUN([LC_PAGE_CHECKED],
+[AC_MSG_CHECKING([kernel has PageChecked and SetPageChecked])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/page-flags.h>
+],[
+ #ifndef PageChecked
+ #error PageChecked not defined in kernel
+ #endif
+ #ifndef SetPageChecked
+ #error SetPageChecked not defined in kernel
+ #endif
+],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_PAGE_CHECKED, 1,
+ [does kernel have PageChecked and SetPageChecked])
+],[
+ AC_MSG_RESULT(NO)
+])
+])
+
+AC_DEFUN([LC_EXPORT_TRUNCATE_COMPLETE],
+[LB_CHECK_SYMBOL_EXPORT([truncate_complete_page],
+[mm/truncate.c],[
+AC_DEFINE(HAVE_TRUNCATE_COMPLETE_PAGE, 1,
+ [kernel export truncate_complete_page])
+],[
+])
+])
+
+AC_DEFUN([LC_EXPORT_D_REHASH_COND],
+[LB_CHECK_SYMBOL_EXPORT([d_rehash_cond],
+[fs/dcache.c],[
+AC_DEFINE(HAVE_D_REHASH_COND, 1,
+ [d_rehash_cond is exported by the kernel])
+],[
+])
+])
+
+AC_DEFUN([LC_EXPORT___D_REHASH],
+[LB_CHECK_SYMBOL_EXPORT([__d_rehash],
+[fs/dcache.c],[
+AC_DEFINE(HAVE___D_REHASH, 1,
+ [__d_rehash is exported by the kernel])
+],[
+])
+])
+
+AC_DEFUN([LC_EXPORT_D_MOVE_LOCKED],
+[LB_CHECK_SYMBOL_EXPORT([d_move_locked],
+[fs/dcache.c],[
+AC_DEFINE(HAVE_D_MOVE_LOCKED, 1,
+ [d_move_locked is exported by the kernel])
+],[
+])
+])
+
+AC_DEFUN([LC_EXPORT___D_MOVE],
+[LB_CHECK_SYMBOL_EXPORT([__d_move],
+[fs/dcache.c],[
+AC_DEFINE(HAVE___D_MOVE, 1,
+ [__d_move is exported by the kernel])
+],[
+])
+])
+
+# The actual symbol exported varies among architectures, so we need
+# to check many symbols (but only in the current architecture.) No
+# matter what symbol is exported, the kernel #defines node_to_cpumask
+# to the appropriate function and that's what we use.
+AC_DEFUN([LC_EXPORT_NODE_TO_CPUMASK],
+ [LB_CHECK_SYMBOL_EXPORT([node_to_cpumask],
+ [arch/$LINUX_ARCH/mm/numa.c],
+ [AC_DEFINE(HAVE_NODE_TO_CPUMASK, 1,
+ [node_to_cpumask is exported by
+ the kernel])]) # x86_64
+ LB_CHECK_SYMBOL_EXPORT([node_to_cpu_mask],
+ [arch/$LINUX_ARCH/kernel/smpboot.c],
+ [AC_DEFINE(HAVE_NODE_TO_CPUMASK, 1,
+ [node_to_cpumask is exported by
+ the kernel])]) # ia64
+ LB_CHECK_SYMBOL_EXPORT([node_2_cpu_mask],
+ [arch/$LINUX_ARCH/kernel/smpboot.c],
+ [AC_DEFINE(HAVE_NODE_TO_CPUMASK, 1,
+ [node_to_cpumask is exported by
+ the kernel])]) # i386
+ ])
+
+# 2.6.22 lost second parameter for invalidate_bdev
+AC_DEFUN([LC_INVALIDATE_BDEV_2ARG],
+[AC_MSG_CHECKING([if invalidate_bdev has second argument])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/buffer_head.h>
+],[
+ invalidate_bdev(NULL,0);
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_INVALIDATE_BDEV_2ARG, 1,
+ [invalidate_bdev has second argument])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.23 have return type 'void' for unregister_blkdev
+AC_DEFUN([LC_UNREGISTER_BLKDEV_RETURN_INT],
+[AC_MSG_CHECKING([if unregister_blkdev return int])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ int i = unregister_blkdev(0,NULL);
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_UNREGISTER_BLKDEV_RETURN_INT, 1,
+ [unregister_blkdev return int])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.23 change .sendfile to .splice_read
+AC_DEFUN([LC_KERNEL_SPLICE_READ],
+[AC_MSG_CHECKING([if kernel has .splice_read])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct file_operations file;
+
+ file.splice_read = NULL;
+], [
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_KERNEL_SPLICE_READ, 1,
+ [kernel has .slice_read])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+# 2.6.23 extract nfs export related data into exportfs.h
+AC_DEFUN([LC_HAVE_EXPORTFS_H],
+[
+tmpfl="$CFLAGS"
+CFLAGS="$CFLAGS -I$LINUX_OBJ/include"
+AC_CHECK_HEADERS([linux/exportfs.h])
+CFLAGS="$tmpfl"
+])
+
+#
+# LC_VFS_INTENT_PATCHES
+#
+# check if the kernel has the VFS intent patches
+AC_DEFUN([LC_VFS_INTENT_PATCHES],
+[AC_MSG_CHECKING([if the kernel has the VFS intent patches])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ #include <linux/namei.h>
+],[
+ struct nameidata nd;
+ struct lookup_intent *it;
+
+ it = &nd.intent;
+ intent_init(it, IT_OPEN);
+ it->d.lustre.it_disposition = 0;
+ it->d.lustre.it_data = NULL;
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_VFS_INTENT_PATCHES, 1, [VFS intent patches are applied])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+AC_DEFUN([LC_S_TIME_GRAN],
+[AC_MSG_CHECKING([if super block has s_time_gran member])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct super_block sb;
+
+ return sb.s_time_gran;
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_S_TIME_GRAN, 1, [super block has s_time_gran member])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+AC_DEFUN([LC_SB_TIME_GRAN],
+[AC_MSG_CHECKING([if kernel has old get_sb_time_gran])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ return get_sb_time_gran(NULL);
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_SB_TIME_GRAN, 1, [kernel has old get_sb_time_gran])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+
+# ~2.6.12 merge patch from oracle to convert tree_lock from spinlock to rwlock
+AC_DEFUN([LC_RW_TREE_LOCK],
+[AC_MSG_CHECKING([if kernel has tree_lock as rwlock])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct address_space a;
+
+ write_lock(&a.tree_lock);
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_RW_TREE_LOCK, 1, [kernel has tree_lock as rw_lock])
+],[
+ AC_MSG_RESULT([no])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+
+AC_DEFUN([LC_CONST_ACL_SIZE],
+[AC_MSG_CHECKING([calc acl size])
+tmp_flags="$CFLAGS"
+CFLAGS="$CFLAGS -I $LINUX_OBJ/include $EXTRA_KCFLAGS"
+AC_TRY_RUN([
+#define __KERNEL__
+#include <linux/autoconf.h>
+#include <linux/types.h>
+#undef __KERNEL__
+// block include
+#define __LINUX_POSIX_ACL_H
+
+# ifdef CONFIG_FS_POSIX_ACL
+# ifdef HAVE_XATTR_ACL
+# include <linux/xattr_acl.h>
+# endif
+# ifdef HAVE_LINUX_POSIX_ACL_XATTR_H
+# include <linux/posix_acl_xattr.h>
+# endif
+# endif
+
+#include <linux/lustre_acl.h>
+
+#include <stdio.h>
+
+int main(void)
+{
+ int size = mds_xattr_acl_size(LUSTRE_POSIX_ACL_MAX_ENTRIES);
+ FILE *f = fopen("acl.size","w+");
+ fprintf(f,"%d", size);
+ fclose(f);
+
+ return 0;
+}
+
+],[
+ acl_size=`cat acl.size`
+ AC_MSG_RESULT([ACL size $acl_size])
+ AC_DEFINE_UNQUOTED(XATTR_ACL_SIZE, AS_TR_SH([$acl_size]), [size of xattr acl])
+],[
+ AC_ERROR([ACL size can't computed])
+])
+CFLAGS="$tmp_flags"
+])
+
+#
+# check for crypto API
+#
+AC_DEFUN([LC_ASYNC_BLOCK_CIPHER],
+[AC_MSG_CHECKING([if kernel has block cipher support])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/crypto.h>
+],[
+ int v = CRYPTO_ALG_TYPE_BLKCIPHER;
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_ASYNC_BLOCK_CIPHER, 1, [kernel has block cipher support])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
+# check for FS_RENAME_DOES_D_MOVE flag
+#
+AC_DEFUN([LC_FS_RENAME_DOES_D_MOVE],
+[AC_MSG_CHECKING([if kernel has FS_RENAME_DOES_D_MOVE flag])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ int v = FS_RENAME_DOES_D_MOVE;
+],[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_FS_RENAME_DOES_D_MOVE, 1, [kernel has FS_RENAME_DOES_D_MOVE flag])
+],[
+ AC_MSG_RESULT([no])
+])
+])