summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Dbtree.c13
-rw-r--r--src/H5Dchunk.c60
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)