From bacf7149e948c6c33401a9ecb0ad16e60805a9a2 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 1 Apr 2010 20:48:23 -0500 Subject: [svn-r18495] Description: Bring r18494 from trunk to 1.8 branch: Bring r18491 from metadata journaling "merging" branch to trunk: Extract data structure 'destroy' routines from metadata cache client 'destroy' callbacks. Tested on: FreeBSD/32 6.3 (duty) w/debug (h5committested on trunk) --- src/H5B.c | 34 +++++++++- src/H5B2.c | 1 - src/H5B2cache.c | 69 +++++++------------ src/H5B2hdr.c | 4 +- src/H5B2int.c | 92 +++++++++++++++++++++++++- src/H5B2pkg.h | 11 ++-- src/H5Bcache.c | 14 ++-- src/H5Bpkg.h | 2 +- src/H5FS.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++---- src/H5FScache.c | 152 ++++++------------------------------------ src/H5FSpkg.h | 12 ++-- src/H5FSsection.c | 6 +- 12 files changed, 372 insertions(+), 218 deletions(-) diff --git a/src/H5B.c b/src/H5B.c index 6d951f6..acafe2c 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -258,7 +258,8 @@ done: (void)H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, *addr_p, (hsize_t)shared->sizeof_rnode); } /* end if */ if(bt) - (void)H5B_dest(f, bt); + if(H5B_node_dest(bt) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree node") } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -2045,3 +2046,34 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B_valid() */ +/*------------------------------------------------------------------------- + * Function: H5B_node_dest + * + * Purpose: Destroy/release a B-tree node + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 26, 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B_node_dest(H5B_t *bt) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_node_dest) + + /* check arguments */ + HDassert(bt); + HDassert(bt->rc_shared); + + bt->child = H5FL_SEQ_FREE(haddr_t, bt->child); + bt->native = H5FL_BLK_FREE(native_block, bt->native); + H5RC_DEC(bt->rc_shared); + bt = H5FL_FREE(H5B_t, bt); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5B_node_dest() */ + diff --git a/src/H5B2.c b/src/H5B2.c index 0d7d86d..e268629 100644 --- a/src/H5B2.c +++ b/src/H5B2.c @@ -1263,7 +1263,6 @@ done: if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release v2 B-tree header") - FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_delete() */ diff --git a/src/H5B2cache.c b/src/H5B2cache.c index d278b85..d79deff 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -71,14 +71,17 @@ /* Metadata cache callbacks */ static H5B2_hdr_t *H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata); static herr_t H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_hdr_t *hdr, unsigned UNUSED * flags_ptr); +static herr_t H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr); static herr_t H5B2_cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy); static herr_t H5B2_cache_hdr_size(const H5F_t *f, const H5B2_hdr_t *hdr, size_t *size_ptr); static H5B2_internal_t *H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *udata2); static herr_t H5B2_cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_internal_t *i, unsigned UNUSED * flags_ptr); +static herr_t H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal); static herr_t H5B2_cache_internal_clear(H5F_t *f, H5B2_internal_t *i, hbool_t destroy); static herr_t H5B2_cache_internal_size(const H5F_t *f, const H5B2_internal_t *i, size_t *size_ptr); static H5B2_leaf_t *H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, void *_hdr); static herr_t H5B2_cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_leaf_t *l, unsigned UNUSED * flags_ptr); +static herr_t H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf); static herr_t H5B2_cache_leaf_clear(H5F_t *f, H5B2_leaf_t *l, hbool_t destroy); static herr_t H5B2_cache_leaf_size(const H5F_t *f, const H5B2_leaf_t *l, size_t *size_ptr); @@ -377,16 +380,14 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr) { - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_hdr_dest) - /* - * Check arguments. - */ + /* Check arguments */ HDassert(hdr); HDassert(hdr->rc == 0); @@ -603,7 +604,8 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_uda done: if(!ret_value && internal) - (void)H5B2_cache_internal_dest(f, internal); + if(H5B2_internal_free(internal) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to destroy B-tree internal node") FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_cache_internal_load() */ /*lint !e818 Can't make udata a pointer to const */ @@ -719,16 +721,14 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal) { - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_internal_dest) - /* - * Check arguments. - */ + /* Check arguments */ HDassert(f); HDassert(internal); HDassert(internal->hdr); @@ -744,23 +744,9 @@ H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree internal node") } /* end if */ - /* Set the B-tree header's file context for this operation */ - internal->hdr->f = f; - - /* Release internal node's native key buffer */ - if(internal->int_native) - H5FL_FAC_FREE(internal->hdr->node_info[internal->depth].nat_rec_fac, internal->int_native); - - /* Release internal node's node pointer buffer */ - if(internal->node_ptrs) - H5FL_FAC_FREE(internal->hdr->node_info[internal->depth].node_ptr_fac, internal->node_ptrs); - - /* Decrement ref. count on B-tree header */ - if(H5B2_hdr_decr(internal->hdr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header") - - /* Free B-tree internal node info */ - internal = H5FL_FREE(H5B2_internal_t, internal); + /* Release v2 b-tree internal node */ + if(H5B2_internal_free(internal) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release v2 B-tree internal node") done: FUNC_LEAVE_NOAPI(ret_value) @@ -941,7 +927,8 @@ H5B2_cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrec, v done: if(!ret_value && leaf) - (void)H5B2_cache_leaf_dest(f, leaf); + if(H5B2_leaf_free(leaf) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to destroy B-tree leaf node") FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_cache_leaf_load() */ /*lint !e818 Can't make udata a pointer to const */ @@ -1043,16 +1030,14 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf) { - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_leaf_dest) - /* - * Check arguments. - */ + /* Check arguments */ HDassert(f); HDassert(leaf); HDassert(leaf->hdr); @@ -1068,19 +1053,9 @@ H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree leaf node") } /* end if */ - /* Set the B-tree header's file context for this operation */ - leaf->hdr->f = f; - - /* Release leaf's native key buffer */ - if(leaf->leaf_native) - H5FL_FAC_FREE(leaf->hdr->node_info[0].nat_rec_fac, leaf->leaf_native); - - /* Decrement ref. count on B-tree header */ - if(H5B2_hdr_decr(leaf->hdr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header") - - /* Free B-tree leaf node info */ - leaf = H5FL_FREE(H5B2_leaf_t, leaf); + /* Destroy v2 b-tree leaf node */ + if(H5B2_leaf_free(leaf) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree leaf node") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c index 668bce4..a219859 100644 --- a/src/H5B2hdr.c +++ b/src/H5B2hdr.c @@ -519,7 +519,7 @@ H5B2_hdr_free(H5B2_hdr_t *hdr) /* Free the B-tree node buffer */ if(hdr->page) - (void)H5FL_BLK_FREE(node_page, hdr->page); + hdr->page = H5FL_BLK_FREE(node_page, hdr->page); /* Free the array of offsets into the native key block */ if(hdr->nat_off) @@ -544,7 +544,7 @@ H5B2_hdr_free(H5B2_hdr_t *hdr) } /* end if */ /* Free B-tree header info */ - (void)H5FL_FREE(H5B2_hdr_t, hdr); + hdr = H5FL_FREE(H5B2_hdr_t, hdr); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5B2int.c b/src/H5B2int.c index 63212d7..9b9c75d 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -1730,7 +1730,8 @@ HDmemset(leaf->leaf_native, 0, hdr->cls->nrec_size * hdr->node_info[0].max_nrec) done: if(ret_value < 0) { if(leaf) - (void)H5B2_cache_leaf_dest(hdr->f, leaf); + if(H5B2_leaf_free(leaf) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release v2 B-tree leaf node") } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -1808,7 +1809,8 @@ HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (hdr->node_info[depth done: if(ret_value < 0) { if(internal) - (void)H5B2_cache_internal_dest(hdr->f, internal); + if(H5B2_internal_free(internal) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release v2 B-tree internal node") } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -2890,6 +2892,92 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5B2_node_size() */ + +/*------------------------------------------------------------------------- + * Function: H5B2_internal_free + * + * Purpose: Destroys a B-tree internal node in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 2 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_internal_free(H5B2_internal_t *internal) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_internal_free) + + /* + * Check arguments. + */ + HDassert(internal); + + /* Release internal node's native key buffer */ + if(internal->int_native) + H5FL_FAC_FREE(internal->hdr->node_info[internal->depth].nat_rec_fac, internal->int_native); + + /* Release internal node's node pointer buffer */ + if(internal->node_ptrs) + H5FL_FAC_FREE(internal->hdr->node_info[internal->depth].node_ptr_fac, internal->node_ptrs); + + /* Decrement ref. count on B-tree header */ + if(H5B2_hdr_decr(internal->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header") + + /* Free B-tree internal node info */ + internal = H5FL_FREE(H5B2_internal_t, internal); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_internal_free() */ + + +/*------------------------------------------------------------------------- + * Function: H5B2_leaf_free + * + * Purpose: Destroys a B-tree leaf node in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 2 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B2_leaf_free(H5B2_leaf_t *leaf) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_leaf_free) + + /* + * Check arguments. + */ + HDassert(leaf); + + /* Release leaf's native key buffer */ + if(leaf->leaf_native) + H5FL_FAC_FREE(leaf->hdr->node_info[0].nat_rec_fac, leaf->leaf_native); + + /* Decrement ref. count on B-tree header */ + if(H5B2_hdr_decr(leaf->hdr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header") + + /* Free B-tree leaf node info */ + leaf = H5FL_FREE(H5B2_leaf_t, leaf); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B2_leaf_free() */ + #ifdef H5B2_DEBUG /*------------------------------------------------------------------------- diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index 5817d22..6307187 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -266,7 +266,6 @@ H5_DLL herr_t H5B2_hdr_decr(H5B2_hdr_t *hdr); H5_DLL herr_t H5B2_hdr_fuse_incr(H5B2_hdr_t *hdr); H5_DLL size_t H5B2_hdr_fuse_decr(H5B2_hdr_t *hdr); H5_DLL herr_t H5B2_hdr_dirty(H5B2_hdr_t *hdr); -H5_DLL herr_t H5B2_hdr_free(H5B2_hdr_t *hdr); H5_DLL herr_t H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id); /* Routines for operating on internal nodes */ @@ -278,6 +277,11 @@ H5_DLL herr_t H5B2_split_root(H5B2_hdr_t *hdr, hid_t dxpl_id); H5_DLL herr_t H5B2_create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *node_ptr); +/* Routines for releasing structures */ +H5_DLL herr_t H5B2_hdr_free(H5B2_hdr_t *hdr); +H5_DLL herr_t H5B2_leaf_free(H5B2_leaf_t *l); +H5_DLL herr_t H5B2_internal_free(H5B2_internal_t *i); + /* Routines for inserting records */ H5_DLL herr_t H5B2_insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, unsigned *parent_cache_info_flags_ptr, @@ -321,11 +325,6 @@ H5_DLL herr_t H5B2_remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id, H5_DLL herr_t H5B2_delete_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, const H5B2_node_ptr_t *curr_node, H5B2_remove_t op, void *op_data); -/* Metadata cache callbacks */ -H5_DLL herr_t H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *b); -H5_DLL herr_t H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *l); -H5_DLL herr_t H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *i); - /* Debugging routines for dumping file structures */ H5_DLL herr_t H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, const H5B2_class_t *type); diff --git a/src/H5Bcache.c b/src/H5Bcache.c index 476bbe6..e9210ca 100644 --- a/src/H5Bcache.c +++ b/src/H5Bcache.c @@ -57,6 +57,7 @@ /* Metadata cache callbacks */ static H5B_t *H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata); static herr_t H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *b, unsigned UNUSED * flags_ptr); +static herr_t H5B_dest(H5F_t *f, H5B_t *bt); static herr_t H5B_clear(H5F_t *f, H5B_t *b, hbool_t destroy); static herr_t H5B_compute_size(const H5F_t *f, const H5B_t *bt, size_t *size_ptr); @@ -181,7 +182,8 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata) done: if(!ret_value && bt) - (void)H5B_dest(f, bt); + if(H5B_node_dest(bt) < 0) + HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to destroy B-tree node") FUNC_LEAVE_NOAPI(ret_value) } /* end H5B_load() */ /*lint !e818 Can't make udata a pointer to const */ @@ -291,7 +293,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5B_dest(H5F_t *f, H5B_t *bt) { herr_t ret_value = SUCCEED; /* Return value */ @@ -322,11 +324,9 @@ H5B_dest(H5F_t *f, H5B_t *bt) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree node") } /* end if */ - /* Release resources for B-tree node */ - bt->child = H5FL_SEQ_FREE(haddr_t, bt->child); - bt->native = H5FL_BLK_FREE(native_block, bt->native); - H5RC_DEC(bt->rc_shared); - bt = H5FL_FREE(H5B_t, bt); + /* Destroy B-tree node */ + if(H5B_node_dest(bt) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree node") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h index e430a89..ad88351 100644 --- a/src/H5Bpkg.h +++ b/src/H5Bpkg.h @@ -82,7 +82,7 @@ H5FL_EXTERN(H5B_t); /******************************/ /* Package Private Prototypes */ /******************************/ -H5_DLL herr_t H5B_dest(H5F_t *f, H5B_t *b); +H5_DLL herr_t H5B_node_dest(H5B_t *b); #ifdef H5B_DEBUG herr_t H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void *udata); diff --git a/src/H5FS.c b/src/H5FS.c index 9518c8d..a09cb67 100644 --- a/src/H5FS.c +++ b/src/H5FS.c @@ -55,6 +55,8 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5FS_sinfo_free_sect_cb(void *item, void *key, void *op_data); +static herr_t H5FS_sinfo_free_node_cb(void *item, void *key, void *op_data); /*********************/ @@ -156,7 +158,8 @@ HDfprintf(stderr, "%s: fspace = %p, fspace->addr = %a\n", FUNC, fspace, fspace-> done: if(!ret_value && fspace) - (void)H5FS_cache_hdr_dest(f, fspace); + if(H5FS_hdr_dest(fspace) < 0) + HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, NULL, "unable to destroy free space header") #ifdef H5FS_DEBUG HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value); @@ -220,7 +223,7 @@ HDfprintf(stderr, "%s: fspace->rc = %u\n", FUNC, fspace->rc); /* Increment the reference count on the free space manager header */ HDassert(fspace->rc <= 1); - if(H5FS_incr(f, fspace) < 0) + if(H5FS_incr(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTINC, NULL, "unable to increment ref. count on free space header") fspace->alignment = alignment; @@ -465,7 +468,7 @@ HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC); } /* end else */ /* Destroy section info */ - if(H5FS_cache_sinfo_dest(f, fspace->sinfo) < 0) + if(H5FS_sinfo_dest(fspace->sinfo) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy free space section info") } /* end else */ @@ -483,7 +486,7 @@ HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC); } /* end else */ /* Decrement the reference count on the free space manager header */ - if(H5FS_decr(f, fspace) < 0) + if(H5FS_decr(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTDEC, FAIL, "unable to decrement ref. count on free space header") done: @@ -619,7 +622,7 @@ H5FS_size(const H5F_t *f, const H5FS_t *fspace, hsize_t *meta_size) *------------------------------------------------------------------------- */ herr_t -H5FS_incr(H5F_t *f, H5FS_t *fspace) +H5FS_incr(H5FS_t *fspace) { herr_t ret_value = SUCCEED; /* Return value */ @@ -631,7 +634,6 @@ HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fsp /* * Check arguments. */ - HDassert(f); HDassert(fspace); /* Check if we should pin the header in the cache */ @@ -661,7 +663,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5FS_decr(H5F_t *f, H5FS_t *fspace) +H5FS_decr(H5FS_t *fspace) { herr_t ret_value = SUCCEED; /* Return value */ @@ -673,7 +675,6 @@ HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fsp /* * Check arguments. */ - HDassert(f); HDassert(fspace); /* Decrement reference count on header */ @@ -686,7 +687,7 @@ HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fsp HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header") } /* end if */ else { - if(H5FS_cache_hdr_dest(f, fspace) < 0) + if(H5FS_hdr_dest(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy free space header") } /* end else */ } /* end if */ @@ -710,7 +711,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5FS_dirty(H5F_t *f, H5FS_t *fspace) +H5FS_dirty(H5FS_t *fspace) { herr_t ret_value = SUCCEED; /* Return value */ @@ -720,7 +721,6 @@ HDfprintf(stderr, "%s: Marking free space header as dirty\n", FUNC); #endif /* QAK */ /* Sanity check */ - HDassert(f); HDassert(fspace); /* Check if the free space manager is persistant */ @@ -733,6 +733,177 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FS_dirty() */ + +/*------------------------------------------------------------------------- + * Function: H5FS_hdr_dest + * + * Purpose: Destroys a free space header in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * May 2 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_hdr_dest(H5FS_t *fspace) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FS_hdr_dest) + + /* + * Check arguments. + */ + HDassert(fspace); + + /* Terminate the section classes for this free space list */ + for(u = 0; u < fspace->nclasses ; u++) { + /* Call the class termination routine, if there is one */ + if(fspace->sect_cls[u].term_cls) + if((fspace->sect_cls[u].term_cls)(&fspace->sect_cls[u]) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "unable to finalize section class") + } /* end for */ + + /* Release the memory for the free space section classes */ + if(fspace->sect_cls) + fspace->sect_cls = (H5FS_section_class_t *)H5FL_SEQ_FREE(H5FS_section_class_t, fspace->sect_cls); + + /* Free free space info */ + fspace = H5FL_FREE(H5FS_t, fspace); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FS_hdr_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_sinfo_free_sect_cb + * + * Purpose: Free a size-tracking node for a bin + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, March 11, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FS_sinfo_free_sect_cb(void *_sect, void UNUSED *key, void *op_data) +{ + H5FS_section_info_t *sect = (H5FS_section_info_t *)_sect; /* Section to free */ + const H5FS_sinfo_t *sinfo = (const H5FS_sinfo_t *)op_data; /* Free space manager for section */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sinfo_free_sect_cb) + + HDassert(sect); + HDassert(sinfo); + + /* Call the section's class 'free' method on the section */ + (*sinfo->fspace->sect_cls[sect->type].free)(sect); + + FUNC_LEAVE_NOAPI(0) +} /* H5FS_sinfo_free_sect_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_sinfo_free_node_cb + * + * Purpose: Free a size-tracking node for a bin + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Saturday, March 11, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data) +{ + H5FS_node_t *fspace_node = (H5FS_node_t *)item; /* Temporary pointer to free space list node */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sinfo_free_node_cb) + + HDassert(fspace_node); + HDassert(op_data); + + /* Release the skip list for sections of this size */ + H5SL_destroy(fspace_node->sect_list, H5FS_sinfo_free_sect_cb, op_data); + + /* Release free space list node */ + fspace_node = H5FL_FREE(H5FS_node_t, fspace_node); + + FUNC_LEAVE_NOAPI(0) +} /* H5FS_sinfo_free_node_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5FS_sinfo_dest + * + * Purpose: Destroys a free space section info in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * July 31 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5FS_sinfo_dest(H5FS_sinfo_t *sinfo) +{ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_dest) + + /* + * Check arguments. + */ + HDassert(sinfo); + HDassert(sinfo->fspace); + HDassert(sinfo->bins); + + /* Clear out lists of nodes */ + for(u = 0; u < sinfo->nbins; u++) + if(sinfo->bins[u].bin_list) { + H5SL_destroy(sinfo->bins[u].bin_list, H5FS_sinfo_free_node_cb, sinfo); + sinfo->bins[u].bin_list = NULL; + } /* end if */ + + /* Release bins for skip lists */ + sinfo->bins = H5FL_SEQ_FREE(H5FS_bin_t, sinfo->bins); + + /* Release skip list for merging sections */ + if(sinfo->merge_list) + if(H5SL_close(sinfo->merge_list) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "can't destroy section merging skip list") + + /* Decrement the reference count on free space header */ + /* (make certain this is last action with section info, to allow for header + * disappearing immediately) + */ + sinfo->fspace->sinfo = NULL; + if(H5FS_decr(sinfo->fspace) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTDEC, FAIL, "unable to decrement ref. count on free space header") + sinfo->fspace = NULL; + + /* Release free space section info */ + sinfo = H5FL_FREE(H5FS_sinfo_t, sinfo); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FS_sinfo_dest() */ + #ifdef H5FS_DEBUG_ASSERT /*------------------------------------------------------------------------- diff --git a/src/H5FScache.c b/src/H5FScache.c index 000a462..9e5f2b9 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -74,18 +74,18 @@ typedef struct { /********************/ /* Section info routines */ -static herr_t H5FS_sinfo_free_sect_cb(void *item, void *key, void *op_data); -static herr_t H5FS_sinfo_free_node_cb(void *item, void *key, void *op_data); static herr_t H5FS_sinfo_serialize_sect_cb(void *_item, void UNUSED *key, void *_udata); static herr_t H5FS_sinfo_serialize_node_cb(void *_item, void UNUSED *key, void *_udata); /* Metadata cache callbacks */ static H5FS_t *H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_t *fspace, unsigned UNUSED * flags_ptr); +static herr_t H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *fspace); static herr_t H5FS_cache_hdr_clear(H5F_t *f, H5FS_t *fspace, hbool_t destroy); static herr_t H5FS_cache_hdr_size(const H5F_t *f, const H5FS_t *fspace, size_t *size_ptr); static H5FS_sinfo_t *H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_sinfo_t *sinfo, unsigned UNUSED * flags_ptr); +static herr_t H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo); static herr_t H5FS_cache_sinfo_clear(H5F_t *f, H5FS_sinfo_t *sinfo, hbool_t destroy); static herr_t H5FS_cache_sinfo_size(const H5F_t *f, const H5FS_sinfo_t *sinfo, size_t *size_ptr); @@ -252,7 +252,7 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_fs_prot, /* Verify checksum */ if(stored_chksum != computed_chksum) - HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap indirect block") + HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap indirect block") /* Set return value */ ret_value = fspace; @@ -262,7 +262,8 @@ done: if(wb && H5WB_unwrap(wb) < 0) HDONE_ERROR(H5E_FSPACE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") if(!ret_value && fspace) - (void)H5FS_cache_hdr_dest(f, fspace); + if(H5FS_hdr_dest(fspace) < 0) + HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, NULL, "unable to destroy free space header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5FS_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */ @@ -449,17 +450,14 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *fspace) { - unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_hdr_dest) - /* - * Check arguments. - */ + /* Check arguments */ HDassert(fspace); /* We should not still be holding on to the free space section info */ @@ -468,14 +466,6 @@ H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *fspace) /* If we're going to free the space on disk, the address must be valid */ HDassert(!fspace->cache_info.free_file_space_on_destroy || H5F_addr_defined(fspace->cache_info.addr)); - /* Terminate the section classes for this free space list */ - for(u = 0; u < fspace->nclasses ; u++) { - /* Call the class termination routine, if there is one */ - if(fspace->sect_cls[u].term_cls) - if((fspace->sect_cls[u].term_cls)(&fspace->sect_cls[u]) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "unable to finalize section class") - } /* end for */ - /* Check for freeing file space for free space header */ if(fspace->cache_info.free_file_space_on_destroy) { /* Sanity check */ @@ -487,12 +477,9 @@ H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *fspace) HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space header") } /* end if */ - /* Release the memory for the free space section classes */ - if(fspace->sect_cls) - fspace->sect_cls = (H5FS_section_class_t *)H5FL_SEQ_FREE(H5FS_section_class_t, fspace->sect_cls); - - /* Free free space info */ - (void)H5FL_FREE(H5FS_t, fspace); + /* Destroy free space header */ + if(H5FS_hdr_dest(fspace) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to destroy free space header") done: FUNC_LEAVE_NOAPI(ret_value) @@ -717,7 +704,7 @@ H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * /* Verify checksum */ if(stored_chksum != computed_chksum) - HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap indirect block") + HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap indirect block") /* Sanity check */ HDassert((size_t)(p - (const uint8_t *)buf) == old_sect_size); @@ -727,9 +714,10 @@ H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * done: if(buf) - (void)H5FL_BLK_FREE(sect_block, buf); + buf = H5FL_BLK_FREE(sect_block, buf); if(!ret_value && sinfo) - (void)H5FS_cache_sinfo_dest(f, sinfo); + if(H5FS_sinfo_dest(sinfo) < 0) + HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, NULL, "unable to destroy free space section info") FUNC_LEAVE_NOAPI(ret_value) } /* end H5FS_cache_sinfo_load() */ /*lint !e818 Can't make udata a pointer to const */ @@ -920,7 +908,7 @@ H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H if(H5F_block_write(f, H5FD_MEM_FSPACE_SINFO, sinfo->fspace->sect_addr, (size_t)sinfo->fspace->sect_size, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space sections to disk") - (void)H5FL_BLK_FREE(sect_block, buf); + buf = H5FL_BLK_FREE(sect_block, buf); sinfo->cache_info.is_dirty = FALSE; sinfo->dirty = FALSE; @@ -936,76 +924,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5FS_sinfo_free_sect_cb - * - * Purpose: Free a size-tracking node for a bin - * - * Return: Success: non-negative - * Failure: negative - * - * Programmer: Quincey Koziol - * Saturday, March 11, 2006 - * - * Modifications: - * Vailin Choi, July 29th, 2008 - * Add HDassert() to make sure "free" method exists before calling - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FS_sinfo_free_sect_cb(void *_sect, void UNUSED *key, void *op_data) -{ - H5FS_section_info_t *sect = (H5FS_section_info_t *)_sect; /* Section to free */ - const H5FS_sinfo_t *sinfo = (const H5FS_sinfo_t *)op_data; /* Free space manager for section */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sinfo_free_sect_cb) - - HDassert(sect); - HDassert(sinfo); - HDassert(sinfo->fspace->sect_cls[sect->type].free); - - /* Call the section's class 'free' method on the section */ - (*sinfo->fspace->sect_cls[sect->type].free)(sect); - - FUNC_LEAVE_NOAPI(0) -} /* H5FS_sinfo_free_sect_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5FS_sinfo_free_node_cb - * - * Purpose: Free a size-tracking node for a bin - * - * Return: Success: non-negative - * - * Failure: negative - * - * Programmer: Quincey Koziol - * Saturday, March 11, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data) -{ - H5FS_node_t *fspace_node = (H5FS_node_t *)item; /* Temporary pointer to free space list node */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sinfo_free_node_cb) - - HDassert(fspace_node); - HDassert(op_data); - - /* Release the skip list for sections of this size */ - H5SL_destroy(fspace_node->sect_list, H5FS_sinfo_free_sect_cb, op_data); - - /* Release free space list node */ - (void)H5FL_FREE(H5FS_node_t, fspace_node); - - FUNC_LEAVE_NOAPI(0) -} /* H5FS_sinfo_free_node_cb() */ - - -/*------------------------------------------------------------------------- * Function: H5FS_cache_sinfo_dest * * Purpose: Destroys a free space section info in memory. @@ -1018,20 +936,15 @@ H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data) * *------------------------------------------------------------------------- */ -herr_t -H5FS_cache_sinfo_dest(H5F_t UNUSED *f, H5FS_sinfo_t *sinfo) +static herr_t +H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo) { - unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_sinfo_dest) - /* - * Check arguments. - */ + /* Check arguments */ HDassert(sinfo); - HDassert(sinfo->fspace); - HDassert(sinfo->bins); /* If we're going to free the space on disk, the address must be valid */ HDassert(!sinfo->cache_info.free_file_space_on_destroy || H5F_addr_defined(sinfo->cache_info.addr)); @@ -1047,32 +960,9 @@ H5FS_cache_sinfo_dest(H5F_t UNUSED *f, H5FS_sinfo_t *sinfo) HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space section info") } /* end if */ - /* Clear out lists of nodes */ - for(u = 0; u < sinfo->nbins; u++) - if(sinfo->bins[u].bin_list) { - H5SL_destroy(sinfo->bins[u].bin_list, H5FS_sinfo_free_node_cb, sinfo); - sinfo->bins[u].bin_list = NULL; - } /* end if */ - - /* Release bins for skip lists */ - sinfo->bins = (H5FS_bin_t *)H5FL_SEQ_FREE(H5FS_bin_t, sinfo->bins); - - /* Release skip list for merging sections */ - if(sinfo->merge_list) - if(H5SL_close(sinfo->merge_list) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "can't destroy section merging skip list") - - /* Decrement the reference count on free space header */ - /* (make certain this is last action with section info, to allow for header - * disappearing immediately) - */ - sinfo->fspace->sinfo = NULL; - if(H5FS_decr(f, sinfo->fspace) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTDEC, FAIL, "unable to decrement ref. count on free space header") - sinfo->fspace = NULL; - - /* Release free space section info */ - (void)H5FL_FREE(H5FS_sinfo_t, sinfo); + /* Destroy free space info */ + if(H5FS_sinfo_dest(sinfo) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to destroy free space info") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5FSpkg.h b/src/H5FSpkg.h index 1786b44..a287d23 100644 --- a/src/H5FSpkg.h +++ b/src/H5FSpkg.h @@ -213,16 +213,16 @@ H5FL_EXTERN(H5FS_t); /* Free space manager header routines */ H5_DLL H5FS_t *H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata); -H5_DLL herr_t H5FS_incr(H5F_t *f, H5FS_t *fspace); -H5_DLL herr_t H5FS_decr(H5F_t *f, H5FS_t *fspace); -H5_DLL herr_t H5FS_dirty(H5F_t *f, H5FS_t *fspace); +H5_DLL herr_t H5FS_incr(H5FS_t *fspace); +H5_DLL herr_t H5FS_decr(H5FS_t *fspace); +H5_DLL herr_t H5FS_dirty(H5FS_t *fspace); /* Free space section routines */ H5_DLL H5FS_sinfo_t *H5FS_sinfo_new(H5F_t *f, H5FS_t *fspace); -/* Metadata cache callbacks */ -H5_DLL herr_t H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *hdr); -H5_DLL herr_t H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo); +/* Routines for destroying structures */ +H5_DLL herr_t H5FS_hdr_dest(H5FS_t *hdr); +H5_DLL herr_t H5FS_sinfo_dest(H5FS_sinfo_t *sinfo); /* Sanity check routines */ #ifdef H5FS_DEBUG diff --git a/src/H5FSsection.c b/src/H5FSsection.c index 9bdd99a..d367238 100644 --- a/src/H5FSsection.c +++ b/src/H5FSsection.c @@ -159,7 +159,7 @@ HDfprintf(stderr, "%s: sinfo->sect_off_size = %u, sinfo->sect_len_size = %u\n", HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space section bin array") /* Increment the reference count on the free space manager header */ - if(H5FS_incr(f, fspace) < 0) + if(H5FS_incr(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTINC, NULL, "unable to increment ref. count on free space header") sinfo->fspace = fspace; @@ -335,7 +335,7 @@ HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n" /* Assume that the modification will affect the statistics in the header * and mark that dirty also */ - if(H5FS_dirty(f, fspace) < 0) + if(H5FS_dirty(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") } /* end if */ @@ -430,7 +430,7 @@ HDfprintf(stderr, "%s: Relinquishing section info ownership\n", FUNC); /* If we haven't already marked the header dirty, do so now */ if(!modified) - if(H5FS_dirty(f, fspace) < 0) + if(H5FS_dirty(fspace) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty") #ifdef H5FS_SINFO_DEBUG -- cgit v0.12