public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Georgy Yakovlev" <gyakovlev@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] repo/gentoo:master commit in: sys-fs/zfs-kmod/, sys-fs/zfs-kmod/files/
Date: Fri,  4 Jun 2021 02:14:29 +0000 (UTC)	[thread overview]
Message-ID: <1622769913.919f0c385d58501b3b1aa32543ff3772aea483ee.gyakovlev@gentoo> (raw)

commit:     919f0c385d58501b3b1aa32543ff3772aea483ee
Author:     Georgy Yakovlev <gyakovlev <AT> gentoo <DOT> org>
AuthorDate: Fri Jun  4 01:20:37 2021 +0000
Commit:     Georgy Yakovlev <gyakovlev <AT> gentoo <DOT> org>
CommitDate: Fri Jun  4 01:25:13 2021 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=919f0c38

sys-fs/zfs-kmod: revbump 2.0.4, add 5.12 support and fixes

run eautoreconf, as a lot of m4 files changed

Bug: https://bugs.gentoo.org/792627
Bug: https://bugs.gentoo.org/790686
Signed-off-by: Georgy Yakovlev <gyakovlev <AT> gentoo.org>

 .../files/zfs-8.0.4_5.12_compat_bio_max_segs.patch |   91 ++
 .../zfs-8.0.4_5.12_compat_idmapped_mounts.patch    | 1231 ++++++++++++++++++++
 .../zfs-8.0.4_5.12_compat_iov_iter_advance.patch   |   40 +
 .../files/zfs-8.0.4_5.12_compat_tmpfile.patch      |   89 ++
 .../files/zfs-8.0.4_5.12_compat_userns.patch       |  173 +++
 .../zfs-8.0.4_spl_kmem_cache_slab_limit_16K.patch  |   59 +
 .../zfs-kmod/files/zfs-8.0.4_stream_resume.patch   |   33 +
 sys-fs/zfs-kmod/zfs-kmod-2.0.4-r1.ebuild           |  186 +++
 8 files changed, 1902 insertions(+)

diff --git a/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_bio_max_segs.patch b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_bio_max_segs.patch
new file mode 100644
index 00000000000..33f9a344e2f
--- /dev/null
+++ b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_bio_max_segs.patch
@@ -0,0 +1,91 @@
+From 77352db228c07ce8ba50478b9029820ca69c6c1b Mon Sep 17 00:00:00 2001
+From: Coleman Kane <ckane@colemankane.org>
+Date: Sat, 20 Mar 2021 01:33:42 -0400
+Subject: [PATCH] Linux 5.12 update: bio_max_segs() replaces BIO_MAX_PAGES
+
+The BIO_MAX_PAGES macro is being retired in favor of a bio_max_segs()
+function that implements the typical MIN(x,y) logic used throughout the
+kernel for bounding the allocation, and also the new implementation is
+intended to be signed-safe (which the former was not).
+
+Reviewed-by: Tony Hutter <hutter2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Coleman Kane <ckane@colemankane.org>
+Closes #11765
+(cherry picked from commit ffd6978ef59cfe2773e984bf03de2f0b93b03f5c)
+Signed-off-by: Jonathon Fernyhough <jonathon@m2x.dev>
+---
+ config/kernel-bio_max_segs.m4   | 23 +++++++++++++++++++++++
+ config/kernel.m4                |  2 ++
+ module/os/linux/zfs/vdev_disk.c |  5 +++++
+ 3 files changed, 30 insertions(+)
+ create mode 100644 config/kernel-bio_max_segs.m4
+
+diff --git a/config/kernel-bio_max_segs.m4 b/config/kernel-bio_max_segs.m4
+new file mode 100644
+index 00000000000..a90d75455c1
+--- /dev/null
++++ b/config/kernel-bio_max_segs.m4
+@@ -0,0 +1,23 @@
++dnl #
++dnl # 5.12 API change removes BIO_MAX_PAGES in favor of bio_max_segs()
++dnl # which will handle the logic of setting the upper-bound to a
++dnl # BIO_MAX_PAGES, internally.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS], [
++	ZFS_LINUX_TEST_SRC([bio_max_segs], [
++		#include <linux/bio.h>
++	],[
++		bio_max_segs(1);
++	])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_BIO_MAX_SEGS], [
++	AC_MSG_CHECKING([whether bio_max_segs() exists])
++	ZFS_LINUX_TEST_RESULT([bio_max_segs], [
++		AC_MSG_RESULT(yes)
++
++		AC_DEFINE([HAVE_BIO_MAX_SEGS], 1, [bio_max_segs() is implemented])
++	],[
++		AC_MSG_RESULT(no)
++	])
++])
+diff --git a/config/kernel.m4 b/config/kernel.m4
+index 51c7fb926ec..b8d53490a4a 100644
+--- a/config/kernel.m4
++++ b/config/kernel.m4
+@@ -127,6 +127,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
+ 	ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS
+ 	ZFS_AC_KERNEL_SRC_MKNOD
+ 	ZFS_AC_KERNEL_SRC_SYMLINK
++	ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS
+ 
+ 	AC_MSG_CHECKING([for available kernel interfaces])
+ 	ZFS_LINUX_TEST_COMPILE_ALL([kabi])
+@@ -227,6 +228,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
+ 	ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
+ 	ZFS_AC_KERNEL_MKNOD
+ 	ZFS_AC_KERNEL_SYMLINK
++	ZFS_AC_KERNEL_BIO_MAX_SEGS
+ ])
+ 
+ dnl #
+diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c
+index 08c33313407..aaaf4105979 100644
+--- a/module/os/linux/zfs/vdev_disk.c
++++ b/module/os/linux/zfs/vdev_disk.c
+@@ -593,9 +593,14 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
+ 		}
+ 
+ 		/* bio_alloc() with __GFP_WAIT never returns NULL */
++#ifdef HAVE_BIO_MAX_SEGS
++		dr->dr_bio[i] = bio_alloc(GFP_NOIO, bio_max_segs(
++		    abd_nr_pages_off(zio->io_abd, bio_size, abd_offset)));
++#else
+ 		dr->dr_bio[i] = bio_alloc(GFP_NOIO,
+ 		    MIN(abd_nr_pages_off(zio->io_abd, bio_size, abd_offset),
+ 		    BIO_MAX_PAGES));
++#endif
+ 		if (unlikely(dr->dr_bio[i] == NULL)) {
+ 			vdev_disk_dio_free(dr);
+ 			return (SET_ERROR(ENOMEM));

diff --git a/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_idmapped_mounts.patch b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_idmapped_mounts.patch
new file mode 100644
index 00000000000..fd8b025a8fd
--- /dev/null
+++ b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_idmapped_mounts.patch
@@ -0,0 +1,1231 @@
+From f315d9a3ff3cc0b81c99dd9be5878a55d2e98d8e Mon Sep 17 00:00:00 2001
+From: Coleman Kane <ckane@colemankane.org>
+Date: Sat, 20 Mar 2021 00:00:59 -0400
+Subject: [PATCH] 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 <hutter2@llnl.gov>
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Co-authored-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Coleman Kane <ckane@colemankane.org>
+Closes #11712
+(cherry picked from commit e2a8296131e94ad785f5564156ed2db1fdb2e080)
+Signed-off-by: Jonathon Fernyhough <jonathon@m2x.dev>
+---
+ config/kernel-generic_fillattr.m4            | 28 +++++++
+ config/kernel-inode-create.m4                | 43 +++++++++--
+ config/kernel-inode-getattr.m4               | 63 +++++++++++++---
+ config/kernel-is_owner_or_cap.m4             | 23 +++++-
+ config/kernel-mkdir-umode-t.m4               | 32 --------
+ config/kernel-mkdir.m4                       | 65 ++++++++++++++++
+ config/kernel-mknod.m4                       | 30 ++++++++
+ config/kernel-rename.m4                      | 50 ++++++++++---
+ config/kernel-setattr-prepare.m4             | 45 ++++++++---
+ config/kernel-symlink.m4                     | 30 ++++++++
+ config/kernel-xattr-handler.m4               | 78 +++++++++++++-------
+ config/kernel.m4                             | 18 +++--
+ include/os/linux/kernel/linux/vfs_compat.h   | 24 +++++-
+ include/os/linux/kernel/linux/xattr_compat.h | 17 ++++-
+ include/os/linux/zfs/sys/zfs_vnops_os.h      |  3 +-
+ include/os/linux/zfs/sys/zpl.h               | 18 +++++
+ module/os/linux/zfs/policy.c                 |  2 +-
+ module/os/linux/zfs/zfs_vnops_os.c           |  5 +-
+ module/os/linux/zfs/zpl_ctldir.c             | 51 ++++++++++++-
+ module/os/linux/zfs/zpl_file.c               |  2 +-
+ module/os/linux/zfs/zpl_inode.c              | 49 +++++++++++-
+ module/os/linux/zfs/zpl_xattr.c              |  4 +-
+ 22 files changed, 557 insertions(+), 123 deletions(-)
+ create mode 100644 config/kernel-generic_fillattr.m4
+ delete mode 100644 config/kernel-mkdir-umode-t.m4
+ create mode 100644 config/kernel-mkdir.m4
+ create mode 100644 config/kernel-mknod.m4
+ create mode 100644 config/kernel-symlink.m4
+
+diff --git a/config/kernel-generic_fillattr.m4 b/config/kernel-generic_fillattr.m4
+new file mode 100644
+index 00000000000..50c8031305b
+--- /dev/null
++++ b/config/kernel-generic_fillattr.m4
+@@ -0,0 +1,28 @@
++dnl #
++dnl # 5.12 API
++dnl #
++dnl # generic_fillattr in linux/fs.h now requires a struct user_namespace*
++dnl # as the first arg, to support idmapped mounts.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [
++	ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
++		#include <linux/fs.h>
++	],[
++		struct user_namespace *userns = NULL;
++		struct inode *in = NULL;
++		struct kstat *k = NULL;
++		generic_fillattr(userns, in, k);
++	])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [
++	AC_MSG_CHECKING([whether generic_fillattr requres struct user_namespace*])
++	ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
++		AC_MSG_RESULT([yes])
++		AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1,
++		    [generic_fillattr requires struct user_namespace*])
++	],[
++		AC_MSG_RESULT([no])
++	])
++])
++
+diff --git a/config/kernel-inode-create.m4 b/config/kernel-inode-create.m4
+index 9f28bcbd4f7..a6ea11fb61b 100644
+--- a/config/kernel-inode-create.m4
++++ b/config/kernel-inode-create.m4
+@@ -1,7 +1,25 @@
+-dnl #
+-dnl # 3.6 API change
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
++AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
++	dnl #
++	dnl # 5.12 API change that added the struct user_namespace* arg
++	dnl # to the front of this function type's arg list.
++	dnl #
++	ZFS_LINUX_TEST_SRC([create_userns], [
++		#include <linux/fs.h>
++		#include <linux/sched.h>
++
++		int inode_create(struct user_namespace *userns,
++		    struct inode *inode ,struct dentry *dentry,
++		    umode_t umode, bool flag) { return 0; }
++
++		static const struct inode_operations
++			iops __attribute__ ((unused)) = {
++			.create		= inode_create,
++		};
++	],[])
++
++	dnl #
++	dnl # 3.6 API change
++	dnl #
+ 	ZFS_LINUX_TEST_SRC([create_flags], [
+ 		#include <linux/fs.h>
+ 		#include <linux/sched.h>
+@@ -16,11 +34,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
+ 	],[])
+ ])
+ 
+-AC_DEFUN([ZFS_AC_KERNEL_CREATE_FLAGS], [
+-	AC_MSG_CHECKING([whether iops->create() passes flags])
+-	ZFS_LINUX_TEST_RESULT([create_flags], [
++AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
++	AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
++	ZFS_LINUX_TEST_RESULT([create_userns], [
+ 		AC_MSG_RESULT(yes)
++		AC_DEFINE(HAVE_IOPS_CREATE_USERNS, 1,
++		   [iops->create() takes struct user_namespace*])
+ 	],[
+-		ZFS_LINUX_TEST_ERROR([iops->create()])
++		AC_MSG_RESULT(no)
++
++		AC_MSG_CHECKING([whether iops->create() passes flags])
++		ZFS_LINUX_TEST_RESULT([create_flags], [
++			AC_MSG_RESULT(yes)
++		],[
++			ZFS_LINUX_TEST_ERROR([iops->create()])
++		])
+ 	])
+ ])
+diff --git a/config/kernel-inode-getattr.m4 b/config/kernel-inode-getattr.m4
+index 48391d66f8b..f62e82f5230 100644
+--- a/config/kernel-inode-getattr.m4
++++ b/config/kernel-inode-getattr.m4
+@@ -1,8 +1,29 @@
+-dnl #
+-dnl # Linux 4.11 API
+-dnl # See torvalds/linux@a528d35
+-dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
++	dnl #
++	dnl # Linux 5.12 API
++	dnl # The getattr I/O operations handler type was extended to require
++	dnl # a struct user_namespace* as its first arg, to support idmapped
++	dnl # mounts.
++	dnl #
++	ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
++		#include <linux/fs.h>
++
++		int test_getattr(
++			struct user_namespace *userns,
++		    const struct path *p, struct kstat *k,
++		    u32 request_mask, unsigned int query_flags)
++		    { return 0; }
++
++		static const struct inode_operations
++		    iops __attribute__ ((unused)) = {
++			.getattr = test_getattr,
++		};
++	],[])
++
++	dnl #
++	dnl # Linux 4.11 API
++	dnl # See torvalds/linux@a528d35
++	dnl #
+ 	ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
+ 		#include <linux/fs.h>
+ 
+@@ -33,21 +54,39 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
+ ])
+ 
+ AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
+-	AC_MSG_CHECKING([whether iops->getattr() takes a path])
+-	ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
++	dnl #
++	dnl # Kernel 5.12 test
++	dnl #
++	AC_MSG_CHECKING([whether iops->getattr() takes user_namespace])
++	ZFS_LINUX_TEST_RESULT([inode_operations_getattr_userns], [
+ 		AC_MSG_RESULT(yes)
+-		AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
+-		    [iops->getattr() takes a path])
++		AC_DEFINE(HAVE_USERNS_IOPS_GETATTR, 1,
++		    [iops->getattr() takes struct user_namespace*])
+ 	],[
+ 		AC_MSG_RESULT(no)
+ 
+-		AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
+-		ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
++		dnl #
++		dnl # Kernel 4.11 test
++		dnl #
++		AC_MSG_CHECKING([whether iops->getattr() takes a path])
++		ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
+ 			AC_MSG_RESULT(yes)
+-			AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
+-			    [iops->getattr() takes a vfsmount])
++			AC_DEFINE(HAVE_PATH_IOPS_GETATTR, 1,
++				[iops->getattr() takes a path])
+ 		],[
+ 			AC_MSG_RESULT(no)
++
++			dnl #
++			dnl # Kernel < 4.11 test
++			dnl #
++			AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
++			ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
++				AC_MSG_RESULT(yes)
++				AC_DEFINE(HAVE_VFSMOUNT_IOPS_GETATTR, 1,
++					[iops->getattr() takes a vfsmount])
++			],[
++				AC_MSG_RESULT(no)
++			])
+ 		])
+ 	])
+ ])
+diff --git a/config/kernel-is_owner_or_cap.m4 b/config/kernel-is_owner_or_cap.m4
+index 3df6163da27..3c3c6ad2240 100644
+--- a/config/kernel-is_owner_or_cap.m4
++++ b/config/kernel-is_owner_or_cap.m4
+@@ -11,13 +11,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [
+ 		struct inode *ip = NULL;
+ 		(void) inode_owner_or_capable(ip);
+ 	])
++
++	ZFS_LINUX_TEST_SRC([inode_owner_or_capable_idmapped], [
++		#include <linux/fs.h>
++	],[
++		struct inode *ip = NULL;
++		(void) inode_owner_or_capable(&init_user_ns, ip);
++	])
+ ])
+ 
+ AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
+ 	AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
+ 	ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
+ 		AC_MSG_RESULT(yes)
+-	],[
+-		ZFS_LINUX_TEST_ERROR([capability])
++		AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
++		    [inode_owner_or_capable() exists])
++	], [
++		AC_MSG_RESULT(no)
++
++		AC_MSG_CHECKING(
++		    [whether inode_owner_or_capable() takes user_ns])
++		ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_idmapped], [
++			AC_MSG_RESULT(yes)
++			AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED, 1,
++			    [inode_owner_or_capable() takes user_ns])
++		],[
++			ZFS_LINUX_TEST_ERROR([capability])
++		])
+ 	])
+ ])
+diff --git a/config/kernel-mkdir-umode-t.m4 b/config/kernel-mkdir-umode-t.m4
+deleted file mode 100644
+index 19599670df3..00000000000
+--- a/config/kernel-mkdir-umode-t.m4
++++ /dev/null
+@@ -1,32 +0,0 @@
+-dnl #
+-dnl # 3.3 API change
+-dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
+-dnl # umode_t type rather than an int.  The expectation is that any backport
+-dnl # would also change all three prototypes.  However, if it turns out that
+-dnl # some distribution doesn't backport the whole thing this could be
+-dnl # broken apart into three separate checks.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T], [
+-	ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
+-		#include <linux/fs.h>
+-
+-		int mkdir(struct inode *inode, struct dentry *dentry,
+-		    umode_t umode) { return 0; }
+-
+-		static const struct inode_operations
+-		    iops __attribute__ ((unused)) = {
+-			.mkdir = mkdir,
+-		};
+-	],[])
+-])
+-
+-AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
+-	AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
+-	ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
+-		AC_MSG_RESULT(yes)
+-		AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
+-		    [iops->create()/mkdir()/mknod() take umode_t])
+-	],[
+-		ZFS_LINUX_TEST_ERROR([mkdir()])
+-	])
+-])
+diff --git a/config/kernel-mkdir.m4 b/config/kernel-mkdir.m4
+new file mode 100644
+index 00000000000..a162bcd880f
+--- /dev/null
++++ b/config/kernel-mkdir.m4
+@@ -0,0 +1,65 @@
++dnl #
++dnl # Supported mkdir() interfaces checked newest to oldest.
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
++	dnl #
++	dnl # 5.12 API change
++	dnl # The struct user_namespace arg was added as the first argument to
++	dnl # mkdir()
++	dnl #
++	ZFS_LINUX_TEST_SRC([mkdir_user_namespace], [
++		#include <linux/fs.h>
++
++		int mkdir(struct user_namespace *userns,
++			struct inode *inode, struct dentry *dentry,
++		    umode_t umode) { return 0; }
++
++		static const struct inode_operations
++		    iops __attribute__ ((unused)) = {
++			.mkdir = mkdir,
++		};
++	],[])
++
++	dnl #
++	dnl # 3.3 API change
++	dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
++	dnl # umode_t type rather than an int.  The expectation is that any backport
++	dnl # would also change all three prototypes.  However, if it turns out that
++	dnl # some distribution doesn't backport the whole thing this could be
++	dnl # broken apart into three separate checks.
++	dnl #
++	ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
++		#include <linux/fs.h>
++
++		int mkdir(struct inode *inode, struct dentry *dentry,
++		    umode_t umode) { return 0; }
++
++		static const struct inode_operations
++		    iops __attribute__ ((unused)) = {
++			.mkdir = mkdir,
++		};
++	],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_MKDIR], [
++	dnl #
++	dnl # 5.12 API change
++	dnl # The struct user_namespace arg was added as the first argument to
++	dnl # mkdir() of the iops structure.
++	dnl #
++	AC_MSG_CHECKING([whether iops->mkdir() takes struct user_namespace*])
++	ZFS_LINUX_TEST_RESULT([mkdir_user_namespace], [
++		AC_MSG_RESULT(yes)
++		AC_DEFINE(HAVE_IOPS_MKDIR_USERNS, 1,
++		    [iops->mkdir() takes struct user_namespace*])
++	],[
++		AC_MSG_CHECKING([whether iops->mkdir() takes umode_t])
++		ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
++			AC_MSG_RESULT(yes)
++			AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
++			    [iops->mkdir() takes umode_t])
++		],[
++			ZFS_LINUX_TEST_ERROR([mkdir()])
++		])
++	])
++])
+diff --git a/config/kernel-mknod.m4 b/config/kernel-mknod.m4
+new file mode 100644
+index 00000000000..ffe45106003
+--- /dev/null
++++ b/config/kernel-mknod.m4
+@@ -0,0 +1,30 @@
++AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
++	dnl #
++	dnl # 5.12 API change that added the struct user_namespace* arg
++	dnl # to the front of this function type's arg list.
++	dnl #
++	ZFS_LINUX_TEST_SRC([mknod_userns], [
++		#include <linux/fs.h>
++		#include <linux/sched.h>
++
++		int tmp_mknod(struct user_namespace *userns,
++		    struct inode *inode ,struct dentry *dentry,
++		    umode_t u, dev_t d) { return 0; }
++
++		static const struct inode_operations
++			iops __attribute__ ((unused)) = {
++			.mknod		= tmp_mknod,
++		};
++	],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_MKNOD], [
++	AC_MSG_CHECKING([whether iops->mknod() takes struct user_namespace*])
++	ZFS_LINUX_TEST_RESULT([mknod_userns], [
++		AC_MSG_RESULT(yes)
++		AC_DEFINE(HAVE_IOPS_MKNOD_USERNS, 1,
++		    [iops->mknod() takes struct user_namespace*])
++	],[
++		AC_MSG_RESULT(no)
++	])
++])
+diff --git a/config/kernel-rename.m4 b/config/kernel-rename.m4
+index f707391539d..31d199f33bb 100644
+--- a/config/kernel-rename.m4
++++ b/config/kernel-rename.m4
+@@ -1,10 +1,10 @@
+-dnl #
+-dnl # 4.9 API change,
+-dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
+-dnl # flags.
+-dnl #
+-AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
+-	ZFS_LINUX_TEST_SRC([inode_operations_rename], [
++AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
++	dnl #
++	dnl # 4.9 API change,
++	dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
++	dnl # flags.
++	dnl #
++	ZFS_LINUX_TEST_SRC([inode_operations_rename_flags], [
+ 		#include <linux/fs.h>
+ 		int rename_fn(struct inode *sip, struct dentry *sdp,
+ 			struct inode *tip, struct dentry *tdp,
+@@ -15,15 +15,41 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
+ 			.rename = rename_fn,
+ 		};
+ 	],[])
++
++	dnl #
++	dnl # 5.12 API change,
++	dnl #
++	dnl # Linux 5.12 introduced passing struct user_namespace* as the first argument
++	dnl # of the rename() and other inode_operations members.
++	dnl #
++	ZFS_LINUX_TEST_SRC([inode_operations_rename_userns], [
++		#include <linux/fs.h>
++		int rename_fn(struct user_namespace *user_ns, struct inode *sip,
++			struct dentry *sdp, struct inode *tip, struct dentry *tdp,
++			unsigned int flags) { return 0; }
++
++		static const struct inode_operations
++		    iops __attribute__ ((unused)) = {
++			.rename = rename_fn,
++		};
++	],[])
+ ])
+ 
+-AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
+-	AC_MSG_CHECKING([whether iops->rename() wants flags])
+-	ZFS_LINUX_TEST_RESULT([inode_operations_rename], [
++AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
++	AC_MSG_CHECKING([whether iops->rename() takes struct user_namespace*])
++	ZFS_LINUX_TEST_RESULT([inode_operations_rename_userns], [
+ 		AC_MSG_RESULT(yes)
+-		AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
+-		    [iops->rename() wants flags])
++		AC_DEFINE(HAVE_IOPS_RENAME_USERNS, 1,
++		    [iops->rename() takes struct user_namespace*])
+ 	],[
+ 		AC_MSG_RESULT(no)
++
++		ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
++			AC_MSG_RESULT(yes)
++			AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
++				[iops->rename() wants flags])
++		],[
++			AC_MSG_RESULT(no)
++		])
+ 	])
+ ])
+diff --git a/config/kernel-setattr-prepare.m4 b/config/kernel-setattr-prepare.m4
+index 45408c45c69..24245aa5344 100644
+--- a/config/kernel-setattr-prepare.m4
++++ b/config/kernel-setattr-prepare.m4
+@@ -1,27 +1,52 @@
+-dnl #
+-dnl # 4.9 API change
+-dnl # The inode_change_ok() function has been renamed setattr_prepare()
+-dnl # and updated to take a dentry rather than an inode.
+-dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
++	dnl #
++	dnl # 4.9 API change
++	dnl # The inode_change_ok() function has been renamed setattr_prepare()
++	dnl # and updated to take a dentry rather than an inode.
++	dnl #
+ 	ZFS_LINUX_TEST_SRC([setattr_prepare], [
+ 		#include <linux/fs.h>
+ 	], [
+ 		struct dentry *dentry = NULL;
+ 		struct iattr *attr = NULL;
+ 		int error __attribute__ ((unused)) =
+-		    setattr_prepare(dentry, attr);
++			setattr_prepare(dentry, attr);
++	])
++
++	dnl #
++	dnl # 5.12 API change
++	dnl # The setattr_prepare() function has been changed to accept a new argument
++	dnl # for struct user_namespace*
++	dnl #
++	ZFS_LINUX_TEST_SRC([setattr_prepare_userns], [
++		#include <linux/fs.h>
++	], [
++		struct dentry *dentry = NULL;
++		struct iattr *attr = NULL;
++		struct user_namespace *userns = NULL;
++		int error __attribute__ ((unused)) =
++			setattr_prepare(userns, dentry, attr);
+ 	])
+ ])
+ 
+ AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
+-	AC_MSG_CHECKING([whether setattr_prepare() is available])
+-	ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
++	AC_MSG_CHECKING([whether setattr_prepare() is available and accepts struct user_namespace*])
++	ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare_userns],
+ 	    [setattr_prepare], [fs/attr.c], [
+ 		AC_MSG_RESULT(yes)
+-		AC_DEFINE(HAVE_SETATTR_PREPARE, 1,
+-		    [setattr_prepare() is available])
++		AC_DEFINE(HAVE_SETATTR_PREPARE_USERNS, 1,
++		    [setattr_prepare() accepts user_namespace])
+ 	], [
+ 		AC_MSG_RESULT(no)
++
++		AC_MSG_CHECKING([whether setattr_prepare() is available, doesn't accept user_namespace])
++		ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
++			[setattr_prepare], [fs/attr.c], [
++			AC_MSG_RESULT(yes)
++			AC_DEFINE(HAVE_SETATTR_PREPARE_NO_USERNS, 1,
++				[setattr_prepare() is available, doesn't accept user_namespace])
++		], [
++			AC_MSG_RESULT(no)
++		])
+ 	])
+ ])
+diff --git a/config/kernel-symlink.m4 b/config/kernel-symlink.m4
+new file mode 100644
+index 00000000000..d90366d04b7
+--- /dev/null
++++ b/config/kernel-symlink.m4
+@@ -0,0 +1,30 @@
++AC_DEFUN([ZFS_AC_KERNEL_SRC_SYMLINK], [
++	dnl #
++	dnl # 5.12 API change that added the struct user_namespace* arg
++	dnl # to the front of this function type's arg list.
++	dnl #
++	ZFS_LINUX_TEST_SRC([symlink_userns], [
++		#include <linux/fs.h>
++		#include <linux/sched.h>
++
++		int tmp_symlink(struct user_namespace *userns,
++		    struct inode *inode ,struct dentry *dentry,
++		    const char *path) { return 0; }
++
++		static const struct inode_operations
++			iops __attribute__ ((unused)) = {
++			.symlink		= tmp_symlink,
++		};
++	],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_SYMLINK], [
++	AC_MSG_CHECKING([whether iops->symlink() takes struct user_namespace*])
++	ZFS_LINUX_TEST_RESULT([symlink_userns], [
++		AC_MSG_RESULT(yes)
++		AC_DEFINE(HAVE_IOPS_SYMLINK_USERNS, 1,
++		    [iops->symlink() takes struct user_namespace*])
++	],[
++		AC_MSG_RESULT(no)
++	])
++])
+diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
+index 137bf4a8aff..00b1e74a9cc 100644
+--- a/config/kernel-xattr-handler.m4
++++ b/config/kernel-xattr-handler.m4
+@@ -152,6 +152,21 @@ dnl #
+ dnl # Supported xattr handler set() interfaces checked newest to oldest.
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
++	ZFS_LINUX_TEST_SRC([xattr_handler_set_userns], [
++		#include <linux/xattr.h>
++
++		int set(const struct xattr_handler *handler,
++			struct user_namespace *mnt_userns,
++			struct dentry *dentry, struct inode *inode,
++			const char *name, const void *buffer,
++			size_t size, int flags)
++			{ return 0; }
++		static const struct xattr_handler
++			xops __attribute__ ((unused)) = {
++			.set = set,
++		};
++	],[])
++
+ 	ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
+ 		#include <linux/xattr.h>
+ 
+@@ -194,45 +209,58 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
+ 
+ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ 	dnl #
+-	dnl # 4.7 API change,
+-	dnl # The xattr_handler->set() callback was changed to take both
+-	dnl # dentry and inode.
++	dnl # 5.12 API change,
++	dnl # The xattr_handler->set() callback was changed to 8 arguments, and
++	dnl # struct user_namespace* was inserted as arg #2
+ 	dnl #
+-	AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
+-	ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
++	AC_MSG_CHECKING([whether xattr_handler->set() wants dentry, inode, and user_namespace])
++	ZFS_LINUX_TEST_RESULT([xattr_handler_set_userns], [
+ 		AC_MSG_RESULT(yes)
+-		AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
+-		    [xattr_handler->set() wants both dentry and inode])
++		AC_DEFINE(HAVE_XATTR_SET_USERNS, 1,
++		    [xattr_handler->set() takes user_namespace])
+ 	],[
+ 		dnl #
+-		dnl # 4.4 API change,
+-		dnl # The xattr_handler->set() callback was changed to take a
+-		dnl # xattr_handler, and handler_flags argument was removed and
+-		dnl # should be accessed by handler->flags.
++		dnl # 4.7 API change,
++		dnl # The xattr_handler->set() callback was changed to take both
++		dnl # dentry and inode.
+ 		dnl #
+ 		AC_MSG_RESULT(no)
+-		AC_MSG_CHECKING(
+-		    [whether xattr_handler->set() wants xattr_handler])
+-		ZFS_LINUX_TEST_RESULT([xattr_handler_set_xattr_handler], [
++		AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
++		ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
+ 			AC_MSG_RESULT(yes)
+-			AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
+-			    [xattr_handler->set() wants xattr_handler])
++			AC_DEFINE(HAVE_XATTR_SET_DENTRY_INODE, 1,
++			    [xattr_handler->set() wants both dentry and inode])
+ 		],[
+ 			dnl #
+-			dnl # 2.6.33 API change,
+-			dnl # The xattr_handler->set() callback was changed
+-			dnl # to take a dentry instead of an inode, and a
+-			dnl # handler_flags argument was added.
++			dnl # 4.4 API change,
++			dnl # The xattr_handler->set() callback was changed to take a
++			dnl # xattr_handler, and handler_flags argument was removed and
++			dnl # should be accessed by handler->flags.
+ 			dnl #
+ 			AC_MSG_RESULT(no)
+ 			AC_MSG_CHECKING(
+-			    [whether xattr_handler->set() wants dentry])
+-			ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry], [
++			    [whether xattr_handler->set() wants xattr_handler])
++			ZFS_LINUX_TEST_RESULT([xattr_handler_set_xattr_handler], [
+ 				AC_MSG_RESULT(yes)
+-				AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
+-				    [xattr_handler->set() wants dentry])
++				AC_DEFINE(HAVE_XATTR_SET_HANDLER, 1,
++				    [xattr_handler->set() wants xattr_handler])
+ 			],[
+-				ZFS_LINUX_TEST_ERROR([xattr set()])
++				dnl #
++				dnl # 2.6.33 API change,
++				dnl # The xattr_handler->set() callback was changed
++				dnl # to take a dentry instead of an inode, and a
++				dnl # handler_flags argument was added.
++				dnl #
++				AC_MSG_RESULT(no)
++				AC_MSG_CHECKING(
++				    [whether xattr_handler->set() wants dentry])
++				ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry], [
++					AC_MSG_RESULT(yes)
++					AC_DEFINE(HAVE_XATTR_SET_DENTRY, 1,
++					    [xattr_handler->set() wants dentry])
++				],[
++					ZFS_LINUX_TEST_ERROR([xattr set()])
++				])
+ 			])
+ 		])
+ 	])
+diff --git a/config/kernel.m4 b/config/kernel.m4
+index 55620b3daa8..51c7fb926ec 100644
+--- a/config/kernel.m4
++++ b/config/kernel.m4
+@@ -79,9 +79,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
+ 	ZFS_AC_KERNEL_SRC_EVICT_INODE
+ 	ZFS_AC_KERNEL_SRC_DIRTY_INODE
+ 	ZFS_AC_KERNEL_SRC_SHRINKER
+-	ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T
++	ZFS_AC_KERNEL_SRC_MKDIR
+ 	ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS
+-	ZFS_AC_KERNEL_SRC_CREATE_FLAGS
++	ZFS_AC_KERNEL_SRC_CREATE
+ 	ZFS_AC_KERNEL_SRC_GET_LINK
+ 	ZFS_AC_KERNEL_SRC_PUT_LINK
+ 	ZFS_AC_KERNEL_SRC_TMPFILE
+@@ -115,7 +115,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
+ 	ZFS_AC_KERNEL_SRC_KUIDGID_T
+ 	ZFS_AC_KERNEL_SRC_KUID_HELPERS
+ 	ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
+-	ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS
++	ZFS_AC_KERNEL_SRC_RENAME
+ 	ZFS_AC_KERNEL_SRC_CURRENT_TIME
+ 	ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
+ 	ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
+@@ -124,6 +124,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
+ 	ZFS_AC_KERNEL_SRC_TOTALHIGH_PAGES
+ 	ZFS_AC_KERNEL_SRC_KSTRTOUL
+ 	ZFS_AC_KERNEL_SRC_PERCPU
++	ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS
++	ZFS_AC_KERNEL_SRC_MKNOD
++	ZFS_AC_KERNEL_SRC_SYMLINK
+ 
+ 	AC_MSG_CHECKING([for available kernel interfaces])
+ 	ZFS_LINUX_TEST_COMPILE_ALL([kabi])
+@@ -176,9 +179,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
+ 	ZFS_AC_KERNEL_EVICT_INODE
+ 	ZFS_AC_KERNEL_DIRTY_INODE
+ 	ZFS_AC_KERNEL_SHRINKER
+-	ZFS_AC_KERNEL_MKDIR_UMODE_T
++	ZFS_AC_KERNEL_MKDIR
+ 	ZFS_AC_KERNEL_LOOKUP_FLAGS
+-	ZFS_AC_KERNEL_CREATE_FLAGS
++	ZFS_AC_KERNEL_CREATE
+ 	ZFS_AC_KERNEL_GET_LINK
+ 	ZFS_AC_KERNEL_PUT_LINK
+ 	ZFS_AC_KERNEL_TMPFILE
+@@ -212,7 +215,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
+ 	ZFS_AC_KERNEL_KUIDGID_T
+ 	ZFS_AC_KERNEL_KUID_HELPERS
+ 	ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
+-	ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
++	ZFS_AC_KERNEL_RENAME
+ 	ZFS_AC_KERNEL_CURRENT_TIME
+ 	ZFS_AC_KERNEL_USERNS_CAPABILITIES
+ 	ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
+@@ -221,6 +224,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
+ 	ZFS_AC_KERNEL_TOTALHIGH_PAGES
+ 	ZFS_AC_KERNEL_KSTRTOUL
+ 	ZFS_AC_KERNEL_PERCPU
++	ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
++	ZFS_AC_KERNEL_MKNOD
++	ZFS_AC_KERNEL_SYMLINK
+ ])
+ 
+ dnl #
+diff --git a/include/os/linux/kernel/linux/vfs_compat.h b/include/os/linux/kernel/linux/vfs_compat.h
+index c35e80d31cd..91e908598fb 100644
+--- a/include/os/linux/kernel/linux/vfs_compat.h
++++ b/include/os/linux/kernel/linux/vfs_compat.h
+@@ -343,7 +343,8 @@ static inline void zfs_gid_write(struct inode *ip, gid_t gid)
+ /*
+  * 4.9 API change
+  */
+-#ifndef HAVE_SETATTR_PREPARE
++#if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \
++    defined(HAVE_SETATTR_PREPARE_USERNS))
+ static inline int
+ setattr_prepare(struct dentry *dentry, struct iattr *ia)
+ {
+@@ -389,6 +390,15 @@ func(const struct path *path, struct kstat *stat, u32 request_mask,	\
+ {									\
+ 	return (func##_impl(path, stat, request_mask, query_flags));	\
+ }
++#elif defined(HAVE_USERNS_IOPS_GETATTR)
++#define	ZPL_GETATTR_WRAPPER(func)					\
++static int								\
++func(struct user_namespace *user_ns, const struct path *path,	\
++    struct kstat *stat, u32 request_mask, unsigned int query_flags)	\
++{									\
++	return (func##_impl(user_ns, path, stat, request_mask, \
++	    query_flags));	\
++}
+ #else
+ #error
+ #endif
+@@ -436,4 +446,16 @@ zpl_is_32bit_api(void)
+ #endif
+ }
+ 
++/*
++ * 5.12 API change
++ * To support id-mapped mounts, generic_fillattr() was modified to
++ * accept a new struct user_namespace* as its first arg.
++ */
++#ifdef HAVE_GENERIC_FILLATTR_USERNS
++#define	zpl_generic_fillattr(user_ns, ip, sp)	\
++    generic_fillattr(user_ns, ip, sp)
++#else
++#define	zpl_generic_fillattr(user_ns, ip, sp)	generic_fillattr(ip, sp)
++#endif
++
+ #endif /* _ZFS_VFS_H */
+diff --git a/include/os/linux/kernel/linux/xattr_compat.h b/include/os/linux/kernel/linux/xattr_compat.h
+index 8348e99198a..54690727eab 100644
+--- a/include/os/linux/kernel/linux/xattr_compat.h
++++ b/include/os/linux/kernel/linux/xattr_compat.h
+@@ -119,12 +119,27 @@ fn(struct dentry *dentry, const char *name, void *buffer, size_t size,	\
+ #error "Unsupported kernel"
+ #endif
+ 
++/*
++ * 5.12 API change,
++ * The xattr_handler->set() callback was changed to take the
++ * struct user_namespace* as the first arg, to support idmapped
++ * mounts.
++ */
++#if defined(HAVE_XATTR_SET_USERNS)
++#define	ZPL_XATTR_SET_WRAPPER(fn)					\
++static int								\
++fn(const struct xattr_handler *handler, struct user_namespace *user_ns, \
++    struct dentry *dentry, struct inode *inode, const char *name,	\
++    const void *buffer, size_t size, int flags)	\
++{									\
++	return (__ ## fn(inode, name, buffer, size, flags));		\
++}
+ /*
+  * 4.7 API change,
+  * The xattr_handler->set() callback was changed to take a both dentry and
+  * inode, because the dentry might not be attached to an inode yet.
+  */
+-#if defined(HAVE_XATTR_SET_DENTRY_INODE)
++#elif defined(HAVE_XATTR_SET_DENTRY_INODE)
+ #define	ZPL_XATTR_SET_WRAPPER(fn)					\
+ static int								\
+ fn(const struct xattr_handler *handler, struct dentry *dentry,		\
+diff --git a/include/os/linux/zfs/sys/zfs_vnops_os.h b/include/os/linux/zfs/sys/zfs_vnops_os.h
+index 1c9cdf7bf8f..ba83f5dd83d 100644
+--- a/include/os/linux/zfs/sys/zfs_vnops_os.h
++++ b/include/os/linux/zfs/sys/zfs_vnops_os.h
+@@ -56,7 +56,8 @@ extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap,
+ extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd,
+     cred_t *cr, int flags);
+ extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr);
+-extern int zfs_getattr_fast(struct inode *ip, struct kstat *sp);
++extern int zfs_getattr_fast(struct user_namespace *, struct inode *ip,
++	struct kstat *sp);
+ extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
+ extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
+     char *tnm, cred_t *cr, int flags);
+diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h
+index b0bb9c29c0b..21825d1f378 100644
+--- a/include/os/linux/zfs/sys/zpl.h
++++ b/include/os/linux/zfs/sys/zpl.h
+@@ -171,4 +171,22 @@ zpl_dir_emit_dots(struct file *file, zpl_dir_context_t *ctx)
+ 	timespec_trunc(ts, (ip)->i_sb->s_time_gran)
+ #endif
+ 
++#if defined(HAVE_INODE_OWNER_OR_CAPABLE)
++#define	zpl_inode_owner_or_capable(ns, ip)	inode_owner_or_capable(ip)
++#elif defined(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED)
++#define	zpl_inode_owner_or_capable(ns, ip)	inode_owner_or_capable(ns, ip)
++#else
++#error "Unsupported kernel"
++#endif
++
++#ifdef HAVE_SETATTR_PREPARE_USERNS
++#define	zpl_setattr_prepare(ns, dentry, ia)	setattr_prepare(ns, dentry, ia)
++#else
++/*
++ * Use kernel-provided version, or our own from
++ * linux/vfs_compat.h
++ */
++#define	zpl_setattr_prepare(ns, dentry, ia)	setattr_prepare(dentry, ia)
++#endif
++
+ #endif	/* _SYS_ZPL_H */
+diff --git a/module/os/linux/zfs/policy.c b/module/os/linux/zfs/policy.c
+index 8780d7f6c70..bbccb2e572d 100644
+--- a/module/os/linux/zfs/policy.c
++++ b/module/os/linux/zfs/policy.c
+@@ -124,7 +124,7 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
+ 	if (crgetfsuid(cr) == owner)
+ 		return (0);
+ 
+-	if (inode_owner_or_capable(ip))
++	if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
+ 		return (0);
+ 
+ #if defined(CONFIG_USER_NS)
+diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
+index 7484d651c1f..ce0701763fd 100644
+--- a/module/os/linux/zfs/zfs_vnops_os.c
++++ b/module/os/linux/zfs/zfs_vnops_os.c
+@@ -1907,7 +1907,8 @@ zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr)
+  */
+ /* ARGSUSED */
+ int
+-zfs_getattr_fast(struct inode *ip, struct kstat *sp)
++zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
++    struct kstat *sp)
+ {
+ 	znode_t *zp = ITOZ(ip);
+ 	zfsvfs_t *zfsvfs = ITOZSB(ip);
+@@ -1919,7 +1920,7 @@ zfs_getattr_fast(struct inode *ip, struct kstat *sp)
+ 
+ 	mutex_enter(&zp->z_lock);
+ 
+-	generic_fillattr(ip, sp);
++	zpl_generic_fillattr(user_ns, ip, sp);
+ 	/*
+ 	 * +1 link count for root inode with visible '.zfs' directory.
+ 	 */
+diff --git a/module/os/linux/zfs/zpl_ctldir.c b/module/os/linux/zfs/zpl_ctldir.c
+index e6420f19ed8..9b526afd000 100644
+--- a/module/os/linux/zfs/zpl_ctldir.c
++++ b/module/os/linux/zfs/zpl_ctldir.c
+@@ -101,12 +101,22 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
+  */
+ /* ARGSUSED */
+ static int
++#ifdef HAVE_USERNS_IOPS_GETATTR
++zpl_root_getattr_impl(struct user_namespace *user_ns,
++    const struct path *path, struct kstat *stat, u32 request_mask,
++    unsigned int query_flags)
++#else
+ zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
+     u32 request_mask, unsigned int query_flags)
++#endif
+ {
+ 	struct inode *ip = path->dentry->d_inode;
+ 
++#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
++	generic_fillattr(user_ns, ip, stat);
++#else
+ 	generic_fillattr(ip, stat);
++#endif
+ 	stat->atime = current_time(ip);
+ 
+ 	return (0);
+@@ -290,8 +300,14 @@ zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ #endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
+ 
+ static int
++#ifdef HAVE_IOPS_RENAME_USERNS
++zpl_snapdir_rename2(struct user_namespace *user_ns, struct inode *sdip,
++    struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
++    unsigned int flags)
++#else
+ zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
+     struct inode *tdip, struct dentry *tdentry, unsigned int flags)
++#endif
+ {
+ 	cred_t *cr = CRED();
+ 	int error;
+@@ -309,7 +325,7 @@ zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
+ 	return (error);
+ }
+ 
+-#ifndef HAVE_RENAME_WANTS_FLAGS
++#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
+ static int
+ zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
+     struct inode *tdip, struct dentry *tdentry)
+@@ -333,7 +349,12 @@ zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
+ }
+ 
+ static int
++#ifdef HAVE_IOPS_MKDIR_USERNS
++zpl_snapdir_mkdir(struct user_namespace *user_ns, struct inode *dip,
++    struct dentry *dentry, umode_t mode)
++#else
+ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
++#endif
+ {
+ 	cred_t *cr = CRED();
+ 	vattr_t *vap;
+@@ -363,14 +384,24 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
+  */
+ /* ARGSUSED */
+ static int
++#ifdef HAVE_USERNS_IOPS_GETATTR
++zpl_snapdir_getattr_impl(struct user_namespace *user_ns,
++    const struct path *path, struct kstat *stat, u32 request_mask,
++    unsigned int query_flags)
++#else
+ zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
+     u32 request_mask, unsigned int query_flags)
++#endif
+ {
+ 	struct inode *ip = path->dentry->d_inode;
+ 	zfsvfs_t *zfsvfs = ITOZSB(ip);
+ 
+ 	ZPL_ENTER(zfsvfs);
++#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
++	generic_fillattr(user_ns, ip, stat);
++#else
+ 	generic_fillattr(ip, stat);
++#endif
+ 
+ 	stat->nlink = stat->size = 2;
+ 	stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
+@@ -408,7 +439,7 @@ const struct file_operations zpl_fops_snapdir = {
+ const struct inode_operations zpl_ops_snapdir = {
+ 	.lookup		= zpl_snapdir_lookup,
+ 	.getattr	= zpl_snapdir_getattr,
+-#ifdef HAVE_RENAME_WANTS_FLAGS
++#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
+ 	.rename		= zpl_snapdir_rename2,
+ #else
+ 	.rename		= zpl_snapdir_rename,
+@@ -495,8 +526,14 @@ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ 
+ /* ARGSUSED */
+ static int
++#ifdef HAVE_USERNS_IOPS_GETATTR
++zpl_shares_getattr_impl(struct user_namespace *user_ns,
++    const struct path *path, struct kstat *stat, u32 request_mask,
++    unsigned int query_flags)
++#else
+ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
+     u32 request_mask, unsigned int query_flags)
++#endif
+ {
+ 	struct inode *ip = path->dentry->d_inode;
+ 	zfsvfs_t *zfsvfs = ITOZSB(ip);
+@@ -506,7 +543,11 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
+ 	ZPL_ENTER(zfsvfs);
+ 
+ 	if (zfsvfs->z_shares_dir == 0) {
++#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
++		generic_fillattr(user_ns, path->dentry->d_inode, stat);
++#else
+ 		generic_fillattr(path->dentry->d_inode, stat);
++#endif
+ 		stat->nlink = stat->size = 2;
+ 		stat->atime = current_time(ip);
+ 		ZPL_EXIT(zfsvfs);
+@@ -515,7 +556,11 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
+ 
+ 	error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
+ 	if (error == 0) {
+-		error = -zfs_getattr_fast(ZTOI(dzp), stat);
++#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
++		error = -zfs_getattr_fast(user_ns, ZTOI(dzp), stat);
++#else
++		error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat);
++#endif
+ 		iput(ZTOI(dzp));
+ 	}
+ 
+diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c
+index 80762f9669b..08bf97ff338 100644
+--- a/module/os/linux/zfs/zpl_file.c
++++ b/module/os/linux/zfs/zpl_file.c
+@@ -869,7 +869,7 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
+ 	    !capable(CAP_LINUX_IMMUTABLE))
+ 		return (-EACCES);
+ 
+-	if (!inode_owner_or_capable(ip))
++	if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
+ 		return (-EACCES);
+ 
+ 	xva_init(xva);
+diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c
+index f336fbb1272..364b9fbef24 100644
+--- a/module/os/linux/zfs/zpl_inode.c
++++ b/module/os/linux/zfs/zpl_inode.c
+@@ -128,7 +128,12 @@ zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr)
+ }
+ 
+ static int
++#ifdef HAVE_IOPS_CREATE_USERNS
++zpl_create(struct user_namespace *user_ns, struct inode *dir,
++    struct dentry *dentry, umode_t mode, bool flag)
++#else
+ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
++#endif
+ {
+ 	cred_t *cr = CRED();
+ 	znode_t *zp;
+@@ -163,7 +168,12 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
+ }
+ 
+ static int
++#ifdef HAVE_IOPS_MKNOD_USERNS
++zpl_mknod(struct user_namespace *user_ns, struct inode *dir,
++    struct dentry *dentry, umode_t mode,
++#else
+ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
++#endif
+     dev_t rdev)
+ {
+ 	cred_t *cr = CRED();
+@@ -278,7 +288,12 @@ zpl_unlink(struct inode *dir, struct dentry *dentry)
+ }
+ 
+ static int
++#ifdef HAVE_IOPS_MKDIR_USERNS
++zpl_mkdir(struct user_namespace *user_ns, struct inode *dir,
++    struct dentry *dentry, umode_t mode)
++#else
+ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
++#endif
+ {
+ 	cred_t *cr = CRED();
+ 	vattr_t *vap;
+@@ -338,8 +353,14 @@ zpl_rmdir(struct inode *dir, struct dentry *dentry)
+ }
+ 
+ static int
++#ifdef HAVE_USERNS_IOPS_GETATTR
++zpl_getattr_impl(struct user_namespace *user_ns,
++    const struct path *path, struct kstat *stat, u32 request_mask,
++    unsigned int query_flags)
++#else
+ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
+     unsigned int query_flags)
++#endif
+ {
+ 	int error;
+ 	fstrans_cookie_t cookie;
+@@ -350,7 +371,11 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
+ 	 * XXX request_mask and query_flags currently ignored.
+ 	 */
+ 
+-	error = -zfs_getattr_fast(path->dentry->d_inode, stat);
++#ifdef HAVE_USERNS_IOPS_GETATTR
++	error = -zfs_getattr_fast(user_ns, path->dentry->d_inode, stat);
++#else
++	error = -zfs_getattr_fast(kcred->user_ns, path->dentry->d_inode, stat);
++#endif
+ 	spl_fstrans_unmark(cookie);
+ 	ASSERT3S(error, <=, 0);
+ 
+@@ -359,7 +384,12 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
+ ZPL_GETATTR_WRAPPER(zpl_getattr);
+ 
+ static int
++#ifdef HAVE_SETATTR_PREPARE_USERNS
++zpl_setattr(struct user_namespace *user_ns, struct dentry *dentry,
++    struct iattr *ia)
++#else
+ zpl_setattr(struct dentry *dentry, struct iattr *ia)
++#endif
+ {
+ 	struct inode *ip = dentry->d_inode;
+ 	cred_t *cr = CRED();
+@@ -367,7 +397,7 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
+ 	int error;
+ 	fstrans_cookie_t cookie;
+ 
+-	error = setattr_prepare(dentry, ia);
++	error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
+ 	if (error)
+ 		return (error);
+ 
+@@ -399,8 +429,14 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
+ }
+ 
+ static int
++#ifdef HAVE_IOPS_RENAME_USERNS
++zpl_rename2(struct user_namespace *user_ns, struct inode *sdip,
++    struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
++    unsigned int flags)
++#else
+ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
+     struct inode *tdip, struct dentry *tdentry, unsigned int flags)
++#endif
+ {
+ 	cred_t *cr = CRED();
+ 	int error;
+@@ -421,7 +457,7 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
+ 	return (error);
+ }
+ 
+-#ifndef HAVE_RENAME_WANTS_FLAGS
++#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
+ static int
+ zpl_rename(struct inode *sdip, struct dentry *sdentry,
+     struct inode *tdip, struct dentry *tdentry)
+@@ -431,7 +467,12 @@ zpl_rename(struct inode *sdip, struct dentry *sdentry,
+ #endif
+ 
+ static int
++#ifdef HAVE_IOPS_SYMLINK_USERNS
++zpl_symlink(struct user_namespace *user_ns, struct inode *dir,
++    struct dentry *dentry, const char *name)
++#else
+ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
++#endif
+ {
+ 	cred_t *cr = CRED();
+ 	vattr_t *vap;
+@@ -677,7 +718,7 @@ const struct inode_operations zpl_dir_inode_operations = {
+ 	.mkdir		= zpl_mkdir,
+ 	.rmdir		= zpl_rmdir,
+ 	.mknod		= zpl_mknod,
+-#ifdef HAVE_RENAME_WANTS_FLAGS
++#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
+ 	.rename		= zpl_rename2,
+ #else
+ 	.rename		= zpl_rename,
+diff --git a/module/os/linux/zfs/zpl_xattr.c b/module/os/linux/zfs/zpl_xattr.c
+index 1ec3dae2bb8..5e35f90df85 100644
+--- a/module/os/linux/zfs/zpl_xattr.c
++++ b/module/os/linux/zfs/zpl_xattr.c
+@@ -1233,7 +1233,7 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
+ 	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
+ 		return (-EOPNOTSUPP);
+ 
+-	if (!inode_owner_or_capable(ip))
++	if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
+ 		return (-EPERM);
+ 
+ 	if (value) {
+@@ -1273,7 +1273,7 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name,
+ 	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
+ 		return (-EOPNOTSUPP);
+ 
+-	if (!inode_owner_or_capable(ip))
++	if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
+ 		return (-EPERM);
+ 
+ 	if (value) {

diff --git a/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_iov_iter_advance.patch b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_iov_iter_advance.patch
new file mode 100644
index 00000000000..95ecda34652
--- /dev/null
+++ b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_iov_iter_advance.patch
@@ -0,0 +1,40 @@
+From 3e0bc63e1b0ca03493b936e92e871ca7ae451a0a Mon Sep 17 00:00:00 2001
+From: Rich Ercolani <214141+rincebrain@users.noreply.github.com>
+Date: Tue, 1 Jun 2021 14:58:08 -0400
+Subject: [PATCH] Remove iov_iter_advance() for iter_write
+
+The additional iter advance is incorrect, as copy_from_iter() has
+already done the right thing.  This will result in the following
+warning being printed to the console as of the 5.12 kernel.
+
+    Attempted to advance past end of bvec iter
+
+This change should have been included with #11378 when a
+similar change was made on the read side.
+
+Suggested-by: @siebenmann
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
+Issue #11378
+Closes #12041
+Closes #12155
+(cherry picked from commit 3f81aba7668143c6ca6fc44983d4c880606dea8f)
+Signed-off-by: Jonathon Fernyhough <jonathon@m2x.dev>
+---
+ module/os/linux/zfs/zpl_file.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c
+index 08bf97ff338..e20c1dd413c 100644
+--- a/module/os/linux/zfs/zpl_file.c
++++ b/module/os/linux/zfs/zpl_file.c
+@@ -342,9 +342,6 @@ zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from)
+ 	ssize_t wrote = count - uio.uio_resid;
+ 	kiocb->ki_pos += wrote;
+ 
+-	if (wrote > 0)
+-		iov_iter_advance(from, wrote);
+-
+ 	return (wrote);
+ }
+ 

diff --git a/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_tmpfile.patch b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_tmpfile.patch
new file mode 100644
index 00000000000..08acee82148
--- /dev/null
+++ b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_tmpfile.patch
@@ -0,0 +1,89 @@
+From 6eced028dbbc2a44e32c4c0a76234ac2da9a365a Mon Sep 17 00:00:00 2001
+From: Rich Ercolani <214141+rincebrain@users.noreply.github.com>
+Date: Thu, 20 May 2021 19:02:36 -0400
+Subject: [PATCH] Update tmpfile() existence detection
+
+Linux changed the tmpfile() signature again in torvalds/linux@6521f89,
+which in turn broke our HAVE_TMPFILE detection in configure.
+
+Update that macro to include the new case, and change the signature of
+zpl_tmpfile as appropriate.
+
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
+Closes: #12060
+Closes: #12087
+---
+ config/kernel-tmpfile.m4        | 28 ++++++++++++++++++++++++----
+ module/os/linux/zfs/zpl_inode.c |  5 +++++
+ 2 files changed, 29 insertions(+), 4 deletions(-)
+
+diff --git a/config/kernel-tmpfile.m4 b/config/kernel-tmpfile.m4
+index f510bfe6ba0..45c2e6ceea5 100644
+--- a/config/kernel-tmpfile.m4
++++ b/config/kernel-tmpfile.m4
+@@ -3,23 +3,43 @@ dnl # 3.11 API change
+ dnl # Add support for i_op->tmpfile
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
+-	ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
++	dnl #
++	dnl # 5.11 API change
++	dnl # add support for userns parameter to tmpfile
++	dnl #
++	ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_userns], [
+ 		#include <linux/fs.h>
+-		int tmpfile(struct inode *inode, struct dentry *dentry,
++		int tmpfile(struct user_namespace *userns,
++		    struct inode *inode, struct dentry *dentry,
+ 		    umode_t mode) { return 0; }
+ 		static struct inode_operations
+ 		    iops __attribute__ ((unused)) = {
+ 			.tmpfile = tmpfile,
+ 		};
+ 	],[])
++	ZFS_LINUX_TEST_SRC([inode_operations_tmpfile], [
++			#include <linux/fs.h>
++			int tmpfile(struct inode *inode, struct dentry *dentry,
++			    umode_t mode) { return 0; }
++			static struct inode_operations
++			    iops __attribute__ ((unused)) = {
++				.tmpfile = tmpfile,
++			};
++	],[])
+ ])
+ 
+ AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
+ 	AC_MSG_CHECKING([whether i_op->tmpfile() exists])
+-	ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
++	ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_userns], [
+ 		AC_MSG_RESULT(yes)
+ 		AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
++		AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns])
+ 	],[
+-		AC_MSG_RESULT(no)
++		ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
++			AC_MSG_RESULT(yes)
++			AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
++		],[
++			AC_MSG_RESULT(no)
++		])
+ 	])
+ ])
+diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c
+index 364b9fbef24..ab0373ef9ba 100644
+--- a/module/os/linux/zfs/zpl_inode.c
++++ b/module/os/linux/zfs/zpl_inode.c
+@@ -218,7 +218,12 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
+ 
+ #ifdef HAVE_TMPFILE
+ static int
++#ifdef HAVE_TMPFILE_USERNS
++zpl_tmpfile(struct user_namespace *userns, struct inode *dir,
++    struct dentry *dentry, umode_t mode)
++#else
+ zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
++#endif
+ {
+ 	cred_t *cr = CRED();
+ 	struct inode *ip;

diff --git a/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_userns.patch b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_userns.patch
new file mode 100644
index 00000000000..1d8530ec8c6
--- /dev/null
+++ b/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_userns.patch
@@ -0,0 +1,173 @@
+From b3f8b103cb3a4bbb7ad41f6faf630be7baa4f585 Mon Sep 17 00:00:00 2001
+From: Rich Ercolani <214141+rincebrain@users.noreply.github.com>
+Date: Thu, 27 May 2021 11:55:49 -0400
+Subject: [PATCH] Bend zpl_set_acl to permit the new userns* parameter
+
+Just like #12087, the set_acl signature changed with all the bolted-on
+*userns parameters, which disabled set_acl usage, and caused #12076.
+
+Turn zpl_set_acl into zpl_set_acl and zpl_set_acl_impl, and add a
+new configure test for the new version.
+
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
+Closes #12076
+Closes #12093
+---
+ config/kernel-acl.m4            | 25 +++++++++++++++++++++--
+ include/os/linux/zfs/sys/zpl.h  |  5 +++++
+ module/os/linux/zfs/zpl_xattr.c | 35 ++++++++++++++++++++++-----------
+ 3 files changed, 51 insertions(+), 14 deletions(-)
+
+diff --git a/config/kernel-acl.m4 b/config/kernel-acl.m4
+index e02ce665323..c6da4df24eb 100644
+--- a/config/kernel-acl.m4
++++ b/config/kernel-acl.m4
+@@ -189,7 +189,22 @@ dnl #
+ dnl # 3.14 API change,
+ dnl # Check if inode_operations contains the function set_acl
+ dnl #
++dnl # 5.12 API change,
++dnl # set_acl() added a user_namespace* parameter first
++dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
++	ZFS_LINUX_TEST_SRC([inode_operations_set_acl_userns], [
++		#include <linux/fs.h>
++
++		int set_acl_fn(struct user_namespace *userns,
++		    struct inode *inode, struct posix_acl *acl,
++		    int type) { return 0; }
++
++		static const struct inode_operations
++		    iops __attribute__ ((unused)) = {
++			.set_acl = set_acl_fn,
++		};
++	],[])
+ 	ZFS_LINUX_TEST_SRC([inode_operations_set_acl], [
+ 		#include <linux/fs.h>
+ 
+@@ -205,11 +220,17 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
+ 
+ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
+ 	AC_MSG_CHECKING([whether iops->set_acl() exists])
+-	ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
++	ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns], [
+ 		AC_MSG_RESULT(yes)
+ 		AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
++		AC_DEFINE(HAVE_SET_ACL_USERNS, 1, [iops->set_acl() takes 4 args])
+ 	],[
+-		AC_MSG_RESULT(no)
++		ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
++			AC_MSG_RESULT(yes)
++			AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args])
++		],[
++			AC_MSG_RESULT(no)
++		])
+ 	])
+ ])
+ 
+diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h
+index 21825d1f378..54f3fa0fdb0 100644
+--- a/include/os/linux/zfs/sys/zpl.h
++++ b/include/os/linux/zfs/sys/zpl.h
+@@ -63,7 +63,12 @@ extern int zpl_xattr_security_init(struct inode *ip, struct inode *dip,
+     const struct qstr *qstr);
+ #if defined(CONFIG_FS_POSIX_ACL)
+ #if defined(HAVE_SET_ACL)
++#if defined(HAVE_SET_ACL_USERNS)
++extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip,
++    struct posix_acl *acl, int type);
++#else
+ extern int zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type);
++#endif /* HAVE_SET_ACL_USERNS */
+ #endif /* HAVE_SET_ACL */
+ extern struct posix_acl *zpl_get_acl(struct inode *ip, int type);
+ extern int zpl_init_acl(struct inode *ip, struct inode *dir);
+diff --git a/module/os/linux/zfs/zpl_xattr.c b/module/os/linux/zfs/zpl_xattr.c
+index 5e35f90df85..89ba9de14f6 100644
+--- a/module/os/linux/zfs/zpl_xattr.c
++++ b/module/os/linux/zfs/zpl_xattr.c
+@@ -926,11 +926,8 @@ xattr_handler_t zpl_xattr_security_handler = {
+  * attribute implemented by filesystems in the kernel." - xattr(7)
+  */
+ #ifdef CONFIG_FS_POSIX_ACL
+-#ifndef HAVE_SET_ACL
+-static
+-#endif
+-int
+-zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type)
++static int
++zpl_set_acl_impl(struct inode *ip, struct posix_acl *acl, int type)
+ {
+ 	char *name, *value = NULL;
+ 	int error = 0;
+@@ -1002,6 +999,19 @@ zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type)
+ 	return (error);
+ }
+ 
++#ifdef HAVE_SET_ACL
++int
++#ifdef HAVE_SET_ACL_USERNS
++zpl_set_acl(struct user_namespace *userns, struct inode *ip,
++    struct posix_acl *acl, int type)
++#else
++zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type)
++#endif /* HAVE_SET_ACL_USERNS */
++{
++	return (zpl_set_acl_impl(ip, acl, type));
++}
++#endif /* HAVE_SET_ACL */
++
+ struct posix_acl *
+ zpl_get_acl(struct inode *ip, int type)
+ {
+@@ -1083,7 +1093,7 @@ zpl_init_acl(struct inode *ip, struct inode *dir)
+ 		umode_t mode;
+ 
+ 		if (S_ISDIR(ip->i_mode)) {
+-			error = zpl_set_acl(ip, acl, ACL_TYPE_DEFAULT);
++			error = zpl_set_acl_impl(ip, acl, ACL_TYPE_DEFAULT);
+ 			if (error)
+ 				goto out;
+ 		}
+@@ -1093,8 +1103,10 @@ zpl_init_acl(struct inode *ip, struct inode *dir)
+ 		if (error >= 0) {
+ 			ip->i_mode = mode;
+ 			zfs_mark_inode_dirty(ip);
+-			if (error > 0)
+-				error = zpl_set_acl(ip, acl, ACL_TYPE_ACCESS);
++			if (error > 0) {
++				error = zpl_set_acl_impl(ip, acl,
++				    ACL_TYPE_ACCESS);
++			}
+ 		}
+ 	}
+ out:
+@@ -1121,7 +1133,7 @@ zpl_chmod_acl(struct inode *ip)
+ 
+ 	error = __posix_acl_chmod(&acl, GFP_KERNEL, ip->i_mode);
+ 	if (!error)
+-		error = zpl_set_acl(ip, acl, ACL_TYPE_ACCESS);
++		error = zpl_set_acl_impl(ip, acl, ACL_TYPE_ACCESS);
+ 
+ 	zpl_posix_acl_release(acl);
+ 
+@@ -1250,8 +1262,7 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
+ 	} else {
+ 		acl = NULL;
+ 	}
+-
+-	error = zpl_set_acl(ip, acl, type);
++	error = zpl_set_acl_impl(ip, acl, type);
+ 	zpl_posix_acl_release(acl);
+ 
+ 	return (error);
+@@ -1291,7 +1302,7 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name,
+ 		acl = NULL;
+ 	}
+ 
+-	error = zpl_set_acl(ip, acl, type);
++	error = zpl_set_acl_impl(ip, acl, type);
+ 	zpl_posix_acl_release(acl);
+ 
+ 	return (error);

diff --git a/sys-fs/zfs-kmod/files/zfs-8.0.4_spl_kmem_cache_slab_limit_16K.patch b/sys-fs/zfs-kmod/files/zfs-8.0.4_spl_kmem_cache_slab_limit_16K.patch
new file mode 100644
index 00000000000..3448f76a801
--- /dev/null
+++ b/sys-fs/zfs-kmod/files/zfs-8.0.4_spl_kmem_cache_slab_limit_16K.patch
@@ -0,0 +1,59 @@
+From 783784582225e8ddfbf07993d9fc278bf08025c5 Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1@llnl.gov>
+Date: Thu, 3 Jun 2021 13:37:45 -0700
+Subject: [PATCH] Linux: Set spl_kmem_cache_slab_limit when page size !4K
+
+For small objects the kernel's slab implementation is very fast and
+space efficient. However, as the allocation size increases to
+require multiple pages performance suffers. The SPL kmem cache
+allocator was designed to better handle these large allocation
+sizes. Therefore, on Linux the kmem_cache_* compatibility wrappers
+prefer to use the kernel's slab allocator for small objects and
+the custom SPL kmem cache allocator for larger objects.
+
+This logic was effectively disabled for all architectures using
+a non-4K page size which caused all kmem caches to only use the
+SPL implementation. Functionally this is fine, but the SPL code
+which calculates the target number of objects per-slab does not
+take in to account that __vmalloc() always returns page-aligned
+memory. This can result in a massive amount of wasted space when
+allocating tiny objects on a platform using large pages (64k).
+
+To resolve this issue we set the spl_kmem_cache_slab_limit cutoff
+to 16K for all architectures.
+
+This particular change does not attempt to update the logic used
+to calculate the optimal number of pages per slab. This remains
+an issue which should be addressed in a future change.
+
+Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
+Reviewed-by: Tony Nguyen <tony.nguyen@delphix.com>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #12152
+Closes #11429
+Closes #11574
+Closes #12150
+---
+ module/os/linux/spl/spl-kmem-cache.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/module/os/linux/spl/spl-kmem-cache.c b/module/os/linux/spl/spl-kmem-cache.c
+index 3699b6a159a..2151ef008fd 100644
+--- a/module/os/linux/spl/spl-kmem-cache.c
++++ b/module/os/linux/spl/spl-kmem-cache.c
+@@ -100,13 +100,10 @@ MODULE_PARM_DESC(spl_kmem_cache_max_size, "Maximum size of slab in MB");
+  * For small objects the Linux slab allocator should be used to make the most
+  * efficient use of the memory.  However, large objects are not supported by
+  * the Linux slab and therefore the SPL implementation is preferred.  A cutoff
+- * of 16K was determined to be optimal for architectures using 4K pages.
++ * of 16K was determined to be optimal for architectures using 4K pages and
++ * to also work well on architecutres using larger 64K page sizes.
+  */
+-#if PAGE_SIZE == 4096
+ unsigned int spl_kmem_cache_slab_limit = 16384;
+-#else
+-unsigned int spl_kmem_cache_slab_limit = 0;
+-#endif
+ module_param(spl_kmem_cache_slab_limit, uint, 0644);
+ MODULE_PARM_DESC(spl_kmem_cache_slab_limit,
+ 	"Objects less than N bytes use the Linux slab");

diff --git a/sys-fs/zfs-kmod/files/zfs-8.0.4_stream_resume.patch b/sys-fs/zfs-kmod/files/zfs-8.0.4_stream_resume.patch
new file mode 100644
index 00000000000..196fab65f4a
--- /dev/null
+++ b/sys-fs/zfs-kmod/files/zfs-8.0.4_stream_resume.patch
@@ -0,0 +1,33 @@
+From ee2a9d2c771657168652e058477b81389c662b5e Mon Sep 17 00:00:00 2001
+From: Paul Zuchowski <31706010+PaulZ-98@users.noreply.github.com>
+Date: Fri, 14 May 2021 00:46:14 -0400
+Subject: [PATCH] Fix dmu_recv_stream test for resumable
+
+Use dsl_dataset_has_resume_receive_state()
+not dsl_dataset_is_zapified() to check if
+stream is resumable.
+
+Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
+Reviewed-by: Alek Pinchuk <apinchuk@axcient.com>
+Reviewed-by: Ryan Moeller <ryan@ixsystems.com>
+Signed-off-by: Paul Zuchowski <pzuchowski@datto.com>
+Closes #12034
+---
+ module/zfs/dmu_recv.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/module/zfs/dmu_recv.c b/module/zfs/dmu_recv.c
+index b5414749f7f..f44b397853f 100644
+--- a/module/zfs/dmu_recv.c
++++ b/module/zfs/dmu_recv.c
+@@ -2878,8 +2878,8 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
+ 	int err = 0;
+ 	struct receive_writer_arg *rwa = kmem_zalloc(sizeof (*rwa), KM_SLEEP);
+ 
+-	if (dsl_dataset_is_zapified(drc->drc_ds)) {
+-		uint64_t bytes;
++	if (dsl_dataset_has_resume_receive_state(drc->drc_ds)) {
++		uint64_t bytes = 0;
+ 		(void) zap_lookup(drc->drc_ds->ds_dir->dd_pool->dp_meta_objset,
+ 		    drc->drc_ds->ds_object, DS_FIELD_RESUME_BYTES,
+ 		    sizeof (bytes), 1, &bytes);

diff --git a/sys-fs/zfs-kmod/zfs-kmod-2.0.4-r1.ebuild b/sys-fs/zfs-kmod/zfs-kmod-2.0.4-r1.ebuild
new file mode 100644
index 00000000000..505ae6384ef
--- /dev/null
+++ b/sys-fs/zfs-kmod/zfs-kmod-2.0.4-r1.ebuild
@@ -0,0 +1,186 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit autotools dist-kernel-utils flag-o-matic linux-mod toolchain-funcs
+
+DESCRIPTION="Linux ZFS kernel module for sys-fs/zfs"
+HOMEPAGE="https://github.com/openzfs/zfs"
+
+if [[ ${PV} == "9999" ]]; then
+	inherit git-r3
+	EGIT_REPO_URI="https://github.com/openzfs/zfs.git"
+else
+	MY_PV="${PV/_rc/-rc}"
+	SRC_URI="https://github.com/openzfs/zfs/releases/download/zfs-${MY_PV}/zfs-${MY_PV}.tar.gz"
+	KEYWORDS="~amd64 ~arm64 ~ppc64"
+	S="${WORKDIR}/zfs-${PV%_rc?}"
+	ZFS_KERNEL_COMPAT="5.12"
+fi
+
+LICENSE="CDDL MIT debug? ( GPL-2+ )"
+SLOT="0"
+IUSE="custom-cflags debug +rootfs"
+
+DEPEND=""
+
+RDEPEND="${DEPEND}
+	!sys-kernel/spl
+"
+
+BDEPEND="
+	dev-lang/perl
+	virtual/awk
+"
+
+RESTRICT="debug? ( strip ) test"
+
+DOCS=( AUTHORS COPYRIGHT META README.md )
+
+PATCHES=(
+	"${FILESDIR}"/zfs-8.0.4_5.12_compat_idmapped_mounts.patch
+	"${FILESDIR}"/zfs-8.0.4_5.12_compat_bio_max_segs.patch
+	"${FILESDIR}"/zfs-8.0.4_5.12_compat_tmpfile.patch
+	"${FILESDIR}"/zfs-8.0.4_5.12_compat_userns.patch
+	"${FILESDIR}"/zfs-8.0.4_5.12_compat_iov_iter_advance.patch
+	"${FILESDIR}"/zfs-8.0.4_stream_resume.patch
+	"${FILESDIR}"/zfs-8.0.4_spl_kmem_cache_slab_limit_16K.patch
+)
+
+pkg_setup() {
+	CONFIG_CHECK="
+		!DEBUG_LOCK_ALLOC
+		EFI_PARTITION
+		MODULES
+		!PAX_KERNEXEC_PLUGIN_METHOD_OR
+		!TRIM_UNUSED_KSYMS
+		ZLIB_DEFLATE
+		ZLIB_INFLATE
+	"
+
+	use debug && CONFIG_CHECK="${CONFIG_CHECK}
+		FRAME_POINTER
+		DEBUG_INFO
+		!DEBUG_INFO_REDUCED
+	"
+
+	use rootfs && \
+		CONFIG_CHECK="${CONFIG_CHECK}
+			BLK_DEV_INITRD
+			DEVTMPFS
+	"
+
+	kernel_is -lt 5 && CONFIG_CHECK="${CONFIG_CHECK} IOSCHED_NOOP"
+
+	if [[ ${PV} != "9999" ]]; then
+		local kv_major_max kv_minor_max zcompat
+		zcompat="${ZFS_KERNEL_COMPAT_OVERRIDE:-${ZFS_KERNEL_COMPAT}}"
+		kv_major_max="${zcompat%%.*}"
+		zcompat="${zcompat#*.}"
+		kv_minor_max="${zcompat%%.*}"
+		kernel_is -le "${kv_major_max}" "${kv_minor_max}" || die \
+			"Linux ${kv_major_max}.${kv_minor_max} is the latest supported version"
+
+	fi
+
+	kernel_is -ge 3 10 || die "Linux 3.10 or newer required"
+
+	linux-mod_pkg_setup
+}
+
+src_prepare() {
+	default
+	eautoreconf
+	# Set module revision number
+	sed -i "s/\(Release:\)\(.*\)1/\1\2${PR}-gentoo/" META || die "Could not set Gentoo release"
+}
+
+src_configure() {
+	set_arch_to_kernel
+
+	use custom-cflags || strip-flags
+
+	filter-ldflags -Wl,*
+
+	local myconf=(
+		CROSS_COMPILE="${CHOST}-"
+		HOSTCC="$(tc-getBUILD_CC)"
+		--bindir="${EPREFIX}/bin"
+		--sbindir="${EPREFIX}/sbin"
+		--with-config=kernel
+		--with-linux="${KV_DIR}"
+		--with-linux-obj="${KV_OUT_DIR}"
+		$(use_enable debug)
+	)
+
+	econf "${myconf[@]}"
+}
+
+src_compile() {
+	set_arch_to_kernel
+
+	myemakeargs=(
+		CROSS_COMPILE="${CHOST}-"
+		HOSTCC="$(tc-getBUILD_CC)"
+		V=1
+	)
+
+	emake "${myemakeargs[@]}"
+}
+
+src_install() {
+	set_arch_to_kernel
+
+	myemakeargs+=(
+		DEPMOD=:
+		DESTDIR="${D}"
+		INSTALL_MOD_PATH="${EPREFIX:-/}" # lib/modules/<kver> added by KBUILD
+	)
+
+	emake "${myemakeargs[@]}" install
+
+	einstalldocs
+}
+
+pkg_postinst() {
+	linux-mod_pkg_postinst
+
+	# Remove old modules
+	if [[ -d "${EROOT}/lib/modules/${KV_FULL}/addon/zfs" ]]; then
+		ewarn "${PN} now installs modules in ${EROOT}/lib/modules/${KV_FULL}/extra/zfs"
+		ewarn "Old modules were detected in ${EROOT}/lib/modules/${KV_FULL}/addon/zfs"
+		ewarn "Automatically removing old modules to avoid problems."
+		rm -r "${EROOT}/lib/modules/${KV_FULL}/addon/zfs" || die "Cannot remove modules"
+		rmdir --ignore-fail-on-non-empty "${EROOT}/lib/modules/${KV_FULL}/addon"
+	fi
+
+	if [[ -z ${ROOT} ]] && use dist-kernel; then
+		set_arch_to_portage
+		dist-kernel_reinstall_initramfs "${KV_DIR}" "${KV_FULL}"
+	fi
+
+	if use x86 || use arm; then
+		ewarn "32-bit kernels will likely require increasing vmalloc to"
+		ewarn "at least 256M and decreasing zfs_arc_max to some value less than that."
+	fi
+
+	ewarn "This version of OpenZFS includes support for new feature flags"
+	ewarn "that are incompatible with previous versions. GRUB2 support for"
+	ewarn "/boot with the new feature flags is not yet available."
+	ewarn "Do *NOT* upgrade root pools to use the new feature flags."
+	ewarn "Any new pools will be created with the new feature flags by default"
+	ewarn "and will not be compatible with older versions of ZFSOnLinux. To"
+	ewarn "create a newpool that is backward compatible wih GRUB2, use "
+	ewarn
+	ewarn "zpool create -d -o feature@async_destroy=enabled "
+	ewarn "	-o feature@empty_bpobj=enabled -o feature@lz4_compress=enabled"
+	ewarn "	-o feature@spacemap_histogram=enabled"
+	ewarn "	-o feature@enabled_txg=enabled "
+	ewarn "	-o feature@extensible_dataset=enabled -o feature@bookmarks=enabled"
+	ewarn "	..."
+	ewarn
+	ewarn "GRUB2 support will be updated as soon as either the GRUB2"
+	ewarn "developers do a tag or the Gentoo developers find time to backport"
+	ewarn "support from GRUB2 HEAD."
+}


             reply	other threads:[~2021-06-04  2:14 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-04  2:14 Georgy Yakovlev [this message]
  -- strict thread matches above, loose matches on Subject: below --
2025-09-13  9:02 [gentoo-commits] repo/gentoo:master commit in: sys-fs/zfs-kmod/, sys-fs/zfs-kmod/files/ Sam James
2024-10-05  6:16 Sam James
2024-02-06  1:50 Sam James
2024-01-29 16:08 Sam James
2023-12-28  3:43 Sam James
2023-11-24 21:53 Sam James
2023-07-03 21:03 Sam James
2023-05-30  2:51 Sam James
2022-10-04  5:07 Sam James
2022-09-17 22:16 Georgy Yakovlev
2022-03-22 18:01 Sam James
2021-12-20  5:19 Georgy Yakovlev
2021-11-11  2:22 Georgy Yakovlev
2021-11-07 23:59 Georgy Yakovlev
2021-07-02  8:31 Georgy Yakovlev
2021-06-09  5:20 Georgy Yakovlev
2020-12-18 20:04 Georgy Yakovlev
2020-09-21 23:04 Georgy Yakovlev
2020-09-07  4:04 Georgy Yakovlev
2020-03-30 21:08 Georgy Yakovlev
2019-05-29 22:15 Georgy Yakovlev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1622769913.919f0c385d58501b3b1aa32543ff3772aea483ee.gyakovlev@gentoo \
    --to=gyakovlev@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox