X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_io.c;h=5924aa197194374175376129eb59f6edd1c1cd54;hb=a54ecd2c2d964e2ae226fca5b043b5462a34eb7b;hp=2c0f9a5787bed724b4fa31137b7e0542ea292c81;hpb=804a837775f5f3527546de92f57f57fc5be5bdf2;p=fs%2Flustre-release.git diff --git a/lustre/mdt/mdt_io.c b/lustre/mdt/mdt_io.c index 2c0f9a5..5924aa1 100644 --- a/lustre/mdt/mdt_io.c +++ b/lustre/mdt/mdt_io.c @@ -63,7 +63,7 @@ static void mdt_dom_resource_prolong(struct ldlm_prolong_args *arg) ENTRY; res = ldlm_resource_get(arg->lpa_export->exp_obd->obd_namespace, NULL, - &arg->lpa_resid, LDLM_EXTENT, 0); + &arg->lpa_resid, LDLM_IBITS, 0); if (IS_ERR(res)) { CDEBUG(D_DLMTRACE, "Failed to get resource for resid %llu/%llu\n", @@ -76,7 +76,11 @@ static void mdt_dom_resource_prolong(struct ldlm_prolong_args *arg) if (ldlm_has_dom(lock)) { LDLM_DEBUG(lock, "DOM lock to prolong "); ldlm_lock_prolong_one(lock, arg); - break; + /* only one PW or EX lock can be granted, + * no need to continue search + */ + if (lock->l_granted_mode & (LCK_PW | LCK_EX)) + break; } } unlock_res(res); @@ -137,7 +141,7 @@ static int mdt_rw_hpreq_lock_match(struct ptlrpc_request *req, RETURN(0); /* a bulk write can only hold a reference on a PW extent lock. */ - mode = LCK_PW; + mode = LCK_PW | LCK_GROUP; if (opc == OST_READ) /* whereas a bulk read can be protected by either a PR or PW * extent lock */ @@ -177,7 +181,7 @@ static int mdt_rw_hpreq_check(struct ptlrpc_request *req) LASSERT(rnb != NULL); LASSERT(!(rnb->rnb_flags & OBD_BRW_SRVLOCK)); - pa.lpa_mode = LCK_PW; + pa.lpa_mode = LCK_PW | LCK_GROUP; if (opc == OST_READ) pa.lpa_mode |= LCK_PR; @@ -265,7 +269,7 @@ static int mdt_punch_hpreq_lock_match(struct ptlrpc_request *req, if (!fid_res_name_eq(&oa->o_oi.oi_fid, &lock->l_resource->lr_name)) RETURN(0); - if (!(lock->l_granted_mode & LCK_PW)) + if (!(lock->l_granted_mode & (LCK_PW | LCK_GROUP))) RETURN(0); RETURN(1); @@ -303,14 +307,13 @@ static int mdt_punch_hpreq_check(struct ptlrpc_request *req) LASSERT(!(oa->o_valid & OBD_MD_FLFLAGS && oa->o_flags & OBD_FL_SRVLOCK)); - pa.lpa_mode = LCK_PW; + pa.lpa_mode = LCK_PW | LCK_GROUP; CDEBUG(D_DLMTRACE, "%s: refresh DOM lock for "DFID"\n", tgt_name(tsi->tsi_tgt), PFID(&tsi->tsi_fid)); mdt_prolong_dom_lock(tsi, &pa); - if (pa.lpa_blocks_cnt > 0) { CDEBUG(D_DLMTRACE, "%s: refreshed %u locks timeout for req %p.\n", @@ -595,7 +598,7 @@ static int mdt_commitrw_write(const struct lu_env *env, struct obd_export *exp, struct thandle *th; int rc = 0; int retries = 0; - int i; + int i, restart = 0; ENTRY; @@ -655,8 +658,10 @@ retry: dt_write_lock(env, dob, 0); rc = dt_write_commit(env, dob, lnb, niocount, th, oa->o_size); - if (rc) + if (rc) { + restart = th->th_restart_tran; GOTO(unlock, rc); + } if (la->la_valid) { rc = dt_attr_set(env, dob, la, th); @@ -680,13 +685,23 @@ out_stop: granted = 0; } - th->th_result = rc; + th->th_result = restart ? 0 : rc; dt_trans_stop(env, dt, th); if (rc == -ENOSPC && retries++ < 3) { CDEBUG(D_INODE, "retry after force commit, retries:%d\n", retries); goto retry; } + if (restart) { + retries++; + restart = 0; + if (retries % 10000 == 0) + CERROR("%s: restart IO write too many times: %d\n", + exp->exp_obd->obd_name, retries); + CDEBUG(D_INODE, "retry transaction, retries:%d\n", + retries); + goto retry; + } out: dt_bufs_put(env, dob, lnb, niocount); @@ -1033,22 +1048,26 @@ out: return rc; } -static void mdt_lvb2body(struct ldlm_resource *res, struct mdt_body *mb) +static void mdt_lvb2reply(struct ldlm_resource *res, struct mdt_body *mb, + struct ost_lvb *lvb) { struct ost_lvb *res_lvb; lock_res(res); res_lvb = res->lr_lvb_data; - mb->mbo_dom_size = res_lvb->lvb_size; - mb->mbo_dom_blocks = res_lvb->lvb_blocks; - mb->mbo_mtime = res_lvb->lvb_mtime; - mb->mbo_ctime = res_lvb->lvb_ctime; - mb->mbo_atime = res_lvb->lvb_atime; - + if (lvb) + *lvb = *res_lvb; + + if (mb) { + mb->mbo_dom_size = res_lvb->lvb_size; + mb->mbo_dom_blocks = res_lvb->lvb_blocks; + mb->mbo_mtime = res_lvb->lvb_mtime; + mb->mbo_ctime = res_lvb->lvb_ctime; + mb->mbo_atime = res_lvb->lvb_atime; + mb->mbo_valid |= OBD_MD_FLATIME | OBD_MD_FLCTIME | + OBD_MD_FLMTIME | OBD_MD_DOM_SIZE; + } CDEBUG(D_DLMTRACE, "size %llu\n", res_lvb->lvb_size); - - mb->mbo_valid |= OBD_MD_FLATIME | OBD_MD_FLCTIME | OBD_MD_FLMTIME | - OBD_MD_DOM_SIZE; unlock_res(res); } @@ -1079,7 +1098,7 @@ int mdt_dom_object_size(const struct lu_env *env, struct mdt_device *mdt, if (dom_lock || !mdt_dom_lvb_is_valid(res)) mdt_dom_lvbo_update(res, NULL, NULL, false); - mdt_lvb2body(res, mb); + mdt_lvb2reply(res, mb, NULL); ldlm_resource_putref(res); RETURN(rc); } @@ -1110,6 +1129,8 @@ int mdt_glimpse_enqueue(struct mdt_thread_info *mti, struct ldlm_namespace *ns, ldlm_processing_policy policy; struct ldlm_reply *rep; struct mdt_body *mbo; + struct ost_lvb *lvb; + bool old_client = !exp_connect_dom_lvb(mti->mti_exp); int rc; ENTRY; @@ -1117,19 +1138,28 @@ int mdt_glimpse_enqueue(struct mdt_thread_info *mti, struct ldlm_namespace *ns, policy = ldlm_get_processing_policy(res); LASSERT(policy != NULL); - req_capsule_set_size(mti->mti_pill, &RMF_MDT_MD, RCL_SERVER, 0); - req_capsule_set_size(mti->mti_pill, &RMF_ACL, RCL_SERVER, 0); + if (unlikely(old_client)) { + req_capsule_set_size(mti->mti_pill, &RMF_MDT_MD, RCL_SERVER, 0); + req_capsule_set_size(mti->mti_pill, &RMF_ACL, RCL_SERVER, 0); + } else { + req_capsule_set_size(mti->mti_pill, &RMF_DLM_LVB, RCL_SERVER, + sizeof(*lvb)); + } rc = req_capsule_server_pack(mti->mti_pill); if (rc) RETURN(err_serious(rc)); rep = req_capsule_server_get(mti->mti_pill, &RMF_DLM_REP); - if (rep == NULL) - RETURN(-EPROTO); - mbo = req_capsule_server_get(mti->mti_pill, &RMF_MDT_BODY); - if (mbo == NULL) - RETURN(-EPROTO); + if (unlikely(old_client)) { + mbo = req_capsule_server_get(mti->mti_pill, &RMF_MDT_BODY); + LASSERT(mbo); + lvb = NULL; + } else { + lvb = req_capsule_server_get(mti->mti_pill, &RMF_DLM_LVB); + LASSERT(lvb); + mbo = NULL; + } lock_res(res); /* Check if this is a resend case (MSG_RESENT is set on RPC) and a @@ -1160,14 +1190,12 @@ int mdt_glimpse_enqueue(struct mdt_thread_info *mti, struct ldlm_namespace *ns, if (rc == -ENOENT) { /* We are racing with unlink(); just return -ENOENT */ rep->lock_policy_res2 = ptlrpc_status_hton(-ENOENT); - rc = 0; } else if (rc == -EINVAL) { /* this is possible is client lock has been cancelled but * still exists on server. If that lock was found on server * as only conflicting lock then the client has already * size authority and glimpse is not needed. */ CDEBUG(D_DLMTRACE, "Glimpse from the client owning lock\n"); - rc = 0; } else if (rc < 0) { RETURN(rc); } @@ -1176,7 +1204,8 @@ fill_mbo: /* LVB can be without valid data in case of DOM */ if (!mdt_dom_lvb_is_valid(res)) mdt_dom_lvbo_update(res, lock, NULL, false); - mdt_lvb2body(res, mbo); + mdt_lvb2reply(res, mbo, lvb); + RETURN(rc); } @@ -1247,7 +1276,7 @@ int mdt_brw_enqueue(struct mdt_thread_info *mti, struct ldlm_namespace *ns, GOTO(out_fail, rc); mdt_dom_disk_lvbo_update(mti->mti_env, mo, res, false); } - mdt_lvb2body(res, mbo); + mdt_lvb2reply(res, mbo, NULL); out_fail: rep->lock_policy_res2 = clear_serious(rc); if (rep->lock_policy_res2) {