From a5369b61a24cf75d8188af8ee554123cf7fae14c Mon Sep 17 00:00:00 2001 From: Tony Hutter Date: Thu, 22 Feb 2018 09:02:06 -0800 Subject: [PATCH] Linux 4.16 compat: use correct *_dec_and_test() Use refcount_dec_and_test() on 4.16+ kernels, atomic_dec_and_test() on older kernels. https://lwn.net/Articles/714974/ Reviewed-by: Giuseppe Di Natale Reviewed-by: Brian Behlendorf Signed-off-by: Tony Hutter Closes: #7179 Closes: #7211 --- config/kernel-acl-refcount.m4 | 20 ++++++++++++++++++++ config/kernel.m4 | 1 + include/linux/vfs_compat.h | 6 +++++- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 config/kernel-acl-refcount.m4 diff --git a/config/kernel-acl-refcount.m4 b/config/kernel-acl-refcount.m4 new file mode 100644 index 0000000000..43e3c442dc --- /dev/null +++ b/config/kernel-acl-refcount.m4 @@ -0,0 +1,20 @@ +dnl # +dnl # 4.16 kernel: check if struct posix_acl acl.a_refcount is a refcount_t. +dnl # It's an atomic_t on older kernels. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_ACL_HAS_REFCOUNT], [ + AC_MSG_CHECKING([whether posix_acl has refcount_t]) + ZFS_LINUX_TRY_COMPILE([ + #include + #include + #include + ],[ + struct posix_acl acl; + refcount_t *r __attribute__ ((unused)) = &acl.a_refcount; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_ACL_REFCOUNT, 1, [posix_acl has refcount_t]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index e9eec70d44..9b11dc1798 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -124,6 +124,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_HAVE_GENERIC_SETXATTR ZFS_AC_KERNEL_CURRENT_TIME ZFS_AC_KERNEL_VM_NODE_STAT + ZFS_AC_KERNEL_ACL_HAS_REFCOUNT AS_IF([test "$LINUX_OBJ" != "$LINUX"], [ KERNEL_MAKE="$KERNEL_MAKE O=$LINUX_OBJ" diff --git a/include/linux/vfs_compat.h b/include/linux/vfs_compat.h index 7fcf3c055e..6347268af9 100644 --- a/include/linux/vfs_compat.h +++ b/include/linux/vfs_compat.h @@ -288,9 +288,13 @@ zpl_posix_acl_release(struct posix_acl *acl) { if ((acl == NULL) || (acl == ACL_NOT_CACHED)) return; - +#ifdef HAVE_ACL_REFCOUNT + if (refcount_dec_and_test(&acl->a_refcount)) + zpl_posix_acl_release_impl(acl); +#else if (atomic_dec_and_test(&acl->a_refcount)) zpl_posix_acl_release_impl(acl); +#endif } #endif /* HAVE_POSIX_ACL_RELEASE */