void mdt_pack_attr2body(struct mdt_thread_info *info, struct mdt_body *b,
const struct lu_attr *attr, const struct lu_fid *fid)
{
- struct md_attr *ma = &info->mti_attr;
+ struct mdt_device *mdt = info->mti_mdt;
struct obd_export *exp = info->mti_exp;
+ struct md_attr *ma = &info->mti_attr;
struct lu_nodemap *nodemap = NULL;
LASSERT(ma->ma_valid & MA_INODE);
else
b->mbo_blocks = 1;
b->mbo_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
- } else if (info->mti_som_valid) { /* som is valid */
+ } else if (info->mti_som_strict &&
+ mdt->mdt_opts.mo_enable_strict_som) {
+ /* use SOM for size*/
b->mbo_valid |= OBD_MD_FLSIZE | OBD_MD_FLBLOCKS;
} else if (ma->ma_valid & MA_SOM) { /* lsom is valid */
b->mbo_valid |= OBD_MD_FLLAZYSIZE | OBD_MD_FLLAZYBLOCKS;
RETURN(rc);
}
+static void mdt_preset_encctx_size(struct mdt_thread_info *info)
+{
+ struct req_capsule *pill = info->mti_pill;
+
+ ENTRY;
+ if (req_capsule_has_field(pill, &RMF_FILE_ENCCTX,
+ RCL_SERVER))
+ /* pre-set size in server part with max size */
+ req_capsule_set_size(pill, &RMF_FILE_ENCCTX,
+ RCL_SERVER,
+ info->mti_mdt->mdt_max_mdsize);
+ EXIT;
+}
+
static int mdt_getattr_internal(struct mdt_thread_info *info,
struct mdt_object *o, int ma_need)
{
* enlarge the buffer when necessary. */
req_capsule_set_size(pill, &RMF_ACL, RCL_SERVER,
LUSTRE_POSIX_ACL_MAX_SIZE_OLD);
+ mdt_preset_encctx_size(info);
rc = req_capsule_server_pack(pill);
if (unlikely(rc != 0))
info->mti_cross_ref = !!(reqbody->mbo_valid & OBD_MD_FLCROSSREF);
rc = mdt_getattr_internal(info, obj, 0);
+ if (unlikely(rc))
+ GOTO(out_shrink, rc);
+
+ rc = mdt_pack_encctx_in_reply(info, obj);
EXIT;
out_shrink:
mdt_client_compatibility(info);
* \param lname encoded hash to find
* \param parent parent object
* \param child object to search with LinkEA
- * \param force_check true to check hash even if LinkEA has only one entry
*
* \retval 1 match found
* \retval 0 no match found
* \retval -ev negative errno upon error
*/
int find_name_matching_hash(struct mdt_thread_info *info, struct lu_name *lname,
- struct mdt_object *parent, struct mdt_object *child,
- bool force_check)
+ struct mdt_object *parent, struct mdt_object *child)
{
/* Here, lname is an encoded hash of on-disk name, and
* client is doing access without encryption key.
struct link_ea_header *leh;
struct link_ea_entry *lee;
struct lu_buf link = { 0 };
- char *hash = NULL;
+ char *hash;
int reclen, count, rc;
ENTRY;
-
- if (lname->ln_namelen < LLCRYPT_FNAME_DIGEST_SIZE)
+ if (lname->ln_namelen < LL_CRYPTO_BLOCK_SIZE)
RETURN(-EINVAL);
buf = lu_buf_check_and_alloc(buf, PATH_MAX);
if (rc < 0)
RETURN(rc);
+ hash = kmalloc(lname->ln_namelen, GFP_NOFS);
+ if (!hash)
+ RETURN(-ENOMEM);
+ rc = critical_decode(lname->ln_name, lname->ln_namelen, hash);
+
leh = buf->lb_buf;
- if (force_check || leh->leh_reccount > 1) {
- hash = kmalloc(lname->ln_namelen, GFP_NOFS);
- if (!hash)
- RETURN(-ENOMEM);
- rc = critical_decode(lname->ln_name, lname->ln_namelen, hash);
- }
lee = (struct link_ea_entry *)(leh + 1);
for (count = 0; count < leh->leh_reccount; count++) {
linkea_entry_unpack(lee, &reclen, &name, &pfid);
- if (!force_check && leh->leh_reccount == 1) {
- /* if there is only one rec, it has to be it */
- *lname = name;
- break;
- }
if (!parent || lu_fid_eq(&pfid, mdt_object_fid(parent))) {
lu_buf_check_and_alloc(&link, name.ln_namelen);
if (!link.lb_buf)
rc = critical_decode(name.ln_name, name.ln_namelen,
link.lb_buf);
- if (memcmp(LLCRYPT_FNAME_DIGEST(link.lb_buf, rc),
- hash, LLCRYPT_FNAME_DIGEST_SIZE) == 0) {
+ if (memcmp(LLCRYPT_EXTRACT_DIGEST(link.lb_buf, rc),
+ hash, LL_CRYPTO_BLOCK_SIZE) == 0) {
*lname = name;
break;
}
GOTO(out_child, rc = -ESTALE);
}
- if (!(info->mti_body->mbo_valid & OBD_MD_NAMEHASH) &&
+ if (!child && is_resent) {
+ lock = ldlm_handle2lock(&lhc->mlh_reg_lh);
+ if (lock == NULL) {
+ /* Lock is pinned by ldlm_handle_enqueue0() as it is
+ * a resend case, however, it could be already destroyed
+ * due to client eviction or a raced cancel RPC.
+ */
+ LDLM_DEBUG_NOLOCK("Invalid lock handle %#llx",
+ lhc->mlh_reg_lh.cookie);
+ RETURN(-ESTALE);
+ }
+ fid_extract_from_res_name(child_fid,
+ &lock->l_resource->lr_name);
+ LDLM_LOCK_PUT(lock);
+ child = mdt_object_find(info->mti_env, info->mti_mdt,
+ child_fid);
+ if (IS_ERR(child))
+ RETURN(PTR_ERR(child));
+ } else if (!(info->mti_body->mbo_valid & OBD_MD_NAMEHASH) &&
lu_name_is_valid(lname)) {
if (info->mti_body->mbo_valid == OBD_MD_FLID) {
rc = mdt_raw_lookup(info, parent, lname);
* So we need to compare name hash with the one in the request.
*/
if (!find_name_matching_hash(info, lname, parent,
- child, true)) {
+ child)) {
mdt_set_disposition(info, ldlm_rep, DISP_LOOKUP_NEG);
mdt_clear_disposition(info, ldlm_rep, DISP_LOOKUP_POS);
GOTO(out_child, rc = -ENOENT);
/* finally, we can get attr for child. */
rc = mdt_getattr_internal(info, child, ma_need);
if (unlikely(rc != 0)) {
- mdt_object_unlock(info, child, lhc, 1);
+ if (!is_resent)
+ mdt_object_unlock(info, child, lhc, 1);
GOTO(out_child, rc);
}
rc = mdt_pack_secctx_in_reply(info, child);
if (unlikely(rc)) {
- mdt_object_unlock(info, child, lhc, 1);
+ if (!is_resent)
+ mdt_object_unlock(info, child, lhc, 1);
GOTO(out_child, rc);
}
rc = mdt_pack_encctx_in_reply(info, child);
if (unlikely(rc)) {
- mdt_object_unlock(info, child, lhc, 1);
+ if (!is_resent)
+ mdt_object_unlock(info, child, lhc, 1);
GOTO(out_child, rc);
}
unlock_parent:
if (lhp)
mdt_object_unlock(info, parent, lhp, 1);
+ if (rc == -ENOENT) {
+ /* return -ENOKEY instead of -ENOENT to encryption-unaware
+ * client if trying to access an encrypted file
+ */
+ int rc2 = mdt_check_enc(info, parent);
+
+ if (rc2)
+ rc = rc2;
+ }
return rc;
}
}
}
-static void mdt_preset_encctx_size(struct mdt_thread_info *info)
-{
- struct req_capsule *pill = info->mti_pill;
-
- if (req_capsule_has_field(pill, &RMF_FILE_ENCCTX,
- RCL_SERVER))
- /* pre-set size in server part with max size */
- req_capsule_set_size(pill, &RMF_FILE_ENCCTX,
- RCL_SERVER,
- info->mti_mdt->mdt_max_mdsize);
-}
-
static int mdt_reint_internal(struct mdt_thread_info *info,
struct mdt_lock_handle *lhc,
__u32 op)
case LUSTRE_Q_SETQUOTAPOOL:
case LUSTRE_Q_SETINFOPOOL:
case LUSTRE_Q_SETDEFAULT_POOL:
+ case LUSTRE_Q_DELETEQID:
if (!nodemap_can_setquota(nodemap, oqctl->qc_type,
oqctl->qc_id))
GOTO(out_nodemap, rc = -EPERM);
- /* fallthrough */
+ fallthrough;
case Q_GETINFO:
case Q_GETQUOTA:
case LUSTRE_Q_GETDEFAULT:
if (qmt == NULL)
GOTO(out_nodemap, rc = -EOPNOTSUPP);
/* slave quotactl */
- /* fallthrough */
+ fallthrough;
case Q_GETOINFO:
case Q_GETOQUOTA:
break;
case LUSTRE_Q_GETINFOPOOL:
case LUSTRE_Q_SETDEFAULT_POOL:
case LUSTRE_Q_GETDEFAULT_POOL:
+ case LUSTRE_Q_DELETEQID:
/* forward quotactl request to QMT */
rc = qmt_hdls.qmth_quotactl(tsi->tsi_env, qmt, oqctl);
break;
einfo->ei_cb_cp = ldlm_completion_ast;
einfo->ei_enq_slave = 0;
einfo->ei_res_id = res_id;
+ einfo->ei_req_slot = 1;
if (cache) {
/*
info->mti_opdata = 0;
info->mti_big_lmm_used = 0;
info->mti_big_acl_used = 0;
- info->mti_som_valid = 0;
+ info->mti_som_strict = 0;
info->mti_spec.no_create = 0;
info->mti_spec.sp_rm_entry = 0;
rc = mdt_getattr_name_lock(info, lhc, child_bits, ldlm_rep);
ldlm_rep->lock_policy_res2 = clear_serious(rc);
- if (mdt_get_disposition(ldlm_rep, DISP_LOOKUP_NEG))
- ldlm_rep->lock_policy_res2 = 0;
- if (!mdt_get_disposition(ldlm_rep, DISP_LOOKUP_POS) ||
- ldlm_rep->lock_policy_res2) {
- lhc->mlh_reg_lh.cookie = 0ull;
- GOTO(out_ucred, rc = ELDLM_LOCK_ABORTED);
- }
+ if (mdt_get_disposition(ldlm_rep, DISP_LOOKUP_NEG) &&
+ ldlm_rep->lock_policy_res2 != -ENOKEY)
+ ldlm_rep->lock_policy_res2 = 0;
+ if (!mdt_get_disposition(ldlm_rep, DISP_LOOKUP_POS) ||
+ ldlm_rep->lock_policy_res2) {
+ lhc->mlh_reg_lh.cookie = 0ull;
+ GOTO(out_ucred, rc = ELDLM_LOCK_ABORTED);
+ }
rc = mdt_intent_lock_replace(info, lockp, lhc, flags, rc);
EXIT;
break;
case IT_GETATTR:
check_mdt_object = true;
- /* fallthrough */
+ fallthrough;
case IT_LOOKUP:
it_format = &RQF_LDLM_INTENT_GETATTR;
it_handler = &mdt_intent_getattr;
INIT_LIST_HEAD(&m->mdt_squash.rsi_nosquash_nids);
spin_lock_init(&m->mdt_squash.rsi_lock);
spin_lock_init(&m->mdt_lock);
- m->mdt_enable_remote_dir = 1;
- m->mdt_enable_striped_dir = 1;
+ m->mdt_enable_chprojid_gid = 0;
m->mdt_enable_dir_migration = 1;
m->mdt_enable_dir_restripe = 0;
m->mdt_enable_dir_auto_split = 0;
+ m->mdt_enable_parallel_rename_dir = 1;
+ m->mdt_enable_parallel_rename_file = 1;
+ m->mdt_enable_remote_dir = 1;
m->mdt_enable_remote_dir_gid = 0;
- m->mdt_enable_chprojid_gid = 0;
m->mdt_enable_remote_rename = 1;
- m->mdt_dir_restripe_nsonly = 1;
m->mdt_enable_remote_subdir_mount = 1;
+ m->mdt_enable_striped_dir = 1;
+ m->mdt_dir_restripe_nsonly = 1;
+ m->mdt_rename_stats.rs_init = ktime_get();
atomic_set(&m->mdt_mds_mds_conns, 0);
atomic_set(&m->mdt_async_commit_count, 0);
else
m->mdt_opts.mo_acl = 0;
+ m->mdt_opts.mo_enable_strict_som = 1;
+
/* XXX: to support suppgid for ACL, we enable identity_upcall
* by default, otherwise, maybe got unexpected -EACCESS. */
if (m->mdt_opts.mo_acl)
atomic_set(&mo->mot_open_count, 0);
mo->mot_restripe_offset = 0;
INIT_LIST_HEAD(&mo->mot_restripe_linkage);
+ mo->mot_lsom_size = 0;
+ mo->mot_lsom_blocks = 0;
+ mo->mot_lsom_inited = false;
RETURN(o);
}
RETURN(NULL);