-/**
- * Lock slave stripes if necessary, the lock handles of slave stripes
- * will be stored in einfo->ei_cbdata.
- **/
-static int mdt_lock_slaves(struct mdt_thread_info *mti, struct mdt_object *obj,
- enum ldlm_mode mode, __u64 ibits,
- struct mdt_lock_handle *s0_lh,
- struct mdt_object **s0_objp,
- struct ldlm_enqueue_info *einfo)
-{
- union ldlm_policy_data *policy = &mti->mti_policy;
- struct lu_buf *buf = &mti->mti_buf;
- struct lmv_mds_md_v1 *lmv;
- struct lu_fid *fid = &mti->mti_tmp_fid1;
- int rc;
- ENTRY;
-
- if (!S_ISDIR(obj->mot_header.loh_attr))
- RETURN(0);
-
- buf->lb_buf = mti->mti_xattr_buf;
- buf->lb_len = sizeof(mti->mti_xattr_buf);
- rc = mo_xattr_get(mti->mti_env, mdt_object_child(obj), buf,
- XATTR_NAME_LMV);
- if (rc == -ERANGE) {
- rc = mdt_big_xattr_get(mti, obj, XATTR_NAME_LMV);
- if (rc > 0) {
- buf->lb_buf = mti->mti_big_lmm;
- buf->lb_len = mti->mti_big_lmmsize;
- }
- }
-
- if (rc == -ENODATA || rc == -ENOENT)
- RETURN(0);
-
- if (rc <= 0)
- RETURN(rc);
-
- lmv = buf->lb_buf;
- if (le32_to_cpu(lmv->lmv_magic) != LMV_MAGIC_V1)
- RETURN(-EINVAL);
-
- fid_le_to_cpu(fid, &lmv->lmv_stripe_fids[0]);
- if (!lu_fid_eq(fid, mdt_object_fid(obj))) {
- /* Except migrating object, whose 0_stripe and master
- * object are the same object, 0_stripe and master
- * object are different, though they are in the same
- * MDT, to avoid adding osd_object_lock here, so we
- * will enqueue the stripe0 lock in MDT0 for now */
- *s0_objp = mdt_object_find_lock(mti, fid, s0_lh, ibits);
- if (IS_ERR(*s0_objp))
- RETURN(PTR_ERR(*s0_objp));
- }
-
- memset(einfo, 0, sizeof(*einfo));
- einfo->ei_type = LDLM_IBITS;
- einfo->ei_mode = mode;
- einfo->ei_cb_bl = mdt_remote_blocking_ast;
- einfo->ei_cb_local_bl = mdt_blocking_ast;
- einfo->ei_cb_cp = ldlm_completion_ast;
- einfo->ei_enq_slave = 1;
- einfo->ei_namespace = mti->mti_mdt->mdt_namespace;
- memset(policy, 0, sizeof(*policy));
- policy->l_inodebits.bits = ibits;
-
- rc = mo_object_lock(mti->mti_env, mdt_object_child(obj), NULL, einfo,
- policy);
- RETURN(rc);
-}
-
-static int mdt_attr_set(struct mdt_thread_info *info, struct mdt_object *mo,
- struct md_attr *ma)
-{
- struct mdt_lock_handle *lh;
- int do_vbr = ma->ma_attr.la_valid & (LA_MODE|LA_UID|LA_GID|LA_FLAGS);
- __u64 lockpart = MDS_INODELOCK_UPDATE;
- struct ldlm_enqueue_info *einfo = &info->mti_einfo;
- struct mdt_lock_handle *s0_lh;
- struct mdt_object *s0_obj = NULL;
- int rc;
- ENTRY;
-
- lh = &info->mti_lh[MDT_LH_PARENT];
- mdt_lock_reg_init(lh, LCK_PW);
-
- /* Even though the new MDT will grant PERM lock to the old
- * client, but the old client will almost ignore that during
- * So it needs to revoke both LOOKUP and PERM lock here, so
- * both new and old client can cancel the dcache */
- if (ma->ma_attr.la_valid & (LA_MODE|LA_UID|LA_GID))
- lockpart |= MDS_INODELOCK_LOOKUP | MDS_INODELOCK_PERM;
-
- rc = mdt_object_lock(info, mo, lh, lockpart);
- if (rc != 0)
- RETURN(rc);
-
- s0_lh = &info->mti_lh[MDT_LH_LOCAL];
- mdt_lock_reg_init(s0_lh, LCK_PW);
- rc = mdt_lock_slaves(info, mo, LCK_PW, lockpart, s0_lh, &s0_obj, einfo);
- if (rc != 0)
- GOTO(out_unlock, rc);
-
- /* all attrs are packed into mti_attr in unpack_setattr */
- mdt_fail_write(info->mti_env, info->mti_mdt->mdt_bottom,
- OBD_FAIL_MDS_REINT_SETATTR_WRITE);
-
- /* This is only for set ctime when rename's source is on remote MDS. */
- if (unlikely(ma->ma_attr.la_valid == LA_CTIME))
- ma->ma_attr_flags |= MDS_VTX_BYPASS;