]> git.pld-linux.org Git - packages/zfs.git/blame - kernel-5.12.patch
- fixes for building with kernel 5.12, rel 2
[packages/zfs.git] / kernel-5.12.patch
CommitLineData
0b2b52b7
JR
1From e2a8296131e94ad785f5564156ed2db1fdb2e080 Mon Sep 17 00:00:00 2001
2From: Coleman Kane <ckane@colemankane.org>
3Date: Sat, 20 Mar 2021 00:00:59 -0400
4Subject: [PATCH] Linux 5.12 compat: idmapped mounts
5
6In Linux 5.12, the filesystem API was modified to support ipmapped
7mounts by adding a "struct user_namespace *" parameter to a number
8functions and VFS handlers. This change adds the needed autoconf
9macros to detect the new interfaces and updates the code appropriately.
10This change does not add support for idmapped mounts, instead it
11preserves the existing behavior by passing the initial user namespace
12where needed. A subsequent commit will be required to add support
13for idmapped mounted.
14
15Reviewed-by: Tony Hutter <hutter2@llnl.gov>
16Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
17Co-authored-by: Brian Behlendorf <behlendorf1@llnl.gov>
18Signed-off-by: Coleman Kane <ckane@colemankane.org>
19Closes #11712
20---
21 config/kernel-generic_fillattr.m4 | 28 +++++++
22 config/kernel-inode-create.m4 | 43 +++++++++--
23 config/kernel-inode-getattr.m4 | 63 +++++++++++++---
24 config/kernel-is_owner_or_cap.m4 | 23 +++++-
25 config/kernel-mkdir-umode-t.m4 | 32 --------
26 config/kernel-mkdir.m4 | 65 ++++++++++++++++
27 config/kernel-mknod.m4 | 30 ++++++++
28 config/kernel-rename.m4 | 50 ++++++++++---
29 config/kernel-setattr-prepare.m4 | 45 ++++++++---
30 config/kernel-symlink.m4 | 30 ++++++++
31 config/kernel-xattr-handler.m4 | 78 +++++++++++++-------
32 config/kernel.m4 | 18 +++--
33 include/os/linux/kernel/linux/vfs_compat.h | 24 +++++-
34 include/os/linux/kernel/linux/xattr_compat.h | 17 ++++-
35 include/os/linux/zfs/sys/zfs_vnops_os.h | 3 +-
36 include/os/linux/zfs/sys/zpl.h | 18 +++++
37 module/os/linux/zfs/policy.c | 2 +-
38 module/os/linux/zfs/zfs_vnops_os.c | 5 +-
39 module/os/linux/zfs/zpl_ctldir.c | 51 ++++++++++++-
40 module/os/linux/zfs/zpl_file.c | 2 +-
41 module/os/linux/zfs/zpl_inode.c | 49 +++++++++++-
42 module/os/linux/zfs/zpl_xattr.c | 4 +-
43 22 files changed, 557 insertions(+), 123 deletions(-)
44 create mode 100644 config/kernel-generic_fillattr.m4
45 delete mode 100644 config/kernel-mkdir-umode-t.m4
46 create mode 100644 config/kernel-mkdir.m4
47 create mode 100644 config/kernel-mknod.m4
48 create mode 100644 config/kernel-symlink.m4
49
50diff --git a/config/kernel-generic_fillattr.m4 b/config/kernel-generic_fillattr.m4
51new file mode 100644
52index 00000000000..50c8031305b
53--- /dev/null
54+++ b/config/kernel-generic_fillattr.m4
55@@ -0,0 +1,28 @@
56+dnl #
57+dnl # 5.12 API
58+dnl #
59+dnl # generic_fillattr in linux/fs.h now requires a struct user_namespace*
60+dnl # as the first arg, to support idmapped mounts.
61+dnl #
62+AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [
63+ ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
64+ #include <linux/fs.h>
65+ ],[
66+ struct user_namespace *userns = NULL;
67+ struct inode *in = NULL;
68+ struct kstat *k = NULL;
69+ generic_fillattr(userns, in, k);
70+ ])
71+])
72+
73+AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [
74+ AC_MSG_CHECKING([whether generic_fillattr requres struct user_namespace*])
75+ ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
76+ AC_MSG_RESULT([yes])
77+ AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1,
78+ [generic_fillattr requires struct user_namespace*])
79+ ],[
80+ AC_MSG_RESULT([no])
81+ ])
82+])
83+
84diff --git a/config/kernel-inode-create.m4 b/config/kernel-inode-create.m4
85index 9f28bcbd4f7..a6ea11fb61b 100644
86--- a/config/kernel-inode-create.m4
87+++ b/config/kernel-inode-create.m4
88@@ -1,7 +1,25 @@
89-dnl #
90-dnl # 3.6 API change
91-dnl #
92-AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
93+AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
94+ dnl #
95+ dnl # 5.12 API change that added the struct user_namespace* arg
96+ dnl # to the front of this function type's arg list.
97+ dnl #
98+ ZFS_LINUX_TEST_SRC([create_userns], [
99+ #include <linux/fs.h>
100+ #include <linux/sched.h>
101+
102+ int inode_create(struct user_namespace *userns,
103+ struct inode *inode ,struct dentry *dentry,
104+ umode_t umode, bool flag) { return 0; }
105+
106+ static const struct inode_operations
107+ iops __attribute__ ((unused)) = {
108+ .create = inode_create,
109+ };
110+ ],[])
111+
112+ dnl #
113+ dnl # 3.6 API change
114+ dnl #
115 ZFS_LINUX_TEST_SRC([create_flags], [
116 #include <linux/fs.h>
117 #include <linux/sched.h>
118@@ -16,11 +34,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
119 ],[])
120 ])
121
122-AC_DEFUN([ZFS_AC_KERNEL_CREATE_FLAGS], [
123- AC_MSG_CHECKING([whether iops->create() passes flags])
124- ZFS_LINUX_TEST_RESULT([create_flags], [
125+AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
126+ AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
127+ ZFS_LINUX_TEST_RESULT([create_userns], [
128 AC_MSG_RESULT(yes)
129+ AC_DEFINE(HAVE_IOPS_CREATE_USERNS, 1,
130+ [iops->create() takes struct user_namespace*])
131 ],[
132- ZFS_LINUX_TEST_ERROR([iops->create()])
133+ AC_MSG_RESULT(no)
134+
135+ AC_MSG_CHECKING([whether iops->create() passes flags])
136+ ZFS_LINUX_TEST_RESULT([create_flags], [
137+ AC_MSG_RESULT(yes)
138+ ],[
139+ ZFS_LINUX_TEST_ERROR([iops->create()])
140+ ])
141 ])
142 ])
143diff --git a/config/kernel-inode-getattr.m4 b/config/kernel-inode-getattr.m4
144index 48391d66f8b..f62e82f5230 100644
145--- a/config/kernel-inode-getattr.m4
146+++ b/config/kernel-inode-getattr.m4
147@@ -1,8 +1,29 @@
148-dnl #
149-dnl # Linux 4.11 API
150-dnl # See torvalds/linux@a528d35
151-dnl #
152 AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
153+ dnl #
154+ dnl # Linux 5.12 API
155+ dnl # The getattr I/O operations handler type was extended to require
156+ dnl # a struct user_namespace* as its first arg, to support idmapped
157+ dnl # mounts.
158+ dnl #
159+ ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
160+ #include <linux/fs.h>
161+
162+ int test_getattr(
163+ struct user_namespace *userns,
164+ const struct path *p, struct kstat *k,
165+ u32 request_mask, unsigned int query_flags)
166+ { return 0; }
167+
168+ static const struct inode_operations
169+ iops __attribute__ ((unused)) = {
170+ .getattr = test_getattr,
171+ };
172+ ],[])
173+
174+ dnl #
175+ dnl # Linux 4.11 API
176+ dnl # See torvalds/linux@a528d35
177+ dnl #
178 ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
179 #include <linux/fs.h>
180
181@@ -33,21 +54,39 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
182 ])
183
184 AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
185- AC_MSG_CHECKING([whether iops->getattr() takes a path])
186- ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
187+ dnl #
188+ dnl # Kernel 5.12 test
189+ dnl #
190+ AC_MSG_CHECKING([whether iops->getattr() takes user_namespace])
191+ ZFS_LINUX_TEST_RESULT([inode_operations_getattr_userns], [
192 AC_MSG_RESULT(yes)
193- AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
194- [iops->getattr() takes a path])
195+ AC_DEFINE(HAVE_USERNS_IOPS_GETATTR, 1,
196+ [iops->getattr() takes struct user_namespace*])
197 ],[
198 AC_MSG_RESULT(no)
199
200- AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
201- ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
202+ dnl #
203+ dnl # Kernel 4.11 test
204+ dnl #
205+ AC_MSG_CHECKING([whether iops->getattr() takes a path])
206+ ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
207 AC_MSG_RESULT(yes)
208- AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
209- [iops->getattr() takes a vfsmount])
210+ AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
211+ [iops->getattr() takes a path])
212 ],[
213 AC_MSG_RESULT(no)
214+
215+ dnl #
216+ dnl # Kernel < 4.11 test
217+ dnl #
218+ AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
219+ ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
220+ AC_MSG_RESULT(yes)
221+ AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
222+ [iops->getattr() takes a vfsmount])
223+ ],[
224+ AC_MSG_RESULT(no)
225+ ])
226 ])
227 ])
228 ])
229diff --git a/config/kernel-is_owner_or_cap.m4 b/config/kernel-is_owner_or_cap.m4
230index 3df6163da27..3c3c6ad2240 100644
231--- a/config/kernel-is_owner_or_cap.m4
232+++ b/config/kernel-is_owner_or_cap.m4
233@@ -11,13 +11,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [
234 struct inode *ip = NULL;
235 (void) inode_owner_or_capable(ip);
236 ])
237+
238+ ZFS_LINUX_TEST_SRC([inode_owner_or_capable_idmapped], [
239+ #include <linux/fs.h>
240+ ],[
241+ struct inode *ip = NULL;
242+ (void) inode_owner_or_capable(&init_user_ns, ip);
243+ ])
244 ])
245
246 AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
247 AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
248 ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
249 AC_MSG_RESULT(yes)
250- ],[
251- ZFS_LINUX_TEST_ERROR([capability])
252+ AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
253+ [inode_owner_or_capable() exists])
254+ ], [
255+ AC_MSG_RESULT(no)
256+
257+ AC_MSG_CHECKING(
258+ [whether inode_owner_or_capable() takes user_ns])
259+ ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_idmapped], [
260+ AC_MSG_RESULT(yes)
261+ AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED, 1,
262+ [inode_owner_or_capable() takes user_ns])
263+ ],[
264+ ZFS_LINUX_TEST_ERROR([capability])
265+ ])
266 ])
267 ])
268diff --git a/config/kernel-mkdir-umode-t.m4 b/config/kernel-mkdir-umode-t.m4
269deleted file mode 100644
270index 19599670df3..00000000000
271--- a/config/kernel-mkdir-umode-t.m4
272+++ /dev/null
273@@ -1,32 +0,0 @@
274-dnl #
275-dnl # 3.3 API change
276-dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
277-dnl # umode_t type rather than an int. The expectation is that any backport
278-dnl # would also change all three prototypes. However, if it turns out that
279-dnl # some distribution doesn't backport the whole thing this could be
280-dnl # broken apart into three separate checks.
281-dnl #
282-AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T], [
283- ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
284- #include <linux/fs.h>
285-
286- int mkdir(struct inode *inode, struct dentry *dentry,
287- umode_t umode) { return 0; }
288-
289- static const struct inode_operations
290- iops __attribute__ ((unused)) = {
291- .mkdir = mkdir,
292- };
293- ],[])
294-])
295-
296-AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
297- AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
298- ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
299- AC_MSG_RESULT(yes)
300- AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
301- [iops->create()/mkdir()/mknod() take umode_t])
302- ],[
303- ZFS_LINUX_TEST_ERROR([mkdir()])
304- ])
305-])
306diff --git a/config/kernel-mkdir.m4 b/config/kernel-mkdir.m4
307new file mode 100644
308index 00000000000..a162bcd880f
309--- /dev/null
310+++ b/config/kernel-mkdir.m4
311@@ -0,0 +1,65 @@
312+dnl #
313+dnl # Supported mkdir() interfaces checked newest to oldest.
314+dnl #
315+AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
316+ dnl #
317+ dnl # 5.12 API change
318+ dnl # The struct user_namespace arg was added as the first argument to
319+ dnl # mkdir()
320+ dnl #
321+ ZFS_LINUX_TEST_SRC([mkdir_user_namespace], [
322+ #include <linux/fs.h>
323+
324+ int mkdir(struct user_namespace *userns,
325+ struct inode *inode, struct dentry *dentry,
326+ umode_t umode) { return 0; }
327+
328+ static const struct inode_operations
329+ iops __attribute__ ((unused)) = {
330+ .mkdir = mkdir,
331+ };
332+ ],[])
333+
334+ dnl #
335+ dnl # 3.3 API change
336+ dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
337+ dnl # umode_t type rather than an int. The expectation is that any backport
338+ dnl # would also change all three prototypes. However, if it turns out that
339+ dnl # some distribution doesn't backport the whole thing this could be
340+ dnl # broken apart into three separate checks.
341+ dnl #
342+ ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
343+ #include <linux/fs.h>
344+
345+ int mkdir(struct inode *inode, struct dentry *dentry,
346+ umode_t umode) { return 0; }
347+
348+ static const struct inode_operations
349+ iops __attribute__ ((unused)) = {
350+ .mkdir = mkdir,
351+ };
352+ ],[])
353+])
354+
355+AC_DEFUN([ZFS_AC_KERNEL_MKDIR], [
356+ dnl #
357+ dnl # 5.12 API change
358+ dnl # The struct user_namespace arg was added as the first argument to
359+ dnl # mkdir() of the iops structure.
360+ dnl #
361+ AC_MSG_CHECKING([whether iops->mkdir() takes struct user_namespace*])
362+ ZFS_LINUX_TEST_RESULT([mkdir_user_namespace], [
363+ AC_MSG_RESULT(yes)
364+ AC_DEFINE(HAVE_IOPS_MKDIR_USERNS, 1,
365+ [iops->mkdir() takes struct user_namespace*])
366+ ],[
367+ AC_MSG_CHECKING([whether iops->mkdir() takes umode_t])
368+ ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
369+ AC_MSG_RESULT(yes)
370+ AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
371+ [iops->mkdir() takes umode_t])
372+ ],[
373+ ZFS_LINUX_TEST_ERROR([mkdir()])
374+ ])
375+ ])
376+])
377diff --git a/config/kernel-mknod.m4 b/config/kernel-mknod.m4
378new file mode 100644
379index 00000000000..ffe45106003
380--- /dev/null
381+++ b/config/kernel-mknod.m4
382@@ -0,0 +1,30 @@
383+AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
384+ dnl #
385+ dnl # 5.12 API change that added the struct user_namespace* arg
386+ dnl # to the front of this function type's arg list.
387+ dnl #
388+ ZFS_LINUX_TEST_SRC([mknod_userns], [
389+ #include <linux/fs.h>
390+ #include <linux/sched.h>
391+
392+ int tmp_mknod(struct user_namespace *userns,
393+ struct inode *inode ,struct dentry *dentry,
394+ umode_t u, dev_t d) { return 0; }
395+
396+ static const struct inode_operations
397+ iops __attribute__ ((unused)) = {
398+ .mknod = tmp_mknod,
399+ };
400+ ],[])
401+])
402+
403+AC_DEFUN([ZFS_AC_KERNEL_MKNOD], [
404+ AC_MSG_CHECKING([whether iops->mknod() takes struct user_namespace*])
405+ ZFS_LINUX_TEST_RESULT([mknod_userns], [
406+ AC_MSG_RESULT(yes)
407+ AC_DEFINE(HAVE_IOPS_MKNOD_USERNS, 1,
408+ [iops->mknod() takes struct user_namespace*])
409+ ],[
410+ AC_MSG_RESULT(no)
411+ ])
412+])
413diff --git a/config/kernel-rename.m4 b/config/kernel-rename.m4
414index f707391539d..31d199f33bb 100644
415--- a/config/kernel-rename.m4
416+++ b/config/kernel-rename.m4
417@@ -1,10 +1,10 @@
418-dnl #
419-dnl # 4.9 API change,
420-dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
421-dnl # flags.
422-dnl #
423-AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
424- ZFS_LINUX_TEST_SRC([inode_operations_rename], [
425+AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
426+ dnl #
427+ dnl # 4.9 API change,
428+ dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
429+ dnl # flags.
430+ dnl #
431+ ZFS_LINUX_TEST_SRC([inode_operations_rename_flags], [
432 #include <linux/fs.h>
433 int rename_fn(struct inode *sip, struct dentry *sdp,
434 struct inode *tip, struct dentry *tdp,
435@@ -15,15 +15,41 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
436 .rename = rename_fn,
437 };
438 ],[])
439+
440+ dnl #
441+ dnl # 5.12 API change,
442+ dnl #
443+ dnl # Linux 5.12 introduced passing struct user_namespace* as the first argument
444+ dnl # of the rename() and other inode_operations members.
445+ dnl #
446+ ZFS_LINUX_TEST_SRC([inode_operations_rename_userns], [
447+ #include <linux/fs.h>
448+ int rename_fn(struct user_namespace *user_ns, struct inode *sip,
449+ struct dentry *sdp, struct inode *tip, struct dentry *tdp,
450+ unsigned int flags) { return 0; }
451+
452+ static const struct inode_operations
453+ iops __attribute__ ((unused)) = {
454+ .rename = rename_fn,
455+ };
456+ ],[])
457 ])
458
459-AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
460- AC_MSG_CHECKING([whether iops->rename() wants flags])
461- ZFS_LINUX_TEST_RESULT([inode_operations_rename], [
462+AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
463+ AC_MSG_CHECKING([whether iops->rename() takes struct user_namespace*])
464+ ZFS_LINUX_TEST_RESULT([inode_operations_rename_userns], [
465 AC_MSG_RESULT(yes)
466- AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
467- [iops->rename() wants flags])
468+ AC_DEFINE(HAVE_IOPS_RENAME_USERNS, 1,
469+ [iops->rename() takes struct user_namespace*])
470 ],[
471 AC_MSG_RESULT(no)
472+
473+ ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
474+ AC_MSG_RESULT(yes)
475+ AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
476+ [iops->rename() wants flags])
477+ ],[
478+ AC_MSG_RESULT(no)
479+ ])
480 ])
481 ])
482diff --git a/config/kernel-setattr-prepare.m4 b/config/kernel-setattr-prepare.m4
483index 45408c45c69..24245aa5344 100644
484--- a/config/kernel-setattr-prepare.m4
485+++ b/config/kernel-setattr-prepare.m4
486@@ -1,27 +1,52 @@
487-dnl #
488-dnl # 4.9 API change
489-dnl # The inode_change_ok() function has been renamed setattr_prepare()
490-dnl # and updated to take a dentry rather than an inode.
491-dnl #
492 AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
493+ dnl #
494+ dnl # 4.9 API change
495+ dnl # The inode_change_ok() function has been renamed setattr_prepare()
496+ dnl # and updated to take a dentry rather than an inode.
497+ dnl #
498 ZFS_LINUX_TEST_SRC([setattr_prepare], [
499 #include <linux/fs.h>
500 ], [
501 struct dentry *dentry = NULL;
502 struct iattr *attr = NULL;
503 int error __attribute__ ((unused)) =
504- setattr_prepare(dentry, attr);
505+ setattr_prepare(dentry, attr);
506+ ])
507+
508+ dnl #
509+ dnl # 5.12 API change
510+ dnl # The setattr_prepare() function has been changed to accept a new argument
511+ dnl # for struct user_namespace*
512+ dnl #
513+ ZFS_LINUX_TEST_SRC([setattr_prepare_userns], [
514+ #include <linux/fs.h>
515+ ], [
516+ struct dentry *dentry = NULL;
517+ struct iattr *attr = NULL;
518+ struct user_namespace *userns = NULL;
519+ int error __attribute__ ((unused)) =
520+ setattr_prepare(userns, dentry, attr);
521 ])
522 ])
523
524 AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
525- AC_MSG_CHECKING([whether setattr_prepare() is available])
526- ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
527+ AC_MSG_CHECKING([whether setattr_prepare() is available and accepts struct user_namespace*])
528+ ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare_userns],
529 [setattr_prepare], [fs/attr.c], [
530 AC_MSG_RESULT(yes)
531- AC_DEFINE(HAVE_SETATTR_PREPARE, 1,
532- [setattr_prepare() is available])
533+ AC_DEFINE(HAVE_SETATTR_PREPARE_USERNS, 1,
534+ [setattr_prepare() accepts user_namespace])
535 ], [
536 AC_MSG_RESULT(no)
537+
538+ AC_MSG_CHECKING([whether setattr_prepare() is available, doesn't accept user_namespace])
539+ ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
540+ [setattr_prepare], [fs/attr.c], [
541+ AC_MSG_RESULT(yes)
542+ AC_DEFINE(HAVE_SETATTR_PREPARE_NO_USERNS, 1,
543+ [setattr_prepare() is available, doesn't accept user_namespace])
544+ ], [
545+ AC_MSG_RESULT(no)
546+ ])
547 ])
548 ])
549diff --git a/config/kernel-symlink.m4 b/config/kernel-symlink.m4
550new file mode 100644
551index 00000000000..d90366d04b7
552--- /dev/null
553+++ b/config/kernel-symlink.m4
554@@ -0,0 +1,30 @@
555+AC_DEFUN([ZFS_AC_KERNEL_SRC_SYMLINK], [
556+ dnl #
557+ dnl # 5.12 API change that added the struct user_namespace* arg
558+ dnl # to the front of this function type's arg list.
559+ dnl #
560+ ZFS_LINUX_TEST_SRC([symlink_userns], [
561+ #include <linux/fs.h>
562+ #include <linux/sched.h>
563+
564+ int tmp_symlink(struct user_namespace *userns,
565+ struct inode *inode ,struct dentry *dentry,
566+ const char *path) { return 0; }
567+
568+ static const struct inode_operations
569+ iops __attribute__ ((unused)) = {
570+ .symlink = tmp_symlink,
571+ };
572+ ],[])
573+])
574+
575+AC_DEFUN([ZFS_AC_KERNEL_SYMLINK], [
576+ AC_MSG_CHECKING([whether iops->symlink() takes struct user_namespace*])
577+ ZFS_LINUX_TEST_RESULT([symlink_userns], [
578+ AC_MSG_RESULT(yes)
579+ AC_DEFINE(HAVE_IOPS_SYMLINK_USERNS, 1,
580+ [iops->symlink() takes struct user_namespace*])
581+ ],[
582+ AC_MSG_RESULT(no)
583+ ])
584+])
585diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
586index 137bf4a8aff..00b1e74a9cc 100644
587--- a/config/kernel-xattr-handler.m4
588+++ b/config/kernel-xattr-handler.m4
589@@ -152,6 +152,21 @@ dnl #
590 dnl # Supported xattr handler set() interfaces checked newest to oldest.
591 dnl #
592 AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
593+ ZFS_LINUX_TEST_SRC([xattr_handler_set_userns], [
594+ #include <linux/xattr.h>
595+
596+ int set(const struct xattr_handler *handler,
597+ struct user_namespace *mnt_userns,
598+ struct dentry *dentry, struct inode *inode,
599+ const char *name, const void *buffer,
600+ size_t size, int flags)
601+ { return 0; }
602+ static const struct xattr_handler
603+ xops __attribute__ ((unused)) = {
604+ .set = set,
605+ };
606+ ],[])
607+
608 ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
609 #include <linux/xattr.h>
610
611@@ -194,45 +209,58 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
612
613 AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
614 dnl #
615- dnl # 4.7 API change,
616- dnl # The xattr_handler->set() callback was changed to take both
617- dnl # dentry and inode.
618+ dnl # 5.12 API change,
619+ dnl # The xattr_handler->set() callback was changed to 8 arguments, and
620+ dnl # struct user_namespace* was inserted as arg #2
621 dnl #
622- AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
623- ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
624+ AC_MSG_CHECKING([whether xattr_handler->set() wants dentry, inode, and user_namespace])
625+ ZFS_LINUX_TEST_RESULT([xattr_handler_set_userns], [
626 AC_MSG_RESULT(yes)
627- AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
628- [xattr_handler->set() wants both dentry and inode])
629+ AC_DEFINE(HAVE_XATTR_SET_USERNS, 1,
630+ [xattr_handler->set() takes user_namespace])
631 ],[
632 dnl #
633- dnl # 4.4 API change,
634- dnl # The xattr_handler->set() callback was changed to take a
635- dnl # xattr_handler, and handler_flags argument was removed and
636- dnl # should be accessed by handler->flags.
637+ dnl # 4.7 API change,
638+ dnl # The xattr_handler->set() callback was changed to take both
639+ dnl # dentry and inode.
640 dnl #
641 AC_MSG_RESULT(no)
642- AC_MSG_CHECKING(
643- [whether xattr_handler->set() wants xattr_handler])
644- ZFS_LINUX_TEST_RESULT([xattr_handler_set_xattr_handler], [
645+ AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
646+ ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
647 AC_MSG_RESULT(yes)
648- AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
649- [xattr_handler->set() wants xattr_handler])
650+ AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
651+ [xattr_handler->set() wants both dentry and inode])
652 ],[
653 dnl #
654- dnl # 2.6.33 API change,
655- dnl # The xattr_handler->set() callback was changed
656- dnl # to take a dentry instead of an inode, and a
657- dnl # handler_flags argument was added.
658+ dnl # 4.4 API change,
659+ dnl # The xattr_handler->set() callback was changed to take a
660+ dnl # xattr_handler, and handler_flags argument was removed and
661+ dnl # should be accessed by handler->flags.
662 dnl #
663 AC_MSG_RESULT(no)
664 AC_MSG_CHECKING(
665- [whether xattr_handler->set() wants dentry])
666- ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry], [
667+ [whether xattr_handler->set() wants xattr_handler])
668+ ZFS_LINUX_TEST_RESULT([xattr_handler_set_xattr_handler], [
669 AC_MSG_RESULT(yes)
670- AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
671- [xattr_handler->set() wants dentry])
672+ AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
673+ [xattr_handler->set() wants xattr_handler])
674 ],[
675- ZFS_LINUX_TEST_ERROR([xattr set()])
676+ dnl #
677+ dnl # 2.6.33 API change,
678+ dnl # The xattr_handler->set() callback was changed
679+ dnl # to take a dentry instead of an inode, and a
680+ dnl # handler_flags argument was added.
681+ dnl #
682+ AC_MSG_RESULT(no)
683+ AC_MSG_CHECKING(
684+ [whether xattr_handler->set() wants dentry])
685+ ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry], [
686+ AC_MSG_RESULT(yes)
687+ AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
688+ [xattr_handler->set() wants dentry])
689+ ],[
690+ ZFS_LINUX_TEST_ERROR([xattr set()])
691+ ])
692 ])
693 ])
694 ])
695diff --git a/config/kernel.m4 b/config/kernel.m4
696index f31be845f5d..24db38f09f4 100644
697--- a/config/kernel.m4
698+++ b/config/kernel.m4
699@@ -79,9 +79,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
700 ZFS_AC_KERNEL_SRC_EVICT_INODE
701 ZFS_AC_KERNEL_SRC_DIRTY_INODE
702 ZFS_AC_KERNEL_SRC_SHRINKER
703- ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T
704+ ZFS_AC_KERNEL_SRC_MKDIR
705 ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS
706- ZFS_AC_KERNEL_SRC_CREATE_FLAGS
707+ ZFS_AC_KERNEL_SRC_CREATE
708 ZFS_AC_KERNEL_SRC_GET_LINK
709 ZFS_AC_KERNEL_SRC_PUT_LINK
710 ZFS_AC_KERNEL_SRC_TMPFILE
711@@ -115,7 +115,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
712 ZFS_AC_KERNEL_SRC_KUIDGID_T
713 ZFS_AC_KERNEL_SRC_KUID_HELPERS
714 ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
715- ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS
716+ ZFS_AC_KERNEL_SRC_RENAME
717 ZFS_AC_KERNEL_SRC_CURRENT_TIME
718 ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
719 ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
720@@ -125,6 +125,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
721 ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
722 ZFS_AC_KERNEL_SRC_KSTRTOUL
723 ZFS_AC_KERNEL_SRC_PERCPU
724+ ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS
725+ ZFS_AC_KERNEL_SRC_MKNOD
726+ ZFS_AC_KERNEL_SRC_SYMLINK
727
728 AC_MSG_CHECKING([for available kernel interfaces])
729 ZFS_LINUX_TEST_COMPILE_ALL([kabi])
730@@ -177,9 +180,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
731 ZFS_AC_KERNEL_EVICT_INODE
732 ZFS_AC_KERNEL_DIRTY_INODE
733 ZFS_AC_KERNEL_SHRINKER
734- ZFS_AC_KERNEL_MKDIR_UMODE_T
735+ ZFS_AC_KERNEL_MKDIR
736 ZFS_AC_KERNEL_LOOKUP_FLAGS
737- ZFS_AC_KERNEL_CREATE_FLAGS
738+ ZFS_AC_KERNEL_CREATE
739 ZFS_AC_KERNEL_GET_LINK
740 ZFS_AC_KERNEL_PUT_LINK
741 ZFS_AC_KERNEL_TMPFILE
742@@ -213,7 +216,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
743 ZFS_AC_KERNEL_KUIDGID_T
744 ZFS_AC_KERNEL_KUID_HELPERS
745 ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
746- ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
747+ ZFS_AC_KERNEL_RENAME
748 ZFS_AC_KERNEL_CURRENT_TIME
749 ZFS_AC_KERNEL_USERNS_CAPABILITIES
750 ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
751@@ -223,6 +226,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
752 ZFS_AC_KERNEL_TOTALHIGH_PAGES
753 ZFS_AC_KERNEL_KSTRTOUL
754 ZFS_AC_KERNEL_PERCPU
755+ ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
756+ ZFS_AC_KERNEL_MKNOD
757+ ZFS_AC_KERNEL_SYMLINK
758 ])
759
760 dnl #
761diff --git a/include/os/linux/kernel/linux/vfs_compat.h b/include/os/linux/kernel/linux/vfs_compat.h
762index c35e80d31cd..91e908598fb 100644
763--- a/include/os/linux/kernel/linux/vfs_compat.h
764+++ b/include/os/linux/kernel/linux/vfs_compat.h
765@@ -343,7 +343,8 @@ static inline void zfs_gid_write(struct inode *ip, gid_t gid)
766 /*
767 * 4.9 API change
768 */
769-#ifndef HAVE_SETATTR_PREPARE
770+#if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \
771+ defined(HAVE_SETATTR_PREPARE_USERNS))
772 static inline int
773 setattr_prepare(struct dentry *dentry, struct iattr *ia)
774 {
775@@ -389,6 +390,15 @@ func(const struct path *path, struct kstat *stat, u32 request_mask, \
776 { \
777 return (func##_impl(path, stat, request_mask, query_flags)); \
778 }
779+#elif defined(HAVE_USERNS_IOPS_GETATTR)
780+#define ZPL_GETATTR_WRAPPER(func) \
781+static int \
782+func(struct user_namespace *user_ns, const struct path *path, \
783+ struct kstat *stat, u32 request_mask, unsigned int query_flags) \
784+{ \
785+ return (func##_impl(user_ns, path, stat, request_mask, \
786+ query_flags)); \
787+}
788 #else
789 #error
790 #endif
791@@ -436,4 +446,16 @@ zpl_is_32bit_api(void)
792 #endif
793 }
794
795+/*
796+ * 5.12 API change
797+ * To support id-mapped mounts, generic_fillattr() was modified to
798+ * accept a new struct user_namespace* as its first arg.
799+ */
800+#ifdef HAVE_GENERIC_FILLATTR_USERNS
801+#define zpl_generic_fillattr(user_ns, ip, sp) \
802+ generic_fillattr(user_ns, ip, sp)
803+#else
804+#define zpl_generic_fillattr(user_ns, ip, sp) generic_fillattr(ip, sp)
805+#endif
806+
807 #endif /* _ZFS_VFS_H */
808diff --git a/include/os/linux/kernel/linux/xattr_compat.h b/include/os/linux/kernel/linux/xattr_compat.h
809index 8348e99198a..54690727eab 100644
810--- a/include/os/linux/kernel/linux/xattr_compat.h
811+++ b/include/os/linux/kernel/linux/xattr_compat.h
812@@ -119,12 +119,27 @@ fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \
813 #error "Unsupported kernel"
814 #endif
815
816+/*
817+ * 5.12 API change,
818+ * The xattr_handler->set() callback was changed to take the
819+ * struct user_namespace* as the first arg, to support idmapped
820+ * mounts.
821+ */
822+#if defined(HAVE_XATTR_SET_USERNS)
823+#define ZPL_XATTR_SET_WRAPPER(fn) \
824+static int \
825+fn(const struct xattr_handler *handler, struct user_namespace *user_ns, \
826+ struct dentry *dentry, struct inode *inode, const char *name, \
827+ const void *buffer, size_t size, int flags) \
828+{ \
829+ return (__ ## fn(inode, name, buffer, size, flags)); \
830+}
831 /*
832 * 4.7 API change,
833 * The xattr_handler->set() callback was changed to take a both dentry and
834 * inode, because the dentry might not be attached to an inode yet.
835 */
836-#if defined(HAVE_XATTR_SET_DENTRY_INODE)
837+#elif defined(HAVE_XATTR_SET_DENTRY_INODE)
838 #define ZPL_XATTR_SET_WRAPPER(fn) \
839 static int \
840 fn(const struct xattr_handler *handler, struct dentry *dentry, \
841diff --git a/include/os/linux/zfs/sys/zfs_vnops_os.h b/include/os/linux/zfs/sys/zfs_vnops_os.h
842index ef76de3e298..47f91e4a6cf 100644
843--- a/include/os/linux/zfs/sys/zfs_vnops_os.h
844+++ b/include/os/linux/zfs/sys/zfs_vnops_os.h
845@@ -54,7 +54,8 @@ extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap,
846 extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd,
847 cred_t *cr, int flags);
848 extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr);
849-extern int zfs_getattr_fast(struct inode *ip, struct kstat *sp);
850+extern int zfs_getattr_fast(struct user_namespace *, struct inode *ip,
851+ struct kstat *sp);
852 extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
853 extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
854 char *tnm, cred_t *cr, int flags);
855diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h
856index b0bb9c29c0b..21825d1f378 100644
857--- a/include/os/linux/zfs/sys/zpl.h
858+++ b/include/os/linux/zfs/sys/zpl.h
859@@ -171,4 +171,22 @@ zpl_dir_emit_dots(struct file *file, zpl_dir_context_t *ctx)
860 timespec_trunc(ts, (ip)->i_sb->s_time_gran)
861 #endif
862
863+#if defined(HAVE_INODE_OWNER_OR_CAPABLE)
864+#define zpl_inode_owner_or_capable(ns, ip) inode_owner_or_capable(ip)
865+#elif defined(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED)
866+#define zpl_inode_owner_or_capable(ns, ip) inode_owner_or_capable(ns, ip)
867+#else
868+#error "Unsupported kernel"
869+#endif
870+
871+#ifdef HAVE_SETATTR_PREPARE_USERNS
872+#define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(ns, dentry, ia)
873+#else
874+/*
875+ * Use kernel-provided version, or our own from
876+ * linux/vfs_compat.h
877+ */
878+#define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(dentry, ia)
879+#endif
880+
881 #endif /* _SYS_ZPL_H */
882diff --git a/module/os/linux/zfs/policy.c b/module/os/linux/zfs/policy.c
883index 8780d7f6c70..bbccb2e572d 100644
884--- a/module/os/linux/zfs/policy.c
885+++ b/module/os/linux/zfs/policy.c
886@@ -124,7 +124,7 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
887 if (crgetfsuid(cr) == owner)
888 return (0);
889
890- if (inode_owner_or_capable(ip))
891+ if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
892 return (0);
893
894 #if defined(CONFIG_USER_NS)
895diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
896index 84c33b541ea..8aeed6f568c 100644
897--- a/module/os/linux/zfs/zfs_vnops_os.c
898+++ b/module/os/linux/zfs/zfs_vnops_os.c
899@@ -1656,7 +1656,8 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
900 */
901 /* ARGSUSED */
902 int
903-zfs_getattr_fast(struct inode *ip, struct kstat *sp)
904+zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
905+ struct kstat *sp)
906 {
907 znode_t *zp = ITOZ(ip);
908 zfsvfs_t *zfsvfs = ITOZSB(ip);
909@@ -1668,7 +1669,7 @@ zfs_getattr_fast(struct inode *ip, struct kstat *sp)
910
911 mutex_enter(&zp->z_lock);
912
913- generic_fillattr(ip, sp);
914+ zpl_generic_fillattr(user_ns, ip, sp);
915 /*
916 * +1 link count for root inode with visible '.zfs' directory.
917 */
918diff --git a/module/os/linux/zfs/zpl_ctldir.c b/module/os/linux/zfs/zpl_ctldir.c
919index e6420f19ed8..9b526afd000 100644
920--- a/module/os/linux/zfs/zpl_ctldir.c
921+++ b/module/os/linux/zfs/zpl_ctldir.c
922@@ -101,12 +101,22 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
923 */
924 /* ARGSUSED */
925 static int
926+#ifdef HAVE_USERNS_IOPS_GETATTR
927+zpl_root_getattr_impl(struct user_namespace *user_ns,
928+ const struct path *path, struct kstat *stat, u32 request_mask,
929+ unsigned int query_flags)
930+#else
931 zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
932 u32 request_mask, unsigned int query_flags)
933+#endif
934 {
935 struct inode *ip = path->dentry->d_inode;
936
937+#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
938+ generic_fillattr(user_ns, ip, stat);
939+#else
940 generic_fillattr(ip, stat);
941+#endif
942 stat->atime = current_time(ip);
943
944 return (0);
945@@ -290,8 +300,14 @@ zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
946 #endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
947
948 static int
949+#ifdef HAVE_IOPS_RENAME_USERNS
950+zpl_snapdir_rename2(struct user_namespace *user_ns, struct inode *sdip,
951+ struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
952+ unsigned int flags)
953+#else
954 zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
955 struct inode *tdip, struct dentry *tdentry, unsigned int flags)
956+#endif
957 {
958 cred_t *cr = CRED();
959 int error;
960@@ -309,7 +325,7 @@ zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
961 return (error);
962 }
963
964-#ifndef HAVE_RENAME_WANTS_FLAGS
965+#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
966 static int
967 zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
968 struct inode *tdip, struct dentry *tdentry)
969@@ -333,7 +349,12 @@ zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
970 }
971
972 static int
973+#ifdef HAVE_IOPS_MKDIR_USERNS
974+zpl_snapdir_mkdir(struct user_namespace *user_ns, struct inode *dip,
975+ struct dentry *dentry, umode_t mode)
976+#else
977 zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
978+#endif
979 {
980 cred_t *cr = CRED();
981 vattr_t *vap;
982@@ -363,14 +384,24 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
983 */
984 /* ARGSUSED */
985 static int
986+#ifdef HAVE_USERNS_IOPS_GETATTR
987+zpl_snapdir_getattr_impl(struct user_namespace *user_ns,
988+ const struct path *path, struct kstat *stat, u32 request_mask,
989+ unsigned int query_flags)
990+#else
991 zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
992 u32 request_mask, unsigned int query_flags)
993+#endif
994 {
995 struct inode *ip = path->dentry->d_inode;
996 zfsvfs_t *zfsvfs = ITOZSB(ip);
997
998 ZPL_ENTER(zfsvfs);
999+#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
1000+ generic_fillattr(user_ns, ip, stat);
1001+#else
1002 generic_fillattr(ip, stat);
1003+#endif
1004
1005 stat->nlink = stat->size = 2;
1006 stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
1007@@ -408,7 +439,7 @@ const struct file_operations zpl_fops_snapdir = {
1008 const struct inode_operations zpl_ops_snapdir = {
1009 .lookup = zpl_snapdir_lookup,
1010 .getattr = zpl_snapdir_getattr,
1011-#ifdef HAVE_RENAME_WANTS_FLAGS
1012+#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
1013 .rename = zpl_snapdir_rename2,
1014 #else
1015 .rename = zpl_snapdir_rename,
1016@@ -495,8 +526,14 @@ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
1017
1018 /* ARGSUSED */
1019 static int
1020+#ifdef HAVE_USERNS_IOPS_GETATTR
1021+zpl_shares_getattr_impl(struct user_namespace *user_ns,
1022+ const struct path *path, struct kstat *stat, u32 request_mask,
1023+ unsigned int query_flags)
1024+#else
1025 zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
1026 u32 request_mask, unsigned int query_flags)
1027+#endif
1028 {
1029 struct inode *ip = path->dentry->d_inode;
1030 zfsvfs_t *zfsvfs = ITOZSB(ip);
1031@@ -506,7 +543,11 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
1032 ZPL_ENTER(zfsvfs);
1033
1034 if (zfsvfs->z_shares_dir == 0) {
1035+#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
1036+ generic_fillattr(user_ns, path->dentry->d_inode, stat);
1037+#else
1038 generic_fillattr(path->dentry->d_inode, stat);
1039+#endif
1040 stat->nlink = stat->size = 2;
1041 stat->atime = current_time(ip);
1042 ZPL_EXIT(zfsvfs);
1043@@ -515,7 +556,11 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
1044
1045 error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
1046 if (error == 0) {
1047- error = -zfs_getattr_fast(ZTOI(dzp), stat);
1048+#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
1049+ error = -zfs_getattr_fast(user_ns, ZTOI(dzp), stat);
1050+#else
1051+ error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat);
1052+#endif
1053 iput(ZTOI(dzp));
1054 }
1055
1056diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c
1057index 970db4a8b73..ea6993ffa4b 100644
1058--- a/module/os/linux/zfs/zpl_file.c
1059+++ b/module/os/linux/zfs/zpl_file.c
1060@@ -869,7 +869,7 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
1061 !capable(CAP_LINUX_IMMUTABLE))
1062 return (-EACCES);
1063
1064- if (!inode_owner_or_capable(ip))
1065+ if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
1066 return (-EACCES);
1067
1068 xva_init(xva);
1069diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c
1070index 117963f44af..cf0eab3e8c9 100644
1071--- a/module/os/linux/zfs/zpl_inode.c
1072+++ b/module/os/linux/zfs/zpl_inode.c
1073@@ -128,7 +128,12 @@ zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr)
1074 }
1075
1076 static int
1077+#ifdef HAVE_IOPS_CREATE_USERNS
1078+zpl_create(struct user_namespace *user_ns, struct inode *dir,
1079+ struct dentry *dentry, umode_t mode, bool flag)
1080+#else
1081 zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
1082+#endif
1083 {
1084 cred_t *cr = CRED();
1085 znode_t *zp;
1086@@ -163,7 +168,12 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
1087 }
1088
1089 static int
1090+#ifdef HAVE_IOPS_MKNOD_USERNS
1091+zpl_mknod(struct user_namespace *user_ns, struct inode *dir,
1092+ struct dentry *dentry, umode_t mode,
1093+#else
1094 zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
1095+#endif
1096 dev_t rdev)
1097 {
1098 cred_t *cr = CRED();
1099@@ -278,7 +288,12 @@ zpl_unlink(struct inode *dir, struct dentry *dentry)
1100 }
1101
1102 static int
1103+#ifdef HAVE_IOPS_MKDIR_USERNS
1104+zpl_mkdir(struct user_namespace *user_ns, struct inode *dir,
1105+ struct dentry *dentry, umode_t mode)
1106+#else
1107 zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1108+#endif
1109 {
1110 cred_t *cr = CRED();
1111 vattr_t *vap;
1112@@ -338,8 +353,14 @@ zpl_rmdir(struct inode *dir, struct dentry *dentry)
1113 }
1114
1115 static int
1116+#ifdef HAVE_USERNS_IOPS_GETATTR
1117+zpl_getattr_impl(struct user_namespace *user_ns,
1118+ const struct path *path, struct kstat *stat, u32 request_mask,
1119+ unsigned int query_flags)
1120+#else
1121 zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
1122 unsigned int query_flags)
1123+#endif
1124 {
1125 int error;
1126 fstrans_cookie_t cookie;
1127@@ -350,7 +371,11 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
1128 * XXX request_mask and query_flags currently ignored.
1129 */
1130
1131- error = -zfs_getattr_fast(path->dentry->d_inode, stat);
1132+#ifdef HAVE_USERNS_IOPS_GETATTR
1133+ error = -zfs_getattr_fast(user_ns, path->dentry->d_inode, stat);
1134+#else
1135+ error = -zfs_getattr_fast(kcred->user_ns, path->dentry->d_inode, stat);
1136+#endif
1137 spl_fstrans_unmark(cookie);
1138 ASSERT3S(error, <=, 0);
1139
1140@@ -359,7 +384,12 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
1141 ZPL_GETATTR_WRAPPER(zpl_getattr);
1142
1143 static int
1144+#ifdef HAVE_SETATTR_PREPARE_USERNS
1145+zpl_setattr(struct user_namespace *user_ns, struct dentry *dentry,
1146+ struct iattr *ia)
1147+#else
1148 zpl_setattr(struct dentry *dentry, struct iattr *ia)
1149+#endif
1150 {
1151 struct inode *ip = dentry->d_inode;
1152 cred_t *cr = CRED();
1153@@ -367,7 +397,7 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
1154 int error;
1155 fstrans_cookie_t cookie;
1156
1157- error = setattr_prepare(dentry, ia);
1158+ error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
1159 if (error)
1160 return (error);
1161
1162@@ -399,8 +429,14 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
1163 }
1164
1165 static int
1166+#ifdef HAVE_IOPS_RENAME_USERNS
1167+zpl_rename2(struct user_namespace *user_ns, struct inode *sdip,
1168+ struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
1169+ unsigned int flags)
1170+#else
1171 zpl_rename2(struct inode *sdip, struct dentry *sdentry,
1172 struct inode *tdip, struct dentry *tdentry, unsigned int flags)
1173+#endif
1174 {
1175 cred_t *cr = CRED();
1176 int error;
1177@@ -421,7 +457,7 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
1178 return (error);
1179 }
1180
1181-#ifndef HAVE_RENAME_WANTS_FLAGS
1182+#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
1183 static int
1184 zpl_rename(struct inode *sdip, struct dentry *sdentry,
1185 struct inode *tdip, struct dentry *tdentry)
1186@@ -431,7 +467,12 @@ zpl_rename(struct inode *sdip, struct dentry *sdentry,
1187 #endif
1188
1189 static int
1190+#ifdef HAVE_IOPS_SYMLINK_USERNS
1191+zpl_symlink(struct user_namespace *user_ns, struct inode *dir,
1192+ struct dentry *dentry, const char *name)
1193+#else
1194 zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
1195+#endif
1196 {
1197 cred_t *cr = CRED();
1198 vattr_t *vap;
1199@@ -678,7 +719,7 @@ const struct inode_operations zpl_dir_inode_operations = {
1200 .mkdir = zpl_mkdir,
1201 .rmdir = zpl_rmdir,
1202 .mknod = zpl_mknod,
1203-#ifdef HAVE_RENAME_WANTS_FLAGS
1204+#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
1205 .rename = zpl_rename2,
1206 #else
1207 .rename = zpl_rename,
1208diff --git a/module/os/linux/zfs/zpl_xattr.c b/module/os/linux/zfs/zpl_xattr.c
1209index 83812f2dcba..971cd6ad031 100644
1210--- a/module/os/linux/zfs/zpl_xattr.c
1211+++ b/module/os/linux/zfs/zpl_xattr.c
1212@@ -1233,7 +1233,7 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
1213 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
1214 return (-EOPNOTSUPP);
1215
1216- if (!inode_owner_or_capable(ip))
1217+ if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
1218 return (-EPERM);
1219
1220 if (value) {
1221@@ -1273,7 +1273,7 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name,
1222 if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
1223 return (-EOPNOTSUPP);
1224
1225- if (!inode_owner_or_capable(ip))
1226+ if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
1227 return (-EPERM);
1228
1229 if (value) {
1230From ffd6978ef59cfe2773e984bf03de2f0b93b03f5c Mon Sep 17 00:00:00 2001
1231From: Coleman Kane <ckane@colemankane.org>
1232Date: Sat, 20 Mar 2021 01:33:42 -0400
1233Subject: [PATCH] Linux 5.12 update: bio_max_segs() replaces BIO_MAX_PAGES
1234
1235The BIO_MAX_PAGES macro is being retired in favor of a bio_max_segs()
1236function that implements the typical MIN(x,y) logic used throughout the
1237kernel for bounding the allocation, and also the new implementation is
1238intended to be signed-safe (which the former was not).
1239
1240Reviewed-by: Tony Hutter <hutter2@llnl.gov>
1241Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
1242Signed-off-by: Coleman Kane <ckane@colemankane.org>
1243Closes #11765
1244---
1245 config/kernel-bio_max_segs.m4 | 23 +++++++++++++++++++++++
1246 config/kernel.m4 | 2 ++
1247 module/os/linux/zfs/vdev_disk.c | 5 +++++
1248 3 files changed, 30 insertions(+)
1249 create mode 100644 config/kernel-bio_max_segs.m4
1250
1251diff --git a/config/kernel-bio_max_segs.m4 b/config/kernel-bio_max_segs.m4
1252new file mode 100644
1253index 00000000000..a90d75455c1
1254--- /dev/null
1255+++ b/config/kernel-bio_max_segs.m4
1256@@ -0,0 +1,23 @@
1257+dnl #
1258+dnl # 5.12 API change removes BIO_MAX_PAGES in favor of bio_max_segs()
1259+dnl # which will handle the logic of setting the upper-bound to a
1260+dnl # BIO_MAX_PAGES, internally.
1261+dnl #
1262+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS], [
1263+ ZFS_LINUX_TEST_SRC([bio_max_segs], [
1264+ #include <linux/bio.h>
1265+ ],[
1266+ bio_max_segs(1);
1267+ ])
1268+])
1269+
1270+AC_DEFUN([ZFS_AC_KERNEL_BIO_MAX_SEGS], [
1271+ AC_MSG_CHECKING([whether bio_max_segs() exists])
1272+ ZFS_LINUX_TEST_RESULT([bio_max_segs], [
1273+ AC_MSG_RESULT(yes)
1274+
1275+ AC_DEFINE([HAVE_BIO_MAX_SEGS], 1, [bio_max_segs() is implemented])
1276+ ],[
1277+ AC_MSG_RESULT(no)
1278+ ])
1279+])
1280diff --git a/config/kernel.m4 b/config/kernel.m4
1281index 24db38f09f4..dfb6165d879 100644
1282--- a/config/kernel.m4
1283+++ b/config/kernel.m4
1284@@ -128,6 +128,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
1285 ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS
1286 ZFS_AC_KERNEL_SRC_MKNOD
1287 ZFS_AC_KERNEL_SRC_SYMLINK
1288+ ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS
1289
1290 AC_MSG_CHECKING([for available kernel interfaces])
1291 ZFS_LINUX_TEST_COMPILE_ALL([kabi])
1292@@ -229,6 +230,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
1293 ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
1294 ZFS_AC_KERNEL_MKNOD
1295 ZFS_AC_KERNEL_SYMLINK
1296+ ZFS_AC_KERNEL_BIO_MAX_SEGS
1297 ])
1298
1299 dnl #
1300diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c
1301index ff71ef4cd06..c56fd3a6ff2 100644
1302--- a/module/os/linux/zfs/vdev_disk.c
1303+++ b/module/os/linux/zfs/vdev_disk.c
1304@@ -589,9 +589,14 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
1305 }
1306
1307 /* bio_alloc() with __GFP_WAIT never returns NULL */
1308+#ifdef HAVE_BIO_MAX_SEGS
1309+ dr->dr_bio[i] = bio_alloc(GFP_NOIO, bio_max_segs(
1310+ abd_nr_pages_off(zio->io_abd, bio_size, abd_offset)));
1311+#else
1312 dr->dr_bio[i] = bio_alloc(GFP_NOIO,
1313 MIN(abd_nr_pages_off(zio->io_abd, bio_size, abd_offset),
1314 BIO_MAX_PAGES));
1315+#endif
1316 if (unlikely(dr->dr_bio[i] == NULL)) {
1317 vdev_disk_dio_free(dr);
1318 return (SET_ERROR(ENOMEM));
This page took 0.317127 seconds and 4 git commands to generate.