1 From e2a8296131e94ad785f5564156ed2db1fdb2e080 Mon Sep 17 00:00:00 2001
2 From: Coleman Kane <ckane@colemankane.org>
3 Date: Sat, 20 Mar 2021 00:00:59 -0400
4 Subject: [PATCH] Linux 5.12 compat: idmapped mounts
6 In Linux 5.12, the filesystem API was modified to support ipmapped
7 mounts by adding a "struct user_namespace *" parameter to a number
8 functions and VFS handlers. This change adds the needed autoconf
9 macros to detect the new interfaces and updates the code appropriately.
10 This change does not add support for idmapped mounts, instead it
11 preserves the existing behavior by passing the initial user namespace
12 where needed. A subsequent commit will be required to add support
15 Reviewed-by: Tony Hutter <hutter2@llnl.gov>
16 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
17 Co-authored-by: Brian Behlendorf <behlendorf1@llnl.gov>
18 Signed-off-by: Coleman Kane <ckane@colemankane.org>
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
50 diff --git a/config/kernel-generic_fillattr.m4 b/config/kernel-generic_fillattr.m4
52 index 00000000000..50c8031305b
54 +++ b/config/kernel-generic_fillattr.m4
59 +dnl # generic_fillattr in linux/fs.h now requires a struct user_namespace*
60 +dnl # as the first arg, to support idmapped mounts.
62 +AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [
63 + ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
64 + #include <linux/fs.h>
66 + struct user_namespace *userns = NULL;
67 + struct inode *in = NULL;
68 + struct kstat *k = NULL;
69 + generic_fillattr(userns, in, k);
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*])
84 diff --git a/config/kernel-inode-create.m4 b/config/kernel-inode-create.m4
85 index 9f28bcbd4f7..a6ea11fb61b 100644
86 --- a/config/kernel-inode-create.m4
87 +++ b/config/kernel-inode-create.m4
92 -AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
93 +AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
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.
98 + ZFS_LINUX_TEST_SRC([create_userns], [
99 + #include <linux/fs.h>
100 + #include <linux/sched.h>
102 + int inode_create(struct user_namespace *userns,
103 + struct inode *inode ,struct dentry *dentry,
104 + umode_t umode, bool flag) { return 0; }
106 + static const struct inode_operations
107 + iops __attribute__ ((unused)) = {
108 + .create = inode_create,
113 + dnl # 3.6 API change
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], [
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], [
129 + AC_DEFINE(HAVE_IOPS_CREATE_USERNS, 1,
130 + [iops->create() takes struct user_namespace*])
132 - ZFS_LINUX_TEST_ERROR([iops->create()])
135 + AC_MSG_CHECKING([whether iops->create() passes flags])
136 + ZFS_LINUX_TEST_RESULT([create_flags], [
139 + ZFS_LINUX_TEST_ERROR([iops->create()])
143 diff --git a/config/kernel-inode-getattr.m4 b/config/kernel-inode-getattr.m4
144 index 48391d66f8b..f62e82f5230 100644
145 --- a/config/kernel-inode-getattr.m4
146 +++ b/config/kernel-inode-getattr.m4
149 -dnl # Linux 4.11 API
150 -dnl # See torvalds/linux@a528d35
152 AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
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
159 + ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
160 + #include <linux/fs.h>
163 + struct user_namespace *userns,
164 + const struct path *p, struct kstat *k,
165 + u32 request_mask, unsigned int query_flags)
168 + static const struct inode_operations
169 + iops __attribute__ ((unused)) = {
170 + .getattr = test_getattr,
175 + dnl # Linux 4.11 API
176 + dnl # See torvalds/linux@a528d35
178 ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
179 #include <linux/fs.h>
181 @@ -33,21 +54,39 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
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], [
188 + dnl # Kernel 5.12 test
190 + AC_MSG_CHECKING([whether iops->getattr() takes user_namespace])
191 + ZFS_LINUX_TEST_RESULT([inode_operations_getattr_userns], [
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*])
200 - AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
201 - ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
203 + dnl # Kernel 4.11 test
205 + AC_MSG_CHECKING([whether iops->getattr() takes a path])
206 + ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
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])
216 + dnl # Kernel < 4.11 test
218 + AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
219 + ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
221 + AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
222 + [iops->getattr() takes a vfsmount])
229 diff --git a/config/kernel-is_owner_or_cap.m4 b/config/kernel-is_owner_or_cap.m4
230 index 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);
238 + ZFS_LINUX_TEST_SRC([inode_owner_or_capable_idmapped], [
239 + #include <linux/fs.h>
241 + struct inode *ip = NULL;
242 + (void) inode_owner_or_capable(&init_user_ns, ip);
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], [
251 - ZFS_LINUX_TEST_ERROR([capability])
252 + AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
253 + [inode_owner_or_capable() exists])
258 + [whether inode_owner_or_capable() takes user_ns])
259 + ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_idmapped], [
261 + AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED, 1,
262 + [inode_owner_or_capable() takes user_ns])
264 + ZFS_LINUX_TEST_ERROR([capability])
268 diff --git a/config/kernel-mkdir-umode-t.m4 b/config/kernel-mkdir-umode-t.m4
269 deleted file mode 100644
270 index 19599670df3..00000000000
271 --- a/config/kernel-mkdir-umode-t.m4
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.
282 -AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T], [
283 - ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
284 - #include <linux/fs.h>
286 - int mkdir(struct inode *inode, struct dentry *dentry,
287 - umode_t umode) { return 0; }
289 - static const struct inode_operations
290 - iops __attribute__ ((unused)) = {
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], [
300 - AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
301 - [iops->create()/mkdir()/mknod() take umode_t])
303 - ZFS_LINUX_TEST_ERROR([mkdir()])
306 diff --git a/config/kernel-mkdir.m4 b/config/kernel-mkdir.m4
308 index 00000000000..a162bcd880f
310 +++ b/config/kernel-mkdir.m4
313 +dnl # Supported mkdir() interfaces checked newest to oldest.
315 +AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
317 + dnl # 5.12 API change
318 + dnl # The struct user_namespace arg was added as the first argument to
321 + ZFS_LINUX_TEST_SRC([mkdir_user_namespace], [
322 + #include <linux/fs.h>
324 + int mkdir(struct user_namespace *userns,
325 + struct inode *inode, struct dentry *dentry,
326 + umode_t umode) { return 0; }
328 + static const struct inode_operations
329 + iops __attribute__ ((unused)) = {
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.
342 + ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
343 + #include <linux/fs.h>
345 + int mkdir(struct inode *inode, struct dentry *dentry,
346 + umode_t umode) { return 0; }
348 + static const struct inode_operations
349 + iops __attribute__ ((unused)) = {
355 +AC_DEFUN([ZFS_AC_KERNEL_MKDIR], [
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.
361 + AC_MSG_CHECKING([whether iops->mkdir() takes struct user_namespace*])
362 + ZFS_LINUX_TEST_RESULT([mkdir_user_namespace], [
364 + AC_DEFINE(HAVE_IOPS_MKDIR_USERNS, 1,
365 + [iops->mkdir() takes struct user_namespace*])
367 + AC_MSG_CHECKING([whether iops->mkdir() takes umode_t])
368 + ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
370 + AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
371 + [iops->mkdir() takes umode_t])
373 + ZFS_LINUX_TEST_ERROR([mkdir()])
377 diff --git a/config/kernel-mknod.m4 b/config/kernel-mknod.m4
379 index 00000000000..ffe45106003
381 +++ b/config/kernel-mknod.m4
383 +AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
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.
388 + ZFS_LINUX_TEST_SRC([mknod_userns], [
389 + #include <linux/fs.h>
390 + #include <linux/sched.h>
392 + int tmp_mknod(struct user_namespace *userns,
393 + struct inode *inode ,struct dentry *dentry,
394 + umode_t u, dev_t d) { return 0; }
396 + static const struct inode_operations
397 + iops __attribute__ ((unused)) = {
398 + .mknod = tmp_mknod,
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], [
407 + AC_DEFINE(HAVE_IOPS_MKNOD_USERNS, 1,
408 + [iops->mknod() takes struct user_namespace*])
413 diff --git a/config/kernel-rename.m4 b/config/kernel-rename.m4
414 index f707391539d..31d199f33bb 100644
415 --- a/config/kernel-rename.m4
416 +++ b/config/kernel-rename.m4
419 -dnl # 4.9 API change,
420 -dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
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], [
427 + dnl # 4.9 API change,
428 + dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
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], [
441 + dnl # 5.12 API change,
443 + dnl # Linux 5.12 introduced passing struct user_namespace* as the first argument
444 + dnl # of the rename() and other inode_operations members.
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; }
452 + static const struct inode_operations
453 + iops __attribute__ ((unused)) = {
454 + .rename = rename_fn,
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], [
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*])
473 + ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
475 + AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
476 + [iops->rename() wants flags])
482 diff --git a/config/kernel-setattr-prepare.m4 b/config/kernel-setattr-prepare.m4
483 index 45408c45c69..24245aa5344 100644
484 --- a/config/kernel-setattr-prepare.m4
485 +++ b/config/kernel-setattr-prepare.m4
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.
492 AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
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.
498 ZFS_LINUX_TEST_SRC([setattr_prepare], [
499 #include <linux/fs.h>
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);
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*
513 + ZFS_LINUX_TEST_SRC([setattr_prepare_userns], [
514 + #include <linux/fs.h>
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);
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], [
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])
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], [
542 + AC_DEFINE(HAVE_SETATTR_PREPARE_NO_USERNS, 1,
543 + [setattr_prepare() is available, doesn't accept user_namespace])
549 diff --git a/config/kernel-symlink.m4 b/config/kernel-symlink.m4
551 index 00000000000..d90366d04b7
553 +++ b/config/kernel-symlink.m4
555 +AC_DEFUN([ZFS_AC_KERNEL_SRC_SYMLINK], [
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.
560 + ZFS_LINUX_TEST_SRC([symlink_userns], [
561 + #include <linux/fs.h>
562 + #include <linux/sched.h>
564 + int tmp_symlink(struct user_namespace *userns,
565 + struct inode *inode ,struct dentry *dentry,
566 + const char *path) { return 0; }
568 + static const struct inode_operations
569 + iops __attribute__ ((unused)) = {
570 + .symlink = tmp_symlink,
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], [
579 + AC_DEFINE(HAVE_IOPS_SYMLINK_USERNS, 1,
580 + [iops->symlink() takes struct user_namespace*])
585 diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
586 index 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.
592 AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
593 + ZFS_LINUX_TEST_SRC([xattr_handler_set_userns], [
594 + #include <linux/xattr.h>
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)
602 + static const struct xattr_handler
603 + xops __attribute__ ((unused)) = {
608 ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
609 #include <linux/xattr.h>
611 @@ -194,45 +209,58 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
613 AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
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
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], [
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])
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.
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], [
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])
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.
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], [
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])
675 - ZFS_LINUX_TEST_ERROR([xattr set()])
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.
684 + [whether xattr_handler->set() wants dentry])
685 + ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry], [
687 + AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
688 + [xattr_handler->set() wants dentry])
690 + ZFS_LINUX_TEST_ERROR([xattr set()])
695 diff --git a/config/kernel.m4 b/config/kernel.m4
696 index 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
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
755 + ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
756 + ZFS_AC_KERNEL_MKNOD
757 + ZFS_AC_KERNEL_SYMLINK
761 diff --git a/include/os/linux/kernel/linux/vfs_compat.h b/include/os/linux/kernel/linux/vfs_compat.h
762 index 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)
769 -#ifndef HAVE_SETATTR_PREPARE
770 +#if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \
771 + defined(HAVE_SETATTR_PREPARE_USERNS))
773 setattr_prepare(struct dentry *dentry, struct iattr *ia)
775 @@ -389,6 +390,15 @@ func(const struct path *path, struct kstat *stat, u32 request_mask, \
777 return (func##_impl(path, stat, request_mask, query_flags)); \
779 +#elif defined(HAVE_USERNS_IOPS_GETATTR)
780 +#define ZPL_GETATTR_WRAPPER(func) \
782 +func(struct user_namespace *user_ns, const struct path *path, \
783 + struct kstat *stat, u32 request_mask, unsigned int query_flags) \
785 + return (func##_impl(user_ns, path, stat, request_mask, \
791 @@ -436,4 +446,16 @@ zpl_is_32bit_api(void)
797 + * To support id-mapped mounts, generic_fillattr() was modified to
798 + * accept a new struct user_namespace* as its first arg.
800 +#ifdef HAVE_GENERIC_FILLATTR_USERNS
801 +#define zpl_generic_fillattr(user_ns, ip, sp) \
802 + generic_fillattr(user_ns, ip, sp)
804 +#define zpl_generic_fillattr(user_ns, ip, sp) generic_fillattr(ip, sp)
807 #endif /* _ZFS_VFS_H */
808 diff --git a/include/os/linux/kernel/linux/xattr_compat.h b/include/os/linux/kernel/linux/xattr_compat.h
809 index 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"
818 + * The xattr_handler->set() callback was changed to take the
819 + * struct user_namespace* as the first arg, to support idmapped
822 +#if defined(HAVE_XATTR_SET_USERNS)
823 +#define ZPL_XATTR_SET_WRAPPER(fn) \
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) \
829 + return (__ ## fn(inode, name, buffer, size, flags)); \
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.
836 -#if defined(HAVE_XATTR_SET_DENTRY_INODE)
837 +#elif defined(HAVE_XATTR_SET_DENTRY_INODE)
838 #define ZPL_XATTR_SET_WRAPPER(fn) \
840 fn(const struct xattr_handler *handler, struct dentry *dentry, \
841 diff --git a/include/os/linux/zfs/sys/zfs_vnops_os.h b/include/os/linux/zfs/sys/zfs_vnops_os.h
842 index 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,
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);
855 diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h
856 index 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)
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)
868 +#error "Unsupported kernel"
871 +#ifdef HAVE_SETATTR_PREPARE_USERNS
872 +#define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(ns, dentry, ia)
875 + * Use kernel-provided version, or our own from
876 + * linux/vfs_compat.h
878 +#define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(dentry, ia)
881 #endif /* _SYS_ZPL_H */
882 diff --git a/module/os/linux/zfs/policy.c b/module/os/linux/zfs/policy.c
883 index 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)
890 - if (inode_owner_or_capable(ip))
891 + if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
894 #if defined(CONFIG_USER_NS)
895 diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
896 index 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)
903 -zfs_getattr_fast(struct inode *ip, struct kstat *sp)
904 +zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
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)
911 mutex_enter(&zp->z_lock);
913 - generic_fillattr(ip, sp);
914 + zpl_generic_fillattr(user_ns, ip, sp);
916 * +1 link count for root inode with visible '.zfs' directory.
918 diff --git a/module/os/linux/zfs/zpl_ctldir.c b/module/os/linux/zfs/zpl_ctldir.c
919 index 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)
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)
931 zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
932 u32 request_mask, unsigned int query_flags)
935 struct inode *ip = path->dentry->d_inode;
937 +#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
938 + generic_fillattr(user_ns, ip, stat);
940 generic_fillattr(ip, stat);
942 stat->atime = current_time(ip);
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 */
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)
954 zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
955 struct inode *tdip, struct dentry *tdentry, unsigned int flags)
960 @@ -309,7 +325,7 @@ zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
964 -#ifndef HAVE_RENAME_WANTS_FLAGS
965 +#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
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)
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)
977 zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
982 @@ -363,14 +384,24 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
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)
991 zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
992 u32 request_mask, unsigned int query_flags)
995 struct inode *ip = path->dentry->d_inode;
996 zfsvfs_t *zfsvfs = ITOZSB(ip);
999 +#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
1000 + generic_fillattr(user_ns, ip, stat);
1002 generic_fillattr(ip, stat);
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,
1015 .rename = zpl_snapdir_rename,
1016 @@ -495,8 +526,14 @@ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
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)
1025 zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
1026 u32 request_mask, unsigned int query_flags)
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,
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);
1038 generic_fillattr(path->dentry->d_inode, stat);
1040 stat->nlink = stat->size = 2;
1041 stat->atime = current_time(ip);
1043 @@ -515,7 +556,11 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
1045 error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
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);
1051 + error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat);
1056 diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c
1057 index 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))
1064 - if (!inode_owner_or_capable(ip))
1065 + if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
1069 diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c
1070 index 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)
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)
1081 zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
1084 cred_t *cr = CRED();
1086 @@ -163,7 +168,12 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
1090 +#ifdef HAVE_IOPS_MKNOD_USERNS
1091 +zpl_mknod(struct user_namespace *user_ns, struct inode *dir,
1092 + struct dentry *dentry, umode_t mode,
1094 zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
1098 cred_t *cr = CRED();
1099 @@ -278,7 +288,12 @@ zpl_unlink(struct inode *dir, struct dentry *dentry)
1103 +#ifdef HAVE_IOPS_MKDIR_USERNS
1104 +zpl_mkdir(struct user_namespace *user_ns, struct inode *dir,
1105 + struct dentry *dentry, umode_t mode)
1107 zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
1110 cred_t *cr = CRED();
1112 @@ -338,8 +353,14 @@ zpl_rmdir(struct inode *dir, struct dentry *dentry)
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)
1121 zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
1122 unsigned int query_flags)
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.
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);
1135 + error = -zfs_getattr_fast(kcred->user_ns, path->dentry->d_inode, stat);
1137 spl_fstrans_unmark(cookie);
1138 ASSERT3S(error, <=, 0);
1140 @@ -359,7 +384,12 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
1141 ZPL_GETATTR_WRAPPER(zpl_getattr);
1144 +#ifdef HAVE_SETATTR_PREPARE_USERNS
1145 +zpl_setattr(struct user_namespace *user_ns, struct dentry *dentry,
1148 zpl_setattr(struct dentry *dentry, struct iattr *ia)
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)
1155 fstrans_cookie_t cookie;
1157 - error = setattr_prepare(dentry, ia);
1158 + error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
1162 @@ -399,8 +429,14 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
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)
1171 zpl_rename2(struct inode *sdip, struct dentry *sdentry,
1172 struct inode *tdip, struct dentry *tdentry, unsigned int flags)
1175 cred_t *cr = CRED();
1177 @@ -421,7 +457,7 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
1181 -#ifndef HAVE_RENAME_WANTS_FLAGS
1182 +#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
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,
1190 +#ifdef HAVE_IOPS_SYMLINK_USERNS
1191 +zpl_symlink(struct user_namespace *user_ns, struct inode *dir,
1192 + struct dentry *dentry, const char *name)
1194 zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
1197 cred_t *cr = CRED();
1199 @@ -678,7 +719,7 @@ const struct inode_operations zpl_dir_inode_operations = {
1203 -#ifdef HAVE_RENAME_WANTS_FLAGS
1204 +#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
1205 .rename = zpl_rename2,
1207 .rename = zpl_rename,
1208 diff --git a/module/os/linux/zfs/zpl_xattr.c b/module/os/linux/zfs/zpl_xattr.c
1209 index 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);
1216 - if (!inode_owner_or_capable(ip))
1217 + if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
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);
1225 - if (!inode_owner_or_capable(ip))
1226 + if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
1230 From ffd6978ef59cfe2773e984bf03de2f0b93b03f5c Mon Sep 17 00:00:00 2001
1231 From: Coleman Kane <ckane@colemankane.org>
1232 Date: Sat, 20 Mar 2021 01:33:42 -0400
1233 Subject: [PATCH] Linux 5.12 update: bio_max_segs() replaces BIO_MAX_PAGES
1235 The BIO_MAX_PAGES macro is being retired in favor of a bio_max_segs()
1236 function that implements the typical MIN(x,y) logic used throughout the
1237 kernel for bounding the allocation, and also the new implementation is
1238 intended to be signed-safe (which the former was not).
1240 Reviewed-by: Tony Hutter <hutter2@llnl.gov>
1241 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
1242 Signed-off-by: Coleman Kane <ckane@colemankane.org>
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
1251 diff --git a/config/kernel-bio_max_segs.m4 b/config/kernel-bio_max_segs.m4
1252 new file mode 100644
1253 index 00000000000..a90d75455c1
1255 +++ b/config/kernel-bio_max_segs.m4
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.
1262 +AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS], [
1263 + ZFS_LINUX_TEST_SRC([bio_max_segs], [
1264 + #include <linux/bio.h>
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)
1275 + AC_DEFINE([HAVE_BIO_MAX_SEGS], 1, [bio_max_segs() is implemented])
1280 diff --git a/config/kernel.m4 b/config/kernel.m4
1281 index 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
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
1295 ZFS_AC_KERNEL_SYMLINK
1296 + ZFS_AC_KERNEL_BIO_MAX_SEGS
1300 diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c
1301 index 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,
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)));
1312 dr->dr_bio[i] = bio_alloc(GFP_NOIO,
1313 MIN(abd_nr_pages_off(zio->io_abd, bio_size, abd_offset),
1316 if (unlikely(dr->dr_bio[i] == NULL)) {
1317 vdev_disk_dio_free(dr);
1318 return (SET_ERROR(ENOMEM));