Skip to content

Commit 7a41ef2

Browse files
behlendorftonyhutter
authored andcommitted
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 <[email protected]> Reviewed-by: Tony Hutter <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #12548
1 parent 72d16a9 commit 7a41ef2

File tree

3 files changed

+52
-9
lines changed

3 files changed

+52
-9
lines changed

config/kernel-acl.m4

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ dnl #
162162
dnl # 3.1 API change,
163163
dnl # Check if inode_operations contains the function get_acl
164164
dnl #
165+
dnl # 5.15 API change,
166+
dnl # Added the bool rcu argument to get_acl for rcu path walk.
167+
dnl #
165168
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
166169
ZFS_LINUX_TEST_SRC([inode_operations_get_acl], [
167170
#include <linux/fs.h>
@@ -174,14 +177,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_GET_ACL], [
174177
.get_acl = get_acl_fn,
175178
};
176179
],[])
180+
181+
ZFS_LINUX_TEST_SRC([inode_operations_get_acl_rcu], [
182+
#include <linux/fs.h>
183+
184+
struct posix_acl *get_acl_fn(struct inode *inode, int type,
185+
bool rcu) { return NULL; }
186+
187+
static const struct inode_operations
188+
iops __attribute__ ((unused)) = {
189+
.get_acl = get_acl_fn,
190+
};
191+
],[])
177192
])
178193

179194
AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_GET_ACL], [
180195
AC_MSG_CHECKING([whether iops->get_acl() exists])
181196
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl], [
182197
AC_MSG_RESULT(yes)
198+
AC_DEFINE(HAVE_GET_ACL, 1, [iops->get_acl() exists])
183199
],[
184-
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
200+
ZFS_LINUX_TEST_RESULT([inode_operations_get_acl_rcu], [
201+
AC_MSG_RESULT(yes)
202+
AC_DEFINE(HAVE_GET_ACL_RCU, 1, [iops->get_acl() takes rcu])
203+
],[
204+
ZFS_LINUX_TEST_ERROR([iops->get_acl()])
205+
])
185206
])
186207
])
187208

include/os/linux/zfs/sys/zpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip,
7070
extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type);
7171
#endif /* HAVE_SET_ACL_USERNS */
7272
#endif /* HAVE_SET_ACL */
73+
#if defined(HAVE_GET_ACL_RCU)
74+
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type, bool rcu);
75+
#elif defined(HAVE_GET_ACL)
7376
extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
77+
#endif
7478
extern int zpl_init_acl(struct inode *ip, struct inode *dir);
7579
extern int zpl_chmod_acl(struct inode *ip);
7680
#else

module/os/linux/zfs/zpl_xattr.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,13 +1012,12 @@ zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type)
10121012
}
10131013
#endif /* HAVE_SET_ACL */
10141014

1015-
struct posix_acl *
1016-
zpl_get_acl(struct inode *ip, int type)
1015+
static struct posix_acl *
1016+
zpl_get_acl_impl(struct inode *ip, int type)
10171017
{
10181018
struct posix_acl *acl;
10191019
void *value = NULL;
10201020
char *name;
1021-
int size;
10221021

10231022
/*
10241023
* 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)
10421041
return (ERR_PTR(-EINVAL));
10431042
}
10441043

1045-
size = zpl_xattr_get(ip, name, NULL, 0);
1044+
int size = zpl_xattr_get(ip, name, NULL, 0);
10461045
if (size > 0) {
10471046
value = kmem_alloc(size, KM_SLEEP);
10481047
size = zpl_xattr_get(ip, name, value, size);
@@ -1068,6 +1067,25 @@ zpl_get_acl(struct inode *ip, int type)
10681067
return (acl);
10691068
}
10701069

1070+
#if defined(HAVE_GET_ACL_RCU)
1071+
struct posix_acl *
1072+
zpl_get_acl(struct inode *ip, int type, bool rcu)
1073+
{
1074+
if (rcu)
1075+
return (ERR_PTR(-ECHILD));
1076+
1077+
return (zpl_get_acl_impl(ip, type));
1078+
}
1079+
#elif defined(HAVE_GET_ACL)
1080+
struct posix_acl *
1081+
zpl_get_acl(struct inode *ip, int type)
1082+
{
1083+
return (zpl_get_acl_impl(ip, type));
1084+
}
1085+
#else
1086+
#error "Unsupported iops->get_acl() implementation"
1087+
#endif /* HAVE_GET_ACL_RCU */
1088+
10711089
int
10721090
zpl_init_acl(struct inode *ip, struct inode *dir)
10731091
{
@@ -1078,7 +1096,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir)
10781096
return (0);
10791097

10801098
if (!S_ISLNK(ip->i_mode)) {
1081-
acl = zpl_get_acl(dir, ACL_TYPE_DEFAULT);
1099+
acl = zpl_get_acl_impl(dir, ACL_TYPE_DEFAULT);
10821100
if (IS_ERR(acl))
10831101
return (PTR_ERR(acl));
10841102
if (!acl) {
@@ -1127,7 +1145,7 @@ zpl_chmod_acl(struct inode *ip)
11271145
if (S_ISLNK(ip->i_mode))
11281146
return (-EOPNOTSUPP);
11291147

1130-
acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
1148+
acl = zpl_get_acl_impl(ip, ACL_TYPE_ACCESS);
11311149
if (IS_ERR(acl) || !acl)
11321150
return (PTR_ERR(acl));
11331151

@@ -1189,7 +1207,7 @@ __zpl_xattr_acl_get_access(struct inode *ip, const char *name,
11891207
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
11901208
return (-EOPNOTSUPP);
11911209

1192-
acl = zpl_get_acl(ip, type);
1210+
acl = zpl_get_acl_impl(ip, type);
11931211
if (IS_ERR(acl))
11941212
return (PTR_ERR(acl));
11951213
if (acl == NULL)
@@ -1217,7 +1235,7 @@ __zpl_xattr_acl_get_default(struct inode *ip, const char *name,
12171235
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
12181236
return (-EOPNOTSUPP);
12191237

1220-
acl = zpl_get_acl(ip, type);
1238+
acl = zpl_get_acl_impl(ip, type);
12211239
if (IS_ERR(acl))
12221240
return (PTR_ERR(acl));
12231241
if (acl == NULL)

0 commit comments

Comments
 (0)