SHA256
1
0
forked from pool/openafs
openafs/f6fbb85.diff
2023-05-15 10:59:16 +00:00

275 lines
9.5 KiB
Diff

From f6fbb85c00411bf97e9855be73baf49bd6b061d7 Mon Sep 17 00:00:00 2001
From: Cheyenne Wills <cwills@sinenomine.net>
Date: Wed, 29 Mar 2023 12:11:38 -0600
Subject: [PATCH] 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>
---
diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h
index 808c608..bb4969c 100644
--- a/src/afs/LINUX/osi_compat.h
+++ b/src/afs/LINUX/osi_compat.h
@@ -534,7 +534,9 @@
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 @@
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);
diff --git a/src/afs/LINUX/osi_machdep.h b/src/afs/LINUX/osi_machdep.h
index 34940c6..2220e05 100644
--- a/src/afs/LINUX/osi_machdep.h
+++ b/src/afs/LINUX/osi_machdep.h
@@ -217,6 +217,10 @@
# 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);
}
diff --git a/src/afs/LINUX/osi_module.c b/src/afs/LINUX/osi_module.c
index 79ba57c..fdc347d 100644
--- a/src/afs/LINUX/osi_module.c
+++ b/src/afs/LINUX/osi_module.c
@@ -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 @@
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_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
diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
index d875788..2c5439d 100644
--- a/src/afs/LINUX/osi_vnodeops.c
+++ b/src/afs/LINUX/osi_vnodeops.c
@@ -1146,7 +1146,10 @@
* 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 @@
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 @@
* 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 @@
}
-#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 @@
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 @@
}
-#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 @@
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 @@
* 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)
diff --git a/src/cf/linux-kernel-sig.m4 b/src/cf/linux-kernel-sig.m4
index e0cc9a2..5301f35 100644
--- a/src/cf/linux-kernel-sig.m4
+++ b/src/cf/linux-kernel-sig.m4
@@ -28,4 +28,17 @@
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])])
])
\ No newline at end of file