Skip to content

Commit 0233475

Browse files
author
Youzhong Yang
committed
Support idmapped mount
Signed-off-by: Youzhong Yang <[email protected]>
1 parent 642c2de commit 0233475

File tree

26 files changed

+313
-162
lines changed

26 files changed

+313
-162
lines changed

config/kernel-idmap_mnt_api.m4

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
dnl #
2+
dnl # 5.12 API
3+
dnl #
4+
dnl # Check if APIs for idmapped mount are available
5+
dnl #
6+
AC_DEFUN([ZFS_AC_KERNEL_SRC_IDMAP_MNT_API], [
7+
ZFS_LINUX_TEST_SRC([idmap_mnt_api], [
8+
#include <linux/fs.h>
9+
],[
10+
int fs_flags = 0;
11+
fs_flags |= FS_ALLOW_IDMAP;
12+
])
13+
])
14+
15+
AC_DEFUN([ZFS_AC_KERNEL_IDMAP_MNT_API], [
16+
AC_MSG_CHECKING([whether APIs for idmapped mount are present])
17+
ZFS_LINUX_TEST_RESULT([idmap_mnt_api], [
18+
AC_MSG_RESULT([yes])
19+
AC_DEFINE(HAVE_IDMAP_MNT_API, 1,
20+
[APIs for idmapped mount are present])
21+
],[
22+
AC_MSG_RESULT([no])
23+
])
24+
])
25+

config/kernel.m4

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
147147
ZFS_AC_KERNEL_SRC_ZERO_PAGE
148148
ZFS_AC_KERNEL_SRC___COPY_FROM_USER_INATOMIC
149149
ZFS_AC_KERNEL_SRC_USER_NS_COMMON_INUM
150+
ZFS_AC_KERNEL_SRC_IDMAP_MNT_API
150151
151152
AC_MSG_CHECKING([for available kernel interfaces])
152153
ZFS_LINUX_TEST_COMPILE_ALL([kabi])
@@ -267,6 +268,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
267268
ZFS_AC_KERNEL_ZERO_PAGE
268269
ZFS_AC_KERNEL___COPY_FROM_USER_INATOMIC
269270
ZFS_AC_KERNEL_USER_NS_COMMON_INUM
271+
ZFS_AC_KERNEL_IDMAP_MNT_API
270272
])
271273

272274
dnl #

include/os/freebsd/spl/sys/types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,7 @@ typedef u_longlong_t len_t;
105105

106106
typedef longlong_t diskaddr_t;
107107

108+
typedef void zuserns_t;
109+
108110
#include <sys/debug.h>
109111
#endif /* !_OPENSOLARIS_SYS_TYPES_H_ */

include/os/freebsd/zfs/sys/zfs_vnops_os.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,22 @@ int dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
3535
int *rbehind, int *rahead, int last_size);
3636
extern int zfs_remove(znode_t *dzp, const char *name, cred_t *cr, int flags);
3737
extern int zfs_mkdir(znode_t *dzp, const char *dirname, vattr_t *vap,
38-
znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp);
38+
znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns);
3939
extern int zfs_rmdir(znode_t *dzp, const char *name, znode_t *cwd,
4040
cred_t *cr, int flags);
41-
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
41+
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr,
42+
zuserns_t *mnt_ns);
4243
extern int zfs_rename(znode_t *sdzp, const char *snm, znode_t *tdzp,
43-
const char *tnm, cred_t *cr, int flags);
44+
const char *tnm, cred_t *cr, int flags, zuserns_t *mnt_ns);
4445
extern int zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
45-
const char *link, znode_t **zpp, cred_t *cr, int flags);
46+
const char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns);
4647
extern int zfs_link(znode_t *tdzp, znode_t *sp,
4748
const char *name, cred_t *cr, int flags);
4849
extern int zfs_space(znode_t *zp, int cmd, struct flock *bfp, int flag,
4950
offset_t offset, cred_t *cr);
5051
extern int zfs_create(znode_t *dzp, const char *name, vattr_t *vap, int excl,
51-
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp);
52+
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
53+
zuserns_t *mnt_ns);
5254
extern int zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag,
5355
cred_t *cr);
5456
extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,

include/os/linux/spl/sys/cred.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,34 @@ typedef struct cred cred_t;
4545
#define SGID_TO_KGID(x) (KGIDT_INIT(x))
4646
#define KGIDP_TO_SGIDP(x) (&(x)->val)
4747

48+
static inline uid_t zfs_uid_into_mnt(struct user_namespace *mnt_ns, uid_t uid)
49+
{
50+
if (mnt_ns)
51+
return (__kuid_val(make_kuid(mnt_ns, uid)));
52+
return (uid);
53+
}
54+
55+
static inline gid_t zfs_gid_into_mnt(struct user_namespace *mnt_ns, gid_t gid)
56+
{
57+
if (mnt_ns)
58+
return (__kgid_val(make_kgid(mnt_ns, gid)));
59+
return (gid);
60+
}
61+
62+
static inline uid_t zfs_uid_from_mnt(struct user_namespace *mnt_ns, uid_t uid)
63+
{
64+
if (mnt_ns)
65+
return (from_kuid(mnt_ns, KUIDT_INIT(uid)));
66+
return (uid);
67+
}
68+
69+
static inline gid_t zfs_gid_from_mnt(struct user_namespace *mnt_ns, gid_t gid)
70+
{
71+
if (mnt_ns)
72+
return (from_kgid(mnt_ns, KGIDT_INIT(gid)));
73+
return (gid);
74+
}
75+
4876
extern void crhold(cred_t *cr);
4977
extern void crfree(cred_t *cr);
5078
extern uid_t crgetuid(const cred_t *cr);

include/os/linux/spl/sys/types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,7 @@ typedef ulong_t pgcnt_t;
5454
typedef int major_t;
5555
typedef int minor_t;
5656

57+
struct user_namespace;
58+
typedef struct user_namespace zuserns_t;
59+
5760
#endif /* _SPL_TYPES_H */

include/os/linux/zfs/sys/policy.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ int secpolicy_vnode_create_gid(const cred_t *);
4747
int secpolicy_vnode_remove(const cred_t *);
4848
int secpolicy_vnode_setdac(const cred_t *, uid_t);
4949
int secpolicy_vnode_setid_retain(struct znode *, const cred_t *, boolean_t);
50-
int secpolicy_vnode_setids_setgids(const cred_t *, gid_t);
50+
int secpolicy_vnode_setids_setgids(const cred_t *, gid_t, zuserns_t *);
5151
int secpolicy_zinject(const cred_t *);
5252
int secpolicy_zfs(const cred_t *);
5353
int secpolicy_zfs_proc(const cred_t *, proc_t *);
5454
void secpolicy_setid_clear(vattr_t *, cred_t *);
5555
int secpolicy_setid_setsticky_clear(struct inode *, vattr_t *,
56-
const vattr_t *, cred_t *);
56+
const vattr_t *, cred_t *, zuserns_t *);
5757
int secpolicy_xvattr(xvattr_t *, uid_t, cred_t *, mode_t);
5858
int secpolicy_vnode_setattr(cred_t *, struct inode *, struct vattr *,
5959
const struct vattr *, int, int (void *, int, cred_t *), void *);

include/os/linux/zfs/sys/zfs_vnops_os.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,25 @@ extern int zfs_write_simple(znode_t *zp, const void *data, size_t len,
4545
extern int zfs_lookup(znode_t *dzp, char *nm, znode_t **zpp, int flags,
4646
cred_t *cr, int *direntflags, pathname_t *realpnp);
4747
extern int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
48-
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp);
48+
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp,
49+
zuserns_t *mnt_ns);
4950
extern int zfs_tmpfile(struct inode *dip, vattr_t *vapzfs, int excl,
50-
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp);
51+
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp,
52+
zuserns_t *mnt_ns);
5153
extern int zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags);
5254
extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap,
53-
znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp);
55+
znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp, zuserns_t *mnt_ns);
5456
extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd,
5557
cred_t *cr, int flags);
5658
extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr);
5759
extern int zfs_getattr_fast(struct user_namespace *, struct inode *ip,
5860
struct kstat *sp);
59-
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
61+
extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr,
62+
zuserns_t *mnt_ns);
6063
extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
61-
char *tnm, cred_t *cr, int flags);
64+
char *tnm, cred_t *cr, int flags, zuserns_t *mnt_ns);
6265
extern int zfs_symlink(znode_t *dzp, char *name, vattr_t *vap,
63-
char *link, znode_t **zpp, cred_t *cr, int flags);
66+
char *link, znode_t **zpp, cred_t *cr, int flags, zuserns_t *mnt_ns);
6467
extern int zfs_readlink(struct inode *ip, zfs_uio_t *uio, cred_t *cr);
6568
extern int zfs_link(znode_t *tdzp, znode_t *szp,
6669
char *name, cred_t *cr, int flags);

include/os/linux/zfs/sys/zpl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
/* zpl_inode.c */
4141
extern void zpl_vap_init(vattr_t *vap, struct inode *dir,
42-
umode_t mode, cred_t *cr);
42+
umode_t mode, cred_t *cr, zuserns_t *mnt_ns);
4343

4444
extern const struct inode_operations zpl_inode_operations;
4545
extern const struct inode_operations zpl_dir_inode_operations;

include/sys/zfs_acl.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ struct zfsvfs;
206206

207207
#ifdef _KERNEL
208208
int zfs_acl_ids_create(struct znode *, int, vattr_t *,
209-
cred_t *, vsecattr_t *, zfs_acl_ids_t *);
209+
cred_t *, vsecattr_t *, zfs_acl_ids_t *, zuserns_t *);
210210
void zfs_acl_ids_free(zfs_acl_ids_t *);
211211
boolean_t zfs_acl_ids_overquota(struct zfsvfs *, zfs_acl_ids_t *, uint64_t);
212212
int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *);
@@ -215,15 +215,16 @@ void zfs_acl_rele(void *);
215215
void zfs_oldace_byteswap(ace_t *, int);
216216
void zfs_ace_byteswap(void *, size_t, boolean_t);
217217
extern boolean_t zfs_has_access(struct znode *zp, cred_t *cr);
218-
extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *);
218+
extern int zfs_zaccess(struct znode *, int, int, boolean_t, cred_t *,
219+
zuserns_t *);
219220
int zfs_fastaccesschk_execute(struct znode *, cred_t *);
220-
extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *);
221+
extern int zfs_zaccess_rwx(struct znode *, mode_t, int, cred_t *, zuserns_t *);
221222
extern int zfs_zaccess_unix(struct znode *, mode_t, cred_t *);
222223
extern int zfs_acl_access(struct znode *, int, cred_t *);
223224
int zfs_acl_chmod_setattr(struct znode *, zfs_acl_t **, uint64_t);
224-
int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *);
225+
int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *, zuserns_t *);
225226
int zfs_zaccess_rename(struct znode *, struct znode *,
226-
struct znode *, struct znode *, cred_t *cr);
227+
struct znode *, struct znode *, cred_t *cr, zuserns_t *mnt_ns);
227228
void zfs_acl_free(zfs_acl_t *);
228229
int zfs_vsec_2_aclp(struct zfsvfs *, umode_t, vsecattr_t *, cred_t *,
229230
struct zfs_fuid_info **, zfs_acl_t **);

module/os/freebsd/zfs/zfs_acl.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,7 +1619,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
16191619
*/
16201620
int
16211621
zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
1622-
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
1622+
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids, zuserns_t *mnt_ns)
16231623
{
16241624
int error;
16251625
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
@@ -1789,7 +1789,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
17891789
if (mask == 0)
17901790
return (SET_ERROR(ENOSYS));
17911791

1792-
if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)))
1792+
if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr, NULL)))
17931793
return (error);
17941794

17951795
mutex_enter(&zp->z_acl_lock);
@@ -1952,7 +1952,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
19521952
if (zp->z_pflags & ZFS_IMMUTABLE)
19531953
return (SET_ERROR(EPERM));
19541954

1955-
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
1955+
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr, NULL)))
19561956
return (error);
19571957

19581958
error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, cr, &fuidp,
@@ -2341,7 +2341,8 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
23412341
* can define any form of access.
23422342
*/
23432343
int
2344-
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
2344+
zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr,
2345+
zuserns_t *mnt_ns)
23452346
{
23462347
uint32_t working_mode;
23472348
int error;
@@ -2471,9 +2472,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
24712472
* NFSv4-style ZFS ACL format and call zfs_zaccess()
24722473
*/
24732474
int
2474-
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
2475+
zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr,
2476+
zuserns_t *mnt_ns)
24752477
{
2476-
return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
2478+
return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr,
2479+
mnt_ns));
24772480
}
24782481

24792482
/*
@@ -2484,7 +2487,7 @@ zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
24842487
{
24852488
int v4_mode = zfs_unix_to_v4(mode >> 6);
24862489

2487-
return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
2490+
return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr, NULL));
24882491
}
24892492

24902493
static int
@@ -2540,7 +2543,7 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp,
25402543
*
25412544
*/
25422545
int
2543-
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
2546+
zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr, zuserns_t *mnt_ns)
25442547
{
25452548
uint32_t dzp_working_mode = 0;
25462549
uint32_t zp_working_mode = 0;
@@ -2627,7 +2630,7 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
26272630

26282631
int
26292632
zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
2630-
znode_t *tzp, cred_t *cr)
2633+
znode_t *tzp, cred_t *cr, zuserns_t *mnt_ns)
26312634
{
26322635
int add_perm;
26332636
int error;
@@ -2647,7 +2650,8 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
26472650
* to another.
26482651
*/
26492652
if (ZTOV(szp)->v_type == VDIR && ZTOV(sdzp) != ZTOV(tdzp)) {
2650-
if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr)))
2653+
if ((error = zfs_zaccess(szp, ACE_WRITE_DATA, 0, B_FALSE, cr,
2654+
mnt_ns)))
26512655
return (error);
26522656
}
26532657

@@ -2657,19 +2661,19 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
26572661
* If that succeeds then check for add_file/add_subdir permissions
26582662
*/
26592663

2660-
if ((error = zfs_zaccess_delete(sdzp, szp, cr)))
2664+
if ((error = zfs_zaccess_delete(sdzp, szp, cr, mnt_ns)))
26612665
return (error);
26622666

26632667
/*
26642668
* If we have a tzp, see if we can delete it?
26652669
*/
2666-
if (tzp && (error = zfs_zaccess_delete(tdzp, tzp, cr)))
2670+
if (tzp && (error = zfs_zaccess_delete(tdzp, tzp, cr, mnt_ns)))
26672671
return (error);
26682672

26692673
/*
26702674
* Now check for add permissions
26712675
*/
2672-
error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
2676+
error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr, mnt_ns);
26732677

26742678
return (error);
26752679
}

module/os/freebsd/zfs/zfs_dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xvpp, cred_t *cr)
809809
*xvpp = NULL;
810810

811811
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
812-
&acl_ids)) != 0)
812+
&acl_ids, NULL)) != 0)
813813
return (error);
814814
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids, 0)) {
815815
zfs_acl_ids_free(&acl_ids);
@@ -955,7 +955,7 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
955955

956956
if ((uid = crgetuid(cr)) == downer || uid == fowner ||
957957
(ZTOV(zp)->v_type == VREG &&
958-
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0))
958+
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr, NULL) == 0))
959959
return (0);
960960
else
961961
return (secpolicy_vnode_remove(ZTOV(zp), cr));

0 commit comments

Comments
 (0)