diff options
author | David Young <dyoung@hdfgroup.org> | 2019-12-09 16:30:58 (GMT) |
---|---|---|
committer | David Young <dyoung@hdfgroup.org> | 2019-12-09 16:30:58 (GMT) |
commit | c8f533cfc33ac743227cbed8eba361c715a2976f (patch) | |
tree | bcae5320f80bac774647cacbbd8493604f9384d2 /src/H5Adense.c | |
parent | adcf8a315e82c0848d126e7e46b662930c081896 (diff) | |
download | hdf5-c8f533cfc33ac743227cbed8eba361c715a2976f.zip hdf5-c8f533cfc33ac743227cbed8eba361c715a2976f.tar.gz hdf5-c8f533cfc33ac743227cbed8eba361c715a2976f.tar.bz2 |
Merge all of my changes from merge-back-to-feature-vfd_swmr-attempt-1,
including the merge of `hdffv/hdf5/develop`, back to the branch that Vailin and
I share.
Now I need to put this branch on a fork with a less confusing name than
vchoi_fork!
Diffstat (limited to 'src/H5Adense.c')
-rw-r--r-- | src/H5Adense.c | 65 |
1 files changed, 62 insertions, 3 deletions
diff --git a/src/H5Adense.c b/src/H5Adense.c index 5bed82d..7491dd2 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -299,19 +299,48 @@ done: static herr_t H5A__dense_fnd_cb(const H5A_t *attr, hbool_t *took_ownership, void *_user_attr) { - H5A_t const **user_attr = (H5A_t const **)_user_attr; /* User data from v2 B-tree attribute lookup */ + const H5A_t **user_attr = (const H5A_t **)_user_attr; /* User data from v2 B-tree attribute lookup */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC_NOERR + FUNC_ENTER_STATIC /* Check arguments */ HDassert(attr); HDassert(user_attr); + HDassert(took_ownership); + + /* + * If there is an attribute already stored in "user_attr", + * we need to free the dynamially allocated spaces for the + * attribute, otherwise we got infinite loop closing library due to + * outstanding allocation. (HDFFV-10659) + * + * This callback is used by H5A__dense_remove() to close/free the + * attribute stored in "user_attr" (via H5O__msg_free_real()) after + * the attribute node is deleted from the name index v2 B-tree. + * The issue is: + * When deleting the attribute node from the B-tree, + * if the attribute is found in the intermediate B-tree nodes, + * which may be merged/redistributed, we need to free the dynamically + * allocated spaces for the intermediate decoded attribute. + */ + if(*user_attr != NULL) { + H5A_t *old_attr = *(H5A_t **)_user_attr; + + /* Free any dynamically allocated items */ + if(old_attr->shared) + if(H5A__shared_free(old_attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info") + + old_attr = H5FL_FREE(H5A_t, old_attr); + } /* end if */ /* Take over attribute ownership */ *user_attr = attr; *took_ownership = TRUE; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5A__dense_fnd_cb() */ @@ -868,6 +897,7 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, H5HF_t *fheap = NULL; /* Fractal heap handle */ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ H5B2_t *bt2_name = NULL; /* v2 B-tree handle for name index */ + H5B2_t *bt2_corder = NULL; /* v2 B-tree handle for creation order ndex */ H5A_t *attr_copy = NULL; /* Copy of attribute to rename */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ @@ -945,6 +975,33 @@ H5A__dense_rename(H5F_t *f, const H5O_ainfo_t *ainfo, const char *old_name, if(H5A__set_version(f, attr_copy) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version") + /* Need to remove the attribute from the creation order index v2 B-tree */ + if(ainfo->index_corder) { + htri_t corder_attr_exists; /* Attribute exists in v2 B-tree */ + + /* Open the creation order index v2 B-tree */ + HDassert(H5F_addr_defined(ainfo->corder_bt2_addr)); + if(NULL == (bt2_corder = H5B2_open(f, ainfo->corder_bt2_addr, NULL))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation index") + + /* Set up the creation order to search for */ + udata.corder = attr_copy->shared->crt_idx; + + if((corder_attr_exists = H5B2_find(bt2_corder, &udata, NULL, NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't search for attribute in name index") + + if(corder_attr_exists) { + H5A_bt2_ud_rm_t rm_udata; + + /* Set up the creation order in user data for the v2 B-tree 'record remove' callback */ + rm_udata.common.corder = attr_copy->shared->crt_idx; + + /* Remove the record from the creation order index v2 B-tree */ + if(H5B2_remove(bt2_corder, &rm_udata, NULL, NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "unable to remove attribute from creation order index v2 B-tree") + } + } + /* Insert renamed attribute back into dense storage */ /* (Possibly making it shared) */ if(H5A__dense_insert(f, ainfo, attr_copy) < 0) @@ -992,6 +1049,8 @@ done: HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap") if(bt2_name && H5B2_close(bt2_name) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for name index") + if(bt2_corder && H5B2_close(bt2_corder) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for creation order index") if(attr_copy) H5O_msg_free(H5O_ATTR_ID, attr_copy); |