}
}
- if (!inode_owner_or_capable(&init_user_ns, inode))
+ if (!inode_owner_or_capable(&nop_mnt_idmap, inode))
return -EACCES;
ret = mnt_want_write_file(filp);
LB2_LINUX_TEST_SRC([acl_with_dentry], [
#include <linux/fs.h>
],[
- struct user_namespace *ns = NULL;
struct dentry *dentry = NULL;
- ((struct inode_operations *)1)->get_acl(ns, dentry, 0);
- (void)ns; (void)dentry;
+ ((struct inode_operations *)1)->get_acl(NULL, dentry, 0);
+ (void)dentry;
],[-Werror])
])
AC_DEFUN([LC_HAVE_ACL_WITH_DENTRY], [
]) # LC_HAVE_U64_CAPABILITY
#
+# LC_HAVE_MNT_IDMAP_ARG
+#
+# linux kernel v6.2-rc1-4-gb74d24f7a74f
+# fs: port ->getattr() to pass mnt_idmap
+# linux kernel v6.2-rc1-3-gc1632a0f1120
+# fs: port ->setattr() to pass mnt_idmap
+#
+AC_DEFUN([LC_SRC_HAVE_MNT_IDMAP_ARG], [
+ LB2_LINUX_TEST_SRC([inode_ops_getattr_has_mnt_idmap_argument], [
+ #include <linux/mount.h>
+ #include <linux/fs.h>
+ ],[
+ ((struct inode_operations *)1)->getattr((struct mnt_idmap *)NULL,
+ NULL, NULL, 0, 0);
+ ],[-Werror])
+])
+AC_DEFUN([LC_HAVE_MNT_IDMAP_ARG], [
+ AC_MSG_CHECKING([if 'inode_operations' members have mnt_idmap argument])
+ LB2_LINUX_TEST_RESULT([inode_ops_getattr_has_mnt_idmap_argument], [
+ AC_DEFINE(HAVE_MNT_IDMAP_ARG, 1,
+ ['inode_operations' members have mnt_idmap argument])
+ AC_DEFINE(HAVE_USER_NAMESPACE_ARG, 1,
+ [use mnt_idmap in place of user_namespace argument])
+ AC_DEFINE(HAVE_DQUOT_TRANSFER_WITH_USER_NS, 1,
+ [use mnt_idmap with dquot_transfer])
+ ])
+]) # LC_HAVE_MNT_IDMAP_ARG
+
+#
+# LC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK
+#
+# Linux commit v6.2-rc3-9-g5970e15dbcfe
+# filelock: move file locking definitions to separate header file
+#
+AC_DEFUN([LC_SRC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK], [
+ LB2_LINUX_TEST_SRC([locks_lock_file_wait_in_filelock], [
+ #include <linux/filelock.h>
+ ],[
+ locks_lock_file_wait(NULL, NULL);
+ ])
+])
+AC_DEFUN([LC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK], [
+ AC_MSG_CHECKING([if 'locks_lock_file_wait' exists in filelock.h])
+ LB2_LINUX_TEST_RESULT([locks_lock_file_wait_in_filelock], [
+ AC_DEFINE(HAVE_LOCKS_LOCK_FILE_WAIT, 1,
+ [kernel has locks_lock_file_wait in filelock.h])
+ AC_DEFINE(HAVE_LINUX_FILELOCK_HEADER, 1,
+ [linux/filelock.h is present])
+ ])
+]) # LC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK
+
+#
# LC_PROG_LINUX
#
# Lustre linux kernel checks
LC_SRC_HAVE_ACL_WITH_DENTRY
# 6.3
+ LC_SRC_HAVE_MNT_IDMAP_ARG
+ LC_SRC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK
LC_SRC_HAVE_U64_CAPABILITY
# kernel patch to extend integrity interface
LC_HAVE_ACL_WITH_DENTRY
# 6.3
+ LC_HAVE_MNT_IDMAP_ARG
+ LC_HAVE_LOCKS_LOCK_FILE_WAIT_IN_FILELOCK
LC_HAVE_U64_CAPABILITY
# kernel patch to extend integrity interface
#define vfs_unlink(ns, dir, de) vfs_unlink(dir, de)
#endif
+#ifndef HAVE_MNT_IDMAP_ARG
+#define mnt_idmap user_namespace
+#define nop_mnt_idmap init_user_ns
+#endif
+
static inline int ll_vfs_getattr(struct path *path, struct kstat *st,
u32 request_mask, unsigned int flags)
{
#ifdef HAVE_IOP_SET_ACL
#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
-#if !defined(HAVE_USER_NAMESPACE_ARG) && !defined(HAVE_POSIX_ACL_UPDATE_MODE)
+#if !defined(HAVE_USER_NAMESPACE_ARG) \
+ && !defined(HAVE_POSIX_ACL_UPDATE_MODE) \
+ && !defined(HAVE_MNT_IDMAP_ARG)
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)
{
-#ifdef HAVE_USER_NAMESPACE_ARG
- return vfs_getxattr(&init_user_ns, dentry, name, value, size);
+#if defined(HAVE_MNT_IDMAP_ARG) || defined(HAVE_USER_NAMESPACE_ARG)
+ return vfs_getxattr(&nop_mnt_idmap, dentry, name, value, size);
#elif defined(HAVE_VFS_SETXATTR)
return __vfs_getxattr(dentry, inode, name, value, size);
#else
const char *name,
const void *value, size_t size, int flags)
{
-#ifdef HAVE_USER_NAMESPACE_ARG
- return vfs_setxattr(&init_user_ns, dentry, name,
+#if defined(HAVE_MNT_IDMAP_ARG) || defined(HAVE_USER_NAMESPACE_ARG)
+ return vfs_setxattr(&nop_mnt_idmap, dentry, name,
VFS_SETXATTR_VALUE(value), size, flags);
#elif defined(HAVE_VFS_SETXATTR)
return __vfs_setxattr(dentry, inode, name, value, size, flags);
static inline int ll_vfs_removexattr(struct dentry *dentry, struct inode *inode,
const char *name)
{
-#ifdef HAVE_USER_NAMESPACE_ARG
- return vfs_removexattr(&init_user_ns, dentry, name);
+#if defined(HAVE_MNT_IDMAP_ARG) || defined(HAVE_USER_NAMESPACE_ARG)
+ return vfs_removexattr(&nop_mnt_idmap, dentry, name);
#elif defined(HAVE_VFS_SETXATTR)
return __vfs_removexattr(dentry, name);
#else
#endif
}
-#ifndef HAVE_USER_NAMESPACE_ARG
+#if !defined(HAVE_USER_NAMESPACE_ARG) && !defined(HAVE_MNT_IDMAP_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 DEBUG_SUBSYSTEM S_LDLM
#include <linux/list.h>
+#ifdef HAVE_LINUX_FILELOCK_HEADER
+#include <linux/filelock.h>
+#endif
#include <lustre_dlm.h>
#include <obd_support.h>
#include <obd_class.h>
struct posix_acl *ll_get_acl(
#ifdef HAVE_ACL_WITH_DENTRY
- struct user_namespace *ns, struct dentry *dentry, int type)
+ struct mnt_idmap *map, struct dentry *dentry, int type)
#elif defined HAVE_GET_ACL_RCU_ARG
struct inode *inode, int type, bool rcu)
#else
}
#ifdef HAVE_IOP_SET_ACL
-int ll_set_acl(struct user_namespace *mnt_userns,
+int ll_set_acl(struct mnt_idmap *map,
#ifdef HAVE_ACL_WITH_DENTRY
struct dentry *dentry,
#else
case ACL_TYPE_ACCESS:
name = XATTR_NAME_POSIX_ACL_ACCESS;
if (acl)
- rc = posix_acl_update_mode(mnt_userns, inode,
+ rc = posix_acl_update_mode(map, inode,
&inode->i_mode, &acl);
break;
if (!S_ISREG(inode2->i_mode))
GOTO(out_iput, rc = -EINVAL);
- if (!inode_owner_or_capable(&init_user_ns, inode2))
+ if (!inode_owner_or_capable(&nop_mnt_idmap, inode2))
GOTO(out_iput, rc = -EPERM);
rc = pcc_ioctl_detach(inode2, detach->pccd_opt);
#include <linux/uidgid.h>
#include <linux/falloc.h>
#include <linux/ktime.h>
+#ifdef HAVE_LINUX_FILELOCK_HEADER
+#include <linux/filelock.h>
+#endif
#include <uapi/linux/lustre/lustre_ioctl.h>
#include <lustre_swab.h>
if (!S_ISREG(inode1->i_mode) || !S_ISREG(inode2->i_mode))
return -EINVAL;
- if (inode_permission(&init_user_ns, inode1, MAY_WRITE) ||
- inode_permission(&init_user_ns, inode2, MAY_WRITE))
+ if (inode_permission(&nop_mnt_idmap, inode1, MAY_WRITE) ||
+ inode_permission(&nop_mnt_idmap, 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(&init_user_ns, inode))
+ if (!inode_owner_or_capable(&nop_mnt_idmap, inode))
GOTO(out_detach_free, rc = -EPERM);
rc = pcc_ioctl_detach(inode, detach->pccd_opt);
}
#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
-int ll_getattr(struct user_namespace *mnt_userns, const struct path *path,
+int ll_getattr(struct mnt_idmap *map, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int flags)
{
return ll_getattr_dentry(path->dentry, stat, request_mask, flags,
return rc;
}
-int ll_inode_permission(struct user_namespace *mnt_userns, struct inode *inode,
- int mask)
+int ll_inode_permission(struct mnt_idmap *idmap, struct inode *inode, int mask)
{
int rc = 0;
struct ll_sb_info *sbi;
old_cred = override_creds(cred);
}
- rc = generic_permission(mnt_userns, inode, mask);
+ rc = generic_permission(idmap, inode, mask);
/* restore current process's credentials and FS capability */
if (squash_id) {
revert_creds(old_cred);
/* foreign fake-symlink version of ll_getattr() */
#if defined(HAVE_USER_NAMESPACE_ARG)
-static int ll_foreign_symlink_getattr(struct user_namespace *mnt_userns,
+static int ll_foreign_symlink_getattr(struct mnt_idmap *map,
const struct path *path,
struct kstat *stat, u32 request_mask,
unsigned int flags)
struct ll_file_data *file, loff_t pos,
size_t count, int rw);
#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
-int ll_getattr(struct user_namespace *mnt_userns, const struct path *path,
+int ll_getattr(struct mnt_idmap *, 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);
#ifdef CONFIG_LUSTRE_FS_POSIX_ACL
struct posix_acl *ll_get_acl(
#ifdef HAVE_ACL_WITH_DENTRY
- struct user_namespace *, struct dentry *, int);
+ struct mnt_idmap *, struct dentry *, int);
#elif defined HAVE_GET_ACL_RCU_ARG
struct inode *inode, int type, bool rcu);
#else
struct inode *inode, int type);
#endif /* HAVE_GET_ACL_RCU_ARG */
-int ll_set_acl(struct user_namespace *mnt_userns,
+int ll_set_acl(struct mnt_idmap *mnt_userns,
#ifdef HAVE_ACL_WITH_DENTRY
struct dentry *dentry,
#else
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 user_namespace *mnt_userns, struct inode *inode,
- int mask);
+int ll_inode_permission(struct mnt_idmap *, struct inode *inode, int mask);
int ll_ioctl_check_project(struct inode *inode, __u32 xflags, __u32 projid);
int ll_set_project(struct inode *inode, __u32 xflags, __u32 projid);
#ifndef HAVE_FILEATTR_GET
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 user_namespace *mnt_userns, struct dentry *de,
- struct iattr *attr);
+int ll_setattr(struct mnt_idmap *, 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);
void ll_delete_inode(struct inode *inode);
#ifdef HAVE_FILEATTR_GET
int ll_fileattr_get(struct dentry *dentry, struct fileattr *fa);
-int ll_fileattr_set(struct user_namespace *mnt_userns,
+int ll_fileattr_set(struct mnt_idmap *mnt_userns,
struct dentry *dentry, struct fileattr *fa);
#endif
int ll_iocontrol(struct inode *inode, struct file *file,
!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(&init_user_ns, dentry,
+ rc = simple_setattr(&nop_mnt_idmap, dentry,
&op_data->op_attr);
op_data->op_attr.ia_valid = ia_valid;
}
op_data->op_attr.ia_valid &= ~(TIMES_SET_FLAGS | ATTR_SIZE);
if (S_ISREG(inode->i_mode))
ll_inode_lock(inode);
- rc = simple_setattr(&init_user_ns, dentry, &op_data->op_attr);
+ rc = simple_setattr(&nop_mnt_idmap, dentry, &op_data->op_attr);
if (S_ISREG(inode->i_mode))
ll_inode_unlock(inode);
op_data->op_attr.ia_valid = ia_valid;
RETURN(rc);
}
-int ll_setattr(struct user_namespace *mnt_userns, struct dentry *de,
- struct iattr *attr)
+int ll_setattr(struct mnt_idmap *map, struct dentry *de, struct iattr *attr)
{
int mode = de->d_inode->i_mode;
enum op_xvalid xvalid = 0;
&fa->fsx_xflags, &fa->fsx_projid);
}
-int ll_fileattr_set(struct user_namespace *mnt_userns,
+int ll_fileattr_set(struct mnt_idmap *mnt_userns,
struct dentry *dentry, struct fileattr *fa)
{
if (fa->fsx_valid)
* to proceed with lookup. LU-4185
*/
if ((flags & LOOKUP_CREATE) && !(flags & LOOKUP_OPEN) &&
- (inode_permission(&init_user_ns,
+ (inode_permission(&nop_mnt_idmap,
parent, MAY_WRITE | MAY_EXEC) == 0))
goto clear;
RETURN(err);
}
-static int ll_mknod(struct user_namespace *mnt_userns, struct inode *dir,
+static int ll_mknod(struct mnt_idmap *map, struct inode *dir,
struct dentry *dchild, umode_t mode, dev_t rdev)
{
ktime_t kstart = ktime_get();
/*
* Plain create. Intent create is handled in atomic_open.
*/
-static int ll_create_nd(struct user_namespace *mnt_userns,
- struct inode *dir, struct dentry *dentry,
- umode_t mode, bool want_excl)
+static int ll_create_nd(struct mnt_idmap *map, struct inode *dir,
+ struct dentry *dentry, umode_t mode, bool want_excl)
{
ktime_t kstart = ktime_get();
int rc;
/* 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(mnt_userns, dir, dentry, mode, 0);
+ rc = ll_mknod(map, 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 user_namespace *mnt_userns, struct inode *dir,
+static int ll_symlink(struct mnt_idmap *map, struct inode *dir,
struct dentry *dchild, const char *oldpath)
{
ktime_t kstart = ktime_get();
RETURN(err);
}
-static int ll_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
+static int ll_mkdir(struct mnt_idmap *map, struct inode *dir,
struct dentry *dchild, umode_t mode)
{
ktime_t kstart = ktime_get();
RETURN(rc);
}
-static int ll_rename(struct user_namespace *mnt_userns,
+static int ll_rename(struct mnt_idmap *map,
struct inode *src, struct dentry *src_dchild,
struct inode *tgt, struct dentry *tgt_dchild
#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_IOPS_RENAME_WITH_FLAGS)
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,
+ rc = pcc_dentry->d_inode->i_op->setattr(&nop_mnt_idmap, pcc_dentry,
&attr2);
#else
rc = pcc_dentry->d_inode->i_op->setattr(pcc_dentry, &attr2);
{
int rc;
- rc = vfs_unlink(&init_user_ns,
+ rc = vfs_unlink(&nop_mnt_idmap,
pcc_dentry->d_parent->d_inode, pcc_dentry);
if (rc)
CWARN("%s: failed to unlink PCC file %pd, rc = %d\n",
if (d_is_positive(dentry))
goto out;
- rc = vfs_mkdir(&init_user_ns, dir, dentry, mode);
+ rc = vfs_mkdir(&nop_mnt_idmap, dir, dentry, mode);
if (rc) {
dput(dentry);
dentry = ERR_PTR(rc);
if (d_is_positive(dentry))
goto out;
- rc = vfs_create(&init_user_ns, dir, dentry, mode, false);
+ rc = vfs_create(&nop_mnt_idmap, dir, dentry, mode, false);
if (rc) {
dput(dentry);
dentry = ERR_PTR(rc);
attr.ia_size = size;
inode_lock(inode);
- rc = notify_change(&init_user_ns, dentry, &attr, NULL);
+ rc = notify_change(&nop_mnt_idmap, dentry, &attr, NULL);
inode_unlock(inode);
RETURN(rc);
int rc;
old_cred = override_creds(pcc_super_cred(sb));
- rc = vfs_unlink(&init_user_ns,
+ rc = vfs_unlink(&nop_mnt_idmap,
pca->pca_dentry->d_parent->d_inode,
pca->pca_dentry);
if (rc)
#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,
+ struct mnt_idmap *map,
#endif
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
const char *link;
int rc;
- rc = ll_getattr(mnt_userns, path, stat, request_mask, flags);
+ rc = ll_getattr(map, path, stat, request_mask, flags);
if (rc || !IS_ENCRYPTED(inode))
return rc;
#endif
static int ll_xattr_set_common(const struct xattr_handler *handler,
- struct user_namespace *mnt_userns,
+ struct mnt_idmap *map,
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(mnt_userns, inode))
+ !inode_owner_or_capable(map, inode))
GOTO(out, rc = -EPERM);
/* b10667: ignore lustre special xattr for now */
#endif
static int ll_xattr_set(const struct xattr_handler *handler,
- struct user_namespace *mnt_userns,
+ struct mnt_idmap *map,
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);
- rc = ll_xattr_set_common(handler, mnt_userns, dentry, inode, name,
+ rc = ll_xattr_set_common(handler, map, dentry, inode, name,
value, size, flags);
out:
ll_clear_inode_lock_owner(inode);
RETURN(dchild);
}
- err = vfs_mkdir(&init_user_ns, dir->d_inode, dchild, mode);
+ err = vfs_mkdir(&nop_mnt_idmap, 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 = vfs_unlink(&init_user_ns, src_parent, src_child);
+ rc = vfs_unlink(&nop_mnt_idmap, src_parent, src_child);
if (unlikely(rc == -ENOENT))
rc = 0;
}
iattr.ia_gid = make_kgid(&init_user_ns, attr->la_gid);
lock_dquot_transfer(inode);
- rc = osd_dquot_transfer(&init_user_ns, inode, &iattr);
+ rc = osd_dquot_transfer(&nop_mnt_idmap, inode, &iattr);
unlock_dquot_transfer(inode);
if (rc) {
CERROR("%s: quota transfer failed. Is quota enforcement enabled on the ldiskfs filesystem? rc = %d\n",
if (IS_ERR(child)) {
rc = PTR_ERR(child);
} else {
- rc = vfs_unlink(&init_user_ns, parent->d_inode, child);
+ rc = vfs_unlink(&nop_mnt_idmap, parent->d_inode, child);
dput(child);
}
};
#if defined(HAVE_USER_NAMESPACE_ARG)
-# define USERNS_ARG mnt_userns,
+# define IDMAP_ARG idmap,
#else
-# define USERNS_ARG
+# define IDMAP_ARG
# ifdef HAVE_INODEOPS_ENHANCED_GETATTR
# define server_getattr(ns, path, st, rq, fl) server_getattr(path, st, rq, fl)
# endif
* inode operations for Lustre server mountpoints
*/
#if defined(HAVE_USER_NAMESPACE_ARG) || defined(HAVE_INODEOPS_ENHANCED_GETATTR)
-static int server_getattr(struct user_namespace *mnt_userns,
+static int server_getattr(struct mnt_idmap *idmap,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags)
{
CDEBUG(D_SUPER, "%s: root_inode from %s ino=%lu, dev=%x\n",
lsi->lsi_svname, root_inode == inode ? "lsi" : "vfsmnt",
root_inode->i_ino, root_inode->i_rdev);
- generic_fillattr(USERNS_ARG root_inode, stat);
+ generic_fillattr(IDMAP_ARG root_inode, stat);
iput(root_inode);
return 0;