mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +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
(cherry picked from commit e2a8296131)
Signed-off-by: Jonathon Fernyhough <jonathon@m2x.dev>
This commit is contained in:
committed by
Tony Hutter
parent
fd8ccce07b
commit
91d5ac85c0
@@ -124,7 +124,7 @@ secpolicy_vnode_any_access(const cred_t *cr, struct inode *ip, uid_t owner)
|
||||
if (crgetfsuid(cr) == owner)
|
||||
return (0);
|
||||
|
||||
if (inode_owner_or_capable(ip))
|
||||
if (zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||
return (0);
|
||||
|
||||
#if defined(CONFIG_USER_NS)
|
||||
|
||||
@@ -1907,7 +1907,8 @@ out:
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
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);
|
||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||
@@ -1919,7 +1920,7 @@ zfs_getattr_fast(struct inode *ip, struct kstat *sp)
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -101,12 +101,22 @@ zpl_root_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
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,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
#endif
|
||||
{
|
||||
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);
|
||||
#endif
|
||||
stat->atime = current_time(ip);
|
||||
|
||||
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 */
|
||||
|
||||
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,
|
||||
struct inode *tdip, struct dentry *tdentry, unsigned int flags)
|
||||
#endif
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
int error;
|
||||
@@ -309,7 +325,7 @@ zpl_snapdir_rename2(struct inode *sdip, struct dentry *sdentry,
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef HAVE_RENAME_WANTS_FLAGS
|
||||
#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
|
||||
static int
|
||||
zpl_snapdir_rename(struct inode *sdip, struct dentry *sdentry,
|
||||
struct inode *tdip, struct dentry *tdentry)
|
||||
@@ -333,7 +349,12 @@ zpl_snapdir_rmdir(struct inode *dip, struct dentry *dentry)
|
||||
}
|
||||
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
vattr_t *vap;
|
||||
@@ -363,14 +384,24 @@ zpl_snapdir_mkdir(struct inode *dip, struct dentry *dentry, umode_t mode)
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
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,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
#endif
|
||||
{
|
||||
struct inode *ip = path->dentry->d_inode;
|
||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||
|
||||
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);
|
||||
#endif
|
||||
|
||||
stat->nlink = stat->size = 2;
|
||||
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 = {
|
||||
.lookup = zpl_snapdir_lookup,
|
||||
.getattr = zpl_snapdir_getattr,
|
||||
#ifdef HAVE_RENAME_WANTS_FLAGS
|
||||
#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
|
||||
.rename = zpl_snapdir_rename2,
|
||||
#else
|
||||
.rename = zpl_snapdir_rename,
|
||||
@@ -495,8 +526,14 @@ zpl_shares_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
|
||||
/* ARGSUSED */
|
||||
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,
|
||||
u32 request_mask, unsigned int query_flags)
|
||||
#endif
|
||||
{
|
||||
struct inode *ip = path->dentry->d_inode;
|
||||
zfsvfs_t *zfsvfs = ITOZSB(ip);
|
||||
@@ -506,7 +543,11 @@ 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)
|
||||
generic_fillattr(user_ns, path->dentry->d_inode, stat);
|
||||
#else
|
||||
generic_fillattr(path->dentry->d_inode, stat);
|
||||
#endif
|
||||
stat->nlink = stat->size = 2;
|
||||
stat->atime = current_time(ip);
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -869,7 +869,7 @@ __zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
|
||||
!capable(CAP_LINUX_IMMUTABLE))
|
||||
return (-EACCES);
|
||||
|
||||
if (!inode_owner_or_capable(ip))
|
||||
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||
return (-EACCES);
|
||||
|
||||
xva_init(xva);
|
||||
|
||||
@@ -128,7 +128,12 @@ zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr)
|
||||
}
|
||||
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
znode_t *zp;
|
||||
@@ -163,7 +168,12 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
|
||||
}
|
||||
|
||||
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,
|
||||
#endif
|
||||
dev_t rdev)
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
@@ -278,7 +288,12 @@ zpl_unlink(struct inode *dir, struct dentry *dentry)
|
||||
}
|
||||
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
vattr_t *vap;
|
||||
@@ -338,8 +353,14 @@ zpl_rmdir(struct inode *dir, struct dentry *dentry)
|
||||
}
|
||||
|
||||
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,
|
||||
unsigned int query_flags)
|
||||
#endif
|
||||
{
|
||||
int error;
|
||||
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.
|
||||
*/
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
struct inode *ip = dentry->d_inode;
|
||||
cred_t *cr = CRED();
|
||||
@@ -367,7 +397,7 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
||||
int error;
|
||||
fstrans_cookie_t cookie;
|
||||
|
||||
error = setattr_prepare(dentry, ia);
|
||||
error = zpl_setattr_prepare(kcred->user_ns, dentry, ia);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
@@ -399,8 +429,14 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
|
||||
}
|
||||
|
||||
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,
|
||||
struct inode *tdip, struct dentry *tdentry, unsigned int flags)
|
||||
#endif
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
int error;
|
||||
@@ -421,7 +457,7 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef HAVE_RENAME_WANTS_FLAGS
|
||||
#if !defined(HAVE_RENAME_WANTS_FLAGS) && !defined(HAVE_IOPS_RENAME_USERNS)
|
||||
static int
|
||||
zpl_rename(struct inode *sdip, struct dentry *sdentry,
|
||||
struct inode *tdip, struct dentry *tdentry)
|
||||
@@ -431,7 +467,12 @@ zpl_rename(struct inode *sdip, struct dentry *sdentry,
|
||||
#endif
|
||||
|
||||
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)
|
||||
#endif
|
||||
{
|
||||
cred_t *cr = CRED();
|
||||
vattr_t *vap;
|
||||
@@ -677,7 +718,7 @@ const struct inode_operations zpl_dir_inode_operations = {
|
||||
.mkdir = zpl_mkdir,
|
||||
.rmdir = zpl_rmdir,
|
||||
.mknod = zpl_mknod,
|
||||
#ifdef HAVE_RENAME_WANTS_FLAGS
|
||||
#if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
|
||||
.rename = zpl_rename2,
|
||||
#else
|
||||
.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)
|
||||
return (-EOPNOTSUPP);
|
||||
|
||||
if (!inode_owner_or_capable(ip))
|
||||
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||
return (-EPERM);
|
||||
|
||||
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)
|
||||
return (-EOPNOTSUPP);
|
||||
|
||||
if (!inode_owner_or_capable(ip))
|
||||
if (!zpl_inode_owner_or_capable(kcred->user_ns, ip))
|
||||
return (-EPERM);
|
||||
|
||||
if (value) {
|
||||
|
||||
Reference in New Issue
Block a user