aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/os/freebsd/spl/sys/types.h2
-rw-r--r--include/os/freebsd/zfs/sys/zfs_vnops_os.h10
-rw-r--r--include/os/linux/kernel/linux/vfs_compat.h21
-rw-r--r--include/os/linux/kernel/linux/xattr_compat.h17
-rw-r--r--include/os/linux/spl/sys/cred.h30
-rw-r--r--include/os/linux/spl/sys/types.h15
-rw-r--r--include/os/linux/zfs/sys/policy.h6
-rw-r--r--include/os/linux/zfs/sys/zfs_vnops_os.h15
-rw-r--r--include/os/linux/zfs/sys/zpl.h13
-rw-r--r--include/sys/zfs_acl.h10
10 files changed, 97 insertions, 42 deletions
diff --git a/include/os/freebsd/spl/sys/types.h b/include/os/freebsd/spl/sys/types.h
index 558843dca..ebc93f4f4 100644
--- a/include/os/freebsd/spl/sys/types.h
+++ b/include/os/freebsd/spl/sys/types.h
@@ -105,7 +105,7 @@ typedef u_longlong_t len_t;
typedef longlong_t diskaddr_t;
-typedef void zuserns_t;
+typedef void zidmap_t;
#include <sys/debug.h>
#endif /* !_OPENSOLARIS_SYS_TYPES_H_ */
diff --git a/include/os/freebsd/zfs/sys/zfs_vnops_os.h b/include/os/freebsd/zfs/sys/zfs_vnops_os.h
index 839ee629a..eddcab575 100644
--- a/include/os/freebsd/zfs/sys/zfs_vnops_os.h
+++ b/include/os/freebsd/zfs/sys/zfs_vnops_os.h
@@ -35,23 +35,23 @@ int dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
int *rbehind, int *rahead, int last_size);
extern int zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags);
extern int zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap,
- znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns);
+ znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zidmap_t *mnt_ns);
extern int zfs_rmdir(znode_t *dzp, const char *name, znode_t *cwd,
cred_t *cr, int flags);
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr,
- zuserns_t *mnt_ns);
+ zidmap_t *mnt_ns);
extern int zfs_rename(znode_t *sdzp, const char *snm, znode_t *tdzp,
const char *tnm, cred_t *cr, int flags, uint64_t rflags, vattr_t *wo_vap,
- zuserns_t *mnt_ns);
+ zidmap_t *mnt_ns);
extern int zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
- const char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns);
+ const char *link, znode_t **zpp, cred_t *cr, int flags, zidmap_t *mnt_ns);
extern int zfs_link(znode_t *tdzp, znode_t *sp,
const char *name, cred_t *cr, int flags);
extern int zfs_space(znode_t *zp, int cmd, struct flock *bfp, int flag,
offset_t offset, cred_t *cr);
extern int zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl,
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
- zuserns_t *mnt_ns);
+ zidmap_t *mnt_ns);
extern int zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag,
cred_t *cr);
extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,
diff --git a/include/os/linux/kernel/linux/vfs_compat.h b/include/os/linux/kernel/linux/vfs_compat.h
index fd0b9e8e1..e156ed41c 100644
--- a/include/os/linux/kernel/linux/vfs_compat.h
+++ b/include/os/linux/kernel/linux/vfs_compat.h
@@ -341,7 +341,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)
{
@@ -396,6 +397,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
@@ -447,8 +457,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 ff80fbb06..bcc7289ad 100644
--- a/include/os/linux/kernel/linux/xattr_compat.h
+++ b/include/os/linux/kernel/linux/xattr_compat.h
@@ -134,12 +134,27 @@ fn(const struct xattr_handler *handler, struct dentry *dentry, \
#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, \
diff --git a/include/os/linux/spl/sys/cred.h b/include/os/linux/spl/sys/cred.h
index 75ad400d3..7fd5f6448 100644
--- a/include/os/linux/spl/sys/cred.h
+++ b/include/os/linux/spl/sys/cred.h
@@ -48,6 +48,8 @@ extern struct task_struct init_task;
#define SGID_TO_KGID(x) (KGIDT_INIT(x))
#define KGIDP_TO_SGIDP(x) (&(x)->val)
+extern zidmap_t *zfs_get_init_idmap(void);
+
/* Check if the user ns is the initial one */
static inline boolean_t
zfs_is_init_userns(struct user_namespace *user_ns)
@@ -74,36 +76,39 @@ static inline boolean_t zfs_no_idmapping(struct user_namespace *mnt_userns,
return (zfs_is_init_userns(mnt_userns) || mnt_userns == fs_userns);
}
-static inline uid_t zfs_uid_to_vfsuid(struct user_namespace *mnt_userns,
+static inline uid_t zfs_uid_to_vfsuid(zidmap_t *mnt_userns,
struct user_namespace *fs_userns, uid_t uid)
{
- if (zfs_no_idmapping(mnt_userns, fs_userns))
+ struct user_namespace *owner = idmap_owner(mnt_userns);
+ if (zfs_no_idmapping(owner, fs_userns))
return (uid);
if (!zfs_is_init_userns(fs_userns))
uid = from_kuid(fs_userns, KUIDT_INIT(uid));
if (uid == (uid_t)-1)
return (uid);
- return (__kuid_val(make_kuid(mnt_userns, uid)));
+ return (__kuid_val(make_kuid(owner, uid)));
}
-static inline gid_t zfs_gid_to_vfsgid(struct user_namespace *mnt_userns,
+static inline gid_t zfs_gid_to_vfsgid(zidmap_t *mnt_userns,
struct user_namespace *fs_userns, gid_t gid)
{
- if (zfs_no_idmapping(mnt_userns, fs_userns))
+ struct user_namespace *owner = idmap_owner(mnt_userns);
+ if (zfs_no_idmapping(owner, fs_userns))
return (gid);
if (!zfs_is_init_userns(fs_userns))
gid = from_kgid(fs_userns, KGIDT_INIT(gid));
if (gid == (gid_t)-1)
return (gid);
- return (__kgid_val(make_kgid(mnt_userns, gid)));
+ return (__kgid_val(make_kgid(owner, gid)));
}
-static inline uid_t zfs_vfsuid_to_uid(struct user_namespace *mnt_userns,
+static inline uid_t zfs_vfsuid_to_uid(zidmap_t *mnt_userns,
struct user_namespace *fs_userns, uid_t uid)
{
- if (zfs_no_idmapping(mnt_userns, fs_userns))
+ struct user_namespace *owner = idmap_owner(mnt_userns);
+ if (zfs_no_idmapping(owner, fs_userns))
return (uid);
- uid = from_kuid(mnt_userns, KUIDT_INIT(uid));
+ uid = from_kuid(owner, KUIDT_INIT(uid));
if (uid == (uid_t)-1)
return (uid);
if (zfs_is_init_userns(fs_userns))
@@ -111,12 +116,13 @@ static inline uid_t zfs_vfsuid_to_uid(struct user_namespace *mnt_userns,
return (__kuid_val(make_kuid(fs_userns, uid)));
}
-static inline gid_t zfs_vfsgid_to_gid(struct user_namespace *mnt_userns,
+static inline gid_t zfs_vfsgid_to_gid(zidmap_t *mnt_userns,
struct user_namespace *fs_userns, gid_t gid)
{
- if (zfs_no_idmapping(mnt_userns, fs_userns))
+ struct user_namespace *owner = idmap_owner(mnt_userns);
+ if (zfs_no_idmapping(owner, fs_userns))
return (gid);
- gid = from_kgid(mnt_userns, KGIDT_INIT(gid));
+ gid = from_kgid(owner, KGIDT_INIT(gid));
if (gid == (gid_t)-1)
return (gid);
if (zfs_is_init_userns(fs_userns))
diff --git a/include/os/linux/spl/sys/types.h b/include/os/linux/spl/sys/types.h
index cae1bbddf..a7666187e 100644
--- a/include/os/linux/spl/sys/types.h
+++ b/include/os/linux/spl/sys/types.h
@@ -55,6 +55,19 @@ typedef int major_t;
typedef int minor_t;
struct user_namespace;
-typedef struct user_namespace zuserns_t;
+#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/policy.h b/include/os/linux/zfs/sys/policy.h
index b182da95b..0c265db78 100644
--- a/include/os/linux/zfs/sys/policy.h
+++ b/include/os/linux/zfs/sys/policy.h
@@ -47,14 +47,14 @@ int secpolicy_vnode_create_gid(const cred_t *);
int secpolicy_vnode_remove(const cred_t *);
int secpolicy_vnode_setdac(const cred_t *, uid_t);
int secpolicy_vnode_setid_retain(struct znode *, const cred_t *, boolean_t);
-int secpolicy_vnode_setids_setgids(const cred_t *, gid_t, zuserns_t *,
- zuserns_t *);
+int secpolicy_vnode_setids_setgids(const cred_t *, gid_t, zidmap_t *,
+ struct user_namespace *);
int secpolicy_zinject(const cred_t *);
int secpolicy_zfs(const cred_t *);
int secpolicy_zfs_proc(const cred_t *, proc_t *);
void secpolicy_setid_clear(vattr_t *, cred_t *);
int secpolicy_setid_setsticky_clear(struct inode *, vattr_t *,
- const vattr_t *, cred_t *, zuserns_t *, zuserns_t *);
+ const vattr_t *, cred_t *, zidmap_t *, struct user_namespace *);
int secpolicy_xvattr(xvattr_t *, uid_t, cred_t *, mode_t);
int secpolicy_vnode_setattr(cred_t *, struct inode *, struct vattr *,
const struct vattr *, int, int (void *, int, cred_t *), void *);
diff --git a/include/os/linux/zfs/sys/zfs_vnops_os.h b/include/os/linux/zfs/sys/zfs_vnops_os.h
index 1caec0ef4..7a1db7dee 100644
--- a/include/os/linux/zfs/sys/zfs_vnops_os.h
+++ b/include/os/linux/zfs/sys/zfs_vnops_os.h
@@ -46,25 +46,24 @@ extern int zfs_lookup(znode_t *dzp, char *nm, znode_t **zpp, int flags,
cred_t *cr, int *direntflags, pathname_t *realpnp);
extern int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
- zuserns_t *mnt_ns);
+ zidmap_t *mnt_ns);
extern int zfs_tmpfile(struct inode *dip, vattr_t *vapzfs, int excl,
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp,
- zuserns_t *mnt_ns);
+ zidmap_t *mnt_ns);
extern int zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags);
extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap,
- znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns);
+ znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zidmap_t *mnt_ns);
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,
- zuserns_t *mnt_ns);
+ zidmap_t *mnt_ns);
extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
char *tnm, cred_t *cr, int flags, uint64_t rflags, vattr_t *wo_vap,
- zuserns_t *mnt_ns);
+ zidmap_t *mnt_ns);
extern int zfs_symlink(znode_t *dzp, char *name, vattr_t *vap,
- char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns);
+ char *link, znode_t **zpp, cred_t *cr, int flags, zidmap_t *mnt_ns);
extern int zfs_readlink(struct inode *ip, zfs_uio_t *uio, cred_t *cr);
extern int zfs_link(znode_t *tdzp, znode_t *szp,
char *name, cred_t *cr, int flags);
diff --git a/include/os/linux/zfs/sys/zpl.h b/include/os/linux/zfs/sys/zpl.h
index ac1f01a86..2b302e9da 100644
--- a/include/os/linux/zfs/sys/zpl.h
+++ b/include/os/linux/zfs/sys/zpl.h
@@ -39,7 +39,7 @@
/* zpl_inode.c */
extern void zpl_vap_init(vattr_t *vap, struct inode *dir,
- umode_t mode, cred_t *cr, zuserns_t *mnt_ns);
+ umode_t mode, cred_t *cr, zidmap_t *mnt_ns);
extern const struct inode_operations zpl_inode_operations;
#ifdef HAVE_RENAME2_OPERATIONS_WRAPPER
@@ -68,7 +68,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)
@@ -189,13 +192,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/include/sys/zfs_acl.h b/include/sys/zfs_acl.h
index e5c570c47..e19288528 100644
--- a/include/sys/zfs_acl.h
+++ b/include/sys/zfs_acl.h
@@ -206,7 +206,7 @@ struct zfsvfs;
#ifdef _KERNEL
int zfs_acl_ids_create(struct znode *, int, vattr_t *,
- cred_t *, vsecattr_t *, zfs_acl_ids_t *, zuserns_t *);
+ cred_t *, vsecattr_t *, zfs_acl_ids_t *, zidmap_t *);
void zfs_acl_ids_free(zfs_acl_ids_t *);
boolean_t zfs_acl_ids_overquota(struct zfsvfs *, zfs_acl_ids_t *, uint64_t);
int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *);
@@ -216,15 +216,15 @@ void zfs_oldace_byteswap(ace_t *, int);
void zfs_ace_byteswap(void *, size_t, boolean_t);
extern boolean_t zfs_has_access(struct znode *zp, cred_t *cr);
extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *,
- zuserns_t *);
+ zidmap_t *);
int zfs_fastaccesschk_execute(struct znode *, cred_t *);
-extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *, zuserns_t *);
+extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *, zidmap_t *);
extern int zfs_zaccess_unix(void *, int, cred_t *);
extern int zfs_acl_access(struct znode *, int, cred_t *);
int zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t);
-int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *, zuserns_t *);
+int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *, zidmap_t *);
int zfs_zaccess_rename(struct znode *, struct znode *,
- struct znode *, struct znode *, cred_t *cr, zuserns_t *mnt_ns);
+ struct znode *, struct znode *, cred_t *cr, zidmap_t *mnt_ns);
void zfs_acl_free(zfs_acl_t *);
int zfs_vsec_2_aclp(struct zfsvfs *, umode_t, vsecattr_t *, cred_t *,
struct zfs_fuid_info **, zfs_acl_t **);