Linux 6.3 compat: idmapped mount API changes

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.

NOTE: This backport only includes the configure checks to detect
the 6.3 idmap API changes.  It does not include support for idmap.
When provided the idmap variable is ignored in most case in the
same way the user_ns argument was ignored.  This change is solely
to provide compatibility with the new interfaces.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Youzhong Yang <yyang@mathworks.com>
Closes #14682
This commit is contained in:
youzhongyang 2023-04-10 17:15:36 -04:00 committed by Tony Hutter
parent 04305bbd18
commit f0aca5f7bb
28 changed files with 708 additions and 166 deletions

View File

@ -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>
@ -280,6 +295,12 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
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])
],[
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_IDMAP_DENTRY, 1,
[iops->set_acl() takes 4 args, arg1 is struct mnt_idmap *])
],[
ZFS_LINUX_TEST_RESULT([inode_operations_set_acl_userns_dentry], [
AC_MSG_RESULT(yes)
@ -296,6 +317,7 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_OPERATIONS_SET_ACL], [
])
])
])
])
dnl #
dnl # 4.7 API change,

View File

@ -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,9 +16,24 @@ 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_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_IDMAP, 1,
[generic_fillattr requires struct mnt_idmap*])
],[
AC_MSG_CHECKING([whether generic_fillattr requires struct user_namespace*])
ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
AC_MSG_RESULT([yes])
@ -25,4 +43,5 @@ AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [
AC_MSG_RESULT([no])
])
])
])

View File

@ -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,6 +53,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
])
AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
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_IDMAP, 1,
[iops->create() takes struct mnt_idmap*])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
ZFS_LINUX_TEST_RESULT([create_userns], [
AC_MSG_RESULT(yes)
@ -51,3 +77,4 @@ AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
])
])
])
])

View File

@ -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
@ -54,6 +74,16 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
])
AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
dnl #
dnl # Kernel 6.3 test
dnl #
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_IDMAP_IOPS_GETATTR, 1,
[iops->getattr() takes struct mnt_idmap*])
],[
AC_MSG_RESULT(no)
dnl #
dnl # Kernel 5.12 test
dnl #
@ -90,3 +120,4 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
])
])
])
])

View File

@ -0,0 +1,87 @@
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_SETATTR], [
dnl #
dnl # Linux 6.3 API
dnl # The first arg of setattr I/O operations handler type
dnl # is changed to struct mnt_idmap*
dnl #
ZFS_LINUX_TEST_SRC([inode_operations_setattr_mnt_idmap], [
#include <linux/fs.h>
int test_setattr(
struct mnt_idmap *idmap,
struct dentry *de, struct iattr *ia)
{ return 0; }
static const struct inode_operations
iops __attribute__ ((unused)) = {
.setattr = test_setattr,
};
],[])
dnl #
dnl # Linux 5.12 API
dnl # The setattr 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_setattr_userns], [
#include <linux/fs.h>
int test_setattr(
struct user_namespace *userns,
struct dentry *de, struct iattr *ia)
{ return 0; }
static const struct inode_operations
iops __attribute__ ((unused)) = {
.setattr = test_setattr,
};
],[])
ZFS_LINUX_TEST_SRC([inode_operations_setattr], [
#include <linux/fs.h>
int test_setattr(
struct dentry *de, struct iattr *ia)
{ return 0; }
static const struct inode_operations
iops __attribute__ ((unused)) = {
.setattr = test_setattr,
};
],[])
])
AC_DEFUN([ZFS_AC_KERNEL_INODE_SETATTR], [
dnl #
dnl # Kernel 6.3 test
dnl #
AC_MSG_CHECKING([whether iops->setattr() takes mnt_idmap])
ZFS_LINUX_TEST_RESULT([inode_operations_setattr_mnt_idmap], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_IDMAP_IOPS_SETATTR, 1,
[iops->setattr() takes struct mnt_idmap*])
],[
AC_MSG_RESULT(no)
dnl #
dnl # Kernel 5.12 test
dnl #
AC_MSG_CHECKING([whether iops->setattr() takes user_namespace])
ZFS_LINUX_TEST_RESULT([inode_operations_setattr_userns], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_USERNS_IOPS_SETATTR, 1,
[iops->setattr() takes struct user_namespace*])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether iops->setattr() exists])
ZFS_LINUX_TEST_RESULT([inode_operations_setattr], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_IOPS_SETATTR, 1,
[iops->setattr() exists])
],[
AC_MSG_RESULT(no)
])
])
])
])

View File

@ -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])
],[
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])
])
])
])
])

View File

@ -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
@ -42,6 +58,16 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
])
AC_DEFUN([ZFS_AC_KERNEL_MKDIR], [
dnl #
dnl # 6.3 API change
dnl # mkdir() takes struct mnt_idmap * as the first arg
dnl #
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_IDMAP, 1,
[iops->mkdir() takes struct mnt_idmap*])
],[
dnl #
dnl # 5.12 API change
dnl # The struct user_namespace arg was added as the first argument to
@ -65,3 +91,4 @@ AC_DEFUN([ZFS_AC_KERNEL_MKDIR], [
])
])
])
])

View File

@ -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,6 +37,13 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
])
AC_DEFUN([ZFS_AC_KERNEL_MKNOD], [
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_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)
@ -28,3 +53,4 @@ AC_DEFUN([ZFS_AC_KERNEL_MKNOD], [
AC_MSG_RESULT(no)
])
])
])

View File

@ -33,9 +33,32 @@ 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 mnt_idmap*])
ZFS_LINUX_TEST_RESULT([inode_operations_rename_mnt_idmap], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_IOPS_RENAME_IDMAP, 1,
[iops->rename() takes struct mnt_idmap*])
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether iops->rename() takes struct user_namespace*])
ZFS_LINUX_TEST_RESULT([inode_operations_rename_userns], [
AC_MSG_RESULT(yes)
@ -44,7 +67,7 @@ AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
],[
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether iop->rename() wants flags])
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,
@ -54,3 +77,4 @@ AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
])
])
])
])

View File

@ -27,9 +27,30 @@ 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 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_IDMAP, 1,
[setattr_prepare() accepts mnt_idmap])
], [
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], [
@ -50,3 +71,4 @@ AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
])
])
])
])

View File

@ -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,6 +35,12 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SYMLINK], [
])
AC_DEFUN([ZFS_AC_KERNEL_SYMLINK], [
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_IDMAP, 1,
[iops->symlink() takes struct mnt_idmap*])
],[
AC_MSG_CHECKING([whether iops->symlink() takes struct user_namespace*])
ZFS_LINUX_TEST_RESULT([symlink_userns], [
AC_MSG_RESULT(yes)
@ -28,3 +50,4 @@ AC_DEFUN([ZFS_AC_KERNEL_SYMLINK], [
AC_MSG_RESULT(no)
])
])
])

View File

@ -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,6 +57,11 @@ 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_mnt_idmap], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_TMPFILE, 1, [i_op->tmpfile() exists])
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])
@ -65,3 +83,4 @@ AC_DEFUN([ZFS_AC_KERNEL_TMPFILE], [
])
])
])
])

View File

@ -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,6 +255,15 @@ 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 #
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_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)
@ -292,6 +316,7 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
])
])
])
])
dnl #
dnl # Supported xattr handler list() interfaces checked newest to oldest.

View File

@ -69,6 +69,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE
ZFS_AC_KERNEL_SRC_XATTR
ZFS_AC_KERNEL_SRC_ACL
ZFS_AC_KERNEL_SRC_INODE_SETATTR
ZFS_AC_KERNEL_SRC_INODE_GETATTR
ZFS_AC_KERNEL_SRC_INODE_SET_FLAGS
ZFS_AC_KERNEL_SRC_INODE_SET_IVERSION
@ -130,7 +131,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
@ -194,6 +195,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE
ZFS_AC_KERNEL_XATTR
ZFS_AC_KERNEL_ACL
ZFS_AC_KERNEL_INODE_SETATTR
ZFS_AC_KERNEL_INODE_GETATTR
ZFS_AC_KERNEL_INODE_SET_FLAGS
ZFS_AC_KERNEL_INODE_SET_IVERSION
@ -255,7 +257,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

View File

@ -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

View File

@ -133,20 +133,35 @@ 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(user_ns, 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, \
struct dentry *dentry, struct inode *inode, const char *name, \
const void *buffer, size_t size, int flags) \
{ \
return (__ ## fn(inode, name, buffer, size, flags)); \
return (__ ## fn(user_ns, inode, name, buffer, size, flags)); \
}
/*
* 4.7 API change,
@ -160,7 +175,7 @@ fn(const struct xattr_handler *handler, struct dentry *dentry, \
struct inode *inode, const char *name, const void *buffer, \
size_t size, int flags) \
{ \
return (__ ## fn(inode, name, buffer, size, flags)); \
return (__ ## fn(kcred->user_ns, inode, name, buffer, size, flags));\
}
/*
* 4.4 API change,
@ -174,7 +189,8 @@ static int \
fn(const struct xattr_handler *handler, struct dentry *dentry, \
const char *name, const void *buffer, size_t size, int flags) \
{ \
return (__ ## fn(dentry->d_inode, name, buffer, size, flags)); \
return (__ ## fn(kcred->user_ns, dentry->d_inode, name, \
buffer, size, flags)); \
}
/*
* 2.6.33 API change,
@ -187,7 +203,8 @@ static int \
fn(struct dentry *dentry, const char *name, const void *buffer, \
size_t size, int flags, int unused_handler_flags) \
{ \
return (__ ## fn(dentry->d_inode, name, buffer, size, flags)); \
return (__ ## fn(kcred->user_ns, dentry->d_inode, name, buffer, \
size, flags)); \
}
#else
#error "Unsupported kernel"

View File

@ -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);

View File

@ -54,4 +54,18 @@ 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;
#else
typedef struct user_namespace zidmap_t;
#endif
extern zidmap_t *zfs_init_idmap;
#endif /* _SPL_TYPES_H */

View File

@ -54,8 +54,7 @@ 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 user_namespace *, struct inode *ip,
struct kstat *sp);
extern int zfs_getattr_fast(zidmap_t *, 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);

View File

@ -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
/*

View File

@ -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);

View File

@ -124,7 +124,7 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
if (crgetuid(cr) == owner)
return (0);
if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
if (zpl_inode_owner_or_capable(zfs_init_idmap, ip))
return (0);
#if defined(CONFIG_USER_NS)

View File

@ -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);
}

View File

@ -1675,8 +1675,7 @@ out:
*/
/* ARGSUSED */
int
zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
struct kstat *sp)
zfs_getattr_fast(zidmap_t *user_ns, struct inode *ip, struct kstat *sp)
{
znode_t *zp = ITOZ(ip);
zfsvfs_t *zfsvfs = ITOZSB(ip);

View File

@ -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);

View File

@ -978,7 +978,7 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
!capable(CAP_LINUX_IMMUTABLE))
return (-EPERM);
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
if (!zpl_inode_owner_or_capable(zfs_init_idmap, ip))
return (-EACCES);
xva_init(xva);

View File

@ -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);
@ -441,9 +457,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
#ifdef HAVE_USERNS_IOPS_SETATTR
zpl_setattr(struct user_namespace *user_ns, struct dentry *dentry,
struct iattr *ia)
#elif defined(HAVE_IDMAP_IOPS_SETATTR)
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,13 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
int error;
fstrans_cookie_t cookie;
error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
#ifdef HAVE_SETATTR_PREPARE_USERNS
error = zpl_setattr_prepare(user_ns, dentry, ia);
#elif defined(HAVE_SETATTR_PREPARE_IDMAP)
error = zpl_setattr_prepare(user_ns, dentry, ia);
#else
error = zpl_setattr_prepare(zfs_init_idmap, dentry, ia);
#endif
if (error)
return (error);
@ -489,10 +514,14 @@ 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)
unsigned int rflags)
#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 rflags)
#else
zpl_rename2(struct inode *sdip, struct dentry *sdentry,
struct inode *tdip, struct dentry *tdentry, unsigned int flags)
struct inode *tdip, struct dentry *tdentry, unsigned int rflags)
#endif
{
cred_t *cr = CRED();
@ -500,7 +529,7 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
fstrans_cookie_t cookie;
/* We don't have renameat2(2) support */
if (flags)
if (rflags)
return (-EINVAL);
crhold(cr);
@ -514,7 +543,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 +558,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 +779,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

View File

@ -725,9 +725,11 @@ __zpl_xattr_user_get(struct inode *ip, const char *name,
ZPL_XATTR_GET_WRAPPER(zpl_xattr_user_get);
static int
__zpl_xattr_user_set(struct inode *ip, const char *name,
__zpl_xattr_user_set(zidmap_t *user_ns,
struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
(void) user_ns;
char *xattr_name;
int error;
/* xattr_resolve_name will do this for us if this is defined */
@ -794,9 +796,11 @@ __zpl_xattr_trusted_get(struct inode *ip, const char *name,
ZPL_XATTR_GET_WRAPPER(zpl_xattr_trusted_get);
static int
__zpl_xattr_trusted_set(struct inode *ip, const char *name,
__zpl_xattr_trusted_set(zidmap_t *user_ns,
struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
(void) user_ns;
char *xattr_name;
int error;
@ -863,9 +867,11 @@ __zpl_xattr_security_get(struct inode *ip, const char *name,
ZPL_XATTR_GET_WRAPPER(zpl_xattr_security_get);
static int
__zpl_xattr_security_set(struct inode *ip, const char *name,
__zpl_xattr_security_set(zidmap_t *user_ns,
struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
(void) user_ns;
char *xattr_name;
int error;
/* xattr_resolve_name will do this for us if this is defined */
@ -889,7 +895,7 @@ zpl_xattr_security_init_impl(struct inode *ip, const struct xattr *xattrs,
int error = 0;
for (xattr = xattrs; xattr->name != NULL; xattr++) {
error = __zpl_xattr_security_set(ip,
error = __zpl_xattr_security_set(NULL, ip,
xattr->name, xattr->value, xattr->value_len, 0);
if (error < 0)
@ -1004,6 +1010,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 +1022,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 defined(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 */
@ -1256,7 +1267,8 @@ __zpl_xattr_acl_get_default(struct inode *ip, const char *name,
ZPL_XATTR_GET_WRAPPER(zpl_xattr_acl_get_default);
static int
__zpl_xattr_acl_set_access(struct inode *ip, const char *name,
__zpl_xattr_acl_set_access(zidmap_t *mnt_ns,
struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
struct posix_acl *acl;
@ -1270,8 +1282,14 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (-EOPNOTSUPP);
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
#if defined(HAVE_XATTR_SET_USERNS) || defined(HAVE_XATTR_SET_IDMAP)
if (!zpl_inode_owner_or_capable(mnt_ns, ip))
return (-EPERM);
#else
(void) mnt_ns;
if (!zpl_inode_owner_or_capable(zfs_init_idmap, ip))
return (-EPERM);
#endif
if (value) {
acl = zpl_acl_from_xattr(value, size);
@ -1295,7 +1313,8 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
ZPL_XATTR_SET_WRAPPER(zpl_xattr_acl_set_access);
static int
__zpl_xattr_acl_set_default(struct inode *ip, const char *name,
__zpl_xattr_acl_set_default(zidmap_t *mnt_ns,
struct inode *ip, const char *name,
const void *value, size_t size, int flags)
{
struct posix_acl *acl;
@ -1309,8 +1328,14 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name,
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
return (-EOPNOTSUPP);
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
#if defined(HAVE_XATTR_SET_USERNS) || defined(HAVE_XATTR_SET_IDMAP)
if (!zpl_inode_owner_or_capable(mnt_ns, ip))
return (-EPERM);
#else
(void) mnt_ns;
if (!zpl_inode_owner_or_capable(zfs_init_idmap, ip))
return (-EPERM);
#endif
if (value) {
acl = zpl_acl_from_xattr(value, size);