#include <linux/random.h>
#include <linux/string.h>
#include <linux/mount.h>
+#include <lustre_compat.h>
#include "llcrypt_private.h"
/**
return -EFAULT;
policy.version = version;
- if (!inode_owner_or_capable(inode))
+ if (!inode_owner_or_capable(&init_user_ns, inode))
return -EACCES;
ret = mnt_want_write_file(filp);
vm_fault_address, [
#include <linux/mm.h>
],[
- struct vm_fault vmf;
- vmf.address = NULL;
+ unsigned long vaddr = ((struct vm_fault *)0)->address;
+ (void)vaddr;
],[
AC_DEFINE(HAVE_VM_FAULT_ADDRESS, 1,
[virtual_address has been replaced by address field])
EXTRA_KCFLAGS="$tmp_flags"
]) # LC_LM_COMPARE_OWNER_EXISTS
-AC_DEFUN([LC_PROG_LINUX_SRC], [])
-AC_DEFUN([LC_PROG_LINUX_RESULTS], [])
-
#
# LC_FSCRYPT_SUPPORT
#
]) # LC_FSCRYPT_SUPPORT
#
+# LC_HAVE_USER_NAMESPACE_ARG
+#
+# kernel 5.12 commit 549c7297717c32ee53f156cd949e055e601f67bb
+# fs: make helpers idmap mount aware
+# Extend some inode methods with an additional user namespace argument.
+#
+AC_DEFUN([LC_HAVE_USER_NAMESPACE_ARG], [
+tmp_flags="$EXTRA_KCFLAGS"
+EXTRA_KCFLAGS="-Werror"
+LB_CHECK_COMPILE([if 'inode_operations' members have user namespace argument],
+user_namespace_argument, [
+ #include <linux/fs.h>
+],[
+ ((struct inode_operations *)1)->getattr((struct user_namespace *)NULL,
+ NULL, NULL, 0, 0);
+],[
+ AC_DEFINE(HAVE_USER_NAMESPACE_ARG, 1,
+ ['inode_operations' members have user namespace argument])
+])
+EXTRA_KCFLAGS="$tmp_flags"
+]) # LC_HAVE_USER_NAMESPACE_ARG
+
+AC_DEFUN([LC_PROG_LINUX_SRC], [])
+AC_DEFUN([LC_PROG_LINUX_RESULTS], [])
+
+#
# LC_PROG_LINUX
#
# Lustre linux kernel checks
LC_BIO_BI_PHYS_SEGMENTS
LC_LM_COMPARE_OWNER_EXISTS
+ # 5.12
+ LC_HAVE_USER_NAMESPACE_ARG
+
# kernel patch to extend integrity interface
LC_BIO_INTEGRITY_PREP_FN
#define ll_vfs_rename(a, b, c, d) vfs_rename(a, b, c, d)
#endif
-#ifdef HAVE_VFS_UNLINK_3ARGS
-#define ll_vfs_unlink(a, b) vfs_unlink(a, b, NULL)
+#ifdef HAVE_USER_NAMESPACE_ARG
+#define vfs_unlink(ns, dir, de) vfs_unlink(ns, dir, de, NULL)
+#elif defined HAVE_VFS_UNLINK_3ARGS
+#define vfs_unlink(ns, dir, de) vfs_unlink(dir, de, NULL)
#else
-#define ll_vfs_unlink(a, b) vfs_unlink(a, b)
+#define vfs_unlink(ns, dir, de) vfs_unlink(dir, de)
#endif
static inline int ll_vfs_getattr(struct path *path, struct kstat *st,
{
int rc;
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
rc = vfs_getattr(path, st, request_mask, flags);
#else
rc = vfs_getattr(path, st);
#ifdef HAVE_IOP_SET_ACL
#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
-#ifndef HAVE_POSIX_ACL_UPDATE_MODE
+#if !defined(HAVE_USER_NAMESPACE_ARG) && !defined(HAVE_POSIX_ACL_UPDATE_MODE)
static inline int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
struct posix_acl **acl)
{
const char *name,
void *value, size_t size)
{
-#ifndef HAVE_VFS_SETXATTR
+#ifdef HAVE_USER_NAMESPACE_ARG
+ return vfs_getxattr(&init_user_ns, dentry, name, value, size);
+#elif defined(HAVE_VFS_SETXATTR)
+ return __vfs_getxattr(dentry, inode, name, value, size);
+#else
if (unlikely(!inode->i_op->getxattr))
return -ENODATA;
return inode->i_op->getxattr(dentry, name, value, size);
-#else
- return __vfs_getxattr(dentry, inode, name, value, size);
#endif
}
const char *name,
const void *value, size_t size, int flags)
{
-#ifndef HAVE_VFS_SETXATTR
+#ifdef HAVE_USER_NAMESPACE_ARG
+ return vfs_setxattr(&init_user_ns, dentry, name, value, size, flags);
+#elif defined(HAVE_VFS_SETXATTR)
+ return __vfs_setxattr(dentry, inode, name, value, size, flags);
+#else
if (unlikely(!inode->i_op->setxattr))
return -EOPNOTSUPP;
return inode->i_op->setxattr(dentry, name, value, size, flags);
-#else
- return __vfs_setxattr(dentry, inode, name, value, size, flags);
#endif
}
static inline int ll_vfs_removexattr(struct dentry *dentry, struct inode *inode,
const char *name)
{
-#ifndef HAVE_VFS_SETXATTR
+#ifdef HAVE_USER_NAMESPACE_ARG
+ return vfs_removexattr(&init_user_ns, dentry, name);
+#elif defined(HAVE_VFS_SETXATTR)
+ return __vfs_removexattr(dentry, name);
+#else
if (unlikely(!inode->i_op->setxattr))
return -EOPNOTSUPP;
return inode->i_op->removexattr(dentry, name);
-#else
- return __vfs_removexattr(dentry, name);
#endif
}
#endif
}
+#ifndef HAVE_USER_NAMESPACE_ARG
+#define posix_acl_update_mode(ns, inode, mode, acl) \
+ posix_acl_update_mode(inode, mode, acl)
+#define notify_change(ns, de, attr, inode) notify_change(de, attr, inode)
+#define inode_owner_or_capable(ns, inode) inode_owner_or_capable(inode)
+#define vfs_create(ns, dir, de, mode, ex) vfs_create(dir, de, mode, ex)
+#define vfs_mkdir(ns, dir, de, mode) vfs_mkdir(dir, de, mode)
+#define ll_set_acl(ns, inode, acl, type) ll_set_acl(inode, acl, type)
+#endif
+
#endif /* _LUSTRE_COMPAT_H */
}
#ifdef HAVE_IOP_SET_ACL
-int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+int ll_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
+ struct posix_acl *acl, int type)
{
struct ll_sb_info *sbi = ll_i2sbi(inode);
struct ptlrpc_request *req = NULL;
case ACL_TYPE_ACCESS:
name = XATTR_NAME_POSIX_ACL_ACCESS;
if (acl)
- rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ rc = posix_acl_update_mode(mnt_userns, inode,
+ &inode->i_mode, &acl);
break;
case ACL_TYPE_DEFAULT:
if (!S_ISREG(inode2->i_mode))
GOTO(out_iput, rc = -EINVAL);
- if (!inode_owner_or_capable(inode2))
+ if (!inode_owner_or_capable(&init_user_ns, inode2))
GOTO(out_iput, rc = -EPERM);
rc = pcc_ioctl_detach(inode2, detach->pccd_opt);
if (!S_ISREG(inode1->i_mode) || !S_ISREG(inode2->i_mode))
return -EINVAL;
- if (inode_permission(inode1, MAY_WRITE) ||
- inode_permission(inode2, MAY_WRITE))
+ if (inode_permission(&init_user_ns, inode1, MAY_WRITE) ||
+ inode_permission(&init_user_ns, inode2, MAY_WRITE))
return -EPERM;
if (inode1->i_sb != inode2->i_sb)
if (!S_ISREG(inode->i_mode))
GOTO(out_detach_free, rc = -EINVAL);
- if (!inode_owner_or_capable(inode))
+ if (!inode_owner_or_capable(&init_user_ns, inode))
GOTO(out_detach_free, rc = -EPERM);
rc = pcc_ioctl_detach(inode, detach->pccd_opt);
stat->size = i_size_read(inode);
stat->blocks = inode->i_blocks;
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
if (flags & AT_STATX_DONT_SYNC) {
if (stat->size == 0 &&
lli->lli_attr_valid & OBD_MD_FLLAZYSIZE)
return 0;
}
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
-int ll_getattr(const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int flags)
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
+int ll_getattr(struct user_namespace *mnt_userns, const struct path *path,
+ struct kstat *stat, u32 request_mask, unsigned int flags)
{
return ll_getattr_dentry(path->dentry, stat, request_mask, flags,
false);
return rc;
}
-int ll_inode_permission(struct inode *inode, int mask)
+int ll_inode_permission(struct user_namespace *mnt_userns, struct inode *inode,
+ int mask)
{
int rc = 0;
struct ll_sb_info *sbi;
old_cred = override_creds(cred);
}
- rc = generic_permission(inode, mask);
+ rc = generic_permission(mnt_userns, inode, mask);
/* restore current process's credentials and FS capability */
if (squash_id) {
revert_creds(old_cred);
#define LLITE_FOREIGN_SYMLINK_H
/* llite/llite_foreign_symlink.c */
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
-int ll_foreign_symlink_getattr(const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int flags);
-#else
-int ll_foreign_symlink_getattr(struct vfsmount *mnt, struct dentry *de,
- struct kstat *stat);
-#endif
ssize_t foreign_symlink_enable_show(struct kobject *kobj,
struct attribute *attr, char *buf);
ssize_t foreign_symlink_enable_store(struct kobject *kobj,
RETURN(rc == 0 ? count : rc);
}
+/* foreign fake-symlink version of ll_getattr() */
+#if defined(HAVE_USER_NAMESPACE_ARG)
+int ll_foreign_symlink_getattr(struct user_namespace *mnt_userns,
+ const struct path *path, struct kstat *stat,
+ u32 request_mask, unsigned int flags)
+{
+ return ll_getattr_dentry(path->dentry, stat, request_mask, flags,
+ true);
+}
+#elif defined(HAVE_INODEOPS_ENHANCED_GETATTR)
+int ll_foreign_symlink_getattr(const struct path *path, struct kstat *stat,
+ u32 request_mask, unsigned int flags)
+{
+ return ll_getattr_dentry(path->dentry, stat, request_mask, flags,
+ true);
+}
+#else
+int ll_foreign_symlink_getattr(struct vfsmount *mnt, struct dentry *de,
+ struct kstat *stat)
+{
+ return ll_getattr_dentry(de, stat, STATX_BASIC_STATS,
+ AT_STATX_SYNC_AS_STAT, true);
+}
+#endif
+
struct inode_operations ll_foreign_file_symlink_inode_operations = {
#ifdef HAVE_IOP_GENERIC_READLINK
.readlink = generic_readlink,
#endif
.listxattr = ll_listxattr,
};
-
-/* foreign fake-symlink version of ll_getattr() */
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
-int ll_foreign_symlink_getattr(const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int flags)
-{
- return ll_getattr_dentry(path->dentry, stat, request_mask, flags,
- true);
-}
-#else
-int ll_foreign_symlink_getattr(struct vfsmount *mnt, struct dentry *de,
- struct kstat *stat)
-{
- return ll_getattr_dentry(de, stat, STATX_BASIC_STATS,
- AT_STATX_SYNC_AS_STAT, true);
-}
-#endif
struct list_head lli_lccs; /* list of ll_cl_context */
};
+#ifndef HAVE_USER_NAMESPACE_ARG
+#define inode_permission(ns, inode, mask) inode_permission(inode, mask)
+#define generic_permission(ns, inode, mask) generic_permission(inode, mask)
+#define simple_setattr(ns, de, iattr) simple_setattr(de, iattr)
+#define ll_inode_permission(ns, inode, mask) ll_inode_permission(inode, mask)
+#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
+#define ll_getattr(ns, path, stat, mask, fl) ll_getattr(path, stat, mask, fl)
+#endif /* HAVE_INODEOPS_ENHANCED_GETATTR */
+#define ll_setattr(ns, de, attr) ll_setattr(de, attr)
+#endif
+
static inline void ll_trunc_sem_init(struct ll_trunc_sem *sem)
{
atomic_set(&sem->ll_trunc_readers, 0);
extern void ll_rw_stats_tally(struct ll_sb_info *sbi, pid_t pid,
struct ll_file_data *file, loff_t pos,
size_t count, int rw);
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
-int ll_getattr(const struct path *path, struct kstat *stat,
- u32 request_mask, unsigned int flags);
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
+int ll_getattr(struct user_namespace *mnt_userns, const struct path *path,
+ struct kstat *stat, u32 request_mask, unsigned int flags);
#else
int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
-#endif
+#endif /* HAVE_USER_NAMESPACE_ARG */
int ll_getattr_dentry(struct dentry *de, struct kstat *stat, u32 request_mask,
unsigned int flags, bool foreign);
#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
struct posix_acl *ll_get_acl(struct inode *inode, int type);
-int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type);
+int ll_set_acl(struct user_namespace *mnt_userns, struct inode *inode,
+ struct posix_acl *acl, int type);
#else /* !CONFIG_LUSTRE_FS_POSIX_ACL */
#define ll_get_acl NULL
#define ll_set_acl NULL
struct lmv_user_md *lum, const char *name, __u32 flags);
int ll_get_fid_by_name(struct inode *parent, const char *name,
int namelen, struct lu_fid *fid, struct inode **inode);
-int ll_inode_permission(struct inode *inode, int mask);
+int ll_inode_permission(struct user_namespace *mnt_userns, struct inode *inode,
+ int mask);
int ll_ioctl_check_project(struct inode *inode, __u32 xflags, __u32 projid);
int ll_ioctl_fsgetxattr(struct inode *inode, unsigned int cmd,
unsigned long arg);
struct file **ref_file);
int ll_setattr_raw(struct dentry *dentry, struct iattr *attr,
enum op_xvalid xvalid, bool hsm_import);
-int ll_setattr(struct dentry *de, struct iattr *attr);
+int ll_setattr(struct user_namespace *mnt_userns, struct dentry *de,
+ struct iattr *attr);
int ll_statfs(struct dentry *de, struct kstatfs *sfs);
int ll_statfs_internal(struct ll_sb_info *sbi, struct obd_statfs *osfs,
u32 flags);
!S_ISDIR(inode->i_mode)) {
ia_valid = op_data->op_attr.ia_valid;
op_data->op_attr.ia_valid &= ~TIMES_SET_FLAGS;
- rc = simple_setattr(dentry, &op_data->op_attr);
+ rc = simple_setattr(&init_user_ns, dentry,
+ &op_data->op_attr);
op_data->op_attr.ia_valid = ia_valid;
}
} else if (rc != -EPERM && rc != -EACCES && rc != -ETXTBSY) {
op_data->op_attr.ia_valid &= ~(TIMES_SET_FLAGS | ATTR_SIZE);
if (S_ISREG(inode->i_mode))
inode_lock(inode);
- rc = simple_setattr(dentry, &op_data->op_attr);
+ rc = simple_setattr(&init_user_ns, dentry, &op_data->op_attr);
if (S_ISREG(inode->i_mode))
inode_unlock(inode);
op_data->op_attr.ia_valid = ia_valid;
RETURN(rc);
}
-int ll_setattr(struct dentry *de, struct iattr *attr)
+int ll_setattr(struct user_namespace *mnt_userns, struct dentry *de,
+ struct iattr *attr)
{
int mode = de->d_inode->i_mode;
enum op_xvalid xvalid = 0;
#include <lustre_dlm.h>
#include "llite_internal.h"
+#ifndef HAVE_USER_NAMESPACE_ARG
+#define ll_create_nd(ns, dir, de, mode, ex) ll_create_nd(dir, de, mode, ex)
+#define ll_mkdir(ns, dir, dch, mode) ll_mkdir(dir, dch, mode)
+#define ll_mknod(ns, dir, dch, mode, rd) ll_mknod(dir, dch, mode, rd)
+#ifdef HAVE_IOPS_RENAME_WITH_FLAGS
+#define ll_rename(ns, src, sdc, tgt, tdc, fl) ll_rename(src, sdc, tgt, tdc, fl)
+#else
+#define ll_rename(ns, src, sdc, tgt, tdc) ll_rename(src, sdc, tgt, tdc)
+#endif /* HAVE_IOPS_RENAME_WITH_FLAGS */
+#define ll_symlink(nd, dir, dch, old) ll_symlink(dir, dch, old)
+#endif
+
static int ll_create_it(struct inode *dir, struct dentry *dentry,
struct lookup_intent *it,
void *secctx, __u32 secctxlen, bool encrypt,
* to proceed with lookup. LU-4185
*/
if ((flags & LOOKUP_CREATE) && !(flags & LOOKUP_OPEN) &&
- (inode_permission(parent, MAY_WRITE | MAY_EXEC) == 0))
+ (inode_permission(&init_user_ns,
+ parent, MAY_WRITE | MAY_EXEC) == 0))
return NULL;
if (flags & (LOOKUP_PARENT|LOOKUP_OPEN|LOOKUP_CREATE))
RETURN(err);
}
-static int ll_mknod(struct inode *dir, struct dentry *dchild, umode_t mode,
- dev_t rdev)
+static int ll_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+ struct dentry *dchild, umode_t mode, dev_t rdev)
{
ktime_t kstart = ktime_get();
int err;
/*
* Plain create. Intent create is handled in atomic_open.
*/
-static int ll_create_nd(struct inode *dir, struct dentry *dentry,
+static int ll_create_nd(struct user_namespace *mnt_userns,
+ struct inode *dir, struct dentry *dentry,
umode_t mode, bool want_excl)
{
ktime_t kstart = ktime_get();
/* Using mknod(2) to create a regular file is designed to not recognize
* volatile file name, so we use ll_mknod() here. */
- rc = ll_mknod(dir, dentry, mode, 0);
+ rc = ll_mknod(mnt_userns, dir, dentry, mode, 0);
CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, unhashed %d\n",
dentry, d_unhashed(dentry));
return rc;
}
-static int ll_symlink(struct inode *dir, struct dentry *dchild,
- const char *oldpath)
+static int ll_symlink(struct user_namespace *mnt_userns, struct inode *dir,
+ struct dentry *dchild, const char *oldpath)
{
ktime_t kstart = ktime_get();
int len = strlen(oldpath);
RETURN(err);
}
-static int ll_mkdir(struct inode *dir, struct dentry *dchild, umode_t mode)
+static int ll_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
+ struct dentry *dchild, umode_t mode)
{
ktime_t kstart = ktime_get();
int err;
RETURN(rc);
}
-static int ll_rename(struct inode *src, struct dentry *src_dchild,
+static int ll_rename(struct user_namespace *mnt_userns,
+ struct inode *src, struct dentry *src_dchild,
struct inode *tgt, struct dentry *tgt_dchild
-#ifdef HAVE_IOPS_RENAME_WITH_FLAGS
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_IOPS_RENAME_WITH_FLAGS)
, unsigned int flags
#endif
)
int err;
ENTRY;
-#ifdef HAVE_IOPS_RENAME_WITH_FLAGS
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_IOPS_RENAME_WITH_FLAGS)
if (flags)
return -EINVAL;
#endif
if (unlikely(d_mountpoint(src_dchild) || d_mountpoint(tgt_dchild)))
RETURN(-EBUSY);
-#ifdef HAVE_IOPS_RENAME_WITH_FLAGS
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_IOPS_RENAME_WITH_FLAGS)
err = llcrypt_prepare_rename(src, src_dchild, tgt, tgt_dchild, flags);
#else
err = llcrypt_prepare_rename(src, src_dchild, tgt, tgt_dchild, 0);
pcc_dentry = pcci->pcci_path.dentry;
inode_lock(pcc_dentry->d_inode);
old_cred = override_creds(pcc_super_cred(inode->i_sb));
+#ifdef HAVE_USER_NAMESPACE_ARG
+ rc = pcc_dentry->d_inode->i_op->setattr(&init_user_ns, pcc_dentry,
+ &attr2);
+#else
rc = pcc_dentry->d_inode->i_op->setattr(pcc_dentry, &attr2);
+#endif
revert_creds(old_cred);
inode_unlock(pcc_dentry->d_inode);
{
int rc;
- rc = ll_vfs_unlink(pcc_dentry->d_parent->d_inode, pcc_dentry);
+ rc = vfs_unlink(&init_user_ns,
+ pcc_dentry->d_parent->d_inode, pcc_dentry);
if (rc)
CWARN("%s: failed to unlink PCC file %pd, rc = %d\n",
ll_i2sbi(inode)->ll_fsname, pcc_dentry, rc);
if (d_is_positive(dentry))
goto out;
- rc = vfs_mkdir(dir, dentry, mode);
+ rc = vfs_mkdir(&init_user_ns, dir, dentry, mode);
if (rc) {
dput(dentry);
dentry = ERR_PTR(rc);
if (d_is_positive(dentry))
goto out;
- rc = vfs_create(dir, dentry, mode, false);
+ rc = vfs_create(&init_user_ns, dir, dentry, mode, false);
if (rc) {
dput(dentry);
dentry = ERR_PTR(rc);
attr.ia_size = size;
inode_lock(inode);
- rc = notify_change(dentry, &attr, NULL);
+ rc = notify_change(&init_user_ns, dentry, &attr, NULL);
inode_unlock(inode);
RETURN(rc);
int rc;
old_cred = override_creds(pcc_super_cred(sb));
- rc = ll_vfs_unlink(pca->pca_dentry->d_parent->d_inode,
- pca->pca_dentry);
+ rc = vfs_unlink(&init_user_ns,
+ pca->pca_dentry->d_parent->d_inode,
+ pca->pca_dentry);
if (rc)
CWARN("%s: failed to unlink PCC file %pd: rc = %d\n",
ll_s2sbi(sb)->ll_fsname, pca->pca_dentry, rc);
# endif /* HAVE_IOP_GET_LINK */
#endif /* HAVE_SYMLINK_OPS_USE_NAMEIDATA */
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
/**
* ll_getattr_link() - link-specific getattr to set the correct st_size
* for encrypted symlinks
*
* Return: 0 on success, -errno on failure
*/
-static int ll_getattr_link(const struct path *path, struct kstat *stat,
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
+static int ll_getattr_link(
+#if defined(HAVE_USER_NAMESPACE_ARG)
+ struct user_namespace *mnt_userns,
+#endif
+ const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
struct dentry *dentry = path->dentry;
const char *link;
int rc;
- rc = ll_getattr(path, stat, request_mask, flags);
+ rc = ll_getattr(mnt_userns, path, stat, request_mask, flags);
if (rc || !IS_ENCRYPTED(inode))
return rc;
#define ll_getattr_link ll_getattr
#endif
-
const struct inode_operations ll_fast_symlink_inode_operations = {
#ifdef HAVE_IOP_GENERIC_READLINK
.readlink = generic_readlink,
return 0;
}
+#ifndef HAVE_USER_NAMESPACE_ARG
+#define ll_xattr_set_common(hd, ns, de, inode, name, value, size, flags) \
+ ll_xattr_set_common(hd, de, inode, name, value, size, flags)
+#endif
+
static int ll_xattr_set_common(const struct xattr_handler *handler,
+ struct user_namespace *mnt_userns,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value, size_t size,
int flags)
if ((handler->flags == XATTR_ACL_ACCESS_T ||
handler->flags == XATTR_ACL_DEFAULT_T) &&
- !inode_owner_or_capable(inode))
+ !inode_owner_or_capable(mnt_userns, inode))
RETURN(-EPERM);
/* b10667: ignore lustre special xattr for now */
return rc;
}
+#ifndef HAVE_USER_NAMESPACE_ARG
+#define ll_xattr_set(hd, ns, de, inode, name, value, size, flags) \
+ ll_xattr_set(hd, de, inode, name, value, size, flags)
+#endif
+
static int ll_xattr_set(const struct xattr_handler *handler,
+ struct user_namespace *mnt_userns,
struct dentry *dentry, struct inode *inode,
const char *name, const void *value, size_t size,
int flags)
le32_to_cpu(LOV_MAGIC_MASK)) == le32_to_cpu(LOV_MAGIC_MAGIC))
lustre_swab_lov_user_md((struct lov_user_md *)value, 0);
- return ll_xattr_set_common(handler, dentry, inode, name, value, size,
- flags);
+ return ll_xattr_set_common(handler, mnt_userns, dentry, inode, name,
+ value, size, flags);
}
int ll_xattr_list(struct inode *inode, const char *name, int type, void *buffer,
size, flags);
}
-#elif !defined(HAVE_XATTR_HANDLER_INODE_PARAM)
+#elif !defined(HAVE_USER_NAMESPACE_ARG) && \
+!defined(HAVE_XATTR_HANDLER_INODE_PARAM)
const struct xattr_handler *get_xattr_handler(int handler_flag)
{
int i = 0;
if (!handler)
return -ENXIO;
- return ll_xattr_set_common(handler, dentry, dentry->d_inode, name,
+ return ll_xattr_set_common(handler, NULL, dentry, dentry->d_inode, name,
value, size, flags);
}
if (!handler)
return -ENXIO;
- return ll_xattr_set(handler, dentry, dentry->d_inode, name, value,
+ return ll_xattr_set(handler, NULL, dentry, dentry->d_inode, name, value,
size, flags);
}
#endif
#if defined(HAVE_XATTR_HANDLER_SIMPLIFIED)
.get = ll_xattr_get_common_4_3,
.set = ll_xattr_set_common_4_3,
-#elif !defined(HAVE_XATTR_HANDLER_INODE_PARAM)
+#elif !defined(HAVE_USER_NAMESPACE_ARG) && \
+!defined(HAVE_XATTR_HANDLER_INODE_PARAM)
.get = ll_xattr_get_common_3_11,
.set = ll_xattr_set_common_3_11,
#else
#if defined(HAVE_XATTR_HANDLER_SIMPLIFIED)
.get = ll_xattr_get_4_3,
.set = ll_xattr_set_4_3,
-#elif !defined(HAVE_XATTR_HANDLER_INODE_PARAM)
+#elif !defined(HAVE_USER_NAMESPACE_ARG) && \
+!defined(HAVE_XATTR_HANDLER_INODE_PARAM)
.get = ll_xattr_get_3_11,
.set = ll_xattr_set_3_11,
#else
#if defined(HAVE_XATTR_HANDLER_SIMPLIFIED)
.get = ll_xattr_get_common_4_3,
.set = ll_xattr_set_common_4_3,
-#elif !defined(HAVE_XATTR_HANDLER_INODE_PARAM)
+#elif !defined(HAVE_USER_NAMESPACE_ARG) && \
+!defined(HAVE_XATTR_HANDLER_INODE_PARAM)
.get = ll_xattr_get_common_3_11,
.set = ll_xattr_set_common_3_11,
#else
#if defined(HAVE_XATTR_HANDLER_SIMPLIFIED)
.get = ll_xattr_get_common_4_3,
.set = ll_xattr_set_common_4_3,
-#elif !defined(HAVE_XATTR_HANDLER_INODE_PARAM)
+#elif !defined(HAVE_USER_NAMESPACE_ARG) && \
+!defined(HAVE_XATTR_HANDLER_INODE_PARAM)
.get = ll_xattr_get_common_3_11,
.set = ll_xattr_set_common_3_11,
#else
#if defined(HAVE_XATTR_HANDLER_SIMPLIFIED)
.get = ll_xattr_get_common_4_3,
.set = ll_xattr_set_common_4_3,
-#elif !defined(HAVE_XATTR_HANDLER_INODE_PARAM)
+#elif !defined(HAVE_USER_NAMESPACE_ARG) && \
+!defined(HAVE_XATTR_HANDLER_INODE_PARAM)
.get = ll_xattr_get_common_3_11,
.set = ll_xattr_set_common_3_11,
#else
#if defined(HAVE_XATTR_HANDLER_SIMPLIFIED)
.get = ll_xattr_get_4_3,
.set = ll_xattr_set_4_3,
-#elif !defined(HAVE_XATTR_HANDLER_INODE_PARAM)
+#elif !defined(HAVE_USER_NAMESPACE_ARG) && \
+!defined(HAVE_XATTR_HANDLER_INODE_PARAM)
.get = ll_xattr_get_3_11,
.set = ll_xattr_set_3_11,
#else
RETURN(dchild);
}
- err = vfs_mkdir(dir->d_inode, dchild, mode);
+ err = vfs_mkdir(&init_user_ns, dir->d_inode, dchild, mode);
if (err)
GOTO(out_err, err);
/* If the src object has never been modified, then remove it. */
if (inode->i_size == 0 && inode->i_mode & S_ISUID &&
inode->i_mode & S_ISGID) {
- rc = ll_vfs_unlink(src_parent, src_child);
+ rc = vfs_unlink(&init_user_ns, src_parent, src_child);
if (unlikely(rc == -ENOENT))
rc = 0;
}
if (IS_ERR(child)) {
rc = PTR_ERR(child);
} else {
- rc = ll_vfs_unlink(parent->d_inode, child);
+ rc = vfs_unlink(&init_user_ns, parent->d_inode, child);
dput(child);
}
return -EIO;
}
-#ifdef HAVE_INODEOPS_ENHANCED_GETATTR
+#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
rc = vfs_getattr(&fd->f_path, stbuf, STATX_INO, AT_STATX_SYNC_AS_STAT);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
rc = vfs_getattr(&fd->f_path, stbuf);