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)
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);
* 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();
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)
{
*
* 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
{
}
+#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();
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
{
}
+#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();
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
/* 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
{
[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