/** * Lookup with version checking. * * This checks version of 'name'. Many reint functions uses 'name' for child not * FID, therefore we need to get object by name and check its version. */ int mdt_lookup_version_check(struct mdt_thread_info *info, struct mdt_object *p, struct lu_name *lname, struct lu_fid *fid, int idx) { int rc, vbrc; rc = mdo_lookup(info->mti_env, mdt_object_child(p), lname, fid, &info->mti_spec); /* Check version only during replay */ if (!req_is_replay(mdt_info_req(info))) return rc; info->mti_ver[idx] = ENOENT_VERSION; if (rc == 0) { struct mdt_object *child; child = mdt_object_find(info->mti_env, info->mti_mdt, fid); if (likely(!IS_ERR(child))) { mdt_obj_version_get(info, child, &info->mti_ver[idx]); mdt_object_put(info->mti_env, child); } } vbrc = mdt_version_check(mdt_info_req(info), info->mti_ver[idx], idx); return vbrc ? vbrc : rc; }
/* partial operation for rename */ static int mdt_reint_rename_tgt(struct mdt_thread_info *info) { struct mdt_reint_record *rr = &info->mti_rr; struct ptlrpc_request *req = mdt_info_req(info); struct md_attr *ma = &info->mti_attr; struct mdt_object *mtgtdir; struct mdt_object *mtgt = NULL; struct mdt_lock_handle *lh_tgtdir; struct mdt_lock_handle *lh_tgt = NULL; struct lu_fid *tgt_fid = &info->mti_tmp_fid1; struct lu_name *lname; int rc; ENTRY; DEBUG_REQ(D_INODE, req, "rename_tgt: insert (%s->"DFID") in "DFID, rr->rr_tgt, PFID(rr->rr_fid2), PFID(rr->rr_fid1)); /* step 1: lookup & lock the tgt dir. */ lh_tgtdir = &info->mti_lh[MDT_LH_PARENT]; mdt_lock_pdo_init(lh_tgtdir, LCK_PW, rr->rr_tgt, rr->rr_tgtlen); mtgtdir = mdt_object_find_lock(info, rr->rr_fid1, lh_tgtdir, MDS_INODELOCK_UPDATE, MDT_OBJ_MUST_EXIST); if (IS_ERR(mtgtdir)) RETURN(PTR_ERR(mtgtdir)); /* step 2: find & lock the target object if exists. */ mdt_set_capainfo(info, 0, rr->rr_fid1, BYPASS_CAPA); lname = mdt_name(info->mti_env, (char *)rr->rr_tgt, rr->rr_tgtlen); rc = mdo_lookup(info->mti_env, mdt_object_child(mtgtdir), lname, tgt_fid, &info->mti_spec); if (rc != 0 && rc != -ENOENT) { GOTO(out_unlock_tgtdir, rc); } else if (rc == 0) { /* * In case of replay that name can be already inserted, check * that and do nothing if so. */ if (lu_fid_eq(tgt_fid, rr->rr_fid2)) GOTO(out_unlock_tgtdir, rc); lh_tgt = &info->mti_lh[MDT_LH_CHILD]; mdt_lock_reg_init(lh_tgt, LCK_EX); mtgt = mdt_object_find_lock(info, tgt_fid, lh_tgt, MDS_INODELOCK_LOOKUP, MDT_OBJ_MUST_EXIST); if (IS_ERR(mtgt)) GOTO(out_unlock_tgtdir, rc = PTR_ERR(mtgt)); mdt_reint_init_ma(info, ma); if (!ma->ma_lmm || !ma->ma_cookie) GOTO(out_unlock_tgt, rc = -EINVAL); rc = mdo_rename_tgt(info->mti_env, mdt_object_child(mtgtdir), mdt_object_child(mtgt), rr->rr_fid2, lname, ma); } else /* -ENOENT */ { rc = mdo_name_insert(info->mti_env, mdt_object_child(mtgtdir), lname, rr->rr_fid2, ma); } /* handle last link of tgt object */ if (rc == 0 && mtgt) mdt_handle_last_unlink(info, mtgt, ma); EXIT; out_unlock_tgt: if (mtgt) mdt_object_unlock_put(info, mtgt, lh_tgt, rc); out_unlock_tgtdir: mdt_object_unlock_put(info, mtgtdir, lh_tgtdir, rc); return rc; }