Пример #1
0
/**
 * 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;

}
Пример #2
0
/* 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;
}