#include "H5Fmodule.h"
#include "H5private.h"
#include "H5Aprivate.h"
#include "H5ACprivate.h"
#include "H5CXprivate.h"
#include "H5Dprivate.h"
#include "H5Eprivate.h"
#include "H5Fpkg.h"
#include "H5FDprivate.h"
#include "H5Gprivate.h"
#include "H5Iprivate.h"
#include "H5Lprivate.h"
#include "H5MFprivate.h"
#include "H5MMprivate.h"
#include "H5Pprivate.h"
#include "H5SMprivate.h"
#include "H5Tprivate.h"
typedef struct H5F_olist_t {
H5I_type_t obj_type;
hid_t *obj_id_list;
size_t *obj_id_count;
struct {
hbool_t local;
union {
H5F_shared_t *shared;
const H5F_t *file;
} ptr;
} file_info;
size_t list_index;
size_t max_nobjs;
} H5F_olist_t;
static herr_t H5F__get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr);
static int H5F__get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
static herr_t H5F__build_name(const char *prefix, const char *file_name, char **full_name);
static char *H5F__getenv_prefix_name(char **env_prefix);
static herr_t H5F__check_if_using_file_locks(H5P_genplist_t *fapl, hbool_t *use_file_locking);
static herr_t H5F__build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, char ** actual_name);
static herr_t H5F__flush_phase1(H5F_t *f);
static herr_t H5F__flush_phase2(H5F_t *f, hbool_t closing);
hbool_t H5_PKG_INIT_VAR = FALSE;
htri_t use_locks_env_g = FAIL;
H5FL_DEFINE(H5F_t);
H5FL_DEFINE(H5F_shared_t);
static const H5I_class_t H5I_FILE_CLS[1] = {{
H5I_FILE,
0,
0,
(H5I_free_t)H5F__close_cb
}};
herr_t
H5F__init_package(void)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
if(H5I_register_type(H5I_FILE_CLS) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface")
if(H5F__parse_file_lock_env_var(&use_locks_env_g) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to parse file locking environment variable")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
int
H5F_term_package(void)
{
int n = 0;
FUNC_ENTER_NOAPI_NOINIT_NOERR
if(H5_PKG_INIT_VAR) {
if(H5I_nmembers(H5I_FILE) > 0) {
(void)H5I_clear_type(H5I_FILE, FALSE, FALSE);
n++;
}
else {
H5F_sfile_assert_num(0);
n += (H5I_dec_type_ref(H5I_FILE) > 0);
if(0 == n)
H5_PKG_INIT_VAR = FALSE;
}
}
FUNC_LEAVE_NOAPI(n)
}
herr_t
H5F__parse_file_lock_env_var(htri_t *use_locks)
{
char *lock_env_var = NULL;
FUNC_ENTER_PACKAGE_NOERR
lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
if(lock_env_var && (!HDstrcmp(lock_env_var, "FALSE") || !HDstrcmp(lock_env_var, "0")))
*use_locks = FALSE;
else if(lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "BEST_EFFORT") || !HDstrcmp(lock_env_var, "1")))
*use_locks = TRUE;
else
*use_locks = FAIL;
FUNC_LEAVE_NOAPI(SUCCEED)
}
hid_t
H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
{
H5P_genplist_t *new_plist;
H5P_genplist_t *old_plist;
H5FD_driver_prop_t driver_prop;
hbool_t driver_prop_copied = FALSE;
unsigned efc_size = 0;
hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_NOAPI(H5I_INVALID_HID)
HDassert(f);
if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_FILE_ACCESS_ID_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list")
if((ret_value = H5P_copy_plist(old_plist, app_ref)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "can't copy file access property list")
if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(ret_value)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list")
if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set initial metadata cache resize config.")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set data cache number of slots")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set data cache byte size")
if(H5P_set(new_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set preempt read chunks")
if(H5P_set(new_plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set alignment threshold")
if(H5P_set(new_plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set alignment")
if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set garbage collect reference")
if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set metadata cache size")
if(H5P_set(new_plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't sieve buffer size")
if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set 'small data' cache size")
if(H5P_set(new_plist, H5F_ACS_LIBVER_LOW_BOUND_NAME, &f->shared->low_bound) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set 'low' bound for library format versions")
if(H5P_set(new_plist, H5F_ACS_LIBVER_HIGH_BOUND_NAME, &f->shared->high_bound) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set 'high' bound for library format versions")
if(H5P_set(new_plist, H5F_ACS_METADATA_READ_ATTEMPTS_NAME, &(f->shared->read_attempts)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set 'read attempts ' flag")
if(H5P_set(new_plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &(f->shared->object_flush)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set object flush callback")
if(f->shared->efc)
efc_size = H5F__efc_max_nfiles(f->shared->efc);
if(H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set elink file cache size")
if(f->shared->page_buf != NULL) {
if(H5P_set(new_plist, H5F_ACS_PAGE_BUFFER_SIZE_NAME, &(f->shared->page_buf->max_size)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set page buffer size")
if(H5P_set(new_plist, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_NAME, &(f->shared->page_buf->min_meta_perc)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set minimum metadata fraction of page buffer")
if(H5P_set(new_plist, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_NAME, &(f->shared->page_buf->min_raw_perc)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set minimum raw data fraction of page buffer")
}
#ifdef H5_HAVE_PARALLEL
if(H5P_set(new_plist, H5_COLL_MD_READ_FLAG_NAME, &(f->coll_md_read)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set collective metadata read flag")
if(H5P_set(new_plist, H5F_ACS_COLL_MD_WRITE_FLAG_NAME, &(f->coll_md_write)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't set collective metadata read flag")
#endif
if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_IMAGE_CONFIG_NAME, &(f->shared->mdc_initCacheImageCfg)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set initial metadata cache resize config.")
driver_prop.driver_id = f->shared->lf->driver_id;
driver_prop.driver_info = H5FD_fapl_get(f->shared->lf);
driver_prop_copied = TRUE;
if(H5P_set(new_plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set file driver ID & info")
if(f->shared->fc_degree == H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->lf->cls->fc_degree)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set file close degree")
else if(f->shared->fc_degree != H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->fc_degree)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set file close degree")
done:
if(driver_prop_copied && H5FD_free_driver_info(driver_prop.driver_id, driver_prop.driver_info) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, H5I_INVALID_HID, "can't close copy of driver info")
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(obj_id_count_ptr);
if((ret_value = H5F__get_objects(f, types, 0, NULL, app_ref, obj_id_count_ptr)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F__get_objects failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(obj_id_count_ptr);
if((ret_value = H5F__get_objects(f, types, max_objs, oid_list, app_ref, obj_id_count_ptr)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F__get_objects failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5F__get_objects(const H5F_t *f, unsigned types, size_t max_nobjs, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr)
{
size_t obj_id_count = 0;
H5F_olist_t olist;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(obj_id_count_ptr);
olist.obj_id_list = (max_nobjs==0 ? NULL : obj_id_list);
olist.obj_id_count = &obj_id_count;
olist.list_index = 0;
olist.max_nobjs = max_nobjs;
if(types & H5F_OBJ_LOCAL) {
olist.file_info.local = TRUE;
olist.file_info.ptr.file = f;
}
else {
olist.file_info.local = FALSE;
olist.file_info.ptr.shared = f ? f->shared : NULL;
}
if(types & H5F_OBJ_FILE) {
olist.obj_type = H5I_FILE;
if(H5I_iterate(H5I_FILE, H5F__get_objects_cb, &olist, app_ref) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)")
}
if(!olist.max_nobjs || (olist.max_nobjs && olist.list_index<olist.max_nobjs)) {
if(types & H5F_OBJ_DATASET) {
olist.obj_type = H5I_DATASET;
if(H5I_iterate(H5I_DATASET, H5F__get_objects_cb, &olist, app_ref) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(2)")
}
}
if(!olist.max_nobjs || (olist.max_nobjs && olist.list_index<olist.max_nobjs)) {
if(types & H5F_OBJ_GROUP) {
olist.obj_type = H5I_GROUP;
if(H5I_iterate(H5I_GROUP, H5F__get_objects_cb, &olist, app_ref) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(3)")
}
}
if(!olist.max_nobjs || (olist.max_nobjs && olist.list_index<olist.max_nobjs)) {
if(types & H5F_OBJ_DATATYPE) {
olist.obj_type = H5I_DATATYPE;
if(H5I_iterate(H5I_DATATYPE, H5F__get_objects_cb, &olist, app_ref) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(4)")
}
}
if(!olist.max_nobjs || (olist.max_nobjs && olist.list_index<olist.max_nobjs)) {
if(types & H5F_OBJ_ATTR) {
olist.obj_type = H5I_ATTR;
if(H5I_iterate(H5I_ATTR, H5F__get_objects_cb, &olist, app_ref) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(5)")
}
}
*obj_id_count_ptr = obj_id_count;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static int
H5F__get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
{
H5F_olist_t *olist = (H5F_olist_t *)key;
hbool_t add_obj = FALSE;
int ret_value = H5_ITER_CONT;
FUNC_ENTER_STATIC
HDassert(obj_ptr);
HDassert(olist);
if(olist->obj_type == H5I_FILE) {
if((olist->file_info.local &&
(!olist->file_info.ptr.file ||
(olist->file_info.ptr.file && (H5F_t*)obj_ptr == olist->file_info.ptr.file))) ||
(!olist->file_info.local &&
(!olist->file_info.ptr.shared ||
(olist->file_info.ptr.shared && ((H5F_t*)obj_ptr)->shared == olist->file_info.ptr.shared)))) {
add_obj = TRUE;
}
}
else {
H5O_loc_t *oloc;
switch(olist->obj_type) {
case H5I_ATTR:
oloc = H5A_oloc((H5A_t *)obj_ptr);
break;
case H5I_GROUP:
oloc = H5G_oloc((H5G_t *)obj_ptr);
break;
case H5I_DATASET:
oloc = H5D_oloc((H5D_t *)obj_ptr);
break;
case H5I_DATATYPE:
if(H5T_is_named((H5T_t*)obj_ptr)==TRUE)
oloc = H5T_oloc((H5T_t*)obj_ptr);
else
oloc = NULL;
break;
case H5I_UNINIT:
case H5I_BADID:
case H5I_FILE:
case H5I_DATASPACE:
case H5I_REFERENCE:
case H5I_VFL:
case H5I_GENPROP_CLS:
case H5I_GENPROP_LST:
case H5I_ERROR_CLASS:
case H5I_ERROR_MSG:
case H5I_ERROR_STACK:
case H5I_NTYPES:
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "unknown or invalid data object")
}
if((olist->file_info.local &&
((!olist->file_info.ptr.file && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) ||
(!olist->file_info.ptr.file && olist->obj_type != H5I_DATATYPE) ||
(oloc && oloc->file == olist->file_info.ptr.file))) ||
(!olist->file_info.local &&
((!olist->file_info.ptr.shared && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) ||
(!olist->file_info.ptr.shared && olist->obj_type != H5I_DATATYPE) ||
(oloc && oloc->file && oloc->file->shared == olist->file_info.ptr.shared)))) {
add_obj = TRUE;
}
}
if(add_obj) {
if(olist->obj_id_list) {
olist->obj_id_list[olist->list_index] = obj_id;
olist->list_index++;
}
if(olist->obj_id_count)
(*olist->obj_id_count)++;
if(olist->max_nobjs > 0 && olist->list_index >= olist->max_nobjs)
HGOTO_DONE(H5_ITER_STOP)
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5F__build_name(const char *prefix, const char *file_name, char **full_name)
{
size_t prefix_len;
size_t fname_len;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
prefix_len = HDstrlen(prefix);
fname_len = HDstrlen(file_name);
if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2 + 2)))
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "unable to allocate filename buffer")
HDsnprintf(*full_name, (prefix_len + fname_len + 2 + 2), "%s%s%s", prefix,
((prefix_len == 0 || H5_CHECK_DELIMITER(prefix[prefix_len - 1])) ? "" : H5_DIR_SEPS), file_name);
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static char *
H5F__getenv_prefix_name(char **env_prefix)
{
char *strret;
char *ret_value = NULL;
FUNC_ENTER_STATIC_NOERR
ret_value = *env_prefix;
strret = HDstrchr(*env_prefix, H5_COLON_SEPC);
if(strret == NULL)
*env_prefix = NULL;
else {
*env_prefix = strret + 1;
*strret = '\0';
}
FUNC_LEAVE_NOAPI(ret_value)
}
H5F_t *
H5F_prefix_open_file(H5F_t *primary_file, H5F_prefix_open_t prefix_type,
const char *prop_prefix, const char *file_name, unsigned file_intent,
hid_t fapl_id)
{
H5F_t *src_file = NULL;
char *full_name = NULL;
char *actual_file_name = NULL;
char *temp_file_name = NULL;
size_t temp_file_name_len;
H5F_t *ret_value = NULL;
FUNC_ENTER_NOAPI_NOINIT
file_intent &= (H5F_ACC_RDWR | H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ);
if(NULL == (temp_file_name = H5MM_strdup(file_name)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
temp_file_name_len = HDstrlen(temp_file_name);
if(H5_CHECK_ABSOLUTE(file_name) || H5_CHECK_ABS_PATH(file_name)) {
src_file = H5F__efc_open(primary_file, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id);
if(NULL == src_file) {
char *ptr;
H5E_clear_stack(NULL);
H5_GET_LAST_DELIMITER(file_name, ptr)
HDassert(ptr);
ptr++;
HDstrncpy(temp_file_name, ptr, temp_file_name_len);
temp_file_name[temp_file_name_len - 1] = '\0';
}
}
else if(H5_CHECK_ABS_DRIVE(file_name)) {
src_file = H5F__efc_open(primary_file, file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id);
if(NULL == src_file) {
H5E_clear_stack(NULL);
HDstrncpy(temp_file_name, &file_name[2], temp_file_name_len);
temp_file_name[temp_file_name_len - 1] = '\0';
}
}
if(src_file == NULL) {
char *env_prefix;
if(H5F_PREFIX_VDS == prefix_type)
env_prefix = HDgetenv("HDF5_VDS_PREFIX");
else if(H5F_PREFIX_ELINK == prefix_type)
env_prefix = HDgetenv("HDF5_EXT_PREFIX");
else
HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, NULL, "prefix type is not sensible")
if(NULL != env_prefix) {
char *tmp_env_prefix, *saved_env;
if(NULL == (saved_env = tmp_env_prefix = H5MM_strdup(env_prefix)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
while((tmp_env_prefix) && (*tmp_env_prefix)) {
char *out_prefix_name;
out_prefix_name = H5F__getenv_prefix_name(&tmp_env_prefix);
if(out_prefix_name && (*out_prefix_name)) {
if(H5F__build_name(out_prefix_name, temp_file_name, &full_name) < 0) {
saved_env = (char *)H5MM_xfree(saved_env);
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename")
}
src_file = H5F__efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id);
full_name = (char *)H5MM_xfree(full_name);
if(NULL == src_file)
H5E_clear_stack(NULL);
else
break;
}
}
saved_env = (char *)H5MM_xfree(saved_env);
}
}
if(src_file == NULL && prop_prefix) {
if(H5F__build_name(prop_prefix, temp_file_name, &full_name) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename")
src_file = H5F__efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id);
full_name = (char *)H5MM_xfree(full_name);
if(NULL == src_file)
H5E_clear_stack(NULL);
}
if(src_file == NULL) {
char *dspath;
if(NULL != (dspath = H5F_EXTPATH(primary_file))) {
if(H5F__build_name(dspath, temp_file_name, &full_name) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename")
src_file = H5F__efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id);
full_name = (char *)H5MM_xfree(full_name);
if(NULL == src_file)
H5E_clear_stack(NULL);
}
}
if(src_file == NULL) {
src_file = H5F__efc_open(primary_file, temp_file_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id);
if(NULL == src_file)
H5E_clear_stack(NULL);
}
if(src_file == NULL) {
char *ptr = NULL;
if(NULL == (actual_file_name = H5MM_strdup(H5F_ACTUAL_NAME(primary_file))))
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't duplicate resolved file name string")
H5_GET_LAST_DELIMITER(actual_file_name, ptr)
if(!ptr)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file, file name = '%s', temp_file_name = '%s'", file_name, temp_file_name)
*ptr = '\0';
if(H5F__build_name(actual_file_name, temp_file_name, &full_name) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't prepend prefix to filename")
actual_file_name = (char *)H5MM_xfree(actual_file_name);
src_file = H5F__efc_open(primary_file, full_name, file_intent, H5P_FILE_CREATE_DEFAULT, fapl_id);
full_name = (char *)H5MM_xfree(full_name);
if(NULL == src_file)
H5E_clear_stack(NULL);
}
ret_value = src_file;
done:
if((NULL == ret_value) && src_file)
if(H5F_efc_close(primary_file, src_file) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "can't close source file")
if(full_name)
full_name = (char *)H5MM_xfree(full_name);
if(temp_file_name)
temp_file_name = (char *)H5MM_xfree(temp_file_name);
if(actual_file_name)
actual_file_name = (char *)H5MM_xfree(actual_file_name);
FUNC_LEAVE_NOAPI(ret_value)
}
htri_t
H5F__is_hdf5(const char *name)
{
H5FD_t *file = NULL;
haddr_t sig_addr = HADDR_UNDEF;
htri_t ret_value = FAIL;
FUNC_ENTER_PACKAGE
if(NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to open file")
if(H5FD_locate_signature(file, &sig_addr) < 0)
HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "error while trying to locate file signature")
ret_value = (HADDR_UNDEF != sig_addr);
done:
if(file)
if(H5FD_close(file) < 0 && TRUE == ret_value)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
FUNC_LEAVE_NOAPI(ret_value)
}
H5F_t *
H5F__new(H5F_shared_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
{
H5F_t *f = NULL;
H5F_t *ret_value = NULL;
FUNC_ENTER_PACKAGE
if(NULL == (f = H5FL_CALLOC(H5F_t)))
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate top file structure")
f->file_id = H5I_INVALID_HID;
if(shared) {
HDassert(lf == NULL);
f->shared = shared;
}
else {
H5P_genplist_t *plist;
unsigned efc_size;
size_t u;
HDassert(lf != NULL);
if(NULL == (f->shared = H5FL_CALLOC(H5F_shared_t)))
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure")
f->shared->flags = flags;
f->shared->sohm_addr = HADDR_UNDEF;
f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION;
f->shared->accum.loc = HADDR_UNDEF;
f->shared->lf = lf;
for(u = 0; u < NELMTS(f->shared->fs_addr); u++) {
f->shared->fs_state[u] = H5F_FS_STATE_CLOSED;
f->shared->fs_addr[u] = HADDR_UNDEF;
f->shared->fs_man[u] = NULL;
}
f->shared->first_alloc_dealloc = FALSE;
f->shared->eoa_pre_fsm_fsalloc = HADDR_UNDEF;
f->shared->eoa_post_fsm_fsalloc = HADDR_UNDEF;
f->shared->eoa_post_mdci_fsalloc = HADDR_UNDEF;
f->shared->pgend_meta_thres = H5F_FILE_SPACE_PGEND_META_THRES;
f->shared->point_of_no_return = FALSE;
if(NULL == (plist = (H5P_genplist_t *)H5I_object(fcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list")
f->shared->fcpl_id = H5P_copy_plist(plist, FALSE);
if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &f->shared->sizeof_addr) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for address")
if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &f->shared->sizeof_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size")
if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes")
HDassert(f->shared->sohm_nindexes < 255);
if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &f->shared->fs_strategy) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space strategy")
if(H5P_get(plist, H5F_CRT_FREE_SPACE_PERSIST_NAME, &f->shared->fs_persist) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space persisting status")
if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &f->shared->fs_threshold) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get free-space section threshold")
if(H5P_get(plist, H5F_CRT_FILE_SPACE_PAGE_SIZE_NAME, &f->shared->fs_page_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space page size")
HDassert(f->shared->fs_page_size >= H5F_FILE_SPACE_PAGE_SIZE_MIN);
if(H5F_HAS_FEATURE(f, H5FD_FEAT_PAGED_AGGR))
if(f->shared->fs_strategy == H5F_FSPACE_STRATEGY_PAGE || f->shared->fs_persist)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't open with this strategy or persistent fs")
if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache number of slots")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache byte size")
if(H5P_get(plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get preempt read chunk")
if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold")
if(H5P_get(plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment")
if(H5P_get(plist, H5F_ACS_GARBG_COLCT_REF_NAME,&(f->shared->gc_ref)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get garbage collect reference")
if(H5P_get(plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size")
if(H5P_get(plist, H5F_ACS_LIBVER_LOW_BOUND_NAME, &(f->shared->low_bound)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'low' bound for library format versions")
if(H5P_get(plist, H5F_ACS_LIBVER_HIGH_BOUND_NAME, &(f->shared->high_bound)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'high' bound for library format versions")
if(H5P_get(plist, H5F_ACS_USE_MDC_LOGGING_NAME, &(f->shared->use_mdc_logging)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'use mdc logging' flag")
if(H5P_get(plist, H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME, &(f->shared->start_mdc_log_on_access)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'start mdc log on access' flag")
if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache size")
f->shared->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA;
if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' cache size")
f->shared->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA;
if(H5P_get(plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get elink file cache size")
if(efc_size > 0)
if(NULL == (f->shared->efc = H5F__efc_create(efc_size)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache")
#ifdef H5_HAVE_PARALLEL
if(H5P_get(plist, H5_COLL_MD_READ_FLAG_NAME, &(f->coll_md_read)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get collective metadata read flag")
if(H5P_get(plist, H5F_ACS_COLL_MD_WRITE_FLAG_NAME, &(f->coll_md_write)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get collective metadata write flag")
#endif
if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_IMAGE_CONFIG_NAME, &(f->shared->mdc_initCacheImageCfg)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config")
f->shared->maxaddr = H5FD_get_maxaddr(lf);
if(!H5F_addr_defined(f->shared->maxaddr))
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD")
if(H5FD_get_feature_flags(lf, &f->shared->feature_flags) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get feature flags from VFD")
if(!H5F_HAS_FEATURE(f, H5FD_FEAT_SUPPORTS_SWMR_IO) && (H5F_INTENT(f) & (H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ)))
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "must use a SWMR-compatible VFD when SWMR is specified")
if(H5FD_get_fs_type_map(lf, f->shared->fs_type_map) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get free space type mapping from VFD")
if(H5MF_init_merge_flags(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "problem initializing free space merge flags")
f->shared->tmp_addr = f->shared->maxaddr;
f->shared->use_tmp_space = !H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI);
if(H5P_get(plist, H5F_ACS_METADATA_READ_ATTEMPTS_NAME, &f->shared->read_attempts) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get the # of read attempts")
if(H5F_INTENT(f) & (H5F_ACC_SWMR_READ | H5F_ACC_SWMR_WRITE)) {
if(!f->shared->read_attempts)
f->shared->read_attempts = H5F_SWMR_METADATA_READ_ATTEMPTS;
f->shared->feature_flags &= ~(unsigned)H5FD_FEAT_ACCUMULATE_METADATA;
if(H5FD_set_feature_flags(f->shared->lf, f->shared->feature_flags) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set feature_flags in VFD")
}
else {
if(!f->shared->read_attempts)
f->shared->read_attempts = H5F_METADATA_READ_ATTEMPTS;
}
if(H5F_set_retries(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't set retries and retries_nbins")
{
char *mdc_log_location = NULL;
if(H5P_get(plist, H5F_ACS_MDC_LOG_LOCATION_NAME, &mdc_log_location) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get mdc log location")
if(mdc_log_location != NULL) {
size_t len = HDstrlen(mdc_log_location);
if(NULL == (f->shared->mdc_log_location = (char *)H5MM_calloc((len + 1) * sizeof(char))))
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate memory for mdc log file name")
HDstrncpy(f->shared->mdc_log_location, mdc_log_location, len);
}
else
f->shared->mdc_log_location = NULL;
}
if(H5P_get(plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &(f->shared->object_flush)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get object flush cb info")
if(H5AC_create(f, &(f->shared->mdc_initCacheCfg), &(f->shared->mdc_initCacheImageCfg)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create metadata cache")
if(H5FO_create(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure")
if(H5F__sfile_add(f->shared) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to append to list of open files")
}
f->shared->nrefs++;
if(H5FO_top_create(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure")
ret_value = f;
done:
if(!ret_value && f) {
if(!shared) {
if(f->shared->efc)
if(H5F__efc_destroy(f->shared->efc) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, NULL, "can't destroy external file cache")
if(f->shared->fcpl_id > 0)
if(H5I_dec_ref(f->shared->fcpl_id) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTDEC, NULL, "can't close property list")
f->shared = H5FL_FREE(H5F_shared_t, f->shared);
}
f = H5FL_FREE(H5F_t, f);
}
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__dest(H5F_t *f, hbool_t flush)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
if(1 == f->shared->nrefs) {
int actype;
if((H5F_ACC_RDWR & H5F_INTENT(f)) && flush)
if(H5F__flush_phase1(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush cached data (phase 1)")
if(H5AC_prep_for_file_close(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "metadata cache prep for close failed")
if((H5F_ACC_RDWR & H5F_INTENT(f)) && flush)
if(H5F__flush_phase2(f, TRUE) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush cached data (phase 2)")
HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
if(f->shared->efc) {
if(H5F__efc_destroy(f->shared->efc) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't destroy external file cache")
f->shared->efc = NULL;
}
HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
if(f->shared->sblock) {
if(H5F_ACC_RDWR & H5F_INTENT(f)) {
if(H5MF_close(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info")
HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
if(flush) {
f->shared->sblock->status_flags &= (uint8_t)(~H5F_SUPER_WRITE_ACCESS);
f->shared->sblock->status_flags &= (uint8_t)(~H5F_SUPER_SWMR_WRITE_ACCESS);
if(H5F_eoa_dirty(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
if(H5MF_free_aggrs(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space")
if(H5FD_truncate(f->shared->lf, TRUE) < 0)
HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed")
HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
}
}
if(f->shared->drvinfo)
if(H5AC_unpin_entry(f->shared->drvinfo) < 0)
HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin drvinfo")
if(H5AC_unpin_entry(f->shared->sblock) < 0)
HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock")
f->shared->sblock = NULL;
}
HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
if(H5F__sfile_remove(f->shared) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
if(H5AC_dest(f))
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
if(H5PB_dest(f->shared) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing page buffer cache")
if(f->shared->mdc_log_location)
f->shared->mdc_log_location = (char *)H5MM_xfree(f->shared->mdc_log_location);
if(f->shared->root_grp) {
if(H5G_root_free(f->shared->root_grp) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
f->shared->root_grp = NULL;
}
if(H5F__accum_reset(f->shared, TRUE) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
if(H5FO_dest(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
f->shared->cwfs = (struct H5HG_heap_t **)H5MM_xfree(f->shared->cwfs);
if(H5G_node_close(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file")
if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id))
HDONE_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a property list")
if(H5I_dec_ref(f->shared->fcpl_id) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close property list")
if(H5FD_close(f->shared->lf) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child);
f->shared->mtab.nalloc = 0;
for(actype = 0; actype < (int)H5AC_NTYPES; actype++)
if(f->shared->retries[actype])
f->shared->retries[actype] = (uint32_t *)H5MM_xfree(f->shared->retries[actype]);
f->shared = (H5F_shared_t *)H5FL_FREE(H5F_shared_t, f->shared);
}
else if(f->shared->nrefs > 0) {
--f->shared->nrefs;
}
f->open_name = (char *)H5MM_xfree(f->open_name);
f->actual_name = (char *)H5MM_xfree(f->actual_name);
f->extpath = (char *)H5MM_xfree(f->extpath);
if(H5FO_top_dest(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file")
f->shared = NULL;
f = H5FL_FREE(H5F_t, f);
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5F__check_if_using_file_locks(H5P_genplist_t *fapl, hbool_t *use_file_locking)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
*use_file_locking = TRUE;
if(H5P_get(fapl, H5F_ACS_USE_FILE_LOCKING_NAME, use_file_locking) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get use file locking flag")
if(use_locks_env_g != FAIL)
*use_file_locking = (use_locks_env_g == TRUE) ? TRUE : FALSE;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
H5F_t *
H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
{
H5F_t *file = NULL;
H5F_shared_t *shared = NULL;
H5FD_t *lf = NULL;
unsigned tent_flags;
H5FD_class_t *drvr;
H5P_genplist_t *a_plist;
H5F_close_degree_t fc_degree;
size_t page_buf_size;
unsigned page_buf_min_meta_perc = 0;
unsigned page_buf_min_raw_perc = 0;
hbool_t set_flag = FALSE;
hbool_t clear = FALSE;
hbool_t evict_on_close;
hbool_t use_file_locking = TRUE;
hbool_t ci_load = FALSE;
hbool_t ci_write = FALSE;
H5F_t *ret_value = NULL;
FUNC_ENTER_NOAPI(NULL)
if(NULL == (drvr = H5FD_get_class(fapl_id)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class")
if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
if (H5F__check_if_using_file_locks(a_plist, &use_file_locking) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get file locking flag")
if(drvr->cmp)
tent_flags = flags & ~(H5F_ACC_CREAT|H5F_ACC_TRUNC|H5F_ACC_EXCL);
else
tent_flags = flags;
if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) {
if(tent_flags == flags) {
#ifndef H5_USING_MEMCHECKER
time_t mytime = HDtime(NULL);
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags)
#else
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags)
#endif
}
H5E_clear_stack(NULL);
tent_flags = flags;
if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) {
#ifndef H5_USING_MEMCHECKER
time_t mytime = HDtime(NULL);
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags)
#else
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags)
#endif
}
}
if((shared = H5F__sfile_search(lf)) != NULL) {
if(H5FD_close(lf) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info")
if(flags & H5F_ACC_TRUNC)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open")
if(flags & H5F_ACC_EXCL)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists")
if((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only")
if((flags & H5F_ACC_SWMR_WRITE) && 0 == (shared->flags & H5F_ACC_SWMR_WRITE))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "SWMR write access flag not the same for file that is already open")
if((flags & H5F_ACC_SWMR_READ) && !((shared->flags & H5F_ACC_SWMR_WRITE) || (shared->flags & H5F_ACC_SWMR_READ) || (shared->flags & H5F_ACC_RDWR)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "SWMR read access flag not the same for file that is already open")
if((file = H5F__new(shared, flags, fcpl_id, fapl_id, NULL)) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object")
}
else {
if(flags != tent_flags) {
if(H5FD_close(lf) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info")
if(NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
}
if(use_file_locking)
if(H5FD_lock(lf, (hbool_t)((flags & H5F_ACC_RDWR) ? TRUE : FALSE)) < 0) {
if(H5FD_close(lf) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "unable to close low-level file info")
HGOTO_ERROR(H5E_FILE, H5E_CANTLOCKFILE, NULL, "unable to lock the file")
}
if(NULL == (file = H5F__new(NULL, flags, fcpl_id, fapl_id, lf))) {
if(H5FD_close(lf) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info")
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to initialize file structure")
}
if(drvr->lock)
set_flag = TRUE;
}
if(H5C_cache_image_status(file, &ci_load, &ci_write) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get MDC cache image status")
if((ci_load || ci_write) && (flags & (H5F_ACC_SWMR_READ | H5F_ACC_SWMR_WRITE)))
HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, NULL, "can't have both SWMR and cache image")
file->open_name = H5MM_xstrdup(name);
shared = file->shared;
lf = shared->lf;
if(shared->nrefs == 1)
file->shared->use_file_locking = use_file_locking;
else if(shared->nrefs > 1)
if(file->shared->use_file_locking != use_file_locking)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file locking flag values don't match")
if(H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_SIZE_NAME, &page_buf_size) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get page buffer size")
if(page_buf_size) {
#ifdef H5_HAVE_PARALLEL
if(file->coll_md_write)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "collective metadata writes are not supported with page buffering")
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "page buffering is disabled for parallel")
#endif
if(H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_MIN_META_PERC_NAME, &page_buf_min_meta_perc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get minimum metadata fraction of page buffer")
if(H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_NAME, &page_buf_min_raw_perc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get minimum raw data fraction of page buffer")
}
if(0 == (MAX(H5FD_get_eof(lf, H5FD_MEM_SUPER), H5FD_get_eoa(lf, H5FD_MEM_SUPER))) && (flags & H5F_ACC_RDWR)) {
if(page_buf_size)
if(H5PB_create(shared, page_buf_size, page_buf_min_meta_perc, page_buf_min_raw_perc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create page buffer")
if(H5F__super_init(file) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to allocate file superblock")
if(H5G_mkroot(file, TRUE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group")
}
else if(1 == shared->nrefs) {
if(H5F__super_read(file, a_plist, TRUE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")
if(page_buf_size)
if(H5PB_create(shared, page_buf_size, page_buf_min_meta_perc, page_buf_min_raw_perc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create page buffer")
if(H5G_mkroot(file, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group")
}
if(H5P_get(a_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file close degree")
if(shared->nrefs == 1) {
if(fc_degree == H5F_CLOSE_DEFAULT)
shared->fc_degree = lf->cls->fc_degree;
else
shared->fc_degree = fc_degree;
}
else if(shared->nrefs > 1) {
if(fc_degree == H5F_CLOSE_DEFAULT && shared->fc_degree != lf->cls->fc_degree)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match")
if(fc_degree != H5F_CLOSE_DEFAULT && fc_degree != shared->fc_degree)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match")
}
if(H5P_exist_plist(a_plist, H5F_ACS_CLEAR_STATUS_FLAGS_NAME) > 0) {
if(H5P_get(a_plist, H5F_ACS_CLEAR_STATUS_FLAGS_NAME, &clear) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get clearance for status_flags")
else if(clear)
file->shared->sblock->status_flags = 0;
}
if(H5P_get(a_plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, &evict_on_close) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get evict on close value")
if(shared->nrefs == 1)
shared->evict_on_close = evict_on_close;
else if(shared->nrefs > 1) {
if(shared->evict_on_close != evict_on_close)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "file evict-on-close value doesn't match")
}
if(H5_build_extpath(name, &file->extpath) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath")
if(H5F__build_actual_name(file, a_plist, name, &file->actual_name) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name")
if(set_flag) {
if(H5F_INTENT(file) & H5F_ACC_RDWR) {
if(file->shared->sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_3) {
if(file->shared->sblock->status_flags & H5F_SUPER_WRITE_ACCESS ||
file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for write/SWMR write (may use <h5clear file> to clear file consistency flags)")
}
file->shared->sblock->status_flags |= H5F_SUPER_WRITE_ACCESS;
if(H5F_INTENT(file) & H5F_ACC_SWMR_WRITE)
file->shared->sblock->status_flags |= H5F_SUPER_SWMR_WRITE_ACCESS;
if(H5F_super_dirty(file) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, NULL, "unable to mark superblock as dirty")
if(H5F_flush_tagged_metadata(file, H5AC__SUPERBLOCK_TAG) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, NULL, "unable to flush superblock")
if(H5F_flush_tagged_metadata(file, file->shared->sblock->ext_addr) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, NULL, "unable to flush superblock extension")
if(use_file_locking && (H5F_INTENT(file) & H5F_ACC_SWMR_WRITE)) {
if(H5FD_unlock(file->shared->lf) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTUNLOCKFILE, NULL, "unable to unlock the file")
}
}
else {
if(file->shared->sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_3) {
if(H5F_INTENT(file) & H5F_ACC_SWMR_READ) {
if((file->shared->sblock->status_flags & H5F_SUPER_WRITE_ACCESS &&
!(file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS))
||
(!(file->shared->sblock->status_flags & H5F_SUPER_WRITE_ACCESS) &&
file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is not already open for SWMR writing")
}
else if((file->shared->sblock->status_flags & H5F_SUPER_WRITE_ACCESS) ||
(file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for write (may use <h5clear file> to clear file consistency flags)")
}
}
}
ret_value = file;
done:
if((NULL == ret_value) && file)
if(H5F__dest(file, FALSE) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file")
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5F__flush_phase1(H5F_t *f)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(f);
if(H5D_flush_all(f) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache")
if(H5MF_free_aggrs(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space")
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5F__flush_phase2(H5F_t *f, hbool_t closing)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(f);
if(H5AC_prep_for_file_flush(f) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "prep for MDC flush failed")
if(H5AC_flush(f) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache")
#ifdef H5_HAVE_PARALLEL
if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) {
H5CX_set_mpi_file_flushing(TRUE);
}
#endif
if(H5FD_truncate(f->shared->lf, closing) < 0)
HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed")
if(H5AC_flush(f) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache")
#ifdef H5_HAVE_PARALLEL
if(H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI))
H5CX_set_mpi_file_flushing(FALSE);
#endif
if(H5AC_secure_from_file_flush(f) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "secure from MDC flush failed")
if(H5F__accum_flush(f->shared) < 0)
HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator")
if(H5PB_flush(f->shared) < 0)
HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "page buffer flush failed")
if(H5FD_flush(f->shared->lf, closing) < 0)
HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "low level flush failed")
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__flush(H5F_t *f)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
if(H5F__flush_phase1(f) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush file data")
if(H5F__flush_phase2(f, FALSE) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush file data")
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__close(hid_t file_id)
{
H5F_t *f;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
if(NULL == (f = (H5F_t *)H5I_object(file_id)))
HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "invalid file identifier")
if((f->shared->nrefs > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) {
int nref;
if((nref = H5I_get_ref(file_id, FALSE)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get ID ref count")
if(nref == 1)
if(H5F__flush(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
}
if(H5I_dec_app_ref(file_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "decrementing file ID failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__close_cb(H5F_t *f)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->file_id > 0);
if(f->shared->fc_degree == H5F_CLOSE_SEMI) {
unsigned nopen_files = 0;
unsigned nopen_objs = 0;
if(H5F__mount_count_ids(f, &nopen_files, &nopen_objs) < 0)
HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy")
if(nopen_files == 1 && nopen_objs > 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open")
}
f->file_id = H5I_INVALID_HID;
if(H5F_try_close(f, NULL) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F_try_close(H5F_t *f, hbool_t *was_closed )
{
unsigned nopen_files = 0;
unsigned nopen_objs = 0;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
HDassert(f);
HDassert(f->shared);
if(was_closed)
*was_closed = FALSE;
if(f->closing) {
if(was_closed)
*was_closed = TRUE;
HGOTO_DONE(SUCCEED)
}
if(H5F__mount_count_ids(f, &nopen_files, &nopen_objs) < 0)
HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy")
switch(f->shared->fc_degree) {
case H5F_CLOSE_WEAK:
if((nopen_files + nopen_objs) > 0)
HGOTO_DONE(SUCCEED)
break;
case H5F_CLOSE_SEMI:
if(nopen_files > 0)
HGOTO_DONE(SUCCEED)
HDassert(nopen_files == 0 && nopen_objs == 0);
break;
case H5F_CLOSE_STRONG:
if(nopen_files > 0)
HGOTO_DONE(SUCCEED)
break;
case H5F_CLOSE_DEFAULT:
default:
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, unknown file close degree")
}
f->closing = TRUE;
if(f->shared->fc_degree == H5F_CLOSE_STRONG) {
HDassert(nopen_files == 0);
if(f->nopen_objs > 0) {
size_t obj_count;
hid_t objs[128];
herr_t result;
size_t u;
while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_ATTR, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0
&& obj_count != 0 ) {
for(u = 0; u < obj_count; u++)
if(H5I_dec_ref(objs[u]) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
}
if(result < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(1)")
while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATATYPE, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0
&& obj_count != 0) {
for(u = 0; u < obj_count; u++)
if(H5I_dec_ref(objs[u]) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
}
if(result < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(2)")
}
}
if(f->parent)
if(H5F_try_close(f->parent, NULL) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file")
if(H5F__close_mounts(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files")
if(f->shared->efc && (f->shared->nrefs > 1))
if(H5F__efc_try_close(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't attempt to close EFC")
if(H5F__dest(f, TRUE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file")
if(was_closed)
*was_closed = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
hid_t
H5F_get_id(H5F_t *file, hbool_t app_ref)
{
hid_t ret_value = H5I_INVALID_HID;
FUNC_ENTER_NOAPI_NOINIT
HDassert(file);
if(file->file_id == H5I_INVALID_HID) {
if((file->file_id = H5I_register(H5I_FILE, file, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file")
}
else {
if(H5I_inc_ref(file->file_id, app_ref) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTINC, H5I_INVALID_HID, "incrementing file ID failed")
}
ret_value = file->file_id;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
unsigned
H5F_incr_nopen_objs(H5F_t *f)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
FUNC_LEAVE_NOAPI(++f->nopen_objs)
}
unsigned
H5F_decr_nopen_objs(H5F_t *f)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
FUNC_LEAVE_NOAPI(--f->nopen_objs)
}
static herr_t
H5F__build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name,
char **actual_name)
{
hid_t new_fapl_id = H5I_INVALID_HID;
#ifdef H5_HAVE_SYMLINK
char *realname = NULL;
#endif
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(f);
HDassert(fapl);
HDassert(name);
HDassert(actual_name);
*actual_name = NULL;
#ifdef H5_HAVE_SYMLINK
if(H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE)) {
h5_stat_t lst;
if(HDlstat(name, &lst) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stat info for file")
if(S_IFLNK == (lst.st_mode & S_IFMT)) {
H5P_genplist_t *new_fapl;
int *fd;
h5_stat_t st;
h5_stat_t fst;
hbool_t want_posix_fd;
if(NULL == (realname = (char *)H5MM_calloc((size_t)PATH_MAX * sizeof(char))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
if((new_fapl_id = H5P_copy_plist(fapl, FALSE)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy file access property list")
if(NULL == (new_fapl = (H5P_genplist_t *)H5I_object(new_fapl_id)))
HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "can't get property list")
want_posix_fd = TRUE;
if(H5P_set(new_fapl, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding")
if(H5F_get_vfd_handle(f, new_fapl_id, (void **)&fd) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve POSIX file descriptor")
if(HDstat(name, &st) < 0)
HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat file")
if(HDfstat(*fd, &fst) < 0)
HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to fstat file")
if(st.st_mode != fst.st_mode || st.st_ino != fst.st_ino || st.st_dev != fst.st_dev)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "files' st_ino or st_dev fields changed!")
if(NULL == HDrealpath(name, realname))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve real path for file")
if(NULL == (*actual_name = (char *)H5MM_strdup(realname)))
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate real path")
}
}
#endif
if(NULL == *actual_name) {
if(NULL == (*actual_name = (char *)H5MM_strdup(name)))
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate open name")
}
done:
if(new_fapl_id > 0)
if(H5I_dec_app_ref(new_fapl_id) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close duplicated FAPL")
#ifdef H5_HAVE_SYMLINK
if(realname)
realname = (char *)H5MM_xfree(realname);
#endif
FUNC_LEAVE_NOAPI(ret_value)
}
void
H5F_addr_encode_len(size_t addr_len, uint8_t **pp, haddr_t addr)
{
unsigned u;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(addr_len);
HDassert(pp && *pp);
if(H5F_addr_defined(addr)) {
for(u = 0; u < addr_len; u++) {
*(*pp)++ = (uint8_t)(addr & 0xff);
addr >>= 8;
}
HDassert("overflow" && 0 == addr);
}
else {
for(u = 0; u < addr_len; u++)
*(*pp)++ = 0xff;
}
FUNC_LEAVE_NOAPI_VOID
}
void
H5F_addr_encode(const H5F_t *f, uint8_t **pp, haddr_t addr)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
H5F_addr_encode_len(H5F_SIZEOF_ADDR(f), pp, addr);
FUNC_LEAVE_NOAPI_VOID
}
void
H5F_addr_decode_len(size_t addr_len, const uint8_t **pp, haddr_t *addr_p)
{
hbool_t all_zero = TRUE;
unsigned u;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(addr_len);
HDassert(pp && *pp);
HDassert(addr_p);
*addr_p = 0;
for(u = 0; u < addr_len; u++) {
uint8_t c;
c = *(*pp)++;
if(c != 0xff)
all_zero = FALSE;
if(u < sizeof(*addr_p)) {
haddr_t tmp = c;
tmp <<= (u * 8);
*addr_p |= tmp;
}
else
if(!all_zero)
HDassert(0 == **pp);
}
if(all_zero)
*addr_p = HADDR_UNDEF;
FUNC_LEAVE_NOAPI_VOID
}
void
H5F_addr_decode(const H5F_t *f, const uint8_t **pp, haddr_t *addr_p)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
H5F_addr_decode_len(H5F_SIZEOF_ADDR(f), pp, addr_p);
FUNC_LEAVE_NOAPI_VOID
}
herr_t
H5F_set_grp_btree_shared(H5F_t *f, H5UC_t *rc)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
HDassert(f->shared);
HDassert(rc);
f->shared->grp_btree_shared = rc;
FUNC_LEAVE_NOAPI(SUCCEED)
}
herr_t
H5F_set_sohm_addr(H5F_t *f, haddr_t addr)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
HDassert(f->shared);
f->shared->sohm_addr = addr;
FUNC_LEAVE_NOAPI(SUCCEED)
}
herr_t
H5F_set_sohm_vers(H5F_t *f, unsigned vers)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
HDassert(f->shared);
f->shared->sohm_vers = vers;
FUNC_LEAVE_NOAPI(SUCCEED)
}
herr_t
H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
HDassert(f->shared);
f->shared->sohm_nindexes = nindexes;
FUNC_LEAVE_NOAPI(SUCCEED)
}
herr_t
H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
HDassert(f->shared);
f->shared->store_msg_crt_idx = flag;
FUNC_LEAVE_NOAPI(SUCCEED)
}
herr_t
H5F__set_libver_bounds(H5F_t *f, H5F_libver_t low, H5F_libver_t high)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
if(f->shared->low_bound != low || f->shared->high_bound != high) {
if(H5F__flush(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information")
f->shared->low_bound = low;
f->shared->high_bound = high;
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
ssize_t
H5F__get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len)
{
H5FD_t *fd_ptr;
haddr_t eoa;
ssize_t ret_value = -1;
FUNC_ENTER_PACKAGE
if(!file || !file->shared || !file->shared->lf)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "file_id yields invalid file pointer")
fd_ptr = file->shared->lf;
if(!fd_ptr->cls)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "fd_ptr yields invalid class pointer")
if(HDstrcmp(fd_ptr->cls->name, "multi") == 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "Not supported for multi file driver.")
if(HDstrcmp(fd_ptr->cls->name, "family") == 0)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "Not supported for family file driver.")
if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file size")
ret_value = (ssize_t)eoa;
if(buf_ptr != NULL) {
size_t space_needed;
unsigned tmp, tmp_size;
if((haddr_t)buf_len < eoa)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, (-1), "supplied buffer too small")
space_needed = (size_t)eoa;
if(H5FD_read(fd_ptr, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0)
HGOTO_ERROR(H5E_FILE, H5E_READERROR, (-1), "file image read request failed")
tmp = H5F_SUPER_STATUS_FLAGS_OFF(file->shared->sblock->super_vers);
tmp_size = H5F_SUPER_STATUS_FLAGS_SIZE(file->shared->sblock->super_vers);
HDmemset((uint8_t *)buf_ptr + tmp, 0, tmp_size);
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__get_info(H5F_t *f, H5F_info2_t *finfo)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
HDassert(finfo);
HDmemset(finfo, 0, sizeof(*finfo));
if(H5F__super_size(f, &finfo->super.super_size, &finfo->super.super_ext_size) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve superblock sizes")
if(H5MF_get_freespace(f, &finfo->free.tot_space, &finfo->free.meta_size) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve free space information")
if(H5F_addr_defined(f->shared->sohm_addr))
if(H5SM_ih_size(f, &finfo->sohm.hdr_size, &finfo->sohm.msgs_info) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve SOHM index & heap storage info")
finfo->super.version = f->shared->sblock->super_vers;
finfo->sohm.version = f->shared->sohm_vers;
finfo->free.version = HDF5_FREESPACE_VERSION;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F_track_metadata_read_retries(H5F_t *f, unsigned actype, unsigned retries)
{
unsigned log_ind;
double tmp;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(f);
HDassert(f->shared->read_attempts > 1);
HDassert(f->shared->retries_nbins > 0);
HDassert(retries > 0);
HDassert(retries < f->shared->read_attempts);
HDassert(actype < H5AC_NTYPES);
if(NULL == f->shared->retries[actype])
if(NULL == (f->shared->retries[actype] = (uint32_t *)H5MM_calloc((size_t)f->shared->retries_nbins * sizeof(uint32_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
tmp = HDlog10((double)retries);
log_ind = (unsigned)tmp;
HDassert(log_ind < f->shared->retries_nbins);
f->shared->retries[actype][log_ind]++;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F_set_retries(H5F_t *f)
{
double tmp;
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
HDmemset(f->shared->retries, 0, sizeof(f->shared->retries));
f->shared->retries_nbins = 0;
if(f->shared->read_attempts > 1) {
tmp = HDceil(HDlog10((double)f->shared->read_attempts));
f->shared->retries_nbins = (unsigned)tmp;
}
FUNC_LEAVE_NOAPI(SUCCEED)
}
herr_t
H5F_object_flush_cb(H5F_t *f, hid_t obj_id)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(f);
HDassert(f->shared);
if(f->shared->object_flush.func && f->shared->object_flush.func(obj_id, f->shared->object_flush.udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "object flush callback returns error")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__set_base_addr(const H5F_t *f, haddr_t addr)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
if(H5FD_set_base_addr(f->shared->lf, addr) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set_base_addr request failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__set_eoa(const H5F_t *f, H5F_mem_t type, haddr_t addr)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
if(H5FD_set_eoa(f->shared->lf, type, addr) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set_eoa request failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__set_paged_aggr(const H5F_t *f, hbool_t paged)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
if(H5FD_set_paged_aggr(f->shared->lf, paged) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set paged aggr mode failed")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__get_max_eof_eoa(const H5F_t *f, haddr_t *max_eof_eoa)
{
haddr_t eof;
haddr_t eoa;
haddr_t tmp_max;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT);
eof = H5FD_get_eof(f->shared->lf, H5FD_MEM_DEFAULT);
tmp_max = MAX(eof, eoa);
if(HADDR_UNDEF == tmp_max)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file get eof/eoa requests failed")
*max_eof_eoa = tmp_max;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
#ifdef H5_HAVE_PARALLEL
void
H5F_set_coll_md_read(H5F_t *f, H5P_coll_md_read_flag_t cmr)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
f->coll_md_read = cmr;
FUNC_LEAVE_NOAPI_VOID
}
#endif
herr_t
H5F__get_metadata_read_retry_info(H5F_t *file, H5F_retry_info_t *info)
{
unsigned i, j;
size_t tot_size;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(file);
HDassert(info);
info->nbins = file->shared->retries_nbins;
HDmemset(info->retries, 0, sizeof(info->retries));
if(!info->nbins)
HGOTO_DONE(SUCCEED);
tot_size = info->nbins * sizeof(uint32_t);
j = 0;
for(i = 0; i < H5AC_NTYPES; i++) {
switch (i) {
case H5AC_OHDR_ID:
case H5AC_OHDR_CHK_ID:
case H5AC_BT2_HDR_ID:
case H5AC_BT2_INT_ID:
case H5AC_BT2_LEAF_ID:
case H5AC_FHEAP_HDR_ID:
case H5AC_FHEAP_DBLOCK_ID:
case H5AC_FHEAP_IBLOCK_ID:
case H5AC_FSPACE_HDR_ID:
case H5AC_FSPACE_SINFO_ID:
case H5AC_SOHM_TABLE_ID:
case H5AC_SOHM_LIST_ID:
case H5AC_EARRAY_HDR_ID:
case H5AC_EARRAY_IBLOCK_ID:
case H5AC_EARRAY_SBLOCK_ID:
case H5AC_EARRAY_DBLOCK_ID:
case H5AC_EARRAY_DBLK_PAGE_ID:
case H5AC_FARRAY_HDR_ID:
case H5AC_FARRAY_DBLOCK_ID:
case H5AC_FARRAY_DBLK_PAGE_ID:
case H5AC_SUPERBLOCK_ID:
HDassert(j < H5F_NUM_METADATA_READ_RETRY_TYPES);
if(file->shared->retries[i] != NULL) {
if(NULL == (info->retries[j] = (uint32_t *)H5MM_malloc(tot_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
H5MM_memcpy(info->retries[j], file->shared->retries[i], tot_size);
}
j++;
break;
default:
break;
}
}
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__start_swmr_write(H5F_t *f)
{
hbool_t ci_load = FALSE;
hbool_t ci_write = FALSE;
size_t grp_dset_count = 0;
size_t nt_attr_count = 0;
hid_t *obj_ids = NULL;
H5G_loc_t *obj_glocs = NULL;
H5O_loc_t *obj_olocs = NULL;
H5G_name_t *obj_paths = NULL;
size_t u;
hbool_t setup = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
if((H5F_INTENT(f) & H5F_ACC_RDWR) == 0)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "no write intent on file")
if(f->shared->sblock->super_vers < HDF5_SUPERBLOCK_VERSION_3)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file superblock version - should be at least 3")
if((f->shared->low_bound != H5F_LIBVER_V110) || (f->shared->high_bound != H5F_LIBVER_V110))
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file format version does not support SWMR - needs to be 1.10 or greater")
if(f->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file already in SWMR writing mode")
if(H5C_cache_image_status(f, &ci_load, &ci_write) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MDC cache image status")
if(ci_load || ci_write )
HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL, "can't have both SWMR and MDC cache image")
if(H5F_flush_tagged_metadata(f, f->shared->sblock->ext_addr) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock extension")
if(H5F__flush(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information")
if(H5F_get_obj_count(f, H5F_OBJ_DATATYPE | H5F_OBJ_ATTR, FALSE, &nt_attr_count) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
if(nt_attr_count > 0)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "named datatypes and/or attributes opened in the file")
if(H5F_get_obj_count(f, H5F_OBJ_GROUP | H5F_OBJ_DATASET, FALSE, &grp_dset_count) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
if(grp_dset_count > 0) {
if((obj_ids = (hid_t *) H5MM_malloc(grp_dset_count * sizeof(hid_t))) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for hid_t")
if((obj_glocs = (H5G_loc_t *) H5MM_malloc(grp_dset_count * sizeof(H5G_loc_t))) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_loc_t")
if((obj_olocs = (H5O_loc_t *) H5MM_malloc(grp_dset_count * sizeof(H5O_loc_t))) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5O_loc_t")
if((obj_paths = (H5G_name_t *) H5MM_malloc(grp_dset_count * sizeof(H5G_name_t))) == NULL)
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_name_t")
if(H5F_get_obj_ids(f, H5F_OBJ_GROUP|H5F_OBJ_DATASET, grp_dset_count, obj_ids, FALSE, &grp_dset_count) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "H5F_get_obj_ids failed")
for(u = 0; u < grp_dset_count; u++) {
H5O_loc_t *oloc;
H5G_loc_t tmp_loc;
obj_glocs[u].oloc = &obj_olocs[u];
obj_glocs[u].path = &obj_paths[u];
H5G_loc_reset(&obj_glocs[u]);
if((oloc = H5O_get_loc(obj_ids[u])) == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object")
H5G_loc(obj_ids[u], &tmp_loc);
H5G_loc_copy(&obj_glocs[u], &tmp_loc, H5_COPY_DEEP);
if(H5I_dec_ref(obj_ids[u]) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEOBJ, FAIL, "decrementing object ID failed")
}
}
if(H5F__accum_reset(f->shared, TRUE) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTRESET, FAIL, "can't reset accumulator")
f->shared->flags |= H5F_ACC_SWMR_WRITE;
f->shared->sblock->status_flags |= H5F_SUPER_SWMR_WRITE_ACCESS;
f->shared->read_attempts = H5F_SWMR_METADATA_READ_ATTEMPTS;
if(H5F_set_retries(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't set retries and retries_nbins")
f->shared->feature_flags &= ~(unsigned)H5FD_FEAT_ACCUMULATE_METADATA;
if(H5FD_set_feature_flags(f->shared->lf, f->shared->feature_flags) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set feature_flags in VFD")
setup = TRUE;
if(H5F_USE_FILE_LOCKING(f))
if(H5FD_lock(f->shared->lf, TRUE) < 0) {
HGOTO_ERROR(H5E_FILE, H5E_CANTLOCKFILE, FAIL, "unable to lock the file")
}
if(H5F_super_dirty(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
if(H5F_flush_tagged_metadata(f, H5AC__SUPERBLOCK_TAG) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock")
if(H5F__evict_cache_entries(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to evict file's cached information")
for(u = 0; u < grp_dset_count; u++)
if(H5O_refresh_metadata_reopen(obj_ids[u], &obj_glocs[u], TRUE) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't refresh-close object")
done:
if(ret_value < 0 && setup) {
f->shared->feature_flags |= (unsigned)H5FD_FEAT_ACCUMULATE_METADATA;
if(H5FD_set_feature_flags(f->shared->lf, f->shared->feature_flags) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set feature_flags in VFD")
f->shared->read_attempts = H5F_METADATA_READ_ATTEMPTS;
if(H5F_set_retries(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't set retries and retries_nbins")
f->shared->flags &= ~H5F_ACC_SWMR_WRITE;
f->shared->sblock->status_flags &= (uint8_t)(~H5F_SUPER_SWMR_WRITE_ACCESS);
if(H5F_super_dirty(f) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
if(H5F_flush_tagged_metadata(f, H5AC__SUPERBLOCK_TAG) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock")
}
if(H5F_USE_FILE_LOCKING(f))
if(H5FD_unlock(f->shared->lf) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTUNLOCKFILE, FAIL, "unable to unlock the file")
if(obj_ids)
H5MM_xfree(obj_ids);
if(obj_glocs)
H5MM_xfree(obj_glocs);
if(obj_olocs)
H5MM_xfree(obj_olocs);
if(obj_paths)
H5MM_xfree(obj_paths);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F__format_convert(H5F_t *f)
{
hbool_t mark_dirty = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(f);
HDassert(f->shared);
if(f->shared->sblock->super_vers > HDF5_SUPERBLOCK_VERSION_V18_LATEST) {
f->shared->sblock->super_vers = HDF5_SUPERBLOCK_VERSION_V18_LATEST;
mark_dirty = TRUE;
}
if(!(f->shared->fs_strategy == H5F_FILE_SPACE_STRATEGY_DEF &&
f->shared->fs_persist == H5F_FREE_SPACE_PERSIST_DEF &&
f->shared->fs_threshold == H5F_FREE_SPACE_THRESHOLD_DEF &&
f->shared->fs_page_size == H5F_FILE_SPACE_PAGE_SIZE_DEF)) {
if(H5F_addr_defined(f->shared->sblock->ext_addr))
if(H5F__super_ext_remove_msg(f, H5O_FSINFO_ID) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "error in removing message from superblock extension")
if(H5MF_try_close(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to free free-space address")
f->shared->fs_strategy = H5F_FILE_SPACE_STRATEGY_DEF;
f->shared->fs_persist = H5F_FREE_SPACE_PERSIST_DEF;
f->shared->fs_threshold = H5F_FREE_SPACE_THRESHOLD_DEF;
f->shared->fs_page_size = H5F_FILE_SPACE_PAGE_SIZE_DEF;
mark_dirty = TRUE;
}
if(mark_dirty)
if(H5F_super_dirty(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5F_set_min_dset_ohdr(H5F_t *f, hbool_t minimize)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(f);
HDassert(f->shared);
f->shared->crt_dset_min_ohdr_flag = minimize;
FUNC_LEAVE_NOAPI(SUCCEED)
}