summaryrefslogtreecommitdiffstats
path: root/src/H5MF.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5MF.c')
-rw-r--r--src/H5MF.c496
1 files changed, 325 insertions, 171 deletions
diff --git a/src/H5MF.c b/src/H5MF.c
index 2cf52b0..dfd1547 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -75,6 +75,10 @@ typedef enum {
/* Local Prototypes */
/********************/
+/* Allocator routines */
+static herr_t H5MF_alloc_create(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type);
+static herr_t H5MF_alloc_close(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type);
+
/*********************/
/* Package Variables */
@@ -195,11 +199,10 @@ H5MF_init_merge_flags(H5F_t *f)
/*-------------------------------------------------------------------------
- * Function: H5MF_alloc_start
+ * Function: H5MF_alloc_open
*
- * Purpose: "Start up" free space for file - open existing free space
- * structure if one exists, otherwise create a new free space
- * structure
+ * Purpose: Open an existing free space manager of TYPE for file by
+ * creating a free-space structure
*
* Return: Success: non-negative
* Failure: negative
@@ -208,19 +211,112 @@ H5MF_init_merge_flags(H5F_t *f)
* koziol@hdfgroup.org
* Jan 8 2008
*
- * Modifications:
- * Vailin Choi, July 29th, 2008
- * Pass values of alignment and threshold to FS_create() for handling alignment
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5MF_alloc_start(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, hbool_t may_create)
+H5MF_alloc_open(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
{
const H5FS_section_class_t *classes[] = { /* Free space section classes implemented for file */
H5MF_FSPACE_SECT_CLS_SIMPLE};
herr_t ret_value = SUCCEED; /* Return value */
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_alloc_open)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(H5F_addr_defined(f->shared->fs_addr[type]));
+ HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);
+
+ /* Open an existing free space structure for the file */
+ if(NULL == (f->shared->fs_man[type] = H5FS_open(f, dxpl_id, f->shared->fs_addr[type],
+ NELMTS(classes), classes, f, f->shared->alignment, f->shared->threshold)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
+
+ /* Set the state for the free space manager to "open", if it is now */
+ if(f->shared->fs_man[type])
+ f->shared->fs_state[type] = H5F_FS_STATE_OPEN;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_alloc_create
+ *
+ * Purpose: Create free space manager of TYPE for the file by creating
+ * a free-space structure
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 8 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_alloc_create(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
+{
+ const H5FS_section_class_t *classes[] = { /* Free space section classes implemented for file */
+ H5MF_FSPACE_SECT_CLS_SIMPLE};
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5FS_create_t fs_create; /* Free space creation parameters */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_alloc_create)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(!H5F_addr_defined(f->shared->fs_addr[type]));
+ HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);
+
+ /* Set the free space creation parameters */
+ fs_create.client = H5FS_CLIENT_FILE_ID;
+ fs_create.shrink_percent = H5MF_FSPACE_SHRINK;
+ fs_create.expand_percent = H5MF_FSPACE_EXPAND;
+ fs_create.max_sect_addr = 1 + H5V_log2_gen((uint64_t)f->shared->maxaddr);
+ fs_create.max_sect_size = f->shared->maxaddr;
+
+ if(NULL == (f->shared->fs_man[type] = H5FS_create(f, dxpl_id, NULL,
+ &fs_create, NELMTS(classes), classes, f, f->shared->alignment, f->shared->threshold)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
+
+
+ /* Set the state for the free space manager to "open", if it is now */
+ if(f->shared->fs_man[type])
+ f->shared->fs_state[type] = H5F_FS_STATE_OPEN;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_alloc_start
+ *
+ * Purpose: Open or create a free space manager of a given type
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 8 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5MF_alloc_start(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
FUNC_ENTER_NOAPI_NOINIT(H5MF_alloc_start)
/*
@@ -229,50 +325,62 @@ H5MF_alloc_start(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, hbool_t may_create)
HDassert(f);
HDassert(f->shared);
- /* Check for creating free space info for the file */
+ /* Check if the free space manager exists already */
if(H5F_addr_defined(f->shared->fs_addr[type])) {
- /* Open an existing free space structure for the file */
- HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);
- if(NULL == (f->shared->fs_man[type] = H5FS_open(f, dxpl_id, f->shared->fs_addr[type],
- NELMTS(classes), classes, f, f->shared->alignment, f->shared->threshold)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
+ /* Open existing free space manager */
+ if(H5MF_alloc_open(f, dxpl_id, type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, FAIL, "can't initialize file free space")
} /* end if */
else {
- /* Check if we are allowed to create the free space manager */
- if(may_create) {
- H5FS_create_t fs_create; /* Free space creation parameters */
-
- /* Set the free space creation parameters */
- fs_create.client = H5FS_CLIENT_FILE_ID;
- fs_create.shrink_percent = H5MF_FSPACE_SHRINK;
- fs_create.expand_percent = H5MF_FSPACE_EXPAND;
- fs_create.max_sect_addr = 1 + H5V_log2_gen((uint64_t)f->shared->maxaddr);
- fs_create.max_sect_size = f->shared->maxaddr;
-
- /* Create the free space structure for the heap */
- HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);
-#ifdef LATER
- if(NULL == (f->shared->fs_man[type] = H5FS_create(f, dxpl_id, &f->shared->fs_addr[type],
- &fs_create, NELMTS(classes), classes, f, f->shared->alignment, f->shared->threshold)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
-#else /* LATER */
- if(NULL == (f->shared->fs_man[type] = H5FS_create(f, dxpl_id, NULL,
- &fs_create, NELMTS(classes), classes, f, f->shared->alignment, f->shared->threshold)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
-#endif /* LATER */
- } /* end if */
+ /* Create new free space manager */
+ if(H5MF_alloc_create(f, dxpl_id, type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCREATE, FAIL, "can't initialize file free space")
} /* end else */
- /* Set the state for the free space manager to "open", if it is now */
- if(f->shared->fs_man[type])
- f->shared->fs_state[type] = H5F_FS_STATE_OPEN;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_alloc_start() */
/*-------------------------------------------------------------------------
+ * Function: H5MF_alloc_close
+ *
+ * Purpose: Close an existing free space manager of TYPE for file
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi; July 1st, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_alloc_close(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5MF_alloc_close)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->fs_man[type]);
+ HDassert(f->shared->fs_state[type] != H5F_FS_STATE_CLOSED);
+
+ /* Close an existing free space structure for the file */
+ if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release free space info")
+ f->shared->fs_man[type] = NULL;
+ f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_alloc_close() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5MF_alloc
*
* Purpose: Allocate SIZE bytes of file memory and return the relative
@@ -309,83 +417,75 @@ HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", FUNC, (unsigned)alloc_typ
/* Get free space type from allocation type */
fs_type = H5MF_ALLOC_TO_FS_TYPE(f, alloc_type);
- /* Check if the free space manager for the file has been initialized */
- if(!f->shared->fs_man[fs_type])
- if(H5MF_alloc_start(f, dxpl_id, fs_type, FALSE) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "can't initialize file free space")
-
- /* Search for large enough space in the free space manager */
- if(f->shared->fs_man[fs_type]) {
- H5MF_free_section_t *node; /* Free space section pointer */
- htri_t node_found = FALSE; /* Whether an existing free list node was found */
-
- /* Try to get a section from the free space manager */
- if((node_found = H5FS_sect_find(f, dxpl_id, f->shared->fs_man[fs_type], size, (H5FS_section_info_t **)&node)) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "error locating free space in file")
+ /* Check if we are using the free space manager for this file */
+ if(H5F_HAVE_FREE_SPACE_MANAGER(f)) {
+ /* Check if the free space manager for the file has been initialized */
+ if(!f->shared->fs_man[fs_type] && H5F_addr_defined(f->shared->fs_addr[fs_type]))
+ if(H5MF_alloc_open(f, dxpl_id, fs_type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, HADDR_UNDEF, "can't initialize file free space")
+
+ /* Search for large enough space in the free space manager */
+ if(f->shared->fs_man[fs_type]) {
+ H5MF_free_section_t *node; /* Free space section pointer */
+ htri_t node_found = FALSE; /* Whether an existing free list node was found */
+
+ /* Try to get a section from the free space manager */
+ if((node_found = H5FS_sect_find(f, dxpl_id, f->shared->fs_man[fs_type], size, (H5FS_section_info_t **)&node)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "error locating free space in file")
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 1.5, node_found = %t\n", FUNC, node_found);
#endif /* H5MF_ALLOC_DEBUG_MORE */
- /* Check for actually finding section */
- if(node_found) {
- /* Sanity check */
- HDassert(node);
+ /* Check for actually finding section */
+ if(node_found) {
+ /* Sanity check */
+ HDassert(node);
- /* Retrieve return value */
- ret_value = node->sect_info.addr;
+ /* Retrieve return value */
+ ret_value = node->sect_info.addr;
- /* Check for eliminating the section */
- if(node->sect_info.size == size) {
+ /* Check for eliminating the section */
+ if(node->sect_info.size == size) {
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 1.6, freeing node\n", FUNC);
#endif /* H5MF_ALLOC_DEBUG_MORE */
- /* Free section node */
- if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, HADDR_UNDEF, "can't free simple section node")
- } /* end if */
- else {
- H5MF_sect_ud_t udata; /* User data for callback */
+ /* Free section node */
+ if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, HADDR_UNDEF, "can't free simple section node")
+ } /* end if */
+ else {
+ H5MF_sect_ud_t udata; /* User data for callback */
- /* Adjust information for section */
- node->sect_info.addr += size;
- node->sect_info.size -= size;
+ /* Adjust information for section */
+ node->sect_info.addr += size;
+ node->sect_info.size -= size;
- /* Construct user data for callbacks */
- udata.f = f;
- udata.dxpl_id = dxpl_id;
- udata.alloc_type = alloc_type;
- udata.allow_sect_absorb = TRUE;
+ /* Construct user data for callbacks */
+ udata.f = f;
+ udata.dxpl_id = dxpl_id;
+ udata.alloc_type = alloc_type;
+ udata.allow_sect_absorb = TRUE;
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 1.7, re-adding node, node->sect_info.size = %Hu\n", FUNC, node->sect_info.size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
- /* Re-insert section node into file's free space */
- if(H5FS_sect_add(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF, "can't re-add section to file free space")
- } /* end else */
+ /* Re-insert section node into file's free space */
+ if(H5FS_sect_add(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF, "can't re-add section to file free space")
+ } /* end else */
- /* Leave now */
- HGOTO_DONE(ret_value)
+ /* Leave now */
+ HGOTO_DONE(ret_value)
+ } /* end if */
} /* end if */
- } /* end if */
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 2.0\n", FUNC);
#endif /* H5MF_ALLOC_DEBUG_MORE */
-
- /* Couldn't find anything from the free space manager, go allocate some */
- if(alloc_type != H5FD_MEM_DRAW) {
- /* Handle metadata differently from "raw" data */
- if(HADDR_UNDEF == (ret_value = H5MF_aggr_alloc(f, dxpl_id, &(f->shared->meta_aggr), &(f->shared->sdata_aggr), alloc_type, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata")
} /* end if */
- else {
- /* Allocate "raw" data */
- if(HADDR_UNDEF == (ret_value = H5MF_aggr_alloc(f, dxpl_id, &(f->shared->sdata_aggr), &(f->shared->meta_aggr), alloc_type, size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data")
- } /* end else */
- /* Sanity check for overlapping into file's temporary allocation space */
- HDassert(H5F_addr_le((ret_value + size), f->shared->tmp_addr));
+ /* Allocate from the metadata aggregator (or the VFD) */
+ if(HADDR_UNDEF == (ret_value = H5MF_aggr_vfd_alloc(f, alloc_type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "allocation failed from aggr/vfd")
done:
#ifdef H5MF_ALLOC_DEBUG
@@ -394,6 +494,7 @@ HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", FUNC, ret_value,
#ifdef H5MF_ALLOC_DEBUG_DUMP
H5MF_sects_dump(f, dxpl_id, stderr);
#endif /* H5MF_ALLOC_DEBUG_DUMP */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_alloc() */
@@ -531,23 +632,26 @@ HDfprintf(stderr, "%s: Trying to avoid starting up free space manager\n", FUNC);
/* If we are deleting the free space manager, leave now, to avoid
* [re-]starting it.
+ * or if file space strategy type is not using a free space manager
+ * (H5F_FILE_SPACE_AGGR_VFD or H5F_FILE_SPACE_VFD), drop free space
+ * section on the floor.
*
* Note: this drops the space to free on the floor...
*
*/
- if(f->shared->fs_state[fs_type] == H5F_FS_STATE_DELETING)
-{
+ if(f->shared->fs_state[fs_type] == H5F_FS_STATE_DELETING ||
+ !H5F_HAVE_FREE_SPACE_MANAGER(f)) {
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, addr, size);
#endif /* H5MF_ALLOC_DEBUG_MORE */
HGOTO_DONE(SUCCEED)
-}
+ } /* end if */
/* There's either already a free space manager, or the freed
* space isn't at the end of the file, so start up (or create)
* the file space manager
*/
- if(H5MF_alloc_start(f, dxpl_id, fs_type, TRUE) < 0)
+ if(H5MF_alloc_start(f, dxpl_id, fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
} /* end if */
HDassert(f->shared->fs_man[fs_type]);
@@ -568,14 +672,14 @@ HDfprintf(stderr, "%s: Before H5FS_sect_add()\n", FUNC);
#endif /* H5MF_ALLOC_DEBUG_MORE */
if(H5FS_sect_add(f, dxpl_id, f->shared->fs_man[fs_type], (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't add section to file free space")
+ node = NULL;
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: After H5FS_sect_add()\n", FUNC);
#endif /* H5MF_ALLOC_DEBUG_MORE */
- node = NULL;
done:
- if(ret_value < 0 && node)
- /* On error, free section node allocated */
+ /* Release section node, if allocated and not added to section list or merged */
+ if(node)
if(H5MF_sect_simple_free((H5FS_section_info_t *)node) < 0)
HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
@@ -635,8 +739,8 @@ HDfprintf(stderr, "%s: Entering: alloc_type = %u, addr = %a, size = %Hu, extra_r
fs_type = H5MF_ALLOC_TO_FS_TYPE(f, alloc_type);
/* Check if the free space for the file has been initialized */
- if(!f->shared->fs_man[fs_type])
- if(H5MF_alloc_start(f, dxpl_id, fs_type, FALSE) < 0)
+ if(!f->shared->fs_man[fs_type] && H5F_addr_defined(f->shared->fs_addr[fs_type]))
+ if(H5MF_alloc_open(f, dxpl_id, fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
/* Check for test block able to block in free space manager */
@@ -670,8 +774,8 @@ H5MF_sects_dump(f, dxpl_id, stderr);
*
*-------------------------------------------------------------------------
*/
-hssize_t
-H5MF_get_freespace(H5F_t *f, hid_t dxpl_id)
+herr_t
+H5MF_get_freespace(H5F_t *f, hid_t dxpl_id, hsize_t *tot_space, hsize_t *meta_size)
{
haddr_t eoa; /* End of allocated space in the file */
haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
@@ -679,8 +783,9 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id)
haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
hsize_t sda_size = 0; /* Size of "small data aggregator" */
hsize_t tot_fs_size = 0; /* Amount of all free space managed */
+ hsize_t tot_meta_size = 0; /* Amount of metadata for free space managers */
H5FD_mem_t type; /* Memory type for iteration */
- hssize_t ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5MF_get_freespace, FAIL)
@@ -694,38 +799,53 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
/* Retrieve metadata aggregator info, if available */
- H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
+ if(H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query metadata aggregator stats")
/* Retrieve 'small data' aggregator info, if available */
- H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size);
+ if(H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query small data aggregator stats")
/* Iterate over all the free space types that have managers and get each free list's space */
for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type)) {
- hsize_t type_fs_size = 0; /* Amount of free space managed for each type */
+ hbool_t fs_started = FALSE;
- /* Check if the free space for the file has been initialized */
- if(!f->shared->fs_man[type])
- if(H5MF_alloc_start(f, dxpl_id, type, FALSE) < 0)
+ /* Check if the free space for the file has been initialized */
+ if(!f->shared->fs_man[type] && H5F_addr_defined(f->shared->fs_addr[type])) {
+ if(H5MF_alloc_open(f, dxpl_id, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
+ HDassert(f->shared->fs_man[type]);
+ fs_started = TRUE;
+ } /* end if */
- /* Retrieve free space size from free space manager */
- if(f->shared->fs_man[type])
- if((ret_value = H5FS_sect_stats(f->shared->fs_man[type], &type_fs_size, NULL)) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space stats")
+ /* Check if there's free space of this type */
+ if(f->shared->fs_man[type]) {
+ hsize_t type_fs_size = 0; /* Amount of free space managed for each type */
+ hsize_t type_meta_size = 0; /* Amount of free space metadata for each type */
- /* Increment total free space for types */
- tot_fs_size += type_fs_size;
+ /* Retrieve free space size from free space manager */
+ if(H5FS_sect_stats(f->shared->fs_man[type], &type_fs_size, NULL) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space stats")
+ if(H5FS_size(f, f->shared->fs_man[type], &type_meta_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space metadata stats")
+
+ /* Increment total free space for types */
+ tot_fs_size += type_fs_size;
+ tot_meta_size += type_meta_size;
+ } /* end if */
+
+ /* Close the free space manager, if we opened it here */
+ if(fs_started)
+ if(H5MF_alloc_close(f, dxpl_id, type) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't close file free space")
} /* end for */
- /* Start computing value to return */
- ret_value = tot_fs_size;
-
/* Check for aggregating metadata allocations */
if(ma_size > 0) {
/* Add in the reserved space for metadata to the available free space */
/* (if it's not at the tail of the file) */
if(H5F_addr_ne(ma_addr + ma_size, eoa))
- ret_value += ma_size;
+ tot_fs_size += ma_size;
} /* end if */
/* Check for aggregating small data allocations */
@@ -733,9 +853,15 @@ H5MF_get_freespace(H5F_t *f, hid_t dxpl_id)
/* Add in the reserved space for metadata to the available free space */
/* (if it's not at the tail of the file) */
if(H5F_addr_ne(sda_addr + sda_size, eoa))
- ret_value += sda_size;
+ tot_fs_size += sda_size;
} /* end if */
+ /* Set the value(s) to return */
+ if(tot_space)
+ *tot_space = tot_fs_size;
+ if(meta_size)
+ *meta_size = tot_meta_size;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_get_freespace() */
@@ -807,6 +933,74 @@ HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
/*-------------------------------------------------------------------------
+ * Function: H5MF_free_aggrs
+ *
+ * Purpose: Reset a block aggregator, returning any space back to file
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ * July 1st, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id)
+{
+ H5F_blk_aggr_t *first_aggr; /* First aggregator to reset */
+ H5F_blk_aggr_t *second_aggr; /* Second aggregator to reset */
+ haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
+ hsize_t ma_size = 0; /* Size of "metadata aggregator" */
+ haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
+ hsize_t sda_size = 0; /* Size of "small data aggregator" */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5MF_free_aggrs, FAIL)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->lf);
+
+ /* Retrieve metadata aggregator info, if available */
+ if(H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query metadata aggregator stats")
+
+ /* Retrieve 'small data' aggregator info, if available */
+ if(H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query small data aggregator stats")
+
+ /* Make certain we release the aggregator that's later in the file first */
+ /* (so the file shrinks properly) */
+ if(H5F_addr_defined(ma_addr) && H5F_addr_defined(sda_addr)) {
+ if(H5F_addr_lt(ma_addr, sda_addr)) {
+ first_aggr = &(f->shared->sdata_aggr);
+ second_aggr = &(f->shared->meta_aggr);
+ } /* end if */
+ else {
+ first_aggr = &(f->shared->meta_aggr);
+ second_aggr = &(f->shared->sdata_aggr);
+ } /* end else */
+ } /* end if */
+ else {
+ first_aggr = &(f->shared->meta_aggr);
+ second_aggr = &(f->shared->sdata_aggr);
+ } /* end else */
+
+ /* Release the unused portion of the metadata and "small data" blocks back
+ * to the free lists in the file.
+ */
+ if(H5MF_aggr_reset(f, dxpl_id, first_aggr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset metadata block")
+ if(H5MF_aggr_reset(f, dxpl_id, second_aggr) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset 'small data' block")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_free_aggrs() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5MF_close
*
* Purpose: Close the free space tracker(s) for a file
@@ -822,12 +1016,6 @@ herr_t
H5MF_close(H5F_t *f, hid_t dxpl_id)
{
H5FD_mem_t type; /* Memory type for iteration */
- H5F_blk_aggr_t *first_aggr; /* First aggregator to reset */
- H5F_blk_aggr_t *second_aggr; /* Second aggregator to reset */
- haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */
- hsize_t ma_size = 0; /* Size of "metadata aggregator" */
- haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */
- hsize_t sda_size = 0; /* Size of "small data aggregator" */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5MF_close, FAIL)
@@ -851,7 +1039,7 @@ HDfprintf(stderr, "%s: Check 1.0 - f->shared->fs_man[%u] = %p, f->shared->fs_add
HDfprintf(stderr, "%s: Before closing free space manager\n", FUNC);
#endif /* H5MF_ALLOC_DEBUG_MORE */
if(H5FS_close(f, dxpl_id, f->shared->fs_man[type]) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't release free space info")
f->shared->fs_man[type] = NULL;
f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
} /* end if */
@@ -878,8 +1066,8 @@ HDfprintf(stderr, "%s: Check 2.0 - f->shared->fs_man[%u] = %p, f->shared->fs_add
HDfprintf(stderr, "%s: Before deleting free space manager\n", FUNC);
#endif /* H5MF_ALLOC_DEBUG_MORE */
/* Delete free space manager for this type */
- if(H5FS_delete(f, dxpl_id, tmp_fs_addr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "can't delete free space manager")
+ if(H5FS_delete(f, dxpl_id, tmp_fs_addr) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't delete free space manager")
/* Shift [back] to closed state */
HDassert(f->shared->fs_state[type] == H5F_FS_STATE_DELETING);
@@ -890,42 +1078,8 @@ HDfprintf(stderr, "%s: Before deleting free space manager\n", FUNC);
} /* end if */
} /* end for */
- /* Retrieve metadata aggregator info, if available */
- H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size);
-#ifdef H5MF_ALLOC_DEBUG_MORE
-HDfprintf(stderr, "%s: ma_addr = %a, ma_size = %Hu, end of ma = %a\n", FUNC, ma_addr, ma_size, (haddr_t)((ma_addr + ma_size) - 1));
-#endif /* H5MF_ALLOC_DEBUG_MORE */
-
- /* Retrieve 'small data' aggregator info, if available */
- H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size);
-#ifdef H5MF_ALLOC_DEBUG_MORE
-HDfprintf(stderr, "%s: sda_addr = %a, sda_size = %Hu, end of sda = %a\n", FUNC, sda_addr, sda_size, (haddr_t)((sda_addr + sda_size) - 1));
-#endif /* H5MF_ALLOC_DEBUG_MORE */
-
- /* Make certain we release the aggregator that's later in the file first */
- /* (so the file shrinks properly) */
- if(H5F_addr_defined(ma_addr) && H5F_addr_defined(sda_addr)) {
- if(H5F_addr_lt(ma_addr, sda_addr)) {
- first_aggr = &(f->shared->sdata_aggr);
- second_aggr = &(f->shared->meta_aggr);
- } /* end if */
- else {
- first_aggr = &(f->shared->meta_aggr);
- second_aggr = &(f->shared->sdata_aggr);
- } /* end else */
- } /* end if */
- else {
- first_aggr = &(f->shared->meta_aggr);
- second_aggr = &(f->shared->sdata_aggr);
- } /* end else */
-
- /* Release the unused portion of the metadata and "small data" blocks back
- * to the free lists in the file.
- */
- if(H5MF_aggr_reset(f, dxpl_id, first_aggr) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset metadata block")
- if(H5MF_aggr_reset(f, dxpl_id, second_aggr) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset 'small data' block")
+ if(H5MF_free_aggrs(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators")
done:
#ifdef H5MF_ALLOC_DEBUG