diff options
-rw-r--r-- | src/H5Dbtree.c | 13 | ||||
-rw-r--r-- | src/H5Dchunk.c | 60 |
2 files changed, 55 insertions, 18 deletions
diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c index 098e01b..996c89e 100644 --- a/src/H5Dbtree.c +++ b/src/H5Dbtree.c @@ -1234,8 +1234,8 @@ H5D__btree_idx_delete(const H5D_chk_idx_info_t *idx_info) /* Release the shared B-tree page */ if(NULL == tmp_storage.u.btree.shared) - HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "ref-counted page nil") - if(H5UC_DEC(tmp_storage.u.btree.shared) < 0) + ; /* do nothing */ + else if(H5UC_DEC(tmp_storage.u.btree.shared) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") } /* end if */ @@ -1454,10 +1454,12 @@ H5D__btree_idx_dest(const H5D_chk_idx_info_t *idx_info) /* Free the raw B-tree node buffer */ if(NULL == idx_info->storage->u.btree.shared) - HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil") + HGOTO_DONE(SUCCEED); if(H5UC_DEC(idx_info->storage->u.btree.shared) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page") + idx_info->storage->u.btree.shared = NULL; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__btree_idx_dest() */ @@ -1517,9 +1519,8 @@ done: /* Free the raw B-tree node buffer */ if(NULL == storage.u.btree.shared) HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted shared info nil") - else - if(H5UC_DEC(storage.u.btree.shared) < 0) - HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted shared info") + else if(H5UC_DEC(storage.u.btree.shared) < 0) + HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted shared info") } /* end if */ FUNC_LEAVE_NOAPI(ret_value) 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) |