Linux 5.15 compat: get_acl()
Kernel commits 332f606b32b6 ovl: enable RCU'd ->get_acl() 0cad6246621b vfs: add rcu argument to ->get_acl() callback Added compatibility code to detect the new ->get_acl() interface and correctly handle the case where the new rcu argument is set. Reviewed-by: Coleman Kane <ckane@colemankane.org> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #12548
This commit is contained in:
parent
72d16a9b49
commit
7a41ef240a
|
@ -162,6 +162,9 @@ dnl #
|
||||||
dnl # 3.1 API change,
|
dnl # 3.1 API change,
|
||||||
dnl # Check if inode_operations contains the function get_acl
|
dnl # Check if inode_operations contains the function get_acl
|
||||||
dnl #
|
dnl #
|
||||||
|
dnl # 5.15 API change,
|
||||||
|
dnl # Added the bool rcu argument to get_acl for rcu path walk.
|
||||||
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
|
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
@ -174,14 +177,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
|
||||||
.get_acl = get_acl_fn,
|
.get_acl = get_acl_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[])
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_get_acl_rcu], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
struct posix_acl *get_acl_fn(struct inode *inode, int type,
|
||||||
|
bool rcu) { return NULL; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.get_acl = get_acl_fn,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
|
||||||
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
AC_MSG_CHECKING([whether iops->get_acl() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
|
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl_rcu], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_GET_ACL_RCU, 1, [iops->get_acl() takes rcu])
|
||||||
|
],[
|
||||||
|
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
|
||||||
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,11 @@ extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip,
|
||||||
extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type);
|
extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type);
|
||||||
#endif /* HAVE_SET_ACL_USERNS */
|
#endif /* HAVE_SET_ACL_USERNS */
|
||||||
#endif /* HAVE_SET_ACL */
|
#endif /* HAVE_SET_ACL */
|
||||||
|
#if defined(HAVE_GET_ACL_RCU)
|
||||||
|
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type, bool rcu);
|
||||||
|
#elif defined(HAVE_GET_ACL)
|
||||||
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
|
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
|
||||||
|
#endif
|
||||||
extern int zpl_init_acl(struct inode *ip, struct inode *dir);
|
extern int zpl_init_acl(struct inode *ip, struct inode *dir);
|
||||||
extern int zpl_chmod_acl(struct inode *ip);
|
extern int zpl_chmod_acl(struct inode *ip);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1012,13 +1012,12 @@ zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SET_ACL */
|
#endif /* HAVE_SET_ACL */
|
||||||
|
|
||||||
struct posix_acl *
|
static struct posix_acl *
|
||||||
zpl_get_acl(struct inode *ip, int type)
|
zpl_get_acl_impl(struct inode *ip, int type)
|
||||||
{
|
{
|
||||||
struct posix_acl *acl;
|
struct posix_acl *acl;
|
||||||
void *value = NULL;
|
void *value = NULL;
|
||||||
char *name;
|
char *name;
|
||||||
int size;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As of Linux 3.14, the kernel get_acl will check this for us.
|
* As of Linux 3.14, the kernel get_acl will check this for us.
|
||||||
|
@ -1042,7 +1041,7 @@ zpl_get_acl(struct inode *ip, int type)
|
||||||
return (ERR_PTR(-EINVAL));
|
return (ERR_PTR(-EINVAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
size = zpl_xattr_get(ip, name, NULL, 0);
|
int size = zpl_xattr_get(ip, name, NULL, 0);
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
value = kmem_alloc(size, KM_SLEEP);
|
value = kmem_alloc(size, KM_SLEEP);
|
||||||
size = zpl_xattr_get(ip, name, value, size);
|
size = zpl_xattr_get(ip, name, value, size);
|
||||||
|
@ -1068,6 +1067,25 @@ zpl_get_acl(struct inode *ip, int type)
|
||||||
return (acl);
|
return (acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_GET_ACL_RCU)
|
||||||
|
struct posix_acl *
|
||||||
|
zpl_get_acl(struct inode *ip, int type, bool rcu)
|
||||||
|
{
|
||||||
|
if (rcu)
|
||||||
|
return (ERR_PTR(-ECHILD));
|
||||||
|
|
||||||
|
return (zpl_get_acl_impl(ip, type));
|
||||||
|
}
|
||||||
|
#elif defined(HAVE_GET_ACL)
|
||||||
|
struct posix_acl *
|
||||||
|
zpl_get_acl(struct inode *ip, int type)
|
||||||
|
{
|
||||||
|
return (zpl_get_acl_impl(ip, type));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error "Unsupported iops->get_acl() implementation"
|
||||||
|
#endif /* HAVE_GET_ACL_RCU */
|
||||||
|
|
||||||
int
|
int
|
||||||
zpl_init_acl(struct inode *ip, struct inode *dir)
|
zpl_init_acl(struct inode *ip, struct inode *dir)
|
||||||
{
|
{
|
||||||
|
@ -1078,7 +1096,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (!S_ISLNK(ip->i_mode)) {
|
if (!S_ISLNK(ip->i_mode)) {
|
||||||
acl = zpl_get_acl(dir, ACL_TYPE_DEFAULT);
|
acl = zpl_get_acl_impl(dir, ACL_TYPE_DEFAULT);
|
||||||
if (IS_ERR(acl))
|
if (IS_ERR(acl))
|
||||||
return (PTR_ERR(acl));
|
return (PTR_ERR(acl));
|
||||||
if (!acl) {
|
if (!acl) {
|
||||||
|
@ -1127,7 +1145,7 @@ zpl_chmod_acl(struct inode *ip)
|
||||||
if (S_ISLNK(ip->i_mode))
|
if (S_ISLNK(ip->i_mode))
|
||||||
return (-EOPNOTSUPP);
|
return (-EOPNOTSUPP);
|
||||||
|
|
||||||
acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
|
acl = zpl_get_acl_impl(ip, ACL_TYPE_ACCESS);
|
||||||
if (IS_ERR(acl) || !acl)
|
if (IS_ERR(acl) || !acl)
|
||||||
return (PTR_ERR(acl));
|
return (PTR_ERR(acl));
|
||||||
|
|
||||||
|
@ -1189,7 +1207,7 @@ __zpl_xattr_acl_get_access(struct inode *ip, const char *name,
|
||||||
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
|
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
|
||||||
return (-EOPNOTSUPP);
|
return (-EOPNOTSUPP);
|
||||||
|
|
||||||
acl = zpl_get_acl(ip, type);
|
acl = zpl_get_acl_impl(ip, type);
|
||||||
if (IS_ERR(acl))
|
if (IS_ERR(acl))
|
||||||
return (PTR_ERR(acl));
|
return (PTR_ERR(acl));
|
||||||
if (acl == NULL)
|
if (acl == NULL)
|
||||||
|
@ -1217,7 +1235,7 @@ __zpl_xattr_acl_get_default(struct inode *ip, const char *name,
|
||||||
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
|
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
|
||||||
return (-EOPNOTSUPP);
|
return (-EOPNOTSUPP);
|
||||||
|
|
||||||
acl = zpl_get_acl(ip, type);
|
acl = zpl_get_acl_impl(ip, type);
|
||||||
if (IS_ERR(acl))
|
if (IS_ERR(acl))
|
||||||
return (PTR_ERR(acl));
|
return (PTR_ERR(acl));
|
||||||
if (acl == NULL)
|
if (acl == NULL)
|
||||||
|
|
Loading…
Reference in New Issue