mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 03:09:34 +03:00
Linux 5.12 compat: idmapped mounts
In Linux 5.12, the filesystem API was modified to support ipmapped mounts by adding a "struct user_namespace *" parameter to a number functions and VFS handlers. This change adds the needed autoconf macros to detect the new interfaces and updates the code appropriately. This change does not add support for idmapped mounts, instead it preserves the existing behavior by passing the initial user namespace where needed. A subsequent commit will be required to add support for idmapped mounted. Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Co-authored-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Coleman Kane <ckane@colemankane.org> Closes #11712
This commit is contained in:
parent
330c6c0523
commit
e2a8296131
28
config/kernel-generic_fillattr.m4
Normal file
28
config/kernel-generic_fillattr.m4
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
dnl #
|
||||||
|
dnl # 5.12 API
|
||||||
|
dnl #
|
||||||
|
dnl # generic_fillattr in linux/fs.h now requires a struct user_namespace*
|
||||||
|
dnl # as the first arg, to support idmapped mounts.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS], [
|
||||||
|
ZFS_LINUX_TEST_SRC([generic_fillattr_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
struct user_namespace *userns = NULL;
|
||||||
|
struct inode *in = NULL;
|
||||||
|
struct kstat *k = NULL;
|
||||||
|
generic_fillattr(userns, in, k);
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS], [
|
||||||
|
AC_MSG_CHECKING([whether generic_fillattr requres struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([generic_fillattr_userns], [
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
AC_DEFINE(HAVE_GENERIC_FILLATTR_USERNS, 1,
|
||||||
|
[generic_fillattr requires struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
@ -1,7 +1,25 @@
|
|||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change that added the struct user_namespace* arg
|
||||||
|
dnl # to the front of this function type's arg list.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([create_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
|
int inode_create(struct user_namespace *userns,
|
||||||
|
struct inode *inode ,struct dentry *dentry,
|
||||||
|
umode_t umode, bool flag) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.create = inode_create,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 3.6 API change
|
dnl # 3.6 API change
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
|
|
||||||
ZFS_LINUX_TEST_SRC([create_flags], [
|
ZFS_LINUX_TEST_SRC([create_flags], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
@ -16,7 +34,15 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_CREATE_FLAGS], [
|
|||||||
],[])
|
],[])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_CREATE_FLAGS], [
|
AC_DEFUN([ZFS_AC_KERNEL_CREATE], [
|
||||||
|
AC_MSG_CHECKING([whether iops->create() takes struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([create_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_CREATE_USERNS, 1,
|
||||||
|
[iops->create() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether iops->create() passes flags])
|
AC_MSG_CHECKING([whether iops->create() passes flags])
|
||||||
ZFS_LINUX_TEST_RESULT([create_flags], [
|
ZFS_LINUX_TEST_RESULT([create_flags], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
@ -24,3 +50,4 @@ AC_DEFUN([ZFS_AC_KERNEL_CREATE_FLAGS], [
|
|||||||
ZFS_LINUX_TEST_ERROR([iops->create()])
|
ZFS_LINUX_TEST_ERROR([iops->create()])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
|
@ -1,8 +1,29 @@
|
|||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.12 API
|
||||||
|
dnl # The getattr I/O operations handler type was extended to require
|
||||||
|
dnl # a struct user_namespace* as its first arg, to support idmapped
|
||||||
|
dnl # mounts.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_getattr_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
int test_getattr(
|
||||||
|
struct user_namespace *userns,
|
||||||
|
const struct path *p, struct kstat *k,
|
||||||
|
u32 request_mask, unsigned int query_flags)
|
||||||
|
{ return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.getattr = test_getattr,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Linux 4.11 API
|
dnl # Linux 4.11 API
|
||||||
dnl # See torvalds/linux@a528d35
|
dnl # See torvalds/linux@a528d35
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
|
ZFS_LINUX_TEST_SRC([inode_operations_getattr_path], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
|
|
||||||
@ -33,6 +54,20 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GETATTR], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
||||||
|
dnl #
|
||||||
|
dnl # Kernel 5.12 test
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether iops->getattr() takes user_namespace])
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_USERNS_IOPS_GETATTR, 1,
|
||||||
|
[iops->getattr() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Kernel 4.11 test
|
||||||
|
dnl #
|
||||||
AC_MSG_CHECKING([whether iops->getattr() takes a path])
|
AC_MSG_CHECKING([whether iops->getattr() takes a path])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_path], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
@ -41,6 +76,9 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
|||||||
],[
|
],[
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # Kernel < 4.11 test
|
||||||
|
dnl #
|
||||||
AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
|
AC_MSG_CHECKING([whether iops->getattr() takes a vfsmount])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_getattr_vfsmount], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
@ -51,3 +89,4 @@ AC_DEFUN([ZFS_AC_KERNEL_INODE_GETATTR], [
|
|||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
|
@ -11,13 +11,32 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_OWNER_OR_CAPABLE], [
|
|||||||
struct inode *ip = NULL;
|
struct inode *ip = NULL;
|
||||||
(void) inode_owner_or_capable(ip);
|
(void) inode_owner_or_capable(ip);
|
||||||
])
|
])
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_owner_or_capable_idmapped], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
],[
|
||||||
|
struct inode *ip = NULL;
|
||||||
|
(void) inode_owner_or_capable(&init_user_ns, ip);
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
|
AC_DEFUN([ZFS_AC_KERNEL_INODE_OWNER_OR_CAPABLE], [
|
||||||
AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
|
AC_MSG_CHECKING([whether inode_owner_or_capable() exists])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
|
ZFS_LINUX_TEST_RESULT([inode_owner_or_capable], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE, 1,
|
||||||
|
[inode_owner_or_capable() exists])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(
|
||||||
|
[whether inode_owner_or_capable() takes user_ns])
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_owner_or_capable_idmapped], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED, 1,
|
||||||
|
[inode_owner_or_capable() takes user_ns])
|
||||||
],[
|
],[
|
||||||
ZFS_LINUX_TEST_ERROR([capability])
|
ZFS_LINUX_TEST_ERROR([capability])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
dnl #
|
|
||||||
dnl # 3.3 API change
|
|
||||||
dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
|
|
||||||
dnl # umode_t type rather than an int. The expectation is that any backport
|
|
||||||
dnl # would also change all three prototypes. However, if it turns out that
|
|
||||||
dnl # some distribution doesn't backport the whole thing this could be
|
|
||||||
dnl # broken apart into three separate checks.
|
|
||||||
dnl #
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T], [
|
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
|
|
||||||
#include <linux/fs.h>
|
|
||||||
|
|
||||||
int mkdir(struct inode *inode, struct dentry *dentry,
|
|
||||||
umode_t umode) { return 0; }
|
|
||||||
|
|
||||||
static const struct inode_operations
|
|
||||||
iops __attribute__ ((unused)) = {
|
|
||||||
.mkdir = mkdir,
|
|
||||||
};
|
|
||||||
],[])
|
|
||||||
])
|
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_MKDIR_UMODE_T], [
|
|
||||||
AC_MSG_CHECKING([whether iops->create()/mkdir()/mknod() take umode_t])
|
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
|
|
||||||
[iops->create()/mkdir()/mknod() take umode_t])
|
|
||||||
],[
|
|
||||||
ZFS_LINUX_TEST_ERROR([mkdir()])
|
|
||||||
])
|
|
||||||
])
|
|
65
config/kernel-mkdir.m4
Normal file
65
config/kernel-mkdir.m4
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
dnl #
|
||||||
|
dnl # Supported mkdir() interfaces checked newest to oldest.
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_MKDIR], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change
|
||||||
|
dnl # The struct user_namespace arg was added as the first argument to
|
||||||
|
dnl # mkdir()
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([mkdir_user_namespace], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
int mkdir(struct user_namespace *userns,
|
||||||
|
struct inode *inode, struct dentry *dentry,
|
||||||
|
umode_t umode) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.mkdir = mkdir,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 3.3 API change
|
||||||
|
dnl # The VFS .create, .mkdir and .mknod callbacks were updated to take a
|
||||||
|
dnl # umode_t type rather than an int. The expectation is that any backport
|
||||||
|
dnl # would also change all three prototypes. However, if it turns out that
|
||||||
|
dnl # some distribution doesn't backport the whole thing this could be
|
||||||
|
dnl # broken apart into three separate checks.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_mkdir], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
|
||||||
|
int mkdir(struct inode *inode, struct dentry *dentry,
|
||||||
|
umode_t umode) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.mkdir = mkdir,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_MKDIR], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change
|
||||||
|
dnl # The struct user_namespace arg was added as the first argument to
|
||||||
|
dnl # mkdir() of the iops structure.
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether iops->mkdir() takes struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([mkdir_user_namespace], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_MKDIR_USERNS, 1,
|
||||||
|
[iops->mkdir() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_CHECKING([whether iops->mkdir() takes umode_t])
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_mkdir], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_MKDIR_UMODE_T, 1,
|
||||||
|
[iops->mkdir() takes umode_t])
|
||||||
|
],[
|
||||||
|
ZFS_LINUX_TEST_ERROR([mkdir()])
|
||||||
|
])
|
||||||
|
])
|
||||||
|
])
|
30
config/kernel-mknod.m4
Normal file
30
config/kernel-mknod.m4
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_MKNOD], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change that added the struct user_namespace* arg
|
||||||
|
dnl # to the front of this function type's arg list.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([mknod_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
|
int tmp_mknod(struct user_namespace *userns,
|
||||||
|
struct inode *inode ,struct dentry *dentry,
|
||||||
|
umode_t u, dev_t d) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.mknod = tmp_mknod,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_MKNOD], [
|
||||||
|
AC_MSG_CHECKING([whether iops->mknod() takes struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([mknod_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_MKNOD_USERNS, 1,
|
||||||
|
[iops->mknod() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
@ -1,10 +1,10 @@
|
|||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME], [
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 4.9 API change,
|
dnl # 4.9 API change,
|
||||||
dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
|
dnl # iops->rename2() merged into iops->rename(), and iops->rename() now wants
|
||||||
dnl # flags.
|
dnl # flags.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
|
ZFS_LINUX_TEST_SRC([inode_operations_rename_flags], [
|
||||||
ZFS_LINUX_TEST_SRC([inode_operations_rename], [
|
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
int rename_fn(struct inode *sip, struct dentry *sdp,
|
int rename_fn(struct inode *sip, struct dentry *sdp,
|
||||||
struct inode *tip, struct dentry *tdp,
|
struct inode *tip, struct dentry *tdp,
|
||||||
@ -15,11 +15,36 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS], [
|
|||||||
.rename = rename_fn,
|
.rename = rename_fn,
|
||||||
};
|
};
|
||||||
],[])
|
],[])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change,
|
||||||
|
dnl #
|
||||||
|
dnl # Linux 5.12 introduced passing struct user_namespace* as the first argument
|
||||||
|
dnl # of the rename() and other inode_operations members.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([inode_operations_rename_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
int rename_fn(struct user_namespace *user_ns, struct inode *sip,
|
||||||
|
struct dentry *sdp, struct inode *tip, struct dentry *tdp,
|
||||||
|
unsigned int flags) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.rename = rename_fn,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
|
AC_DEFUN([ZFS_AC_KERNEL_RENAME], [
|
||||||
AC_MSG_CHECKING([whether iops->rename() wants flags])
|
AC_MSG_CHECKING([whether iops->rename() takes struct user_namespace*])
|
||||||
ZFS_LINUX_TEST_RESULT([inode_operations_rename], [
|
ZFS_LINUX_TEST_RESULT([inode_operations_rename_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_RENAME_USERNS, 1,
|
||||||
|
[iops->rename() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
|
||||||
|
ZFS_LINUX_TEST_RESULT([inode_operations_rename_flags], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
|
AC_DEFINE(HAVE_RENAME_WANTS_FLAGS, 1,
|
||||||
[iops->rename() wants flags])
|
[iops->rename() wants flags])
|
||||||
@ -27,3 +52,4 @@ AC_DEFUN([ZFS_AC_KERNEL_RENAME_WANTS_FLAGS], [
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 4.9 API change
|
dnl # 4.9 API change
|
||||||
dnl # The inode_change_ok() function has been renamed setattr_prepare()
|
dnl # The inode_change_ok() function has been renamed setattr_prepare()
|
||||||
dnl # and updated to take a dentry rather than an inode.
|
dnl # and updated to take a dentry rather than an inode.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
|
|
||||||
ZFS_LINUX_TEST_SRC([setattr_prepare], [
|
ZFS_LINUX_TEST_SRC([setattr_prepare], [
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
], [
|
], [
|
||||||
@ -12,16 +12,41 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_SETATTR_PREPARE], [
|
|||||||
int error __attribute__ ((unused)) =
|
int error __attribute__ ((unused)) =
|
||||||
setattr_prepare(dentry, attr);
|
setattr_prepare(dentry, attr);
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change
|
||||||
|
dnl # The setattr_prepare() function has been changed to accept a new argument
|
||||||
|
dnl # for struct user_namespace*
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([setattr_prepare_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
], [
|
||||||
|
struct dentry *dentry = NULL;
|
||||||
|
struct iattr *attr = NULL;
|
||||||
|
struct user_namespace *userns = NULL;
|
||||||
|
int error __attribute__ ((unused)) =
|
||||||
|
setattr_prepare(userns, dentry, attr);
|
||||||
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
|
AC_DEFUN([ZFS_AC_KERNEL_SETATTR_PREPARE], [
|
||||||
AC_MSG_CHECKING([whether setattr_prepare() is available])
|
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_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],
|
ZFS_LINUX_TEST_RESULT_SYMBOL([setattr_prepare],
|
||||||
[setattr_prepare], [fs/attr.c], [
|
[setattr_prepare], [fs/attr.c], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
AC_DEFINE(HAVE_SETATTR_PREPARE, 1,
|
AC_DEFINE(HAVE_SETATTR_PREPARE_NO_USERNS, 1,
|
||||||
[setattr_prepare() is available])
|
[setattr_prepare() is available, doesn't accept user_namespace])
|
||||||
], [
|
], [
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
|
30
config/kernel-symlink.m4
Normal file
30
config/kernel-symlink.m4
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_SYMLINK], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change that added the struct user_namespace* arg
|
||||||
|
dnl # to the front of this function type's arg list.
|
||||||
|
dnl #
|
||||||
|
ZFS_LINUX_TEST_SRC([symlink_userns], [
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
|
int tmp_symlink(struct user_namespace *userns,
|
||||||
|
struct inode *inode ,struct dentry *dentry,
|
||||||
|
const char *path) { return 0; }
|
||||||
|
|
||||||
|
static const struct inode_operations
|
||||||
|
iops __attribute__ ((unused)) = {
|
||||||
|
.symlink = tmp_symlink,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([ZFS_AC_KERNEL_SYMLINK], [
|
||||||
|
AC_MSG_CHECKING([whether iops->symlink() takes struct user_namespace*])
|
||||||
|
ZFS_LINUX_TEST_RESULT([symlink_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_IOPS_SYMLINK_USERNS, 1,
|
||||||
|
[iops->symlink() takes struct user_namespace*])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
])
|
@ -152,6 +152,21 @@ dnl #
|
|||||||
dnl # Supported xattr handler set() interfaces checked newest to oldest.
|
dnl # Supported xattr handler set() interfaces checked newest to oldest.
|
||||||
dnl #
|
dnl #
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
|
AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
|
||||||
|
ZFS_LINUX_TEST_SRC([xattr_handler_set_userns], [
|
||||||
|
#include <linux/xattr.h>
|
||||||
|
|
||||||
|
int set(const struct xattr_handler *handler,
|
||||||
|
struct user_namespace *mnt_userns,
|
||||||
|
struct dentry *dentry, struct inode *inode,
|
||||||
|
const char *name, const void *buffer,
|
||||||
|
size_t size, int flags)
|
||||||
|
{ return 0; }
|
||||||
|
static const struct xattr_handler
|
||||||
|
xops __attribute__ ((unused)) = {
|
||||||
|
.set = set,
|
||||||
|
};
|
||||||
|
],[])
|
||||||
|
|
||||||
ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
|
ZFS_LINUX_TEST_SRC([xattr_handler_set_dentry_inode], [
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
|
|
||||||
@ -193,11 +208,23 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_SET], [
|
|||||||
])
|
])
|
||||||
|
|
||||||
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
||||||
|
dnl #
|
||||||
|
dnl # 5.12 API change,
|
||||||
|
dnl # The xattr_handler->set() callback was changed to 8 arguments, and
|
||||||
|
dnl # struct user_namespace* was inserted as arg #2
|
||||||
|
dnl #
|
||||||
|
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry, inode, and user_namespace])
|
||||||
|
ZFS_LINUX_TEST_RESULT([xattr_handler_set_userns], [
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_XATTR_SET_USERNS, 1,
|
||||||
|
[xattr_handler->set() takes user_namespace])
|
||||||
|
],[
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 4.7 API change,
|
dnl # 4.7 API change,
|
||||||
dnl # The xattr_handler->set() callback was changed to take both
|
dnl # The xattr_handler->set() callback was changed to take both
|
||||||
dnl # dentry and inode.
|
dnl # dentry and inode.
|
||||||
dnl #
|
dnl #
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
|
AC_MSG_CHECKING([whether xattr_handler->set() wants dentry and inode])
|
||||||
ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
|
ZFS_LINUX_TEST_RESULT([xattr_handler_set_dentry_inode], [
|
||||||
AC_MSG_RESULT(yes)
|
AC_MSG_RESULT(yes)
|
||||||
@ -237,6 +264,7 @@ AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_SET], [
|
|||||||
])
|
])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # Supported xattr handler list() interfaces checked newest to oldest.
|
dnl # Supported xattr handler list() interfaces checked newest to oldest.
|
||||||
|
@ -79,9 +79,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
|||||||
ZFS_AC_KERNEL_SRC_EVICT_INODE
|
ZFS_AC_KERNEL_SRC_EVICT_INODE
|
||||||
ZFS_AC_KERNEL_SRC_DIRTY_INODE
|
ZFS_AC_KERNEL_SRC_DIRTY_INODE
|
||||||
ZFS_AC_KERNEL_SRC_SHRINKER
|
ZFS_AC_KERNEL_SRC_SHRINKER
|
||||||
ZFS_AC_KERNEL_SRC_MKDIR_UMODE_T
|
ZFS_AC_KERNEL_SRC_MKDIR
|
||||||
ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS
|
ZFS_AC_KERNEL_SRC_LOOKUP_FLAGS
|
||||||
ZFS_AC_KERNEL_SRC_CREATE_FLAGS
|
ZFS_AC_KERNEL_SRC_CREATE
|
||||||
ZFS_AC_KERNEL_SRC_GET_LINK
|
ZFS_AC_KERNEL_SRC_GET_LINK
|
||||||
ZFS_AC_KERNEL_SRC_PUT_LINK
|
ZFS_AC_KERNEL_SRC_PUT_LINK
|
||||||
ZFS_AC_KERNEL_SRC_TMPFILE
|
ZFS_AC_KERNEL_SRC_TMPFILE
|
||||||
@ -115,7 +115,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
|||||||
ZFS_AC_KERNEL_SRC_KUIDGID_T
|
ZFS_AC_KERNEL_SRC_KUIDGID_T
|
||||||
ZFS_AC_KERNEL_SRC_KUID_HELPERS
|
ZFS_AC_KERNEL_SRC_KUID_HELPERS
|
||||||
ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
|
ZFS_AC_KERNEL_SRC_MODULE_PARAM_CALL_CONST
|
||||||
ZFS_AC_KERNEL_SRC_RENAME_WANTS_FLAGS
|
ZFS_AC_KERNEL_SRC_RENAME
|
||||||
ZFS_AC_KERNEL_SRC_CURRENT_TIME
|
ZFS_AC_KERNEL_SRC_CURRENT_TIME
|
||||||
ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
|
ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES
|
||||||
ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
|
ZFS_AC_KERNEL_SRC_IN_COMPAT_SYSCALL
|
||||||
@ -125,6 +125,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
|||||||
ZFS_AC_KERNEL_SRC_KSTRTOUL
|
ZFS_AC_KERNEL_SRC_KSTRTOUL
|
||||||
ZFS_AC_KERNEL_SRC_PERCPU
|
ZFS_AC_KERNEL_SRC_PERCPU
|
||||||
ZFS_AC_KERNEL_SRC_CPU_HOTPLUG
|
ZFS_AC_KERNEL_SRC_CPU_HOTPLUG
|
||||||
|
ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS
|
||||||
|
ZFS_AC_KERNEL_SRC_MKNOD
|
||||||
|
ZFS_AC_KERNEL_SRC_SYMLINK
|
||||||
|
|
||||||
AC_MSG_CHECKING([for available kernel interfaces])
|
AC_MSG_CHECKING([for available kernel interfaces])
|
||||||
ZFS_LINUX_TEST_COMPILE_ALL([kabi])
|
ZFS_LINUX_TEST_COMPILE_ALL([kabi])
|
||||||
@ -177,9 +180,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
|||||||
ZFS_AC_KERNEL_EVICT_INODE
|
ZFS_AC_KERNEL_EVICT_INODE
|
||||||
ZFS_AC_KERNEL_DIRTY_INODE
|
ZFS_AC_KERNEL_DIRTY_INODE
|
||||||
ZFS_AC_KERNEL_SHRINKER
|
ZFS_AC_KERNEL_SHRINKER
|
||||||
ZFS_AC_KERNEL_MKDIR_UMODE_T
|
ZFS_AC_KERNEL_MKDIR
|
||||||
ZFS_AC_KERNEL_LOOKUP_FLAGS
|
ZFS_AC_KERNEL_LOOKUP_FLAGS
|
||||||
ZFS_AC_KERNEL_CREATE_FLAGS
|
ZFS_AC_KERNEL_CREATE
|
||||||
ZFS_AC_KERNEL_GET_LINK
|
ZFS_AC_KERNEL_GET_LINK
|
||||||
ZFS_AC_KERNEL_PUT_LINK
|
ZFS_AC_KERNEL_PUT_LINK
|
||||||
ZFS_AC_KERNEL_TMPFILE
|
ZFS_AC_KERNEL_TMPFILE
|
||||||
@ -213,7 +216,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
|||||||
ZFS_AC_KERNEL_KUIDGID_T
|
ZFS_AC_KERNEL_KUIDGID_T
|
||||||
ZFS_AC_KERNEL_KUID_HELPERS
|
ZFS_AC_KERNEL_KUID_HELPERS
|
||||||
ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
|
ZFS_AC_KERNEL_MODULE_PARAM_CALL_CONST
|
||||||
ZFS_AC_KERNEL_RENAME_WANTS_FLAGS
|
ZFS_AC_KERNEL_RENAME
|
||||||
ZFS_AC_KERNEL_CURRENT_TIME
|
ZFS_AC_KERNEL_CURRENT_TIME
|
||||||
ZFS_AC_KERNEL_USERNS_CAPABILITIES
|
ZFS_AC_KERNEL_USERNS_CAPABILITIES
|
||||||
ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
|
ZFS_AC_KERNEL_IN_COMPAT_SYSCALL
|
||||||
@ -223,6 +226,9 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
|||||||
ZFS_AC_KERNEL_KSTRTOUL
|
ZFS_AC_KERNEL_KSTRTOUL
|
||||||
ZFS_AC_KERNEL_PERCPU
|
ZFS_AC_KERNEL_PERCPU
|
||||||
ZFS_AC_KERNEL_CPU_HOTPLUG
|
ZFS_AC_KERNEL_CPU_HOTPLUG
|
||||||
|
ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
|
||||||
|
ZFS_AC_KERNEL_MKNOD
|
||||||
|
ZFS_AC_KERNEL_SYMLINK
|
||||||
])
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
|
@ -343,7 +343,8 @@ static inline void zfs_gid_write(struct inode *ip, gid_t gid)
|
|||||||
/*
|
/*
|
||||||
* 4.9 API change
|
* 4.9 API change
|
||||||
*/
|
*/
|
||||||
#ifndef HAVE_SETATTR_PREPARE
|
#if !(defined(HAVE_SETATTR_PREPARE_NO_USERNS) || \
|
||||||
|
defined(HAVE_SETATTR_PREPARE_USERNS))
|
||||||
static inline int
|
static inline int
|
||||||
setattr_prepare(struct dentry *dentry, struct iattr *ia)
|
setattr_prepare(struct dentry *dentry, struct iattr *ia)
|
||||||
{
|
{
|
||||||
@ -389,6 +390,15 @@ func(const struct path *path, struct kstat *stat, u32 request_mask, \
|
|||||||
{ \
|
{ \
|
||||||
return (func##_impl(path, stat, request_mask, query_flags)); \
|
return (func##_impl(path, stat, request_mask, query_flags)); \
|
||||||
}
|
}
|
||||||
|
#elif defined(HAVE_USERNS_IOPS_GETATTR)
|
||||||
|
#define ZPL_GETATTR_WRAPPER(func) \
|
||||||
|
static int \
|
||||||
|
func(struct user_namespace *user_ns, const struct path *path, \
|
||||||
|
struct kstat *stat, u32 request_mask, unsigned int query_flags) \
|
||||||
|
{ \
|
||||||
|
return (func##_impl(user_ns, path, stat, request_mask, \
|
||||||
|
query_flags)); \
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
@ -436,4 +446,16 @@ zpl_is_32bit_api(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5.12 API change
|
||||||
|
* To support id-mapped mounts, generic_fillattr() was modified to
|
||||||
|
* accept a new struct user_namespace* as its first arg.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_GENERIC_FILLATTR_USERNS
|
||||||
|
#define zpl_generic_fillattr(user_ns, ip, sp) \
|
||||||
|
generic_fillattr(user_ns, ip, sp)
|
||||||
|
#else
|
||||||
|
#define zpl_generic_fillattr(user_ns, ip, sp) generic_fillattr(ip, sp)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _ZFS_VFS_H */
|
#endif /* _ZFS_VFS_H */
|
||||||
|
@ -119,12 +119,27 @@ fn(struct dentry *dentry, const char *name, void *buffer, size_t size, \
|
|||||||
#error "Unsupported kernel"
|
#error "Unsupported kernel"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5.12 API change,
|
||||||
|
* The xattr_handler->set() callback was changed to take the
|
||||||
|
* struct user_namespace* as the first arg, to support idmapped
|
||||||
|
* mounts.
|
||||||
|
*/
|
||||||
|
#if defined(HAVE_XATTR_SET_USERNS)
|
||||||
|
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||||
|
static int \
|
||||||
|
fn(const struct xattr_handler *handler, struct user_namespace *user_ns, \
|
||||||
|
struct dentry *dentry, struct inode *inode, const char *name, \
|
||||||
|
const void *buffer, size_t size, int flags) \
|
||||||
|
{ \
|
||||||
|
return (__ ## fn(inode, name, buffer, size, flags)); \
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* 4.7 API change,
|
* 4.7 API change,
|
||||||
* The xattr_handler->set() callback was changed to take a both dentry and
|
* The xattr_handler->set() callback was changed to take a both dentry and
|
||||||
* inode, because the dentry might not be attached to an inode yet.
|
* inode, because the dentry might not be attached to an inode yet.
|
||||||
*/
|
*/
|
||||||
#if defined(HAVE_XATTR_SET_DENTRY_INODE)
|
#elif defined(HAVE_XATTR_SET_DENTRY_INODE)
|
||||||
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
#define ZPL_XATTR_SET_WRAPPER(fn) \
|
||||||
static int \
|
static int \
|
||||||
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
fn(const struct xattr_handler *handler, struct dentry *dentry, \
|
||||||
|
@ -54,7 +54,8 @@ extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap,
|
|||||||
extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd,
|
extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd,
|
||||||
cred_t *cr, int flags);
|
cred_t *cr, int flags);
|
||||||
extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr);
|
extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr);
|
||||||
extern int zfs_getattr_fast(struct inode *ip, struct kstat *sp);
|
extern int zfs_getattr_fast(struct user_namespace *, struct inode *ip,
|
||||||
|
struct kstat *sp);
|
||||||
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
|
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
|
||||||
extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
|
extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
|
||||||
char *tnm, cred_t *cr, int flags);
|
char *tnm, cred_t *cr, int flags);
|
||||||
|
@ -171,4 +171,22 @@ zpl_dir_emit_dots(struct file *file, zpl_dir_context_t *ctx)
|
|||||||
timespec_trunc(ts, (ip)->i_sb->s_time_gran)
|
timespec_trunc(ts, (ip)->i_sb->s_time_gran)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_INODE_OWNER_OR_CAPABLE)
|
||||||
|
#define zpl_inode_owner_or_capable(ns, ip) inode_owner_or_capable(ip)
|
||||||
|
#elif defined(HAVE_INODE_OWNER_OR_CAPABLE_IDMAPPED)
|
||||||
|
#define zpl_inode_owner_or_capable(ns, ip) inode_owner_or_capable(ns, ip)
|
||||||
|
#else
|
||||||
|
#error "Unsupported kernel"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SETATTR_PREPARE_USERNS
|
||||||
|
#define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(ns, dentry, ia)
|
||||||
|
#else
|
||||||
|
/*
|
||||||
|
* Use kernel-provided version, or our own from
|
||||||
|
* linux/vfs_compat.h
|
||||||
|
*/
|
||||||
|
#define zpl_setattr_prepare(ns, dentry, ia) setattr_prepare(dentry, ia)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* _SYS_ZPL_H */
|
#endif /* _SYS_ZPL_H */
|
||||||
|
@ -124,7 +124,7 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
|
|||||||
if (crgetfsuid(cr) == owner)
|
if (crgetfsuid(cr) == owner)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
if (inode_owner_or_capable(ip))
|
if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
#if defined(CONFIG_USER_NS)
|
#if defined(CONFIG_USER_NS)
|
||||||
|
@ -1656,7 +1656,8 @@ out:
|
|||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
int
|
int
|
||||||
zfs_getattr_fast(struct inode *ip, struct kstat *sp)
|
zfs_getattr_fast(struct user_namespace *user_ns, struct inode *ip,
|
||||||
|
struct kstat *sp)
|
||||||
{
|
{
|
||||||
znode_t *zp = ITOZ(ip);
|
znode_t *zp = ITOZ(ip);
|
||||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||||
@ -1668,7 +1669,7 @@ zfs_getattr_fast(struct inode *ip, struct kstat *sp)
|
|||||||
|
|
||||||
mutex_enter(&zp->z_lock);
|
mutex_enter(&zp->z_lock);
|
||||||
|
|
||||||
generic_fillattr(ip, sp);
|
zpl_generic_fillattr(user_ns, ip, sp);
|
||||||
/*
|
/*
|
||||||
* +1 link count for root inode with visible '.zfs' directory.
|
* +1 link count for root inode with visible '.zfs' directory.
|
||||||
*/
|
*/
|
||||||
|
@ -101,12 +101,22 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_USERNS_IOPS_GETATTR
|
||||||
|
zpl_root_getattr_impl(struct user_namespace *user_ns,
|
||||||
|
const struct path *path, struct kstat *stat, u32 request_mask,
|
||||||
|
unsigned int query_flags)
|
||||||
|
#else
|
||||||
zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
|
zpl_root_getattr_impl(const struct path *path, struct kstat *stat,
|
||||||
u32 request_mask, unsigned int query_flags)
|
u32 request_mask, unsigned int query_flags)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct inode *ip = path->dentry->d_inode;
|
struct inode *ip = path->dentry->d_inode;
|
||||||
|
|
||||||
|
#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
|
||||||
|
generic_fillattr(user_ns, ip, stat);
|
||||||
|
#else
|
||||||
generic_fillattr(ip, stat);
|
generic_fillattr(ip, stat);
|
||||||
|
#endif
|
||||||
stat->atime = current_time(ip);
|
stat->atime = current_time(ip);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -290,8 +300,14 @@ zpl_snapdir_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
#endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
|
#endif /* !HAVE_VFS_ITERATE && !HAVE_VFS_ITERATE_SHARED */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_IOPS_RENAME_USERNS
|
||||||
|
zpl_snapdir_rename2(struct user_namespace *user_ns, struct inode *sdip,
|
||||||
|
struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
|
||||||
|
unsigned int flags)
|
||||||
|
#else
|
||||||
zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
|
zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
|
||||||
struct inode *tdip, struct dentry *tdentry, unsigned int flags)
|
struct inode *tdip, struct dentry *tdentry, unsigned int flags)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
int error;
|
int error;
|
||||||
@ -309,7 +325,7 @@ zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_RENAME_WANTS_FLAGS
|
#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
|
||||||
static int
|
static int
|
||||||
zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
|
zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
|
||||||
struct inode *tdip, struct dentry *tdentry)
|
struct inode *tdip, struct dentry *tdentry)
|
||||||
@ -333,7 +349,12 @@ zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_IOPS_MKDIR_USERNS
|
||||||
|
zpl_snapdir_mkdir(struct user_namespace *user_ns, struct inode *dip,
|
||||||
|
struct dentry *dentry, umode_t mode)
|
||||||
|
#else
|
||||||
zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
|
zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
vattr_t *vap;
|
vattr_t *vap;
|
||||||
@ -363,14 +384,24 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
|
|||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_USERNS_IOPS_GETATTR
|
||||||
|
zpl_snapdir_getattr_impl(struct user_namespace *user_ns,
|
||||||
|
const struct path *path, struct kstat *stat, u32 request_mask,
|
||||||
|
unsigned int query_flags)
|
||||||
|
#else
|
||||||
zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
|
zpl_snapdir_getattr_impl(const struct path *path, struct kstat *stat,
|
||||||
u32 request_mask, unsigned int query_flags)
|
u32 request_mask, unsigned int query_flags)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct inode *ip = path->dentry->d_inode;
|
struct inode *ip = path->dentry->d_inode;
|
||||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||||
|
|
||||||
ZPL_ENTER(zfsvfs);
|
ZPL_ENTER(zfsvfs);
|
||||||
|
#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
|
||||||
|
generic_fillattr(user_ns, ip, stat);
|
||||||
|
#else
|
||||||
generic_fillattr(ip, stat);
|
generic_fillattr(ip, stat);
|
||||||
|
#endif
|
||||||
|
|
||||||
stat->nlink = stat->size = 2;
|
stat->nlink = stat->size = 2;
|
||||||
stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
|
stat->ctime = stat->mtime = dmu_objset_snap_cmtime(zfsvfs->z_os);
|
||||||
@ -408,7 +439,7 @@ const struct file_operations zpl_fops_snapdir = {
|
|||||||
const struct inode_operations zpl_ops_snapdir = {
|
const struct inode_operations zpl_ops_snapdir = {
|
||||||
.lookup = zpl_snapdir_lookup,
|
.lookup = zpl_snapdir_lookup,
|
||||||
.getattr = zpl_snapdir_getattr,
|
.getattr = zpl_snapdir_getattr,
|
||||||
#ifdef HAVE_RENAME_WANTS_FLAGS
|
#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
|
||||||
.rename = zpl_snapdir_rename2,
|
.rename = zpl_snapdir_rename2,
|
||||||
#else
|
#else
|
||||||
.rename = zpl_snapdir_rename,
|
.rename = zpl_snapdir_rename,
|
||||||
@ -495,8 +526,14 @@ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
|||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_USERNS_IOPS_GETATTR
|
||||||
|
zpl_shares_getattr_impl(struct user_namespace *user_ns,
|
||||||
|
const struct path *path, struct kstat *stat, u32 request_mask,
|
||||||
|
unsigned int query_flags)
|
||||||
|
#else
|
||||||
zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
|
zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
|
||||||
u32 request_mask, unsigned int query_flags)
|
u32 request_mask, unsigned int query_flags)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct inode *ip = path->dentry->d_inode;
|
struct inode *ip = path->dentry->d_inode;
|
||||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||||
@ -506,7 +543,11 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
|
|||||||
ZPL_ENTER(zfsvfs);
|
ZPL_ENTER(zfsvfs);
|
||||||
|
|
||||||
if (zfsvfs->z_shares_dir == 0) {
|
if (zfsvfs->z_shares_dir == 0) {
|
||||||
|
#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
|
||||||
|
generic_fillattr(user_ns, path->dentry->d_inode, stat);
|
||||||
|
#else
|
||||||
generic_fillattr(path->dentry->d_inode, stat);
|
generic_fillattr(path->dentry->d_inode, stat);
|
||||||
|
#endif
|
||||||
stat->nlink = stat->size = 2;
|
stat->nlink = stat->size = 2;
|
||||||
stat->atime = current_time(ip);
|
stat->atime = current_time(ip);
|
||||||
ZPL_EXIT(zfsvfs);
|
ZPL_EXIT(zfsvfs);
|
||||||
@ -515,7 +556,11 @@ zpl_shares_getattr_impl(const struct path *path, struct kstat *stat,
|
|||||||
|
|
||||||
error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
|
error = -zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp);
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
error = -zfs_getattr_fast(ZTOI(dzp), stat);
|
#if defined(HAVE_GENERIC_FILLATTR_USERNS) && defined(HAVE_USERNS_IOPS_GETATTR)
|
||||||
|
error = -zfs_getattr_fast(user_ns, ZTOI(dzp), stat);
|
||||||
|
#else
|
||||||
|
error = -zfs_getattr_fast(kcred->user_ns, ZTOI(dzp), stat);
|
||||||
|
#endif
|
||||||
iput(ZTOI(dzp));
|
iput(ZTOI(dzp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -869,7 +869,7 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
|
|||||||
!capable(CAP_LINUX_IMMUTABLE))
|
!capable(CAP_LINUX_IMMUTABLE))
|
||||||
return (-EACCES);
|
return (-EACCES);
|
||||||
|
|
||||||
if (!inode_owner_or_capable(ip))
|
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||||
return (-EACCES);
|
return (-EACCES);
|
||||||
|
|
||||||
xva_init(xva);
|
xva_init(xva);
|
||||||
|
@ -128,7 +128,12 @@ zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_IOPS_CREATE_USERNS
|
||||||
|
zpl_create(struct user_namespace *user_ns, struct inode *dir,
|
||||||
|
struct dentry *dentry, umode_t mode, bool flag)
|
||||||
|
#else
|
||||||
zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
|
zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
znode_t *zp;
|
znode_t *zp;
|
||||||
@ -163,7 +168,12 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_IOPS_MKNOD_USERNS
|
||||||
|
zpl_mknod(struct user_namespace *user_ns, struct inode *dir,
|
||||||
|
struct dentry *dentry, umode_t mode,
|
||||||
|
#else
|
||||||
zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
|
zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
|
||||||
|
#endif
|
||||||
dev_t rdev)
|
dev_t rdev)
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
@ -278,7 +288,12 @@ zpl_unlink(struct inode *dir, struct dentry *dentry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_IOPS_MKDIR_USERNS
|
||||||
|
zpl_mkdir(struct user_namespace *user_ns, struct inode *dir,
|
||||||
|
struct dentry *dentry, umode_t mode)
|
||||||
|
#else
|
||||||
zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
vattr_t *vap;
|
vattr_t *vap;
|
||||||
@ -338,8 +353,14 @@ zpl_rmdir(struct inode *dir, struct dentry *dentry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_USERNS_IOPS_GETATTR
|
||||||
|
zpl_getattr_impl(struct user_namespace *user_ns,
|
||||||
|
const struct path *path, struct kstat *stat, u32 request_mask,
|
||||||
|
unsigned int query_flags)
|
||||||
|
#else
|
||||||
zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
|
zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
|
||||||
unsigned int query_flags)
|
unsigned int query_flags)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
fstrans_cookie_t cookie;
|
fstrans_cookie_t cookie;
|
||||||
@ -350,7 +371,11 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
|
|||||||
* XXX request_mask and query_flags currently ignored.
|
* XXX request_mask and query_flags currently ignored.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
error = -zfs_getattr_fast(path->dentry->d_inode, stat);
|
#ifdef HAVE_USERNS_IOPS_GETATTR
|
||||||
|
error = -zfs_getattr_fast(user_ns, path->dentry->d_inode, stat);
|
||||||
|
#else
|
||||||
|
error = -zfs_getattr_fast(kcred->user_ns, path->dentry->d_inode, stat);
|
||||||
|
#endif
|
||||||
spl_fstrans_unmark(cookie);
|
spl_fstrans_unmark(cookie);
|
||||||
ASSERT3S(error, <=, 0);
|
ASSERT3S(error, <=, 0);
|
||||||
|
|
||||||
@ -359,7 +384,12 @@ zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
|
|||||||
ZPL_GETATTR_WRAPPER(zpl_getattr);
|
ZPL_GETATTR_WRAPPER(zpl_getattr);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_SETATTR_PREPARE_USERNS
|
||||||
|
zpl_setattr(struct user_namespace *user_ns, struct dentry *dentry,
|
||||||
|
struct iattr *ia)
|
||||||
|
#else
|
||||||
zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct inode *ip = dentry->d_inode;
|
struct inode *ip = dentry->d_inode;
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
@ -367,7 +397,7 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
|||||||
int error;
|
int error;
|
||||||
fstrans_cookie_t cookie;
|
fstrans_cookie_t cookie;
|
||||||
|
|
||||||
error = setattr_prepare(dentry, ia);
|
error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
@ -399,8 +429,14 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_IOPS_RENAME_USERNS
|
||||||
|
zpl_rename2(struct user_namespace *user_ns, struct inode *sdip,
|
||||||
|
struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
|
||||||
|
unsigned int flags)
|
||||||
|
#else
|
||||||
zpl_rename2(struct inode *sdip, struct dentry *sdentry,
|
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 flags)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
int error;
|
int error;
|
||||||
@ -421,7 +457,7 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_RENAME_WANTS_FLAGS
|
#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
|
||||||
static int
|
static int
|
||||||
zpl_rename(struct inode *sdip, struct dentry *sdentry,
|
zpl_rename(struct inode *sdip, struct dentry *sdentry,
|
||||||
struct inode *tdip, struct dentry *tdentry)
|
struct inode *tdip, struct dentry *tdentry)
|
||||||
@ -431,7 +467,12 @@ zpl_rename(struct inode *sdip, struct dentry *sdentry,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
#ifdef HAVE_IOPS_SYMLINK_USERNS
|
||||||
|
zpl_symlink(struct user_namespace *user_ns, struct inode *dir,
|
||||||
|
struct dentry *dentry, const char *name)
|
||||||
|
#else
|
||||||
zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
|
zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
cred_t *cr = CRED();
|
cred_t *cr = CRED();
|
||||||
vattr_t *vap;
|
vattr_t *vap;
|
||||||
@ -678,7 +719,7 @@ const struct inode_operations zpl_dir_inode_operations = {
|
|||||||
.mkdir = zpl_mkdir,
|
.mkdir = zpl_mkdir,
|
||||||
.rmdir = zpl_rmdir,
|
.rmdir = zpl_rmdir,
|
||||||
.mknod = zpl_mknod,
|
.mknod = zpl_mknod,
|
||||||
#ifdef HAVE_RENAME_WANTS_FLAGS
|
#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
|
||||||
.rename = zpl_rename2,
|
.rename = zpl_rename2,
|
||||||
#else
|
#else
|
||||||
.rename = zpl_rename,
|
.rename = zpl_rename,
|
||||||
|
@ -1233,7 +1233,7 @@ __zpl_xattr_acl_set_access(struct inode *ip, const char *name,
|
|||||||
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
|
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
|
||||||
return (-EOPNOTSUPP);
|
return (-EOPNOTSUPP);
|
||||||
|
|
||||||
if (!inode_owner_or_capable(ip))
|
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||||
return (-EPERM);
|
return (-EPERM);
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
@ -1273,7 +1273,7 @@ __zpl_xattr_acl_set_default(struct inode *ip, const char *name,
|
|||||||
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
|
if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIX)
|
||||||
return (-EOPNOTSUPP);
|
return (-EOPNOTSUPP);
|
||||||
|
|
||||||
if (!inode_owner_or_capable(ip))
|
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||||
return (-EPERM);
|
return (-EPERM);
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
|
Loading…
Reference in New Issue
Block a user