#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,
}
}
+ /* at umount s_root becomes NULL */
if ((bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM)) &&
- !is_root_inode(inode))
+ inode->i_sb->s_root && !is_root_inode(inode))
ll_prune_aliases(inode);
if (bits & (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM))
switch (lock->l_req_mode) {
case LCK_PR:
mode = LCK_PR;
- /* fallthrough */
+ fallthrough;
case LCK_PW:
mode |= LCK_CR;
break;
case LCK_CW:
mode = LCK_CW;
- /* fallthrough */
+ fallthrough;
case LCK_CR:
mode |= LCK_CR;
break;
"server returned encryption ctx for "DFID"\n",
PFID(ll_inode2fid(inode)));
rc = ll_xattr_cache_insert(inode,
- LL_XATTR_NAME_ENCRYPTION_CONTEXT,
+ xattr_for_enc(inode),
encctx, encctxlen);
if (rc)
CWARN("%s: cannot set enc ctx for "DFID": rc = %d\n",
struct lookup_intent parent_it = {
.it_op = IT_GETATTR,
.it_lock_handle = 0 };
- struct lu_fid fid = ll_i2info(parent)->lli_fid;
+ struct ll_inode_info *lli = ll_i2info(parent);
+ struct lu_fid fid = lli->lli_fid;
/* If it is striped directory, get the real stripe parent */
if (unlikely(ll_dir_striped(parent))) {
+ down_read(&lli->lli_lsm_sem);
rc = md_get_fid_from_lsm(ll_i2mdexp(parent),
- ll_i2info(parent)->lli_lsm_md,
+ lli->lli_lsm_md,
(*de)->d_name.name,
(*de)->d_name.len, &fid);
+ up_read(&lli->lli_lsm_sem);
if (rc != 0)
GOTO(out, rc);
}
rc = ll_setup_filename(parent, &dentry->d_name, 1, &fname, &fid);
if ((!rc || rc == -ENOENT) && fname.is_ciphertext_name) {
spin_lock(&dentry->d_lock);
- dentry->d_flags |= DCACHE_ENCRYPTED_NAME;
+ dentry->d_flags |= DCACHE_NOKEY_NAME;
spin_unlock(&dentry->d_lock);
}
if (rc == -ENOENT)
#ifdef CONFIG_LL_ENCRYPTION
rc = lsi->lsi_cop->get_context(ref_inode,
ctx, ctx_size);
+#elif defined(HAVE_LUSTRE_CRYPTO)
+ rc = ref_inode->i_sb->s_cop->get_context(ref_inode,
+ ctx, ctx_size);
#else
rc = -ENODATA;
#endif
* 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))
struct ll_inode_info *lli = ll_i2info(dir);
struct lmv_stripe_md *lsm;
- op_data->op_dir_depth = lli->lli_dir_depth;
+ op_data->op_dir_depth = lli->lli_inherit_depth ?: lli->lli_dir_depth;
/* parent directory is striped */
if (unlikely(lli->lli_lsm_md))
if (ll_sbi_has_encrypt(sbi) &&
((IS_ENCRYPTED(dir) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) ||
- (unlikely(llcrypt_dummy_context_enabled(dir)) && S_ISDIR(mode)))) {
+ (unlikely(ll_sb_has_test_dummy_encryption(dir->i_sb)) &&
+ S_ISDIR(mode)))) {
err = llcrypt_get_encryption_info(dir);
if (err)
GOTO(err_exit, err);
from_kuid(&init_user_ns, current_fsuid()),
from_kgid(&init_user_ns, current_fsgid()),
current_cap(), rdev, &request);
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 14, 58, 0)
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 15, 58, 0)
/*
* server < 2.12.58 doesn't pack default LMV in intent_getattr reply,
* fetch default LMV here.
ptlrpc_req_finished(request);
request = NULL;
+ ll_finish_md_op_data(op_data);
+ op_data = NULL;
err2 = ll_dir_getstripe(dir, (void **)&lum, &lumsize, &request,
OBD_MD_DEFAULT_MEA);
- ll_finish_md_op_data(op_data);
- op_data = NULL;
if (err2 == 0) {
struct lustre_md md = { NULL };
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;
switch (mode & S_IFMT) {
case 0:
mode |= S_IFREG;
- /* fallthrough */
+ fallthrough;
case S_IFREG:
case S_IFCHR:
case S_IFBLK:
/*
* 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);
if (IS_ERR(op_data))
RETURN(PTR_ERR(op_data));
+ /* If the client is using a subdir mount and does a rename to what it
+ * sees as /.fscrypt, interpret it as the .fscrypt dir at fs root.
+ */
+ if (unlikely(is_root_inode(tgt) && !fid_is_root(ll_inode2fid(tgt)) &&
+ tgt_dchild->d_name.len == strlen(dot_fscrypt_name) &&
+ strncmp(tgt_dchild->d_name.name, dot_fscrypt_name,
+ tgt_dchild->d_name.len) == 0))
+ lu_root_fid(&op_data->op_fid2);
+
if (src_dchild->d_inode)
op_data->op_fid3 = *ll_inode2fid(src_dchild->d_inode);