#define H5F_FRIEND
#define H5FS_FRIEND
#include "H5MFmodule.h"
#include "H5private.h"
#include "H5Eprivate.h"
#include "H5Fpkg.h"
#include "H5FSpkg.h"
#include "H5Iprivate.h"
#include "H5MFpkg.h"
#include "H5VMprivate.h"
#define H5MF_FSPACE_SHRINK 80
#define H5MF_FSPACE_EXPAND 120
#define H5MF_ALLOC_TO_FS_AGGR_TYPE(F, T) \
((H5FD_MEM_DEFAULT == (F)->shared->fs_type_map[T]) ? (T) : (F)->shared->fs_type_map[T])
typedef enum {
H5MF_AGGR_MERGE_SEPARATE,
H5MF_AGGR_MERGE_DICHOTOMY,
H5MF_AGGR_MERGE_TOGETHER
} H5MF_aggr_merge_t;
typedef struct {
H5F_sect_info_t *sects;
size_t sect_count;
size_t sect_idx;
} H5MF_sect_iter_ud_t;
static haddr_t H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size);
static herr_t H5MF__close_aggrfs(H5F_t *f);
static herr_t H5MF__close_pagefs(H5F_t *f);
static herr_t H5MF__close_shrink_eoa(H5F_t *f);
static herr_t H5MF__get_free_sects(H5F_t *f, H5FS_t *fspace, H5MF_sect_iter_ud_t *sect_udata, size_t *nums);
static hbool_t H5MF__fsm_type_is_self_referential(H5F_t *f, H5F_mem_page_t fsm_type);
static hbool_t H5MF__fsm_is_self_referential(H5F_t *f, H5FS_t *fspace);
static herr_t H5MF__create_fstype(H5F_t *f, H5F_mem_page_t type);
static herr_t H5MF__close_fstype(H5F_t *f, H5F_mem_page_t type);
static herr_t H5MF__delete_fstype(H5F_t *f, H5F_mem_page_t type);
static herr_t H5MF__close_delete_fstype(H5F_t *f, H5F_mem_page_t type);
static herr_t H5MF__sects_cb(H5FS_section_info_t *_sect, void *_udata);
hbool_t H5_PKG_INIT_VAR = FALSE;
herr_t
H5MF_init_merge_flags(H5F_t *f)
{
H5MF_aggr_merge_t mapping_type;
H5FD_mem_t type;
hbool_t all_same;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->lf);
all_same = TRUE;
for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; type++)
if(f->shared->fs_type_map[type] != f->shared->fs_type_map[H5FD_MEM_DEFAULT]) {
all_same = FALSE;
break;
}
if(all_same) {
if(f->shared->fs_type_map[H5FD_MEM_DEFAULT] == H5FD_MEM_DEFAULT)
mapping_type = H5MF_AGGR_MERGE_SEPARATE;
else
mapping_type = H5MF_AGGR_MERGE_TOGETHER;
}
else {
if(f->shared->fs_type_map[H5FD_MEM_DRAW] == f->shared->fs_type_map[H5FD_MEM_SUPER])
mapping_type = H5MF_AGGR_MERGE_SEPARATE;
else {
hbool_t all_metadata_same;
all_metadata_same = TRUE;
for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++)
if(type != H5FD_MEM_DRAW && type != H5FD_MEM_GHEAP) {
if(f->shared->fs_type_map[type] != f->shared->fs_type_map[H5FD_MEM_SUPER]) {
all_metadata_same = FALSE;
break;
}
}
if(all_metadata_same)
mapping_type = H5MF_AGGR_MERGE_DICHOTOMY;
else
mapping_type = H5MF_AGGR_MERGE_SEPARATE;
}
}
switch(mapping_type) {
case H5MF_AGGR_MERGE_SEPARATE:
HDmemset(f->shared->fs_aggr_merge, 0, sizeof(f->shared->fs_aggr_merge));
if(H5FD_MEM_DRAW == f->shared->fs_type_map[H5FD_MEM_DRAW] ||
H5FD_MEM_DEFAULT == f->shared->fs_type_map[H5FD_MEM_DRAW]) {
f->shared->fs_aggr_merge[H5FD_MEM_DRAW] = H5F_FS_MERGE_RAWDATA;
f->shared->fs_aggr_merge[H5FD_MEM_GHEAP] = H5F_FS_MERGE_RAWDATA;
}
break;
case H5MF_AGGR_MERGE_DICHOTOMY:
HDmemset(f->shared->fs_aggr_merge, H5F_FS_MERGE_METADATA, sizeof(f->shared->fs_aggr_merge));
f->shared->fs_aggr_merge[H5FD_MEM_DRAW] = H5F_FS_MERGE_RAWDATA;
f->shared->fs_aggr_merge[H5FD_MEM_GHEAP] = H5F_FS_MERGE_RAWDATA;
break;
case H5MF_AGGR_MERGE_TOGETHER:
HDmemset(f->shared->fs_aggr_merge, (H5F_FS_MERGE_METADATA | H5F_FS_MERGE_RAWDATA), sizeof(f->shared->fs_aggr_merge));
break;
default:
HGOTO_ERROR(H5E_RESOURCE, H5E_BADVALUE, FAIL, "invalid mapping type")
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
void
H5MF__alloc_to_fs_type(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5F_mem_page_t *fs_type)
{
FUNC_ENTER_PACKAGE_NOERR
HDassert(f);
HDassert(fs_type);
if(H5F_PAGED_AGGR(f)) {
if(size >= f->shared->fs_page_size) {
if(H5F_HAS_FEATURE(f, H5FD_FEAT_PAGED_AGGR)) {
if(H5FD_MEM_DEFAULT == f->shared->fs_type_map[alloc_type])
*fs_type = (H5F_mem_page_t) (alloc_type + (H5FD_MEM_NTYPES - 1));
else
*fs_type = (H5F_mem_page_t) (f->shared->fs_type_map[alloc_type] + (H5FD_MEM_NTYPES - 1));
}
else
*fs_type = H5F_MEM_PAGE_GENERIC;
}
else
*fs_type = (H5F_mem_page_t)H5MF_ALLOC_TO_FS_AGGR_TYPE(f, alloc_type);
}
else
*fs_type = (H5F_mem_page_t)H5MF_ALLOC_TO_FS_AGGR_TYPE(f, alloc_type);
FUNC_LEAVE_NOAPI_VOID
}
herr_t
H5MF__open_fstype(H5F_t *f, H5F_mem_page_t type)
{
const H5FS_section_class_t *classes[] = {
H5MF_FSPACE_SECT_CLS_SIMPLE,
H5MF_FSPACE_SECT_CLS_SMALL,
H5MF_FSPACE_SECT_CLS_LARGE };
hsize_t alignment;
hsize_t threshold;
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t fsm_ring;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE_TAG(H5AC__FREESPACE_TAG)
HDassert(f);
if(H5F_PAGED_AGGR(f))
HDassert(type < H5F_MEM_PAGE_NTYPES);
else {
HDassert((H5FD_mem_t)type < H5FD_MEM_NTYPES);
HDassert((H5FD_mem_t)type != H5FD_MEM_NOLIST);
}
HDassert(f->shared);
HDassert(H5F_addr_defined(f->shared->fs_addr[type]));
HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);
if(H5F_PAGED_AGGR(f)) {
alignment = (type == H5F_MEM_PAGE_GENERIC) ? f->shared->fs_page_size : (hsize_t)H5F_ALIGN_DEF;
threshold = H5F_ALIGN_THRHD_DEF;
}
else {
alignment = f->shared->alignment;
threshold = f->shared->threshold;
}
if(H5MF__fsm_type_is_self_referential(f, type))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
if(NULL == (f->shared->fs_man[type] = H5FS_open(f, f->shared->fs_addr[type],
NELMTS(classes), classes, f, alignment, threshold)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
if(f->shared->fs_man[type])
f->shared->fs_state[type] = H5F_FS_STATE_OPEN;
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5MF__create_fstype(H5F_t *f, H5F_mem_page_t type)
{
const H5FS_section_class_t *classes[] = {
H5MF_FSPACE_SECT_CLS_SIMPLE,
H5MF_FSPACE_SECT_CLS_SMALL,
H5MF_FSPACE_SECT_CLS_LARGE };
H5FS_create_t fs_create;
hsize_t alignment;
hsize_t threshold;
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t fsm_ring;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
HDassert(f);
if(H5F_PAGED_AGGR(f))
HDassert(type < H5F_MEM_PAGE_NTYPES);
else {
HDassert((H5FD_mem_t)type < H5FD_MEM_NTYPES);
HDassert((H5FD_mem_t)type != H5FD_MEM_NOLIST);
}
HDassert(f->shared);
HDassert(!H5F_addr_defined(f->shared->fs_addr[type]));
HDassert(f->shared->fs_state[type] == H5F_FS_STATE_CLOSED);
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 + H5VM_log2_gen((uint64_t)f->shared->maxaddr);
fs_create.max_sect_size = f->shared->maxaddr;
if(H5F_PAGED_AGGR(f)) {
alignment = (type == H5F_MEM_PAGE_GENERIC) ? f->shared->fs_page_size : (hsize_t)H5F_ALIGN_DEF;
threshold = H5F_ALIGN_THRHD_DEF;
}
else {
alignment = f->shared->alignment;
threshold = f->shared->threshold;
}
if(H5MF__fsm_type_is_self_referential(f, type))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
if(NULL == (f->shared->fs_man[type] = H5FS_create(f, NULL,
&fs_create, NELMTS(classes), classes, f, alignment, threshold)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space info")
if(f->shared->fs_man[type])
f->shared->fs_state[type] = H5F_FS_STATE_OPEN;
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
herr_t
H5MF__start_fstype(H5F_t *f, H5F_mem_page_t type)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE_TAG(H5AC__FREESPACE_TAG)
HDassert(f);
HDassert(f->shared);
if(H5F_PAGED_AGGR(f))
HDassert(type < H5F_MEM_PAGE_NTYPES);
else {
HDassert((H5FD_mem_t)type < H5FD_MEM_NTYPES);
HDassert((H5FD_mem_t)type != H5FD_MEM_NOLIST);
}
if(H5F_addr_defined(f->shared->fs_addr[type])) {
if(H5MF__open_fstype(f, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, FAIL, "can't initialize file free space")
}
else {
if(H5MF__create_fstype(f, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCREATE, FAIL, "can't initialize file free space")
}
done:
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5MF__delete_fstype(H5F_t *f, H5F_mem_page_t type)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t fsm_ring = H5AC_RING_INV;
haddr_t tmp_fs_addr;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
HDassert(f);
if(H5F_PAGED_AGGR(f))
HDassert(type < H5F_MEM_PAGE_NTYPES);
else
HDassert((H5FD_mem_t)type < H5FD_MEM_NTYPES);
HDassert(H5F_addr_defined(f->shared->fs_addr[type]));
tmp_fs_addr = f->shared->fs_addr[type];
f->shared->fs_addr[type] = HADDR_UNDEF;
f->shared->fs_state[type] = H5F_FS_STATE_DELETING;
if(H5MF__fsm_type_is_self_referential(f, type))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Before deleting free space manager\n", FUNC);
#endif
if(H5FS_delete(f, tmp_fs_addr) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't delete free space manager")
HDassert(f->shared->fs_state[type] == H5F_FS_STATE_DELETING);
f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
HDassert(!H5F_addr_defined(f->shared->fs_addr[type]));
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5MF__close_fstype(H5F_t *f, H5F_mem_page_t type)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
HDassert(f);
if(H5F_PAGED_AGGR(f))
HDassert(type < H5F_MEM_PAGE_NTYPES);
else
HDassert((H5FD_mem_t)type < H5FD_MEM_NTYPES);
HDassert(f->shared);
HDassert(f->shared->fs_man[type]);
HDassert(f->shared->fs_state[type] != H5F_FS_STATE_CLOSED);
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Before closing free space manager\n", FUNC);
#endif
if(H5FS_close(f, f->shared->fs_man[type]) < 0)
HGOTO_ERROR(H5E_RESOURCE, 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_TAG(ret_value)
}
herr_t
H5MF__add_sect(H5F_t *f, H5FD_mem_t alloc_type, H5FS_t *fspace, H5MF_free_section_t *node)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t fsm_ring = H5AC_RING_INV;
H5MF_sect_ud_t udata;
H5F_mem_page_t fs_type;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE_TAG(H5AC__FREESPACE_TAG)
HDassert(f);
HDassert(fspace);
HDassert(node);
H5MF__alloc_to_fs_type(f, alloc_type, node->sect_info.size, &fs_type);
udata.f = f;
udata.alloc_type = alloc_type;
udata.allow_sect_absorb = TRUE;
udata.allow_eoa_shrink_only = FALSE;
if(H5MF__fsm_is_self_referential(f, fspace))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: adding node, node->sect_info.addr = %a, node->sect_info.size = %Hu\n", FUNC, node->sect_info.addr, node->sect_info.size);
#endif
if(H5FS_sect_add(f, fspace, (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, &udata) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space")
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
htri_t
H5MF__find_sect(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size, H5FS_t *fspace,
haddr_t *addr)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t fsm_ring = H5AC_RING_INV;
H5MF_free_section_t *node;
htri_t ret_value = FAIL;
FUNC_ENTER_PACKAGE_TAG(H5AC__FREESPACE_TAG)
HDassert(f);
HDassert(fspace);
if(H5MF__fsm_is_self_referential(f, fspace))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
if((ret_value = H5FS_sect_find(f, fspace, size, (H5FS_section_info_t **)&node)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "error locating free space in file")
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: section found = %t\n", FUNC, ret_value);
#endif
if(ret_value) {
HDassert(node);
if(addr)
*addr = node->sect_info.addr;
if(node->sect_info.size == size) {
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: freeing node\n", FUNC);
#endif
if(H5MF__sect_free((H5FS_section_info_t *)node) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
}
else {
node->sect_info.addr += size;
node->sect_info.size -= size;
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: re-adding node, node->sect_info.size = %Hu\n", FUNC, node->sect_info.size);
#endif
if(H5MF__add_sect(f, alloc_type, fspace, node) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space")
}
}
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
haddr_t
H5MF_alloc(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
{
H5AC_ring_t fsm_ring = H5AC_RING_INV;
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5F_mem_page_t fs_type;
haddr_t ret_value = HADDR_UNDEF;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, HADDR_UNDEF)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", FUNC, (unsigned)alloc_type, size);
#endif
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->lf);
HDassert(size > 0);
if(f->shared->first_alloc_dealloc) {
HDassert(! H5AC_cache_image_pending(f));
if(H5MF_tidy_self_referential_fsm_hack(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "tidy of self referential fsm hack failed")
}
H5MF__alloc_to_fs_type(f, alloc_type, size, &fs_type);
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 1.0\n", FUNC);
#endif
if(H5MF__fsm_type_is_self_referential(f, fs_type))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
if(H5F_HAVE_FREE_SPACE_MANAGER(f)) {
if(H5AC_unsettle_ring(f, fsm_ring) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_SYSTEM, HADDR_UNDEF, "attempt to notify cache that ring is unsettled failed")
if(!f->shared->fs_man[fs_type] && H5F_addr_defined(f->shared->fs_addr[fs_type])) {
if(H5MF__open_fstype(f, fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTOPENOBJ, HADDR_UNDEF, "can't initialize file free space")
HDassert(f->shared->fs_man[fs_type]);
}
if(f->shared->fs_man[fs_type])
if(H5MF__find_sect(f, alloc_type, size, f->shared->fs_man[fs_type], &ret_value) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "error locating a node")
}
if(!H5F_addr_defined(ret_value)) {
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 2.0\n", FUNC);
#endif
if(f->shared->fs_strategy == H5F_FSPACE_STRATEGY_PAGE) {
HDassert(f->shared->fs_page_size >= H5F_FILE_SPACE_PAGE_SIZE_MIN);
if(HADDR_UNDEF == (ret_value = H5MF__alloc_pagefs(f, alloc_type, size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "allocation failed from paged aggregation")
}
else {
if(HADDR_UNDEF == (ret_value = H5MF_aggr_vfd_alloc(f, alloc_type, size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "allocation failed from aggr/vfd")
}
}
HDassert(H5F_addr_defined(ret_value));
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 3.0\n", FUNC);
#endif
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", FUNC, ret_value, size);
#endif
#ifdef H5MF_ALLOC_DEBUG_DUMP
H5MF__sects_dump(f, stderr);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static haddr_t
H5MF__alloc_pagefs(H5F_t *f, H5FD_mem_t alloc_type, hsize_t size)
{
H5F_mem_page_t ptype;
H5MF_free_section_t *node = NULL;
haddr_t ret_value = HADDR_UNDEF;
FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", FUNC, (unsigned)alloc_type, size);
#endif
H5MF__alloc_to_fs_type(f, alloc_type, size, &ptype);
switch(ptype) {
case H5F_MEM_PAGE_GENERIC:
case H5F_MEM_PAGE_LARGE_BTREE:
case H5F_MEM_PAGE_LARGE_DRAW:
case H5F_MEM_PAGE_LARGE_GHEAP:
case H5F_MEM_PAGE_LARGE_LHEAP:
case H5F_MEM_PAGE_LARGE_OHDR:
{
haddr_t eoa;
hsize_t frag_size = 0;
if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, alloc_type)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "Unable to get eoa")
HDassert(!(eoa % f->shared->fs_page_size));
H5MF_EOA_MISALIGN(f, (eoa+size), f->shared->fs_page_size, frag_size);
if(HADDR_UNDEF == (ret_value = H5F__alloc(f, alloc_type, size + frag_size, NULL, NULL)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate file space")
if(frag_size) {
if(!(f->shared->fs_man[ptype]))
if(H5MF__start_fstype(f, ptype) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "can't initialize file free space")
if(NULL == (node = H5MF__sect_new(H5MF_FSPACE_SECT_LARGE, ret_value + size, frag_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "can't initialize free space section")
if(H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF, "can't re-add section to file free space")
node = NULL;
}
}
break;
case H5F_MEM_PAGE_META:
case H5F_MEM_PAGE_DRAW:
case H5F_MEM_PAGE_BTREE:
case H5F_MEM_PAGE_GHEAP:
case H5F_MEM_PAGE_LHEAP:
case H5F_MEM_PAGE_OHDR:
{
haddr_t new_page;
if(HADDR_UNDEF == (new_page = H5MF_alloc(f, alloc_type, f->shared->fs_page_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate file space")
if(!(f->shared->fs_man[ptype]))
if(H5MF__start_fstype(f, ptype) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "can't initialize file free space")
HDassert(f->shared->fs_man[ptype]);
if(NULL == (node = H5MF__sect_new(H5MF_FSPACE_SECT_SMALL, (new_page + size), (f->shared->fs_page_size - size))))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, HADDR_UNDEF, "can't initialize free space section")
if(H5MF__add_sect(f, alloc_type, f->shared->fs_man[ptype], node) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF, "can't re-add section to file free space")
node = NULL;
if(f->shared->page_buf != NULL && H5PB_add_new_page(f->shared, alloc_type, new_page) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, HADDR_UNDEF, "can't add new page to Page Buffer new page list")
ret_value = new_page;
}
break;
case H5F_MEM_PAGE_NTYPES:
case H5F_MEM_PAGE_DEFAULT:
default:
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate file space: unrecognized type")
break;
}
done:
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", FUNC, ret_value, size);
#endif
#ifdef H5MF_ALLOC_DEBUG_DUMP
H5MF__sects_dump(f, stderr);
#endif
if(node)
if(H5MF__sect_free((H5FS_section_info_t *)node) < 0)
HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, HADDR_UNDEF, "can't free section node")
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
haddr_t
H5MF_alloc_tmp(H5F_t *f, hsize_t size)
{
haddr_t eoa;
haddr_t ret_value = HADDR_UNDEF;
FUNC_ENTER_NOAPI(HADDR_UNDEF)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: size = %Hu\n", FUNC, size);
#endif
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->lf);
HDassert(size > 0);
if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, H5FD_MEM_DEFAULT)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "driver get_eoa request failed")
ret_value = f->shared->tmp_addr - size;
if(H5F_addr_le(ret_value, eoa))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "driver get_eoa request failed")
f->shared->tmp_addr = ret_value;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5MF_xfree(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size)
{
H5F_mem_page_t fs_type;
H5MF_free_section_t *node = NULL;
unsigned ctype;
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t fsm_ring;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)alloc_type, addr, size);
#endif
HDassert(f);
if(!H5F_addr_defined(addr) || 0 == size)
HGOTO_DONE(SUCCEED)
HDassert(addr != 0);
if(f->shared->first_alloc_dealloc) {
HDassert(!H5AC_cache_image_pending(f));
if(H5MF_tidy_self_referential_fsm_hack(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "tidy of self referential fsm hack failed")
}
H5MF__alloc_to_fs_type(f, alloc_type, size, &fs_type);
if(H5MF__fsm_type_is_self_referential(f, fs_type))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
if(H5F_HAVE_FREE_SPACE_MANAGER(f))
if(H5AC_unsettle_ring(f, fsm_ring) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_SYSTEM, FAIL, "attempt to notify cache that ring is unsettled failed")
if(H5F_addr_le(f->shared->tmp_addr, addr))
HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, FAIL, "attempting to free temporary file space")
if(H5FD_MEM_DRAW != alloc_type) {
if(H5F__accum_free(f->shared, alloc_type, addr, size) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't check free space intersection w/metadata accumulator")
}
if(!f->shared->fs_man[fs_type]) {
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: fs_addr = %a\n", FUNC, f->shared->fs_addr[fs_type]);
#endif
if(!H5F_addr_defined(f->shared->fs_addr[fs_type])) {
htri_t status;
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Trying to avoid starting up free space manager\n", FUNC);
#endif
if((status = H5MF_try_shrink(f, alloc_type, addr, size)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "can't check for absorbing block")
else if(status > 0)
HGOTO_DONE(SUCCEED)
else if(size < f->shared->fs_threshold) {
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, addr, size);
#endif
HGOTO_DONE(SUCCEED)
}
}
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
HGOTO_DONE(SUCCEED)
}
if(H5MF__start_fstype(f, fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
}
ctype = H5MF_SECT_CLASS_TYPE(f, size);
if(NULL == (node = H5MF__sect_new(ctype, addr, size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space section")
if(size >= f->shared->fs_threshold) {
HDassert(f->shared->fs_man[fs_type]);
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Before H5FS_sect_add()\n", FUNC);
#endif
if(H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 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
}
else {
htri_t merged;
H5MF_sect_ud_t udata;
udata.f = f;
udata.alloc_type = alloc_type;
udata.allow_sect_absorb = TRUE;
udata.allow_eoa_shrink_only = FALSE;
if((merged = H5FS_sect_try_merge(f, 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 merge section to file free space")
else if(merged == TRUE)
node = NULL;
}
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
if(node)
if(H5MF__sect_free((H5FS_section_info_t *)node) < 0)
HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
#endif
#ifdef H5MF_ALLOC_DEBUG_DUMP
H5MF__sects_dump(f, stderr);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
htri_t
H5MF_try_extend(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size,
hsize_t extra_requested)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t fsm_ring;
haddr_t end;
H5FD_mem_t map_type;
H5F_mem_page_t fs_type;
htri_t allow_extend = TRUE;
hsize_t frag_size = 0;
htri_t ret_value = FALSE;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering: alloc_type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n", FUNC, (unsigned)alloc_type, addr, size, extra_requested);
#endif
HDassert(f);
HDassert(H5F_INTENT(f) & H5F_ACC_RDWR);
if(f->shared->first_alloc_dealloc) {
HDassert(! H5AC_cache_image_pending(f));
if(H5MF_tidy_self_referential_fsm_hack(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "tidy of self referential fsm hack failed")
}
map_type = (alloc_type == H5FD_MEM_GHEAP) ? H5FD_MEM_DRAW : alloc_type;
end = addr + size;
if(H5F_PAGED_AGGR(f)) {
if(size < f->shared->fs_page_size) {
if((addr / f->shared->fs_page_size) != (((end + extra_requested) - 1) / f->shared->fs_page_size))
allow_extend = FALSE;
}
else {
haddr_t eoa;
if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, alloc_type)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "Unable to get eoa")
HDassert(!(eoa % f->shared->fs_page_size));
H5MF_EOA_MISALIGN(f, (eoa+extra_requested), f->shared->fs_page_size, frag_size);
}
}
H5MF__alloc_to_fs_type(f, alloc_type, size, &fs_type);
if(H5MF__fsm_type_is_self_referential(f, fs_type))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
if(allow_extend) {
if((ret_value = H5F__try_extend(f, map_type, end, extra_requested + frag_size)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending file")
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: extended = %t\n", FUNC, ret_value);
#endif
if(ret_value == TRUE && H5F_PAGED_AGGR(f) && frag_size) {
H5MF_free_section_t *node = NULL;
HDassert(size >= f->shared->fs_page_size);
if(!(f->shared->fs_man[fs_type]))
if(H5MF__start_fstype(f, fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
if(NULL == (node = H5MF__sect_new(H5MF_FSPACE_SECT_LARGE, end + extra_requested, frag_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space section")
if(H5MF__add_sect(f, alloc_type, f->shared->fs_man[fs_type], node) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space")
node = NULL;
}
if(ret_value == FALSE && (f->shared->fs_strategy == H5F_FSPACE_STRATEGY_FSM_AGGR ||
f->shared->fs_strategy == H5F_FSPACE_STRATEGY_AGGR) ) {
H5F_blk_aggr_t *aggr;
aggr = (map_type == H5FD_MEM_DRAW) ? &(f->shared->sdata_aggr) : &(f->shared->meta_aggr);
if((ret_value = H5MF__aggr_try_extend(f, aggr, map_type, end, extra_requested)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending aggregation block")
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: H5MF__aggr_try_extend = %t\n", FUNC, ret_value);
#endif
}
if(ret_value == FALSE && ((f->shared->fs_strategy == H5F_FSPACE_STRATEGY_FSM_AGGR) ||
(H5F_PAGED_AGGR(f))) ) {
H5MF_sect_ud_t udata;
udata.f = f;
udata.alloc_type = alloc_type;
if(!f->shared->fs_man[fs_type] && H5F_addr_defined(f->shared->fs_addr[fs_type]))
if(H5MF__open_fstype(f, fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
if(f->shared->fs_man[fs_type]) {
if((ret_value = H5FS_sect_try_extend(f, f->shared->fs_man[fs_type], addr, size, extra_requested, H5FS_ADD_RETURNED_SPACE, &udata)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTEXTEND, FAIL, "error extending block in free space manager")
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Try to H5FS_sect_try_extend = %t\n", FUNC, ret_value);
#endif
}
if(ret_value == FALSE && H5F_PAGED_AGGR(f) && map_type != H5FD_MEM_DRAW) {
H5MF_EOA_MISALIGN(f, end, f->shared->fs_page_size, frag_size);
if(frag_size <= H5F_PGEND_META_THRES(f) && extra_requested <= frag_size)
ret_value = TRUE;
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Try to extend into the page end threshold = %t\n", FUNC, ret_value);
#endif
}
}
}
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving: ret_value = %t\n", FUNC, ret_value);
#endif
#ifdef H5MF_ALLOC_DEBUG_DUMP
H5MF__sects_dump(f, stderr);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
htri_t
H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, haddr_t addr, hsize_t size)
{
H5MF_free_section_t *node = NULL;
H5MF_sect_ud_t udata;
H5FS_section_class_t *sect_cls;
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t fsm_ring = H5AC_RING_INV;
H5F_mem_page_t fs_type;
htri_t ret_value = FALSE;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)alloc_type, addr, size);
#endif
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->lf);
HDassert(H5F_addr_defined(addr));
HDassert(size > 0);
sect_cls = H5MF_SECT_CLS_TYPE(f, size);
HDassert(sect_cls);
H5MF__alloc_to_fs_type(f, alloc_type, size, &fs_type);
if(H5MF__fsm_type_is_self_referential(f, fs_type))
fsm_ring = H5AC_RING_MDFSM;
else
fsm_ring = H5AC_RING_RDFSM;
H5AC_set_ring(fsm_ring, &orig_ring);
if(NULL == (node = H5MF__sect_new(sect_cls->type, addr, size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space section")
udata.f = f;
udata.alloc_type = alloc_type;
udata.allow_sect_absorb = FALSE;
udata.allow_eoa_shrink_only = FALSE;
if(sect_cls->can_shrink) {
if((ret_value = (*sect_cls->can_shrink)((const H5FS_section_info_t *)node, &udata)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "can't check if section can shrink container")
if(ret_value > 0) {
HDassert(sect_cls->shrink);
if((*sect_cls->shrink)((H5FS_section_info_t **)&node, &udata) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink container")
}
}
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
if(node && H5MF__sect_free((H5FS_section_info_t *)node) < 0)
HDONE_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
herr_t
H5MF_close(H5F_t *f)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering\n", FUNC);
#endif
HDassert(f);
HDassert(f->shared);
if(H5F_PAGED_AGGR(f)) {
if((ret_value = H5MF__close_pagefs(f)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't close free-space managers for 'page' file space")
}
else {
if((ret_value = H5MF__close_aggrfs(f)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't close free-space managers for 'aggr' file space")
}
done:
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", FUNC);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5MF__close_delete_fstype(H5F_t *f, H5F_mem_page_t type)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering\n", FUNC);
#endif
HDassert(f);
HDassert(f->shared);
if(H5F_PAGED_AGGR(f))
HDassert(type < H5F_MEM_PAGE_NTYPES);
else
HDassert((H5FD_mem_t)type < H5FD_MEM_NTYPES);
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 1.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %a\n", FUNC, (unsigned)type, f->shared->fs_man[type], (unsigned)type, f->shared->fs_addr[type]);
#endif
if(f->shared->fs_man[type])
if(H5MF__close_fstype(f, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't close the free space manager")
#ifdef H5MF_ALLOC_DEBUG_MORE
HDfprintf(stderr, "%s: Check 2.0 - f->shared->fs_man[%u] = %p, f->shared->fs_addr[%u] = %a\n", FUNC, (unsigned)type, f->shared->fs_man[type], (unsigned)type, f->shared->fs_addr[type]);
#endif
if(H5F_addr_defined(f->shared->fs_addr[type]))
if(H5MF__delete_fstype(f, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't delete the free space manager")
done:
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", FUNC);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
herr_t
H5MF_try_close(H5F_t *f)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t curr_ring = H5AC_RING_INV;
H5AC_ring_t needed_ring = H5AC_RING_INV;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering\n", FUNC);
#endif
HDassert(f);
if(f->shared->first_alloc_dealloc) {
if(H5AC_cache_image_pending(f)) {
if(H5AC_force_cache_image_load(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "forced cache image load failed")
}
else {
if(H5MF_tidy_self_referential_fsm_hack(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "tidy of self referential fsm hack failed")
}
}
H5AC_set_ring(H5AC_RING_RDFSM, &orig_ring);
curr_ring = H5AC_RING_RDFSM;
if(H5F_PAGED_AGGR(f)) {
H5F_mem_page_t ptype;
for(ptype = H5F_MEM_PAGE_META; ptype < H5F_MEM_PAGE_NTYPES; ptype++) {
if(H5MF__fsm_type_is_self_referential(f, ptype))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring ) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
if(H5MF__close_delete_fstype(f, ptype) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't close the free space manager")
}
}
else {
H5FD_mem_t type;
for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; type++) {
if(H5MF__fsm_type_is_self_referential(f, (H5F_mem_page_t)type))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
if(H5MF__close_delete_fstype(f, (H5F_mem_page_t)type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't close the free space manager")
}
}
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", FUNC);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5MF__close_aggrfs(H5F_t *f)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t curr_ring = H5AC_RING_INV;
H5AC_ring_t needed_ring = H5AC_RING_INV;
H5FD_mem_t type;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering\n", FUNC);
#endif
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->lf);
HDassert(f->shared->sblock);
H5AC_set_ring(H5AC_RING_RDFSM, &orig_ring);
curr_ring = H5AC_RING_RDFSM;
if(H5MF_free_aggrs(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators")
if(H5MF__close_shrink_eoa(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
if(f->shared->sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2
&& f->shared->fs_persist) {
H5O_fsinfo_t fsinfo;
haddr_t final_eoa;
H5F_mem_page_t ptype;
HDassert(H5F_addr_defined(f->shared->sblock->ext_addr));
for(ptype = H5F_MEM_PAGE_META; ptype < H5F_MEM_PAGE_NTYPES; ptype++)
fsinfo.fs_addr[ptype - 1] = HADDR_UNDEF;
for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++)
fsinfo.fs_addr[type-1] = f->shared->fs_addr[type];
fsinfo.strategy = f->shared->fs_strategy;
fsinfo.persist = f->shared->fs_persist;
fsinfo.threshold = f->shared->fs_threshold;
fsinfo.page_size = f->shared->fs_page_size;
fsinfo.pgend_meta_thres = f->shared->pgend_meta_thres;
fsinfo.eoa_pre_fsm_fsalloc = f->shared->eoa_pre_fsm_fsalloc;
fsinfo.version = f->shared->fs_version;
if(H5F__super_ext_write_msg(f, H5O_FSINFO_ID, &fsinfo, FALSE, H5O_MSG_FLAG_MARK_IF_UNKNOWN) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing message to superblock extension")
for(type = H5FD_MEM_SUPER; type < H5FD_MEM_NTYPES; type++) {
if(f->shared->fs_man[type]) {
if(H5MF__fsm_type_is_self_referential(f, (H5F_mem_page_t)type))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
HDassert(f->shared->fs_state[type] == H5F_FS_STATE_OPEN);
if(H5FS_close(f, f->shared->fs_man[type]) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't close free space manager")
f->shared->fs_man[type] = NULL;
f->shared->fs_state[type] = H5F_FS_STATE_CLOSED;
}
f->shared->fs_addr[type] = HADDR_UNDEF;
}
HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
HDassert(f->shared->sdata_aggr.tot_size == 0);
HDassert(f->shared->sdata_aggr.addr == 0);
HDassert(f->shared->sdata_aggr.size == 0);
HDassert(f->shared->meta_aggr.tot_size == 0);
HDassert(f->shared->meta_aggr.addr == 0);
HDassert(f->shared->meta_aggr.size == 0);
if(H5MF__close_shrink_eoa(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
if(HADDR_UNDEF == (final_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)) )
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size")
HDassert((f->shared->first_alloc_dealloc) || (final_eoa == f->shared->eoa_post_fsm_fsalloc));
}
else {
for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; type++)
if(H5MF__close_delete_fstype(f, (H5F_mem_page_t)type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
}
if(H5MF_free_aggrs(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free aggregators")
if(H5MF__close_shrink_eoa(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", FUNC);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5MF__close_pagefs(H5F_t *f)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t curr_ring = H5AC_RING_INV;
H5AC_ring_t needed_ring = H5AC_RING_INV;
H5F_mem_page_t ptype;
H5O_fsinfo_t fsinfo;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Entering\n", FUNC);
#endif
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->lf);
HDassert(f->shared->sblock);
HDassert(f->shared->fs_page_size);
HDassert(f->shared->sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2);
H5AC_set_ring(H5AC_RING_RDFSM, &orig_ring);
curr_ring = H5AC_RING_RDFSM;
if(H5MF__close_shrink_eoa(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
fsinfo.strategy = f->shared->fs_strategy;
fsinfo.persist = f->shared->fs_persist;
fsinfo.threshold = f->shared->fs_threshold;
fsinfo.page_size = f->shared->fs_page_size;
fsinfo.pgend_meta_thres = f->shared->pgend_meta_thres;
fsinfo.eoa_pre_fsm_fsalloc = HADDR_UNDEF;
fsinfo.version = f->shared->fs_version;
for(ptype = H5F_MEM_PAGE_META; ptype < H5F_MEM_PAGE_NTYPES; ptype++)
fsinfo.fs_addr[ptype - 1] = HADDR_UNDEF;
if(f->shared->fs_persist) {
haddr_t final_eoa;
HDassert(H5F_addr_defined(f->shared->sblock->ext_addr));
for(ptype = H5F_MEM_PAGE_META; ptype < H5F_MEM_PAGE_NTYPES; ptype++)
fsinfo.fs_addr[ptype-1] = f->shared->fs_addr[ptype];
fsinfo.eoa_pre_fsm_fsalloc = f->shared->eoa_pre_fsm_fsalloc;
if(H5F__super_ext_write_msg(f, H5O_FSINFO_ID, &fsinfo, FALSE, H5O_MSG_FLAG_MARK_IF_UNKNOWN) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing message to superblock extension")
for(ptype = H5F_MEM_PAGE_META; ptype < H5F_MEM_PAGE_NTYPES; ptype++) {
if(f->shared->fs_man[ptype]) {
if(H5MF__fsm_type_is_self_referential(f, ptype))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
HDassert(f->shared->fs_state[ptype] == H5F_FS_STATE_OPEN);
if(H5FS_close(f, f->shared->fs_man[ptype]) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't close free space manager")
f->shared->fs_man[ptype] = NULL;
f->shared->fs_state[ptype] = H5F_FS_STATE_CLOSED;
}
f->shared->fs_addr[ptype] = HADDR_UNDEF;
}
HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
if(H5MF__close_shrink_eoa(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
if(HADDR_UNDEF == (final_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)) )
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size")
HDassert((f->shared->first_alloc_dealloc) ||
(final_eoa == f->shared->eoa_post_fsm_fsalloc) ||
((H5F_addr_defined(f->shared->eoa_post_mdci_fsalloc)) &&
(final_eoa == f->shared->eoa_post_mdci_fsalloc)));
}
else {
for(ptype = H5F_MEM_PAGE_META; ptype < H5F_MEM_PAGE_NTYPES; ptype++)
if(H5MF__close_delete_fstype(f, ptype) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't close the free space manager")
if(H5F__super_ext_write_msg(f, H5O_FSINFO_ID, &fsinfo, FALSE, H5O_MSG_FLAG_MARK_IF_UNKNOWN) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing message to superblock extension")
}
if(H5MF__close_shrink_eoa(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
#ifdef H5MF_ALLOC_DEBUG
HDfprintf(stderr, "%s: Leaving\n", FUNC);
#endif
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5MF__close_shrink_eoa(H5F_t *f)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t curr_ring = H5AC_RING_INV;
H5AC_ring_t needed_ring = H5AC_RING_INV;
H5F_mem_t type;
H5F_mem_page_t ptype;
hbool_t eoa_shrank;
htri_t status;
H5MF_sect_ud_t udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC_TAG(H5AC__FREESPACE_TAG)
HDassert(f);
HDassert(f->shared);
udata.f = f;
udata.allow_sect_absorb = FALSE;
udata.allow_eoa_shrink_only = TRUE;
H5AC_set_ring(H5AC_RING_RDFSM, &orig_ring);
curr_ring = H5AC_RING_RDFSM;
do {
eoa_shrank = FALSE;
if(H5F_PAGED_AGGR(f)) {
for(ptype = H5F_MEM_PAGE_META; ptype < H5F_MEM_PAGE_NTYPES; ptype++) {
if(f->shared->fs_man[ptype]) {
if(H5MF__fsm_type_is_self_referential(f, ptype))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
udata.alloc_type = (H5FD_mem_t)((H5FD_mem_t)ptype < H5FD_MEM_NTYPES ? ptype : ((ptype % H5FD_MEM_NTYPES) + 1));
if((status = H5FS_sect_try_shrink_eoa(f, f->shared->fs_man[ptype], &udata)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa")
else if(status > 0)
eoa_shrank = TRUE;
}
}
}
else {
for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; type++) {
if(f->shared->fs_man[type]) {
if(H5MF__fsm_type_is_self_referential(f, (H5F_mem_page_t)type))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
udata.alloc_type = type;
if((status = H5FS_sect_try_shrink_eoa(f, f->shared->fs_man[type], &udata)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa")
else if(status > 0)
eoa_shrank = TRUE;
}
}
if((status = H5MF_aggrs_try_shrink_eoa(f)) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa")
else if(status > 0)
eoa_shrank = TRUE;
}
} while(eoa_shrank);
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
herr_t
H5MF_get_freespace(H5F_t *f, hsize_t *tot_space, hsize_t *meta_size)
{
haddr_t ma_addr = HADDR_UNDEF;
hsize_t ma_size = 0;
haddr_t sda_addr = HADDR_UNDEF;
hsize_t sda_size = 0;
hsize_t tot_fs_size = 0;
hsize_t tot_meta_size = 0;
H5FD_mem_t tt;
H5F_mem_page_t type;
H5F_mem_page_t start_type;
H5F_mem_page_t end_type;
htri_t fs_started[H5F_MEM_PAGE_NTYPES];
haddr_t fs_eoa[H5FD_MEM_NTYPES];
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t curr_ring = H5AC_RING_INV;
H5AC_ring_t needed_ring = H5AC_RING_INV;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->lf);
H5AC_set_ring(H5AC_RING_RDFSM, &orig_ring);
curr_ring = H5AC_RING_RDFSM;
if(H5F_PAGED_AGGR(f)) {
start_type = H5F_MEM_PAGE_META;
end_type = H5F_MEM_PAGE_NTYPES;
}
else {
start_type = (H5F_mem_page_t)H5FD_MEM_SUPER;
end_type = (H5F_mem_page_t)H5FD_MEM_NTYPES;
}
for(tt = H5FD_MEM_SUPER; tt < H5FD_MEM_NTYPES; tt++)
if(HADDR_UNDEF == (fs_eoa[tt] = H5F_get_eoa(f, tt)))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
if(!H5F_PAGED_AGGR(f)) {
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")
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")
}
for(type = start_type; type < end_type; type++) {
fs_started[type] = FALSE;
if(!f->shared->fs_man[type] && H5F_addr_defined(f->shared->fs_addr[type])) {
if(H5MF__open_fstype(f, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space")
HDassert(f->shared->fs_man[type]);
fs_started[type] = TRUE;
}
if(H5MF__fsm_type_is_self_referential(f, (H5F_mem_page_t)type))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
if(f->shared->fs_man[type]) {
hsize_t type_fs_size = 0;
hsize_t type_meta_size = 0;
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->shared->fs_man[type], &type_meta_size) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space metadata stats")
tot_fs_size += type_fs_size;
tot_meta_size += type_meta_size;
}
}
for(type = start_type; type < end_type; type++) {
if(H5MF__fsm_type_is_self_referential(f, (H5F_mem_page_t)type))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, &curr_ring);
curr_ring = needed_ring;
}
if(fs_started[type])
if(H5MF__close_fstype(f, type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't close file free space")
}
if(tot_space)
*tot_space = tot_fs_size + ma_size + sda_size;
if(meta_size)
*meta_size = tot_meta_size;
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
ssize_t
H5MF_get_free_sections(H5F_t *f, H5FD_mem_t type, size_t nsects, H5F_sect_info_t *sect_info)
{
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t curr_ring = H5AC_RING_INV;
H5AC_ring_t needed_ring = H5AC_RING_INV;
size_t total_sects = 0;
H5MF_sect_iter_ud_t sect_udata;
H5F_mem_page_t start_type, end_type;
H5F_mem_page_t ty;
ssize_t ret_value = -1;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, (-1))
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->lf);
if(f->shared->first_alloc_dealloc) {
if(H5AC_cache_image_pending(f)) {
if(H5AC_force_cache_image_load(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, (-1), "forced cache image load failed")
}
else {
if(H5MF_tidy_self_referential_fsm_hack(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, (-1), "tidy of self referential fsm hack failed")
}
}
if(type == H5FD_MEM_DEFAULT) {
start_type = H5F_MEM_PAGE_SUPER;
end_type = H5F_MEM_PAGE_NTYPES;
}
else {
start_type = end_type = (H5F_mem_page_t)type;
if(H5F_PAGED_AGGR(f))
end_type = (H5F_mem_page_t)(end_type + H5FD_MEM_NTYPES);
else
end_type++;
}
sect_udata.sects = sect_info;
sect_udata.sect_count = nsects;
sect_udata.sect_idx = 0;
H5AC_set_ring(H5AC_RING_RDFSM, &orig_ring);
curr_ring = H5AC_RING_RDFSM;
for(ty = start_type; ty < end_type; ty++) {
hbool_t fs_started = FALSE;
size_t nums = 0;
if(H5MF__fsm_type_is_self_referential(f, ty))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, &curr_ring);
curr_ring = needed_ring;
}
if(!f->shared->fs_man[ty] && H5F_addr_defined(f->shared->fs_addr[ty])) {
if(H5MF__open_fstype(f, ty) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, (-1), "can't open the free space manager")
HDassert(f->shared->fs_man[ty]);
fs_started = TRUE;
}
if(f->shared->fs_man[ty])
if(H5MF__get_free_sects(f, f->shared->fs_man[ty], §_udata, &nums) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, (-1), "can't get section info for the free space manager")
total_sects += nums;
if(fs_started)
if(H5MF__close_fstype(f, ty) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCLOSEOBJ, (-1), "can't close file free space")
if((H5F_PAGED_AGGR(f)) && (type != H5FD_MEM_DEFAULT))
ty = (H5F_mem_page_t)(ty + H5FD_MEM_NTYPES - 2);
}
ret_value = (ssize_t)total_sects;
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5MF__sects_cb(H5FS_section_info_t *_sect, void *_udata)
{
H5MF_free_section_t *sect = (H5MF_free_section_t *)_sect;
H5MF_sect_iter_ud_t *udata = (H5MF_sect_iter_ud_t *)_udata;
FUNC_ENTER_STATIC_NOERR
if(udata->sect_idx < udata->sect_count) {
udata->sects[udata->sect_idx].addr = sect->sect_info.addr;
udata->sects[udata->sect_idx].size = sect->sect_info.size;
udata->sect_idx++;
}
FUNC_LEAVE_NOAPI(SUCCEED)
}
static herr_t
H5MF__get_free_sects(H5F_t *f, H5FS_t *fspace, H5MF_sect_iter_ud_t *sect_udata, size_t *nums)
{
hsize_t hnums = 0;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(sect_udata);
HDassert(nums);
HDassert(fspace);
if(H5FS_sect_stats(fspace, NULL, &hnums) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query free space stats")
H5_CHECKED_ASSIGN(*nums, size_t, hnums, hsize_t);
if(sect_udata->sects && *nums > 0)
if(H5FS_sect_iterate(f, fspace, H5MF__sects_cb, sect_udata) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_BADITER, FAIL, "can't iterate over sections")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5MF_settle_raw_data_fsm(H5F_t *f, hbool_t *fsm_settled)
{
int pass_count;
hsize_t alloc_size;
H5F_mem_t mem_type;
H5F_mem_page_t fsm_type;
H5O_fsinfo_t fsinfo;
H5FS_stat_t fs_stat;
H5AC_ring_t orig_ring = H5AC_RING_INV;
H5AC_ring_t curr_ring = H5AC_RING_INV;
H5AC_ring_t needed_ring = H5AC_RING_INV;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
HDassert(f);
HDassert(f->shared);
HDassert(fsm_settled);
HDmemset(&fsinfo, 0, sizeof(fsinfo));
HDmemset(&fs_stat, 0, sizeof(fs_stat));
if(f->shared->fs_persist && !f->shared->first_alloc_dealloc) {
hbool_t fsm_opened[H5F_MEM_PAGE_NTYPES];
hbool_t fsm_visited[H5F_MEM_PAGE_NTYPES];
HDassert(f->shared->sblock);
HDassert(H5F_INTENT(f) & H5F_ACC_RDWR);
HDassert(f->shared->sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2);
HDmemset(fsm_opened, 0, sizeof(fsm_opened));
HDmemset(fsm_visited, 0, sizeof(fsm_visited));
if(!H5F_PAGED_AGGR(f) && (H5MF_free_aggrs(f) < 0))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't free aggregators")
H5AC_set_ring(H5AC_RING_MDFSM, &orig_ring);
curr_ring = H5AC_RING_MDFSM;
for(pass_count = 0; pass_count <= 1; pass_count++) {
if(pass_count == 0)
alloc_size = 1;
else if ( H5F_PAGED_AGGR(f) )
alloc_size = f->shared->fs_page_size + 1;
else
break;
for(mem_type = H5FD_MEM_SUPER; mem_type < H5FD_MEM_NTYPES; mem_type++) {
H5MF__alloc_to_fs_type(f, mem_type, alloc_size, &fsm_type);
if(pass_count == 0) {
HDassert(fsm_type > H5F_MEM_PAGE_DEFAULT);
HDassert(fsm_type < H5F_MEM_PAGE_LARGE_SUPER);
}
else if(H5F_PAGED_AGGR(f)) {
HDassert(fsm_type >= H5F_MEM_PAGE_LARGE_SUPER);
HDassert(fsm_type < H5F_MEM_PAGE_NTYPES);
}
else
HDassert(FALSE);
if(!fsm_visited[fsm_type]) {
fsm_visited[fsm_type] = TRUE;
if(NULL == f->shared->fs_man[fsm_type]) {
if(H5F_addr_defined(f->shared->fs_addr[fsm_type])) {
HDassert(fsm_opened[fsm_type] == FALSE);
if(H5MF__open_fstype(f, fsm_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space manager")
fsm_opened[fsm_type] = TRUE;
}
}
if(f->shared->fs_man[fsm_type]) {
if(H5MF__fsm_type_is_self_referential(f, fsm_type))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
if(H5FS_stat_info(f, f->shared->fs_man[fsm_type], &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't get free-space info")
if(H5F_addr_defined(fs_stat.addr) || H5F_addr_defined(fs_stat.sect_addr)) {
if(H5FS_free(f, f->shared->fs_man[fsm_type], TRUE) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't release free-space headers")
f->shared->fs_addr[fsm_type] = HADDR_UNDEF;
}
}
}
}
}
if(H5F_addr_defined(f->shared->sblock->ext_addr))
if(H5F__super_ext_remove_msg(f, H5O_FSINFO_ID) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "error in removing message from superblock extension")
if(H5MF__close_shrink_eoa(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
for(fsm_type = H5F_MEM_PAGE_SUPER; fsm_type < H5F_MEM_PAGE_NTYPES; fsm_type++)
fsinfo.fs_addr[fsm_type - 1] = HADDR_UNDEF;
fsinfo.strategy = f->shared->fs_strategy;
fsinfo.persist = f->shared->fs_persist;
fsinfo.threshold = f->shared->fs_threshold;
fsinfo.page_size = f->shared->fs_page_size;
fsinfo.pgend_meta_thres = f->shared->pgend_meta_thres;
fsinfo.eoa_pre_fsm_fsalloc = HADDR_UNDEF;
if(H5F__super_ext_write_msg(f, H5O_FSINFO_ID, &fsinfo, TRUE, H5O_MSG_FLAG_MARK_IF_UNKNOWN) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "error in writing fsinfo message to superblock extension")
for(fsm_type = H5F_MEM_PAGE_SUPER; fsm_type < H5F_MEM_PAGE_NTYPES; fsm_type++)
fsm_visited[fsm_type] = FALSE;
for(pass_count = 0; pass_count <= 1; pass_count++) {
if(pass_count == 0)
alloc_size = 1;
else if(H5F_PAGED_AGGR(f))
alloc_size = f->shared->fs_page_size + 1;
else
break;
for(mem_type = H5FD_MEM_SUPER; mem_type < H5FD_MEM_NTYPES; mem_type++) {
H5MF__alloc_to_fs_type(f, mem_type, alloc_size, &fsm_type);
if(pass_count == 0) {
HDassert(fsm_type > H5F_MEM_PAGE_DEFAULT);
HDassert(fsm_type < H5F_MEM_PAGE_LARGE_SUPER);
}
else if(H5F_PAGED_AGGR(f)) {
HDassert(fsm_type >= H5F_MEM_PAGE_LARGE_SUPER);
HDassert(fsm_type < H5F_MEM_PAGE_NTYPES);
}
else
HDassert(FALSE);
if(H5MF__fsm_type_is_self_referential(f, fsm_type))
needed_ring = H5AC_RING_MDFSM;
else
needed_ring = H5AC_RING_RDFSM;
if(needed_ring != curr_ring) {
H5AC_set_ring(needed_ring, NULL);
curr_ring = needed_ring;
}
if(!fsm_visited[fsm_type]) {
fsm_visited[fsm_type] = TRUE;
if(f->shared->fs_man[fsm_type]) {
if(!H5MF__fsm_type_is_self_referential(f, fsm_type)) {
HDassert(curr_ring == H5AC_RING_RDFSM);
if(H5FS_stat_info(f, f->shared->fs_man[fsm_type], &fs_stat) < 0 )
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info")
if(fs_stat.serial_sect_count > 0) {
HDassert(!H5F_addr_defined(fs_stat.addr));
if(H5FS_alloc_hdr(f, f->shared->fs_man[fsm_type], &f->shared->fs_addr[fsm_type]) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocated free-space header")
HDassert(!H5F_addr_defined(fs_stat.sect_addr));
HDassert(fs_stat.alloc_sect_size == 0);
if(H5FS_alloc_sect(f, f->shared->fs_man[fsm_type]) < 0 )
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate free-space section info")
#ifndef NDEBUG
if(H5FS_stat_info(f, f->shared->fs_man[fsm_type], &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't get free-space info")
HDassert(H5F_addr_defined(fs_stat.addr));
HDassert(H5F_addr_defined(fs_stat.sect_addr));
HDassert(fs_stat.serial_sect_count > 0);
HDassert(fs_stat.alloc_sect_size > 0);
HDassert(fs_stat.alloc_sect_size == fs_stat.sect_size);
#endif
}
else {
HDassert(!H5F_addr_defined(fs_stat.addr));
HDassert(!H5F_addr_defined(fs_stat.sect_addr));
HDassert(fs_stat.serial_sect_count == 0);
HDassert(fs_stat.alloc_sect_size == 0);
}
}
}
if(fsm_opened[fsm_type]) {
if(H5MF__close_fstype(f, fsm_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't close file free space manager")
fsm_opened[fsm_type] = FALSE;
}
}
}
}
for(fsm_type = H5F_MEM_PAGE_SUPER; fsm_type < H5F_MEM_PAGE_NTYPES; fsm_type++)
HDassert(!fsm_opened[fsm_type]);
*fsm_settled = TRUE;
}
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
herr_t
H5MF_settle_meta_data_fsm(H5F_t *f, hbool_t *fsm_settled)
{
H5F_mem_page_t sm_fshdr_fs_type;
H5F_mem_page_t sm_fssinfo_fs_type;
H5F_mem_page_t lg_fshdr_fs_type;
H5F_mem_page_t lg_fssinfo_fs_type;
H5FS_t *sm_hdr_fspace = NULL;
H5FS_t *sm_sinfo_fspace = NULL;
H5FS_t *lg_hdr_fspace = NULL;
H5FS_t *lg_sinfo_fspace = NULL;
haddr_t eoa_pre_fsm_fsalloc;
haddr_t eoa_post_fsm_fsalloc;
H5AC_ring_t orig_ring = H5AC_RING_INV;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
HDassert(f);
HDassert(f->shared);
HDassert(fsm_settled);
if(f->shared->fs_persist && !f->shared->first_alloc_dealloc) {
HDassert(f->shared->lf);
HDassert(H5F_INTENT(f) & H5F_ACC_RDWR);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_HDR, (size_t)1, &sm_fshdr_fs_type);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_SINFO, (size_t)1, &sm_fssinfo_fs_type);
HDassert(sm_fshdr_fs_type > H5F_MEM_PAGE_DEFAULT);
HDassert(sm_fshdr_fs_type < H5F_MEM_PAGE_LARGE_SUPER);
HDassert(sm_fssinfo_fs_type > H5F_MEM_PAGE_DEFAULT);
HDassert(sm_fssinfo_fs_type < H5F_MEM_PAGE_LARGE_SUPER);
HDassert(!H5F_addr_defined(f->shared->fs_addr[sm_fshdr_fs_type]));
HDassert(!H5F_addr_defined(f->shared->fs_addr[sm_fssinfo_fs_type]));
sm_hdr_fspace = f->shared->fs_man[sm_fshdr_fs_type];
sm_sinfo_fspace = f->shared->fs_man[sm_fssinfo_fs_type];
if(H5F_PAGED_AGGR(f)) {
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_HDR, f->shared->fs_page_size + 1, &lg_fshdr_fs_type);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_SINFO, f->shared->fs_page_size + 1, &lg_fssinfo_fs_type);
HDassert(lg_fshdr_fs_type >= H5F_MEM_PAGE_LARGE_SUPER);
HDassert(lg_fshdr_fs_type < H5F_MEM_PAGE_NTYPES);
HDassert(lg_fssinfo_fs_type >= H5F_MEM_PAGE_LARGE_SUPER);
HDassert(lg_fssinfo_fs_type < H5F_MEM_PAGE_NTYPES);
HDassert(!H5F_addr_defined(f->shared->fs_addr[lg_fshdr_fs_type]));
HDassert(!H5F_addr_defined(f->shared->fs_addr[lg_fssinfo_fs_type]));
lg_hdr_fspace = f->shared->fs_man[lg_fshdr_fs_type];
lg_sinfo_fspace = f->shared->fs_man[lg_fssinfo_fs_type];
}
H5AC_set_ring(H5AC_RING_MDFSM, &orig_ring);
#ifndef NDEBUG
{
H5FS_stat_t fs_stat;
if(sm_hdr_fspace) {
if(H5FS_stat_info(f, sm_hdr_fspace, &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info")
HDassert(!H5F_addr_defined(fs_stat.addr));
HDassert(!H5F_addr_defined(fs_stat.sect_addr));
HDassert(fs_stat.alloc_sect_size == 0);
}
if((sm_sinfo_fspace) && (sm_hdr_fspace != sm_sinfo_fspace)) {
if(H5FS_stat_info(f, sm_sinfo_fspace, &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info")
HDassert(!H5F_addr_defined(fs_stat.addr));
HDassert(!H5F_addr_defined(fs_stat.sect_addr));
HDassert(fs_stat.alloc_sect_size == 0);
}
if(H5F_PAGED_AGGR(f)) {
if(lg_hdr_fspace) {
if(H5FS_stat_info(f, lg_hdr_fspace, &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info (3)")
HDassert(!H5F_addr_defined(fs_stat.addr));
HDassert(!H5F_addr_defined(fs_stat.sect_addr));
HDassert(fs_stat.alloc_sect_size == 0);
}
if((lg_sinfo_fspace) && (lg_hdr_fspace != lg_sinfo_fspace)) {
if(H5FS_stat_info(f, lg_sinfo_fspace, &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info (4)")
HDassert(!H5F_addr_defined(fs_stat.addr));
HDassert(!H5F_addr_defined(fs_stat.sect_addr));
HDassert(fs_stat.alloc_sect_size == 0);
}
}
}
#endif
if((!H5F_PAGED_AGGR(f)) && (H5MF_free_aggrs(f) < 0))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't free aggregators")
if(H5MF__close_shrink_eoa(f) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't shrink eoa")
if(HADDR_UNDEF == (eoa_pre_fsm_fsalloc = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get EOA")
if(sm_hdr_fspace)
if(H5FS_vfd_alloc_hdr_and_section_info_if_needed(f, sm_hdr_fspace, &(f->shared->fs_addr[sm_fshdr_fs_type])) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't vfd allocate sm hdr FSM file space")
if(sm_sinfo_fspace && (sm_sinfo_fspace != sm_hdr_fspace))
if(H5FS_vfd_alloc_hdr_and_section_info_if_needed(f, sm_sinfo_fspace, &(f->shared->fs_addr[sm_fssinfo_fs_type])) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't vfd allocate sm sinfo FSM file space")
if(H5F_PAGED_AGGR(f)) {
if(lg_hdr_fspace)
if(H5FS_vfd_alloc_hdr_and_section_info_if_needed(f, lg_hdr_fspace, &(f->shared->fs_addr[lg_fshdr_fs_type])) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't vfd allocate lg hdr FSM file space")
if(lg_sinfo_fspace && (lg_sinfo_fspace != lg_hdr_fspace))
if(H5FS_vfd_alloc_hdr_and_section_info_if_needed(f, lg_sinfo_fspace, &(f->shared->fs_addr[lg_fssinfo_fs_type])) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't vfd allocate lg sinfo FSM file space")
}
if(HADDR_UNDEF == (eoa_post_fsm_fsalloc = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size")
f->shared->eoa_pre_fsm_fsalloc = eoa_pre_fsm_fsalloc;
f->shared->eoa_post_fsm_fsalloc = eoa_post_fsm_fsalloc;
*fsm_settled = TRUE;
}
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
hbool_t
H5MF__fsm_type_is_self_referential(H5F_t *f, H5F_mem_page_t fsm_type)
{
H5F_mem_page_t sm_fshdr_fsm;
H5F_mem_page_t sm_fssinfo_fsm;
H5F_mem_page_t lg_fshdr_fsm;
H5F_mem_page_t lg_fssinfo_fsm;
hbool_t result = FALSE;
FUNC_ENTER_PACKAGE_NOERR
HDassert(f);
HDassert(f->shared);
HDassert(fsm_type >= H5F_MEM_PAGE_DEFAULT);
HDassert(fsm_type < H5F_MEM_PAGE_NTYPES);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_HDR, (size_t)1, &sm_fshdr_fsm);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_SINFO, (size_t)1, &sm_fssinfo_fsm);
if(H5F_PAGED_AGGR(f)) {
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_HDR, f->shared->fs_page_size + 1, &lg_fshdr_fsm);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_SINFO, f->shared->fs_page_size + 1, &lg_fssinfo_fsm);
result = (fsm_type == sm_fshdr_fsm) || (fsm_type == sm_fssinfo_fsm)
|| (fsm_type == lg_fshdr_fsm) || (fsm_type == lg_fssinfo_fsm);
}
else {
if(fsm_type >= H5F_MEM_PAGE_LARGE_SUPER)
result = FALSE;
else
result = (fsm_type == sm_fshdr_fsm) || (fsm_type == sm_fssinfo_fsm);
}
FUNC_LEAVE_NOAPI(result)
}
static hbool_t
H5MF__fsm_is_self_referential(H5F_t *f, H5FS_t *fspace)
{
H5F_mem_page_t sm_fshdr_fsm;
H5F_mem_page_t sm_fssinfo_fsm;
hbool_t result = FALSE;
FUNC_ENTER_STATIC_NOERR
HDassert(f);
HDassert(f->shared);
HDassert(fspace);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_HDR, (size_t)1, &sm_fshdr_fsm);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_SINFO, (size_t)1, &sm_fssinfo_fsm);
if(H5F_PAGED_AGGR(f)) {
H5F_mem_page_t lg_fshdr_fsm;
H5F_mem_page_t lg_fssinfo_fsm;
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_HDR, f->shared->fs_page_size + 1, &lg_fshdr_fsm);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_SINFO, f->shared->fs_page_size + 1, &lg_fssinfo_fsm);
result = (fspace == f->shared->fs_man[sm_fshdr_fsm]) ||
(fspace == f->shared->fs_man[sm_fssinfo_fsm]) ||
(fspace == f->shared->fs_man[lg_fshdr_fsm]) ||
(fspace == f->shared->fs_man[lg_fssinfo_fsm]);
}
else
result = (fspace == f->shared->fs_man[sm_fshdr_fsm]) ||
(fspace == f->shared->fs_man[sm_fssinfo_fsm]);
FUNC_LEAVE_NOAPI(result)
}
herr_t
H5MF_tidy_self_referential_fsm_hack(H5F_t *f)
{
haddr_t eoa;
hsize_t tail_size = 0;
H5AC_ring_t orig_ring = H5AC_RING_INV;
haddr_t first_srfsm_hdr = HADDR_UNDEF;
H5FS_stat_t fs_stat;
H5F_mem_page_t sm_fshdr_fs_type;
H5F_mem_page_t sm_fssinfo_fs_type;
H5F_mem_page_t lg_fshdr_fs_type;
H5F_mem_page_t lg_fssinfo_fs_type;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_TAG(H5AC__FREESPACE_TAG, FAIL)
HDassert(f);
HDassert(f->shared);
HDassert(f->shared->fs_persist);
HDassert(f->shared->first_alloc_dealloc);
H5AC_set_ring(H5AC_RING_MDFSM, &orig_ring);
HDassert(f->shared->first_alloc_dealloc);
f->shared->first_alloc_dealloc = FALSE;
if(HADDR_UNDEF == (eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get EOA")
HDassert(H5F_addr_le(f->shared->eoa_pre_fsm_fsalloc, eoa));
if(H5F_addr_eq(f->shared->eoa_pre_fsm_fsalloc, eoa))
HGOTO_DONE(SUCCEED)
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_HDR, (size_t)1, &sm_fshdr_fs_type);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_SINFO, (size_t)1, &sm_fssinfo_fs_type);
HDassert(sm_fshdr_fs_type > H5F_MEM_PAGE_DEFAULT);
HDassert(sm_fshdr_fs_type < H5F_MEM_PAGE_LARGE_SUPER);
HDassert(sm_fssinfo_fs_type > H5F_MEM_PAGE_DEFAULT);
HDassert(sm_fssinfo_fs_type < H5F_MEM_PAGE_LARGE_SUPER);
HDassert(NULL == f->shared->fs_man[sm_fshdr_fs_type]);
HDassert(NULL == f->shared->fs_man[sm_fssinfo_fs_type]);
if(H5F_addr_defined(f->shared->fs_addr[sm_fshdr_fs_type])) {
first_srfsm_hdr = f->shared->fs_addr[sm_fshdr_fs_type];
if(H5MF__open_fstype(f, sm_fshdr_fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space manager")
HDassert(f->shared->fs_man[sm_fshdr_fs_type]);
}
if((sm_fshdr_fs_type != sm_fssinfo_fs_type) &&
(H5F_addr_defined(f->shared->fs_addr[sm_fssinfo_fs_type]))) {
if(!H5F_addr_defined(first_srfsm_hdr) ||
(H5F_addr_defined(first_srfsm_hdr) &&
H5F_addr_lt(f->shared->fs_addr[sm_fssinfo_fs_type], first_srfsm_hdr)))
first_srfsm_hdr = f->shared->fs_addr[sm_fssinfo_fs_type];
HDassert(NULL == f->shared->fs_man[sm_fssinfo_fs_type]);
if(H5MF__open_fstype(f, sm_fssinfo_fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space manager")
HDassert(f->shared->fs_man[sm_fssinfo_fs_type]);
}
if(H5F_PAGED_AGGR(f)) {
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_HDR, f->shared->fs_page_size + 1, &lg_fshdr_fs_type);
H5MF__alloc_to_fs_type(f, H5FD_MEM_FSPACE_SINFO, f->shared->fs_page_size + 1, &lg_fssinfo_fs_type);
HDassert(lg_fshdr_fs_type >= H5F_MEM_PAGE_LARGE_SUPER);
HDassert(lg_fshdr_fs_type < H5F_MEM_PAGE_NTYPES);
HDassert(lg_fssinfo_fs_type >= H5F_MEM_PAGE_LARGE_SUPER);
HDassert(lg_fssinfo_fs_type < H5F_MEM_PAGE_NTYPES);
HDassert(NULL == f->shared->fs_man[lg_fshdr_fs_type]);
HDassert(NULL == f->shared->fs_man[lg_fssinfo_fs_type]);
if(H5F_addr_defined(f->shared->fs_addr[lg_fshdr_fs_type])) {
if(!H5F_addr_defined(first_srfsm_hdr) ||
(H5F_addr_defined(first_srfsm_hdr) &&
H5F_addr_lt(f->shared->fs_addr[lg_fshdr_fs_type], first_srfsm_hdr)))
first_srfsm_hdr = f->shared->fs_addr[lg_fshdr_fs_type];
HDassert(NULL == f->shared->fs_man[lg_fshdr_fs_type]);
if(H5MF__open_fstype(f, lg_fshdr_fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space manager")
HDassert(f->shared->fs_man[lg_fshdr_fs_type]);
}
if(lg_fshdr_fs_type != lg_fssinfo_fs_type && H5F_addr_defined(f->shared->fs_addr[lg_fssinfo_fs_type])) {
if(!H5F_addr_defined(first_srfsm_hdr) ||
(H5F_addr_defined(first_srfsm_hdr) &&
H5F_addr_lt(f->shared->fs_addr[lg_fssinfo_fs_type], first_srfsm_hdr)))
first_srfsm_hdr = f->shared->fs_addr[lg_fssinfo_fs_type];
HDassert(NULL == f->shared->fs_man[lg_fssinfo_fs_type]);
if(H5MF__open_fstype(f, lg_fssinfo_fs_type) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize file free space manager")
HDassert(f->shared->fs_man[lg_fssinfo_fs_type]);
}
}
HDassert(H5F_addr_eq(first_srfsm_hdr, f->shared->eoa_pre_fsm_fsalloc));
if(f->shared->fs_man[sm_fshdr_fs_type]) {
if(H5FS_stat_info(f, f->shared->fs_man[sm_fshdr_fs_type], &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't get free-space info")
HDassert(H5F_addr_defined(fs_stat.addr));
HDassert(H5F_addr_defined(fs_stat.sect_addr));
if(H5FS_free(f, f->shared->fs_man[sm_fshdr_fs_type], FALSE) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't release free-space headers")
f->shared->fs_addr[sm_fshdr_fs_type] = HADDR_UNDEF;
}
if(sm_fshdr_fs_type != sm_fssinfo_fs_type && f->shared->fs_man[sm_fssinfo_fs_type]) {
if(H5FS_stat_info(f, f->shared->fs_man[sm_fssinfo_fs_type], &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't get free-space info")
HDassert(H5F_addr_defined(fs_stat.addr));
HDassert(H5F_addr_defined(fs_stat.sect_addr));
if(H5FS_free(f, f->shared->fs_man[sm_fssinfo_fs_type], FALSE) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't release free-space headers")
f->shared->fs_addr[sm_fssinfo_fs_type] = HADDR_UNDEF;
}
if(H5F_PAGED_AGGR(f)) {
if(f->shared->fs_man[lg_fshdr_fs_type]) {
if(H5FS_stat_info(f, f->shared->fs_man[lg_fshdr_fs_type], &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info")
HDassert(H5F_addr_defined(fs_stat.addr));
HDassert(H5F_addr_defined(fs_stat.sect_addr));
if(H5FS_free(f, f->shared->fs_man[lg_fshdr_fs_type], FALSE) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't float free-space headers")
f->shared->fs_addr[lg_fshdr_fs_type] = HADDR_UNDEF;
}
if(lg_fshdr_fs_type != lg_fssinfo_fs_type && f->shared->fs_man[lg_fssinfo_fs_type]) {
if(H5FS_stat_info(f, f->shared->fs_man[lg_fssinfo_fs_type], &fs_stat) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't get free-space info")
HDassert(H5F_addr_defined(fs_stat.addr));
HDassert(H5F_addr_defined(fs_stat.sect_addr));
if(H5FS_free(f, f->shared->fs_man[lg_fssinfo_fs_type], FALSE) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't float free-space headers")
f->shared->fs_addr[lg_fssinfo_fs_type] = HADDR_UNDEF;
}
}
if(!H5F_PAGED_AGGR(f)) {
HDassert(f->shared->sdata_aggr.tot_size == 0);
HDassert(f->shared->sdata_aggr.addr == 0);
HDassert(f->shared->sdata_aggr.size == 0);
HDassert(f->shared->meta_aggr.tot_size == 0);
HDassert(f->shared->meta_aggr.addr == 0);
HDassert(f->shared->meta_aggr.size == 0);
}
tail_size = (hsize_t)(eoa - f->shared->eoa_pre_fsm_fsalloc);
if(H5F__free(f, H5FD_MEM_DEFAULT, f->shared->eoa_pre_fsm_fsalloc, tail_size) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "driver free request failed")
if(HADDR_UNDEF == (eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get EOA")
HDassert(H5F_addr_eq(f->shared->eoa_pre_fsm_fsalloc, eoa));
f->shared->eoa_pre_fsm_fsalloc = HADDR_UNDEF;
HDassert((!H5F_PAGED_AGGR(f)) || (0 == (eoa % f->shared->fs_page_size)));
done:
if(orig_ring != H5AC_RING_INV)
H5AC_set_ring(orig_ring, NULL);
FUNC_LEAVE_NOAPI_TAG(ret_value)
}