From: sgn <sgn@users.noreply.github.com>
To: ml@inbox.vuxu.org
Subject: [PR PATCH] zfs: patch for linux-6.3
Date: Thu, 25 May 2023 04:33:27 +0200 [thread overview]
Message-ID: <gh-mailinglist-notifications-41a7ca26-5023-4802-975b-f1789d68868e-void-packages-44073@inbox.vuxu.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 1294 bytes --]
There is a new pull request by sgn against master on the void-packages repository
https://github.com/sgn/void-packages zfs-linux-6.3
https://github.com/void-linux/void-packages/pull/44073
zfs: patch for linux-6.3
The last two patches was modified heavily from upstream.
<!-- Uncomment relevant sections and delete options which are not applicable -->
#### Testing the changes
- I tested the changes in this PR: **YES**
<!--
#### New package
- This new package conforms to the [package requirements](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#package-requirements): **YES**|**NO**
-->
<!-- Note: If the build is likely to take more than 2 hours, please add ci skip tag as described in
https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#continuous-integration
and test at least one native build and, if supported, at least one cross build.
Ignore this section if this PR is not skipping CI.
-->
<!--
#### Local build testing
- I built this PR locally for my native architecture, (ARCH-LIBC)
- I built this PR locally for these architectures (if supported. mark crossbuilds):
- aarch64-musl
- armv7l
- armv6l-musl
-->
A patch file from https://github.com/void-linux/void-packages/pull/44073.patch is attached
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-zfs-linux-6.3-44073.patch --]
[-- Type: text/x-diff, Size: 64017 bytes --]
From a54abec3b856037251d265d447572b96e1b2803e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=
<congdanhqx@gmail.com>
Date: Sun, 21 May 2023 18:06:18 +0700
Subject: [PATCH] zfs: patch for linux-6.3
The last two patches was modified heavily from upstream.
---
...t-writepage_t-first-arg-struct-folio.patch | 130 ++
...-Fix-memcpy-detected-field-spanning-.patch | 50 +
....3-compat-idmapped-mount-API-changes.patch | 1493 +++++++++++++++++
srcpkgs/zfs/template | 2 +-
4 files changed, 1674 insertions(+), 1 deletion(-)
create mode 100644 srcpkgs/zfs/patches/0003-Linux-6.3-compat-writepage_t-first-arg-struct-folio.patch
create mode 100644 srcpkgs/zfs/patches/0004-Linux-6.3-compat-Fix-memcpy-detected-field-spanning-.patch
create mode 100644 srcpkgs/zfs/patches/0005-Linux-6.3-compat-idmapped-mount-API-changes.patch
diff --git a/srcpkgs/zfs/patches/0003-Linux-6.3-compat-writepage_t-first-arg-struct-folio.patch b/srcpkgs/zfs/patches/0003-Linux-6.3-compat-writepage_t-first-arg-struct-folio.patch
new file mode 100644
index 000000000000..3bdd26d009e5
--- /dev/null
+++ b/srcpkgs/zfs/patches/0003-Linux-6.3-compat-writepage_t-first-arg-struct-folio.patch
@@ -0,0 +1,130 @@
+From 81c5dcc1a944decba3353b8832c339166cbb1b37 Mon Sep 17 00:00:00 2001
+From: youzhongyang <youzhong@gmail.com>
+Date: Wed, 5 Apr 2023 13:01:38 -0400
+Subject: [PATCH 3/5] Linux 6.3 compat: writepage_t first arg struct folio*
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The type def of writepage_t in kernel 6.3 is changed to take
+struct folio* as the first argument. We need to detect this
+change and pass correct function to write_cache_pages().
+
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Reviewed-by: Brian Atkinson <batkinson@lanl.gov>
+Signed-off-by: Youzhong Yang <yyang@mathworks.com>
+Closes #14699
+
+Modified-from: 8eb2f2605717572d92041534a0556d6d75c47d99
+Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
+---
+ config/kernel-writepage_t.m4 | 26 ++++++++++++++++++++++++++
+ config/kernel.m4 | 2 ++
+ module/os/linux/zfs/zpl_file.c | 27 +++++++++++++++++++++++++--
+ 3 files changed, 53 insertions(+), 2 deletions(-)
+ create mode 100644 config/kernel-writepage_t.m4
+
+diff --git a/config/kernel-writepage_t.m4 b/config/kernel-writepage_t.m4
+new file mode 100644
+index 000000000..3a0cffd98
+--- /dev/null
++++ b/config/kernel-writepage_t.m4
+@@ -0,0 +1,26 @@
++AC_DEFUN([ZFS_AC_KERNEL_SRC_WRITEPAGE_T], [
++ dnl #
++ dnl # 6.3 API change
++ dnl # The writepage_t function type now has its first argument as
++ dnl # struct folio* instead of struct page*
++ dnl #
++ ZFS_LINUX_TEST_SRC([writepage_t_folio], [
++ #include <linux/writeback.h>
++ int putpage(struct folio *folio,
++ struct writeback_control *wbc, void *data)
++ { return 0; }
++ writepage_t func = putpage;
++ ],[])
++])
++
++AC_DEFUN([ZFS_AC_KERNEL_WRITEPAGE_T], [
++ AC_MSG_CHECKING([whether int (*writepage_t)() takes struct folio*])
++ ZFS_LINUX_TEST_RESULT([writepage_t_folio], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_WRITEPAGE_T_FOLIO, 1,
++ [int (*writepage_t)() takes struct folio*])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
++])
++
+diff --git a/config/kernel.m4 b/config/kernel.m4
+index 7806da7a8..f6743acac 100644
+--- a/config/kernel.m4
++++ b/config/kernel.m4
+@@ -144,6 +144,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
+ ZFS_AC_KERNEL_SRC_KTHREAD
+ ZFS_AC_KERNEL_SRC_ZERO_PAGE
+ ZFS_AC_KERNEL_SRC___COPY_FROM_USER_INATOMIC
++ ZFS_AC_KERNEL_SRC_WRITEPAGE_T
+
+ AC_MSG_CHECKING([for available kernel interfaces])
+ ZFS_LINUX_TEST_COMPILE_ALL([kabi])
+@@ -261,6 +262,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
+ ZFS_AC_KERNEL_KTHREAD
+ ZFS_AC_KERNEL_ZERO_PAGE
+ ZFS_AC_KERNEL___COPY_FROM_USER_INATOMIC
++ ZFS_AC_KERNEL_WRITEPAGE_T
+ ])
+
+ dnl #
+diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c
+index 38d2bd147..25030cb2d 100644
+--- a/module/os/linux/zfs/zpl_file.c
++++ b/module/os/linux/zfs/zpl_file.c
+@@ -701,6 +701,29 @@ zpl_putpage(struct page *pp, struct writeback_control *wbc, void *data)
+ return (0);
+ }
+
++#ifdef HAVE_WRITEPAGE_T_FOLIO
++static int
++zpl_putfolio(struct folio *pp, struct writeback_control *wbc, void *data)
++{
++ (void) zpl_putpage(&pp->page, wbc, data);
++ return (0);
++}
++#endif
++
++static inline int
++zpl_write_cache_pages(struct address_space *mapping,
++ struct writeback_control *wbc, void *data)
++{
++ int result;
++
++#ifdef HAVE_WRITEPAGE_T_FOLIO
++ result = write_cache_pages(mapping, wbc, zpl_putfolio, data);
++#else
++ result = write_cache_pages(mapping, wbc, zpl_putpage, data);
++#endif
++ return (result);
++}
++
+ static int
+ zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
+ {
+@@ -723,7 +746,7 @@ zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
+ * and then we commit it all in one go.
+ */
+ wbc->sync_mode = WB_SYNC_NONE;
+- result = write_cache_pages(mapping, wbc, zpl_putpage, mapping);
++ result = zpl_write_cache_pages(mapping, wbc, mapping);
+ if (sync_mode != wbc->sync_mode) {
+ ZPL_ENTER(zfsvfs);
+ ZPL_VERIFY_ZP(zp);
+@@ -739,7 +762,7 @@ zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
+ * details). That being said, this is a no-op in most cases.
+ */
+ wbc->sync_mode = sync_mode;
+- result = write_cache_pages(mapping, wbc, zpl_putpage, mapping);
++ result = zpl_write_cache_pages(mapping, wbc, mapping);
+ }
+ return (result);
+ }
diff --git a/srcpkgs/zfs/patches/0004-Linux-6.3-compat-Fix-memcpy-detected-field-spanning-.patch b/srcpkgs/zfs/patches/0004-Linux-6.3-compat-Fix-memcpy-detected-field-spanning-.patch
new file mode 100644
index 000000000000..9464330d5d12
--- /dev/null
+++ b/srcpkgs/zfs/patches/0004-Linux-6.3-compat-Fix-memcpy-detected-field-spanning-.patch
@@ -0,0 +1,50 @@
+From e5cdfea701c3261867760c2059583001cd69dcdf Mon Sep 17 00:00:00 2001
+From: youzhongyang <youzhong@gmail.com>
+Date: Thu, 13 Apr 2023 12:12:03 -0400
+Subject: [PATCH 4/5] Linux 6.3 compat: Fix memcpy "detected field-spanning
+ write" error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a new union member of flexible array to dnode_phys_t and use
+it in the macro so we can silence the memcpy() fortify error.
+
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Youzhong Yang <yyang@mathworks.com>
+Closes #14737
+
+Modified-from: 27a82cbb3ef2e30a54860b955fb257fb7f8307cd
+Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
+---
+ include/sys/dnode.h | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/include/sys/dnode.h b/include/sys/dnode.h
+index 20b7c2aaf..39bbdae44 100644
+--- a/include/sys/dnode.h
++++ b/include/sys/dnode.h
+@@ -120,7 +120,11 @@ extern "C" {
+ #define DN_MAX_LEVELS (DIV_ROUND_UP(DN_MAX_OFFSET_SHIFT - SPA_MINBLOCKSHIFT, \
+ DN_MIN_INDBLKSHIFT - SPA_BLKPTRSHIFT) + 1)
+
+-#define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus + \
++/*
++ * Use the flexible array instead of the fixed length one dn_bonus
++ * to address memcpy/memmove fortify error
++ */
++#define DN_BONUS(dnp) ((void*)((dnp)->dn_bonus_flexible + \
+ (((dnp)->dn_nblkptr - 1) * sizeof (blkptr_t))))
+ #define DN_MAX_BONUS_LEN(dnp) \
+ ((dnp->dn_flags & DNODE_FLAG_SPILL_BLKPTR) ? \
+@@ -266,6 +270,10 @@ typedef struct dnode_phys {
+ sizeof (blkptr_t)];
+ blkptr_t dn_spill;
+ };
++ struct {
++ blkptr_t __dn_ignore4;
++ uint8_t dn_bonus_flexible[];
++ };
+ };
+ } dnode_phys_t;
+
diff --git a/srcpkgs/zfs/patches/0005-Linux-6.3-compat-idmapped-mount-API-changes.patch b/srcpkgs/zfs/patches/0005-Linux-6.3-compat-idmapped-mount-API-changes.patch
new file mode 100644
index 000000000000..22fa1e4baa10
--- /dev/null
+++ b/srcpkgs/zfs/patches/0005-Linux-6.3-compat-idmapped-mount-API-changes.patch
@@ -0,0 +1,1493 @@
+From 5a54c5cdc920b25f573651bc5001ae9c2887da3a Mon Sep 17 00:00:00 2001
+From: youzhongyang <youzhong@gmail.com>
+Date: Mon, 10 Apr 2023 17:15:36 -0400
+Subject: [PATCH 5/5] Linux 6.3 compat: idmapped mount API changes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Linux kernel 6.3 changed a bunch of APIs to use the dedicated idmap
+type for mounts (struct mnt_idmap), we need to detect these changes
+and make zfs work with the new APIs.
+
+Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Signed-off-by: Youzhong Yang <yyang@mathworks.com>
+Closes #14682
+
+Modified-from: d4dc53dad2f6c3a2d107f1ba0e8d66228c845e00
+Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>
+---
+ config/kernel-acl.m4 | 34 ++++++--
+ config/kernel-generic_fillattr.m4 | 33 +++++--
+ config/kernel-inode-create.m4 | 41 +++++++--
+ config/kernel-inode-getattr.m4 | 63 ++++++++++----
+ config/kernel-is_owner_or_cap.m4 | 25 +++++-
+ config/kernel-mkdir.m4 | 55 +++++++++---
+ config/kernel-mknod.m4 | 34 +++++++-
+ config/kernel-rename.m4 | 59 ++++++++++---
+ config/kernel-setattr-prepare.m4 | 44 +++++++---
+ config/kernel-symlink.m4 | 33 +++++--
+ config/kernel-tmpfile.m4 | 33 +++++--
+ config/kernel-xattr-handler.m4 | 91 +++++++++++++-------
+ config/kernel.m4 | 4 +-
+ include/os/freebsd/spl/sys/types.h | 2 +
+ include/os/linux/kernel/linux/vfs_compat.h | 21 ++++-
+ include/os/linux/kernel/linux/xattr_compat.h | 17 +++-
+ include/os/linux/spl/sys/cred.h | 2 +
+ include/os/linux/spl/sys/types.h | 16 ++++
+ include/os/linux/zfs/sys/zfs_vnops_os.h | 5 ++
+ include/os/linux/zfs/sys/zpl.h | 11 ++-
+ module/os/linux/spl/spl-cred.c | 12 +++
+ module/os/linux/zfs/policy.c | 4 +
+ module/os/linux/zfs/zfs_ioctl_os.c | 4 +
+ module/os/linux/zfs/zfs_vnops_os.c | 5 ++
+ module/os/linux/zfs/zpl_ctldir.c | 57 ++++++++++--
+ module/os/linux/zfs/zpl_file.c | 4 +
+ module/os/linux/zfs/zpl_inode.c | 40 ++++++++-
+ module/os/linux/zfs/zpl_xattr.c | 13 +++
+ 28 files changed, 619 insertions(+), 143 deletions(-)
+
+diff --git a/config/kernel-acl.m4 b/config/kernel-acl.m4
+index 6e92da97d..be08c3c60 100644
+--- a/config/kernel-acl.m4
++++ b/config/kernel-acl.m4
+@@ -236,7 +236,22 @@ dnl #
+ dnl # 6.2 API change,
+ dnl # set_acl() second paramter changed to a struct dentry *
+ dnl #
++dnl # 6.3 API change,
++dnl # set_acl() first parameter changed to struct mnt_idmap *
++dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OPERATIONS_SET_ACL], [
++ ZFS_LINUX_TEST_SRC([inode_operations_set_acl_mnt_idmap_dentry], [
++ #include <linux/fs.h>
++
++ int set_acl_fn(struct mnt_idmap *idmap,
++ struct dentry *dent, 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_userns_dentry], [
+ #include <linux/fs.h>
+
+@@ -281,17 +296,24 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
+ AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
+ AC_DEFINE(HAVE_SET_ACL_USERNS, 1, [iops->set_acl() takes 4 args])
+ ],[
+- ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns_dentry], [
++ ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_mnt_idmap_dentry], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
+- AC_DEFINE(HAVE_SET_ACL_USERNS_DENTRY_ARG2, 1,
+- [iops->set_acl() takes 4 args, arg2 is struct dentry *])
++ AC_DEFINE(HAVE_SET_ACL_IDMAP_DENTRY, 1,
++ [iops->set_acl() takes 4 args, arg1 is struct mnt_idmap *])
+ ],[
+- ZFS_LINUX_TEST_RESULT([inode_operations_set_acl], [
++ ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns_dentry], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists, takes 3 args])
++ AC_DEFINE(HAVE_SET_ACL, 1, [iops->set_acl() exists])
++ AC_DEFINE(HAVE_SET_ACL_USERNS_DENTRY_ARG2, 1,
++ [iops->set_acl() takes 4 args, arg2 is struct dentry *])
+ ],[
+- ZFS_LINUX_REQUIRE_API([i_op->set_acl()], [3.14])
++ 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])
++ ],[
++ ZFS_LINUX_REQUIRE_API([i_op->set_acl()], [3.14])
++ ])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-generic_fillattr.m4 b/config/kernel-generic_fillattr.m4
+index 0acd5d531..02dee4d4c 100644
+--- a/config/kernel-generic_fillattr.m4
++++ b/config/kernel-generic_fillattr.m4
+@@ -4,7 +4,10 @@ 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], [
++dnl # 6.3 API
++dnl # generic_fillattr() now takes struct mnt_idmap* as the first argument
++dnl #
++AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR], [
+ ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
+ #include <linux/fs.h>
+ ],[
+@@ -13,16 +16,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [
+ struct kstat *k = NULL;
+ generic_fillattr(userns, in, k);
+ ])
++
++ ZFS_LINUX_TEST_SRC([generic_fillattr_mnt_idmap], [
++ #include <linux/fs.h>
++ ],[
++ struct mnt_idmap *idmap = NULL;
++ struct inode *in = NULL;
++ struct kstat *k = NULL;
++ generic_fillattr(idmap, in, k);
++ ])
+ ])
+
+-AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [
+- AC_MSG_CHECKING([whether generic_fillattr requires struct user_namespace*])
+- ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
++AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR], [
++ AC_MSG_CHECKING([whether generic_fillattr requires struct mnt_idmap*])
++ ZFS_LINUX_TEST_RESULT([generic_fillattr_mnt_idmap], [
+ AC_MSG_RESULT([yes])
+- AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1,
+- [generic_fillattr requires struct user_namespace*])
++ AC_DEFINE(HAVE_GENERIC_FILLATTR_IDMAP, 1,
++ [generic_fillattr requires struct mnt_idmap*])
+ ],[
+- AC_MSG_RESULT([no])
++ AC_MSG_CHECKING([whether generic_fillattr requires 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 a6ea11fb6..9e9e43180 100644
+--- a/config/kernel-inode-create.m4
++++ b/config/kernel-inode-create.m4
+@@ -1,4 +1,22 @@
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
++ dnl #
++ dnl # 6.3 API change
++ dnl # The first arg is changed to struct mnt_idmap *
++ dnl #
++ ZFS_LINUX_TEST_SRC([create_mnt_idmap], [
++ #include <linux/fs.h>
++ #include <linux/sched.h>
++
++ int inode_create(struct mnt_idmap *idmap,
++ 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 # 5.12 API change that added the struct user_namespace* arg
+ dnl # to the front of this function type's arg list.
+@@ -35,19 +53,28 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
+- AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
+- ZFS_LINUX_TEST_RESULT([create_userns], [
++ AC_MSG_CHECKING([whether iops->create() takes struct mnt_idmap*])
++ ZFS_LINUX_TEST_RESULT([create_mnt_idmap], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_IOPS_CREATE_USERNS, 1,
+- [iops->create() takes struct user_namespace*])
++ AC_DEFINE(HAVE_IOPS_CREATE_IDMAP, 1,
++ [iops->create() takes struct mnt_idmap*])
+ ],[
+ AC_MSG_RESULT(no)
+
+- AC_MSG_CHECKING([whether iops->create() passes flags])
+- ZFS_LINUX_TEST_RESULT([create_flags], [
++ 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 f62e82f52..c8bfb0786 100644
+--- a/config/kernel-inode-getattr.m4
++++ b/config/kernel-inode-getattr.m4
+@@ -1,4 +1,24 @@
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
++ dnl #
++ dnl # Linux 6.3 API
++ dnl # The first arg of getattr I/O operations handler type
++ dnl # is changed to struct mnt_idmap*
++ dnl #
++ ZFS_LINUX_TEST_SRC([inode_operations_getattr_mnt_idmap], [
++ #include <linux/fs.h>
++
++ int test_getattr(
++ struct mnt_idmap *idmap,
++ 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 5.12 API
+ dnl # The getattr I/O operations handler type was extended to require
+@@ -55,37 +75,48 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
+
+ AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
+ dnl #
+- dnl # Kernel 5.12 test
++ dnl # Kernel 6.3 test
+ dnl #
+- AC_MSG_CHECKING([whether iops->getattr() takes user_namespace])
+- ZFS_LINUX_TEST_RESULT([inode_operations_getattr_userns], [
++ AC_MSG_CHECKING([whether iops->getattr() takes mnt_idmap])
++ ZFS_LINUX_TEST_RESULT([inode_operations_getattr_mnt_idmap], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_USERNS_IOPS_GETATTR, 1,
+- [iops->getattr() takes struct user_namespace*])
++ AC_DEFINE(HAVE_IDMAP_IOPS_GETATTR, 1,
++ [iops->getattr() takes struct mnt_idmap*])
+ ],[
+ AC_MSG_RESULT(no)
+-
+ dnl #
+- dnl # Kernel 4.11 test
++ dnl # Kernel 5.12 test
+ dnl #
+- AC_MSG_CHECKING([whether iops->getattr() takes a path])
+- ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
++ 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)
+
+ dnl #
+- dnl # Kernel < 4.11 test
++ 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_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 a90cf3da6..4e9c002b7 100644
+--- a/config/kernel-is_owner_or_cap.m4
++++ b/config/kernel-is_owner_or_cap.m4
+@@ -16,12 +16,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [
+ (void) inode_owner_or_capable(ip);
+ ])
+
+- ZFS_LINUX_TEST_SRC([inode_owner_or_capable_idmapped], [
++ ZFS_LINUX_TEST_SRC([inode_owner_or_capable_userns], [
+ #include <linux/fs.h>
+ ],[
+ struct inode *ip = NULL;
+ (void) inode_owner_or_capable(&init_user_ns, ip);
+ ])
++
++ ZFS_LINUX_TEST_SRC([inode_owner_or_capable_mnt_idmap], [
++ #include <linux/fs.h>
++ #include <linux/mnt_idmapping.h>
++ ],[
++ struct inode *ip = NULL;
++ (void) inode_owner_or_capable(&nop_mnt_idmap, ip);
++ ])
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
+@@ -35,12 +43,21 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
+
+ AC_MSG_CHECKING(
+ [whether inode_owner_or_capable() takes user_ns])
+- ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_idmapped], [
++ ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_userns], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED, 1,
++ AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_USERNS, 1,
+ [inode_owner_or_capable() takes user_ns])
+ ],[
+- ZFS_LINUX_TEST_ERROR([capability])
++ AC_MSG_RESULT(no)
++ AC_MSG_CHECKING(
++ [whether inode_owner_or_capable() takes mnt_idmap])
++ ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_mnt_idmap], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_IDMAP, 1,
++ [inode_owner_or_capable() takes mnt_idmap])
++ ], [
++ ZFS_LINUX_TEST_ERROR([capability])
++ ])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-mkdir.m4 b/config/kernel-mkdir.m4
+index 6667ed04f..7407a791b 100644
+--- a/config/kernel-mkdir.m4
++++ b/config/kernel-mkdir.m4
+@@ -2,6 +2,22 @@ dnl #
+ dnl # Supported mkdir() interfaces checked newest to oldest.
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
++ dnl #
++ dnl # 6.3 API change
++ dnl # mkdir() takes struct mnt_idmap * as the first arg
++ dnl #
++ ZFS_LINUX_TEST_SRC([mkdir_mnt_idmap], [
++ #include <linux/fs.h>
++
++ int mkdir(struct mnt_idmap *idmap,
++ struct inode *inode, struct dentry *dentry,
++ umode_t umode) { return 0; }
++ static const struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .mkdir = mkdir,
++ };
++ ],[])
++
+ dnl #
+ dnl # 5.12 API change
+ dnl # The struct user_namespace arg was added as the first argument to
+@@ -43,25 +59,36 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_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 # 6.3 API change
++ dnl # mkdir() takes struct mnt_idmap * as the first arg
+ dnl #
+- AC_MSG_CHECKING([whether iops->mkdir() takes struct user_namespace*])
+- ZFS_LINUX_TEST_RESULT([mkdir_user_namespace], [
++ AC_MSG_CHECKING([whether iops->mkdir() takes struct mnt_idmap*])
++ ZFS_LINUX_TEST_RESULT([mkdir_mnt_idmap], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_IOPS_MKDIR_USERNS, 1,
+- [iops->mkdir() takes struct user_namespace*])
++ AC_DEFINE(HAVE_IOPS_MKDIR_IDMAP, 1,
++ [iops->mkdir() takes struct mnt_idmap*])
+ ],[
+- AC_MSG_RESULT(no)
+-
+- AC_MSG_CHECKING([whether iops->mkdir() takes umode_t])
+- ZFS_LINUX_TEST_RESULT([inode_operations_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_MKDIR_UMODE_T, 1,
+- [iops->mkdir() takes umode_t])
++ AC_DEFINE(HAVE_IOPS_MKDIR_USERNS, 1,
++ [iops->mkdir() takes struct user_namespace*])
+ ],[
+- ZFS_LINUX_TEST_ERROR([mkdir()])
++ AC_MSG_RESULT(no)
++
++ 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
+index ffe451060..1494ec1ae 100644
+--- a/config/kernel-mknod.m4
++++ b/config/kernel-mknod.m4
+@@ -1,4 +1,22 @@
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
++ dnl #
++ dnl # 6.3 API change
++ dnl # The first arg is now struct mnt_idmap*
++ dnl #
++ ZFS_LINUX_TEST_SRC([mknod_mnt_idmap], [
++ #include <linux/fs.h>
++ #include <linux/sched.h>
++
++ int tmp_mknod(struct mnt_idmap *idmap,
++ 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,
++ };
++ ],[])
++
+ dnl #
+ dnl # 5.12 API change that added the struct user_namespace* arg
+ dnl # to the front of this function type's arg list.
+@@ -19,12 +37,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_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_CHECKING([whether iops->mknod() takes struct mnt_idmap*])
++ ZFS_LINUX_TEST_RESULT([mknod_mnt_idmap], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_IOPS_MKNOD_USERNS, 1,
+- [iops->mknod() takes struct user_namespace*])
++ AC_DEFINE(HAVE_IOPS_MKNOD_IDMAP, 1,
++ [iops->mknod() takes struct mnt_idmap*])
+ ],[
+ AC_MSG_RESULT(no)
++ 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 302db43f5..06a9791bc 100644
+--- a/config/kernel-rename.m4
++++ b/config/kernel-rename.m4
+@@ -33,24 +33,63 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
+ .rename = rename_fn,
+ };
+ ],[])
++
++ dnl #
++ dnl # 6.3 API change - the first arg is now struct mnt_idmap*
++ dnl #
++ ZFS_LINUX_TEST_SRC([inode_operations_rename_mnt_idmap], [
++ #include <linux/fs.h>
++ int rename_fn(struct mnt_idmap *idmap, 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], [
+- AC_MSG_CHECKING([whether iops->rename() takes struct user_namespace*])
+- ZFS_LINUX_TEST_RESULT([inode_operations_rename_userns], [
++ AC_MSG_CHECKING([whether iops->rename() takes struct mnt_idmap*])
++ ZFS_LINUX_TEST_RESULT([inode_operations_rename_mnt_idmap], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_IOPS_RENAME_USERNS, 1,
+- [iops->rename() takes struct user_namespace*])
++ AC_DEFINE(HAVE_IOPS_RENAME_IDMAP, 1,
++ [iops->rename() takes struct mnt_idmap*])
+ ],[
+- AC_MSG_RESULT(no)
+-
+- AC_MSG_CHECKING([whether iop->rename() wants flags])
+- ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
++ 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)
++
++ AC_MSG_CHECKING([whether iops->rename2() exists])
++ ZFS_LINUX_TEST_RESULT([inode_operations_rename2], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_RENAME2, 1, [iops->rename2() exists])
++ ],[
++ AC_MSG_RESULT(no)
++
++ AC_MSG_CHECKING([whether iops->rename() wants flags])
++ 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)
++
++ AC_MSG_CHECKING([whether struct inode_operations_wrapper takes .rename2()])
++ ZFS_LINUX_TEST_RESULT([dir_inode_operations_wrapper_rename2], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_RENAME2_OPERATIONS_WRAPPER, 1,
++ [struct inode_operations_wrapper takes .rename2()])
++ ],[
++ AC_MSG_RESULT(no)
++ ])
++ ])
++ ])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-setattr-prepare.m4 b/config/kernel-setattr-prepare.m4
+index 24245aa53..e02d6263e 100644
+--- a/config/kernel-setattr-prepare.m4
++++ b/config/kernel-setattr-prepare.m4
+@@ -27,26 +27,48 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
+ int error __attribute__ ((unused)) =
+ setattr_prepare(userns, dentry, attr);
+ ])
++
++ dnl #
++ dnl # 6.3 API change
++ dnl # The first arg of setattr_prepare() is changed to struct mnt_idmap*
++ dnl #
++ ZFS_LINUX_TEST_SRC([setattr_prepare_mnt_idmap], [
++ #include <linux/fs.h>
++ ], [
++ struct dentry *dentry = NULL;
++ struct iattr *attr = NULL;
++ struct mnt_idmap *idmap = NULL;
++ int error __attribute__ ((unused)) =
++ setattr_prepare(idmap, dentry, attr);
++ ])
+ ])
+
+ AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
+- AC_MSG_CHECKING([whether setattr_prepare() is available and accepts struct user_namespace*])
+- ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare_userns],
++ AC_MSG_CHECKING([whether setattr_prepare() is available and accepts struct mnt_idmap*])
++ ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare_mnt_idmap],
+ [setattr_prepare], [fs/attr.c], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_SETATTR_PREPARE_USERNS, 1,
+- [setattr_prepare() accepts user_namespace])
++ AC_DEFINE(HAVE_SETATTR_PREPARE_IDMAP, 1,
++ [setattr_prepare() accepts mnt_idmap])
+ ], [
+- 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_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_NO_USERNS, 1,
+- [setattr_prepare() is available, doesn't accept user_namespace])
++ 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
+index d90366d04..a0333ed66 100644
+--- a/config/kernel-symlink.m4
++++ b/config/kernel-symlink.m4
+@@ -1,4 +1,20 @@
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_SYMLINK], [
++ dnl #
++ dnl # 6.3 API change that changed the first arg
++ dnl # to struct mnt_idmap*
++ dnl #
++ ZFS_LINUX_TEST_SRC([symlink_mnt_idmap], [
++ #include <linux/fs.h>
++ #include <linux/sched.h>
++ int tmp_symlink(struct mnt_idmap *idmap,
++ struct inode *inode ,struct dentry *dentry,
++ const char *path) { return 0; }
++
++ static const struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .symlink = tmp_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.
+@@ -19,12 +35,19 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_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_CHECKING([whether iops->symlink() takes struct mnt_idmap*])
++ ZFS_LINUX_TEST_RESULT([symlink_mnt_idmap], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_IOPS_SYMLINK_USERNS, 1,
+- [iops->symlink() takes struct user_namespace*])
++ AC_DEFINE(HAVE_IOPS_SYMLINK_IDMAP, 1,
++ [iops->symlink() takes struct mnt_idmap*])
+ ],[
+- AC_MSG_RESULT(no)
++ 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-tmpfile.m4 b/config/kernel-tmpfile.m4
+index 0e1deb361..f4c01058c 100644
+--- a/config/kernel-tmpfile.m4
++++ b/config/kernel-tmpfile.m4
+@@ -4,6 +4,19 @@ dnl # Add support for i_op->tmpfile
+ dnl #
+ AC_DEFUN([ZFS_AC_KERNEL_SRC_TMPFILE], [
+ dnl #
++ dnl # 6.3 API change
++ dnl # The first arg is now struct mnt_idmap *
++ dnl #
++ ZFS_LINUX_TEST_SRC([inode_operations_tmpfile_mnt_idmap], [
++ #include <linux/fs.h>
++ int tmpfile(struct mnt_idmap *idmap,
++ struct inode *inode, struct file *file,
++ umode_t mode) { return 0; }
++ static struct inode_operations
++ iops __attribute__ ((unused)) = {
++ .tmpfile = tmpfile,
++ };
++ ],[])
+ dnl # 6.1 API change
+ dnl # use struct file instead of struct dentry
+ dnl #
+@@ -44,23 +57,29 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_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_mnt_idmap], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
+- AC_DEFINE(HAVE_TMPFILE_USERNS, 1, [i_op->tmpfile() has userns])
+- ],[
+- ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_dentry_userns], [
++ AC_DEFINE(HAVE_TMPFILE_IDMAP, 1, [i_op->tmpfile() has mnt_idmap])
++ ], [
++ ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile], [
+ 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_DEFINE(HAVE_TMPFILE_DENTRY, 1, [i_op->tmpfile() uses old dentry signature])
+ ],[
+- ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_dentry], [
++ ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_dentry_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_DEFINE(HAVE_TMPFILE_DENTRY, 1, [i_op->tmpfile() uses old dentry signature])
+ ],[
+- ZFS_LINUX_REQUIRE_API([i_op->tmpfile()], [3.11])
++ ZFS_LINUX_TEST_RESULT([inode_operations_tmpfile_dentry], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
++ AC_DEFINE(HAVE_TMPFILE_DENTRY, 1, [i_op->tmpfile() uses old dentry signature])
++ ],[
++ ZFS_LINUX_REQUIRE_API([i_op->tmpfile()], [3.11])
++ ])
+ ])
+ ])
+ ])
+diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4
+index b6cbfa155..6b8a08dbc 100644
+--- a/config/kernel-xattr-handler.m4
++++ b/config/kernel-xattr-handler.m4
+@@ -179,6 +179,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_mnt_idmap], [
++ #include <linux/xattr.h>
++
++ int set(const struct xattr_handler *handler,
++ struct mnt_idmap *idmap,
++ 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_userns], [
+ #include <linux/xattr.h>
+
+@@ -240,53 +255,63 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
+ 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, inode, and user_namespace])
+- ZFS_LINUX_TEST_RESULT([xattr_handler_set_userns], [
++ dnl # 6.3 API change,
++ dnl # The xattr_handler->set() callback 2nd arg is now struct mnt_idmap *
++ dnl #
++ AC_MSG_CHECKING([whether xattr_handler->set() wants dentry, inode, and mnt_idmap])
++ ZFS_LINUX_TEST_RESULT([xattr_handler_set_mnt_idmap], [
+ AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_XATTR_SET_USERNS, 1,
+- [xattr_handler->set() takes user_namespace])
+- ],[
+- dnl #
+- 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 dentry and inode])
+- ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
++ AC_DEFINE(HAVE_XATTR_SET_IDMAP, 1,
++ [xattr_handler->set() takes mnt_idmap])
++ ], [
++ 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 f6743acac..a0878b175 100644
+--- a/config/kernel.m4
++++ b/config/kernel.m4
+@@ -130,7 +130,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
+ ZFS_AC_KERNEL_SRC_KSTRTOUL
+ ZFS_AC_KERNEL_SRC_PERCPU
+ ZFS_AC_KERNEL_SRC_CPU_HOTPLUG
+- ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS
++ ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR
+ ZFS_AC_KERNEL_SRC_MKNOD
+ ZFS_AC_KERNEL_SRC_SYMLINK
+ ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS
+@@ -248,7 +248,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
+ ZFS_AC_KERNEL_KSTRTOUL
+ ZFS_AC_KERNEL_PERCPU
+ ZFS_AC_KERNEL_CPU_HOTPLUG
+- ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
++ ZFS_AC_KERNEL_GENERIC_FILLATTR
+ ZFS_AC_KERNEL_MKNOD
+ ZFS_AC_KERNEL_SYMLINK
+ ZFS_AC_KERNEL_BIO_MAX_SEGS
+diff --git a/include/os/freebsd/spl/sys/types.h b/include/os/freebsd/spl/sys/types.h
+index ecb91fd1b..bef006673 100644
+--- a/include/os/freebsd/spl/sys/types.h
++++ b/include/os/freebsd/spl/sys/types.h
+@@ -104,5 +104,7 @@ typedef u_longlong_t len_t;
+
+ typedef longlong_t diskaddr_t;
+
++typedef void zidmap_t;
++
+ #include <sys/debug.h>
+ #endif /* !_OPENSOLARIS_SYS_TYPES_H_ */
+diff --git a/include/os/linux/kernel/linux/vfs_compat.h b/include/os/linux/kernel/linux/vfs_compat.h
+index 91e908598..e82bbf755 100644
+--- a/include/os/linux/kernel/linux/vfs_compat.h
++++ b/include/os/linux/kernel/linux/vfs_compat.h
+@@ -344,7 +344,8 @@ static inline void zfs_gid_write(struct inode *ip, gid_t gid)
+ * 4.9 API change
+ */
+ #if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \
+- defined(HAVE_SETATTR_PREPARE_USERNS))
++ defined(HAVE_SETATTR_PREPARE_USERNS) || \
++ defined(HAVE_SETATTR_PREPARE_IDMAP))
+ static inline int
+ setattr_prepare(struct dentry *dentry, struct iattr *ia)
+ {
+@@ -399,6 +400,15 @@ func(struct user_namespace *user_ns, const struct path *path, \
+ return (func##_impl(user_ns, path, stat, request_mask, \
+ query_flags)); \
+ }
++#elif defined(HAVE_IDMAP_IOPS_GETATTR)
++#define ZPL_GETATTR_WRAPPER(func) \
++static int \
++func(struct mnt_idmap *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
+@@ -450,8 +460,15 @@ zpl_is_32bit_api(void)
+ * 5.12 API change
+ * To support id-mapped mounts, generic_fillattr() was modified to
+ * accept a new struct user_namespace* as its first arg.
++ *
++ * 6.3 API change
++ * generic_fillattr() first arg is changed to struct mnt_idmap *
++ *
+ */
+-#ifdef HAVE_GENERIC_FILLATTR_USERNS
++#ifdef HAVE_GENERIC_FILLATTR_IDMAP
++#define zpl_generic_fillattr(idmap, ip, sp) \
++ generic_fillattr(idmap, ip, sp)
++#elif defined(HAVE_GENERIC_FILLATTR_USERNS)
+ #define zpl_generic_fillattr(user_ns, ip, sp) \
+ generic_fillattr(user_ns, ip, sp)
+ #else
+diff --git a/include/os/linux/kernel/linux/xattr_compat.h b/include/os/linux/kernel/linux/xattr_compat.h
+index 30403fe87..c40f310d7 100644
+--- a/include/os/linux/kernel/linux/xattr_compat.h
++++ b/include/os/linux/kernel/linux/xattr_compat.h
+@@ -133,13 +133,28 @@ fn(const struct xattr_handler *handler, struct dentry *dentry, \
+ #error "Unsupported kernel"
+ #endif
+
++/*
++ * 6.3 API change,
++ * The xattr_handler->set() callback was changed to take the
++ * struct mnt_idmap* as the first arg, to support idmapped
++ * mounts.
++ */
++#if defined(HAVE_XATTR_SET_IDMAP)
++#define ZPL_XATTR_SET_WRAPPER(fn) \
++static int \
++fn(const struct xattr_handler *handler, struct mnt_idmap *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)); \
++}
+ /*
+ * 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)
++#elif defined(HAVE_XATTR_SET_USERNS)
+ #define ZPL_XATTR_SET_WRAPPER(fn) \
+ static int \
+ fn(const struct xattr_handler *handler, struct user_namespace *user_ns, \
+diff --git a/include/os/linux/spl/sys/cred.h b/include/os/linux/spl/sys/cred.h
+index b7d3f38d7..501bd4566 100644
+--- a/include/os/linux/spl/sys/cred.h
++++ b/include/os/linux/spl/sys/cred.h
+@@ -45,6 +45,8 @@ typedef struct cred cred_t;
+ #define SGID_TO_KGID(x) (KGIDT_INIT(x))
+ #define KGIDP_TO_SGIDP(x) (&(x)->val)
+
++extern zidmap_t *zfs_get_init_idmap(void);
++
+ extern void crhold(cred_t *cr);
+ extern void crfree(cred_t *cr);
+ extern uid_t crgetuid(const cred_t *cr);
+diff --git a/include/os/linux/spl/sys/types.h b/include/os/linux/spl/sys/types.h
+index b44c94518..a7666187e 100644
+--- a/include/os/linux/spl/sys/types.h
++++ b/include/os/linux/spl/sys/types.h
+@@ -54,4 +54,20 @@ typedef ulong_t pgcnt_t;
+ typedef int major_t;
+ typedef int minor_t;
+
++struct user_namespace;
++#ifdef HAVE_IOPS_CREATE_IDMAP
++#include <linux/refcount.h>
++struct mnt_idmap {
++ struct user_namespace *owner;
++ refcount_t count;
++};
++typedef struct mnt_idmap zidmap_t;
++#define idmap_owner(p) (((struct mnt_idmap *)p)->owner)
++#else
++typedef struct user_namespace zidmap_t;
++#define idmap_owner(p) ((struct user_namespace *)p)
++#endif
++
++extern zidmap_t *zfs_init_idmap;
++
+ #endif /* _SPL_TYPES_H */
+diff --git a/include/os/linux/zfs/sys/zfs_vnops_os.h b/include/os/linux/zfs/sys/zfs_vnops_os.h
+index 47f91e4a6..a2deda096 100644
+--- a/include/os/linux/zfs/sys/zfs_vnops_os.h
++++ b/include/os/linux/zfs/sys/zfs_vnops_os.h
+@@ -54,8 +54,13 @@ 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);
++#ifdef HAVE_GENERIC_FILLATTR_IDMAP
++extern int zfs_getattr_fast(struct mnt_idmap *, struct inode *ip,
++ struct kstat *sp);
++#else
+ extern int zfs_getattr_fast(struct user_namespace *, struct inode *ip,
+ struct kstat *sp);
++#endif
+ 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 ac9815d4e..6692fa314 100644
+--- a/include/os/linux/zfs/sys/zpl.h
++++ b/include/os/linux/zfs/sys/zpl.h
+@@ -64,7 +64,10 @@ 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)
++#if defined(HAVE_SET_ACL_IDMAP_DENTRY)
++extern int zpl_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
++ struct posix_acl *acl, int type);
++#elif defined(HAVE_SET_ACL_USERNS)
+ extern int zpl_set_acl(struct user_namespace *userns, struct inode *ip,
+ struct posix_acl *acl, int type);
+ #elif defined(HAVE_SET_ACL_USERNS_DENTRY_ARG2)
+@@ -186,13 +189,15 @@ zpl_dir_emit_dots(struct file *file, zpl_dir_context_t *ctx)
+
+ #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)
++#elif defined(HAVE_INODE_OWNER_OR_CAPABLE_USERNS)
+ #define zpl_inode_owner_or_capable(ns, ip) inode_owner_or_capable(ns, ip)
++#elif defined(HAVE_INODE_OWNER_OR_CAPABLE_IDMAP)
++#define zpl_inode_owner_or_capable(idmap, ip) inode_owner_or_capable(idmap, ip)
+ #else
+ #error "Unsupported kernel"
+ #endif
+
+-#ifdef HAVE_SETATTR_PREPARE_USERNS
++#if defined(HAVE_SETATTR_PREPARE_USERNS) || defined(HAVE_SETATTR_PREPARE_IDMAP)
+ #define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(ns, dentry, ia)
+ #else
+ /*
+diff --git a/module/os/linux/spl/spl-cred.c b/module/os/linux/spl/spl-cred.c
+index f81b9540a..d407fc66b 100644
+--- a/module/os/linux/spl/spl-cred.c
++++ b/module/os/linux/spl/spl-cred.c
+@@ -145,6 +145,18 @@ crgetgid(const cred_t *cr)
+ return (KGID_TO_SGID(cr->fsgid));
+ }
+
++/* Return the initial user ns or nop_mnt_idmap */
++zidmap_t *
++zfs_get_init_idmap(void)
++{
++#ifdef HAVE_IOPS_CREATE_IDMAP
++ return ((zidmap_t *)&nop_mnt_idmap);
++#else
++ return ((zidmap_t *)&init_user_ns);
++#endif
++}
++
++EXPORT_SYMBOL(zfs_get_init_idmap);
+ EXPORT_SYMBOL(crhold);
+ EXPORT_SYMBOL(crfree);
+ EXPORT_SYMBOL(crgetuid);
+diff --git a/module/os/linux/zfs/policy.c b/module/os/linux/zfs/policy.c
+index 5a52092bb..29012cb2a 100644
+--- a/module/os/linux/zfs/policy.c
++++ b/module/os/linux/zfs/policy.c
+@@ -124,7 +124,11 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
+ if (crgetuid(cr) == owner)
+ return (0);
+
++#ifdef HAVE_INODE_OWNER_OR_CAPABLE_IDMAP
++ if (zpl_inode_owner_or_capable(zfs_init_idmap, ip))
++#else
+ if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
++#endif
+ return (0);
+
+ #if defined(CONFIG_USER_NS)
+diff --git a/module/os/linux/zfs/zfs_ioctl_os.c b/module/os/linux/zfs/zfs_ioctl_os.c
+index 79b9d777d..767d3a377 100644
+--- a/module/os/linux/zfs/zfs_ioctl_os.c
++++ b/module/os/linux/zfs/zfs_ioctl_os.c
+@@ -288,6 +288,8 @@ zfsdev_detach(void)
+ #define ZFS_DEBUG_STR ""
+ #endif
+
++zidmap_t *zfs_init_idmap;
++
+ static int __init
+ openzfs_init(void)
+ {
+@@ -311,6 +313,8 @@ openzfs_init(void)
+ printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
+ #endif /* CONFIG_FS_POSIX_ACL */
+
++ zfs_init_idmap = (zidmap_t *)zfs_get_init_idmap();
++
+ return (0);
+ }
+
+diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
+index ae0401e60..ec928bba7 100644
+--- a/module/os/linux/zfs/zfs_vnops_os.c
++++ b/module/os/linux/zfs/zfs_vnops_os.c
+@@ -1663,8 +1663,13 @@ out:
+ */
+ /* ARGSUSED */
+ int
++#ifdef HAVE_GENERIC_FILLATTR_IDMAP
++zfs_getattr_fast(struct mnt_idmap *user_ns, struct inode *ip,
++ struct kstat *sp)
++#else
+ zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
+ struct kstat *sp)
++#endif
+ {
+ znode_t *zp = ITOZ(ip);
+ zfsvfs_t *zfsvfs = ITOZSB(ip);
+diff --git a/module/os/linux/zfs/zpl_ctldir.c b/module/os/linux/zfs/zpl_ctldir.c
+index 9b526afd0..cf4da470f 100644
+--- a/module/os/linux/zfs/zpl_ctldir.c
++++ b/module/os/linux/zfs/zpl_ctldir.c
+@@ -101,7 +101,11 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
+ */
+ /* ARGSUSED */
+ static int
+-#ifdef HAVE_USERNS_IOPS_GETATTR
++#ifdef HAVE_IDMAP_IOPS_GETATTR
++zpl_root_getattr_impl(struct mnt_idmap *user_ns,
++ const struct path *path, struct kstat *stat, u32 request_mask,
++ unsigned int query_flags)
++#elif defined(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)
+@@ -112,8 +116,14 @@ zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
+ {
+ struct inode *ip = path->dentry->d_inode;
+
+-#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
++#if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
++#ifdef HAVE_GENERIC_FILLATTR_USERNS
+ generic_fillattr(user_ns, ip, stat);
++#elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
++ generic_fillattr(user_ns, ip, stat);
++#else
++ (void) user_ns;
++#endif
+ #else
+ generic_fillattr(ip, stat);
+ #endif
+@@ -304,6 +314,10 @@ static int
+ zpl_snapdir_rename2(struct user_namespace *user_ns, struct inode *sdip,
+ struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
+ unsigned int flags)
++#elif defined(HAVE_IOPS_RENAME_IDMAP)
++zpl_snapdir_rename2(struct mnt_idmap *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)
+@@ -325,7 +339,9 @@ zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
+ return (error);
+ }
+
+-#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
++#if (!defined(HAVE_RENAME_WANTS_FLAGS) && \
++ !defined(HAVE_IOPS_RENAME_USERNS) && \
++ !defined(HAVE_IOPS_RENAME_IDMAP))
+ static int
+ zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
+ struct inode *tdip, struct dentry *tdentry)
+@@ -352,6 +368,9 @@ static int
+ #ifdef HAVE_IOPS_MKDIR_USERNS
+ zpl_snapdir_mkdir(struct user_namespace *user_ns, struct inode *dip,
+ struct dentry *dentry, umode_t mode)
++#elif defined(HAVE_IOPS_MKDIR_IDMAP)
++zpl_snapdir_mkdir(struct mnt_idmap *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
+@@ -384,7 +403,11 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
+ */
+ /* ARGSUSED */
+ static int
+-#ifdef HAVE_USERNS_IOPS_GETATTR
++#ifdef HAVE_IDMAP_IOPS_GETATTR
++zpl_snapdir_getattr_impl(struct mnt_idmap *user_ns,
++ const struct path *path, struct kstat *stat, u32 request_mask,
++ unsigned int query_flags)
++#elif defined(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)
+@@ -397,8 +420,14 @@ zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
+ zfsvfs_t *zfsvfs = ITOZSB(ip);
+
+ ZPL_ENTER(zfsvfs);
+-#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
++#if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
++#ifdef HAVE_GENERIC_FILLATTR_USERNS
++ generic_fillattr(user_ns, ip, stat);
++#elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
+ generic_fillattr(user_ns, ip, stat);
++#else
++ (void) user_ns;
++#endif
+ #else
+ generic_fillattr(ip, stat);
+ #endif
+@@ -439,7 +468,9 @@ const struct file_operations zpl_fops_snapdir = {
+ const struct inode_operations zpl_ops_snapdir = {
+ .lookup = zpl_snapdir_lookup,
+ .getattr = zpl_snapdir_getattr,
+-#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
++#if (defined(HAVE_RENAME_WANTS_FLAGS) || \
++ defined(HAVE_IOPS_RENAME_USERNS) || \
++ defined(HAVE_IOPS_RENAME_IDMAP))
+ .rename = zpl_snapdir_rename2,
+ #else
+ .rename = zpl_snapdir_rename,
+@@ -530,6 +561,10 @@ static int
+ zpl_shares_getattr_impl(struct user_namespace *user_ns,
+ const struct path *path, struct kstat *stat, u32 request_mask,
+ unsigned int query_flags)
++#elif defined(HAVE_IDMAP_IOPS_GETATTR)
++zpl_shares_getattr_impl(struct mnt_idmap *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)
+@@ -543,8 +578,14 @@ 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)
++#if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
++#ifdef HAVE_GENERIC_FILLATTR_USERNS
++ generic_fillattr(user_ns, path->dentry->d_inode, stat);
++#elif defined(HAVE_GENERIC_FILLATTR_IDMAP)
+ generic_fillattr(user_ns, path->dentry->d_inode, stat);
++#else
++ (void) user_ns;
++#endif
+ #else
+ generic_fillattr(path->dentry->d_inode, stat);
+ #endif
+@@ -556,7 +597,7 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
+
+ error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
+ if (error == 0) {
+-#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
++#if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
+ error = -zfs_getattr_fast(user_ns, ZTOI(dzp), stat);
+ #else
+ error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat);
+diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c
+index 25030cb2d..fddbb759a 100644
+--- a/module/os/linux/zfs/zpl_file.c
++++ b/module/os/linux/zfs/zpl_file.c
+@@ -947,7 +947,11 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
+ !capable(CAP_LINUX_IMMUTABLE))
+ return (-EPERM);
+
++#ifdef HAVE_INODE_OWNER_OR_CAPABLE_IDMAP
++ if (!zpl_inode_owner_or_capable(zfs_init_idmap, ip))
++#else
+ if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
++#endif
+ return (-EACCES);
+
+ xva_init(xva);
+diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c
+index dd634f70e..f17758344 100644
+--- a/module/os/linux/zfs/zpl_inode.c
++++ b/module/os/linux/zfs/zpl_inode.c
+@@ -131,6 +131,9 @@ 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)
++#elif defined(HAVE_IOPS_CREATE_IDMAP)
++zpl_create(struct mnt_idmap *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
+@@ -174,6 +177,9 @@ static int
+ #ifdef HAVE_IOPS_MKNOD_USERNS
+ zpl_mknod(struct user_namespace *user_ns, struct inode *dir,
+ struct dentry *dentry, umode_t mode,
++#elif defined(HAVE_IOPS_MKNOD_IDMAP)
++zpl_mknod(struct mnt_idmap *user_ns, struct inode *dir,
++ struct dentry *dentry, umode_t mode,
+ #else
+ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
+ #endif
+@@ -224,7 +230,10 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
+
+ #ifdef HAVE_TMPFILE
+ static int
+-#ifndef HAVE_TMPFILE_DENTRY
++#ifdef HAVE_TMPFILE_IDMAP
++zpl_tmpfile(struct mnt_idmap *userns, struct inode *dir,
++ struct file *file, umode_t mode)
++#elif !defined(HAVE_TMPFILE_DENTRY)
+ zpl_tmpfile(struct user_namespace *userns, struct inode *dir,
+ struct file *file, umode_t mode)
+ #else
+@@ -317,6 +326,9 @@ static int
+ #ifdef HAVE_IOPS_MKDIR_USERNS
+ zpl_mkdir(struct user_namespace *user_ns, struct inode *dir,
+ struct dentry *dentry, umode_t mode)
++#elif defined(HAVE_IOPS_MKDIR_IDMAP)
++zpl_mkdir(struct mnt_idmap *user_ns, struct inode *dir,
++ struct dentry *dentry, umode_t mode)
+ #else
+ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
+ #endif
+@@ -386,6 +398,10 @@ static int
+ zpl_getattr_impl(struct user_namespace *user_ns,
+ const struct path *path, struct kstat *stat, u32 request_mask,
+ unsigned int query_flags)
++#elif defined(HAVE_IDMAP_IOPS_GETATTR)
++zpl_getattr_impl(struct mnt_idmap *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)
+@@ -402,7 +418,7 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
+ * XXX query_flags currently ignored.
+ */
+
+-#ifdef HAVE_USERNS_IOPS_GETATTR
++#if (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
+ error = -zfs_getattr_fast(user_ns, ip, stat);
+ #else
+ error = -zfs_getattr_fast(kcred->user_ns, ip, stat);
+@@ -444,6 +460,9 @@ static int
+ #ifdef HAVE_SETATTR_PREPARE_USERNS
+ zpl_setattr(struct user_namespace *user_ns, struct dentry *dentry,
+ struct iattr *ia)
++#elif defined(HAVE_SETATTR_PREPARE_IDMAP)
++zpl_setattr(struct mnt_idmap *user_ns, struct dentry *dentry,
++ struct iattr *ia)
+ #else
+ zpl_setattr(struct dentry *dentry, struct iattr *ia)
+ #endif
+@@ -454,7 +473,11 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
+ int error;
+ fstrans_cookie_t cookie;
+
++#if defined(HAVE_SETATTR_PREPARE_USERNS) || defined(HAVE_SETATTR_PREPARE_IDMAP)
++ error = zpl_setattr_prepare(user_ns, dentry, ia);
++#else
+ error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
++#endif
+ if (error)
+ return (error);
+
+@@ -490,6 +513,10 @@ static int
+ zpl_rename2(struct user_namespace *user_ns, struct inode *sdip,
+ struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
+ unsigned int flags)
++#elif defined(HAVE_IOPS_RENAME_IDMAP)
++zpl_rename2(struct mnt_idmap *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)
+@@ -514,7 +541,9 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
+ return (error);
+ }
+
+-#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
++#if !defined(HAVE_IOPS_RENAME_USERNS) && \
++ !defined(HAVE_RENAME_WANTS_FLAGS) && \
++ !defined(HAVE_IOPS_RENAME_IDMAP)
+ static int
+ zpl_rename(struct inode *sdip, struct dentry *sdentry,
+ struct inode *tdip, struct dentry *tdentry)
+@@ -527,6 +556,9 @@ static int
+ #ifdef HAVE_IOPS_SYMLINK_USERNS
+ zpl_symlink(struct user_namespace *user_ns, struct inode *dir,
+ struct dentry *dentry, const char *name)
++#elif defined(HAVE_IOPS_SYMLINK_IDMAP)
++zpl_symlink(struct mnt_idmap *user_ns, struct inode *dir,
++ struct dentry *dentry, const char *name)
+ #else
+ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
+ #endif
+@@ -745,6 +777,8 @@ const struct inode_operations zpl_dir_inode_operations = {
+ .mknod = zpl_mknod,
+ #if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
+ .rename = zpl_rename2,
++#elif defined(HAVE_IOPS_RENAME_IDMAP)
++ .rename = zpl_rename2,
+ #else
+ .rename = zpl_rename,
+ #endif
+diff --git a/module/os/linux/zfs/zpl_xattr.c b/module/os/linux/zfs/zpl_xattr.c
+index 364cd34c1..30766ab49 100644
+--- a/module/os/linux/zfs/zpl_xattr.c
++++ b/module/os/linux/zfs/zpl_xattr.c
+@@ -1004,6 +1004,9 @@ int
+ #ifdef HAVE_SET_ACL_USERNS
+ zpl_set_acl(struct user_namespace *userns, struct inode *ip,
+ struct posix_acl *acl, int type)
++#elif defined(HAVE_SET_ACL_IDMAP_DENTRY)
++zpl_set_acl(struct mnt_idmap *userns, struct dentry *dentry,
++ struct posix_acl *acl, int type)
+ #elif defined(HAVE_SET_ACL_USERNS_DENTRY_ARG2)
+ zpl_set_acl(struct user_namespace *userns, struct dentry *dentry,
+ struct posix_acl *acl, int type)
+@@ -1013,6 +1016,8 @@ zpl_set_acl(struct inode *ip, struct posix_acl *acl, int type)
+ {
+ #ifdef HAVE_SET_ACL_USERNS_DENTRY_ARG2
+ return (zpl_set_acl_impl(d_inode(dentry), acl, type));
++#elif HAVE_SET_ACL_IDMAP_DENTRY
++ return (zpl_set_acl_impl(d_inode(dentry), acl, type));
+ #else
+ return (zpl_set_acl_impl(ip, acl, type));
+ #endif /* HAVE_SET_ACL_USERNS_DENTRY_ARG2 */
+@@ -1270,7 +1275,11 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
+ if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
+ return (-EOPNOTSUPP);
+
++#ifdef HAVE_INODE_OWNER_OR_CAPABLE_IDMAP
++ if (!zpl_inode_owner_or_capable(zfs_init_idmap, ip))
++#else
+ if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
++#endif
+ return (-EPERM);
+
+ if (value) {
+@@ -1309,7 +1318,11 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name,
+ if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
+ return (-EOPNOTSUPP);
+
++#ifdef HAVE_INODE_OWNER_OR_CAPABLE_IDMAP
++ if (!zpl_inode_owner_or_capable(zfs_init_idmap, ip))
++#else
+ if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
++#endif
+ return (-EPERM);
+
+ if (value) {
diff --git a/srcpkgs/zfs/template b/srcpkgs/zfs/template
index 914114f1cfb7..7d798a729e9a 100644
--- a/srcpkgs/zfs/template
+++ b/srcpkgs/zfs/template
@@ -1,7 +1,7 @@
# Template file for 'zfs'
pkgname=zfs
version=2.1.11
-revision=1
+revision=2
build_style=gnu-configure
configure_args="--with-config=user --with-mounthelperdir=/usr/bin
--with-udevdir=/usr/lib/udev --with-udevruledir=/usr/lib/udev/rules.d
next reply other threads:[~2023-05-25 2:33 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-25 2:33 sgn [this message]
2023-05-25 2:37 ` Vaelatern
2023-05-25 2:39 ` Vaelatern
2023-05-25 2:43 ` Vaelatern
2023-06-07 13:49 ` zdykstra
2023-06-07 13:54 ` zdykstra
2023-06-08 5:42 ` [PR PATCH] [Closed]: " sgn
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=gh-mailinglist-notifications-41a7ca26-5023-4802-975b-f1789d68868e-void-packages-44073@inbox.vuxu.org \
--to=sgn@users.noreply.github.com \
--cc=ml@inbox.vuxu.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;
as well as URLs for NNTP newsgroup(s).