}
-static inline int mdt_remote_permission_check(struct mdt_thread_info *info)
-{
- struct lu_ucred *uc = mdt_ucred(info);
- struct mdt_device *mdt = info->mti_mdt;
-
- if (!md_capable(uc, CFS_CAP_SYS_ADMIN)) {
- if (uc->uc_gid != mdt->mdt_enable_remote_dir_gid &&
- mdt->mdt_enable_remote_dir_gid != -1)
- return -EPERM;
- }
-
- return 0;
-}
-
-/**
- * mdt_remote_permission: Check whether the remote operation is permitted,
- *
- * Only sysadmin can create remote directory / striped directory,
- * migrate directory and set default stripedEA on directory, unless
- *
- * lctl set_param mdt.*.enable_remote_dir_gid=allow_gid.
- *
- * param[in] info: mdt_thread_info.
- *
- * retval = 0 remote operation is allowed.
- * < 0 remote operation is denied.
- */
-static int mdt_remote_permission(struct mdt_thread_info *info)
-{
- struct md_op_spec *spec = &info->mti_spec;
- struct lu_attr *attr = &info->mti_attr.ma_attr;
- struct obd_export *exp = mdt_info_req(info)->rq_export;
- int rc;
-
- if (info->mti_rr.rr_opcode == REINT_MIGRATE) {
- rc = mdt_remote_permission_check(info);
- if (rc != 0)
- return rc;
- }
-
- if (info->mti_rr.rr_opcode == REINT_CREATE &&
- (S_ISDIR(attr->la_mode) && spec->u.sp_ea.eadata != NULL &&
- spec->u.sp_ea.eadatalen != 0)) {
- const struct lmv_user_md *lum = spec->u.sp_ea.eadata;
-
- /* Only new clients can create remote dir( >= 2.4) and
- * striped dir(>= 2.6), old client will return -ENOTSUPP */
- if (!mdt_is_dne_client(exp))
- return -ENOTSUPP;
-
- if (le32_to_cpu(lum->lum_stripe_count) > 1 &&
- !mdt_is_striped_client(exp))
- return -ENOTSUPP;
-
- rc = mdt_remote_permission_check(info);
- if (rc != 0)
- return rc;
- }
-
- if (info->mti_rr.rr_opcode == REINT_SETATTR) {
- struct md_attr *ma = &info->mti_attr;
-
- if ((ma->ma_valid & MA_LMV)) {
- rc = mdt_remote_permission_check(info);
- if (rc != 0)
- return rc;
- }
- }
-
- return 0;
-}
-
static int mdt_unlock_slaves(struct mdt_thread_info *mti,
struct mdt_object *obj,
struct ldlm_enqueue_info *einfo,
policy);
}
-static inline int mdt_reint_striped_lock(struct mdt_thread_info *info,
- struct mdt_object *o,
- struct mdt_lock_handle *lh,
- __u64 ibits,
- struct ldlm_enqueue_info *einfo,
- bool cos_incompat)
+int mdt_reint_striped_lock(struct mdt_thread_info *info,
+ struct mdt_object *o,
+ struct mdt_lock_handle *lh,
+ __u64 ibits,
+ struct ldlm_enqueue_info *einfo,
+ bool cos_incompat)
{
int rc;
return rc;
}
-static inline void
-mdt_reint_striped_unlock(struct mdt_thread_info *info, struct mdt_object *o,
- struct mdt_lock_handle *lh,
- struct ldlm_enqueue_info *einfo, int decref)
+void mdt_reint_striped_unlock(struct mdt_thread_info *info,
+ struct mdt_object *o,
+ struct mdt_lock_handle *lh,
+ struct ldlm_enqueue_info *einfo, int decref)
{
if (einfo->ei_cbdata)
mdt_unlock_slaves(info, o, einfo, decref);
struct mdt_body *repbody;
struct md_attr *ma = &info->mti_attr;
struct mdt_reint_record *rr = &info->mti_rr;
+ struct md_op_spec *spec = &info->mti_spec;
int rc;
ENTRY;
if (!fid_is_md_operative(rr->rr_fid1))
RETURN(-EPERM);
+ if (S_ISDIR(ma->ma_attr.la_mode) &&
+ spec->u.sp_ea.eadata != NULL && spec->u.sp_ea.eadatalen != 0) {
+ const struct lmv_user_md *lum = spec->u.sp_ea.eadata;
+ struct lu_ucred *uc = mdt_ucred(info);
+ struct obd_export *exp = mdt_info_req(info)->rq_export;
+
+ /* Only new clients can create remote dir( >= 2.4) and
+ * striped dir(>= 2.6), old client will return -ENOTSUPP */
+ if (!mdt_is_dne_client(exp))
+ RETURN(-ENOTSUPP);
+
+ if (le32_to_cpu(lum->lum_stripe_count) > 1) {
+ if (!mdt_is_striped_client(exp))
+ RETURN(-ENOTSUPP);
+
+ if (!mdt->mdt_enable_striped_dir)
+ RETURN(-EPERM);
+ } else if (!mdt->mdt_enable_remote_dir) {
+ RETURN(-EPERM);
+ }
+
+ if (!md_capable(uc, CFS_CAP_SYS_ADMIN) &&
+ uc->uc_gid != mdt->mdt_enable_remote_dir_gid &&
+ mdt->mdt_enable_remote_dir_gid != -1)
+ RETURN(-EPERM);
+ }
+
repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
parent = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid1);
if (unlikely(IS_ERR(child)))
GOTO(unlock_parent, rc = PTR_ERR(child));
- rc = mdt_remote_permission(info);
- if (rc != 0)
- GOTO(put_child, rc);
-
ma->ma_need = MA_INODE;
ma->ma_valid = 0;
int mdt_add_dirty_flag(struct mdt_thread_info *info, struct mdt_object *mo,
struct md_attr *ma)
{
+ struct lu_ucred *uc = mdt_ucred(info);
+ cfs_cap_t cap_saved;
int rc;
ENTRY;
&& !(ma->ma_hsm.mh_flags & (HS_DIRTY|HS_RELEASED))) {
ma->ma_hsm.mh_flags |= HS_DIRTY;
+ /* Bump cap so that closes from non-owner writers can
+ * set the HSM state to dirty. */
+ cap_saved = uc->uc_cap;
+ uc->uc_cap |= MD_CAP_TO_MASK(CFS_CAP_FOWNER);
rc = mdt_hsm_attr_set(info, mo, &ma->ma_hsm);
+ uc->uc_cap = cap_saved;
if (rc)
CERROR("file attribute change error for "DFID": %d\n",
PFID(mdt_object_fid(mo)), rc);
}
static int mdt_reint_setattr(struct mdt_thread_info *info,
- struct mdt_lock_handle *lhc)
+ struct mdt_lock_handle *lhc)
{
- struct md_attr *ma = &info->mti_attr;
- struct mdt_reint_record *rr = &info->mti_rr;
- struct ptlrpc_request *req = mdt_info_req(info);
- struct mdt_object *mo;
- struct mdt_body *repbody;
- int rc, rc2;
- ENTRY;
+ struct mdt_device *mdt = info->mti_mdt;
+ struct md_attr *ma = &info->mti_attr;
+ struct mdt_reint_record *rr = &info->mti_rr;
+ struct ptlrpc_request *req = mdt_info_req(info);
+ struct mdt_object *mo;
+ struct mdt_body *repbody;
+ int rc, rc2;
+ ENTRY;
- DEBUG_REQ(D_INODE, req, "setattr "DFID" %x", PFID(rr->rr_fid1),
- (unsigned int)ma->ma_attr.la_valid);
+ DEBUG_REQ(D_INODE, req, "setattr "DFID" %x", PFID(rr->rr_fid1),
+ (unsigned int)ma->ma_attr.la_valid);
if (info->mti_dlm_req)
ldlm_request_cancel(req, info->mti_dlm_req, 0, LATF_SKIP);
repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
- mo = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid1);
- if (IS_ERR(mo))
- GOTO(out, rc = PTR_ERR(mo));
+ mo = mdt_object_find(info->mti_env, mdt, rr->rr_fid1);
+ if (IS_ERR(mo))
+ GOTO(out, rc = PTR_ERR(mo));
if (!mdt_object_exists(mo))
GOTO(out_put, rc = -ENOENT);
GOTO(out_put, rc);
} else if ((ma->ma_valid & (MA_LOV | MA_LMV)) &&
(ma->ma_valid & MA_INODE)) {
- struct lu_buf *buf = &info->mti_buf;
- struct mdt_lock_handle *lh;
+ struct lu_buf *buf = &info->mti_buf;
+ struct lu_ucred *uc = mdt_ucred(info);
+ struct mdt_lock_handle *lh;
- rc = mdt_remote_permission(info);
- if (rc < 0)
- GOTO(out_put, rc);
+ /* reject if either remote or striped dir is disabled */
+ if (ma->ma_valid & MA_LMV) {
+ if (!mdt->mdt_enable_remote_dir ||
+ !mdt->mdt_enable_striped_dir)
+ GOTO(out_put, rc = -EPERM);
+
+ if (!md_capable(uc, CFS_CAP_SYS_ADMIN) &&
+ uc->uc_gid != mdt->mdt_enable_remote_dir_gid &&
+ mdt->mdt_enable_remote_dir_gid != -1)
+ GOTO(out_put, rc = -EPERM);
+ }
if (ma->ma_attr.la_valid != 0)
GOTO(out_put, rc = -EPROTO);
if (!cos_incompat) {
rc = mdt_object_striped(info, mc);
if (rc < 0)
- GOTO(unlock_parent, rc = PTR_ERR(mc));
+ GOTO(unlock_parent, rc);
cos_incompat = rc;
if (cos_incompat) {
* going to be sent to client. If it is - mdt_intent_policy() path will
* fix it up and turn FL_LOCAL flag off.
*/
- rc = mdt_fid_lock(ns, &lh->mlh_reg_lh, lh->mlh_reg_mode, policy,
- res, dlmflags, &info->mti_exp->exp_handle.h_cookie);
+ rc = mdt_fid_lock(info->mti_env, ns, &lh->mlh_reg_lh, lh->mlh_reg_mode,
+ policy, res, dlmflags,
+ &info->mti_exp->exp_handle.h_cookie);
return rc;
}
memset(policy, 0, sizeof *policy);
policy->l_inodebits.bits = MDS_INODELOCK_UPDATE;
flags = LDLM_FL_LOCAL_ONLY | LDLM_FL_ATOMIC_CB;
- rc = ldlm_cli_enqueue_local(ns, res_id, LDLM_IBITS, policy,
- LCK_EX, &flags, ldlm_blocking_ast,
- ldlm_completion_ast, NULL, NULL, 0,
- LVB_T_NONE,
- &info->mti_exp->exp_handle.h_cookie,
- lh);
+ rc = ldlm_cli_enqueue_local(info->mti_env, ns, res_id,
+ LDLM_IBITS, policy, LCK_EX, &flags,
+ ldlm_blocking_ast,
+ ldlm_completion_ast, NULL, NULL, 0,
+ LVB_T_NONE,
+ &info->mti_exp->exp_handle.h_cookie,
+ lh);
RETURN(rc);
}
RETURN(rc);
* in case obj is remote obj on its parent, revoke LOOKUP lock,
* herein we don't really check it, just do revoke.
*/
-static int mdt_revoke_remote_lookup_lock(struct mdt_thread_info *info,
- struct mdt_object *pobj,
- struct mdt_object *obj)
+int mdt_revoke_remote_lookup_lock(struct mdt_thread_info *info,
+ struct mdt_object *pobj,
+ struct mdt_object *obj)
{
struct mdt_lock_handle *lh = &info->mti_lh[MDT_LH_LOCAL];
int rc;
mdt_lock_reg_init(lh, LCK_EX);
if (mdt_object_remote(pobj)) {
+ /* don't bother to check if pobj and obj are on the same MDT. */
rc = mdt_remote_object_lock(info, pobj, mdt_object_fid(obj),
&lh->mlh_rreg_lh, LCK_EX,
MDS_INODELOCK_LOOKUP, false);
- } else {
+ } else if (mdt_object_remote(obj)) {
struct ldlm_res_id *res = &info->mti_res_id;
union ldlm_policy_data *policy = &info->mti_policy;
__u64 dlmflags = LDLM_FL_LOCAL_ONLY | LDLM_FL_ATOMIC_CB |
fid_build_reg_res_name(mdt_object_fid(obj), res);
memset(policy, 0, sizeof(*policy));
policy->l_inodebits.bits = MDS_INODELOCK_LOOKUP;
- rc = mdt_fid_lock(info->mti_mdt->mdt_namespace, &lh->mlh_reg_lh,
- LCK_EX, policy, res, dlmflags, NULL);
+ rc = mdt_fid_lock(info->mti_env, info->mti_mdt->mdt_namespace,
+ &lh->mlh_reg_lh, LCK_EX, policy, res,
+ dlmflags, NULL);
+ } else {
+ /* do nothing if both are local */
+ return 0;
}
if (rc != ELDLM_OK)
INIT_LIST_HEAD(&msl->msl_linkage);
msl->msl_obj = slave;
list_add_tail(&msl->msl_linkage, slave_locks);
-
}
EXIT;
int rc;
if (mdt_object_remote(obj)) {
- /* don't bother to check if pobj and obj are on the same MDT. */
rc = mdt_revoke_remote_lookup_lock(info, pobj, obj);
if (rc)
return rc;
const struct lu_env *env = info->mti_env;
struct mdt_device *mdt = info->mti_mdt;
struct mdt_reint_record *rr = &info->mti_rr;
+ struct lu_ucred *uc = mdt_ucred(info);
struct md_attr *ma = &info->mti_attr;
struct ldlm_enqueue_info *peinfo = &info->mti_einfo[0];
struct ldlm_enqueue_info *seinfo = &info->mti_einfo[1];
if (lu_name_is_dot_or_dotdot(&rr->rr_name))
RETURN(-EBUSY);
- rc = mdt_remote_permission(info);
- if (rc)
- RETURN(rc);
+ if (!mdt->mdt_enable_remote_dir || !mdt->mdt_enable_dir_migration)
+ RETURN(-EPERM);
+
+ if (!md_capable(uc, CFS_CAP_SYS_ADMIN) &&
+ uc->uc_gid != mdt->mdt_enable_remote_dir_gid &&
+ mdt->mdt_enable_remote_dir_gid != -1)
+ RETURN(-EPERM);
/* pobj is master object of parent */
pobj = mdt_object_find_check(info, rr->rr_fid1, 0);
*/
do_sync = rc;
+ /* TODO: DoM migration is not supported yet */
+ if (S_ISREG(lu_object_attr(&sobj->mot_obj))) {
+ ma->ma_lmm = info->mti_big_lmm;
+ ma->ma_lmm_size = info->mti_big_lmmsize;
+ ma->ma_valid = 0;
+ rc = mdt_stripe_get(info, sobj, ma, XATTR_NAME_LOV);
+ if (rc)
+ GOTO(put_source, rc);
+
+ if (ma->ma_valid & MA_LOV &&
+ mdt_lmm_dom_entry(ma->ma_lmm) != LMM_NO_DOM)
+ GOTO(put_source, rc = -EOPNOTSUPP);
+ }
+
/* if migration HSM is allowed */
if (!mdt->mdt_opts.mo_migrate_hsm_allowed) {
ma->ma_need = MA_HSM;
struct mdt_object *mo;
struct ldlm_lock *lease;
struct mdt_body *repbody;
- struct md_layout_change layout = { 0 };
+ struct md_layout_change layout = { .mlc_mirror_id = rr->rr_mirror_id };
bool lease_broken;
int rc, rc2;
ENTRY;
if (mdt_object_remote(mo))
GOTO(out_obj, rc = -EREMOTE);
- lease = ldlm_handle2lock(rr->rr_handle);
+ lease = ldlm_handle2lock(rr->rr_lease_handle);
if (lease == NULL)
GOTO(out_obj, rc = -ESTALE);