From 83bf594d1b08d85b8dd1d477ef2d2f6dfa3ff836 Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Fri, 7 Jul 2023 20:09:35 +0800 Subject: [PATCH] DAOS-13540 object: handle RESTART for TX convert with condition dc_tx_convert_post() may be triggered by the callback for related (existence) condition check. It is relative rare but valid, should not assert. Signed-off-by: Fan Yong --- src/object/obj_tx.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/object/obj_tx.c b/src/object/obj_tx.c index 2e4e58a67b31..d1509099587b 100644 --- a/src/object/obj_tx.c +++ b/src/object/obj_tx.c @@ -83,6 +83,7 @@ struct dc_tx { tx_for_convert:1, tx_has_cond:1, tx_renew:1, + tx_closed:1, tx_reintegrating:1; /** Transaction status (OPEN, COMMITTED, etc.), see dc_tx_status. */ enum dc_tx_status tx_status; @@ -2463,6 +2464,9 @@ dc_tx_open_snap(tse_task_t *task) static void dc_tx_close_internal(struct dc_tx *tx) { + D_ASSERT(tx->tx_closed == 0); + + tx->tx_closed = 1; dc_tx_cleanup(tx); dc_tx_hdl_unlink(tx); dc_tx_decref(tx); @@ -3575,9 +3579,6 @@ dc_tx_convert_restart(struct dc_tx *tx, struct dc_object *obj, enum obj_rpc_opc goto again; out: - if (rc != 0 && tx->tx_has_cond) - dc_tx_close_internal(tx); - return rc; } @@ -3590,7 +3591,6 @@ dc_tx_convert_cb(tse_task_t *task, void *data) enum obj_rpc_opc opc = conv->conv_opc; uint32_t backoff = 0; int rc = task->dt_result; - bool tx_need_close = true; D_DEBUG(DB_IO, "Convert task %p/%p with DTX " DF_DTI ", pm_ver %u: %d\n", task, tx->tx_orig_task, DP_DTI(&tx->tx_id), tx->tx_pm_ver, rc); @@ -3602,15 +3602,11 @@ dc_tx_convert_cb(tse_task_t *task, void *data) * dc_tx_convert_post(). */ task->dt_result = 0; - tx_need_close = false; - rc = dc_tx_convert_restart(tx, obj, opc, &backoff); - if (!tx->tx_has_cond) - rc = dc_tx_convert_post(tx, obj, opc, rc, backoff); - } - - if (tx_need_close) + rc = dc_tx_convert_post(tx, obj, opc, rc, backoff); + } else { dc_tx_close_internal(tx); + } /* Drop object reference held via dc_tx_convert_post(). */ obj_decref(obj); @@ -3630,7 +3626,14 @@ dc_tx_convert_post(struct dc_tx *tx, struct dc_object *obj, enum obj_rpc_opc opc int rc = 0; bool tx_need_close = true; - D_ASSERT(result != -DER_TX_RESTART); + if (unlikely(result == -DER_TX_RESTART)) { + result = dc_tx_convert_restart(tx, obj, opc, &backoff); + /* For condition case, dc_tx_convert_post() will be triggered by dc_tx_post() some + * time later after being re-attached. + */ + if (result == 0 && tx->tx_has_cond) + return 0; + } if (result != 0) D_GOTO(out, rc = result); @@ -3687,7 +3690,6 @@ dc_tx_convert(struct dc_object *obj, enum obj_rpc_opc opc, tse_task_t *task) { struct dc_tx *tx = NULL; int rc = 0; - uint32_t backoff = 0; daos_handle_t coh; D_ASSERT(obj != NULL); @@ -3709,15 +3711,13 @@ dc_tx_convert(struct dc_object *obj, enum obj_rpc_opc opc, tse_task_t *task) tx->tx_for_convert = 1; tx->tx_orig_task = task; rc = dc_tx_attach(dc_tx_ptr2hdl(tx), obj, opc, task, 0, false); - if (unlikely(rc == -DER_TX_RESTART)) - rc = dc_tx_convert_restart(tx, obj, opc, &backoff); /* The 'task' will be completed via dc_tx_convert_post(). For condition case, * dc_tx_convert_post() will be triggered via condition callback; otherwise, * call dc_tx_convert_post() directly. */ - if (!tx->tx_has_cond) - rc = dc_tx_convert_post(tx, obj, opc, rc, backoff); + if (!tx->tx_has_cond || rc != 0) + rc = dc_tx_convert_post(tx, obj, opc, rc, 0); out: if (tx != NULL)