diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2018-03-15 21:54:30 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2018-03-15 21:54:30 (GMT) |
commit | 4a17aff4085ad6ee265b95730aca3f493056dec8 (patch) | |
tree | 8bfb665c6d95a2e3520fa1bb0ff54d95aff3923f /src/H5F.c | |
parent | 853ae26333592faf69cd8c454ef92ffea8549df5 (diff) | |
download | hdf5-4a17aff4085ad6ee265b95730aca3f493056dec8.zip hdf5-4a17aff4085ad6ee265b95730aca3f493056dec8.tar.gz hdf5-4a17aff4085ad6ee265b95730aca3f493056dec8.tar.bz2 |
Add API context interface and use it throughout the library.
Diffstat (limited to 'src/H5F.c')
-rw-r--r-- | src/H5F.c | 483 |
1 files changed, 185 insertions, 298 deletions
@@ -24,6 +24,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Aprivate.h" /* Attributes */ #include "H5ACprivate.h" /* Metadata cache */ +#include "H5CXprivate.h" /* API Contexts */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ @@ -33,7 +34,6 @@ #include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#include "H5SMprivate.h" /* Shared Object Header Messages */ #include "H5Tprivate.h" /* Datatypes */ @@ -79,7 +79,7 @@ static const H5I_class_t H5I_FILE_CLS[1] = {{ H5I_FILE, /* ID class value */ 0, /* Class flags */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5F_close /* Callback routine for closing objects of this class */ + (H5I_free_t)H5F__close_cb /* Callback routine for closing objects of this class */ }}; @@ -355,6 +355,7 @@ done: htri_t H5Fis_hdf5(const char *name) { +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ htri_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -363,13 +364,19 @@ H5Fis_hdf5(const char *name) /* Check args and all the boring stuff. */ if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified") +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; /* call the private is_HDF5 function */ - if((ret_value = H5F__is_hdf5(name, H5AC_ind_read_dxpl_id, H5AC_rawdata_dxpl_id)) < 0) + /* (Should not trigger raw data I/O - QAK, 2018/01/03) */ + if((ret_value = H5F__is_hdf5(name)) < 0) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable open file") done: - +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fis_hdf5() */ @@ -401,36 +408,40 @@ hid_t H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) { H5F_t *new_file = NULL; /* file struct for new file */ - hid_t dxpl_id = H5AC_ind_read_dxpl_id;/* dxpl used by library */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ hid_t ret_value; /* return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); /* Check/fix arguments */ if (!filename || !*filename) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid file name") /* In this routine, we only accept the following flags: * H5F_ACC_EXCL, H5F_ACC_TRUNC and H5F_ACC_SWMR_WRITE */ if (flags & ~(H5F_ACC_EXCL | H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid flags") /* 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") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "mutually exclusive flags for file creation") /* Check file creation property list */ if (H5P_DEFAULT == fcpl_id) fcpl_id = H5P_FILE_CREATE_DEFAULT; else if (TRUE != H5P_isa_class(fcpl_id, H5P_FILE_CREATE)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file create property list") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not file create property list") - /* Verify access property list and get correct dxpl */ - if (H5P_verify_apl_and_dxpl(&fapl_id, H5P_CLS_FACC, &dxpl_id, H5I_INVALID_HID, TRUE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set access and transfer property lists") +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set API context") +api_ctx_pushed = TRUE; +/* Verify access property list and set up collective metadata if appropriate */ +if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") /* 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 @@ -441,19 +452,21 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) flags |= H5F_ACC_RDWR | H5F_ACC_CREAT; /* Create a new file or truncate an existing file. */ - if (NULL == (new_file = H5F_open(filename, flags, fcpl_id, fapl_id, dxpl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file") + if (NULL == (new_file = H5F__create(filename, flags, fcpl_id, fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to create file") /* Get an atom for the file */ if ((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file") /* Keep this ID in file object structure */ new_file->file_id = ret_value; done: - if (ret_value < 0 && new_file && H5F_try_close(new_file, NULL) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") + if(ret_value < 0 && new_file && H5F_try_close(new_file, NULL) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, H5I_INVALID_HID, "problems closing file") +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, H5I_INVALID_HID, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fcreate() */ @@ -482,45 +495,51 @@ hid_t H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) { H5F_t *new_file = NULL; /* file struct for new file */ - hid_t dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ hid_t ret_value; /* return value */ - FUNC_ENTER_API(FAIL) + FUNC_ENTER_API(H5I_INVALID_HID) H5TRACE3("i", "*sIui", filename, flags, fapl_id); /* Check/fix arguments. */ if(!filename || !*filename) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "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") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid file open flags") /* Asking for SWMR write access on a read-only file is invalid */ if((flags & H5F_ACC_SWMR_WRITE) && 0 == (flags & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "SWMR write access on a file open for read-only access is not allowed") + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "SWMR write access on a file open for read-only access is not allowed") /* Asking for SWMR read access on a non-read-only file is invalid */ if((flags & H5F_ACC_SWMR_READ) && (flags & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "SWMR read access on a file open for read-write access is not allowed") + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "SWMR read access on a file open for read-write access is not allowed") - /* Verify access property list and get correct dxpl */ - if(H5P_verify_apl_and_dxpl(&fapl_id, H5P_CLS_FACC, &dxpl_id, H5I_INVALID_HID, TRUE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set access and transfer property lists") +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set API context") +api_ctx_pushed = TRUE; +/* Verify access property list and set up collective metadata if appropriate */ +if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info") /* Open the file */ - if(NULL == (new_file = H5F_open(filename, flags, H5P_FILE_CREATE_DEFAULT, fapl_id, dxpl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file") + if(NULL == (new_file = H5F__open(filename, flags, H5P_FILE_CREATE_DEFAULT, fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open file") /* Get an atom for the file */ if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to atomize file handle") /* Keep this ID in file object structure */ new_file->file_id = ret_value; done: if(ret_value < 0 && new_file && H5F_try_close(new_file, NULL) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, H5I_INVALID_HID, "problems closing file") +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, H5I_INVALID_HID, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fopen() */ @@ -540,6 +559,7 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) { H5F_t *f = NULL; /* File to flush */ H5O_loc_t *oloc = NULL; /* Object location for ID */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -623,20 +643,24 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) * 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_ind_read_dxpl_id, H5AC_rawdata_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_ind_read_dxpl_id, H5AC_rawdata_dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") - } /* end else */ + hid_t fapl_id = H5P_DEFAULT; /* FAPL to use */ + +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; +/* Verify access property list and set up collective metadata if appropriate */ +if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, object_id, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set access property list info") + + /* Flush the file */ + if(H5F__flush(f, scope) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") } /* end if */ done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fflush() */ @@ -658,39 +682,28 @@ done: herr_t H5Fclose(hid_t file_id) { - H5F_t *f = NULL; - int nref; +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); - /* Check/fix arguments. */ - if (H5I_FILE != H5I_get_type(file_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") + /* Check arguments */ + if(H5I_FILE != H5I_get_type(file_id)) + HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a file ID") - /* 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 (NULL == (f = (H5F_t *)H5I_object(file_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if ((f->shared->nrefs > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) { - 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, H5AC_ind_read_dxpl_id, H5AC_rawdata_dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") - } - - /* Decrement reference count on atom. When it reaches zero the file will - * be closed. - */ - if (H5I_dec_app_ref(file_id) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; + + /* Close the file */ + if(H5F__close(file_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "closing file ID failed") done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fclose() */ @@ -739,7 +752,7 @@ H5Freopen(hid_t file_id) done: if(ret_value < 0 && new_file) - if(H5F__dest(new_file, H5AC_ind_read_dxpl_id, H5AC_rawdata_dxpl_id, FALSE) < 0) + if(H5F__dest(new_file, FALSE) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") FUNC_LEAVE_API(ret_value) @@ -810,6 +823,7 @@ H5Fget_freespace(hid_t file_id) { H5F_t *file; /* File object for file ID */ hsize_t tot_space; /* Amount of free space in the file */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ hssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -819,13 +833,20 @@ H5Fget_freespace(hid_t 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 amount of free space in the file */ - if(H5MF_get_freespace(file, H5AC_ind_read_dxpl_id, &tot_space, NULL) < 0) +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; + + /* Get the free space in the file */ + if(H5F__get_freespace(file, &tot_space) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") ret_value = (hssize_t)tot_space; done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fget_freespace() */ @@ -915,6 +936,7 @@ ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len) { H5F_t *file; /* File object for file ID */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -924,11 +946,19 @@ H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len) if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; + /* call private get_file_image function */ - if((ret_value = H5F_get_file_image(file, buf_ptr, buf_len, H5AC_ind_read_dxpl_id, H5AC_rawdata_dxpl_id)) < 0) + /* (Should not trigger raw data I/O - QAK, 2018/01/03) */ + if((ret_value = H5F__get_file_image(file, buf_ptr, buf_len)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file image") done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* H5Fget_file_image() */ @@ -1199,6 +1229,7 @@ herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo) { H5F_t *f; /* Top file in mount hierarchy */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1226,28 +1257,18 @@ H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo) } /* end else */ HDassert(f->shared); - /* Reset file info struct */ - HDmemset(finfo, 0, sizeof(*finfo)); - - /* Get the size of the superblock and any superblock extensions */ - if(H5F__super_size(f, H5AC_ind_read_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_read_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_read_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 API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; - /* Set version # fields */ - finfo->super.version = f->shared->sblock->super_vers; - finfo->sohm.version = f->shared->sohm_vers; - finfo->free.version = HDF5_FREESPACE_VERSION; + /* Get the file info */ + if(H5F__get_info(f, finfo) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info") done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fget_info2() */ @@ -1363,6 +1384,7 @@ 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 */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1374,11 +1396,18 @@ H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, 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_read_dxpl_id, type, nsects, sect_info)) < 0) +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; + + /* Get the free-space section information in the file */ + if((ret_value = H5F__get_free_sections(file, type, nsects, sect_info)) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fget_free_sections() */ @@ -1397,8 +1426,9 @@ done: herr_t H5Fclear_elink_file_cache(hid_t file_id) { - H5F_t *file; /* File */ - herr_t ret_value = SUCCEED; /* Return value */ + H5F_t *file; /* File */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); @@ -1407,12 +1437,21 @@ H5Fclear_elink_file_cache(hid_t 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") - /* Release the EFC */ - if(file->shared->efc) - if(H5F_efc_release(file->shared->efc) < 0) + /* See if there's an EFC */ + if(file->shared->efc) { +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; + + /* Release the EFC */ + if(H5F__efc_release(file->shared->efc) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + } /* end if */ done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fclear_elink_file_cache() */ @@ -1450,18 +1489,10 @@ done: herr_t H5Fstart_swmr_write(hid_t file_id) { + H5F_t *file; /* File info */ hbool_t ci_load = FALSE; /* whether MDC ci load requested */ hbool_t ci_write = FALSE; /* whether MDC CI write requested */ - H5F_t *file = NULL; /* File info */ - size_t grp_dset_count=0; /* # of open objects: groups & datasets */ - size_t nt_attr_count=0; /* # of opened named datatypes + opened attributes */ - hid_t *obj_ids=NULL; /* List of ids */ - H5G_loc_t *obj_glocs=NULL; /* Group location of the object */ - H5O_loc_t *obj_olocs=NULL; /* Object location */ - H5G_name_t *obj_paths=NULL; /* Group hierarchy path */ - size_t u; /* Local index variable */ - hbool_t setup = FALSE; /* Boolean flag to indicate whether SWMR setting is enabled */ - H5F_io_info2_t fio_info; /* I/O info for operation */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1491,154 +1522,21 @@ H5Fstart_swmr_write(hid_t file_id) if(ci_load || ci_write ) HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL, "can't have both SWMR and MDC cache image") - /* Flush the superblock extension */ - if(H5F_flush_tagged_metadata(file, file->shared->sblock->ext_addr, H5AC_ind_read_dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock extension") - - /* Flush data buffers */ - if(H5F__flush(file, H5AC_ind_read_dxpl_id, H5AC_rawdata_dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") - - /* Get the # of opened named datatypes and attributes */ - if(H5F_get_obj_count(file, H5F_OBJ_DATATYPE|H5F_OBJ_ATTR, FALSE, &nt_attr_count) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed") - if(nt_attr_count) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "named datatypes and/or attributes opened in the file") - - /* Get the # of opened datasets and groups */ - if(H5F_get_obj_count(file, H5F_OBJ_GROUP|H5F_OBJ_DATASET, FALSE, &grp_dset_count) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed") - - if(grp_dset_count) { - /* Allocate space for group and object locations */ - if((obj_ids = (hid_t *) H5MM_malloc(grp_dset_count * sizeof(hid_t))) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for hid_t") - if((obj_glocs = (H5G_loc_t *) H5MM_malloc(grp_dset_count * sizeof(H5G_loc_t))) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_loc_t") - if((obj_olocs = (H5O_loc_t *) H5MM_malloc(grp_dset_count * sizeof(H5O_loc_t))) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5O_loc_t") - if((obj_paths = (H5G_name_t *) H5MM_malloc(grp_dset_count * sizeof(H5G_name_t))) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_name_t") - - /* Get the list of opened object ids (groups & datasets) */ - if(H5F_get_obj_ids(file, H5F_OBJ_GROUP|H5F_OBJ_DATASET, grp_dset_count, obj_ids, FALSE, &grp_dset_count) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "H5F_get_obj_ids failed") - - /* Refresh opened objects (groups, datasets) in the file */ - for(u = 0; u < grp_dset_count; u++) { - H5O_loc_t *oloc; /* object location */ - H5G_loc_t tmp_loc; - - /* Set up the id's group location */ - obj_glocs[u].oloc = &obj_olocs[u]; - obj_glocs[u].path = &obj_paths[u]; - H5G_loc_reset(&obj_glocs[u]); - - /* get the id's object location */ - if((oloc = H5O_get_loc(obj_ids[u])) == NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object") - - /* Make deep local copy of object's location information */ - H5G_loc(obj_ids[u], &tmp_loc); - H5G_loc_copy(&obj_glocs[u], &tmp_loc, H5_COPY_DEEP); - - /* Close the object */ - if(H5I_dec_ref(obj_ids[u]) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEOBJ, FAIL, "decrementing object ID failed") - } /* end for */ - } /* end if */ - - /* Set up I/O info for operation */ - fio_info.f = file; - if(NULL == (fio_info.meta_dxpl = (H5P_genplist_t *)H5I_object(H5AC_ind_read_dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") - if(NULL == (fio_info.raw_dxpl = (H5P_genplist_t *)H5I_object(H5AC_rawdata_dxpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; +/* Set up collective metadata if appropriate */ +if(H5CX_set_loc(file_id, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") - /* Flush and reset the accumulator */ - if(H5F__accum_reset(&fio_info, TRUE) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTRESET, FAIL, "can't reset accumulator") - - /* Turn on SWMR write in shared file open flags */ - file->shared->flags |= H5F_ACC_SWMR_WRITE; - - /* Mark the file in SWMR writing mode */ - file->shared->sblock->status_flags |= H5F_SUPER_SWMR_WRITE_ACCESS; - - /* Set up metadata read attempts */ - file->shared->read_attempts = H5F_SWMR_METADATA_READ_ATTEMPTS; - - /* Initialize "retries" and "retries_nbins" */ - if(H5F_set_retries(file) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't set retries and retries_nbins") - - /* Turn off usage of accumulator */ - file->shared->feature_flags &= ~(unsigned)H5FD_FEAT_ACCUMULATE_METADATA; - if(H5FD_set_feature_flags(file->shared->lf, file->shared->feature_flags) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set feature_flags in VFD") - - setup = TRUE; - - /* Mark superblock as dirty */ - if(H5F_super_dirty(file) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty") - - /* Flush the superblock */ - if(H5F_flush_tagged_metadata(file, H5AC__SUPERBLOCK_TAG, H5AC_ind_read_dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock") - - /* Evict all flushed entries in the cache except the pinned superblock */ - if(H5F__evict_cache_entries(file, H5AC_ind_read_dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to evict file's cached information") - - /* Refresh (reopen) the objects (groups & datasets) in the file */ - for(u = 0; u < grp_dset_count; u++) - if(H5O_refresh_metadata_reopen(obj_ids[u], &obj_glocs[u], H5AC_ind_read_dxpl_id, TRUE) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't refresh-close object") - - /* Unlock the file */ - if(H5FD_unlock(file->shared->lf) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to unlock the file") + /* Call the internal routine */ + if(H5F__start_swmr_write(file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCONVERT, FAIL, "unable to convert file format") done: - if(ret_value < 0 && setup) { - HDassert(file); - - /* Re-enable accumulator */ - file->shared->feature_flags |= (unsigned)H5FD_FEAT_ACCUMULATE_METADATA; - if(H5FD_set_feature_flags(file->shared->lf, file->shared->feature_flags) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set feature_flags in VFD") - - /* Reset the # of read attempts */ - file->shared->read_attempts = H5F_METADATA_READ_ATTEMPTS; - if(H5F_set_retries(file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't set retries and retries_nbins") - - /* Un-set H5F_ACC_SWMR_WRITE in shared open flags */ - file->shared->flags &= ~H5F_ACC_SWMR_WRITE; - - /* Unmark the file: not in SWMR writing mode */ - file->shared->sblock->status_flags &= (uint8_t)(~H5F_SUPER_SWMR_WRITE_ACCESS); - - /* Mark superblock as dirty */ - if(H5F_super_dirty(file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty") - - /* Flush the superblock */ - if(H5F_flush_tagged_metadata(file, H5AC__SUPERBLOCK_TAG, H5AC_ind_read_dxpl_id) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock") - } /* end if */ - - /* Free memory */ - if(obj_ids) - H5MM_xfree(obj_ids); - if(obj_glocs) - H5MM_xfree(obj_glocs); - if(obj_olocs) - H5MM_xfree(obj_olocs); - if(obj_paths) - H5MM_xfree(obj_paths); - +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fstart_swmr_write() */ @@ -1752,6 +1650,7 @@ H5Fset_latest_format(hid_t file_id, hbool_t latest_format) { H5F_t *f; /* File */ unsigned latest_flags; /* Latest format flags for file */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1764,8 +1663,18 @@ H5Fset_latest_format(hid_t file_id, hbool_t latest_format) /* Check if the value is changing */ latest_flags = H5F_USE_LATEST_FLAGS(f, H5F_LATEST_ALL_FLAGS); if(latest_format != (H5F_LATEST_ALL_FLAGS == latest_flags)) { + hid_t fapl_id = H5P_DEFAULT; /* FAPL to use */ + +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; +/* Verify access property list and set up collective metadata if appropriate */ +if(H5CX_set_apl(&fapl_id, H5P_CLS_FACC, file_id, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set access property list info") + /* Call the flush routine, for this file */ - if(H5F__flush(f, H5AC_ind_read_dxpl_id, H5AC_rawdata_dxpl_id, FALSE) < 0) + if(H5F__flush_real(f, FALSE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") /* Toggle the 'latest format' flag */ @@ -1773,12 +1682,14 @@ H5Fset_latest_format(hid_t file_id, hbool_t latest_format) } /* end if */ done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fset_latest_format() */ /*------------------------------------------------------------------------- - * Function: H5Fformat_convert_super (Internal) + * Function: H5Fformat_convert * * Purpose: Downgrade the superblock version to v2 and * downgrade persistent file space to non-persistent @@ -1790,59 +1701,35 @@ done: herr_t H5Fformat_convert(hid_t fid) { - herr_t ret_value = SUCCEED; /* Return value */ + H5F_t *f; /* File to flush */ +hbool_t api_ctx_pushed = FALSE; /* Whether API context pushed */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", fid); - if(H5I_FILE == H5I_get_type(fid)) { - H5F_t *f; /* File to flush */ - hbool_t mark_dirty = FALSE; - - /* Get file object */ - if(NULL == (f = (H5F_t *)H5I_object(fid))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + if(H5I_FILE != H5I_get_type(fid)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - /* Check if the superblock should be downgraded */ - if(f->shared->sblock->super_vers > HDF5_SUPERBLOCK_VERSION_V18_LATEST) { - f->shared->sblock->super_vers = HDF5_SUPERBLOCK_VERSION_V18_LATEST; - mark_dirty = TRUE; - } /* end if */ + /* Get file object */ + if(NULL == (f = (H5F_t *)H5I_object(fid))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Check for persistent freespace manager, which needs to be downgraded */ - if(!(f->shared->fs_strategy == H5F_FILE_SPACE_STRATEGY_DEF && - f->shared->fs_persist == H5F_FREE_SPACE_PERSIST_DEF && - f->shared->fs_threshold == H5F_FREE_SPACE_THRESHOLD_DEF && - f->shared->fs_page_size == H5F_FILE_SPACE_PAGE_SIZE_DEF)) { - /* Check to remove free-space manager info message from superblock extension */ - if(H5F_addr_defined(f->shared->sblock->ext_addr)) - if(H5F_super_ext_remove_msg(f, H5AC_ind_read_dxpl_id, H5O_FSINFO_ID) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "error in removing message from superblock extension") - - /* Close freespace manager */ - if(H5MF_try_close(f, H5AC_ind_read_dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to free free-space address") - - /* Set non-persistent freespace manager */ - f->shared->fs_strategy = H5F_FILE_SPACE_STRATEGY_DEF; - f->shared->fs_persist = H5F_FREE_SPACE_PERSIST_DEF; - f->shared->fs_threshold = H5F_FREE_SPACE_THRESHOLD_DEF; - f->shared->fs_page_size = H5F_FILE_SPACE_PAGE_SIZE_DEF; - - /* Indicate that the superblock should be marked dirty */ - mark_dirty = TRUE; - } /* end if */ +/* Set API context */ +if(H5CX_push() < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set API context") +api_ctx_pushed = TRUE; +/* Set up collective metadata if appropriate */ +if(H5CX_set_loc(fid, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info") - /* Check if we should mark the superblock dirty */ - if(mark_dirty) - /* Mark superblock as dirty */ - if(H5F_super_dirty(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty") - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + /* Call the internal routine */ + if(H5F__format_convert(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCONVERT, FAIL, "unable to convert file format") done: +if(api_ctx_pushed && H5CX_pop() < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRESET, FAIL, "can't reset API context") FUNC_LEAVE_API(ret_value) } /* end H5Fformat_convert() */ |