Skip to content

Commit a6e1052

Browse files
ckanebehlendorf
authored andcommitted
Linux 5.12 compat: idmapped mounts
In Linux 5.12, the filesystem API was modified to support ipmapped mounts by adding a "struct user_namespace *" parameter to a number functions and VFS handlers. This change adds the needed autoconf macros to detect the new interfaces and updates the code appropriately. This change does not add support for idmapped mounts, instead it preserves the existing behavior by passing the initial user namespace where needed. A subsequent commit will be required to add support for idmapped mounted. Reviewed-by: Tony Hutter <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Co-authored-by: Brian Behlendorf <[email protected]> Signed-off-by: Coleman Kane <[email protected]> Closes openzfs#11712
1 parent f742627 commit a6e1052

22 files changed

+557
-123
lines changed

config/kernel-generic_fillattr.m4

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
dnl #
2+
dnl # 5.12 API
3+
dnl #
4+
dnl # generic_fillattr in linux/fs.h now requires a struct user_namespace*
5+
dnl # as the first arg, to support idmapped mounts.
6+
dnl #
7+
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [
8+
ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
9+
#include <linux/fs.h>
10+
],[
11+
struct user_namespace *userns = NULL;
12+
struct inode *in = NULL;
13+
struct kstat *k = NULL;
14+
generic_fillattr(userns, in, k);
15+
])
16+
])
17+
18+
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [
19+
AC_MSG_CHECKING([whether generic_fillattr requres struct user_namespace*])
20+
ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
21+
AC_MSG_RESULT([yes])
22+
AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1,
23+
[generic_fillattr requires struct user_namespace*])
24+
],[
25+
AC_MSG_RESULT([no])
26+
])
27+
])
28+

config/kernel-inode-create.m4

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,25 @@
1-
dnl #
2-
dnl # 3.6 API change
3-
dnl #
4-
AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
1+
AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
2+
dnl #
3+
dnl # 5.12 API change that added the struct user_namespace* arg
4+
dnl # to the front of this function type's arg list.
5+
dnl #
6+
ZFS_LINUX_TEST_SRC([create_userns], [
7+
#include <linux/fs.h>
8+
#include <linux/sched.h>
9+
10+
int inode_create(struct user_namespace *userns,
11+
struct inode *inode ,struct dentry *dentry,
12+
umode_t umode, bool flag) { return 0; }
13+
14+
static const struct inode_operations
15+
iops __attribute__ ((unused)) = {
16+
.create = inode_create,
17+
};
18+
],[])
19+
20+
dnl #
21+
dnl # 3.6 API change
22+
dnl #
523
ZFS_LINUX_TEST_SRC([create_flags], [
624
#include <linux/fs.h>
725
#include <linux/sched.h>
@@ -16,11 +34,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
1634
],[])
1735
])
1836

19-
AC_DEFUN([ZFS_AC_KERNEL_CREATE_FLAGS], [
20-
AC_MSG_CHECKING([whether iops->create() passes flags])
21-
ZFS_LINUX_TEST_RESULT([create_flags], [
37+
AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
38+
AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
39+
ZFS_LINUX_TEST_RESULT([create_userns], [
2240
AC_MSG_RESULT(yes)
41+
AC_DEFINE(HAVE_IOPS_CREATE_USERNS, 1,
42+
[iops->create() takes struct user_namespace*])
2343
],[
24-
ZFS_LINUX_TEST_ERROR([iops->create()])
44+
AC_MSG_RESULT(no)
45+
46+
AC_MSG_CHECKING([whether iops->create() passes flags])
47+
ZFS_LINUX_TEST_RESULT([create_flags], [
48+
AC_MSG_RESULT(yes)
49+
],[
50+
ZFS_LINUX_TEST_ERROR([iops->create()])
51+
])
2552
])
2653
])

config/kernel-inode-getattr.m4

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,29 @@
1-
dnl #
2-
dnl # Linux 4.11 API
3-
dnl # See torvalds/linux@a528d35
4-
dnl #
51
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
2+
dnl #
3+
dnl # Linux 5.12 API
4+
dnl # The getattr I/O operations handler type was extended to require
5+
dnl # a struct user_namespace* as its first arg, to support idmapped
6+
dnl # mounts.
7+
dnl #
8+
ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
9+
#include <linux/fs.h>
10+
11+
int test_getattr(
12+
struct user_namespace *userns,
13+
const struct path *p, struct kstat *k,
14+
u32 request_mask, unsigned int query_flags)
15+
{ return 0; }
16+
17+
static const struct inode_operations
18+
iops __attribute__ ((unused)) = {
19+
.getattr = test_getattr,
20+
};
21+
],[])
22+
23+
dnl #
24+
dnl # Linux 4.11 API
25+
dnl # See torvalds/linux@a528d35
26+
dnl #
627
ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
728
#include <linux/fs.h>
829
@@ -33,21 +54,39 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
3354
])
3455

3556
AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
36-
AC_MSG_CHECKING([whether iops->getattr() takes a path])
37-
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
57+
dnl #
58+
dnl # Kernel 5.12 test
59+
dnl #
60+
AC_MSG_CHECKING([whether iops->getattr() takes user_namespace])
61+
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_userns], [
3862
AC_MSG_RESULT(yes)
39-
AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
40-
[iops->getattr() takes a path])
63+
AC_DEFINE(HAVE_USERNS_IOPS_GETATTR, 1,
64+
[iops->getattr() takes struct user_namespace*])
4165
],[
4266
AC_MSG_RESULT(no)
4367
44-
AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
45-
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
68+
dnl #
69+
dnl # Kernel 4.11 test
70+
dnl #
71+
AC_MSG_CHECKING([whether iops->getattr() takes a path])
72+
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
4673
AC_MSG_RESULT(yes)
47-
AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
48-
[iops->getattr() takes a vfsmount])
74+
AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
75+
[iops->getattr() takes a path])
4976
],[
5077
AC_MSG_RESULT(no)
78+
79+
dnl #
80+
dnl # Kernel < 4.11 test
81+
dnl #
82+
AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
83+
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
84+
AC_MSG_RESULT(yes)
85+
AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
86+
[iops->getattr() takes a vfsmount])
87+
],[
88+
AC_MSG_RESULT(no)
89+
])
5190
])
5291
])
5392
])

config/kernel-is_owner_or_cap.m4

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [
1111
struct inode *ip = NULL;
1212
(void) inode_owner_or_capable(ip);
1313
])
14+
15+
ZFS_LINUX_TEST_SRC([inode_owner_or_capable_idmapped], [
16+
#include <linux/fs.h>
17+
],[
18+
struct inode *ip = NULL;
19+
(void) inode_owner_or_capable(&init_user_ns, ip);
20+
])
1421
])
1522

1623
AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
1724
AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
1825
ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
1926
AC_MSG_RESULT(yes)
20-
],[
21-
ZFS_LINUX_TEST_ERROR([capability])
27+
AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
28+
[inode_owner_or_capable() exists])
29+
], [
30+
AC_MSG_RESULT(no)
31+
32+
AC_MSG_CHECKING(
33+
[whether inode_owner_or_capable() takes user_ns])
34+
ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_idmapped], [
35+
AC_MSG_RESULT(yes)
36+
AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED, 1,
37+
[inode_owner_or_capable() takes user_ns])
38+
],[
39+
ZFS_LINUX_TEST_ERROR([capability])
40+
])
2241
])
2342
])

config/kernel-mkdir-umode-t.m4

Lines changed: 0 additions & 32 deletions
This file was deleted.

config/kernel-mkdir.m4

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
dnl #
2+
dnl # Supported mkdir() interfaces checked newest to oldest.
3+
dnl #
4+
AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
5+
dnl #
6+
dnl # 5.12 API change
7+
dnl # The struct user_namespace arg was added as the first argument to
8+
dnl # mkdir()
9+
dnl #
10+
ZFS_LINUX_TEST_SRC([mkdir_user_namespace], [
11+
#include <linux/fs.h>
12+
13+
int mkdir(struct user_namespace *userns,
14+
struct inode *inode, struct dentry *dentry,
15+
umode_t umode) { return 0; }
16+
17+
static const struct inode_operations
18+
iops __attribute__ ((unused)) = {
19+
.mkdir = mkdir,
20+
};
21+
],[])
22+
23+
dnl #
24+
dnl # 3.3 API change
25+
dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
26+
dnl # umode_t type rather than an int. The expectation is that any backport
27+
dnl # would also change all three prototypes. However, if it turns out that
28+
dnl # some distribution doesn't backport the whole thing this could be
29+
dnl # broken apart into three separate checks.
30+
dnl #
31+
ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
32+
#include <linux/fs.h>
33+
34+
int mkdir(struct inode *inode, struct dentry *dentry,
35+
umode_t umode) { return 0; }
36+
37+
static const struct inode_operations
38+
iops __attribute__ ((unused)) = {
39+
.mkdir = mkdir,
40+
};
41+
],[])
42+
])
43+
44+
AC_DEFUN([ZFS_AC_KERNEL_MKDIR], [
45+
dnl #
46+
dnl # 5.12 API change
47+
dnl # The struct user_namespace arg was added as the first argument to
48+
dnl # mkdir() of the iops structure.
49+
dnl #
50+
AC_MSG_CHECKING([whether iops->mkdir() takes struct user_namespace*])
51+
ZFS_LINUX_TEST_RESULT([mkdir_user_namespace], [
52+
AC_MSG_RESULT(yes)
53+
AC_DEFINE(HAVE_IOPS_MKDIR_USERNS, 1,
54+
[iops->mkdir() takes struct user_namespace*])
55+
],[
56+
AC_MSG_CHECKING([whether iops->mkdir() takes umode_t])
57+
ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
58+
AC_MSG_RESULT(yes)
59+
AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
60+
[iops->mkdir() takes umode_t])
61+
],[
62+
ZFS_LINUX_TEST_ERROR([mkdir()])
63+
])
64+
])
65+
])

config/kernel-mknod.m4

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
2+
dnl #
3+
dnl # 5.12 API change that added the struct user_namespace* arg
4+
dnl # to the front of this function type's arg list.
5+
dnl #
6+
ZFS_LINUX_TEST_SRC([mknod_userns], [
7+
#include <linux/fs.h>
8+
#include <linux/sched.h>
9+
10+
int tmp_mknod(struct user_namespace *userns,
11+
struct inode *inode ,struct dentry *dentry,
12+
umode_t u, dev_t d) { return 0; }
13+
14+
static const struct inode_operations
15+
iops __attribute__ ((unused)) = {
16+
.mknod = tmp_mknod,
17+
};
18+
],[])
19+
])
20+
21+
AC_DEFUN([ZFS_AC_KERNEL_MKNOD], [
22+
AC_MSG_CHECKING([whether iops->mknod() takes struct user_namespace*])
23+
ZFS_LINUX_TEST_RESULT([mknod_userns], [
24+
AC_MSG_RESULT(yes)
25+
AC_DEFINE(HAVE_IOPS_MKNOD_USERNS, 1,
26+
[iops->mknod() takes struct user_namespace*])
27+
],[
28+
AC_MSG_RESULT(no)
29+
])
30+
])

config/kernel-rename.m4

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
dnl #
2-
dnl # 4.9 API change,
3-
dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
4-
dnl # flags.
5-
dnl #
6-
AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
7-
ZFS_LINUX_TEST_SRC([inode_operations_rename], [
1+
AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
2+
dnl #
3+
dnl # 4.9 API change,
4+
dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
5+
dnl # flags.
6+
dnl #
7+
ZFS_LINUX_TEST_SRC([inode_operations_rename_flags], [
88
#include <linux/fs.h>
99
int rename_fn(struct inode *sip, struct dentry *sdp,
1010
struct inode *tip, struct dentry *tdp,
@@ -15,15 +15,41 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
1515
.rename = rename_fn,
1616
};
1717
],[])
18+
19+
dnl #
20+
dnl # 5.12 API change,
21+
dnl #
22+
dnl # Linux 5.12 introduced passing struct user_namespace* as the first argument
23+
dnl # of the rename() and other inode_operations members.
24+
dnl #
25+
ZFS_LINUX_TEST_SRC([inode_operations_rename_userns], [
26+
#include <linux/fs.h>
27+
int rename_fn(struct user_namespace *user_ns, struct inode *sip,
28+
struct dentry *sdp, struct inode *tip, struct dentry *tdp,
29+
unsigned int flags) { return 0; }
30+
31+
static const struct inode_operations
32+
iops __attribute__ ((unused)) = {
33+
.rename = rename_fn,
34+
};
35+
],[])
1836
])
1937

20-
AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
21-
AC_MSG_CHECKING([whether iops->rename() wants flags])
22-
ZFS_LINUX_TEST_RESULT([inode_operations_rename], [
38+
AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
39+
AC_MSG_CHECKING([whether iops->rename() takes struct user_namespace*])
40+
ZFS_LINUX_TEST_RESULT([inode_operations_rename_userns], [
2341
AC_MSG_RESULT(yes)
24-
AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
25-
[iops->rename() wants flags])
42+
AC_DEFINE(HAVE_IOPS_RENAME_USERNS, 1,
43+
[iops->rename() takes struct user_namespace*])
2644
],[
2745
AC_MSG_RESULT(no)
46+
47+
ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
48+
AC_MSG_RESULT(yes)
49+
AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
50+
[iops->rename() wants flags])
51+
],[
52+
AC_MSG_RESULT(no)
53+
])
2854
])
2955
])

0 commit comments

Comments
 (0)