summaryrefslogtreecommitdiffstats
path: root/src/H5FScache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5FScache.c')
-rw-r--r--src/H5FScache.c139
1 files changed, 105 insertions, 34 deletions
diff --git a/src/H5FScache.c b/src/H5FScache.c
index 8ace571..8a345fe 100644
--- a/src/H5FScache.c
+++ b/src/H5FScache.c
@@ -36,6 +36,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5FSpkg.h" /* File free space */
+#include "H5MFprivate.h" /* File memory management */
#include "H5Vprivate.h" /* Vectors and arrays */
#include "H5WBprivate.h" /* Wrapped Buffers */
@@ -100,6 +101,7 @@ const H5AC_class_t H5AC_FSPACE_HDR[1] = {{
(H5AC_flush_func_t)H5FS_cache_hdr_flush,
(H5AC_dest_func_t)H5FS_cache_hdr_dest,
(H5AC_clear_func_t)H5FS_cache_hdr_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5FS_cache_hdr_size,
}};
@@ -110,6 +112,7 @@ const H5AC_class_t H5AC_FSPACE_SINFO[1] = {{
(H5AC_flush_func_t)H5FS_cache_sinfo_flush,
(H5AC_dest_func_t)H5FS_cache_sinfo_dest,
(H5AC_clear_func_t)H5FS_cache_sinfo_clear,
+ (H5AC_notify_func_t)NULL,
(H5AC_size_func_t)H5FS_cache_sinfo_size,
}};
@@ -179,7 +182,7 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_fs_prot,
size = H5FS_HEADER_SIZE(f);
/* Get a pointer to a buffer that's large enough for header */
- if(NULL == (hdr = H5WB_actual(wb, size)))
+ if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
@@ -189,16 +192,16 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_fs_prot,
p = hdr;
/* Magic number */
- if(HDmemcmp(p, H5FS_HDR_MAGIC, (size_t)H5FS_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "wrong free space header signature")
- p += H5FS_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5FS_HDR_VERSION)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "wrong free space header version")
/* Client ID */
- fspace->client = *p++;
+ fspace->client = (H5FS_client_t)*p++;
if(fspace->client >= H5FS_NUM_CLIENT_ID)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "unknown client ID in free space header")
@@ -293,6 +296,45 @@ H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(fspace);
+ HDassert(H5F_addr_defined(fspace->addr));
+
+ /* Check if the header "owns" the section info */
+ if(fspace->sinfo) {
+ /* Sanity check - should not be trying to destroy header if it still
+ * "owns" section info
+ */
+ HDassert(!destroy);
+
+ /* Check if the section info is dirty */
+ if(fspace->sinfo->dirty) {
+ if(fspace->serial_sect_count > 0) {
+ /* Check if we need to allocate space for section info */
+ if(!H5F_addr_defined(fspace->sect_addr)) {
+ /* Sanity check */
+ HDassert(fspace->sect_size > 0);
+
+ /* Allocate space for the section info in file */
+ if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
+ fspace->alloc_sect_size = (size_t)fspace->sect_size;
+
+ /* Mark header dirty */
+ /* (don't use cache API, since we're in a callback) */
+ fspace->cache_info.is_dirty = TRUE;
+ } /* end if */
+
+ /* Write section info to file */
+ if(H5FS_cache_sinfo_flush(f, dxpl_id, FALSE, fspace->sect_addr, fspace->sinfo, NULL) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space section info to disk")
+ } /* end if */
+
+ /* Mark section info clean */
+ fspace->sinfo->dirty = FALSE;
+ } /* end if */
+ } /* end if */
+ else if(fspace->serial_sect_count > 0)
+ /* Sanity check that section info has address */
+ HDassert(H5F_addr_defined(fspace->sect_addr));
if(fspace->cache_info.is_dirty) {
uint8_t *hdr; /* Pointer to header buffer */
@@ -308,15 +350,15 @@ H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F
size = H5FS_HEADER_SIZE(f);
/* Get a pointer to a buffer that's large enough for header */
- if(NULL == (hdr = H5WB_actual(wb, size)))
+ if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to header */
p = hdr;
/* Magic number */
- HDmemcpy(p, H5FS_HDR_MAGIC, (size_t)H5FS_SIZEOF_MAGIC);
- p += H5FS_SIZEOF_MAGIC;
+ HDmemcpy(p, H5FS_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5FS_HDR_VERSION;
@@ -400,9 +442,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
-H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_t *fspace)
+H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *fspace)
{
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -414,6 +455,12 @@ H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_t *fspace)
*/
HDassert(fspace);
+ /* We should not still be holding on to the free space section info */
+ HDassert(!fspace->sinfo);
+
+ /* 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 */
@@ -422,12 +469,23 @@ H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_t *fspace)
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 */
+ HDassert(H5F_addr_defined(fspace->addr));
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, H5AC_dxpl_id, fspace->cache_info.addr, (hsize_t)H5FS_HEADER_SIZE(f)) < 0)
+ 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 = H5FL_SEQ_FREE(H5FS_section_class_t, fspace->sect_cls);
+ fspace->sect_cls = (H5FS_section_class_t *)H5FL_SEQ_FREE(H5FS_section_class_t, fspace->sect_cls);
/* Free free space info */
- H5FL_FREE(H5FS_t, fspace);
+ (void)H5FL_FREE(H5FS_t, fspace);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -531,9 +589,6 @@ H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *
H5FS_sinfo_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_sinfo_load)
-#ifdef QAK
-HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
-#endif /* QAK */
/* Check arguments */
HDassert(f);
@@ -543,11 +598,6 @@ HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
/* Allocate a new free space section info */
if(NULL == (sinfo = H5FS_sinfo_new(f, fspace)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Link free space manager to section info */
- /* (for deserializing sections) */
- HDassert(fspace->sinfo == NULL);
- fspace->sinfo = sinfo;
/* Sanity check address */
if(H5F_addr_ne(addr, fspace->sect_addr))
@@ -566,9 +616,9 @@ HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
p = buf;
/* Magic number */
- if(HDmemcmp(p, H5FS_SINFO_MAGIC, (size_t)H5FS_SIZEOF_MAGIC))
+ if(HDmemcmp(p, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "wrong free space sections signature")
- p += H5FS_SIZEOF_MAGIC;
+ p += H5_SIZEOF_MAGIC;
/* Version */
if(*p++ != H5FS_SINFO_VERSION)
@@ -670,7 +720,7 @@ HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
done:
if(buf)
- H5FL_BLK_FREE(sect_block, buf);
+ (void)H5FL_BLK_FREE(sect_block, buf);
if(!ret_value && sinfo)
(void)H5FS_cache_sinfo_dest(f, sinfo);
@@ -807,7 +857,7 @@ H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H
HDassert(sinfo->fspace);
HDassert(sinfo->fspace->sect_cls);
- if(sinfo->cache_info.is_dirty) {
+ if(sinfo->cache_info.is_dirty || sinfo->dirty) {
H5FS_iter_ud_t udata; /* User data for callbacks */
uint8_t *buf = NULL; /* Temporary raw data buffer */
uint8_t *p; /* Pointer into raw data buffer */
@@ -825,8 +875,8 @@ H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H
p = buf;
/* Magic number */
- HDmemcpy(p, H5FS_SINFO_MAGIC, (size_t)H5FS_SIZEOF_MAGIC);
- p += H5FS_SIZEOF_MAGIC;
+ HDmemcpy(p, H5FS_SINFO_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
/* Version # */
*p++ = H5FS_SINFO_VERSION;
@@ -863,9 +913,10 @@ 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")
- H5FL_BLK_FREE(sect_block, buf);
+ (void)H5FL_BLK_FREE(sect_block, buf);
sinfo->cache_info.is_dirty = FALSE;
+ sinfo->dirty = FALSE;
} /* end if */
if(destroy)
@@ -888,6 +939,10 @@ done:
* 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
@@ -900,6 +955,7 @@ H5FS_sinfo_free_sect_cb(void *_sect, void UNUSED *key, void *op_data)
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);
@@ -936,7 +992,7 @@ H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data)
H5SL_destroy(fspace_node->sect_list, H5FS_sinfo_free_sect_cb, op_data);
/* Release free space list node */
- H5FL_FREE(H5FS_node_t, fspace_node);
+ (void)H5FL_FREE(H5FS_node_t, fspace_node);
FUNC_LEAVE_NOAPI(0)
} /* H5FS_sinfo_free_node_cb() */
@@ -955,7 +1011,6 @@ H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data)
*
*-------------------------------------------------------------------------
*/
-/* ARGSUSED */
herr_t
H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo)
{
@@ -971,6 +1026,20 @@ H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *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));
+
+ /* Check for freeing file space for free space section info */
+ if(sinfo->cache_info.free_file_space_on_destroy) {
+ /* Sanity check */
+ HDassert(sinfo->fspace->alloc_sect_size > 0);
+
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, H5AC_dxpl_id, sinfo->cache_info.addr, (hsize_t)sinfo->fspace->alloc_sect_size) < 0)
+ 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) {
@@ -979,22 +1048,24 @@ H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo)
} /* end if */
/* Release bins for skip lists */
- sinfo->bins = H5FL_SEQ_FREE(H5FS_bin_t, sinfo->bins);
+ 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")
- /* Unpin the free space header in the cache */
+ /* Decrement the reference count on free space header */
/* (make certain this is last action with section info, to allow for header
* disappearing immediately)
*/
- if(H5AC_unpin_entry(f, sinfo->fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header")
+ 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 */
- H5FL_FREE(H5FS_sinfo_t, sinfo);
+ (void)H5FL_FREE(H5FS_sinfo_t, sinfo);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1063,7 +1134,7 @@ H5FS_cache_sinfo_size(const H5F_t UNUSED *f, const H5FS_sinfo_t *sinfo, size_t *
HDassert(size_ptr);
/* Set size value */
- H5_ASSIGN_OVERFLOW(/* To: */ *size_ptr, /* From: */ sinfo->fspace->sect_size, /* From: */ hsize_t, /* To: */ size_t);
+ H5_ASSIGN_OVERFLOW(/* To: */ *size_ptr, /* From: */ sinfo->fspace->alloc_sect_size, /* From: */ hsize_t, /* To: */ size_t);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5FS_cache_sinfo_size() */