Skip to content

Commit

Permalink
DAOS-16876 vos: set cont parameter when deregister modification from DTX
Browse files Browse the repository at this point in the history
As long as the container is not destroyed, then anytime want to deregister
a modificaion from related active DTX entry (that is usually triggered for
vos discard or aggregation), the caller needs to offer container handle to
vos_dtx_deregister_record() for locating the DTX entry in active DTX table.
Otherwise, if the caller offers empty container handle, then it will cause
dangling reference in related DTX entry as to data corruption in subsequent
DTX commit or abort.

On the other hand, if the container will be destroyed, then all related DTX
entries for such container will be useless any more. We need to destroy DTX
table firstly to avoid generating dangling DTX references during destroying
the container.

Signed-off-by: Fan Yong <fan.yong@intel.com>
  • Loading branch information
Nasf-Fan committed Dec 21, 2024
1 parent 14f2abd commit 734b47a
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 17 deletions.
18 changes: 8 additions & 10 deletions src/vos/vos_dtx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,6 @@ vos_dtx_deregister_record(struct umem_instance *umm, daos_handle_t coh,
uint32_t entry, daos_epoch_t epoch, umem_off_t record)
{
struct dtx_handle *dth = vos_dth_get(false);
struct vos_container *cont;
struct vos_dtx_act_ent *dae;
struct vos_dtx_act_ent_df *dae_df;
umem_off_t *rec_df;
Expand All @@ -1565,20 +1564,19 @@ vos_dtx_deregister_record(struct umem_instance *umm, daos_handle_t coh,
int rc;
int i;

/*
* If @coh is empty handle, then we are destroying the container. Under such case,
* both the in-DRAM and on-dish DTX entry have already been released or destroyed.
*/
if (daos_handle_is_inval(coh))
return 0;

if (!vos_dtx_is_normal_entry(entry))
return 0;

D_ASSERT(entry >= DTX_LID_RESERVED);

cont = vos_hdl2cont(coh);
/* If "cont" is NULL, then we are destroying the container.
* Under such case, the DTX entry in DRAM has been removed,
* The on-disk entry will be destroyed soon.
*/
if (cont == NULL)
return 0;

found = lrua_lookupx(cont->vc_dtx_array, entry - DTX_LID_RESERVED,
found = lrua_lookupx(vos_hdl2cont(coh)->vc_dtx_array, entry - DTX_LID_RESERVED,
epoch, &dae);
if (!found) {
D_WARN("Could not find active DTX record for lid=%d, epoch="
Expand Down
15 changes: 10 additions & 5 deletions src/vos/vos_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,15 @@ gc_drain_cont(struct vos_gc *gc, struct vos_pool *pool, daos_handle_t coh,
int i;
int rc;

/*
* When we prepaer to drain the container, we do not need DTX entry any long.
* Then destroy DTX table firstly to avoid dangling DXT records during drain
* the container (that may yield).
*/
rc = vos_dtx_table_destroy(&pool->vp_umm, cont);
if (rc != 0)
return rc;

/** Move any leftover bags to the pool gc */
for (i = GC_AKEY; i < GC_CONT; i++) {
src_bin = &cont->cd_gc_bins[i];
Expand Down Expand Up @@ -331,11 +340,7 @@ gc_free_cont(struct vos_gc *gc, struct vos_pool *pool, daos_handle_t coh, struct
}
}

rc = vos_dtx_table_destroy(&pool->vp_umm, cd);
if (rc == 0)
rc = umem_free(&pool->vp_umm, item->it_addr);

return rc;
return umem_free(&pool->vp_umm, item->it_addr);
}

static struct vos_gc gc_table[] = {
Expand Down
2 changes: 1 addition & 1 deletion src/vos/vos_obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -2599,7 +2599,7 @@ vos_obj_iter_aggregate(daos_handle_t ih, bool range_discard)
* be aborted. Then it will be added and handled via GC when ktr_rec_free().
*/

rc = dbtree_iter_delete(oiter->it_hdl, NULL);
rc = dbtree_iter_delete(oiter->it_hdl, obj->obj_cont);
D_ASSERT(rc != -DER_NONEXIST);
} else if (rc == -DER_NONEXIST) {
/* Key no longer exists at epoch but isn't empty */
Expand Down
2 changes: 1 addition & 1 deletion src/vos/vos_obj_index.c
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ oi_iter_aggregate(daos_handle_t ih, bool range_discard)
if (rc != 0)
D_ERROR("Could not evict object "DF_UOID" "DF_RC"\n",
DP_UOID(oid), DP_RC(rc));
rc = dbtree_iter_delete(oiter->oit_hdl, NULL);
rc = dbtree_iter_delete(oiter->oit_hdl, oiter->oit_cont);
D_ASSERT(rc != -DER_NONEXIST);
} else if (rc == -DER_NONEXIST) {
/** ilog isn't visible in range but still has some entries */
Expand Down

0 comments on commit 734b47a

Please sign in to comment.