diff --git a/src/dtx/dtx_rpc.c b/src/dtx/dtx_rpc.c index 0e3dd953a50..7b891ac8a38 100644 --- a/src/dtx/dtx_rpc.c +++ b/src/dtx/dtx_rpc.c @@ -628,7 +628,7 @@ dtx_commit(struct ds_cont_child *cont, struct dtx_entry **dtes, out: D_CDEBUG(rc < 0 || rc1 < 0 || rc2 < 0, DLOG_ERR, DB_IO, "Commit DTXs "DF_DTI", count %d: rc %d %d %d\n", - DP_DTI(&dti[0]), count, rc, rc1, rc2); + DP_DTI(&dtes[0]->dte_xid), count, rc, rc1, rc2); D_FREE(dti); diff --git a/src/dtx/dtx_srv.c b/src/dtx/dtx_srv.c index 1f922e269d8..81cb8ee3fd5 100644 --- a/src/dtx/dtx_srv.c +++ b/src/dtx/dtx_srv.c @@ -158,7 +158,11 @@ dtx_handler(crt_rpc_t *rpc) /* Commit the DTX after replied the original refresh request to * avoid further query the same DTX. */ - dtx_commit(cont, pdte, j, true); + rc = dtx_commit(cont, pdte, j, true); + if (rc < 0) + D_WARN("Failed to commit DTX "DF_DTI", count %d: " + DF_RC"\n", DP_DTI(&dtes[0].dte_xid), j, + DP_RC(rc)); for (i = 0; i < j; i++) D_FREE(pdte[i]->dte_mbs); diff --git a/src/object/srv_obj.c b/src/object/srv_obj.c index d6f09ca083a..fac2e30a09c 100644 --- a/src/object/srv_obj.c +++ b/src/object/srv_obj.c @@ -4149,6 +4149,10 @@ ds_obj_dtx_leader_ult(void *arg) req_cnt = ds_obj_cpd_get_dcsr_cnt(dca->dca_rpc, dca->dca_idx); tgt_cnt = ds_obj_cpd_get_tgt_cnt(dca->dca_rpc, dca->dca_idx); + if (dcde == NULL || dcsrs == NULL || tgts == NULL || + req_cnt < 0 || tgt_cnt < 0) + D_GOTO(out, rc = -DER_INVAL); + /* Refuse any modification with old epoch. */ if (dcde->dcde_write_cnt != 0 && dcsh->dcsh_epoch.oe_value < dss_get_start_epoch()) diff --git a/src/tests/suite/daos_dist_tx.c b/src/tests/suite/daos_dist_tx.c index 5b715bfa6c0..29d41e83e40 100644 --- a/src/tests/suite/daos_dist_tx.c +++ b/src/tests/suite/daos_dist_tx.c @@ -2876,11 +2876,8 @@ dtx_sub_setup(void **state) { int rc; - if (state != NULL) { - saved_dtx_arg = *state; - *state = NULL; - } - + saved_dtx_arg = *state; + *state = NULL; rc = test_setup(state, SETUP_CONT_CONNECT, true, SMALL_POOL_SIZE, 0, NULL); return rc; @@ -2892,10 +2889,8 @@ dtx_sub_teardown(void **state) int rc; rc = test_teardown(state); - if (state != NULL && saved_dtx_arg != NULL) { - *state = saved_dtx_arg; - saved_dtx_arg = NULL; - } + *state = saved_dtx_arg; + saved_dtx_arg = NULL; return rc; } diff --git a/src/vos/tests/vts_mvcc.c b/src/vos/tests/vts_mvcc.c index b3b72880ec5..f5061586112 100644 --- a/src/vos/tests/vts_mvcc.c +++ b/src/vos/tests/vts_mvcc.c @@ -1482,20 +1482,22 @@ uncertainty_check_exec_one(struct io_test_args *arg, int i, int j, bool empty, if (!daos_is_zero_dti(&wtx->th_saved_xid)) { if (wtx->th_skip_commit) - vos_dtx_commit(arg->ctx.tc_co_hdl, &wtx->th_saved_xid, - 1, NULL); + rc = vos_dtx_commit(arg->ctx.tc_co_hdl, + &wtx->th_saved_xid, 1, NULL); else - vos_dtx_abort(arg->ctx.tc_co_hdl, DAOS_EPOCH_MAX, - &wtx->th_saved_xid, 1); + rc = vos_dtx_abort(arg->ctx.tc_co_hdl, DAOS_EPOCH_MAX, + &wtx->th_saved_xid, 1); + assert(rc >= 0 || rc == -DER_NONEXIST); } if (!daos_is_zero_dti(&atx->th_saved_xid)) { if (atx->th_skip_commit) - vos_dtx_commit(arg->ctx.tc_co_hdl, &atx->th_saved_xid, - 1, NULL); + rc = vos_dtx_commit(arg->ctx.tc_co_hdl, + &atx->th_saved_xid, 1, NULL); else - vos_dtx_abort(arg->ctx.tc_co_hdl, DAOS_EPOCH_MAX, - &atx->th_saved_xid, 1); + rc = vos_dtx_abort(arg->ctx.tc_co_hdl, DAOS_EPOCH_MAX, + &atx->th_saved_xid, 1); + assert(rc >= 0 || rc == -DER_NONEXIST); } #undef DP_CASE diff --git a/src/vos/vos_dtx.c b/src/vos/vos_dtx.c index 8373ccef446..732093dc1e7 100644 --- a/src/vos/vos_dtx.c +++ b/src/vos/vos_dtx.c @@ -1768,7 +1768,7 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, struct vos_dtx_blob_df *dbd; struct vos_dtx_blob_df *dbd_prev; umem_off_t dbd_off; - struct vos_dtx_cmt_ent_df *dce_df; + struct vos_dtx_cmt_ent_df *dce_df = NULL; int committed = 0; int slots = 0; int cur = 0; @@ -1777,6 +1777,7 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, int i; int j; bool fatal = false; + bool allocated = false; dbd = umem_off2ptr(umm, cont_df->cd_dtx_committed_tail); if (dbd != NULL) @@ -1787,7 +1788,7 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, rc = umem_tx_add_ptr(umm, &dbd->dbd_count, sizeof(dbd->dbd_count)); if (rc != 0) - return rc; + D_GOTO(out, fatal = true); again: if (slots > count) @@ -1802,10 +1803,12 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, DP_DTI(&dtis[cur])); /* non-fatal, former handled ones can be committed. */ - return committed > 0 ? committed : -DER_NOMEM; + D_GOTO(out, rc1 = -DER_NOMEM); } + allocated = true; } else { dce_df = &dbd->dbd_committed_data[dbd->dbd_count]; + allocated = false; } for (i = 0, j = 0; i < slots && rc1 == 0; i++, cur++) { @@ -1816,7 +1819,7 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, daes != NULL ? &daes[cur] : NULL, &fatal); if (fatal) - return rc; + goto out; if (rc == 0 && (daes == NULL || daes[cur] != NULL)) committed++; @@ -1850,7 +1853,7 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, dbd->dbd_count += j; if (count == 0 || rc1 != 0) - return committed > 0 ? committed : rc1; + goto out; if (j < slots) { slots -= j; @@ -1865,7 +1868,8 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, if (umoff_is_null(dbd_off)) { D_ERROR("No space to store committed DTX %d "DF_DTI"\n", count, DP_DTI(&dtis[cur])); - return -DER_NOSPACE; + fatal = true; + D_GOTO(out, rc = -DER_NOSPACE); } dbd = umem_off2ptr(umm, dbd_off); @@ -1883,10 +1887,12 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, if (dce_df == NULL) { D_ERROR("Not enough DRAM to commit "DF_DTI"\n", DP_DTI(&dtis[cur])); - return committed > 0 ? committed : -DER_NOMEM; + D_GOTO(out, rc1 = -DER_NOMEM); } + allocated = true; } else { dce_df = &dbd->dbd_committed_data[0]; + allocated = false; } if (dbd_prev == NULL) { @@ -1898,21 +1904,21 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, sizeof(cont_df->cd_dtx_committed_head) + sizeof(cont_df->cd_dtx_committed_tail)); if (rc != 0) - return rc; + D_GOTO(out, fatal = true); cont_df->cd_dtx_committed_head = dbd_off; } else { rc = umem_tx_add_ptr(umm, &dbd_prev->dbd_next, sizeof(dbd_prev->dbd_next)); if (rc != 0) - return rc; + D_GOTO(out, fatal = true); dbd_prev->dbd_next = dbd_off; rc = umem_tx_add_ptr(umm, &cont_df->cd_dtx_committed_tail, sizeof(cont_df->cd_dtx_committed_tail)); if (rc != 0) - return rc; + D_GOTO(out, fatal = true); } cont_df->cd_dtx_committed_tail = dbd_off; @@ -1925,7 +1931,7 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, daes != NULL ? &daes[cur] : NULL, &fatal); if (fatal) - return rc; + goto out; if (rc == 0 && (daes == NULL || daes[cur] != NULL)) committed++; @@ -1951,7 +1957,11 @@ vos_dtx_commit_internal(struct vos_container *cont, struct dtx_id *dtis, dbd->dbd_count = j; - return committed > 0 ? committed : rc1; +out: + if (allocated) + D_FREE(dce_df); + + return fatal ? rc : (committed > 0 ? committed : rc1); } void