+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_BLOCKS_FOR_TRUNCATE, 1,
+ [kernel has ext4_blocks_for_truncate])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
+# 3.1 introduced generic_file_llseek_size()
+#
+AC_DEFUN([LC_FILE_LLSEEK_SIZE],
+ [LB_CHECK_SYMBOL_EXPORT([generic_file_llseek_size],
+ [fs/read_write.c],
+ [AC_DEFINE(HAVE_FILE_LLSEEK_SIZE, 1,
+ [generic_file_llseek_size is exported by the kernel])])
+])
+
+#
+# 3.2 request_queue.make_request_fn defined as function returns with void
+# see kernel commit 5a7bbad27a410350e64a2d7f5ec18fc73836c14f
+#
+AC_DEFUN([LC_HAVE_VOID_MAKE_REQUEST_FN],
+[AC_MSG_CHECKING([if request_queue.make_request_fn returns void but not int])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/blkdev.h>
+],[
+ int ret;
+ make_request_fn *mrf;
+ ret = mrf(NULL, NULL);
+],[
+ AC_MSG_RESULT([no])
+],[
+ AC_DEFINE(HAVE_VOID_MAKE_REQUEST_FN, 1,
+ [request_queue.make_request_fn returns void but not int])
+ AC_MSG_RESULT([yes])
+])
+])
+
+#
+# 3.2 protects inode->i_nlink from direct modification
+# see kernel commit a78ef704a8dd430225955f0709b22d4a6ba21deb
+# at the same time adds set_nlink(), so checks set_nlink() for it.
+#
+AC_DEFUN([LC_HAVE_PROTECT_I_NLINK],
+[AC_MSG_CHECKING([if inode->i_nlink is protected from direct modification])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct inode i;
+ set_nlink(&i, 1);
+],[
+ AC_DEFINE(HAVE_PROTECT_I_NLINK, 1,
+ [inode->i_nlink is protected from direct modification])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
+# 3.3 introduces migrate_mode.h and migratepage has 4 args
+#
+AC_DEFUN([LC_HAVE_MIGRATE_HEADER],
+[LB_CHECK_FILE([$LINUX/include/linux/migrate.h],[
+ AC_DEFINE(HAVE_MIGRATE_H, 1,
+ [kernel has include/linux/migrate.h])
+],[LB_CHECK_FILE([$LINUX/include/linux/migrate_mode.h],[
+ AC_DEFINE(HAVE_MIGRATE_MODE_H, 1,
+ [kernel has include/linux/migrate_mode.h])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+])
+
+AC_DEFUN([LC_MIGRATEPAGE_4ARGS],
+[AC_MSG_CHECKING([if address_space_operations.migratepage has 4 args])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+#ifdef HAVE_MIGRATE_H
+ #include <linux/migrate.h>
+#elif defined(HAVE_MIGRATE_MODE_H)
+ #include <linux/migrate_mode.h>
+#endif
+],[
+ struct address_space_operations aops;
+
+ aops.migratepage(NULL, NULL, NULL, MIGRATE_ASYNC);
+],[
+ AC_DEFINE(HAVE_MIGRATEPAGE_4ARGS, 1,
+ [address_space_operations.migratepage has 4 args])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
+# 3.3 switchs super_operations to use dentry as parameter (but not vfsmount)
+# see kernel commit 34c80b1d93e6e20ca9dea0baf583a5b5510d92d4
+#
+AC_DEFUN([LC_SUPEROPS_USE_DENTRY],
+[AC_MSG_CHECKING([if super_operations use dentry as parameter])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ int show_options(struct seq_file *seq, struct dentry *root){
+ return 0;
+ }
+],[
+ struct super_operations ops;
+ ops.show_options = show_options;
+],[
+ AC_DEFINE(HAVE_SUPEROPS_USE_DENTRY, 1,
+ [super_operations use dentry as parameter])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+
+#
+# 3.3 switchs inode_operations to use umode_t as parameter (but not int)
+# see kernel commit 1a67aafb5f72a436ca044293309fa7e6351d6a35
+#
+AC_DEFUN([LC_INODEOPS_USE_UMODE_T],
+[AC_MSG_CHECKING([if inode_operations use umode_t as parameter])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ #include <linux/types.h>
+ int my_mknod(struct inode *dir, struct dentry *dchild,
+ umode_t mode, dev_t dev)
+ {
+ return 0;
+ }
+],[
+ struct inode_operations ops;
+ ops.mknod = my_mknod;
+],[
+ AC_DEFINE(HAVE_INODEOPS_USE_UMODE_T, 1,
+ [inode_operations use umode_t as parameter])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+
+# 3.4 kmap_atomic removes second argument
+# see kernel commit 1ec9c5ddc17aa398f05646abfcbaf315b544e62f
+#
+AC_DEFUN([LC_KMAP_ATOMIC_HAS_1ARG],
+[AC_MSG_CHECKING([if kmap_atomic has only 1 argument])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/highmem.h>
+],[
+ kmap_atomic(NULL);
+],[
+ AC_DEFINE(HAVE_KMAP_ATOMIC_HAS_1ARG, 1,
+ [have kmap_atomic has only 1 argument])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
+# 3.4 switchs touch_atime to struct path
+# see kernel commit 68ac1234fb949b66941d94dce4157742799fc581
+#
+AC_DEFUN([LC_TOUCH_ATIME_1ARG],
+[AC_MSG_CHECKING([if touch_atime use one argument])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ touch_atime((struct path *)NULL);
+],[
+ AC_DEFINE(HAVE_TOUCH_ATIME_1ARG, 1,
+ [touch_atime use one argument])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
+# 3.4 converts d_alloc_root to d_make_root
+# see kernel commit 32991ab305ace7017c62f8eecbe5eb36dc32e13b
+#
+AC_DEFUN([LC_HAVE_D_MAKE_ROOT],
+[AC_MSG_CHECKING([if have d_make_root])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ d_make_root((struct inode *)NULL);
+],[
+ AC_DEFINE(HAVE_D_MAKE_ROOT, 1,
+ [have d_make_root])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
+# 3.5 renames end_writeback() back to clear_inode()...
+# see kernel commit dbd5768f87ff6fb0a4fe09c4d7b6c4a24de99430
+#
+AC_DEFUN([LC_HAVE_CLEAR_INODE],
+[AC_MSG_CHECKING([if have clear_inode])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ clear_inode((struct inode *)NULL);
+],[
+ AC_DEFINE(HAVE_CLEAR_INODE, 1,
+ [have clear_inode])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+])
+
+#
+# 3.5 encode_fh has parent inode passed in directly
+# see kernel commit b0b0382b
+#
+AC_DEFUN([LC_HAVE_ENCODE_FH_PARENT],
+[AC_MSG_CHECKING([if encode_fh have parent inode as parameter])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+ #include <linux/exportfs.h>
+ #include <linux/fs.h>
+ #include <linux/types.h>
+ int ll_encode_fh(struct inode *i, __u32 *a, int *b, struct inode *p)
+ {
+ return 0;
+ }
+],[
+ struct export_operations exp_op;
+ exp_op.encode_fh = ll_encode_fh;
+],[
+ AC_DEFINE(HAVE_ENCODE_FH_PARENT, 1,
+ [have parent inode as parameter])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+
+#
+# 3.6 switch i_dentry/d_alias from list to hlist
+#
+AC_DEFUN([LC_HAVE_DENTRY_D_ALIAS_HLIST],
+[AC_MSG_CHECKING([if i_dentry/d_alias uses hlist])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ #include <linux/list.h>
+],[
+ struct inode inode;
+ struct dentry dentry;
+ struct hlist_head head;
+ struct hlist_node node;
+ inode.i_dentry = head;
+ dentry.d_alias = node;
+],[
+ AC_DEFINE(HAVE_DENTRY_D_ALIAS_HLIST, 1,
+ [have i_dentry/d_alias uses hlist])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+
+#
+# 3.6 dentry_open uses struct path as first argument
+# see kernel commit 765927b2
+#
+AC_DEFUN([LC_DENTRY_OPEN_USE_PATH],
+[AC_MSG_CHECKING([if dentry_open uses struct path as first argument])
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ #include <linux/path.h>
+],[
+ struct path path;
+ dentry_open(&path, 0, NULL);
+],[
+ AC_DEFINE(HAVE_DENTRY_OPEN_USE_PATH, 1,
+ [dentry_open uses struct path as first argument])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+])
+
+#
+# 3.6 vfs adds iop->atomic_open
+#
+AC_DEFUN([LC_HAVE_IOP_ATOMIC_OPEN],
+[AC_MSG_CHECKING([if iop has atomic_open])
+LB_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+],[
+ struct inode_operations iop;
+ iop.atomic_open = NULL;
+],[
+ AC_DEFINE(HAVE_IOP_ATOMIC_OPEN, 1,
+ [have iop atomic_open])
+ AC_MSG_RESULT([yes])
+],[
+ AC_MSG_RESULT([no])