summaryrefslogtreecommitdiffstats
path: root/src/H5HFhdr.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-01-06 20:50:45 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-01-06 20:50:45 (GMT)
commitd6c27d4b4d82d794e860770f5903e84511596d19 (patch)
treeffd0b2a1dac38b61048dc8636c453125a5e365a4 /src/H5HFhdr.c
parent869ed6e043dfc20b6b6dfda6728c3442ef0409be (diff)
downloadhdf5-d6c27d4b4d82d794e860770f5903e84511596d19.zip
hdf5-d6c27d4b4d82d794e860770f5903e84511596d19.tar.gz
hdf5-d6c27d4b4d82d794e860770f5903e84511596d19.tar.bz2
[svn-r13115] Description:
Allow a heap to be marked for deletion while it is still open and being accessed. (Blocks further opens though). Tested on: FreeBSD/32 6.1 (duty)
Diffstat (limited to 'src/H5HFhdr.c')
-rw-r--r--src/H5HFhdr.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c
index 4b61063..6267e76 100644
--- a/src/H5HFhdr.c
+++ b/src/H5HFhdr.c
@@ -1481,3 +1481,117 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_hdr_empty() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_delete
+ *
+ * Purpose: Delete a fractal heap, starting with the header
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 5 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5HF_hdr_delete, FAIL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(!hdr->file_rc);
+
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Heap header's status in the metadata cache */
+
+ /* Check the heap header's status in the metadata cache */
+ if(H5AC_get_entry_status(hdr->f, hdr->heap_addr, &hdr_status) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to check metadata cache status for heap header")
+
+ /* Sanity checks on heap header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PROTECTED);
+} /* end block */
+#endif /* NDEBUG */
+
+ /* Check for free space manager for heap */
+ /* (must occur before attempting to delete the heap, so indirect blocks
+ * will get unpinned)
+ */
+ if(H5F_addr_defined(hdr->fs_addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->fs_addr = %a\n", FUNC, hdr->fs_addr);
+#endif /* QAK */
+ /* Delete free space manager for heap */
+ if(H5HF_space_delete(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap free space manager")
+ } /* end if */
+
+ /* Check for root direct/indirect block */
+ if(H5F_addr_defined(hdr->man_dtable.table_addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->man_dtable.table_addr = %a\n", FUNC, hdr->man_dtable.table_addr);
+#endif /* QAK */
+ if(hdr->man_dtable.curr_root_rows == 0) {
+ hsize_t dblock_size; /* Size of direct block */
+
+ /* Check for I/O filters on this heap */
+ if(hdr->filter_len > 0) {
+ dblock_size = (hsize_t)hdr->pline_root_direct_size;
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->pline_root_direct_size = %Zu\n", FUNC, hdr->pline_root_direct_size);
+#endif /* QAK */
+
+ /* Reset the header's pipeline information */
+ hdr->pline_root_direct_size = 0;
+ hdr->pline_root_direct_filter_mask = 0;
+ } /* end else */
+ else
+ dblock_size = (hsize_t)hdr->man_dtable.cparam.start_block_size;
+
+ /* Delete root direct block */
+ if(H5HF_man_dblock_delete(hdr->f, dxpl_id, hdr->man_dtable.table_addr, dblock_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap root direct block")
+ } /* end if */
+ else {
+ /* Delete root indirect block */
+ if(H5HF_man_iblock_delete(hdr, dxpl_id, hdr->man_dtable.table_addr, hdr->man_dtable.curr_root_rows, NULL, 0) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap root indirect block")
+ } /* end else */
+ } /* end if */
+
+ /* Check for 'huge' objects in heap */
+ if(H5F_addr_defined(hdr->huge_bt2_addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->huge_bt2_addr = %a\n", FUNC, hdr->huge_bt2_addr);
+#endif /* QAK */
+ /* Delete huge objects in heap and their tracker */
+ if(H5HF_huge_delete(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap 'huge' objects and tracker")
+ } /* end if */
+
+ /* Release header's disk space */
+ if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_HDR, dxpl_id, hdr->heap_addr, (hsize_t)hdr->heap_size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap header")
+
+ /* Finished deleting header */
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header")
+ hdr = NULL;
+
+done:
+ /* Unprotect the header, if an error occurred */
+ if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_hdr_delete() */
+