summaryrefslogtreecommitdiffstats
path: root/src/H5FS.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2008-10-07 04:17:35 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2008-10-07 04:17:35 (GMT)
commit9f60f016ab71cf8ce39c859fd9eb61c6fca35d63 (patch)
tree0ddbcb2f8707b578af22c62748420b9e3c19177b /src/H5FS.c
parent504c67846e6a4cc5706403bf21a9ae4f07aae7b4 (diff)
downloadhdf5-9f60f016ab71cf8ce39c859fd9eb61c6fca35d63.zip
hdf5-9f60f016ab71cf8ce39c859fd9eb61c6fca35d63.tar.gz
hdf5-9f60f016ab71cf8ce39c859fd9eb61c6fca35d63.tar.bz2
[svn-r15800] Description:
Bring file free space branch changes through r15795 into trunk, which includes a fair bit of code cleanup & rearrangement along with a couple of bug fixes also. Tested on: Mac OS X/32 10.5.5 (amazon) in debug mode Mac OS X/32 10.5.5 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
Diffstat (limited to 'src/H5FS.c')
-rw-r--r--src/H5FS.c462
1 files changed, 344 insertions, 118 deletions
diff --git a/src/H5FS.c b/src/H5FS.c
index 47ac7ef..4282200 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -91,22 +91,25 @@ H5FL_DEFINE(H5FS_t);
* Programmer: Quincey Koziol
* Tuesday, March 7, 2006
*
+ * Modifications:
+ * Vailin Choi, July 29th, 2008
+ * Add two more parameters for handling alignment: alignment & threshhold
+ *
*-------------------------------------------------------------------------
*/
H5FS_t *
H5FS_create(H5F_t *f, hid_t dxpl_id, haddr_t *fs_addr, const H5FS_create_t *fs_create,
- size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata)
+ size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, hsize_t threshold)
{
H5FS_t *fspace = NULL; /* New free space structure */
H5FS_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FS_create, NULL)
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, nclasses);
-#endif /* QAK */
+#endif /* H5FS_DEBUG */
/* Check arguments. */
- HDassert(fs_addr);
HDassert(fs_create->shrink_percent);
HDassert(fs_create->shrink_percent < fs_create->expand_percent);
HDassert(fs_create->max_sect_size);
@@ -118,11 +121,6 @@ HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, ncl
if(NULL == (fspace = H5FS_new(nclasses, classes, cls_init_udata)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space free list")
- /* Allocate space for the free space header */
- if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)H5FS_HEADER_SIZE(f))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for free space header")
- *fs_addr = fspace->addr;
-
/* Initialize creation information for free space manager */
fspace->client = fs_create->client;
fspace->shrink_percent = fs_create->shrink_percent;
@@ -130,17 +128,39 @@ HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, ncl
fspace->max_sect_addr = fs_create->max_sect_addr;
fspace->max_sect_size = fs_create->max_sect_size;
- /* Cache the new free space header (pinned) */
- if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space header to cache")
+ fspace->alignment = alignment;
+ fspace->threshold = threshold;
+
+ /* Check if the free space tracker is supposed to be persistant */
+ if(fs_addr) {
+ /* Allocate space for the free space header */
+ if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)H5FS_HEADER_SIZE(f))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for free space header")
+
+ /* Cache the new free space header (pinned) */
+ if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space header to cache")
+
+ /* Return free space header address to caller, if desired */
+ *fs_addr = fspace->addr;
+ } /* end if */
+
+ /* Set the reference count to 1, since we inserted the entry in the cache pinned */
+ fspace->rc = 1;
/* Set the return value */
ret_value = fspace;
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: fspace = %p, fspace->addr = %a\n", FUNC, fspace, fspace->addr);
+#endif /* H5FS_DEBUG */
done:
if(!ret_value && fspace)
(void)H5FS_cache_hdr_dest(f, fspace);
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
+#endif /* H5FS_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_create() */
@@ -157,21 +177,25 @@ done:
* Programmer: Quincey Koziol
* Tuesday, May 2, 2006
*
+ * Modfications:
+ *
+ * Vailin Choi, July 29th, 2008
+ * Add two more parameters for handling alignment: alignment & threshhold
+ *
*-------------------------------------------------------------------------
*/
H5FS_t *
H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr, size_t nclasses,
- const H5FS_section_class_t *classes[], void *cls_init_udata)
+ const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, hsize_t threshold)
{
H5FS_t *fspace = NULL; /* New free space structure */
H5FS_prot_t fs_prot; /* Information for protecting free space manager */
- unsigned fspace_status = 0; /* Free space header's status in the metadata cache */
H5FS_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FS_open, NULL)
-#ifdef QAK
-HDfprintf(stderr, "%s: Opening free space manager, nclasses = %Zu\n", FUNC, nclasses);
-#endif /* QAK */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Opening free space manager, fs_addr = %a, nclasses = %Zu\n", FUNC, fs_addr, nclasses);
+#endif /* H5FS_DEBUG */
/* Check arguments. */
HDassert(H5F_addr_defined(fs_addr));
@@ -186,26 +210,23 @@ HDfprintf(stderr, "%s: Opening free space manager, nclasses = %Zu\n", FUNC, ncla
/* Protect the free space header */
if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, NULL, "unable to load free space header")
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
HDfprintf(stderr, "%s: fspace->sect_size = %Hu\n", FUNC, fspace->sect_size);
HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu\n", FUNC, fspace->alloc_sect_size);
HDfprintf(stderr, "%s: fspace->sinfo = %p\n", FUNC, fspace->sinfo);
-#endif /* QAK */
+HDfprintf(stderr, "%s: fspace->rc = %u\n", FUNC, fspace->rc);
+#endif /* H5FS_DEBUG */
- /* Check the free space header's status in the metadata cache */
- if(H5AC_get_entry_status(f, fs_addr, &fspace_status) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, NULL, "unable to check metadata cache status for free space header")
+ /* Increment the reference count on the free space manager header */
+ HDassert(fspace->rc <= 1);
+ if(H5FS_incr(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINC, NULL, "unable to increment ref. count on free space header")
- /* If the free space header isn't already pinned, pin it now */
- /* (could still be pinned from it's section info still hanging around in the cache) */
- if(!(fspace_status & H5AC_ES__IS_PINNED)) {
- /* Pin free space header in the cache */
- if(H5AC_pin_protected_entry(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTPIN, NULL, "unable to pin free space header")
- } /* end if */
+ fspace->alignment = alignment;
+ fspace->threshold = threshold;
- /* Unlock free space header, now pinned */
+ /* Unlock free space header */
if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, NULL, "unable to release free space header")
@@ -239,9 +260,9 @@ H5FS_delete(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FS_delete, FAIL)
-#ifdef QAK
-HDfprintf(stderr, "%s: Deleting free space manager\n", FUNC);
-#endif /* QAK */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Deleting free space manager, fs_addr = %a\n", FUNC, fs_addr);
+#endif /* H5FS_DEBUG */
/* Check arguments. */
HDassert(f);
@@ -257,16 +278,19 @@ HDfprintf(stderr, "%s: Deleting free space manager\n", FUNC);
if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, FAIL, "unable to protect free space header")
+ /* Sanity check */
+ HDassert(fspace->sinfo == NULL);
+
/* Delete serialized section storage, if there are any */
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
-#endif /* QAK */
+#endif /* H5FS_DEBUG */
if(fspace->serial_sect_count > 0) {
unsigned sinfo_status = 0; /* Free space section info's status in the metadata cache */
/* Sanity check */
HDassert(H5F_addr_defined(fspace->sect_addr));
- HDassert(fspace->sect_size > 0);
+ HDassert(fspace->alloc_sect_size > 0);
/* Check the free space section info's status in the metadata cache */
if(H5AC_get_entry_status(f, fspace->sect_addr, &sinfo_status) < 0)
@@ -278,32 +302,28 @@ HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
HDassert(!(sinfo_status & H5AC_ES__IS_PINNED));
HDassert(!(sinfo_status & H5AC_ES__IS_PROTECTED));
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Expunging free space section info from cache\n", FUNC);
-#endif /* QAK */
+#endif /* H5FS_DEBUG */
/* Evict the free space section info from the metadata cache */
- if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr) < 0)
+ /* (Free file space) */
+ if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove free space section info from cache")
-#ifdef QAK
+#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Done expunging free space section info from cache\n", FUNC);
-#endif /* QAK */
+#endif /* H5FS_DEBUG */
} /* end if */
-
- /* Release the space in the file */
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+ else {
+ /* Release the space in the file */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+ } /* end else */
} /* end if */
- /* Release header's disk space */
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, dxpl_id, fs_addr, (hsize_t)H5FS_HEADER_SIZE(f))<0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space header")
-
- /* Release the free space header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__DELETED_FLAG) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space header")
- fspace = NULL;
-
done:
+ if(fspace && H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0)
+ HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_delete() */
@@ -333,72 +353,143 @@ H5FS_close(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
/* Check arguments. */
HDassert(f);
HDassert(fspace);
-#ifdef QAK
-HDfprintf(stderr, "%s: Entering, fspace = %p, fspace->sinfo = %p\n", FUNC, fspace, fspace->sinfo);
-#endif /* QAK */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Entering, fspace = %p, fspace->addr = %a, fspace->sinfo = %p\n", FUNC, fspace, fspace->addr, fspace->sinfo);
+#endif /* H5FS_DEBUG */
/* Check if section info is valid */
+ /* (i.e. the header "owns" the section info and it's not in the cache) */
if(fspace->sinfo) {
- HDassert(H5F_addr_defined(fspace->sect_addr));
-
- /* Unpin the free space section info in the cache */
- if(H5AC_unpin_entry(f, fspace->sinfo) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space section info")
-
- /* If there aren't any sections being managed, free the space for the sections */
-#ifdef QAK
-HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_count);
-#endif /* QAK */
- if(fspace->tot_sect_count == 0) {
- haddr_t old_addr; /* Old section info address */
-
- HDassert(fspace->serial_sect_count == 0);
- HDassert(fspace->ghost_sect_count == 0);
-
- /* Free previous serialized sections disk space */
- old_addr = fspace->sect_addr;
- if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_addr, fspace->alloc_sect_size) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu, fspace->serial_sect_count = %Hu, fspace->sect_addr = %a, fspace->rc = %u\n", FUNC, fspace->tot_sect_count, fspace->serial_sect_count, fspace->sect_addr, fspace->rc);
+HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", FUNC, fspace->alloc_sect_size, fspace->sect_size);
+#endif /* H5FS_DEBUG */
+ /* If there are sections to serialize, update them */
+ /* (if the free space manager is persistant) */
+ if(fspace->serial_sect_count > 0 && H5F_addr_defined(fspace->addr)) {
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Real sections to store in file\n", FUNC);
+#endif /* H5FS_DEBUG */
+ if(fspace->sinfo->dirty) {
+ /* Check if the section info is "floating" */
+ 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 free space header as dirty */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+ } /* end if */
+ } /* end if */
+ else
+ /* Sanity check that section info has address */
+ HDassert(H5F_addr_defined(fspace->sect_addr));
+
+ /* Cache the free space section info */
+ if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, fspace->sinfo, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't add free space sections to cache")
+ } /* end if */
+ else {
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: NOT storing section info in file\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Check if space for the section info is allocated */
+ if(H5F_addr_defined(fspace->sect_addr)) {
+ /* Sanity check */
+ /* (section info should only be in the file if the header is */
+ HDassert(H5F_addr_defined(fspace->addr));
- /* Reset section info */
- fspace->sect_addr = HADDR_UNDEF;
- fspace->alloc_sect_size = fspace->sect_size = 0;
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info allocated though\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Check if the section info is for the free space in the file */
+ /* (NOTE: This is the "bootstrapping" special case for the
+ * free space manager, to avoid freeing the space for the
+ * section info and re-creating it as a section in the
+ * manager. -QAK)
+ */
+ if(fspace->client == H5FS_CLIENT_FILE_ID) {
+ htri_t status; /* "can absorb" status for section into */
- /* Mark free space header as dirty */
- if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info is for file free space\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Try to shrink the file or absorb the section info into a block aggregator */
+ if((status = H5MF_try_shrink(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for absorbing section info")
+ else if(status == FALSE) {
+ /* Section info can't "go away", but it's free. Allow
+ * header to record it
+ */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info can't 'go away', header will own it\n", FUNC);
+#endif /* H5FS_DEBUG */
+ } /* end if */
+ else {
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info went 'go away'\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Reset section info in header */
+ fspace->sect_addr = HADDR_UNDEF;
+ fspace->alloc_sect_size = 0;
+
+ /* Mark free space header as dirty */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+ } /* end else */
+ } /* end if */
+ else {
+ haddr_t old_sect_addr = fspace->sect_addr; /* Previous location of section info in file */
+ hsize_t old_alloc_sect_size = fspace->alloc_sect_size; /* Previous size of section info in file */
- /* Evict the section info from the metadata cache */
- if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, old_addr) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "unable to remove free space section info from cache")
- } /* end if */
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Section info is NOT for file free space\n", FUNC);
+#endif /* H5FS_DEBUG */
+ /* Reset section info in header */
+ fspace->sect_addr = HADDR_UNDEF;
+ fspace->alloc_sect_size = 0;
+
+ /* Mark free space header as dirty */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+
+ /* Free previous serialized sections disk space */
+ if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_sect_addr, old_alloc_sect_size) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to free free space sections")
+ } /* end if */
+ } /* end else */
+
+ /* Destroy section info */
+ if(H5FS_cache_sinfo_dest(f, fspace->sinfo) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy free space section info")
+ } /* end else */
+
+ /* Reset the header's pointer to the section info */
+ fspace->sinfo = NULL;
} /* end if */
else {
- unsigned sect_status = 0; /* Free space section's status in the metadata cache */
-
- /* Check if we've allocated any section info in the file & if it's still in the cache */
- if(H5F_addr_defined(fspace->sect_addr) && H5AC_get_entry_status(f, fspace->sect_addr, &sect_status) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space header")
-
- /* If this free list header's section info exists and is still in the
- * cache, don't unpin the header - let the section info do it,
- * when the section info is evicted from the cache. -QAK
- */
- if(!(sect_status & H5AC_ES__IN_CACHE)) {
- /* Unpin the free space header in the cache */
- /* (the section info destructor would unpin it if the section info existed) */
- if(H5AC_unpin_entry(f, fspace) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header")
- } /* end if */
+ /* Just sanity checks... */
+ if(fspace->serial_sect_count > 0)
+ /* Sanity check that section info has address */
+ HDassert(H5F_addr_defined(fspace->sect_addr));
+ else
+ /* Sanity check that section info doesn't have address */
+ HDassert(!H5F_addr_defined(fspace->sect_addr));
} /* end else */
- /* Reset the header's pointer to the section info, so it will get pinned again
- * if the free space header is still in the metadata cache when the free
- * space manager is re-opened.
- */
- fspace->sinfo = NULL;
+ /* Decrement the reference count on the free space manager header */
+ if(H5FS_decr(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTDEC, FAIL, "unable to decrement ref. count on free space header")
done:
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Leaving, ret_value = %d, fspace->rc = %u\n", FUNC, ret_value, fspace->rc);
+#endif /* H5FS_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_close() */
@@ -453,6 +544,10 @@ H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[],
if(fspace->sect_cls[u].init_cls)
if((fspace->sect_cls[u].init_cls)(&fspace->sect_cls[u], cls_init_udata) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "unable to initialize section class")
+
+ /* Determine maximum class-specific serialization size for each section */
+ if(fspace->sect_cls[u].serial_size > fspace->max_cls_serial_size)
+ fspace->max_cls_serial_size = fspace->sect_cls[u].serial_size;
} /* end for */
} /* end if */
@@ -494,12 +589,141 @@ H5FS_size(const H5F_t *f, const H5FS_t *fspace, hsize_t *meta_size)
HDassert(meta_size);
/* Get the free space size info */
- *meta_size += H5FS_HEADER_SIZE(f) + fspace->alloc_sect_size;
+ *meta_size += H5FS_HEADER_SIZE(f) + (fspace->sinfo ? fspace->sect_size : fspace->alloc_sect_size);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FS_size() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_incr
+ *
+ * Purpose: Increment reference count on free space header
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * February 7, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_incr(H5F_t *f, H5FS_t *fspace)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FS_incr, FAIL)
#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fspace->addr, fspace->rc);
+#endif /* H5FS_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(fspace);
+
+ /* Check if we should pin the header in the cache */
+ if(fspace->rc == 0 && H5F_addr_defined(fspace->addr))
+ if(H5AC_pin_protected_entry(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTPIN, FAIL, "unable to pin free space header")
+
+ /* Increment reference count on header */
+ fspace->rc++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FS_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_decr
+ *
+ * Purpose: Decrement reference count on free space header
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * February 7, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_decr(H5F_t *f, H5FS_t *fspace)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FS_decr, FAIL)
+#ifdef H5FS_DEBUG
+HDfprintf(stderr, "%s: Entering, fpace->addr = %a, fspace->rc = %u\n", FUNC, fspace->addr, fspace->rc);
+#endif /* H5FS_DEBUG */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(fspace);
+
+ /* Decrement reference count on header */
+ fspace->rc--;
+
+ /* Check if we should unpin the header in the cache */
+ if(fspace->rc == 0) {
+ if(H5F_addr_defined(fspace->addr)) {
+ if(H5AC_unpin_entry(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header")
+ } /* end if */
+ else {
+ if(H5FS_cache_hdr_dest(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "unable to destroy free space header")
+ } /* end else */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FS_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FS_dirty
+ *
+ * Purpose: Mark free space header as dirty
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Feb 14 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FS_dirty(H5F_t *f, H5FS_t *fspace)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_dirty)
+#ifdef QAK
+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 */
+ if(H5F_addr_defined(fspace->addr))
+ /* Mark header as dirty in cache */
+ if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FS_dirty() */
+
+#ifdef H5FS_DEBUG_ASSERT
/*-------------------------------------------------------------------------
* Function: H5FS_assert
@@ -518,16 +742,19 @@ herr_t
H5FS_assert(const H5FS_t *fspace)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_assert)
-#ifdef QAK
-HDfprintf(stderr, "%s: fspace->hdr->tot_sect_count = %Hu\n", "H5FS_assert", fspace->hdr->tot_sect_count);
+#ifndef QAK
+HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", "H5FS_assert", fspace->tot_sect_count);
#endif /* QAK */
- /* Sanity check sections */
- H5FS_sect_assert(fspace);
+ /* Checks for section info, if it's available */
+ if(fspace->sinfo) {
+ /* Sanity check sections */
+ H5FS_sect_assert(fspace);
- /* General assumptions about the section size counts */
- HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->serial_size_count);
- HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->ghost_size_count);
+ /* General assumptions about the section size counts */
+ HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->serial_size_count);
+ HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->ghost_size_count);
+ } /* end if */
/* General assumptions about the section counts */
HDassert(fspace->tot_sect_count >= fspace->serial_sect_count);
@@ -539,5 +766,4 @@ HDfprintf(stderr, "%s: fspace->hdr->tot_sect_count = %Hu\n", "H5FS_assert", fspa
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FS_assert() */
-#endif /* H5FS_DEBUG */
-
+#endif /* H5FS_DEBUG_ASSERT */