diff options
Diffstat (limited to 'src/H5F.c')
-rw-r--r-- | src/H5F.c | 2003 |
1 files changed, 654 insertions, 1349 deletions
@@ -29,6 +29,7 @@ #include "H5FDprivate.h" /* File drivers */ #include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ #include "H5SMprivate.h" /* Shared Object Header Messages */ @@ -42,7 +43,7 @@ #include "H5FDmulti.h" /*multiple files partitioned by mem usage */ #include "H5FDsec2.h" /*Posix unbuffered I/O */ #include "H5FDstdio.h" /* Standard C buffered I/O */ -#ifdef H5_HAVE_WINDOWS +#ifdef H5_HAVE_WINDOWS #include "H5FDwindows.h" /* Windows buffered I/O */ #endif #include "H5FDdirect.h" /*Linux direct I/O */ @@ -51,7 +52,7 @@ typedef struct H5F_olist_t { H5I_type_t obj_type; /* Type of object to look for */ hid_t *obj_id_list; /* Pointer to the list of open IDs to return */ - unsigned *obj_id_count; /* Number of open IDs */ + size_t *obj_id_count; /* Number of open IDs */ struct { hbool_t local; /* Set flag for "local" file searches */ union { @@ -59,18 +60,18 @@ typedef struct H5F_olist_t { const H5F_t *file; /* Pointer to file to look inside */ } ptr; } file_info; - unsigned list_index; /* Current index in open ID array */ - int max_index; /* Maximum # of IDs to put into array */ + size_t list_index; /* Current index in open ID array */ + size_t max_index; /* Maximum # of IDs to put into array */ } H5F_olist_t; /* PRIVATE PROTOTYPES */ -static unsigned H5F_get_objects(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list); +static size_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref); static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key); -static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_handle); static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf); +static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, + const char *name, char ** /*out*/ actual_name); static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id); -static herr_t H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags); static herr_t H5F_close(H5F_t *f); /* Declare a free list to manage the H5F_t struct */ @@ -164,7 +165,7 @@ H5F_term_interface(void) if(H5_interface_initialize_g) { if((n = H5I_nmembers(H5I_FILE)) != 0) { - H5I_clear_type(H5I_FILE, FALSE); + H5I_clear_type(H5I_FILE, FALSE, FALSE); } else { /* Make certain we've cleaned up all the shared file objects */ H5F_sfile_assert_num(0); @@ -205,13 +206,13 @@ H5Fget_create_plist(hid_t file_id) H5TRACE1("i", "i", file_id); /* check args */ - if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - if(NULL == (plist = H5I_object(file->shared->fcpl_id))) + if(NULL == (plist = (H5P_genplist_t *)H5I_object(file->shared->fcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Create the property list object to return */ - if((ret_value = H5P_copy_plist(plist)) < 0) + if((ret_value = H5P_copy_plist(plist, TRUE)) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file creation properties") done: @@ -250,11 +251,11 @@ H5Fget_access_plist(hid_t file_id) H5TRACE1("i", "i", file_id); /* Check args */ - if(NULL == (f = H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") /* Retrieve the file's access property list */ - if((ret_value = H5F_get_access_plist(f)) < 0) + if((ret_value = H5F_get_access_plist(f, TRUE)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list") done: @@ -286,7 +287,7 @@ done: *------------------------------------------------------------------------- */ hid_t -H5F_get_access_plist(H5F_t *f) +H5F_get_access_plist(H5F_t *f, hbool_t app_ref) { H5P_genplist_t *new_plist; /* New property list */ H5P_genplist_t *old_plist; /* Old property list */ @@ -299,18 +300,18 @@ H5F_get_access_plist(H5F_t *f) HDassert(f); /* Make a copy of the default file access property list */ - if(NULL == (old_plist = H5I_object(H5P_LST_FILE_ACCESS_g))) + if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_FILE_ACCESS_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - if((ret_value = H5P_copy_plist(old_plist)) < 0) + if((ret_value = H5P_copy_plist(old_plist, app_ref)) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy file access property list") - if(NULL == (new_plist = H5I_object(ret_value))) + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(ret_value))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Copy properties of the file access property list */ if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.") - if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache element size") + if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "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_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size") if(H5P_set(new_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) @@ -321,11 +322,11 @@ H5F_get_access_plist(H5F_t *f) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment") if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set garbage collect reference") - if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->lf->meta_aggr.alloc_size)) < 0) + if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "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_PLIST, H5E_CANTSET, FAIL, "can't sieve buffer size") - if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->lf->sdata_aggr.alloc_size)) < 0) + if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size") if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") @@ -338,7 +339,7 @@ H5F_get_access_plist(H5F_t *f) HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't free the old driver information") /* Increment the reference count on the driver ID and insert it into the property list */ - if(H5I_inc_ref(f->shared->lf->driver_id) < 0) + if(H5I_inc_ref(f->shared->lf->driver_id, FALSE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver") if(H5P_set(new_plist, H5F_ACS_FILE_DRV_ID_NAME, &(f->shared->lf->driver_id)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver ID") @@ -370,31 +371,34 @@ done: * * Programmer: Raymond Lu * Wednesday, Dec 5, 2001 - * * Modification: + * Raymond Lu + * 24 September 2008 + * Changed the return value to ssize_t to accommadate + * potential large number of objects. * *------------------------------------------------------------------------- */ -int +ssize_t H5Fget_obj_count(hid_t file_id, unsigned types) { - H5F_t *f=NULL; - int ret_value; /* Return value */ + H5F_t *f = NULL; /* File to query */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API(H5Fget_obj_count, FAIL) - H5TRACE2("Is", "iIu", file_id, types); + H5TRACE2("Zs", "iIu", file_id, types); - if( file_id != (hid_t)H5F_OBJ_ALL && (NULL==(f=H5I_object_verify(file_id,H5I_FILE))) ) + if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id") - if( (types&H5F_OBJ_ALL)==0) + if(0 == (types & H5F_OBJ_ALL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type") - if((ret_value = H5F_get_obj_count(f, types)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOUNT, FAIL, "can't get object count") + /* H5F_get_obj_count doesn't fail */ + ret_value = (ssize_t)H5F_get_obj_count(f, types, TRUE); done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Fget_obj_count() */ /*------------------------------------------------------------------------- @@ -403,23 +407,28 @@ done: * Purpose: Private function return the number of opened object IDs * (files, datasets, groups, datatypes) in the same file. * - * Return: Non-negative on success; negative on failure. + * Return: Non-negative on success; can't fail. * * Programmer: Raymond Lu * Wednesday, Dec 5, 2001 * * Modification: + * Raymond Lu + * 24 September 2008 + * Changed the return value to size_t to accommadate + * potential large number of objects. * *------------------------------------------------------------------------- */ -unsigned -H5F_get_obj_count(const H5F_t *f, unsigned types) +size_t +H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref) { - unsigned ret_value; /* Return value */ + size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_count) - ret_value=H5F_get_objects(f, types, -1, NULL); + /* H5F_get_objects doesn't fail */ + ret_value = H5F_get_objects(f, types, 0, NULL, app_ref); FUNC_LEAVE_NOAPI(ret_value) } @@ -436,29 +445,34 @@ H5F_get_obj_count(const H5F_t *f, unsigned types) * Wednesday, Dec 5, 2001 * * Modification: + * Raymond Lu + * 24 September 2008 + * Changed the return value to ssize_t and MAX_OBJTS to size_t to + * accommadate potential large number of objects. * *------------------------------------------------------------------------- */ -herr_t -H5Fget_obj_ids(hid_t file_id, unsigned types, int max_objs, hid_t *oid_list) +ssize_t +H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list) { - herr_t ret_value; - H5F_t *f=NULL; + H5F_t *f = NULL; /* File to query */ + ssize_t ret_value; /* Return value */ FUNC_ENTER_API(H5Fget_obj_ids, FAIL) - H5TRACE4("e", "iIuIs*i", file_id, types, max_objs, oid_list); + H5TRACE4("Zs", "iIuz*i", file_id, types, max_objs, oid_list); - if( file_id != (hid_t)H5F_OBJ_ALL && (NULL==(f=H5I_object_verify(file_id,H5I_FILE))) ) + if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id") - if( (types&H5F_OBJ_ALL)==0) + if(0 == (types & H5F_OBJ_ALL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type") - assert(oid_list); - - ret_value = H5F_get_obj_ids(f, types, max_objs, oid_list); + HDassert(oid_list); + + /* H5F_get_objects doesn't fail */ + ret_value = (ssize_t)H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE); done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Fget_obj_ids() */ /*------------------------------------------------------------------------- @@ -466,23 +480,28 @@ done: * * Purpose: Private function to return a list of opened object IDs. * - * Return: Non-negative on success; negative on failure. + * Return: Non-negative on success; can't fail. * * Programmer: Raymond Lu * Wednesday, Dec 5, 2001 * * Modification: + * Raymond Lu + * 24 September 2008 + * Changed the return value and MAX_OBJTS to size_t to accommadate + * potential large number of objects. * *------------------------------------------------------------------------- */ -unsigned -H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *oid_list) +size_t +H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref) { - unsigned ret_value; /* Return value */ + size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_ids) - ret_value = H5F_get_objects(f, types, max_objs, oid_list); + /* H5F_get_objects doesn't fail */ + ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref); FUNC_LEAVE_NOAPI(ret_value) } @@ -494,21 +513,19 @@ H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *oid_list) * Purpose: This function is called by H5F_get_obj_count or * H5F_get_obj_ids to get number of object IDs and/or a * list of opened object IDs (in return value). - * Return: Non-negative on success; negative on failure. + * Return: Non-negative on success; Can't fail. * * Programmer: Raymond Lu * Wednesday, Dec 5, 2001 * - * Modification: - * *--------------------------------------------------------------------------- */ -static unsigned -H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_list) +static size_t +H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref) { - unsigned obj_id_count=0; /* Number of open IDs */ + size_t obj_id_count=0; /* Number of open IDs */ H5F_olist_t olist; /* Structure to hold search results */ - unsigned ret_value; /* Return value */ + size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_objects) @@ -519,7 +536,7 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis olist.max_index = max_index; /* Determine if we are searching for local or global objects */ - if(types&H5F_OBJ_LOCAL) { + if(types & H5F_OBJ_LOCAL) { olist.file_info.local = TRUE; olist.file_info.ptr.file = f; } /* end if */ @@ -529,45 +546,46 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis } /* end else */ /* Search through file IDs to count the number, and put their - * IDs on the object list */ + * IDs on the object list. H5I_search returns NULL if no object + * is found, so don't return failure in this function. */ if(types & H5F_OBJ_FILE) { olist.obj_type = H5I_FILE; - (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist, app_ref); } /* end if */ /* Search through dataset IDs to count number of datasets, and put their * IDs on the object list */ - if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_DATASET) ) { + if(types & H5F_OBJ_DATASET) { olist.obj_type = H5I_DATASET; - (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref); } /* Search through group IDs to count number of groups, and put their * IDs on the object list */ - if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_GROUP) ) { + if(types & H5F_OBJ_GROUP) { olist.obj_type = H5I_GROUP; - (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref); } /* Search through datatype IDs to count number of named datatypes, and put their * IDs on the object list */ - if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_DATATYPE) ) { + if(types & H5F_OBJ_DATATYPE) { olist.obj_type = H5I_DATATYPE; - (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref); } /* Search through attribute IDs to count number of attributes, and put their * IDs on the object list */ - if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_ATTR) ) { + if(types & H5F_OBJ_ATTR) { olist.obj_type = H5I_ATTR; - (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist); + (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref); } /* Set the number of objects currently open */ ret_value = obj_id_count; FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5F_get_objects() */ /*------------------------------------------------------------------------- @@ -577,6 +595,9 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis * object is in the file, and either count it or put its ID * on the list. * + * Return: TRUE if the array of object IDs is filled up. + * FALSE otherwise. + * * Programmer: Raymond Lu * Wednesday, Dec 5, 2001 * @@ -592,8 +613,8 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) FUNC_ENTER_NOAPI_NOINIT(H5F_get_objects_cb) - assert(obj_ptr); - assert(olist); + HDassert(obj_ptr); + HDassert(olist); /* Count file IDs */ if(olist->obj_type == H5I_FILE) { @@ -611,60 +632,71 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) if(olist->obj_id_count) (*olist->obj_id_count)++; - /* Check if we've filled up the array */ - if(olist->max_index>=0 && (int)olist->list_index>=olist->max_index) + /* Check if we've filled up the array. Return TRUE only if + * we have filled up the array. Otherwise return FALSE(RET_VALUE is + * preset to FALSE) because H5I_search needs the return value of FALSE + * to continue searching. */ + if(olist->max_index>0 && olist->list_index>=olist->max_index) HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ } - } else { /* either count opened object IDs or put the IDs on the list */ + } /* end if */ + else { /* either count opened object IDs or put the IDs on the list */ H5O_loc_t *oloc; /* Group entry info for object */ switch(olist->obj_type) { case H5I_ATTR: - oloc = H5A_oloc((H5A_t*)obj_ptr); + oloc = H5A_oloc((H5A_t *)obj_ptr); break; + case H5I_GROUP: - oloc = H5G_oloc((H5G_t*)obj_ptr); + oloc = H5G_oloc((H5G_t *)obj_ptr); break; + case H5I_DATASET: - oloc = H5D_oloc((H5D_t*)obj_ptr); + 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; + default: HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object") - } + } /* end switch */ 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.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) ))) { + ((!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 the object's ID to the ID list, if appropriate */ if(olist->obj_id_list) { olist->obj_id_list[olist->list_index] = obj_id; olist->list_index++; - } + } /* end if */ /* Increment the number of open objects */ if(olist->obj_id_count) (*olist->obj_id_count)++; - /* Check if we've filled up the array */ - if(olist->max_index>=0 && (int)olist->list_index>=olist->max_index) + /* Check if we've filled up the array. Return TRUE only if + * we have filled up the array. Otherwise return FALSE(RET_VALUE is + * preset to FALSE) because H5I_search needs the return value of FALSE + * to continue searching. */ + if(olist->max_index>0 && olist->list_index>=olist->max_index) HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ - } - } + } /* end if */ + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5F_get_objects_cb() */ /*------------------------------------------------------------------------- @@ -674,68 +706,37 @@ done: * driver. * * Return: Success: non-negative value. - * - * Failture: negative. + * Failure: negative. * * Programmer: Raymond Lu * Sep. 16, 2002 * - * Modification: - * *------------------------------------------------------------------------- */ herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle) { - H5F_t *file=NULL; - herr_t ret_value; + H5F_t *file; /* File to query */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Fget_vfd_handle, FAIL) H5TRACE3("e", "ii**x", file_id, fapl, file_handle); /* Check args */ - assert(file_handle); - if(NULL==(file=H5I_object_verify(file_id, H5I_FILE))) + if(!file_handle) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file handle pointer") + + /* Get the file */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id") - ret_value=H5F_get_vfd_handle(file, fapl, file_handle); + /* Retrieve the VFD handle for the file */ + if(H5F_get_vfd_handle(file, fapl, file_handle) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle") done: FUNC_LEAVE_API(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5F_get_vfd_handle - * - * Purpose: Returns a pointer to the file handle of the low-level file - * driver. This is the private function for H5Fget_vfd_handle. - * - * Return: Success: Non-negative. - * - * Failture: negative. - * - * Programmer: Raymond Lu - * Sep. 16, 2002 - * - * Modification: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void**file_handle) -{ - herr_t ret_value; - - FUNC_ENTER_NOAPI_NOINIT(H5F_get_vfd_handle) - - assert(file_handle); - if((ret_value=H5FD_get_vfd_handle(file->shared->lf, fapl, file_handle)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file handle for file driver") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5Fget_vfd_handle() */ /*------------------------------------------------------------------------- @@ -761,31 +762,31 @@ done: htri_t H5Fis_hdf5(const char *name) { - H5FD_t *file = NULL; - htri_t ret_value; + H5FD_t *file = NULL; /* Low-level file struct */ + htri_t ret_value; /* Return value */ FUNC_ENTER_API(H5Fis_hdf5, FAIL) H5TRACE1("t", "*s", name); /* Check args and all the boring stuff. */ - if (!name || !*name) + if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified") /* Open the file at the virtual file layer */ - if (NULL==(file=H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF))) + if(NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF))) HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file") /* The file is an hdf5 file if the hdf5 file signature can be found */ - ret_value = (HADDR_UNDEF!=H5F_locate_signature(file, H5AC_ind_dxpl_id)); + ret_value = (HADDR_UNDEF != H5F_locate_signature(file, H5AC_ind_dxpl_id)); done: /* Close the file */ - if (file) - if(H5FD_close(file) < 0 && ret_value>=0) + if(file) + if(H5FD_close(file) < 0 && ret_value >= 0) HDONE_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") FUNC_LEAVE_API(ret_value) -} +} /* end H5Fis_hdf5() */ /*------------------------------------------------------------------------- @@ -808,22 +809,6 @@ done: * matzke@llnl.gov * Jul 18 1997 * - * Modifications: - * - * Raymond Lu, Oct 14, 2001 - * Changed the file creation and access property list to the - * new generic property list. - * - * J Mainzer, Mar 10, 2005 - * Updated for the new metadata cache, and associated - * property list changes. - * - * J Mainzer, Jun 30, 2005 - * Added lf parameter so the shared->lf field can be - * initialized prior to the call to H5AC_create() if a - * new instance of H5F_file_t is created. lf should be - * NULL if shared isn't, and vise versa. - * *------------------------------------------------------------------------- */ static H5F_t * @@ -842,18 +827,18 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) f->shared = shared; } /* end if */ else { - unsigned super_vers = HDF5_SUPERBLOCK_VERSION_DEF; /* Superblock version for file */ - H5P_genplist_t *plist; /* Property list */ + H5P_genplist_t *plist; /* Property list */ + size_t u; /* Local index variable */ HDassert(lf != NULL); if(NULL == (f->shared = H5FL_CALLOC(H5F_file_t))) HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure") - f->shared->super_addr = HADDR_UNDEF; - f->shared->base_addr = HADDR_UNDEF; - f->shared->extension_addr = HADDR_UNDEF; + f->shared->sohm_addr = HADDR_UNDEF; f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION; - f->shared->driver_addr = HADDR_UNDEF; + for(u = 0; u < NELMTS(f->shared->fs_addr); u++) + f->shared->fs_addr[u] = HADDR_UNDEF; + f->shared->accum.loc = HADDR_UNDEF; f->shared->lf = lf; /* @@ -861,32 +846,32 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) * new file handle. We do this early because some values might need * to change as the file is being opened. */ - if(NULL == (plist = H5I_object(fcpl_id))) + 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); + f->shared->fcpl_id = H5P_copy_plist(plist, FALSE); /* Get the FCPL values to cache */ 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_SYM_LEAF_NAME, &f->shared->sym_leaf_k) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size") - if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, &f->shared->btree_k[0]) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes") - if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes)<0) + 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_THRESHOLD_NAME, &f->shared->fs_threshold) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get free-space section threshold") /* Get the FAPL values to cache */ - if(NULL == (plist = H5I_object(fapl_id))) + 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_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache element size") + 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 cache size") + 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) @@ -899,34 +884,34 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size") if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' 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; /* Get the VFD values to cache */ 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") - - /* Bump superblock version if we are to use the latest version of the format */ - if(f->shared->latest_format) - super_vers = HDF5_SUPERBLOCK_VERSION_LATEST; - /* Bump superblock version to create superblock extension for SOHM info */ - else if(f->shared->sohm_nindexes > 0) - super_vers = HDF5_SUPERBLOCK_VERSION_2; - /* Check for non-default indexed storage B-tree internal 'K' value - * and set the version # of the superblock to 1 if it is a non-default - * value. + 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(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; + /* Disable temp. space allocation for parallel I/O (for now) */ + /* (When we've arranged to have the relocated metadata addresses (and + * sizes) broadcast during the "end of epoch" metadata operations, + * this can be enabled - QAK) */ - else if(f->shared->btree_k[H5B_ISTORE_ID] != HDF5_BTREE_ISTORE_IK_DEF) - super_vers = HDF5_SUPERBLOCK_VERSION_1; - - /* If a newer superblock version is required, set it here */ - if(super_vers != HDF5_SUPERBLOCK_VERSION_DEF) { - H5P_genplist_t *c_plist; /* Property list */ - - if(NULL == (c_plist = H5I_object(f->shared->fcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list") - if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set superblock version") - } /* end if */ + /* (This should be disabled when the metadata journaling branch is + * merged into the trunk and journaling is enabled, at least until + * we make it work. - QAK) + */ + f->shared->use_tmp_space = !(IS_H5FD_MPI(f)); /* * Create a metadata cache with the specified number of elements. @@ -957,8 +942,8 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) done: if(!ret_value && f) { if(!shared) - H5FL_FREE(H5F_file_t, f->shared); - H5FL_FREE(H5F_t, f); + (void)H5FL_FREE(H5F_file_t, f->shared); + (void)H5FL_FREE(H5F_t, f); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -978,16 +963,13 @@ done: * Programmer: Robb Matzke * matzke@llnl.gov * Jul 18 1997 - * Modifications: - * Vailin Choi, April 2, 2008 - * Free f->extpath * *------------------------------------------------------------------------- */ static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id) { - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5F_dest) @@ -1007,10 +989,24 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) H5AC_stats(f); #endif /* H5AC_DUMP_STATS_ON_CLOSE */ - /* Flush and invalidate all caches */ - if(H5F_flush(f, dxpl_id, H5F_SCOPE_LOCAL, H5F_FLUSH_INVALIDATE | H5F_FLUSH_CLOSING) < 0) + /* Shutdown file free space manager(s) */ + /* (We should release the free space information now (before truncating + * the file and before the metadata cache is shut down) since the + * free space manager is holding some data structures in memory + * and also because releasing free space can shrink the file's + * 'eoa' value) + */ + if(H5F_ACC_RDWR & H5F_INTENT(f)) { + if(H5MF_close(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") + } /* end if */ + + /* Unpin the superblock, since we're about to destroy the cache */ + if(H5AC_unpin_entry(f, f->shared->sblock) < 0) /* Push error, but keep going*/ - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") + f->shared->sblock = NULL; } /* end if */ /* Remove shared file struct from list of open files */ @@ -1018,6 +1014,11 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + /* Shutdown the metadata cache */ + if(H5AC_dest(f, dxpl_id)) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + /* * Do not close the root group since we didn't count it, but free * the memory associated with it. @@ -1035,13 +1036,14 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) f->shared->root_grp = NULL; } /* end if */ - if(H5AC_dest(f, dxpl_id) < 0) + /* Destroy other components of the file */ + if(H5F_accum_reset(f, dxpl_id) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") if(H5FO_dest(f) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - f->shared->cwfs = H5MM_xfree(f->shared->cwfs); + f->shared->cwfs = (struct H5HG_heap_t **)H5MM_xfree(f->shared->cwfs); if(H5G_node_close(f) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") @@ -1050,21 +1052,29 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) /* Push error, but keep going*/ HDONE_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list") - if(H5I_dec_ref(f->shared->fcpl_id) < 0) + if(H5I_dec_ref(f->shared->fcpl_id, FALSE) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close property list") - /* Close low-level file */ + /* Only truncate the file on an orderly close, with write-access */ + if(f->closing && (H5F_ACC_RDWR & H5F_INTENT(f))) { + /* Truncate the file to the current allocated size */ + if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed") + } /* end if */ + + /* Close the file */ if(H5FD_close(f->shared->lf) < 0) /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") /* Free mount table */ - f->shared->mtab.child = H5MM_xfree(f->shared->mtab.child); + f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child); f->shared->mtab.nalloc = 0; /* Destroy shared file struct */ - f->shared = H5FL_FREE(H5F_file_t,f->shared); + f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared); } else if(f->shared->nrefs > 0) { /* @@ -1075,12 +1085,13 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) } /* Free the non-shared part of the file */ - f->name = H5MM_xfree(f->name); - f->extpath = H5MM_xfree(f->extpath); + 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; - H5FL_FREE(H5F_t, f); + (void)H5FL_FREE(H5F_t, f); FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_dest() */ @@ -1125,53 +1136,16 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) * cause the default file access parameters to be used. * * Return: Success: A new file pointer. - * * Failure: NULL * * Programmer: Robb Matzke * Tuesday, September 23, 1997 * - * Modifications: - * Albert Cheng, 1998-02-05 - * Added the access_parms argument to pass down access template - * information. - * - * Robb Matzke, 1998-02-18 - * The H5F_access_t changed to allow more generality. The low - * level driver is part of the file access template so the TYPE - * argument has been removed. - * - * Robb Matzke, 1999-08-02 - * Rewritten to use the virtual file layer. - * - * Robb Matzke, 1999-08-16 - * Added decoding of file driver information block, which uses a - * formerly reserved address slot in the boot block in order to - * be compatible with previous versions of the file format. - * - * Robb Matzke, 1999-08-20 - * Optimizations for opening a file. If the driver can't - * determine when two file handles refer to the same file then - * we open the file in one step. Otherwise if the first attempt - * to open the file fails then we skip the second attempt if the - * arguments would be the same. - * - * Raymond Lu, 2001-10-14 - * Changed the file creation and access property lists to the - * new generic property list. - * - * Bill Wendling, 2003-03-18 - * Modified H5F_flush call to take one flag instead of - * multiple Boolean flags. - * - * Vailin Choi, 2008-04-02 - * To formulate path for later searching of target file for - * external link via H5_build_extpath(). - * *------------------------------------------------------------------------- */ H5F_t * -H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id) +H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + hid_t dxpl_id) { H5F_t *file = NULL; /*the success return value */ H5F_file_t *shared = NULL; /*shared part of `file' */ @@ -1192,7 +1166,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d * Otherwise it is the application's responsibility to never open the * same file more than once at a time. */ - if((drvr = H5FD_get_class(fapl_id)) == NULL) + if(NULL == (drvr = H5FD_get_class(fapl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class") /* @@ -1278,23 +1252,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d * file can be accessed through the C library. */ file->intent = flags; - file->name = H5MM_xstrdup(name); - - /* Get the file access property list, for future queries */ - if(NULL == (a_plist = H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") - - /* This step is for h5repart tool only. If user wants to change file driver from - * family to sec2 while using h5repart, this private property should be set so that - * in the later step, the library can ignore the family driver information saved - * in the superblock. - */ - if(H5P_exist_plist(a_plist, H5F_ACS_FAMILY_TO_SEC2_NAME) > 0) { - if(H5P_get(a_plist, H5F_ACS_FAMILY_TO_SEC2_NAME, &shared->fam_to_sec2) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property of changing family to sec2") - } /* end if */ - else - shared->fam_to_sec2 = FALSE; + file->open_name = H5MM_xstrdup(name); /* * Read or write the file superblock, depending on whether the file is @@ -1315,34 +1273,22 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d /* (This must be after the space for the superblock is allocated in * the file, since the superblock must be at offset 0) */ - if(H5G_mkroot(file, dxpl_id, NULL) < 0) + if(H5G_mkroot(file, dxpl_id, TRUE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group") - - /* Write the superblock to the file */ - /* (This must be after the root group is created, since the root - * group's symbol table entry is part of the superblock) - */ - if(H5F_super_write(file, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to write file superblock") } else if (1 == shared->nrefs) { - H5G_loc_t root_loc; /*root location */ - H5O_loc_t root_oloc; /*root object location */ - H5G_name_t root_path; /*root group hier. path */ - - /* Set up root location to fill in */ - root_loc.oloc = &root_oloc; - root_loc.path = &root_path; - H5G_loc_reset(&root_loc); - /* Read the superblock if it hasn't been read before. */ - if(H5F_super_read(file, dxpl_id, &root_loc) < 0) + if(H5F_super_read(file, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") /* Open the root group */ - if(H5G_mkroot(file, dxpl_id, &root_loc) < 0) + if(H5G_mkroot(file, dxpl_id, FALSE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group") } /* end if */ + /* Get the file access property list, for future queries */ + if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") + /* * Decide the file close degree. If it's the first time to open the * file, set the degree to access property list value; if it's the @@ -1364,10 +1310,14 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") } /* end if */ - /* formulate the absolute path for later search of target file for external link */ - if (H5_build_extpath(name, &file->extpath) < 0) + /* Formulate the absolute path for later search of target file for external links */ + if(H5_build_extpath(name, &file->extpath) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") - + + /* Formulate the actual file name, after following symlinks, etc. */ + 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") + /* Success */ ret_value = file; @@ -1405,33 +1355,6 @@ done: * * Programmer: Unknown * - * Modifications: - * Robb Matzke, 1997-07-18 - * File struct creation and destruction is through H5F_new() and - * H5F_dest(). Writing the root symbol table entry is done with - * H5G_encode(). - * - * Robb Matzke, 1997-08-29 - * Moved creation of the boot block to H5F_flush(). - * - * Robb Matzke, 1997-09-23 - * Most of the work is now done by H5F_open() since H5Fcreate() - * and H5Fopen() originally contained almost identical code. - * - * Robb Matzke, 1998-02-18 - * Better error checking for the creation and access property - * lists. It used to be possible to swap the two and core the - * library. Also, zero is no longer valid as a default property - * list; one must use H5P_DEFAULT instead. - * - * Robb Matzke, 1999-08-02 - * The file creation and file access property lists are passed - * to the H5F_open() as object IDs. - * - * Raymond Lu, 2001-10-14 - * Changed the file creation and access property list to the - * new generic property list. - * *------------------------------------------------------------------------- */ hid_t @@ -1444,11 +1367,15 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); /* Check/fix arguments */ - if (!filename || !*filename) + if(!filename || !*filename) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") - if (flags & ~(H5F_ACC_EXCL|H5F_ACC_TRUNC|H5F_ACC_DEBUG)) + /* In this routine, we only accept the following flags: + * H5F_ACC_EXCL, H5F_ACC_TRUNC and H5F_ACC_DEBUG + */ + if(flags & ~(H5F_ACC_EXCL | H5F_ACC_TRUNC | H5F_ACC_DEBUG)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") - if ((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC)) + /* The H5F_ACC_EXCL and H5F_ACC_TRUNC flags are mutually exclusive */ + if((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation") /* Check file creation property list */ @@ -1481,7 +1408,7 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file") /* Get an atom for the file */ - if((ret_value = H5I_register(H5I_FILE, new_file)) < 0) + if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") /* Keep this ID in file object structure */ @@ -1548,6 +1475,7 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) /* Check/fix arguments. */ if(!filename || !*filename) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") + /* Reject undefined flags (~H5F_ACC_PUBLIC_FLAGS) and the H5F_ACC_TRUNC & H5F_ACC_EXCL flags */ if((flags & ~H5F_ACC_PUBLIC_FLAGS) || (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags") @@ -1562,7 +1490,7 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file") /* Get an atom for the file */ - if((ret_value = H5I_register(H5I_FILE, new_file)) < 0) + if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") /* Keep this ID in file object structure */ @@ -1588,58 +1516,62 @@ done: * Programmer: Robb Matzke * Thursday, August 6, 1998 * - * Modifications: - * Robb Matzke, 1998-10-16 - * Added the `scope' argument. - * - * Bill Wendling, 2003-03-18 - * Modified H5F_flush call to take one flag instead of - * several Boolean flags. - * *------------------------------------------------------------------------- */ herr_t H5Fflush(hid_t object_id, H5F_scope_t scope) { - H5F_t *f = NULL; - H5G_t *grp = NULL; - H5T_t *type = NULL; - H5D_t *dset = NULL; - H5A_t *attr = NULL; - H5O_loc_t *oloc = NULL; - herr_t ret_value=SUCCEED; /* Return value */ + H5F_t *f = NULL; /* File to flush */ + H5O_loc_t *oloc = NULL; /* Object location for ID */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Fflush, FAIL) H5TRACE2("e", "iFs", object_id, scope); switch(H5I_get_type(object_id)) { case H5I_FILE: - if(NULL == (f = H5I_object(object_id))) + if(NULL == (f = (H5F_t *)H5I_object(object_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") break; case H5I_GROUP: - if(NULL == (grp = H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier") - oloc = H5G_oloc(grp); + { + H5G_t *grp; + + if(NULL == (grp = (H5G_t *)H5I_object(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier") + oloc = H5G_oloc(grp); + } break; case H5I_DATATYPE: - if(NULL == (type = H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid type identifier") - oloc = H5T_oloc(type); + { + H5T_t *type; + + if(NULL == (type = (H5T_t *)H5I_object(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid type identifier") + oloc = H5T_oloc(type); + } break; case H5I_DATASET: - if(NULL == (dset = H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") - oloc = H5D_oloc(dset); + { + H5D_t *dset; + + if(NULL == (dset = (H5D_t *)H5I_object(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + oloc = H5D_oloc(dset); + } break; case H5I_ATTR: - if(NULL == (attr = H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") - oloc = H5A_oloc(attr); + { + H5A_t *attr; + + if(NULL == (attr = (H5A_t *)H5I_object(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") + oloc = H5A_oloc(attr); + } break; default: @@ -1655,8 +1587,26 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not associated with a file") /* Flush the file */ - if(H5F_flush(f, H5AC_dxpl_id, scope, H5F_FLUSH_NONE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "flush failed") + /* + * Nothing to do if the file is read only. This determination is + * made at the shared open(2) flags level, implying that opening a + * file twice, once for read-only and once for read-write, and then + * calling H5Fflush() with the read-only handle, still causes data + * to be flushed. + */ + if(H5F_ACC_RDWR & H5F_INTENT(f)) { + /* Flush other files, depending on scope */ + if(H5F_SCOPE_GLOBAL == scope) { + /* Call the flush routine for mounted file hierarchies */ + if(H5F_flush_mounts(f, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy") + } /* end if */ + else { + /* Call the flush routine, for this file */ + if(H5F_flush(f, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") + } /* end else */ + } /* end if */ done: FUNC_LEAVE_API(ret_value) @@ -1666,9 +1616,7 @@ done: /*------------------------------------------------------------------------- * Function: H5F_flush * - * Purpose: Flushes (and optionally invalidates) cached data plus the - * file superblock. If the logical file size field is zero - * then it is updated to be the length of the superblock. + * Purpose: Flushes cached data. * * Return: Non-negative on success/Negative on failure * @@ -1678,75 +1626,45 @@ done: * *------------------------------------------------------------------------- */ -static herr_t -H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags) +herr_t +H5F_flush(H5F_t *f, hid_t dxpl_id) { - unsigned nerrors = 0; /* Errors from nested flushes */ - unsigned i; /* Index variable */ - unsigned int H5AC_flags; /* translated flags for H5AC_flush() */ - herr_t ret_value; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5F_flush) + FUNC_ENTER_NOAPI(H5F_flush, FAIL) /* Sanity check arguments */ HDassert(f); - /* - * Nothing to do if the file is read only. This determination is - * made at the shared open(2) flags level, implying that opening a - * file twice, once for read-only and once for read-write, and then - * calling H5F_flush() with the read-only handle, still causes data - * to be flushed. - */ - if(0 == (H5F_ACC_RDWR & f->shared->flags)) - HGOTO_DONE(SUCCEED) - - /* Flush other files, depending on scope */ - if(H5F_SCOPE_GLOBAL == scope) { - while(f->parent) - f = f->parent; - - scope = H5F_SCOPE_DOWN; - } /* end while */ - if(H5F_SCOPE_DOWN == scope) - for(i = 0; i < f->shared->mtab.nmounts; i++) - if(H5F_flush(f->shared->mtab.child[i].file, dxpl_id, scope, flags) < 0) - nerrors++; - /* Flush any cached dataset storage raw data */ - if(H5D_flush(f, dxpl_id, flags) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache") + if(H5D_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache") - /* flush (and invalidate, if requested) the entire metadata cache */ - H5AC_flags = 0; - if((flags & H5F_FLUSH_INVALIDATE) != 0 ) - H5AC_flags |= H5AC__FLUSH_INVALIDATE_FLAG; - if(H5AC_flush(f, dxpl_id, H5AC_flags) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache") - - /* - * If we are invalidating everything (which only happens just before - * the file closes), release the unused portion of the metadata and - * "small data" blocks back to the free lists in the file. + /* Release any space allocated to space aggregators, so that the eoa value + * corresponds to the end of the space written to in the file. + */ + /* (needs to happen before cache flush, with superblock write, since the + * 'eoa' value is written in superblock -QAK) */ - if(flags & H5F_FLUSH_INVALIDATE) { - if(H5FD_aggr_reset(f->shared->lf, &(f->shared->lf->meta_aggr), dxpl_id) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't reset metadata block") + if(H5MF_free_aggrs(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") - if(H5FD_aggr_reset(f->shared->lf, &(f->shared->lf->sdata_aggr), dxpl_id) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't reset 'small data' block") - } /* end if */ + /* Flush the entire metadata cache */ + if(H5AC_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache") - /* Write the superblock to disk */ - if(H5F_super_write(f, dxpl_id) != SUCCEED) - HGOTO_ERROR(H5E_CACHE, H5E_WRITEERROR, FAIL, "unable to write superblock to file") + /* Flush out the metadata accumulator */ + if(H5F_accum_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator") /* Flush file buffers to disk. */ - if(H5FD_flush(f->shared->lf, dxpl_id, (unsigned)((flags & H5F_FLUSH_CLOSING) > 0)) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed") - - /* Check flush errors for children - errors are already on the stack */ - ret_value = (nerrors ? FAIL : SUCCEED); + if(H5FD_flush(f->shared->lf, dxpl_id, FALSE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1916,10 +1834,10 @@ H5F_try_close(H5F_t *f) unsigned u; /* Local index variable */ /* Get the list of IDs of open dataset, group, & attribute objects */ - while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) { + while((obj_count = 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)) != 0) { /* Try to close all the open objects in this file */ for(u = 0; u < obj_count; u++) - if(H5I_dec_ref(objs[u]) < 0) + if(H5I_dec_ref(objs[u], FALSE) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") } /* end while */ @@ -1928,10 +1846,10 @@ H5F_try_close(H5F_t *f) * they could be using one of the named datatypes and then the * open named datatype ID will get closed twice) */ - while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) { + while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs, FALSE)) != 0) { /* Try to close all the open objects in this file */ for(u = 0; u < obj_count; u++) - if(H5I_dec_ref(objs[u]) < 0) + if(H5I_dec_ref(objs[u], FALSE) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") } /* end while */ } /* end if */ @@ -1954,9 +1872,9 @@ H5F_try_close(H5F_t *f) * copy of the cache needs to be clean. * Only try to flush the file if it was opened with write access. */ - if(f->intent&H5F_ACC_RDWR) { - /* Flush and destroy all caches */ - if(H5F_flush(f, H5AC_dxpl_id, H5F_SCOPE_LOCAL, H5C__NO_FLAGS_SET) < 0) + if(f->intent & H5F_ACC_RDWR) { + /* Flush all caches */ + if(H5F_flush(f, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") } /* end if */ @@ -2010,7 +1928,7 @@ H5Fclose(hid_t file_id) * Decrement reference count on atom. When it reaches zero the file will * be closed. */ - if(H5I_dec_ref(file_id) < 0) + if(H5I_dec_ref(file_id, TRUE) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") done: @@ -2051,7 +1969,7 @@ H5Freopen(hid_t file_id) H5TRACE1("i", "i", file_id); /* Check arguments */ - if(NULL == (old_file = H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (old_file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") /* Get a new "top level" file struct, sharing the same "low level" file struct */ @@ -2061,10 +1979,11 @@ H5Freopen(hid_t file_id) /* Keep old file's read/write intent in new file */ new_file->intent = old_file->intent; - /* Duplicate old file's name */ - new_file->name = H5MM_xstrdup(old_file->name); + /* Duplicate old file's names */ + new_file->open_name = H5MM_xstrdup(old_file->open_name); + new_file->actual_name = H5MM_xstrdup(old_file->actual_name); - if((ret_value = H5I_register(H5I_FILE, new_file)) < 0) + if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") /* Keep this ID in file object structure */ @@ -2090,410 +2009,37 @@ done: * Programmer: James Laird * August 23, 2006 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t H5Fget_intent(hid_t file_id, unsigned *intent_flags) { - H5F_t * file = NULL; herr_t ret_value = SUCCEED; FUNC_ENTER_API(H5Fget_intent, FAIL) H5TRACE2("e", "i*Iu", file_id, intent_flags); - if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - /* If no intent flags were passed in, exit quietly */ - if(!intent_flags) - HGOTO_DONE(SUCCEED) - - *intent_flags = H5F_get_intent(file); - - /* HDF5 uses some flags internally that users don't know about. - * Simplify things for them so that they get one of H5F_ACC_RDWR - * or H5F_ACC_RDONLY. - */ - if(*intent_flags & H5F_ACC_RDWR) - *intent_flags = H5F_ACC_RDWR; - else - *intent_flags = H5F_ACC_RDONLY; - -done: - FUNC_LEAVE_API(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5F_get_intent - * - * Purpose: Quick and dirty routine to retrieve the file's 'intent' flags - * (Mainly added to stop non-file routines from poking about in the - * H5F_t data structure) - * - * Return: 'intent' on success/abort on failure (shouldn't fail) - * - * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> - * September 29, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_get_intent(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_intent) - - HDassert(f); - - FUNC_LEAVE_NOAPI(f->intent) -} /* end H5F_get_intent() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_extpath - * - * Purpose: Retrieve the file's 'extpath' flags - * This is used by H5L_extern_traverse() to retrieve the main file's location - * when searching the target file. - * - * Return: 'extpath' on success/abort on failure (shouldn't fail) - * - * Programmer: Vailin Choi, April 2, 2008 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -char * -H5F_get_extpath(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_extpath) - - HDassert(f); - - FUNC_LEAVE_NOAPI(f->extpath) -} /* end H5F_get_extpath() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_sizeof_addr - * - * Purpose: Quick and dirty routine to retrieve the size of the file's size_t - * (Mainly added to stop non-file routines from poking about in the - * H5F_t data structure) - * - * Return: 'sizeof_addr' on success/abort on failure (shouldn't fail) - * - * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> - * September 29, 2000 - * - * Modifications: - * - * Raymond Lu, Oct 14, 2001 - * Changed to generic property list. - * - *------------------------------------------------------------------------- - */ -size_t -H5F_sizeof_addr(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sizeof_addr) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->sizeof_addr) -} - - -/*------------------------------------------------------------------------- - * Function: H5F_sizeof_size - * - * Purpose: Quick and dirty routine to retrieve the size of the file's off_t - * (Mainly added to stop non-file routines from poking about in the - * H5F_t data structure) - * - * Return: 'sizeof_size' on success/abort on failure (shouldn't fail) - * - * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> - * September 29, 2000 - * - *------------------------------------------------------------------------- - */ -size_t -H5F_sizeof_size(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sizeof_size) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->sizeof_size) -} /* H5F_sizeof_size() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_sym_leaf_k - * - * Purpose: Replaced a macro to retrieve the symbol table leaf size, - * now that the generic properties are being used to store - * the values. - * - * Return: Success: Non-negative, and the symbol table leaf size is - * returned. - * - * Failure: Negative (should not happen) - * - * Programmer: Raymond Lu - * slu@ncsa.uiuc.edu - * Oct 14 2001 - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_sym_leaf_k(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sym_leaf_k) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->sym_leaf_k) -} /* end H5F_sym_leaf_k() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_Kvalue - * - * Purpose: Replaced a macro to retrieve a B-tree key value for a certain - * type, now that the generic properties are being used to store - * the B-tree values. - * - * Return: Success: Non-negative, and the B-tree key value is - * returned. - * - * Failure: Negative (should not happen) - * - * Programmer: Raymond Lu - * slu@ncsa.uiuc.edu - * Oct 14 2001 - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_Kvalue(const H5F_t *f, const H5B_class_t *type) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_Kvalue) - - assert(f); - assert(f->shared); - assert(type); - - FUNC_LEAVE_NOAPI(f->shared->btree_k[type->id]) -} /* end H5F_Kvalue() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_rdcc_nelmts - * - * Purpose: Replaced a macro to retrieve the raw data cache number of elments, - * now that the generic properties are being used to store - * the values. - * - * Return: Success: Non-negative, and the raw data cache number of - * of elemnts is returned. - * - * Failure: Negative (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jun 1 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -size_t -H5F_rdcc_nelmts(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_nelmts) - - assert(f); - assert(f->shared); + if(intent_flags) { + H5F_t * file; /* Pointer to file structure */ - FUNC_LEAVE_NOAPI(f->shared->rdcc_nelmts) -} /* end H5F_rdcc_nelmts() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_rdcc_nbytes - * - * Purpose: Replaced a macro to retrieve the raw data cache number of bytes, - * now that the generic properties are being used to store - * the values. - * - * Return: Success: Non-negative, and the raw data cache number of - * of bytes is returned. - * - * Failure: Negative (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jun 1 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -size_t -H5F_rdcc_nbytes(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_nbytes) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->rdcc_nbytes) -} /* end H5F_rdcc_nbytes() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_rdcc_w0 - * - * Purpose: Replaced a macro to retrieve the raw data cache 'w0' value - * now that the generic properties are being used to store - * the values. - * - * Return: Success: Non-negative, and the raw data cache 'w0' value - * is returned. - * - * Failure: Negative (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jun 2 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -double -H5F_rdcc_w0(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rdcc_w0) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->rdcc_w0) -} /* end H5F_rdcc_w0() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_has_feature - * - * Purpose: Check if a file has a particular feature enabled - * - * Return: Success: Non-negative - TRUE or FALSE - * Failure: Negative (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * May 31 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hbool_t -H5F_has_feature(const H5F_t *f, unsigned feature) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_has_feature) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI((hbool_t)(f->shared->lf->feature_flags&feature)) -} /* end H5F_has_feature() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_driver_id - * - * Purpose: Quick and dirty routine to retrieve the file's 'driver_id' value - * (Mainly added to stop non-file routines from poking about in the - * H5F_t data structure) - * - * Return: 'driver_id' on success/abort on failure (shouldn't fail) - * - * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> - * October 10, 2000 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hid_t -H5F_get_driver_id(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_driver_id) - - assert(f); - assert(f->shared); - assert(f->shared->lf); - - FUNC_LEAVE_NOAPI(f->shared->lf->driver_id) -} - - -/*------------------------------------------------------------------------- - * Function: H5F_get_fileno - * - * Purpose: Quick and dirty routine to retrieve the file's 'fileno' value - * (Mainly added to stop non-file routines from poking about in the - * H5F_t data structure) - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> - * March 27, 2002 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_get_fileno(const H5F_t *f, unsigned long *filenum) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(H5F_get_fileno, FAIL) - - HDassert(f); - HDassert(f->shared); - HDassert(f->shared->lf); - HDassert(filenum); + /* Get the internal file structure */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - /* Retrieve the file's serial number */ - if(H5FD_get_fileno(f->shared->lf, filenum) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "can't retrieve fileno") + /* HDF5 uses some flags internally that users don't know about. + * Simplify things for them so that they only get either H5F_ACC_RDWR + * or H5F_ACC_RDONLY. + */ + if(H5F_INTENT(file) & H5F_ACC_RDWR) + *intent_flags = H5F_ACC_RDWR; + else + *intent_flags = H5F_ACC_RDONLY; + } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_fileno() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_intent() */ /*------------------------------------------------------------------------- @@ -2510,7 +2056,7 @@ done: *------------------------------------------------------------------------- */ hid_t -H5F_get_id(H5F_t *file) +H5F_get_id(H5F_t *file, hbool_t app_ref) { hid_t ret_value; @@ -2520,11 +2066,11 @@ H5F_get_id(H5F_t *file) if(file->file_id == -1) { /* Get an atom for the file */ - if((file->file_id = H5I_register(H5I_FILE, file)) < 0) + if((file->file_id = H5I_register(H5I_FILE, file, app_ref)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") } else { /* Increment reference count on atom. */ - if(H5I_inc_ref(file->file_id) < 0) + if(H5I_inc_ref(file->file_id, app_ref) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") } /* end else */ @@ -2536,354 +2082,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_get_base_addr - * - * Purpose: Quick and dirty routine to retrieve the file's 'base_addr' value - * (Mainly added to stop non-file routines from poking about in the - * H5F_t data structure) - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu <slu@ncsa.uiuc.edu> - * December 20, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -haddr_t -H5F_get_base_addr(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_base_addr) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->base_addr) -} /* end H5F_get_base_addr() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_eoa - * - * Purpose: Quick and dirty routine to retrieve the file's 'eoa' value - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu> - * June 1, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -haddr_t -H5F_get_eoa(const H5F_t *f) -{ - haddr_t ret_value; - - FUNC_ENTER_NOAPI(H5F_get_eoa, HADDR_UNDEF) - - assert(f); - assert(f->shared); - - /* Dispatch to driver */ - if (HADDR_UNDEF==(ret_value=H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT))) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_eoa() */ - -#ifdef H5_HAVE_PARALLEL - -/*------------------------------------------------------------------------- - * Function: H5F_mpi_get_rank - * - * Purpose: Retrieves the rank of an MPI process. - * - * Return: Success: The rank (non-negative) - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * Friday, January 30, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -H5F_mpi_get_rank(const H5F_t *f) -{ - int ret_value; - - FUNC_ENTER_NOAPI(H5F_mpi_get_rank, FAIL) - - assert(f && f->shared); - - /* Dispatch to driver */ - if ((ret_value=H5FD_mpi_get_rank(f->shared->lf)) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_rank request failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_mpi_get_rank() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_mpi_get_comm - * - * Purpose: Retrieves the file's communicator - * - * Return: Success: The communicator (non-negative) - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * Friday, January 30, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -MPI_Comm -H5F_mpi_get_comm(const H5F_t *f) -{ - MPI_Comm ret_value; - - FUNC_ENTER_NOAPI(H5F_mpi_get_comm, MPI_COMM_NULL) - - assert(f && f->shared); - - /* Dispatch to driver */ - if ((ret_value=H5FD_mpi_get_comm(f->shared->lf))==MPI_COMM_NULL) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, MPI_COMM_NULL, "driver get_comm request failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_mpi_get_comm() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_mpi_get_size - * - * Purpose: Retrieves the size of an MPI process. - * - * Return: Success: The size (positive) - * - * Failure: Negative - * - * Programmer: John Mainzer - * Friday, May 6, 2005 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -int -H5F_mpi_get_size(const H5F_t *f) -{ - int ret_value; - - FUNC_ENTER_NOAPI(H5F_mpi_get_size, FAIL) - - assert(f && f->shared); - - /* Dispatch to driver */ - if ((ret_value=H5FD_mpi_get_size(f->shared->lf)) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get_size request failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_mpi_get_size() */ -#endif /* H5_HAVE_PARALLEL */ - - -/*------------------------------------------------------------------------- - * Function: H5F_grp_btree_shared - * - * Purpose: Replaced a macro to retrieve the shared B-tree node info - * now that the generic properties are being used to store - * the values. - * - * Return: Success: Non-void, and the shared B-tree node info - * is returned. - * - * Failure: void (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jul 5 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5RC_t * -H5F_grp_btree_shared(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_grp_btree_shared) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->grp_btree_shared) -} /* end H5F_grp_btree_shared() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_sieve_buf_size - * - * Purpose: Replaced a macro to retrieve the dataset sieve buffer size - * now that the generic properties are being used to store - * the values. - * - * Return: Success: Non-void, and the dataset sieve buffer size - * is returned. - * - * Failure: void (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jul 8 2005 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -size_t -H5F_sieve_buf_size(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_sieve_buf_size) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->sieve_buf_size) -} /* end H5F_sieve_buf_size() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_gc_ref - * - * Purpose: Replaced a macro to retrieve the "garbage collect - * references flag" now that the generic properties are being used - * to store the values. - * - * Return: Success: The "garbage collect references flag" - * is returned. - * - * Failure: (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Jul 8 2005 - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_gc_ref(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_gc_ref) - - HDassert(f); - HDassert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->gc_ref) -} /* end H5F_gc_ref() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_fcpl - * - * Purpose: Retrieve the value of a file's FCPL. - * - * Return: Success: The FCPL for the file. - * - * Failure: ? (should not happen) - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * May 25 2005 - * - *------------------------------------------------------------------------- - */ -hid_t -H5F_get_fcpl(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_fcpl) - - assert(f); - assert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->fcpl_id) -} /* end H5F_get_fcpl() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_use_latest_format - * - * Purpose: Retrieve the 'use the latest version of the format' flag for - * the file. - * - * Return: Success: Non-negative, the 'use the latest format' flag - * - * Failure: (can't happen) - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Oct 2 2006 - * - *------------------------------------------------------------------------- - */ -hbool_t -H5F_use_latest_format(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_use_latest_format) - - HDassert(f); - HDassert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->latest_format) -} /* end H5F_use_latest_format() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_fc_degree - * - * Purpose: Retrieve the 'file close degree' for the file. - * - * Return: Success: Non-negative, the 'file close degree' - * - * Failure: (can't happen) - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Mar 5 2007 - * - *------------------------------------------------------------------------- - */ -H5F_close_degree_t -H5F_get_fc_degree(const H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_fc_degree) - - HDassert(f); - HDassert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->fc_degree) -} /* end H5F_get_fc_degree() */ - - -/*------------------------------------------------------------------------- * Function: H5F_incr_nopen_objs * * Purpose: Increment the number of open objects for a file. @@ -2938,145 +2136,157 @@ H5F_decr_nopen_objs(H5F_t *f) /*------------------------------------------------------------------------- - * Function: H5F_store_msg_crt_idx + * Function: H5F_build_actual_name * - * Purpose: Retrieve the 'store message creation index' flag for the file. + * Purpose: Retrieve the name of a file, after following symlinks, etc. * - * Return: Success: Non-negative, the 'store message creation index' flag + * Note: Currently only working for "POSIX I/O compatible" VFDs * - * Failure: (can't happen) + * Return: Success: 0 + * Failure: -1 * * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Mar 6 2007 + * November 25, 2009 * *------------------------------------------------------------------------- */ -hbool_t -H5F_store_msg_crt_idx(const H5F_t *f) +static herr_t +H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, + char **actual_name/*out*/) { - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_store_msg_crt_idx) + hid_t new_fapl_id = -1; /* ID for duplicated FAPL */ + herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_NOAPI_NOINIT(H5F_build_actual_name) + + /* Sanity check */ HDassert(f); - HDassert(f->shared); + HDassert(fapl); + HDassert(name); + HDassert(actual_name); + + /* Clear actual name pointer to begin with */ + *actual_name = NULL; + +/* Assume that if the OS can't create symlinks, that we don't need to worry + * about resolving them either. -QAK + */ +#ifdef H5_HAVE_SYMLINK + /* Check for POSIX I/O compatible file handle */ + if(H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE)) { + h5_stat_t lst; /* Stat info from lstat() call */ + + /* Call lstat() on the file's name */ + if(HDlstat(name, &lst) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stat info for file") + + /* Check for symbolic link */ + if(S_IFLNK == (lst.st_mode & S_IFMT)) { + H5P_genplist_t *new_fapl; /* Duplicated FAPL */ + int *fd; /* POSIX I/O file descriptor */ + h5_stat_t st; /* Stat info from stat() call */ + h5_stat_t fst; /* Stat info from fstat() call */ + char realname[PATH_MAX]; /* Fully resolved path name of file */ + hbool_t want_posix_fd; /* Flag for retrieving file descriptor from VFD */ + + /* Perform a sanity check that the file or link wasn't switched + * between when we opened it and when we called lstat(). This is + * according to the security best practices for lstat() documented + * here: https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link + */ - FUNC_LEAVE_NOAPI(f->shared->store_msg_crt_idx) -} /* end H5F_store_msg_crt_idx() */ + /* Copy the FAPL object to modify */ + 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") - -/*------------------------------------------------------------------------- - * Function: H5F_block_read - * - * Purpose: Reads some data from a file/server/etc into a buffer. - * The data is contiguous. The address is relative to the base - * address for the file. - * - * Errors: - * IO READERROR Low-level read failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 10 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * Robb Matzke, 1999-08-02 - * Modified to use the virtual file layer. The data transfer - * property list is passed in by object ID since that's how the - * virtual file layer needs it. - *------------------------------------------------------------------------- - */ -herr_t -H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, hid_t dxpl_id, - void *buf/*out*/) -{ - haddr_t abs_addr; - herr_t ret_value=SUCCEED; /* Return value */ + /* Set the character encoding on the new 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") - FUNC_ENTER_NOAPI(H5F_block_read, FAIL) + /* Retrieve the file handle */ + 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") - assert (f); - assert (f->shared); - assert(size<SIZET_MAX); - assert (buf); + /* Stat the filename we're resolving */ + if(HDstat(name, &st) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat file") - /* convert the relative address to an absolute address */ - abs_addr = f->shared->base_addr + addr; + /* Stat the file we opened */ + if(HDfstat(*fd, &fst) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to fstat file") - /* Read the data */ - if(H5FD_read(f->shared->lf, type, dxpl_id, abs_addr, size, buf) < 0) - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") + /* Verify that the files are really the same */ + 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!") + + /* Get the resolved path for the file name */ + if(NULL == HDrealpath(name, realname)) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve real path for file") + + /* Duplicate the resolved path for the file name */ + if(NULL == (*actual_name = (char *)H5MM_strdup(realname))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate real path") + } /* end if */ + } /* end if */ +#endif /* H5_HAVE_SYMLINK */ + + /* Check if we've resolved the file's name */ + if(NULL == *actual_name) { + /* Just duplicate the name used to open the file */ + if(NULL == (*actual_name = (char *)H5MM_strdup(name))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate open name") + } /* end else */ done: + if(new_fapl_id > 0 && H5Pclose(new_fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close duplicated FAPL") + FUNC_LEAVE_NOAPI(ret_value) -} +} /* H5F_build_actual_name() */ /*------------------------------------------------------------------------- - * Function: H5F_block_write - * - * Purpose: Writes some data from memory to a file/server/etc. The - * data is contiguous. The address is relative to the base - * address. + * Function: H5F_addr_encode_len * - * Errors: - * IO WRITEERROR Low-level write failed. - * IO WRITEERROR No write intent. + * Purpose: Encodes an address into the buffer pointed to by *PP and + * then increments the pointer to the first byte after the + * address. An undefined value is stored as all 1's. * - * Return: Non-negative on success/Negative on failure + * Return: void * * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 10 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. + * Friday, November 7, 1997 * - * Robb Matzke, 1999-08-02 - * Modified to use the virtual file layer. The data transfer - * property list is passed in by object ID since that's how the - * virtual file layer needs it. *------------------------------------------------------------------------- */ -herr_t -H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, - hid_t dxpl_id, const void *buf) +void +H5F_addr_encode_len(size_t addr_len, uint8_t **pp/*in,out*/, haddr_t addr) { - haddr_t abs_addr; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5F_block_write, FAIL) - - assert (f); - assert (f->shared); - assert (size<SIZET_MAX); - assert (buf); + unsigned u; /* Local index variable */ - if (0==(f->intent & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "no write intent") + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_addr_encode_len) - /* Convert the relative address to an absolute address */ - abs_addr = f->shared->base_addr + addr; + HDassert(addr_len); + HDassert(pp && *pp); - /* Write the data */ - if (H5FD_write(f->shared->lf, type, dxpl_id, abs_addr, size, buf)) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + if(H5F_addr_defined(addr)) { + for(u = 0; u < addr_len; u++) { + *(*pp)++ = (uint8_t)(addr & 0xff); + addr >>= 8; + } /* end for */ + HDassert("overflow" && 0 == addr); + } /* end if */ + else { + for(u = 0; u < addr_len; u++) + *(*pp)++ = 0xff; + } /* end else */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_encode_len() */ /*------------------------------------------------------------------------- @@ -3091,35 +2301,24 @@ done: * Programmer: Robb Matzke * Friday, November 7, 1997 * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. *------------------------------------------------------------------------- */ void H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) { - unsigned u; /* Local index variable */ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_addr_encode) HDassert(f); - HDassert(pp && *pp); - if(H5F_addr_defined(addr)) { - for(u = 0; u < H5F_SIZEOF_ADDR(f); u++) { - *(*pp)++ = (uint8_t)(addr & 0xff); - addr >>= 8; - } /* end for */ - assert("overflow" && 0 == addr); - } /* end if */ - else { - for(u = 0; u < H5F_SIZEOF_ADDR(f); u++) - *(*pp)++ = 0xff; - } /* end else */ + H5F_addr_encode_len(H5F_SIZEOF_ADDR(f), pp, addr); + + FUNC_LEAVE_NOAPI_VOID } /* end H5F_addr_encode() */ /*------------------------------------------------------------------------- - * Function: H5F_addr_decode + * Function: H5F_addr_decode_len * * Purpose: Decodes an address from the buffer pointed to by *PP and * updates the pointer to point to the next byte after the @@ -3133,40 +2332,88 @@ H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) * Programmer: Robb Matzke * Friday, November 7, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ void -H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +H5F_addr_decode_len(size_t addr_len, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) { - unsigned i; - haddr_t tmp; - uint8_t c; - hbool_t all_zero = TRUE; + hbool_t all_zero = TRUE; /* True if address was all zeroes */ + unsigned u; /* Local index variable */ - assert(f); - assert(pp && *pp); - assert(addr_p); + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_addr_decode_len) + HDassert(addr_len); + HDassert(pp && *pp); + HDassert(addr_p); + + /* Reset value in destination */ *addr_p = 0; - for (i=0; i<H5F_SIZEOF_ADDR(f); i++) { + /* Decode bytes from address */ + for(u = 0; u < addr_len; u++) { + uint8_t c; /* Local decoded byte */ + + /* Get decoded byte (and advance pointer) */ c = *(*pp)++; - if (c != 0xff) + + /* Check for non-undefined address byte value */ + if(c != 0xff) all_zero = FALSE; - if (i<sizeof(*addr_p)) { - tmp = c; - tmp <<= (i * 8); /*use tmp to get casting right */ + if(u < sizeof(*addr_p)) { + haddr_t tmp = c; /* Local copy of address, for casting */ + + /* Shift decoded byte to correct position */ + tmp <<= (u * 8); /*use tmp to get casting right */ + + /* Merge into already decoded bytes */ *addr_p |= tmp; - } else if (!all_zero) { - assert(0 == **pp); /*overflow */ - } - } - if (all_zero) + } /* end if */ + else + if(!all_zero) + HDassert(0 == **pp); /*overflow */ + } /* end for */ + + /* If 'all_zero' is still TRUE, the address was entirely composed of '0xff' + * bytes, which is the encoded form of 'HADDR_UNDEF', so set the destination + * to that value */ + if(all_zero) *addr_p = HADDR_UNDEF; -} + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_decode_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_decode + * + * Purpose: Decodes an address from the buffer pointed to by *PP and + * updates the pointer to point to the next byte after the + * address. + * + * If the value read is all 1's then the address is returned + * with an undefined value. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_addr_decode) + + HDassert(f); + + H5F_addr_decode_len(H5F_SIZEOF_ADDR(f), pp, addr_p); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_decode() */ /*------------------------------------------------------------------------- @@ -3186,20 +2433,23 @@ H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*o hssize_t H5Fget_freespace(hid_t file_id) { - H5F_t *file=NULL; /* File object for file ID */ + H5F_t *file; /* File object for file ID */ + hsize_t tot_space; /* Amount of free space in the file */ hssize_t ret_value; /* Return value */ FUNC_ENTER_API(H5Fget_freespace, FAIL) H5TRACE1("Hs", "i", file_id); /* Check args */ - if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Go get the actual amount of free space in the file */ - if((ret_value = H5FD_get_freespace(file->shared->lf)) < 0) + if(H5MF_get_freespace(file, H5AC_ind_dxpl_id, &tot_space, NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + ret_value = (hssize_t)tot_space; + done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_freespace() */ @@ -3226,20 +2476,20 @@ done: herr_t H5Fget_filesize(hid_t file_id, hsize_t *size) { - H5F_t *file=NULL; /* File object for file ID */ - herr_t ret_value = SUCCEED; /* Return value */ - haddr_t eof; + H5F_t *file; /* File object for file ID */ + haddr_t eof; /* End of file address */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Fget_filesize, FAIL) H5TRACE2("e", "i*h", file_id, size); /* Check args */ - if(NULL==(file=H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Go get the actual file size */ - if((eof = H5FDget_eof(file->shared->lf))==HADDR_UNDEF) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") + if(HADDR_UNDEF == (eof = H5FDget_eof(file->shared->lf))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") *size = (hsize_t)eof; @@ -3270,16 +2520,16 @@ herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) { H5F_t *file; /* File object for file ID */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Fget_mdc_config, FAIL) H5TRACE2("e", "i*x", file_id, config_ptr); /* Check args */ - if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") if((NULL == config_ptr) || (config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Bad config_ptr") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Bad config_ptr") /* Go get the resize configuration */ if(H5AC_get_cache_auto_resize_config(file->shared->cache, config_ptr) < 0) @@ -3315,7 +2565,7 @@ H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) H5TRACE2("e", "i*x", file_id, config_ptr); /* Check args */ - if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* set the resize configuration */ @@ -3353,10 +2603,11 @@ H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate_ptr) H5TRACE2("e", "i*d", file_id, hit_rate_ptr); /* Check args */ - if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + if(NULL == hit_rate_ptr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL hit rate pointer") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL hit rate pointer") /* Go get the current hit rate */ if(H5AC_get_cache_hit_rate(file->shared->cache, hit_rate_ptr) < 0) @@ -3397,7 +2648,7 @@ H5Fget_mdc_size(hid_t file_id, size_t *max_size_ptr, size_t *min_clean_size_ptr, cur_size_ptr, cur_num_entries_ptr); /* Check args */ - if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Go get the size data */ @@ -3443,7 +2694,7 @@ H5Freset_mdc_hit_rate_stats(hid_t file_id) H5TRACE1("e", "i", file_id); /* Check args */ - if(NULL == (file = H5I_object_verify(file_id, H5I_FILE))) + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Reset the hit rate statistic */ @@ -3466,6 +2717,9 @@ done: * If an error occurs then the buffer pointed to by `name' (NULL or non-NULL) * is unchanged and the function returns a negative value. * + * Note: This routine returns the name that was used to open the file, + * not the actual name after resolving symlinks, etc. + * * Return: Success: The length of the file name * Failure: Negative * @@ -3489,7 +2743,7 @@ H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size) * the top file in a mount hierarchy) */ if(H5I_get_type(obj_id) == H5I_FILE ) { - if(NULL == (f = H5I_object(obj_id))) + if(NULL == (f = (H5F_t *)H5I_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") } /* end if */ else { @@ -3501,10 +2755,10 @@ H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size) f = loc.oloc->file; } /* end else */ - len = HDstrlen(f->name); + len = HDstrlen(H5F_OPEN_NAME(f)); if(name) { - HDstrncpy(name, f->name, MIN(len+1,size)); + HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size)); if(len >= size) name[size-1]='\0'; } /* end if */ @@ -3518,26 +2772,29 @@ done: /*------------------------------------------------------------------------- - * Function: H5Fget_info - * 1. Get storage size for superblock extension if there is one + * Function: H5Fget_info2 + * + * Purpose: Gets general information about the file, including: + * 1. Get storage size for superblock extension if there is one. * 2. Get the amount of btree and heap storage for entries * in the SOHM table if there is one. - * Consider success when there is no superblock extension and/or SOHM table + * 3. The amount of free space tracked in the file. * * Return: Success: non-negative on success * Failure: Negative * * Programmer: Vailin Choi * July 11, 2007 + * *------------------------------------------------------------------------- */ herr_t -H5Fget_info(hid_t obj_id, H5F_info_t *finfo) +H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo) { H5F_t *f; /* Top file in mount hierarchy */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Fget_info, FAIL) + FUNC_ENTER_API(H5Fget_info2, FAIL) H5TRACE2("e", "i*x", obj_id, finfo); /* Check args */ @@ -3549,7 +2806,7 @@ H5Fget_info(hid_t obj_id, H5F_info_t *finfo) * the top file in a mount hierarchy) */ if(H5I_get_type(obj_id) == H5I_FILE ) { - if(NULL == (f = H5I_object(obj_id))) + if(NULL == (f = (H5F_t *)H5I_object(obj_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") } /* end if */ else { @@ -3563,19 +2820,67 @@ H5Fget_info(hid_t obj_id, H5F_info_t *finfo) HDassert(f->shared); /* Reset file info struct */ - HDmemset(finfo, 0, sizeof(H5F_info_t)); + HDmemset(finfo, 0, sizeof(*finfo)); - /* Check for superblock extension info */ - if(H5F_addr_defined(f->shared->extension_addr)) - if(H5F_super_ext_size(f, H5AC_ind_dxpl_id, &finfo->super_ext_size) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock extension size") + /* Get the size of the superblock and any superblock extensions */ + if(H5F_super_size(f, H5AC_ind_dxpl_id, &finfo->super.super_size, &finfo->super.super_ext_size) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock sizes") + + /* Get the size of any persistent free space */ + if(H5MF_get_freespace(f, H5AC_ind_dxpl_id, &finfo->free.tot_space, &finfo->free.meta_size) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve free space information") /* Check for SOHM info */ if(H5F_addr_defined(f->shared->sohm_addr)) - if(H5SM_ih_size(f, H5AC_ind_dxpl_id, finfo) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM btree & heap storage info") + if(H5SM_ih_size(f, H5AC_ind_dxpl_id, &finfo->sohm.hdr_size, &finfo->sohm.msgs_info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM index & heap storage info") + + /* Set version # fields */ + finfo->super.version = f->shared->sblock->super_vers; + finfo->sohm.version = f->shared->sohm_vers; + finfo->free.version = HDF5_FREESPACE_VERSION; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_info2() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fget_free_sections + * + * Purpose: To get free-space section information for free-space manager with + * TYPE that is associated with file FILE_ID. + * If SECT_INFO is null, this routine returns the total # of free-space + * sections. + * + * Return: Success: non-negative, the total # of free space sections + * Failure: negative + * + * Programmer: Vailin Choi; July 1st, 2009 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, + H5F_sect_info_t *sect_info/*out*/) +{ + H5F_t *file; /* Top file in mount hierarchy */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Fget_free_sections, FAIL) + H5TRACE4("Zs", "iFmzx", file_id, type, nsects, sect_info); + + /* Check args */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + if(sect_info && nsects == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "nsects must be > 0") + + /* Go get the free-space section information in the file */ + if((ret_value = H5MF_get_free_sections(file, H5AC_ind_dxpl_id, type, nsects, sect_info)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") done: FUNC_LEAVE_API(ret_value) -} /* end H5Fget_info() */ +} /* end H5Fget_free_sections() */ |