From: Mikhail Pershin Date: Thu, 1 Oct 2015 18:34:27 +0000 (+0300) Subject: LU-6386 tgt: don't update client data with smaller transno X-Git-Tag: 2.7.62~24 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=5fa93f6011dc37fba3354137457b80151f46c66f;p=fs%2Flustre-release.git LU-6386 tgt: don't update client data with smaller transno Fix tgt_last_rcvd_update() to don't update transaction number in client slot with smaller value. Also patch removes outdated code about ted_lcd == NULL case. This is not possible now, because lcd is set to NULL only upon export destroy. This check was needed in past when that lcd was set to NULL during export disconnect and some activity was still possible on this export. Signed-off-by: Mikhail Pershin Change-Id: I34717ea91493785beadcf725d49c4c9265b63f7c Reviewed-on: http://review.whamcloud.com/14113 Tested-by: Jenkins Reviewed-by: Alex Zhuravlev Tested-by: Maloo Reviewed-by: wangdi Reviewed-by: Oleg Drokin --- diff --git a/lustre/target/tgt_lastrcvd.c b/lustre/target/tgt_lastrcvd.c index a152f05..878246e 100644 --- a/lustre/target/tgt_lastrcvd.c +++ b/lustre/target/tgt_lastrcvd.c @@ -1131,7 +1131,7 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt, struct tg_export_data *ted; __u64 *transno_p; int rc = 0; - bool lw_client, update = false; + bool lw_client; ENTRY; @@ -1190,27 +1190,21 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt, spin_lock(&tgt->lut_translock); if (tti->tti_transno > tgt->lut_lsd.lsd_last_transno) { tgt->lut_lsd.lsd_last_transno = tti->tti_transno; - update = true; + spin_unlock(&tgt->lut_translock); + /* Although lightweight (LW) connections have no slot + * in the last_rcvd, we still want to maintain + * the in-memory lsd_client_data structure in order to + * properly handle reply reconstruction. */ + rc = tgt_server_data_write(env, tgt, th); + } else { + spin_unlock(&tgt->lut_translock); } - spin_unlock(&tgt->lut_translock); - /* Although lightweight (LW) connections have no slot in - * last_rcvd, we still want to maintain the in-memory - * lsd_client_data structure in order to properly handle reply - * reconstruction. */ } else if (ted->ted_lr_off == 0) { CERROR("%s: client idx %d has offset %lld\n", tgt_name(tgt), ted->ted_lr_idx, ted->ted_lr_off); RETURN(-EINVAL); } - /* if the export has already been disconnected, we have no last_rcvd - * slot, update server data with latest transno then */ - if (ted->ted_lcd == NULL) { - CWARN("commit transaction for disconnected client %s: rc %d\n", - exp->exp_client_uuid.uuid, rc); - GOTO(srv_update, rc = 0); - } - /* Target that supports multiple reply data */ if (tgt_is_multimodrpcs_client(exp)) { struct tg_reply_data *trd; @@ -1220,7 +1214,7 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt, OBD_ALLOC_PTR(trd); if (unlikely(trd == NULL)) - GOTO(srv_update, rc = -ENOMEM); + RETURN(-ENOMEM); /* fill reply data information */ lrd = &trd->trd_reply; @@ -1251,12 +1245,14 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt, } rc = tgt_add_reply_data(env, tgt, ted, trd, th, write_update); - GOTO(srv_update, rc); + if (rc < 0) + OBD_FREE_PTR(trd); + return rc; } /* Enough for update replay, let's return */ if (req == NULL) - GOTO(srv_update, rc); + RETURN(rc); mutex_lock(&ted->ted_lcd_lock); LASSERT(ergo(tti->tti_transno == 0, th->th_result != 0)); @@ -1284,21 +1280,27 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt, /* Update transno in slot only if non-zero number, i.e. no errors */ if (likely(tti->tti_transno != 0)) { - if (*transno_p > tti->tti_transno && - !tgt->lut_no_reconstruct) { - CERROR("%s: trying to overwrite bigger transno:" - "on-disk: "LPU64", new: "LPU64" replay: %d. " - "see LU-617.\n", tgt_name(tgt), *transno_p, - tti->tti_transno, req_is_replay(req)); - if (req_is_replay(req)) { - spin_lock(&req->rq_export->exp_lock); - req->rq_export->exp_vbr_failed = 1; - spin_unlock(&req->rq_export->exp_lock); + /* Don't overwrite bigger transaction number with lower one. + * That is not sign of problem in all cases, but in any case + * this value should be monotonically increased only. */ + if (*transno_p > tti->tti_transno) { + if (!tgt->lut_no_reconstruct) { + CERROR("%s: trying to overwrite bigger transno:" + "on-disk: "LPU64", new: "LPU64" replay: " + "%d. See LU-617.\n", tgt_name(tgt), + *transno_p, tti->tti_transno, + req_is_replay(req)); + if (req_is_replay(req)) { + spin_lock(&req->rq_export->exp_lock); + req->rq_export->exp_vbr_failed = 1; + spin_unlock(&req->rq_export->exp_lock); + } + mutex_unlock(&ted->ted_lcd_lock); + RETURN(req_is_replay(req) ? -EOVERFLOW : 0); } - mutex_unlock(&ted->ted_lcd_lock); - RETURN(req_is_replay(req) ? -EOVERFLOW : 0); + } else { + *transno_p = tti->tti_transno; } - *transno_p = tti->tti_transno; } if (!lw_client) { @@ -1310,11 +1312,7 @@ static int tgt_last_rcvd_update(const struct lu_env *env, struct lu_target *tgt, } } mutex_unlock(&ted->ted_lcd_lock); - EXIT; -srv_update: - if (update) - rc = tgt_server_data_write(env, tgt, th); - return rc; + RETURN(rc); } /*