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.

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 GitHub
parent d0cbd9feaf
commit d4dc53dad2
40 changed files with 823 additions and 296 deletions
+18 -12
View File
@@ -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))
+14 -1
View File
@@ -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 */