+# LC_HAVE_FILE_DENTRY
+#
+# 4.5 adds wrapper file_dentry
+#
+AC_DEFUN([LC_HAVE_FILE_DENTRY], [
+LB_CHECK_COMPILE([if Linux kernel has 'file_dentry'],
+file_dentry, [
+ #include <linux/fs.h>
+],[
+ file_dentry(NULL);
+], [
+ AC_DEFINE(HAVE_FILE_DENTRY, 1,
+ [kernel has file_dentry])
+])
+]) # LC_HAVE_FILE_DENTRY
+
+#
+# LC_HAVE_INODE_LOCK
+#
+# 4.5 introduced inode_lock
+#
+AC_DEFUN([LC_HAVE_INODE_LOCK], [
+LB_CHECK_COMPILE([if 'inode_lock' is defined],
+inode_lock, [
+ #include <linux/fs.h>
+],[
+ inode_lock(NULL);
+], [
+ AC_DEFINE(HAVE_INODE_LOCK, 1,
+ [inode_lock is defined])
+])
+]) # LC_HAVE_INODE_LOCK
+
+#
+# LC_HAVE_IOP_GET_LINK
+#
+# 4.5 vfs replaced iop->follow_link with
+# iop->get_link
+#
+AC_DEFUN([LC_HAVE_IOP_GET_LINK], [
+LB_CHECK_COMPILE([if 'iop' has 'get_link'],
+inode_ops_get_link, [
+ #include <linux/fs.h>
+],[
+ struct inode_operations iop;
+ iop.get_link = NULL;
+],[
+ AC_DEFINE(HAVE_IOP_GET_LINK, 1,
+ [have iop get_link])
+])
+]) # LC_HAVE_IOP_GET_LINK
+
+#
+# LC_HAVE_IN_COMPAT_SYSCALL
+#
+# 4.6 renamed is_compat_task to in_compat_syscall
+#
+AC_DEFUN([LC_HAVE_IN_COMPAT_SYSCALL], [
+LB_CHECK_COMPILE([if 'in_compat_syscall' is defined],
+in_compat_syscall, [
+ #include <linux/compat.h>
+],[
+ in_compat_syscall();
+],[
+ AC_DEFINE(HAVE_IN_COMPAT_SYSCALL, 1,
+ [have in_compat_syscall])
+])
+]) # LC_HAVE_IN_COMPAT_SYSCALL
+
+#
+# LC_HAVE_XATTR_HANDLER_INODE_PARAM
+#
+# Kernel version 4.6 commit b296821a7c42fa58baa17513b2b7b30ae66f3336
+# and commit 5930122683dff58f0846b0f0405b4bd598a3ba6a added inode parameter
+# to xattr_handler functions
+#
+AC_DEFUN([LC_HAVE_XATTR_HANDLER_INODE_PARAM], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'struct xattr_handler' functions have inode parameter],
+xattr_handler_inode_param, [
+ #include <linux/xattr.h>
+],[
+ const struct xattr_handler handler;
+
+ ((struct xattr_handler *)0)->get(&handler, NULL, NULL, NULL, NULL, 0);
+ ((struct xattr_handler *)0)->set(&handler, NULL, NULL, NULL, NULL, 0, 0);
+],[
+ AC_DEFINE(HAVE_XATTR_HANDLER_INODE_PARAM, 1, [needs inode parameter])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_HAVE_XATTR_HANDLER_INODE_PARAM
+
+#
+# LC_DIRECTIO_2ARGS
+#
+# Kernel version 4.7 commit c8b8e32d700fe943a935e435ae251364d016c497
+# direct-io: eliminate the offset argument to ->direct_IO
+#
+AC_DEFUN([LC_DIRECTIO_2ARGS], [
+LB_CHECK_COMPILE([if '->direct_IO()' taken 2 arguments],
+direct_io_2args, [
+ #include <linux/fs.h>
+],[
+ struct address_space_operations ops;
+ struct iov_iter *iter = NULL;
+ struct kiocb *iocb = NULL;
+ int rc;
+ rc = ops.direct_IO(iocb, iter);
+],[
+ AC_DEFINE(HAVE_DIRECTIO_2ARGS, 1,
+ [direct_IO need 2 arguments])
+])
+]) # LC_DIRECTIO_2ARGS
+
+#
+# LC_GENERIC_WRITE_SYNC_2ARGS
+#
+# Kernel version 4.7 commit c8b8e32d700fe943a935e435ae251364d016c497
+# direct-io: eliminate the offset argument to ->direct_IO
+#
+AC_DEFUN([LC_GENERIC_WRITE_SYNC_2ARGS], [
+LB_CHECK_COMPILE([if 'generic_write_sync()' taken 2 arguments],
+generic_write_sync_2args, [
+ #include <linux/fs.h>
+],[
+ struct kiocb *iocb = NULL;
+ ssize_t rc;
+ rc = generic_write_sync(iocb, 0);
+],[
+ AC_DEFINE(HAVE_GENERIC_WRITE_SYNC_2ARGS, 1,
+ [generic_write_sync need 2 arguments])
+])
+]) # LC_GENERIC_WRITE_SYNC_2ARGS
+
+#
+# LC_HAVE_POSIX_ACL_VALID_USER_NS
+#
+# 4.8 posix_acl_valid takes struct user_namespace
+#
+AC_DEFUN([LC_HAVE_POSIX_ACL_VALID_USER_NS], [
+LB_CHECK_COMPILE([if 'posix_acl_valid' takes 'struct user_namespace'],
+posix_acl_valid, [
+ #include <linux/fs.h>
+ #include <linux/posix_acl.h>
+],[
+ posix_acl_valid((struct user_namespace*)NULL, (const struct posix_acl*)NULL);
+],[
+ AC_DEFINE(HAVE_POSIX_ACL_VALID_USER_NS, 1,
+ [posix_acl_valid takes struct user_namespace])
+])
+]) # LC_HAVE_POSIX_ACL_VALID_USER_NS
+
+#
+# LC_D_COMPARE_4ARGS
+#
+# Kernel version 4.8 commit 6fa67e707559303e086303aeecc9e8b91ef497d5
+# get rid of 'parent' argument of ->d_compare()
+#
+AC_DEFUN([LC_D_COMPARE_4ARGS], [
+LB_CHECK_COMPILE([if 'd_compare' taken 4 arguments],
+d_compare_4args, [
+ #include <linux/dcache.h>
+],[
+ ((struct dentry_operations*)0)->d_compare(NULL,0,NULL,NULL);
+],[
+ AC_DEFINE(HAVE_D_COMPARE_4ARGS, 1,
+ [d_compare need 4 arguments])
+])
+]) # LC_D_COMPARE_4ARGS
+
+#
+# LC_FULL_NAME_HASH_3ARGS
+#
+# Kernel version 4.8 commit 8387ff2577eb9ed245df9a39947f66976c6bcd02
+# vfs: make the string hashes salt the hash
+#
+AC_DEFUN([LC_FULL_NAME_HASH_3ARGS], [
+LB_CHECK_COMPILE([if 'full_name_hash' taken 3 arguments],
+full_name_hash_3args, [
+ #include <linux/stringhash.h>
+],[
+ unsigned int hash;
+ hash = full_name_hash(NULL,NULL,0);
+],[
+ AC_DEFINE(HAVE_FULL_NAME_HASH_3ARGS, 1,
+ [full_name_hash need 3 arguments])
+])
+]) # LC_FULL_NAME_HASH_3ARGS
+
+#
+# LC_STRUCT_POSIX_ACL_XATTR
+#
+# Kernel version 4.8 commit 2211d5ba5c6c4e972ba6dbc912b2897425ea6621
+# posix_acl: xattr representation cleanups
+#
+AC_DEFUN([LC_STRUCT_POSIX_ACL_XATTR], [
+LB_CHECK_COMPILE([if 'struct posix_acl_xattr_{header,entry}' defined],
+struct_posix_acl_xattr, [
+ #include <linux/fs.h>
+ #include <linux/posix_acl_xattr.h>
+],[
+ struct posix_acl_xattr_header *h = NULL;
+ struct posix_acl_xattr_entry *e;
+ e = (void *)(h + 1);
+],[
+ AC_DEFINE(HAVE_STRUCT_POSIX_ACL_XATTR, 1,
+ [struct posix_acl_xattr_{header,entry} defined])
+])
+]) # LC_STRUCT_POSIX_ACL_XATTR
+
+#
+# LC_IOP_XATTR
+#
+# Kernel version 4.8 commit fd50ecaddf8372a1d96e0daeaac0f93cf04e4d42
+# removed {get,set,remove}xattr inode operations
+#
+AC_DEFUN([LC_IOP_XATTR], [
+LB_CHECK_COMPILE([if 'inode_operations' has {get,set,remove}xattr members],
+inode_ops_xattr, [
+ #include <linux/fs.h>
+],[
+ struct inode_operations iop;
+ iop.setxattr = NULL;
+ iop.getxattr = NULL;
+ iop.removexattr = NULL;
+],[
+ AC_DEFINE(HAVE_IOP_XATTR, 1,
+ [inode_operations has {get,set,remove}xattr members])
+])
+]) # LC_IOP_XATTR
+
+#
+# LC_GROUP_INFO_GID
+#
+# Kernel version 4.9 commit 81243eacfa400f5f7b89f4c2323d0de9982bb0fb
+# cred: simpler, 1D supplementary groups
+#
+AC_DEFUN([LC_GROUP_INFO_GID], [
+LB_CHECK_COMPILE([if 'struct group_info' has member 'gid'],
+group_info_gid, [
+ #include <linux/cred.h>
+],[
+ kgid_t *p;
+ p = ((struct group_info *)0)->gid;
+],[
+ AC_DEFINE(HAVE_GROUP_INFO_GID, 1,
+ [struct group_info has member gid])
+])
+]) # LC_GROUP_INFO_GID
+
+#
+# LC_VFS_SETXATTR
+#
+# Kernel version 4.9 commit 5d6c31910bc0713e37628dc0ce677dcb13c8ccf4
+# added __vfs_{get,set,remove}xattr helpers
+#
+AC_DEFUN([LC_VFS_SETXATTR], [
+LB_CHECK_COMPILE([if '__vfs_setxattr' helper is available],
+vfs_setxattr, [
+ #include <linux/xattr.h>
+],[
+ __vfs_setxattr(NULL, NULL, NULL, NULL, 0, 0);
+],[
+ AC_DEFINE(HAVE_VFS_SETXATTR, 1,
+ ['__vfs_setxattr is available])
+])
+]) # LC_VFS_SETXATTR
+
+#
+# LC_IOP_GENERIC_READLINK
+#
+# Kernel version 4.10 commit dfeef68862edd7d4bafe68ef7aeb5f658ef24bb5
+# removed generic_readlink from individual file systems
+#
+AC_DEFUN([LC_IOP_GENERIC_READLINK], [
+LB_CHECK_COMPILE([if 'generic_readlink' still exist],
+inode_ops_readlink, [
+ #include <linux/fs.h>
+],[
+ struct inode_operations iop;
+ iop.readlink = generic_readlink;
+],[
+ AC_DEFINE(HAVE_IOP_GENERIC_READLINK, 1,
+ [generic_readlink has been removed])
+])
+]) # LC_IOP_GENERIC_READLINK
+
+#
+# LC_HAVE_VM_FAULT_ADDRESS
+#
+# Kernel version 4.10 commit 1a29d85eb0f19b7d8271923d8917d7b4f5540b3e
+# removed virtual_address field. Need to use address field instead
+#
+AC_DEFUN([LC_HAVE_VM_FAULT_ADDRESS], [
+LB_CHECK_COMPILE([if 'struct vm_fault' replaced virtual_address with address field],
+vm_fault_address, [
+ #include <linux/mm.h>
+],[
+ struct vm_fault vmf;
+ vmf.address = NULL;
+],[
+ AC_DEFINE(HAVE_VM_FAULT_ADDRESS, 1,
+ [virtual_address has been replaced by address field])
+])
+]) # LC_HAVE_VM_FAULT_ADDRESS
+
+#