diff options
author | David Young <dyoung@hdfgroup.org> | 2020-06-11 22:02:22 (GMT) |
---|---|---|
committer | David Young <dyoung@hdfgroup.org> | 2020-06-11 22:02:22 (GMT) |
commit | b5d304acf60c5e650b87c28c0be0dd50245611af (patch) | |
tree | 2ffc3d6242ecc8b2e3b1385eee728088e9228202 /src/H5Dchunk.c | |
parent | ff8f7e6da4a9d266dcf4b7c5a97a7366ec440bbe (diff) | |
download | hdf5-b5d304acf60c5e650b87c28c0be0dd50245611af.zip hdf5-b5d304acf60c5e650b87c28c0be0dd50245611af.tar.gz hdf5-b5d304acf60c5e650b87c28c0be0dd50245611af.tar.bz2 |
Extract a subroutine that closes chunk indices,
H5D__chunk_index_close(), and call it in H5D__chunk_read() after reading
a chunked dataset. In this way, indices based on extensible arrays and
v2 B-trees do not leave pinned/tagged entries in the metadata cache that
we cannot evict/refresh when we load changes from the shadow file.
Make some changes to the v1 B-tree code that set the pointer to the
closed B-tree to NULL and, further, tolerate a NULL pointer where
previously that was impossible.
Diffstat (limited to 'src/H5Dchunk.c')
-rw-r--r-- | src/H5Dchunk.c | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 903c15c..556f61b 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -266,6 +266,8 @@ static herr_t H5D__chunk_flush(H5D_t *dset); static herr_t H5D__chunk_io_term(const H5D_chunk_map_t *fm); static herr_t H5D__chunk_dest(H5D_t *dset); +static herr_t H5D__chunk_index_close(H5D_t *); + /* Chunk query operation callbacks */ static int H5D__get_num_chunks_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata); static int H5D__get_chunk_info_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata); @@ -2625,6 +2627,10 @@ H5D__chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info, chunk_node = H5D_CHUNK_GET_NEXT_NODE(fm, chunk_node); } /* end while */ + if(H5D__chunk_index_close(io_info->dset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, + "unable to close chunk index") + done: FUNC_LEAVE_NOAPI(ret_value) } /* H5D__chunk_read() */ @@ -2882,6 +2888,35 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__chunk_io_term() */ +/* Close the given dataset's chunk index. + * + * A useful side-effect of closing the chunk index is the release + * pinned/tagged metadata cache entries connected with the index. + */ +static herr_t +H5D__chunk_index_close(H5D_t *dset) +{ + H5D_chk_idx_info_t idx_info; + H5O_storage_chunk_t *sc = &(dset->shared->layout.storage.u.chunk); + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + H5D_CHUNK_STORAGE_INDEX_CHK(sc); + + /* Compose chunked index info struct */ + idx_info.f = dset->oloc.file; + idx_info.pline = &dset->shared->dcpl_cache.pline; + idx_info.layout = &dset->shared->layout.u.chunk; + idx_info.storage = sc; + + /* Free any index structures */ + if(sc->ops->dest && (sc->ops->dest)(&idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to release chunk index info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /*------------------------------------------------------------------------- * Function: H5D__chunk_dest @@ -2899,18 +2934,15 @@ done: static herr_t H5D__chunk_dest(H5D_t *dset) { - H5D_chk_idx_info_t idx_info; /* Chunked index info */ H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /* Dataset's chunk cache */ H5D_rdcc_ent_t *ent = NULL, *next = NULL; /* Pointer to current & next cache entries */ int nerrors = 0; /* Accumulated count of errors */ - H5O_storage_chunk_t *sc = &(dset->shared->layout.storage.u.chunk); herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC_TAG(dset->oloc.addr) /* Sanity checks */ HDassert(dset); - H5D_CHUNK_STORAGE_INDEX_CHK(sc); /* Flush all the cached chunks */ for(ent = rdcc->head; ent; ent = next) { @@ -2928,15 +2960,19 @@ H5D__chunk_dest(H5D_t *dset) rdcc->slot = H5FL_SEQ_FREE(H5D_rdcc_ent_ptr_t, rdcc->slot); HDmemset(rdcc, 0, sizeof(H5D_rdcc_t)); - /* Compose chunked index info struct */ - idx_info.f = dset->oloc.file; - idx_info.pline = &dset->shared->dcpl_cache.pline; - idx_info.layout = &dset->shared->layout.u.chunk; - idx_info.storage = sc; - - /* Free any index structures */ - if(sc->ops->dest && (sc->ops->dest)(&idx_info) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to release chunk index info") + /* Stopgap fix for VFD SWMR: close the chunk index so that + * pinned/tagged entries in the metadata cache (MDC) are released. + * + * Extensible chunked datasets use extensible arrays or btrees as + * chunk indices. Open chunk indices leave pinned/tagged entries + * in the MDC, and VFD SWMR cannot (yet) evict or refresh those + * entries. After we write refresh routines for those entries, this + * stopgap fix can go away. + */ + if (H5D__chunk_index_close(dset) < 0) { + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, + "unable to close chunk index") + } done: FUNC_LEAVE_NOAPI_TAG(ret_value) |