+]) # LC_HAVE_D_MAKE_ROOT
+
+#
+# LC_HAVE_CACHE_REGISTER
+#
+# 3.4 cache_register/cache_unregister are removed
+# see kernel commit 2c5f846747526e2b83c5f1b8e69016be0e2e87c0
+# Note, since 2.6.37 cache_register_net/cache_unregister_net
+# are defined, but not exported.
+# 3.3 cache_register_net/cache_unregister_net are
+# exported and replacing cache_register/cache_unregister in 3.4
+#
+AC_DEFUN([LC_HAVE_CACHE_REGISTER], [
+LB_CHECK_COMPILE([if have 'cache_register'],
+cache_register, [
+ #include <linux/sunrpc/cache.h>
+],[
+ cache_register(NULL);
+],[
+ AC_DEFINE(HAVE_CACHE_REGISTER, 1,
+ [have cache_register])
+])
+]) # LC_HAVE_CACHE_REGISTER
+
+#
+# LC_HAVE_CLEAR_INODE
+#
+# 3.5 renames end_writeback() back to clear_inode()...
+# see kernel commit dbd5768f87ff6fb0a4fe09c4d7b6c4a24de99430
+#
+AC_DEFUN([LC_HAVE_CLEAR_INODE], [
+LB_CHECK_COMPILE([if have 'clear_inode'],
+clear_inode, [
+ #include <linux/fs.h>
+],[
+ clear_inode((struct inode *)NULL);
+],[
+ AC_DEFINE(HAVE_CLEAR_INODE, 1,
+ [have clear_inode])
+])
+]) # LC_HAVE_CLEAR_INODE
+
+#
+# LC_HAVE_ENCODE_FH_PARENT
+#
+# 3.5 encode_fh has parent inode passed in directly
+# see kernel commit b0b0382b
+#
+AC_DEFUN([LC_HAVE_ENCODE_FH_PARENT], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'encode_fh' have parent inode as parameter],
+encode_fh_parent_inode, [
+ #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])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_HAVE_ENCODE_FH_PARENT
+
+#
+# LC_FILE_LLSEEK_SIZE_5ARG
+#
+# 3.5 has generic_file_llseek_size with 5 args
+#
+AC_DEFUN([LC_FILE_LLSEEK_SIZE_5ARG], [
+LB_CHECK_COMPILE([if Linux kernel has 'generic_file_llseek_size' with 5 args],
+generic_file_llseek_size_5args, [
+ #include <linux/fs.h>
+],[
+ generic_file_llseek_size(NULL, 0, 0, 0, 0);
+], [
+ AC_DEFINE(HAVE_FILE_LLSEEK_SIZE_5ARGS, 1,
+ [kernel has generic_file_llseek_size with 5 args])
+])
+]) # LC_FILE_LLSEEK_SIZE_5ARG
+
+#
+# LC_LLITE_DATA_IS_LIST
+#
+# 3.6 switch i_dentry/d_alias from list to hlist
+#
+# In the upstream kernels d_alias first changes
+# to a hlist and then in later version, 3.11, gets
+# moved to the union d_u. Due to some distros having
+# d_alias in the d_u union as a struct list, which
+# has never existed upstream stream, we can't test
+# if d_alias is a list or hlist directly. If ever
+# i_dentry and d_alias even up different combos then
+# the build will fail. In that case then we will need
+# to separate out the i_dentry and d_alias test below.
+#
+AC_DEFUN([LC_DATA_FOR_LLITE_IS_LIST], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'i_dentry/d_alias' uses 'list'],
+i_dentry_d_alias_list, [
+ #include <linux/fs.h>
+],[
+ struct inode inode;
+ INIT_LIST_HEAD(&inode.i_dentry);
+],[
+ AC_DEFINE(DATA_FOR_LLITE_IS_LIST, 1,
+ [both i_dentry/d_alias uses list])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_DATA_FOR_LLITE_IS_LIST
+
+#
+# LC_DENTRY_OPEN_USE_PATH
+#
+# 3.6 dentry_open uses struct path as first argument
+# see kernel commit 765927b2
+#
+AC_DEFUN([LC_DENTRY_OPEN_USE_PATH], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'dentry_open' uses 'struct path' as first argument],
+dentry_open_path, [
+ #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])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_DENTRY_OPEN_USE_PATH
+
+#
+# LC_HAVE_IOP_ATOMIC_OPEN
+#
+# 3.6 vfs adds iop->atomic_open
+#
+AC_DEFUN([LC_HAVE_IOP_ATOMIC_OPEN], [
+LB_CHECK_COMPILE([if 'iop' has 'atomic_open'],
+inode_ops_atomic_open, [
+ #include <linux/fs.h>
+],[
+ struct inode_operations iop;
+ iop.atomic_open = NULL;
+],[
+ AC_DEFINE(HAVE_IOP_ATOMIC_OPEN, 1,
+ [have iop atomic_open])
+])
+]) # LC_HAVE_IOP_ATOMIC_OPEN
+
+#
+# LC_HAVE_SB_START_WRITE
+#
+# RHEL6 2.6.32, 3.6 or newer support wrapped FS freeze functions
+#
+AC_DEFUN([LC_HAVE_SB_START_WRITE], [
+LB_CHECK_COMPILE([if kernel supports wrapped FS freeze functions],
+sb_start_write, [
+ #include <linux/fs.h>
+],[
+ sb_start_write(NULL);
+],[
+ AC_DEFINE(HAVE_SB_START_WRITE, 1,
+ [kernel supports wrapped FS freeze functions])
+])
+]) # LC_HAVE_SB_START_WRITE
+
+#
+# LC_HAVE_POSIXACL_USER_NS
+#
+# 3.7 posix_acl_{to,from}_xattr take struct user_namespace
+#
+AC_DEFUN([LC_HAVE_POSIXACL_USER_NS], [
+LB_CHECK_COMPILE([if 'posix_acl_to_xattr' takes 'struct user_namespace'],
+posix_acl_to_xattr_user_namespace, [
+ #include <linux/fs.h>
+ #include <linux/posix_acl_xattr.h>
+],[
+ posix_acl_to_xattr((struct user_namespace *)NULL, NULL, NULL, 0);
+],[
+ AC_DEFINE(HAVE_POSIXACL_USER_NS, 1,
+ [posix_acl_to_xattr takes struct user_namespace])
+])
+]) # LC_HAVE_POSIXACL_USER_NS
+
+#
+# LC_HAVE_FILE_F_INODE
+#
+# 3.8 struct file has new member f_inode
+#
+AC_DEFUN([LC_HAVE_FILE_F_INODE], [
+LB_CHECK_COMPILE([if 'struct file' has member 'f_inode'],
+file_f_inode, [
+ #include <linux/fs.h>
+],[
+ ((struct file *)0)->f_inode = NULL;
+],[
+ AC_DEFINE(HAVE_FILE_F_INODE, 1,
+ [struct file has member f_inode])
+])
+]) # LC_HAVE_FILE_F_INODE
+
+#
+# LC_HAVE_FILE_INODE
+#
+# 3.8 has introduced inline function file_inode
+#
+AC_DEFUN([LC_HAVE_FILE_INODE], [
+LB_CHECK_COMPILE([if file_inode() exists],
+file_inode, [
+ #include <linux/fs.h>
+],[
+ file_inode(NULL);
+],[
+ AC_DEFINE(HAVE_FILE_INODE, 1,
+ [file_inode() has been defined])
+])
+]) # LC_HAVE_FILE_INODE
+
+#
+# LC_HAVE_SUNRPC_UPCALL_HAS_3ARGS
+#
+AC_DEFUN([LC_HAVE_SUNRPC_UPCALL_HAS_3ARGS], [
+LB_CHECK_COMPILE([if 'sunrpc_cache_pipe_upcall' takes 3 args],
+sunrpc_cache_pipe_upcall_3args, [
+ #include <linux/sunrpc/cache.h>
+],[
+ sunrpc_cache_pipe_upcall(NULL, NULL, NULL);
+],[
+ AC_DEFINE(HAVE_SUNRPC_UPCALL_HAS_3ARGS, 1,
+ [sunrpc_cache_pipe_upcall takes 3 args])
+])
+]) # LC_HAVE_SUNRPC_UPCALL_HAS_3ARGS
+
+#
+# LC_HAVE_HLIST_FOR_EACH_3ARG
+#
+# 3.9 uses hlist_for_each_entry with 3 args
+# b67bfe0d42cac56c512dd5da4b1b347a23f4b70a
+#
+AC_DEFUN([LC_HAVE_HLIST_FOR_EACH_3ARG], [
+LB_CHECK_COMPILE([if 'hlist_for_each_entry' has 3 args],
+hlist_for_each_entry_3args, [
+ #include <linux/list.h>
+ #include <linux/fs.h>
+],[
+ struct hlist_head *head = NULL;
+ struct inode *inode;
+
+ hlist_for_each_entry(inode, head, i_hash) {
+ continue;
+ }
+],[
+ AC_DEFINE(HAVE_HLIST_FOR_EACH_3ARG, 1,
+ [hlist_for_each_entry has 3 args])
+])
+]) # LC_HAVE_HLIST_FOR_EACH_3ARG
+
+#
+# LC_HAVE_BIO_END_SECTOR
+#
+# 3.9 introduces bio_end_sector macro
+# f73a1c7d117d07a96d89475066188a2b79e53c48
+#
+AC_DEFUN([LC_HAVE_BIO_END_SECTOR], [
+LB_CHECK_COMPILE([if 'bio_end_sector' is defined],
+bio_end_sector, [
+ #include <linux/bio.h>
+],[
+ struct bio bio;
+
+ bio_end_sector(&bio);
+],[
+ AC_DEFINE(HAVE_BIO_END_SECTOR, 1,
+ [bio_end_sector is defined])
+])
+]) # LC_HAVE_BIO_END_SECTOR
+
+#
+# 3.9 created is_sxid
+#
+AC_DEFUN([LC_HAVE_IS_SXID], [
+LB_CHECK_COMPILE([if 'is_sxid' is defined],
+is_sxid, [
+ #include <linux/fs.h>
+],[
+ struct inode inode;
+
+ is_sxid(inode.i_mode);
+],[
+ AC_DEFINE(HAVE_IS_SXID, 1, [is_sxid is defined])
+])
+]) # LC_HAVE_IS_SXID
+
+#
+# LC_HAVE_REMOVE_PROC_SUBTREE
+#
+# 3.10 introduced remove_proc_subtree
+#
+AC_DEFUN([LC_HAVE_REMOVE_PROC_SUBTREE], [
+LB_CHECK_COMPILE([if 'remove_proc_subtree' is defined],
+remove_proc_subtree, [
+ #include <linux/proc_fs.h>
+],[
+ remove_proc_subtree(NULL, NULL);
+], [
+ AC_DEFINE(HAVE_REMOVE_PROC_SUBTREE, 1,
+ [remove_proc_subtree is defined])
+])
+]) # LC_HAVE_REMOVE_PROC_SUBTREE
+
+#
+# LC_HAVE_PROC_REMOVE
+#
+# 3.10 introduced proc_remove
+#
+AC_DEFUN([LC_HAVE_PROC_REMOVE], [
+LB_CHECK_COMPILE([if 'proc_remove' is defined],
+proc_remove, [
+ #include <linux/proc_fs.h>
+],[
+ proc_remove(NULL);
+], [
+ AC_DEFINE(HAVE_PROC_REMOVE, 1,
+ [proc_remove is defined])
+])
+]) # LC_HAVE_PROC_REMOVE
+
+#
+# LC_BLKDEV_RELEASE_RETURN_INT
+#
+# 3.10 release for block device doesn't return int
+#
+AC_DEFUN([LC_BLKDEV_RELEASE_RETURN_INT], [
+LB_CHECK_COMPILE([if 'block_device_operations' release returns 'int'],
+block_device_ops_release_return_int, [
+ #include <linux/blkdev.h>
+],[
+ struct block_device_operations fops;
+ int i __attribute__ ((unused));
+
+ i = fops.release(NULL, 0);
+],[
+ AC_DEFINE(HAVE_BLKDEV_RELEASE_RETURN_INT, 1,
+ [block device release returns int])
+])
+]) # LC_BLKDEV_RELEASE_RETURN_INT
+
+AC_DEFUN([LC_HAVE_PROJECT_QUOTA], [
+LB_CHECK_COMPILE([if get_projid exists],
+get_projid, [
+ #include <linux/quota.h>
+],[
+ struct dquot_operations ops;
+
+ ops.get_projid(NULL, NULL);
+],[
+ AC_DEFINE(HAVE_PROJECT_QUOTA, 1,
+ [get_projid function exists])
+])
+]) # LC_HAVE_PROJECT_QUOTA
+
+
+#
+# LC_HAVE_SECURITY_DENTRY_INIT_SECURITY
+#
+# 3.10 introduced security_dentry_init_security()
+#
+AC_DEFUN([LC_HAVE_SECURITY_DENTRY_INIT_SECURITY], [
+LB_CHECK_COMPILE([if 'security_dentry_init_security' is defined],
+security_dentry_init_security, [
+ #include <linux/security.h>
+],[
+ security_dentry_init_security(NULL, 0, NULL, NULL, NULL);
+],[
+ AC_DEFINE(HAVE_SECURITY_DENTRY_INIT_SECURITY, 1,
+ [security_dentry_init_security' is defined])
+])
+]) # LC_HAVE_SECURITY_DENTRY_INIT_SECURITY
+
+#
+# LC_INVALIDATE_RANGE
+#
+# 3.11 invalidatepage requires the length of the range to invalidate
+#
+AC_DEFUN([LC_INVALIDATE_RANGE], [
+LB_CHECK_COMPILE([if 'address_space_operations.invalidatepage' requires 3 arguments],
+address_space_ops_invalidatepage_3args, [
+ #include <linux/fs.h>
+],[
+ struct address_space_operations a_ops;
+ a_ops.invalidatepage(NULL, 0, 0);
+],[
+ AC_DEFINE(HAVE_INVALIDATE_RANGE, 1,
+ [address_space_operations.invalidatepage needs 3 arguments])
+])
+]) # LC_INVALIDATE_RANGE
+
+#
+# LC_HAVE_DIR_CONTEXT
+#
+# 3.11 readdir now takes the new struct dir_context
+#
+AC_DEFUN([LC_HAVE_DIR_CONTEXT], [
+LB_CHECK_COMPILE([if 'dir_context' exist],
+dir_context, [
+ #include <linux/fs.h>
+],[
+ struct dir_context ctx;
+ ctx.pos = 0;
+],[
+ AC_DEFINE(HAVE_DIR_CONTEXT, 1,
+ [dir_context exist])
+])
+]) # LC_HAVE_DIR_CONTEXT
+
+#
+# LC_D_COMPARE_5ARGS
+#
+# 3.11 dentry_operations.d_compare() taken 5 arguments.
+#
+AC_DEFUN([LC_D_COMPARE_5ARGS], [
+LB_CHECK_COMPILE([if 'd_compare' taken 5 arguments],
+d_compare_5args, [
+ #include <linux/dcache.h>
+],[
+ ((struct dentry_operations*)0)->d_compare(NULL,NULL,0,NULL,NULL);
+],[
+ AC_DEFINE(HAVE_D_COMPARE_5ARGS, 1,
+ [d_compare need 5 arguments])
+])
+]) # LC_D_COMPARE_5ARGS
+
+#
+# LC_HAVE_DCOUNT
+#
+# 3.11 need to access d_count to get dentry reference count
+#
+AC_DEFUN([LC_HAVE_DCOUNT], [
+LB_CHECK_COMPILE([if 'd_count' exist],
+d_count, [
+ #include <linux/dcache.h>
+],[
+ struct dentry de;
+ d_count(&de);
+],[
+ AC_DEFINE(HAVE_D_COUNT, 1,
+ [d_count exist])
+])
+]) # LC_HAVE_DCOUNT
+
+#
+# LC_PID_NS_FOR_CHILDREN
+#
+# 3.11 replaces pid_ns by pid_ns_for_children in struct nsproxy
+#
+AC_DEFUN([LC_PID_NS_FOR_CHILDREN], [
+LB_CHECK_COMPILE([if 'struct nsproxy' has 'pid_ns_for_children'],
+pid_ns_for_children, [
+ #include <linux/nsproxy.h>
+],[
+ struct nsproxy ns;
+ ns.pid_ns_for_children = NULL;
+],[
+ AC_DEFINE(HAVE_PID_NS_FOR_CHILDREN, 1,
+ ['struct nsproxy' has 'pid_ns_for_children'])
+])
+]) # LC_PID_NS_FOR_CHILDREN
+
+#
+# LC_OLDSIZE_TRUNCATE_PAGECACHE
+#
+# 3.12 truncate_pagecache without oldsize parameter
+#
+AC_DEFUN([LC_OLDSIZE_TRUNCATE_PAGECACHE], [
+LB_CHECK_COMPILE([if 'truncate_pagecache' with 'old_size' parameter],
+truncate_pagecache_old_size, [
+ #include <linux/mm.h>
+],[
+ truncate_pagecache(NULL, 0, 0);
+],[
+ AC_DEFINE(HAVE_OLDSIZE_TRUNCATE_PAGECACHE, 1,
+ [with oldsize])
+])
+]) # LC_OLDSIZE_TRUNCATE_PAGECACHE
+
+#
+# LC_HAVE_DENTRY_D_U_D_ALIAS
+#
+# 3.11 kernel moved d_alias to the union d_u in struct dentry
+#
+# Some distros move d_alias to d_u but it is still a struct list
+#
+AC_DEFUN([LC_HAVE_DENTRY_D_U_D_ALIAS], [
+AS_IF([test "x$lb_cv_compile_i_dentry_d_alias_list" = xyes], [
+ LB_CHECK_COMPILE([if list 'dentry.d_u.d_alias' exist],
+ d_alias, [
+ #include <linux/list.h>
+ #include <linux/dcache.h>
+ ],[
+ struct dentry de;
+ INIT_LIST_HEAD(&de.d_u.d_alias);
+ ],[
+ AC_DEFINE(HAVE_DENTRY_D_U_D_ALIAS, 1,
+ [list dentry.d_u.d_alias exist])
+ ])
+],[
+ LB_CHECK_COMPILE([if hlist 'dentry.d_u.d_alias' exist],
+ d_alias, [
+ #include <linux/list.h>
+ #include <linux/dcache.h>
+ ],[
+ struct dentry de;
+ INIT_HLIST_NODE(&de.d_u.d_alias);
+ ],[
+ AC_DEFINE(HAVE_DENTRY_D_U_D_ALIAS, 1,
+ [hlist dentry.d_u.d_alias exist])
+ ])
+])
+]) # LC_HAVE_DENTRY_D_U_D_ALIAS
+
+#
+# LC_HAVE_DENTRY_D_CHILD
+#
+# 3.11 kernel d_child has been moved out of the union d_u
+# in struct dentry
+#
+AC_DEFUN([LC_HAVE_DENTRY_D_CHILD], [
+LB_CHECK_COMPILE([if 'dentry.d_child' exist],
+d_child, [
+ #include <linux/list.h>
+ #include <linux/dcache.h>
+],[
+ struct dentry de;
+ INIT_LIST_HEAD(&de.d_child);
+],[
+ AC_DEFINE(HAVE_DENTRY_D_CHILD, 1,
+ [dentry.d_child exist])
+])
+]) # LC_HAVE_DENTRY_D_CHILD
+
+#
+# LC_KIOCB_KI_LEFT
+#
+# 3.12 ki_left removed from struct kiocb
+#
+AC_DEFUN([LC_KIOCB_KI_LEFT], [
+LB_CHECK_COMPILE([if 'struct kiocb' with 'ki_left' member],
+kiocb_ki_left, [
+ #include <linux/aio.h>
+],[
+ ((struct kiocb*)0)->ki_left = 0;
+],[
+ AC_DEFINE(HAVE_KIOCB_KI_LEFT, 1,
+ [ki_left exist])
+])
+]) # LC_KIOCB_KI_LEFT
+
+#
+# LC_VFS_RENAME_5ARGS
+#
+# 3.13 has vfs_rename with 5 args
+#
+AC_DEFUN([LC_VFS_RENAME_5ARGS], [
+LB_CHECK_COMPILE([if Linux kernel has 'vfs_rename' with 5 args],
+vfs_rename_5args, [
+ #include <linux/fs.h>
+],[
+ vfs_rename(NULL, NULL, NULL, NULL, NULL);
+], [
+ AC_DEFINE(HAVE_VFS_RENAME_5ARGS, 1,
+ [kernel has vfs_rename with 5 args])
+])
+]) # LC_VFS_RENAME_5ARGS
+
+#
+# LC_VFS_UNLINK_3ARGS
+#
+# 3.13 has vfs_unlink with 3 args
+#
+AC_DEFUN([LC_VFS_UNLINK_3ARGS], [
+LB_CHECK_COMPILE([if Linux kernel has 'vfs_unlink' with 3 args],
+vfs_unlink_3args, [
+ #include <linux/fs.h>
+],[
+ vfs_unlink(NULL, NULL, NULL);
+], [
+ AC_DEFINE(HAVE_VFS_UNLINK_3ARGS, 1,
+ [kernel has vfs_unlink with 3 args])
+])
+]) # LC_VFS_UNLINK_3ARGS
+
+#
+# LC_HAVE_BVEC_ITER
+#
+# 3.14 move some of its data in struct bio into the new
+# struct bvec_iter
+#
+AC_DEFUN([LC_HAVE_BVEC_ITER], [
+LB_CHECK_COMPILE([if Linux kernel has struct bvec_iter],
+have_bvec_iter, [
+ #include <linux/bio.h>
+],[
+ struct bvec_iter iter;
+ iter.bi_bvec_done = 0;
+], [
+ AC_DEFINE(HAVE_BVEC_ITER, 1,
+ [kernel has struct bvec_iter])
+])
+]) # LC_HAVE_BVEC_ITER
+
+#
+# LC_HAVE_BI_CNT
+#
+# 4.4 redefined bi_cnt as __bi_cnt
+#
+AC_DEFUN([LC_HAVE_BI_CNT], [
+LB_CHECK_COMPILE([if Linux kernel has bi_cnt in struct bio],
+have_bi_cnt, [
+ #include <asm/atomic.h>
+ #include <linux/bio.h>
+],[
+ struct bio bio;
+ int cnt;
+ cnt = atomic_read(&bio.bi_cnt);
+], [
+ AC_DEFINE(HAVE_BI_CNT, 1,
+ [struct bio has bi_cnt])
+])
+]) # LC_HAVE_BI_CNT
+
+#
+# LC_HAVE_TRUNCATE_IPAGE_FINAL
+#
+# 3.14 bring truncate_inode_pages_final for evict_inode
+#
+AC_DEFUN([LC_HAVE_TRUNCATE_IPAGES_FINAL], [
+LB_CHECK_COMPILE([if Linux kernel has truncate_inode_pages_final],
+truncate_ipages_final, [
+ #include <linux/mm.h>
+],[
+ truncate_inode_pages_final(NULL);
+], [
+ AC_DEFINE(HAVE_TRUNCATE_INODE_PAGES_FINAL, 1,
+ [kernel has truncate_inode_pages_final])
+])
+]) # LC_HAVE_TRUNCATE_IPAGES_FINAL
+
+#
+# LC_IOPS_RENAME_WITH_FLAGS
+#
+# 3.14 has inode_operations->rename with 5 args
+# commit 520c8b16505236fc82daa352e6c5e73cd9870cff
+#
+AC_DEFUN([LC_IOPS_RENAME_WITH_FLAGS], [
+LB_CHECK_COMPILE([if 'inode_operations->rename' taken flags as argument],
+iops_rename_with_flags, [
+ #include <linux/fs.h>
+],[
+ struct inode *i1 = NULL, *i2 = NULL;
+ struct dentry *d1 = NULL, *d2 = NULL;
+ int rc;
+ rc = ((struct inode_operations *)0)->rename(i1, d1, i2, d2, 0);
+], [
+ AC_DEFINE(HAVE_IOPS_RENAME_WITH_FLAGS, 1,
+ [inode_operations->rename need flags as argument])
+])
+]) # LC_IOPS_RENAME_WITH_FLAGS
+
+#
+# LC_VFS_RENAME_6ARGS
+#
+# 3.15 has vfs_rename with 6 args
+#
+AC_DEFUN([LC_VFS_RENAME_6ARGS], [
+LB_CHECK_COMPILE([if Linux kernel has 'vfs_rename' with 6 args],
+vfs_rename_6args, [
+ #include <linux/fs.h>
+],[
+ vfs_rename(NULL, NULL, NULL, NULL, NULL, NULL);
+], [
+ AC_DEFINE(HAVE_VFS_RENAME_6ARGS, 1,
+ [kernel has vfs_rename with 6 args])
+])
+]) # LC_VFS_RENAME_6ARGS
+
+#
+# LC_DIRECTIO_USE_ITER
+#
+# 3.16 kernel changes direct IO to use iov_iter
+#
+AC_DEFUN([LC_DIRECTIO_USE_ITER], [
+LB_CHECK_COMPILE([if direct IO uses iov_iter],
+direct_io_iter, [
+ #include <linux/fs.h>
+],[
+ struct address_space_operations ops;
+ struct iov_iter *iter = NULL;
+ loff_t offset = 0;
+
+ ops.direct_IO(0, NULL, iter, offset);
+],[
+ AC_DEFINE(HAVE_DIRECTIO_ITER, 1,
+ [direct IO uses iov_iter])
+])
+]) # LC_DIRECTIO_USE_ITER
+
+#
+# LC_HAVE_IOV_ITER_INIT_DIRECTION
+#
+#
+# 3.16 linux commit 71d8e532b1549a478e6a6a8a44f309d050294d00
+# changed iov_iter_init api to start accepting a tag
+# that defines if its a read or write operation
+#
+AC_DEFUN([LC_HAVE_IOV_ITER_INIT_DIRECTION], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'iov_iter_init' takes a tag],
+iter_init, [
+ #include <linux/uio.h>
+ #include <linux/fs.h>
+],[
+ const struct iovec *iov = NULL;
+
+ iov_iter_init(NULL, READ, iov, 1, 0);
+],[
+ AC_DEFINE(HAVE_IOV_ITER_INIT_DIRECTION, 1,
+ [iov_iter_init handles directional tag])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_HAVE_IOV_ITER_INIT_DIRECTION
+
+#
+# LC_HAVE_IOV_ITER_TRUNCATE
+#
+#
+# 3.16 introduces a new API iov_iter_truncate()
+#
+AC_DEFUN([LC_HAVE_IOV_ITER_TRUNCATE], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'iov_iter_truncate' exists ],
+iter_truncate, [
+ #include <linux/uio.h>
+ #include <linux/fs.h>
+],[
+ struct iov_iter *i = NULL;
+
+ iov_iter_truncate(i, 0);
+],[
+ AC_DEFINE(HAVE_IOV_ITER_TRUNCATE, 1, [iov_iter_truncate exists])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_HAVE_IOV_ITER_TRUNCATE
+
+#
+# LC_HAVE_FILE_OPERATIONS_READ_WRITE_ITER
+#
+# 3.16 introduces [read|write]_iter to struct file_operations
+#
+AC_DEFUN([LC_HAVE_FILE_OPERATIONS_READ_WRITE_ITER], [
+LB_CHECK_COMPILE([if 'file_operations.[read|write]_iter' exist],
+file_function_iter, [
+ #include <linux/fs.h>
+],[
+ ((struct file_operations *)NULL)->read_iter(NULL, NULL);
+ ((struct file_operations *)NULL)->write_iter(NULL, NULL);
+],[
+ AC_DEFINE(HAVE_FILE_OPERATIONS_READ_WRITE_ITER, 1,
+ [file_operations.[read|write]_iter functions exist])
+])
+]) # LC_HAVE_FILE_OPERATIONS_READ_WRITE_ITER
+
+#
+# LC_KEY_MATCH_DATA
+#
+# 3.17 replaces key_type::match with match_preparse
+# and has new struct key_match_data
+#
+AC_DEFUN([LC_KEY_MATCH_DATA], [
+LB_CHECK_COMPILE([if struct key_match field exist],
+key_match, [
+ #include <linux/key-type.h>
+],[
+ struct key_match_data data;
+],[
+ AC_DEFINE(HAVE_KEY_MATCH_DATA, 1,
+ [struct key_match_data exist])
+])
+]) # LC_KEY_MATCH_DATA
+
+#
+# LC_NFS_FILLDIR_USE_CTX
+#
+# 3.18 kernel moved from void cookie to struct dir_context
+#
+AC_DEFUN([LC_NFS_FILLDIR_USE_CTX], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if filldir_t uses struct dir_context],
+filldir_ctx, [
+ #include <linux/fs.h>
+],[
+ int filldir(struct dir_context *ctx, const char* name,
+ int i, loff_t off, u64 tmp, unsigned temp)
+ {
+ return 0;
+ }
+
+ struct dir_context ctx = {
+ .actor = filldir,
+ };
+
+ ctx.actor(NULL, "test", 0, (loff_t) 0, 0, 0);
+],[
+ AC_DEFINE(HAVE_FILLDIR_USE_CTX, 1,
+ [filldir_t needs struct dir_context as argument])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_NFS_FILLDIR_USE_CTX
+
+#
+# LC_PERCPU_COUNTER_INIT
+#
+# 3.18 For kernels 3.18 and after percpu_counter_init starts
+# to pass a GFP_* memory allocation flag for internal
+# memory allocation purposes.
+#
+AC_DEFUN([LC_PERCPU_COUNTER_INIT], [
+LB_CHECK_COMPILE([if percpu_counter_init uses GFP_* flag as argument],
+percpu_counter_init, [
+ #include <linux/percpu_counter.h>
+],[
+ percpu_counter_init(NULL, 0, GFP_KERNEL);
+],[
+ AC_DEFINE(HAVE_PERCPU_COUNTER_INIT_GFP_FLAG, 1,
+ [percpu_counter_init uses GFP_* flag])
+])
+]) # LC_PERCPU_COUNTER_INIT
+
+#
+# LC_KIOCB_HAS_NBYTES
+#
+# 3.19 kernel removed ki_nbytes from struct kiocb
+#
+AC_DEFUN([LC_KIOCB_HAS_NBYTES], [
+LB_CHECK_COMPILE([if struct kiocb has ki_nbytes field],
+ki_nbytes, [
+ #include <linux/fs.h>
+],[
+ struct kiocb iocb;
+
+ iocb.ki_nbytes = 0;
+],[
+ AC_DEFINE(HAVE_KI_NBYTES, 1, [ki_nbytes field exist])
+])
+]) # LC_KIOCB_HAS_NBYTES
+
+#
+# LC_HAVE_DQUOT_QC_DQBLK
+#
+# 3.19 has quotactl_ops->[sg]et_dqblk that take struct kqid and qc_dqblk
+# Added in commit 14bf61ffe
+#
+AC_DEFUN([LC_HAVE_DQUOT_QC_DQBLK], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'quotactl_ops.set_dqblk' takes struct qc_dqblk],
+qc_dqblk, [
+ #include <linux/fs.h>
+ #include <linux/quota.h>
+],[
+ ((struct quotactl_ops *)0)->set_dqblk(NULL, *((struct kqid*)0), (struct qc_dqblk*)0);
+],[
+ AC_DEFINE(HAVE_DQUOT_QC_DQBLK, 1,
+ [quotactl_ops.set_dqblk takes struct qc_dqblk])
+ AC_DEFINE(HAVE_DQUOT_KQID, 1,
+ [quotactl_ops.set_dqblk takes struct kqid])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_HAVE_DQUOT_QC_DQBLK
+
+#
+# LC_BACKING_DEV_INFO_REMOVAL
+#
+# 3.20 kernel removed backing_dev_info from address_space
+#
+AC_DEFUN([LC_BACKING_DEV_INFO_REMOVAL], [
+LB_CHECK_COMPILE([if struct address_space has backing_dev_info],
+backing_dev_info, [
+ #include <linux/fs.h>
+],[
+ struct address_space mapping;
+
+ mapping.backing_dev_info = NULL;
+],[
+ AC_DEFINE(HAVE_BACKING_DEV_INFO, 1, [backing_dev_info exist])