summarylogtreecommitdiffstats
path: root/0011-Linux-5.12-Add-user_namespace-param-to-inode-ops.patch
diff options
context:
space:
mode:
Diffstat (limited to '0011-Linux-5.12-Add-user_namespace-param-to-inode-ops.patch')
-rw-r--r--0011-Linux-5.12-Add-user_namespace-param-to-inode-ops.patch289
1 files changed, 289 insertions, 0 deletions
diff --git a/0011-Linux-5.12-Add-user_namespace-param-to-inode-ops.patch b/0011-Linux-5.12-Add-user_namespace-param-to-inode-ops.patch
new file mode 100644
index 000000000000..001f1782df22
--- /dev/null
+++ b/0011-Linux-5.12-Add-user_namespace-param-to-inode-ops.patch
@@ -0,0 +1,289 @@
+From 1a5b57363724d221a9065bbb10f817485d0a8bc3 Mon Sep 17 00:00:00 2001
+From: Cheyenne Wills <cwills@sinenomine.net>
+Date: Fri, 5 Mar 2021 16:31:03 -0700
+Subject: [PATCH 11/11] Linux 5.12: Add user_namespace param to inode ops
+
+The Linux commits:
+"fs: make helpers idmap mount aware" (549c72977) and
+"attr: handle idmapped mounts" (2f221d6f7) that were merged into
+Linux-5.12-rc1 cause a build failure when creating the kernel module.
+
+Several functions within the inode_operations structure had their
+signature updated to include a user_namespace parameter. This allows
+a filesystem to support idmapped mounts.
+
+OpenAFS only implements some of the changed functions.
+
+ LINUX/vnodeops function inode_operation
+ ===================== ===============
+ afs_notify_change setattr
+ afs_linux_getattr getattr
+ afs_linux_create create
+ afs_linux_symlink symlink
+ afs_linux_mkdir mkdir
+ afs_linux_rename rename
+ afs_linux_permission permission
+
+Update the autoconf tests to determine if the Linux kernel requires
+the user_namespace structure for inode_operations functions. If so,
+define a generic "IOP_TAKES_USER_NAMESPACE" macro.
+
+Update the above vnodeops functions to accept a 'struct user_namespace'
+parameter.
+
+When using the 'setattr_prepare' function a user namespace must be
+now provided. In order to provide compatibility as a non-idmapped mount
+filesystem the initial user namespace can be used. With OpenAFS, the
+initial user namespace obtained at kernel module load time is stored in
+a global variable 'afs_ns'.
+
+Update the call to setattr_prepare to pass the user namespace pointed
+to by the 'afs_ns' global variable.
+
+Update calls to setattr to pass the user namespace pointed to by
+the 'afs_ns' global variable.
+
+Notes:
+
+The changes introduced with Linux 5.12 allow a filesystem to support
+idmapped mounts if desired. This commit does not implement support for
+idmapped mounts, but will continue to use the same initial user
+namespace as prior to Linux 5.12.
+
+With Linux 5.12 the following autoconf checks fail:
+
+ HAVE_LINUX_INODE_OPERATIONS_RENAME_TAKES_FLAGS
+ HAVE_LINUX_SETATTR_PREPARE
+ IOP_CREATE_TAKES_BOOL
+ IOP_GETATTR_TAKES_PATH_STRUCT
+ IOP_MKDIR_TAKES_UMODE_T
+
+The new macro 'IOP_TAKES_USER_NAMESPACE' covers the cases where these
+macros where used.
+
+Reviewed-on: https://gerrit.openafs.org/14549
+Reviewed-by: Andrew Deason <adeason@sinenomine.net>
+Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
+Tested-by: BuildBot <buildbot@rampaginggeek.com>
+(cherry picked from commit 1bd68506be3243c5670aaf53798b2e4e715d4c8b)
+
+Change-Id: I8cd54042da4e0295f3cf8417c84138bb0458f881
+Reviewed-on: https://gerrit.openafs.org/14565
+Tested-by: BuildBot <buildbot@rampaginggeek.com>
+Reviewed-by: Cheyenne Wills <cwills@sinenomine.net>
+Reviewed-by: Andrew Deason <adeason@sinenomine.net>
+Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
+---
+ src/afs/LINUX/osi_compat.h | 8 +++--
+ src/afs/LINUX/osi_vnodeops.c | 69 +++++++++++++++++++++++++++++++-----
+ src/cf/linux-kernel-sig.m4 | 16 ++++++++-
+ 3 files changed, 81 insertions(+), 12 deletions(-)
+
+diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h
+index 3ac4d798d..726b6559c 100644
+--- a/src/afs/LINUX/osi_compat.h
++++ b/src/afs/LINUX/osi_compat.h
+@@ -524,7 +524,9 @@ afs_inode_setattr(struct osi_file *afile, struct iattr *newattrs) {
+
+ int code = 0;
+ struct inode *inode = OSIFILE_INODE(afile);
+-#if !defined(HAVE_LINUX_INODE_SETATTR)
++#if 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);
+ #elif defined(INODE_SETATTR_NOT_VOID)
+ if (inode->i_op && inode->i_op->setattr)
+@@ -751,7 +753,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(HAVE_LINUX_SETATTR_PREPARE)
++#if defined(IOP_TAKES_USER_NAMESPACE)
++ return setattr_prepare(afs_ns, dp, newattrs);
++#elif defined(HAVE_LINUX_SETATTR_PREPARE)
+ return setattr_prepare(dp, newattrs);
+ #else
+ return inode_change_ok(dp->d_inode, newattrs);
+diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
+index 4d0f55c95..9d4a6e334 100644
+--- a/src/afs/LINUX/osi_vnodeops.c
++++ b/src/afs/LINUX/osi_vnodeops.c
+@@ -1118,8 +1118,13 @@ 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)
++static int
++afs_notify_change(struct user_namespace *mnt_userns, struct dentry *dp, struct iattr *iattrp)
++#else
+ static int
+ afs_notify_change(struct dentry *dp, struct iattr *iattrp)
++#endif
+ {
+ struct vattr *vattr = NULL;
+ cred_t *credp = crref();
+@@ -1147,7 +1152,18 @@ out:
+ return afs_convert_code(code);
+ }
+
+-#if defined(IOP_GETATTR_TAKES_PATH_STRUCT)
++#if 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)
++{
++ int err = afs_linux_revalidate(path->dentry);
++ if (!err) {
++ generic_fillattr(afs_ns, path->dentry->d_inode, stat);
++ }
++ return err;
++}
++#elif defined(IOP_GETATTR_TAKES_PATH_STRUCT)
+ static int
+ afs_linux_getattr(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int sync_mode)
+ {
+@@ -1605,17 +1621,25 @@ struct dentry_operations afs_dentry_operations = {
+ *
+ * name is in kernel space at this point.
+ */
++
++#if 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)
++#elif defined(IOP_CREATE_TAKES_BOOL)
+ static int
+-#if defined(IOP_CREATE_TAKES_BOOL)
+ afs_linux_create(struct inode *dip, struct dentry *dp, umode_t mode,
+ bool excl)
+ #elif defined(IOP_CREATE_TAKES_UMODE_T)
++static int
+ afs_linux_create(struct inode *dip, struct dentry *dp, umode_t mode,
+ struct nameidata *nd)
+ #elif defined(IOP_CREATE_TAKES_NAMEIDATA)
++static int
+ afs_linux_create(struct inode *dip, struct dentry *dp, int mode,
+ struct nameidata *nd)
+ #else
++static int
+ afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
+ #endif
+ {
+@@ -1890,8 +1914,14 @@ afs_linux_unlink(struct inode *dip, struct dentry *dp)
+ }
+
+
++#if defined(IOP_TAKES_USER_NAMESPACE)
++static int
++afs_linux_symlink(struct user_namespace *mnt_userns, struct inode *dip,
++ struct dentry *dp, const char *target)
++#else
+ static int
+ afs_linux_symlink(struct inode *dip, struct dentry *dp, const char *target)
++#endif
+ {
+ int code;
+ cred_t *credp = crref();
+@@ -1919,10 +1949,15 @@ out:
+ return afs_convert_code(code);
+ }
+
++#if defined(IOP_TAKES_USER_NAMESPACE)
++static int
++afs_linux_mkdir(struct user_namespace *mnt_userns, struct inode *dip,
++ struct dentry *dp, umode_t mode)
++#elif defined(IOP_MKDIR_TAKES_UMODE_T)
+ static int
+-#if defined(IOP_MKDIR_TAKES_UMODE_T)
+ afs_linux_mkdir(struct inode *dip, struct dentry *dp, umode_t mode)
+ #else
++static int
+ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode)
+ #endif
+ {
+@@ -1994,13 +2029,22 @@ afs_linux_rmdir(struct inode *dip, struct dentry *dp)
+ }
+
+
++#if defined(IOP_TAKES_USER_NAMESPACE)
++static int
++afs_linux_rename(struct user_namespace *mnt_userns,
++ struct inode *oldip, struct dentry *olddp,
++ struct inode *newip, struct dentry *newdp,
++ unsigned int flags)
++#elif defined(HAVE_LINUX_INODE_OPERATIONS_RENAME_TAKES_FLAGS)
++static int
++afs_linux_rename(struct inode *oldip, struct dentry *olddp,
++ struct inode *newip, struct dentry *newdp,
++ unsigned int flags)
++#else
+ static int
+ afs_linux_rename(struct inode *oldip, struct dentry *olddp,
+- struct inode *newip, struct dentry *newdp
+-#ifdef HAVE_LINUX_INODE_OPERATIONS_RENAME_TAKES_FLAGS
+- , unsigned int flags
++ struct inode *newip, struct dentry *newdp)
+ #endif
+- )
+ {
+ int code;
+ cred_t *credp = crref();
+@@ -2008,7 +2052,8 @@ afs_linux_rename(struct inode *oldip, struct dentry *olddp,
+ const char *newname = newdp->d_name.name;
+ struct dentry *rehash = NULL;
+
+-#ifdef HAVE_LINUX_INODE_OPERATIONS_RENAME_TAKES_FLAGS
++#if defined(HAVE_LINUX_INODE_OPERATIONS_RENAME_TAKES_FLAGS) || \
++ defined(IOP_TAKES_USER_NAMESPACE)
+ if (flags)
+ return -EINVAL; /* no support for new flags yet */
+ #endif
+@@ -3030,12 +3075,18 @@ done:
+ /* afs_linux_permission
+ * Check access rights - returns error if can't check or permission denied.
+ */
++
++#if 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)
+ static int
+-#if defined(IOP_PERMISSION_TAKES_FLAGS)
+ afs_linux_permission(struct inode *ip, int mode, unsigned int flags)
+ #elif defined(IOP_PERMISSION_TAKES_NAMEIDATA)
++static int
+ afs_linux_permission(struct inode *ip, int mode, struct nameidata *nd)
+ #else
++static int
+ afs_linux_permission(struct inode *ip, int mode)
+ #endif
+ {
+diff --git a/src/cf/linux-kernel-sig.m4 b/src/cf/linux-kernel-sig.m4
+index 3d3aff909..e0cc9a2f3 100644
+--- a/src/cf/linux-kernel-sig.m4
++++ b/src/cf/linux-kernel-sig.m4
+@@ -14,4 +14,18 @@ AC_CHECK_LINUX_OPERATION([inode_operations], [rename], [takes_flags],
+ [struct inode *oinode, struct dentry *odentry,
+ struct inode *ninode, struct dentry *ndentry,
+ unsigned int flags])
+-])
++dnl Linux 5.12 added the user_namespace parameter to the several
++dnl inode operations functions.
++dnl Perform a generic test using the inode_op create to test for this change.
++AC_CHECK_LINUX_OPERATION([inode_operations], [create], [user_namespace],
++ [#include <linux/fs.h>],
++ [int],
++ [struct user_namespace *mnt_userns,
++ struct inode *inode, struct dentry *dentry,
++ umode_t umode, bool flag])
++dnl if HAVE_LINUX_INODE_OPERATIONS_CREATE_USER_NAMESPACE, create a more generic
++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])])
++])
+\ No newline at end of file
+--
+2.31.1
+