Linux 6.3: Use mnt_idmap for inode op functions

Through a series of Linux 6.3 commits starting with:
  'f2fs: project ids aren't idmapped' (64b4cdf22f) and ending with
  'fs: move mnt_idmap' (3707d84c13)
the inode operations functions were changed to take a mnt_idmap
structure instead of a user_namespace structure.  These were pulled in
via the the merge commit:
  'Pull vfs idmapping updates from Christian Brauner' (05e6295f7b)
The commit message for the merge contains background and overall
information for this conversion.

The above change simply changes the functions to use a different
structure (mnt_idmap instead of user_namespace).  For afs, it is a
simple change to swap the structures. But for some of the Linux calls
(generic_fillattr(), setattr_prepare(), and inode_op->setattr()) we
would like to use the Linux symbol nop_mnt_idmap, but that symbol is
exported as GPL only.  Instead, we will obtain its address from the
current task structure at libafs initialization (much the same way as
obtaining current user namespace for afs_ns).

Add autoconf tests to determine if inode_operations.create() uses the
mnt_idmap structure.  If so set a generic configure define for
"IOP_TAKES_MNT_IDMAP".

Update afs's inode operations functions to take and use a mnt_idmap
instead of a user_namespace.

At libafs initialization, obtain the mnt_idmap from the current task
and save it as an afs global variable, afs_mnt_idmap, to be used where
needed.

Reviewed-on: https://gerrit.openafs.org/15347
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
(cherry picked from commit 858ee34545e57acab1e4e5813cd1b9a011538b9e)

Change-Id: If89c6f401db04826ef45de83b91240f106cca616
Reviewed-on: https://gerrit.openafs.org/15389
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Mark Vitale <mvitale@sinenomine.net>
Reviewed-by: Michael Meffie <mmeffie@sinenomine.net>
Reviewed-by: Kailas Zadbuke <kailashsz@in.ibm.com>
Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
This commit is contained in:
Cheyenne Wills 2023-03-29 12:11:38 -06:00 committed by Stephan Wiesand
parent 7a3ad3bc1c
commit f6fbb85c00
5 changed files with 88 additions and 10 deletions

View File

@ -534,7 +534,9 @@ afs_inode_setattr(struct osi_file *afile, struct iattr *newattrs) {
int code = 0;
struct inode *inode = OSIFILE_INODE(afile);
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
code = inode->i_op->setattr(afs_mnt_idmap, afile->filp->f_dentry, newattrs);
#elif defined(IOP_TAKES_USER_NAMESPACE)
code = inode->i_op->setattr(afs_ns, afile->filp->f_dentry, newattrs);
#elif !defined(HAVE_LINUX_INODE_SETATTR)
code = inode->i_op->setattr(afile->filp->f_dentry, newattrs);
@ -763,7 +765,9 @@ afs_d_path(struct dentry *dp, struct vfsmount *mnt, char *buf, int buflen)
static inline int
afs_setattr_prepare(struct dentry *dp, struct iattr *newattrs)
{
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
return setattr_prepare(afs_mnt_idmap, dp, newattrs);
#elif defined(IOP_TAKES_USER_NAMESPACE)
return setattr_prepare(afs_ns, dp, newattrs);
#elif defined(HAVE_LINUX_SETATTR_PREPARE)
return setattr_prepare(dp, newattrs);

View File

@ -217,6 +217,10 @@ extern struct user_namespace *afs_ns;
# define afs_current_user_ns() ((struct user_namespace *)NULL)
# endif
#if defined(IOP_TAKES_MNT_IDMAP)
extern struct mnt_idmap *afs_mnt_idmap;
#endif
static inline kuid_t afs_make_kuid(uid_t uid) {
return make_kuid(afs_ns, uid);
}

View File

@ -31,6 +31,10 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#if defined(IOP_TAKES_MNT_IDMAP)
# include <linux/fs_struct.h>
#endif
#include "osi_pagecopy.h"
extern struct file_system_type afs_fs_type;
@ -46,6 +50,20 @@ int afs_global_owner = 0;
struct user_namespace *afs_ns;
#endif
#if defined(IOP_TAKES_MNT_IDMAP)
struct mnt_idmap *afs_mnt_idmap;
static void
afs_init_idmap(void)
{
struct path fs_root;
get_fs_root(current->fs, &fs_root);
afs_mnt_idmap = mnt_idmap(fs_root.mnt);
path_put(&fs_root);
}
#endif
int __init
afs_init(void)
{
@ -55,6 +73,10 @@ afs_init(void)
afs_ns = afs_current_user_ns();
#endif
#if defined(IOP_TAKES_MNT_IDMAP)
afs_init_idmap();
#endif
osi_Init();
/* Initialize CellLRU since it is used while traversing CellServDB proc

View File

@ -1146,7 +1146,10 @@ vattr2inode(struct inode *ip, struct vattr *vp)
* Linux version of setattr call. What to change is in the iattr struct.
* We need to set bits in both the Linux inode as well as the vcache.
*/
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
static int
afs_notify_change(struct mnt_idmap *idmap, struct dentry *dp, struct iattr *iattrp)
#elif defined(IOP_TAKES_USER_NAMESPACE)
static int
afs_notify_change(struct user_namespace *mnt_userns, struct dentry *dp, struct iattr *iattrp)
#else
@ -1180,7 +1183,18 @@ out:
return afs_convert_code(code);
}
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
static int
afs_linux_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int sync_mode)
{
int err = afs_linux_revalidate(path->dentry);
if (!err) {
generic_fillattr(afs_mnt_idmap, path->dentry->d_inode, stat);
}
return err;
}
#elif defined(IOP_TAKES_USER_NAMESPACE)
static int
afs_linux_getattr(struct user_namespace *mnt_userns, const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int sync_mode)
@ -1661,7 +1675,11 @@ struct dentry_operations afs_dentry_operations = {
* name is in kernel space at this point.
*/
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
static int
afs_linux_create(struct mnt_idmap *idmap, struct inode *dip,
struct dentry *dp, umode_t mode, bool excl)
#elif defined(IOP_TAKES_USER_NAMESPACE)
static int
afs_linux_create(struct user_namespace *mnt_userns, struct inode *dip,
struct dentry *dp, umode_t mode, bool excl)
@ -1953,7 +1971,11 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp)
}
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
static int
afs_linux_symlink(struct mnt_idmap *idmap, struct inode *dip,
struct dentry *dp, const char *target)
#elif defined(IOP_TAKES_USER_NAMESPACE)
static int
afs_linux_symlink(struct user_namespace *mnt_userns, struct inode *dip,
struct dentry *dp, const char *target)
@ -1988,7 +2010,11 @@ out:
return afs_convert_code(code);
}
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
static int
afs_linux_mkdir(struct mnt_idmap *idmap, struct inode *dip,
struct dentry *dp, umode_t mode)
#elif defined(IOP_TAKES_USER_NAMESPACE)
static int
afs_linux_mkdir(struct user_namespace *mnt_userns, struct inode *dip,
struct dentry *dp, umode_t mode)
@ -2068,7 +2094,13 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp)
}
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
static int
afs_linux_rename(struct mnt_idmap *idmap,
struct inode *oldip, struct dentry *olddp,
struct inode *newip, struct dentry *newdp,
unsigned int flags)
#elif defined(IOP_TAKES_USER_NAMESPACE)
static int
afs_linux_rename(struct user_namespace *mnt_userns,
struct inode *oldip, struct dentry *olddp,
@ -2092,7 +2124,7 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp,
struct dentry *rehash = NULL;
#if defined(HAVE_LINUX_INODE_OPERATIONS_RENAME_TAKES_FLAGS) || \
defined(IOP_TAKES_USER_NAMESPACE)
defined(IOP_TAKES_MNT_IDMAP) || defined(IOP_TAKES_USER_NAMESPACE)
if (flags)
return -EINVAL; /* no support for new flags yet */
#endif
@ -3388,7 +3420,10 @@ done:
* Check access rights - returns error if can't check or permission denied.
*/
#if defined(IOP_TAKES_USER_NAMESPACE)
#if defined(IOP_TAKES_MNT_IDMAP)
static int
afs_linux_permission(struct mnt_idmap *idmap, struct inode *ip, int mode)
#elif defined(IOP_TAKES_USER_NAMESPACE)
static int
afs_linux_permission(struct user_namespace *mnt_userns, struct inode *ip, int mode)
#elif defined(IOP_PERMISSION_TAKES_FLAGS)

View File

@ -28,4 +28,17 @@ dnl define.
AS_IF([test AS_VAR_GET([ac_cv_linux_operation_inode_operations_create_user_namespace]) = yes],
[AC_DEFINE([IOP_TAKES_USER_NAMESPACE], 1,
[define if inodeops require struct user_namespace])])
dnl Linux 6.3 replaced the user_namespace parameter with mnt_idmap for
dnl the inode operations functions.
AC_CHECK_LINUX_OPERATION([inode_operations], [create], [mnt_idmap],
[#include <linux/fs.h>],
[int],
[struct mnt_idmap *idmap,
struct inode *inode, struct dentry *dentry,
umode_t umode, bool flag])
dnl if HAVE_LINUX_INODE_OPERATIONS_CREATE_MNT_IDMAP, create a more generic
dnl define.
AS_IF([test AS_VAR_GET([ac_cv_linux_operation_inode_operations_create_mnt_idmap]) = yes],
[AC_DEFINE([IOP_TAKES_MNT_IDMAP], 1,
[define if inodeops require struct mnt_idmap])])
])