/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * Purpose: File callbacks for the native VOL connector * */ #define H5F_FRIEND /* Suppress error about including H5Fpkg */ #include "H5private.h" /* Generic Functions */ #include "H5ACprivate.h" /* Metadata cache */ #include "H5Cprivate.h" /* Cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* Files */ #include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5MFprivate.h" /* File memory management */ #include "H5Pprivate.h" /* Property lists */ #include "H5PBprivate.h" /* Page buffering */ #include "H5VLprivate.h" /* Virtual Object Layer */ #include "H5VLnative_private.h" /* Native VOL connector */ /*------------------------------------------------------------------------- * Function: H5VL__native_file_create * * Purpose: Handles the file create callback * * Return: Success: file pointer * Failure: NULL * *------------------------------------------------------------------------- */ void * H5VL__native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5F_t *new_file = NULL; void *ret_value = NULL; FUNC_ENTER_PACKAGE /* Adjust bit flags by turning on the creation bit and making sure that * the EXCL or TRUNC bit is set. All newly-created files are opened for * reading and writing. */ if(0 == (flags & (H5F_ACC_EXCL|H5F_ACC_TRUNC))) flags |= H5F_ACC_EXCL; /* default */ flags |= H5F_ACC_RDWR | H5F_ACC_CREAT; /* Create the file */ if(NULL == (new_file = H5F_open(name, flags, fcpl_id, fapl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create file") new_file->id_exists = TRUE; ret_value = (void *)new_file; done: if(NULL == ret_value && new_file) if(H5F__close(new_file) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_file_create() */ /*------------------------------------------------------------------------- * Function: H5VL__native_file_open * * Purpose: Handles the file open callback * * Return: Success: file pointer * Failure: NULL * *------------------------------------------------------------------------- */ void * H5VL__native_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5F_t *new_file = NULL; void *ret_value = NULL; FUNC_ENTER_PACKAGE /* Open the file */ if(NULL == (new_file = H5F_open(name, flags, H5P_FILE_CREATE_DEFAULT, fapl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") new_file->id_exists = TRUE; ret_value = (void *)new_file; done: if(NULL == ret_value && new_file && H5F_try_close(new_file, NULL) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_file_open() */ /*------------------------------------------------------------------------- * Function: H5VL__native_file_get * * Purpose: Handles the file get callback * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) { H5F_t *f = NULL; /* File struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE switch(get_type) { /* H5Fget_access_plist */ case H5VL_FILE_GET_FAPL: { H5P_genplist_t *new_plist; /* New property list */ hid_t *plist_id = HDva_arg(arguments, hid_t *); f = (H5F_t *)obj; /* Retrieve the file's access property list */ if((*plist_id = H5F_get_access_plist(f, TRUE)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list") if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") break; } /* H5Fget_create_plist */ case H5VL_FILE_GET_FCPL: { H5P_genplist_t *plist; /* Property list */ hid_t *plist_id = HDva_arg(arguments, hid_t *); f = (H5F_t *)obj; if(NULL == (plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") /* Create the property list object to return */ if((*plist_id = H5P_copy_plist(plist, TRUE)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy file creation properties") break; } /* H5Fget_obj_count */ case H5VL_FILE_GET_OBJ_COUNT: { unsigned types = HDva_arg(arguments, unsigned); ssize_t *ret = HDva_arg(arguments, ssize_t *); size_t obj_count = 0; /* Number of opened objects */ f = (H5F_t *)obj; /* Perform the query */ if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed") /* Set the return value */ *ret = (ssize_t)obj_count; break; } /* H5Fget_obj_ids */ case H5VL_FILE_GET_OBJ_IDS: { unsigned types = HDva_arg(arguments, unsigned); size_t max_objs = HDva_arg(arguments, size_t); hid_t *oid_list = HDva_arg(arguments, hid_t *); ssize_t *ret = HDva_arg(arguments, ssize_t *); size_t obj_count = 0; /* Number of opened objects */ f = (H5F_t *)obj; /* Perform the query */ if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") /* Set the return value */ *ret = (ssize_t)obj_count; break; } /* H5Fget_intent */ case H5VL_FILE_GET_INTENT: { unsigned *intent_flags = HDva_arg(arguments, unsigned *); f = (H5F_t *)obj; /* 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 and any SWMR flags. */ if(H5F_INTENT(f) & H5F_ACC_RDWR) { *intent_flags = H5F_ACC_RDWR; /* Check for SWMR write access on the file */ if(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) *intent_flags |= H5F_ACC_SWMR_WRITE; } /* end if */ else { *intent_flags = H5F_ACC_RDONLY; /* Check for SWMR read access on the file */ if(H5F_INTENT(f) & H5F_ACC_SWMR_READ) *intent_flags |= H5F_ACC_SWMR_READ; } /* end else */ break; } /* H5Fget_name */ case H5VL_FILE_GET_NAME: { H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ size_t size = HDva_arg(arguments, size_t); char *name = HDva_arg(arguments, char *); ssize_t *ret = HDva_arg(arguments, ssize_t *); size_t len; if(NULL == (f = H5F__get_file(obj, type))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") len = HDstrlen(H5F_OPEN_NAME(f)); if(name) { HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size)); if(len >= size) name[size-1]='\0'; } /* end if */ /* Set the return value for the API call */ *ret = (ssize_t)len; break; } default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information") } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_file_get() */ /*------------------------------------------------------------------------- * Function: H5VL__native_file_specific * * Purpose: Handles the file specific callback * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE switch(specific_type) { /* H5Fflush */ case H5VL_FILE_FLUSH: { H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ H5F_scope_t scope = (H5F_scope_t)HDva_arg(arguments, int); /* enum work-around */ H5F_t *f = NULL; /* File to flush */ /* Get the file for the object */ if(NULL == (f = H5F__get_file(obj, type))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* 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) < 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) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") } /* end else */ } /* end if */ break; } /* H5Freopen */ case H5VL_FILE_REOPEN: { void **ret = HDva_arg(arguments, void **); H5F_t *new_file = NULL; /* Reopen the file through the VOL connector */ if(NULL == (new_file = H5F__reopen((H5F_t *)obj))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") new_file->id_exists = TRUE; *ret = (void *)new_file; break; } /* H5Fmount */ case H5VL_FILE_MOUNT: { H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ const char *name = HDva_arg(arguments, const char *); H5F_t *child = HDva_arg(arguments, H5F_t *); hid_t plist_id = HDva_arg(arguments, hid_t); H5G_loc_t loc; if(H5G_loc_real(obj, type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Do the mount */ if(H5F__mount(&loc, name, child, plist_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") break; } /* H5Funmount */ case H5VL_FILE_UNMOUNT: { H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ const char *name = HDva_arg(arguments, const char *); H5G_loc_t loc; if(H5G_loc_real(obj, type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") /* Unmount */ if(H5F__unmount(&loc, name) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file") break; } /* H5Fis_accessible */ case H5VL_FILE_IS_ACCESSIBLE: { hid_t fapl_id = HDva_arg(arguments, hid_t); const char *name = HDva_arg(arguments, const char *); htri_t *ret = HDva_arg(arguments, htri_t *); /* Call private routine */ if((*ret = H5F__is_hdf5(name, fapl_id)) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "error in HDF5 file check") break; } default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation") } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_file_specific() */ /*------------------------------------------------------------------------- * Function: H5VL__native_file_optional * * Purpose: Handles the file optional callback * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5VL__native_file_optional(void *obj, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req, va_list arguments) { H5F_t *f = NULL; /* File */ H5VL_native_file_optional_t optional_type = HDva_arg(arguments, H5VL_native_file_optional_t); herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE f = (H5F_t *)obj; switch(optional_type) { /* H5Fget_filesize */ case H5VL_NATIVE_FILE_GET_SIZE: { haddr_t max_eof_eoa; /* Maximum of the EOA & EOF */ haddr_t base_addr; /* Base address for the file */ hsize_t *size = HDva_arg(arguments, hsize_t *); /* Go get the actual file size */ if(H5F__get_max_eof_eoa(f, &max_eof_eoa) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") base_addr = H5FD_get_base_addr(f->shared->lf); if(size) *size = (hsize_t)(max_eof_eoa + base_addr); /* Convert relative base address for file to absolute address */ break; } /* H5Fget_file_image */ case H5VL_NATIVE_FILE_GET_FILE_IMAGE: { void *buf_ptr = HDva_arg(arguments, void *); ssize_t *ret = HDva_arg(arguments, ssize_t *); size_t buf_len = HDva_arg(arguments, size_t ); /* Do the actual work */ if((*ret = H5F__get_file_image(f, buf_ptr, buf_len)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get file image failed") break; } /* H5Fget_freespace */ case H5VL_NATIVE_FILE_GET_FREE_SPACE: { hsize_t tot_space; /* Amount of free space in the file */ hssize_t *ret = HDva_arg(arguments, hssize_t *); /* Go get the actual amount of free space in the file */ if(H5MF_get_freespace(f, &tot_space, NULL) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") *ret = (hssize_t)tot_space; break; } /* H5Fget_free_sections */ case H5VL_NATIVE_FILE_GET_FREE_SECTIONS: { H5F_sect_info_t *sect_info = HDva_arg(arguments, H5F_sect_info_t *); ssize_t *ret = HDva_arg(arguments, ssize_t *); H5F_mem_t type = (H5F_mem_t)HDva_arg(arguments, int); /* enum work-around */ size_t nsects = HDva_arg(arguments, size_t); /* Go get the free-space section information in the file */ if((*ret = H5MF_get_free_sections(f, type, nsects, sect_info)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") break; } /* H5Fget_info1/2 */ case H5VL_NATIVE_FILE_GET_INFO: { H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ H5F_info2_t *finfo = HDva_arg(arguments, H5F_info2_t *); /* Get the file struct. This call is careful to not return the file pointer * for the top file in a mount hierarchy. */ if(NULL == (f = H5F__get_file(obj, type))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get a file struct") /* Get the file info */ if(H5F__get_info(f, finfo) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") break; } /* H5Fget_mdc_config */ case H5VL_NATIVE_FILE_GET_MDC_CONF: { H5AC_cache_config_t *config_ptr = HDva_arg(arguments, H5AC_cache_config_t *); /* Go get the resize configuration */ if(H5AC_get_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_auto_resize_config() failed.") break; } /* H5Fget_mdc_hit_rate */ case H5VL_NATIVE_FILE_GET_MDC_HR: { double *hit_rate_ptr = HDva_arg(arguments, double *); /* Go get the current hit rate */ if(H5AC_get_cache_hit_rate(f->shared->cache, hit_rate_ptr) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_hit_rate() failed.") break; } /* H5Fget_mdc_size */ case H5VL_NATIVE_FILE_GET_MDC_SIZE: { size_t *max_size_ptr = HDva_arg(arguments, size_t *); size_t *min_clean_size_ptr = HDva_arg(arguments, size_t *); size_t *cur_size_ptr = HDva_arg(arguments, size_t *); int *cur_num_entries_ptr = HDva_arg(arguments, int *); uint32_t cur_num_entries; /* Go get the size data */ if(H5AC_get_cache_size(f->shared->cache, max_size_ptr, min_clean_size_ptr, cur_size_ptr, &cur_num_entries) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_size() failed.") if(cur_num_entries_ptr != NULL) *cur_num_entries_ptr = (int)cur_num_entries; break; } /* H5Fget_vfd_handle */ case H5VL_NATIVE_FILE_GET_VFD_HANDLE: { void **file_handle = HDva_arg(arguments, void **); hid_t fapl_id = HDva_arg(arguments, hid_t); /* Retrieve the VFD handle for the file */ if(H5F_get_vfd_handle(f, fapl_id, file_handle) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle") break; } /* H5Iget_file_id */ case H5VL_NATIVE_FILE_GET_FILE_ID: { H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */ hid_t *file_id = HDva_arg(arguments, hid_t *); if(NULL == (f = H5F__get_file(obj, type))) HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a file or file object") if((*file_id = H5F__get_file_id(f)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file ID") break; } /* H5Fclear_elink_file_cache */ case H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE: { /* Release the EFC */ if(f->shared->efc) if(H5F__efc_release(f->shared->efc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") break; } /* H5Freset_mdc_hit_rate_stats */ case H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE: { /* Reset the hit rate statistic */ if(H5AC_reset_cache_hit_rate_stats(f->shared->cache) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't reset cache hit rate") break; } /* H5Fset_mdc_config */ case H5VL_NATIVE_FILE_SET_MDC_CONFIG: { H5AC_cache_config_t *config_ptr = HDva_arg(arguments, H5AC_cache_config_t *); /* set the resize configuration */ if(H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "H5AC_set_cache_auto_resize_config() failed") break; } /* H5Fget_metadata_read_retry_info */ case H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO: { H5F_retry_info_t *info = HDva_arg(arguments, H5F_retry_info_t *); if(H5F_get_metadata_read_retry_info(f, info) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't get metadata read retry info") break; } /* H5Fstart_swmr_write */ case H5VL_NATIVE_FILE_START_SWMR_WRITE: { if(H5F__start_swmr_write(f) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't start SWMR write") break; } /* H5Fstart_mdc_logging */ case H5VL_NATIVE_FILE_START_MDC_LOGGING: { /* Call mdc logging function */ if(H5C_start_logging(f->shared->cache) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to start mdc logging") break; } /* H5Fstop_mdc_logging */ case H5VL_NATIVE_FILE_STOP_MDC_LOGGING: { /* Call mdc logging function */ if(H5C_stop_logging(f->shared->cache) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to stop mdc logging") break; } /* H5Fget_mdc_logging_status */ case H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS: { hbool_t *is_enabled = HDva_arg(arguments, hbool_t *); hbool_t *is_currently_logging = HDva_arg(arguments, hbool_t *); /* Call mdc logging function */ if(H5C_get_logging_status(f->shared->cache, is_enabled, is_currently_logging) < 0) HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to get logging status") break; } /* H5Fformat_convert */ case H5VL_NATIVE_FILE_FORMAT_CONVERT: { /* Convert the format */ if(H5F__format_convert(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCONVERT, FAIL, "can't convert file format") break; } /* H5Freset_page_buffering_stats */ case H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS: { /* Sanity check */ if(NULL == f->shared->page_buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "page buffering not enabled on file") /* Reset the statistics */ if(H5PB_reset_stats(f->shared->page_buf) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't reset stats for page buffering") break; } /* H5Fget_page_buffering_stats */ case H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS: { unsigned *accesses = HDva_arg(arguments, unsigned *); unsigned *hits = HDva_arg(arguments, unsigned *); unsigned *misses = HDva_arg(arguments, unsigned *); unsigned *evictions = HDva_arg(arguments, unsigned *); unsigned *bypasses = HDva_arg(arguments, unsigned *); /* Sanity check */ if(NULL == f->shared->page_buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "page buffering not enabled on file") /* Get the statistics */ if(H5PB_get_stats(f->shared->page_buf, accesses, hits, misses, evictions, bypasses) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stats for page buffering") break; } /* H5Fget_mdc_image_info */ case H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO: { haddr_t *image_addr = HDva_arg(arguments, haddr_t *); hsize_t *image_len = HDva_arg(arguments, hsize_t *); /* Go get the address and size of the cache image */ if(H5AC_get_mdc_image_info(f->shared->cache, image_addr, image_len) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve cache image info") break; } /* H5Fget_eoa */ case H5VL_NATIVE_FILE_GET_EOA: { haddr_t *eoa = HDva_arg(arguments, haddr_t *); haddr_t rel_eoa; /* Relative address of EOA */ /* Sanity check */ HDassert(eoa); /* This routine will work only for drivers with this feature enabled.*/ /* We might introduce a new feature flag in the future */ if(!H5F_HAS_FEATURE(f, H5FD_FEAT_SUPPORTS_SWMR_IO)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must use a SWMR-compatible VFD for this public routine") /* The real work */ if(HADDR_UNDEF == (rel_eoa = H5F_get_eoa(f, H5FD_MEM_DEFAULT))) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get_eoa request failed") /* Set return value */ /* (Note compensating for base address subtraction in internal routine) */ *eoa = rel_eoa + H5F_get_base_addr(f); break; } /* H5Fincrement_filesize */ case H5VL_NATIVE_FILE_INCR_FILESIZE: { hsize_t increment = HDva_arg(arguments, hsize_t); haddr_t max_eof_eoa; /* Maximum of the relative EOA & EOF */ /* This public routine will work only for drivers with this feature enabled.*/ /* We might introduce a new feature flag in the future */ if(!H5F_HAS_FEATURE(f, H5FD_FEAT_SUPPORTS_SWMR_IO)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must use a SWMR-compatible VFD for this public routine") /* Get the maximum of EOA and EOF */ if(H5F__get_max_eof_eoa(f, &max_eof_eoa) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") /* Set EOA to the maximum value + increment */ if(H5F__set_eoa(f, H5FD_MEM_DEFAULT, max_eof_eoa + increment) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set_eoa request failed") break; } /* H5Fset_latest_format, H5Fset_libver_bounds */ case H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS: { H5F_libver_t low = (H5F_libver_t)HDva_arg(arguments, int); /* enum work-around */ H5F_libver_t high = (H5F_libver_t)HDva_arg(arguments, int); /* enum work-around */ /* Call internal set_libver_bounds function */ if(H5F__set_libver_bounds(f, low, high) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set low/high bounds") break; } default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid optional operation") } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_file_optional() */ /*------------------------------------------------------------------------- * Function: H5VL__native_file_close * * Purpose: Handles the file close callback * * Return: Success: SUCCEED * Failure: FAIL (file will not be closed) * *------------------------------------------------------------------------- */ herr_t H5VL__native_file_close(void *file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { int nref; H5F_t *f = (H5F_t *)file; hid_t file_id = H5I_INVALID_HID; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* This routine should only be called when a file ID's ref count drops to zero */ HDassert(H5F_ID_EXISTS(f)); /* Flush file if this is the last reference to this id and we have write * intent, unless it will be flushed by the "shared" file being closed. * This is only necessary to replicate previous behaviour, and could be * disabled by an option/property to improve performance. */ if((H5F_NREFS(f) > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) { /* Get the file ID corresponding to the H5F_t struct */ if(H5I_find_id(f, H5I_FILE, &file_id) < 0 || H5I_INVALID_HID == file_id) HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "invalid atom") /* Get the number of references outstanding for this file ID */ if((nref = H5I_get_ref(file_id, FALSE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") if(nref == 1) if(H5F__flush(f) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") } /* end if */ /* Close the file */ if(H5F__close(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close file") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_file_close() */