#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,
- void *encctx, __u32 encctxlen);
+ void *encctx, __u32 encctxlen, unsigned int open_flags);
/* called from iget5_locked->find_inode() under inode_lock spinlock */
static int ll_test_inode(struct inode *inode, void *opaque)
}
if (bits & MDS_INODELOCK_XATTR) {
- ll_xattr_cache_destroy(inode);
+ ll_xattr_cache_empty(inode);
bits &= ~MDS_INODELOCK_XATTR;
}
it->it_create_mode &= ~current_umask();
if (it->it_op & IT_CREAT &&
- ll_i2sbi(parent)->ll_flags & LL_SBI_FILE_SECCTX) {
+ test_bit(LL_SBI_FILE_SECCTX, ll_i2sbi(parent)->ll_flags)) {
rc = ll_dentry_init_security(dentry, it->it_create_mode,
&dentry->d_name,
&op_data->op_file_secctx_name,
*secctxlen = 0;
}
if (it->it_op & IT_CREAT && encrypt) {
- /* Volatile file name may look like:
- * <parent>/LUSTRE_VOLATILE_HDR:<mdt_index>:<random>:fd=<fd>
- * where fd is opened descriptor of reference file.
- */
if (unlikely(filename_is_volatile(dentry->d_name.name,
dentry->d_name.len, NULL))) {
+ /* get encryption context from reference file */
int ctx_size = LLCRYPT_ENC_CTX_SIZE;
struct lustre_sb_info *lsi;
struct file *ref_file;
struct inode *ref_inode;
- char *p, *q, *fd_str;
void *ctx;
- int fd;
- p = strnstr(dentry->d_name.name, ":fd=",
- dentry->d_name.len);
- if (!p || strlen(p + 4) == 0)
- GOTO(out, retval = ERR_PTR(-EINVAL));
-
- q = strchrnul(p + 4, ':');
- fd_str = kstrndup(p + 4, q - p - 4, GFP_NOFS);
- if (!fd_str)
- GOTO(out, retval = ERR_PTR(-ENOMEM));
- rc = kstrtouint(fd_str, 10, &fd);
- kfree(fd_str);
+ rc = volatile_ref_file(dentry->d_name.name,
+ dentry->d_name.len,
+ &ref_file);
if (rc)
- GOTO(inherit, rc = -EINVAL);
-
- ref_file = fget(fd);
- if (!ref_file)
- GOTO(inherit, rc = -EINVAL);
+ GOTO(out, retval = ERR_PTR(rc));
ref_inode = file_inode(ref_file);
if (!ref_inode) {
#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
op_data->op_file_encctx_size);
OBD_FREE(ctx, ctx_size);
}
-
} else {
inherit:
rc = llcrypt_inherit_context(parent, NULL, op_data,
* 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))
if (rc)
GOTO(out_release, rc);
if (open_flags & O_CREAT) {
- if (!llcrypt_has_encryption_key(dir))
+ /* For migration or mirroring without enc key, we still
+ * need to be able to create a volatile file.
+ */
+ if (!llcrypt_has_encryption_key(dir) &&
+ (!filename_is_volatile(dentry->d_name.name,
+ dentry->d_name.len, NULL) ||
+ (open_flags & O_FILE_ENC) != O_FILE_ENC ||
+ !(open_flags & O_DIRECT)))
GOTO(out_release, rc = -ENOKEY);
encrypt = true;
}
if (it_disposition(it, DISP_OPEN_CREATE)) {
/* Dentry instantiated in ll_create_it. */
rc = ll_create_it(dir, dentry, it, secctx, secctxlen,
- encrypt, encctx, encctxlen);
+ encrypt, encctx, encctxlen,
+ open_flags);
ll_security_release_secctx(secctx, secctxlen);
llcrypt_free_ctx(encctx, encctxlen);
if (rc) {
static int ll_create_it(struct inode *dir, struct dentry *dentry,
struct lookup_intent *it,
void *secctx, __u32 secctxlen, bool encrypt,
- void *encctx, __u32 encctxlen)
+ void *encctx, __u32 encctxlen, unsigned int open_flags)
{
struct inode *inode;
__u64 bits = 0;
if (IS_ERR(inode))
RETURN(PTR_ERR(inode));
- if ((ll_i2sbi(inode)->ll_flags & LL_SBI_FILE_SECCTX) &&
- secctx != NULL) {
+ if (test_bit(LL_SBI_FILE_SECCTX, ll_i2sbi(inode)->ll_flags) &&
+ secctx) {
/* must be done before d_instantiate, because it calls
* security_d_instantiate, which means a getxattr if security
* context is not set yet */
d_instantiate(dentry, inode);
if (encrypt) {
- rc = ll_set_encflags(inode, encctx, encctxlen, true);
+ bool preload = true;
+
+ /* For migration or mirroring without enc key, we
+ * create a volatile file without enc context.
+ */
+ if (!llcrypt_has_encryption_key(dir) &&
+ filename_is_volatile(dentry->d_name.name,
+ dentry->d_name.len, NULL) &&
+ (open_flags & O_FILE_ENC) == O_FILE_ENC &&
+ open_flags & O_DIRECT)
+ preload = false;
+ rc = ll_set_encflags(inode, encctx, encctxlen, preload);
if (rc)
RETURN(rc);
}
- if (!(ll_i2sbi(inode)->ll_flags & LL_SBI_FILE_SECCTX)) {
+ if (!test_bit(LL_SBI_FILE_SECCTX, ll_i2sbi(inode)->ll_flags)) {
rc = ll_inode_init_security(dentry, inode, dir);
if (rc)
RETURN(rc);
struct ll_inode_info *lli = ll_i2info(dir);
struct lmv_stripe_md *lsm;
- op_data->op_dir_depth = lli->lli_depth;
+ op_data->op_dir_depth = lli->lli_dir_depth;
/* parent directory is striped */
if (unlikely(lli->lli_lsm_md))
if (lsm->lsm_md_max_inherit != LMV_INHERIT_NONE &&
(lsm->lsm_md_max_inherit == LMV_INHERIT_UNLIMITED ||
- lsm->lsm_md_max_inherit >= lli->lli_depth)) {
+ lsm->lsm_md_max_inherit >= lli->lli_dir_depth)) {
op_data->op_flags |= MF_QOS_MKDIR;
if (lsm->lsm_md_max_inherit_rr != LMV_INHERIT_RR_NONE &&
(lsm->lsm_md_max_inherit_rr == LMV_INHERIT_RR_UNLIMITED ||
- lsm->lsm_md_max_inherit_rr >= lli->lli_depth))
+ lsm->lsm_md_max_inherit_rr >= lli->lli_dir_depth))
op_data->op_flags |= MF_RR_MKDIR;
CDEBUG(D_INODE, DFID" requests qos mkdir %#x\n",
PFID(&lli->lli_fid), op_data->op_flags);
if (S_ISDIR(mode))
ll_qos_mkdir_prep(op_data, dir);
- if (sbi->ll_flags & LL_SBI_FILE_SECCTX) {
+ if (test_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags)) {
err = ll_dentry_init_security(dchild, mode, &dchild->d_name,
&op_data->op_file_secctx_name,
&op_data->op_file_secctx,
if (err)
GOTO(err_exit, err);
- if (sbi->ll_flags & LL_SBI_FILE_SECCTX) {
+ if (test_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags)) {
/* must be done before d_instantiate, because it calls
* security_d_instantiate, which means a getxattr if security
* context is not set yet */
}
}
- if (!(sbi->ll_flags & LL_SBI_FILE_SECCTX)) {
+ if (!test_bit(LL_SBI_FILE_SECCTX, sbi->ll_flags)) {
err = ll_inode_init_security(dchild, inode, dir);
if (err)
GOTO(err_exit, err);
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;
* immediately.
*/
body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
- if (body->mbo_valid & OBD_MD_FLNLINK)
+ if (body->mbo_valid & OBD_MD_FLNLINK) {
+ spin_lock(&dchild->d_inode->i_lock);
set_nlink(dchild->d_inode, body->mbo_nlink);
+ spin_unlock(&dchild->d_inode->i_lock);
+ }
}
ptlrpc_req_finished(request);
* the link count so the inode can be freed immediately.
*/
body = req_capsule_server_get(&request->rq_pill, &RMF_MDT_BODY);
- if (body->mbo_valid & OBD_MD_FLNLINK)
+ if (body->mbo_valid & OBD_MD_FLNLINK) {
+ spin_lock(&dchild->d_inode->i_lock);
set_nlink(dchild->d_inode, body->mbo_nlink);
+ spin_unlock(&dchild->d_inode->i_lock);
+ }
ll_update_times(request, dir);
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);