From: Jian Yu Date: Fri, 14 Jan 2022 18:22:25 +0000 (-0800) Subject: LU-14651 llite: extend inode methods with user namespace arg X-Git-Tag: 2.14.57~7 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=0feec5a3c7d4518d5c563739124b202a6a0a99f7 LU-14651 llite: extend inode methods with user namespace arg Kernel 5.12 supports idmapped mounts, which extends vfsmount struct with a new struct user_namespace member, and also extends some inode methods with an additional user namespace argument. The series can be found here: https://git.kernel.org/pub/scm/linux/kernel/git/brauner/linux.git/log/?h=idmapped_mounts Change-Id: I7cccde8cb3288e1ce3d9b6255796b954a6e115df Signed-off-by: Jian Yu Reviewed-on: https://review.whamcloud.com/45938 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- diff --git a/libcfs/libcfs/crypto/policy.c b/libcfs/libcfs/crypto/policy.c index 5e74454..243b412 100644 --- a/libcfs/libcfs/crypto/policy.c +++ b/libcfs/libcfs/crypto/policy.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "llcrypt_private.h" /** @@ -333,7 +334,7 @@ int llcrypt_ioctl_set_policy(struct file *filp, const void __user *arg) 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); diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index 9247f24..8a66bd9 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1897,8 +1897,8 @@ LB_CHECK_COMPILE([if 'struct vm_fault' replaced virtual_address with address fie vm_fault_address, [ #include ],[ - 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]) @@ -2457,9 +2457,6 @@ lock_manager_ops_lm_compare_owner, [ EXTRA_KCFLAGS="$tmp_flags" ]) # LC_LM_COMPARE_OWNER_EXISTS -AC_DEFUN([LC_PROG_LINUX_SRC], []) -AC_DEFUN([LC_PROG_LINUX_RESULTS], []) - # # LC_FSCRYPT_SUPPORT # @@ -2478,6 +2475,32 @@ 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 +],[ + ((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 @@ -2659,6 +2682,9 @@ AC_DEFUN([LC_PROG_LINUX], [ 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 diff --git a/lustre/include/lustre_compat.h b/lustre/include/lustre_compat.h index 9af8d4b..f4ba40e 100644 --- a/lustre/include/lustre_compat.h +++ b/lustre/include/lustre_compat.h @@ -109,10 +109,12 @@ static inline int d_in_lookup(struct dentry *dentry) #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, @@ -120,7 +122,7 @@ 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); @@ -207,7 +209,7 @@ static inline int __must_check PTR_ERR_OR_ZERO(__force const void *ptr) #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) { @@ -527,13 +529,15 @@ static inline int ll_vfs_getxattr(struct dentry *dentry, struct inode *inode, 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 } @@ -541,26 +545,30 @@ static inline int ll_vfs_setxattr(struct dentry *dentry, struct inode *inode, 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 } @@ -603,4 +611,14 @@ static inline void ll_security_release_secctx(char *secdata, u32 seclen) #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 */ diff --git a/lustre/llite/acl.c b/lustre/llite/acl.c index 7e5b1f0..fb12ce2 100644 --- a/lustre/llite/acl.c +++ b/lustre/llite/acl.c @@ -53,7 +53,8 @@ struct posix_acl *ll_get_acl(struct inode *inode, int type) } #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; @@ -67,7 +68,8 @@ int ll_set_acl(struct inode *inode, struct posix_acl *acl, int type) 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: diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index f335e2c..ae83d1b 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -2227,7 +2227,7 @@ migrate_free: 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); diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 28d5226..4b19afb 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1284,8 +1284,8 @@ static int ll_check_swap_layouts_validity(struct inode *inode1, 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) @@ -4333,7 +4333,7 @@ out_ladvise: 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); @@ -5334,7 +5334,7 @@ fill_attr: 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) @@ -5360,9 +5360,9 @@ fill_attr: 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); @@ -5525,7 +5525,8 @@ out: 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; @@ -5581,7 +5582,7 @@ int ll_inode_permission(struct inode *inode, int mask) 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); diff --git a/lustre/llite/foreign_symlink.h b/lustre/llite/foreign_symlink.h index a44fa5e..b1c10e4 100644 --- a/lustre/llite/foreign_symlink.h +++ b/lustre/llite/foreign_symlink.h @@ -24,13 +24,6 @@ #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, diff --git a/lustre/llite/llite_foreign_symlink.c b/lustre/llite/llite_foreign_symlink.c index 8c66a5e..b9ee7da 100644 --- a/lustre/llite/llite_foreign_symlink.c +++ b/lustre/llite/llite_foreign_symlink.c @@ -795,6 +795,31 @@ failed: 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, @@ -838,20 +863,3 @@ struct inode_operations ll_foreign_dir_symlink_inode_operations = { #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 diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index ff41517..9b7386c 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -273,6 +273,17 @@ struct ll_inode_info { 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); @@ -1096,17 +1107,18 @@ void ll_track_file_opens(struct inode *inode); 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 @@ -1132,7 +1144,8 @@ int ll_migrate(struct inode *parent, struct file *file, 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); @@ -1198,7 +1211,8 @@ int volatile_ref_file(const char *volatile_name, int volatile_len, 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); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 01783b1..ccdcc8c 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1863,7 +1863,8 @@ static int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data) !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) { @@ -1885,7 +1886,7 @@ static int ll_md_setattr(struct dentry *dentry, struct md_op_data *op_data) 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; @@ -2363,7 +2364,8 @@ out: 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; diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index c50f172..3b0267e 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -46,6 +46,18 @@ #include #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, @@ -1121,7 +1133,8 @@ static struct dentry *ll_lookup_nd(struct inode *parent, struct dentry *dentry, * 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)) @@ -1766,8 +1779,8 @@ err_exit: 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; @@ -1808,7 +1821,8 @@ static int ll_mknod(struct inode *dir, struct dentry *dchild, umode_t mode, /* * 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(); @@ -1822,7 +1836,7 @@ static int ll_create_nd(struct inode *dir, struct dentry *dentry, /* 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)); @@ -1834,8 +1848,8 @@ static int ll_create_nd(struct inode *dir, struct dentry *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); @@ -1904,7 +1918,8 @@ out: 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; @@ -2078,9 +2093,10 @@ out: 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 ) @@ -2094,7 +2110,7 @@ static int ll_rename(struct inode *src, struct dentry *src_dchild, 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 @@ -2107,7 +2123,7 @@ static int ll_rename(struct inode *src, struct dentry *src_dchild, 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); diff --git a/lustre/llite/pcc.c b/lustre/llite/pcc.c index f60ab53..9f176b5 100644 --- a/lustre/llite/pcc.c +++ b/lustre/llite/pcc.c @@ -1775,7 +1775,12 @@ int pcc_inode_setattr(struct inode *inode, struct iattr *attr, 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); @@ -2136,7 +2141,8 @@ static int pcc_inode_remove(struct inode *inode, struct dentry *pcc_dentry) { 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); @@ -2160,7 +2166,7 @@ pcc_mkdir(struct dentry *base, const char *name, umode_t mode) 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); @@ -2216,7 +2222,7 @@ pcc_create(struct dentry *base, const char *name, umode_t mode) 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); @@ -2282,7 +2288,7 @@ int pcc_inode_reset_iattr(struct dentry *dentry, unsigned int valid, 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); @@ -2370,8 +2376,9 @@ void pcc_create_attach_cleanup(struct super_block *sb, 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); diff --git a/lustre/llite/symlink.c b/lustre/llite/symlink.c index 1319c09..1a4bf5f 100644 --- a/lustre/llite/symlink.c +++ b/lustre/llite/symlink.c @@ -258,7 +258,6 @@ static const char *ll_follow_link(struct dentry *dentry, void **cookie) # 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 @@ -280,7 +279,12 @@ static const char *ll_follow_link(struct dentry *dentry, void **cookie) * * 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; @@ -289,7 +293,7 @@ static int ll_getattr_link(const struct path *path, struct kstat *stat, 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; @@ -312,7 +316,6 @@ static int ll_getattr_link(const struct path *path, struct kstat *stat, #define ll_getattr_link ll_getattr #endif - const struct inode_operations ll_fast_symlink_inode_operations = { #ifdef HAVE_IOP_GENERIC_READLINK .readlink = generic_readlink, diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index cc7839f..1651d6b 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -90,7 +90,13 @@ static int xattr_type_filter(struct ll_sb_info *sbi, 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) @@ -123,7 +129,7 @@ static int ll_xattr_set_common(const struct xattr_handler *handler, 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 */ @@ -330,7 +336,13 @@ static int ll_setstripe_ea(struct dentry *dentry, struct lov_user_md *lump, 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) @@ -364,8 +376,8 @@ static int ll_xattr_set(const struct xattr_handler *handler, 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, @@ -741,7 +753,8 @@ static int ll_xattr_set_4_3(const struct xattr_handler *handler, 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; @@ -787,7 +800,7 @@ static int ll_xattr_set_common_3_11(struct dentry *dentry, const char *name, 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); } @@ -800,7 +813,7 @@ static int ll_xattr_set_3_11(struct dentry *dentry, const char *name, 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 @@ -811,7 +824,8 @@ static const struct xattr_handler ll_user_xattr_handler = { #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 @@ -826,7 +840,8 @@ static const struct xattr_handler ll_trusted_xattr_handler = { #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 @@ -841,7 +856,8 @@ static const struct xattr_handler ll_security_xattr_handler = { #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 @@ -860,7 +876,8 @@ static const struct xattr_handler ll_acl_access_xattr_handler = { #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 @@ -879,7 +896,8 @@ static const struct xattr_handler ll_acl_default_xattr_handler = { #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 @@ -894,7 +912,8 @@ static const struct xattr_handler ll_lustre_xattr_handler = { #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 diff --git a/lustre/osd-ldiskfs/osd_compat.c b/lustre/osd-ldiskfs/osd_compat.c index 7c8aee1..23e623a 100644 --- a/lustre/osd-ldiskfs/osd_compat.c +++ b/lustre/osd-ldiskfs/osd_compat.c @@ -200,7 +200,7 @@ simple_mkdir(const struct lu_env *env, struct osd_device *osd, 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); @@ -1313,7 +1313,7 @@ int osd_obj_map_recover(struct osd_thread_info *info, /* 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; } diff --git a/lustre/osd-ldiskfs/osd_oi.c b/lustre/osd-ldiskfs/osd_oi.c index 2b3d505..7fb40f3 100644 --- a/lustre/osd-ldiskfs/osd_oi.c +++ b/lustre/osd-ldiskfs/osd_oi.c @@ -349,7 +349,7 @@ static int osd_remove_oi_one(struct osd_device *osd, struct dentry *parent, 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); } diff --git a/lustre/tests/kernel/kinode.c b/lustre/tests/kernel/kinode.c index 0973584..83c531f 100644 --- a/lustre/tests/kernel/kinode.c +++ b/lustre/tests/kernel/kinode.c @@ -64,7 +64,7 @@ static int stat_file(struct kstat *stbuf) 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);