aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Norris <rob.norris@truenas.com>2026-01-27 05:49:59 +0000
committerBrian Behlendorf <behlendorf1@llnl.gov>2026-02-23 17:44:48 +0000
commitd34fd6cff3ac882a0f26cb6bdd5a5b1c189c0e82 (patch)
treee7f0852952ec2b3273dfcca880f12c06d520c101
parent204de946ebd1e540efe0067f3b880daf0795c1fb (diff)
-rw-r--r--config/kernel-acl.m431
-rw-r--r--include/os/linux/kernel/linux/xattr_compat.h17
2 files changed, 48 insertions, 0 deletions
diff --git a/config/kernel-acl.m4 b/config/kernel-acl.m4
index bced1990bfc1..9350a4c5f00e 100644
--- a/config/kernel-acl.m4
+++ b/config/kernel-acl.m4
@@ -23,6 +23,35 @@ AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T], [
])
dnl #
+dnl # 7.0 API change
+dnl # posix_acl_to_xattr() now allocates and returns the value.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_POSIX_ACL_TO_XATTR_ALLOC], [
+ ZFS_LINUX_TEST_SRC([posix_acl_to_xattr_alloc], [
+ #include <linux/fs.h>
+ #include <linux/posix_acl_xattr.h>
+ ], [
+ struct user_namespace *ns = NULL;
+ struct posix_acl *acl = NULL;
+ size_t size = 0;
+ gfp_t gfp = 0;
+ void *xattr = NULL;
+ xattr = posix_acl_to_xattr(ns, acl, &size, gfp);
+ ])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_POSIX_ACL_TO_XATTR_ALLOC], [
+ AC_MSG_CHECKING([whether posix_acl_to_xattr() allocates its result]);
+ ZFS_LINUX_TEST_RESULT([posix_acl_to_xattr_alloc], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_POSIX_ACL_TO_XATTR_ALLOC, 1,
+ [posix_acl_to_xattr() allocates its result])
+ ], [
+ AC_MSG_RESULT(no)
+ ])
+])
+
+dnl #
dnl # 3.1 API change,
dnl # Check if inode_operations contains the function get_acl
dnl #
@@ -174,12 +203,14 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_ACL], [
ZFS_AC_KERNEL_SRC_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
+ ZFS_AC_KERNEL_SRC_POSIX_ACL_TO_XATTR_ALLOC
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL
ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL
])
AC_DEFUN([ZFS_AC_KERNEL_ACL], [
ZFS_AC_KERNEL_POSIX_ACL_EQUIV_MODE_WANTS_UMODE_T
+ ZFS_AC_KERNEL_POSIX_ACL_TO_XATTR_ALLOC
ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL
ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL
])
diff --git a/include/os/linux/kernel/linux/xattr_compat.h b/include/os/linux/kernel/linux/xattr_compat.h
index f2f7e1ed017f..39645c19094f 100644
--- a/include/os/linux/kernel/linux/xattr_compat.h
+++ b/include/os/linux/kernel/linux/xattr_compat.h
@@ -130,10 +130,27 @@ zpl_acl_from_xattr(const void *value, int size)
return (posix_acl_from_xattr(kcred->user_ns, value, size));
}
+/*
+ * Linux 7.0 API change. posix_acl_to_xattr() changed from filling the
+ * caller-provided buffer to allocating a buffer with enough space and
+ * returning it. We wrap this up by copying the result into the provided
+ * buffer and freeing the allocated buffer.
+ */
static inline int
zpl_acl_to_xattr(struct posix_acl *acl, void *value, int size)
{
+#ifdef HAVE_POSIX_ACL_TO_XATTR_ALLOC
+ size_t s = 0;
+ void *v = posix_acl_to_xattr(kcred->user_ns, acl, &s,
+ kmem_flags_convert(KM_SLEEP));
+ if (v == NULL)
+ return (-ENOMEM);
+ memcpy(value, v, MIN(size, s));
+ kfree(v);
+ return (0);
+#else
return (posix_acl_to_xattr(kcred->user_ns, acl, value, size));
+#endif
}
#endif /* _ZFS_XATTR_H */