diff options
author | Vailin Choi <vchoi@jam.ad.hdfgroup.org> | 2017-10-03 19:57:36 (GMT) |
---|---|---|
committer | Vailin Choi <vchoi@jam.ad.hdfgroup.org> | 2017-10-03 19:57:36 (GMT) |
commit | fe70476a225d2e0576149e0f1bdf95689f922c77 (patch) | |
tree | ca07b675475ec83f9c8588c0256d585e69688578 | |
parent | 9d6ba29a01079e0f81ffa530605d8cd830378f9c (diff) | |
download | hdf5-fe70476a225d2e0576149e0f1bdf95689f922c77.zip hdf5-fe70476a225d2e0576149e0f1bdf95689f922c77.tar.gz hdf5-fe70476a225d2e0576149e0f1bdf95689f922c77.tar.bz2 |
Initial checkin for library version bounds
Code changes to provide versioning support when adding to the enumerated defines for H5F_libver_t.
39 files changed, 2163 insertions, 364 deletions
diff --git a/src/H5Aint.c b/src/H5Aint.c index 160c7fb..bfc69ec 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -112,6 +112,13 @@ static herr_t H5A__attr_sort_table(H5A_attr_table_t *atable, H5_index_t idx_type /* Local Variables */ /*******************/ +/* Format version bounds for attribute */ +static const unsigned H5O_attr_ver_bounds[] = { + H5O_ATTR_VERSION_1, /* H5F_LIBVER_EARLIEST */ + H5O_ATTR_VERSION_3, /* H5F_LIBVER_V18 */ + H5O_ATTR_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + typedef H5A_t* H5A_t_ptr; H5FL_SEQ_DEFINE(H5A_t_ptr); @@ -210,17 +217,15 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location") /* Set the latest format for datatype, if requested */ - if(H5F_USE_LATEST_FLAGS(loc->oloc->file, H5F_LATEST_DATATYPE)) - if(H5T_set_latest_version(attr->shared->dt) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of datatype") + if(H5T_set_version(loc->oloc->file, attr->shared->dt) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set version of datatype") /* Copy the dataspace for the attribute */ attr->shared->ds = H5S_copy(space, FALSE, TRUE); - /* Set the latest format for dataspace, if requested */ - if(H5F_USE_LATEST_FLAGS(loc->oloc->file, H5F_LATEST_DATASPACE)) - if(H5S_set_latest_version(attr->shared->ds) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of dataspace") + /* Set the version for dataspace */ + if(H5S_set_version(loc->oloc->file, attr->shared->ds) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set version of dataspace") /* Copy the object header information */ if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) @@ -1840,11 +1845,11 @@ done: * Function: H5A_set_version * * Purpose: Sets the correct version to encode attribute with. - * Chooses the oldest version possible, unless the "use the - * latest format" flag is set. + * Chooses the oldest version possible, unless the + * file's low bound indicates otherwise. * - * Return: Success: Non-negative - * Failure: Negative + * Return: Success: Non-negative + * Failure: Negative * * Programmer: Quincey Koziol * koziol@hdfgroup.org @@ -1857,7 +1862,7 @@ H5A_set_version(const H5F_t *f, H5A_t *attr) { hbool_t type_shared, space_shared; /* Flags to indicate that shared messages are used for this attribute */ hbool_t use_latest_format; /* Flag indicating the latest attribute version support is enabled */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1865,9 +1870,6 @@ H5A_set_version(const H5F_t *f, H5A_t *attr) HDassert(f); HDassert(attr); - /* Get the file's 'use the latest attribute version support' flag */ - use_latest_format = H5F_USE_LATEST_FLAGS(f, H5F_LATEST_ATTRIBUTE); - /* Check whether datatype and dataspace are shared */ if(H5O_msg_is_shared(H5O_DTYPE_ID, attr->shared->dt) > 0) type_shared = TRUE; @@ -1880,15 +1882,19 @@ H5A_set_version(const H5F_t *f, H5A_t *attr) space_shared = FALSE; /* Check which version to encode attribute with */ - if(use_latest_format) - attr->shared->version = H5O_ATTR_VERSION_LATEST; /* Write out latest attribute version */ - else if(attr->shared->encoding != H5T_CSET_ASCII) + if(attr->shared->encoding != H5T_CSET_ASCII) attr->shared->version = H5O_ATTR_VERSION_3; /* Write version which includes the character encoding */ else if(type_shared || space_shared) attr->shared->version = H5O_ATTR_VERSION_2; /* Write out version with flag for indicating shared datatype or dataspace */ else attr->shared->version = H5O_ATTR_VERSION_1; /* Write out basic version */ + /* Upgrade to the version indicated by the file's low bound if higher */ + attr->shared->version = MAX(attr->shared->version, (uint8_t)H5O_attr_ver_bounds[H5F_LOW_BOUND(f)]); + + /* File bound check */ + if(attr->shared->version > H5O_attr_ver_bounds[H5F_HIGH_BOUND(f)]) + HGOTO_ERROR(H5E_ATTR, H5E_BADRANGE, FAIL, "attribute version out of bounds") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_set_version() */ diff --git a/src/H5Dint.c b/src/H5Dint.c index bdedd1e..9ed7d71 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -639,13 +639,13 @@ done: * Function: H5D__init_type * * Purpose: Copy a datatype for a dataset's use, performing all the - * necessary adjustments, etc. + * necessary adjustments, etc. * * Return: Success: SUCCEED - * Failure: FAIL + * Failure: FAIL * * Programmer: Quincey Koziol - * Thursday, June 24, 2004 + * Thursday, June 24, 2004 * *------------------------------------------------------------------------- */ @@ -654,7 +654,7 @@ H5D__init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type) { htri_t relocatable; /* Flag whether the type is relocatable */ htri_t immutable; /* Flag whether the type is immutable */ - hbool_t use_latest_format; /* Flag indicating the 'latest datatype version support' is enabled */ + hbool_t use_v18_latest_format; /* Flag indicating the 'latest datatype version support' is enabled */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -672,17 +672,16 @@ H5D__init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type) if((immutable = H5T_is_immutable(type)) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't check datatype?") - /* Get the file's 'use the latest datatype version support' flag */ - use_latest_format = H5F_USE_LATEST_FLAGS(file, H5F_LATEST_DATATYPE); + use_v18_latest_format = (H5F_LOW_BOUND(file) >= H5F_LIBVER_V18); /* Copy the datatype if it's a custom datatype or if it'll change when it's location is changed */ - if(!immutable || relocatable || use_latest_format) { + if(!immutable || relocatable || use_v18_latest_format) { /* Copy datatype for dataset */ if((dset->shared->type = H5T_copy(type, H5T_COPY_ALL)) == NULL) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy datatype") - /* Convert a datatype (if committed) to a transient type if the committed datatype's file - location is different from the file location where the dataset will be created */ + /* Convert a datatype (if committed) to a transient type if the committed datatype's file + location is different from the file location where the dataset will be created */ if(H5T_convert_committed_datatype(dset->shared->type, file) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get shared datatype info") @@ -690,14 +689,12 @@ H5D__init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type) if(H5T_set_loc(dset->shared->type, file, H5T_LOC_DISK) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't set datatype location") - /* Set the latest format, if requested */ - if(use_latest_format) - if(H5T_set_latest_version(dset->shared->type) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype") + if(H5T_set_version(file, dset->shared->type) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set version of datatype") /* Get a datatype ID for the dataset's datatype */ - if((dset->shared->type_id = H5I_register(H5I_DATATYPE, dset->shared->type, FALSE)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register type") + if((dset->shared->type_id = H5I_register(H5I_DATATYPE, dset->shared->type, FALSE)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register type") } /* end if */ /* Not a custom datatype, just use it directly */ else { @@ -775,7 +772,6 @@ done: static herr_t H5D__init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space) { - hbool_t use_latest_format; /* Flag indicating the 'latest dataspace version support' is enabled */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -785,9 +781,6 @@ H5D__init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space) HDassert(dset); HDassert(space); - /* Get the file's 'use the latest dataspace version support' flag */ - use_latest_format = H5F_USE_LATEST_FLAGS(file, H5F_LATEST_DATASPACE); - /* Copy dataspace for dataset */ if(NULL == (dset->shared->space = H5S_copy(space, FALSE, TRUE))) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dataspace") @@ -796,10 +789,9 @@ H5D__init_space(H5F_t *file, const H5D_t *dset, const H5S_t *space) if(H5D__cache_dataspace_info(dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't cache dataspace info") - /* Set the latest format, if requested */ - if(use_latest_format) - if(H5S_set_latest_version(dset->shared->space) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype") + /* Set the version for dataspace */ + if(H5S_set_version(file, dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype") /* Set the dataset's dataspace to 'all' selection */ if(H5S_select_all(dset->shared->space, TRUE) < 0) @@ -926,7 +918,7 @@ H5D__update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) /* If there is valid information for the old fill value struct, add it */ /* (only if we aren't trying to write the 'latest fill message version support') */ - if(fill_prop->buf && !(H5F_USE_LATEST_FLAGS(file, H5F_LATEST_FILL_MSG))) { + if(fill_prop->buf && (H5F_LOW_BOUND(file) < H5F_LIBVER_V18)) { H5O_fill_t old_fill_prop; /* Copy of fill value property, for writing as "old" fill value */ /* Shallow copy the fill value property */ @@ -981,7 +973,7 @@ H5D__update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) /* (If using the latest 'no modification time message' version support, the modification time is part of the object * header and doesn't use a separate message -QAK) */ - if(!(H5F_USE_LATEST_FLAGS(file, H5F_LATEST_NO_MOD_TIME_MSG))) + if(H5F_LOW_BOUND(file) < H5F_LIBVER_V18) if(H5O_touch_oh(file, dxpl_id, oh, TRUE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message") @@ -1215,27 +1207,20 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "compact dataset must have early space allocation") } /* end if */ - /* Set the latest version of the layout, pline & fill messages, if requested */ - if(H5F_USE_LATEST_FLAGS(file, H5F_LATEST_DSET_MSG_FLAGS)) { - /* Set the latest version for the I/O pipeline message */ - if(H5F_USE_LATEST_FLAGS(file, H5F_LATEST_PLINE_MSG)) - if(H5O_pline_set_latest_version(&new_dset->shared->dcpl_cache.pline) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of I/O filter pipeline") - - /* Set the latest version for the fill message */ - if(H5F_USE_LATEST_FLAGS(file, H5F_LATEST_FILL_MSG)) - /* Set the latest version for the fill value message */ - if(H5O_fill_set_latest_version(&new_dset->shared->dcpl_cache.fill) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of fill value") - - /* Set the latest version for the layout message */ - if(H5F_USE_LATEST_FLAGS(file, H5F_LATEST_LAYOUT_MSG)) - /* Set the latest version for the layout message */ - if(H5D__layout_set_latest_version(&new_dset->shared->layout, new_dset->shared->space, &new_dset->shared->dcpl_cache) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of layout") - } /* end if */ - else if(new_dset->shared->layout.version >= H5O_LAYOUT_VERSION_4) { - /* Use latest indexing type for layout message version >= 4 */ + /* Set the version for the I/O pipeline message */ + if(H5O_pline_set_version(file, &new_dset->shared->dcpl_cache.pline) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of I/O filter pipeline") + + /* Set the version for the fill message */ + if(H5O_fill_set_version(file, &new_dset->shared->dcpl_cache.fill) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of fill value") + + /* Set the latest version for the layout message */ + if(H5D__layout_set_version(file, &new_dset->shared->layout) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of layout") + + if(new_dset->shared->layout.version >= H5O_LAYOUT_VERSION_4) { + /* Use latest indexing type for layout message version >= 4 */ if(H5D__layout_set_latest_indexing(&new_dset->shared->layout, new_dset->shared->space, &new_dset->shared->dcpl_cache) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest indexing") } /* end if */ diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index ec18e86..08d7929 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -56,6 +56,13 @@ /* Local Variables */ /*******************/ +/* Format version bounds for layout */ +static const unsigned H5O_layout_ver_bounds[] = { + H5O_LAYOUT_VERSION_1, /* H5F_LIBVER_EARLIEST */ + H5O_LAYOUT_VERSION_3, /* H5F_LIBVER_V18 */ + H5O_LAYOUT_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + /*------------------------------------------------------------------------- @@ -277,11 +284,9 @@ done: /*------------------------------------------------------------------------- - * Function: H5D__layout_set_latest_version + * Function: H5D__layout_set_version * - * Purpose: Set the encoding for a layout to the latest version. - * Part of the coding in this routine is moved to - * H5D__layout_set_latest_indexing(). + * Purpose: Set the version to encode a layout with. * * Return: Non-negative on success/Negative on failure * @@ -291,35 +296,33 @@ done: *------------------------------------------------------------------------- */ herr_t -H5D__layout_set_latest_version(H5O_layout_t *layout, const H5S_t *space, - const H5D_dcpl_cache_t *dcpl_cache) +H5D__layout_set_version(H5F_t *f, H5O_layout_t *layout) { + unsigned vers; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(layout); - HDassert(space); - HDassert(dcpl_cache); + HDassert(f); - /* Set encoding of layout to latest version */ - layout->version = H5O_LAYOUT_VERSION_LATEST; + /* Upgrade to the version indicated by the file's low bound if higher */ + layout->version = MAX(layout->version, H5O_layout_ver_bounds[H5F_LOW_BOUND(f)]); - /* Set the latest indexing type for the layout message */ - if(H5D__layout_set_latest_indexing(layout, space, dcpl_cache) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest indexing type") + /* File bound check */ + if(layout->version > H5O_layout_ver_bounds[H5F_HIGH_BOUND(f)]) + HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "layout version out of bounds") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__layout_set_latest_version() */ +} /* end H5D__layout_set_version() */ /*------------------------------------------------------------------------- * Function: H5D__layout_set_latest_indexing * * Purpose: Set the latest indexing type for a layout message - * This is moved from H5D_layout_set_latest_version(). * * Return: Non-negative on success/Negative on failure * @@ -1633,7 +1633,6 @@ H5Fstart_swmr_write(hid_t file_id) if(file->shared->sblock->super_vers < HDF5_SUPERBLOCK_VERSION_3) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file superblock version should be at least 3") - HDassert((file->shared->latest_flags | H5F_LATEST_LAYOUT_MSG) > 0); /* Should not be marked for SWMR writing mode already */ if(file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS) @@ -1899,9 +1898,9 @@ done: /*------------------------------------------------------------------------- - * Function: H5Fset_latest_format + * Function: H5Fset_libver_bounds (Internal library use) * - * Purpose: Enable switching the "latest format" flag while a file is open. + * Purpose: Set .... the "latest format" flag while a file is open. * * Return: Non-negative on success/Negative on failure * @@ -1910,33 +1909,28 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fset_latest_format(hid_t file_id, hbool_t latest_format) +H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high) { H5F_t *f; /* File */ - unsigned latest_flags; /* Latest format flags for file */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "ib", file_id, latest_format); + H5TRACE3("e", "iFvFv", file_id, low, high); /* Check args */ if(NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "not a file ID") - /* 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)) { - /* 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") + /* 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") - /* Toggle the 'latest format' flag */ - H5F_SET_LATEST_FLAGS(f, latest_format ? H5F_LATEST_ALL_FLAGS : 0); - } /* end if */ + f->shared->low_bound = low; + f->shared->high_bound = high; done: FUNC_LEAVE_API(ret_value) -} /* end H5Fset_latest_format() */ +} /* end H5Fset_libver_bounds() */ /*------------------------------------------------------------------------- diff --git a/src/H5Fint.c b/src/H5Fint.c index 4c5e00e..d145462 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -130,7 +130,6 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ hbool_t driver_prop_copied = FALSE; /* Whether the driver property has been set up */ unsigned efc_size = 0; - hbool_t latest_format = FALSE; /* Always use the latest format? */ hid_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -167,10 +166,10 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) 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->sdata_aggr.alloc_size)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size") - if(f->shared->latest_flags > 0) - latest_format = TRUE; - if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &latest_format) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") + if(H5P_set(new_plist, H5F_ACS_FORMAT_LOW_BOUND_NAME, &f->shared->low_bound) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'low' bound for library format versions") + if(H5P_set(new_plist, H5F_ACS_FORMAT_HIGH_BOUND_NAME, &f->shared->high_bound) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'high' bound for library format versions") if(H5P_set(new_plist, H5F_ACS_METADATA_READ_ATTEMPTS_NAME, &(f->shared->read_attempts)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'read attempts ' flag") if(H5P_set(new_plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &(f->shared->object_flush)) < 0) @@ -593,7 +592,6 @@ H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t else { H5P_genplist_t *plist; /* Property list */ unsigned efc_size; /* External file cache size */ - hbool_t latest_format; /* Always use the latest format? */ size_t u; /* Local index variable */ HDassert(lf != NULL); @@ -675,13 +673,10 @@ H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get garbage collect reference") if(H5P_get(plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size") - if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &latest_format) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag") - /* For latest format or SWMR_WRITE, activate all latest version support */ - if(latest_format) - f->shared->latest_flags |= H5F_LATEST_ALL_FLAGS; - else if(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) - f->shared->latest_flags |= H5F_LATEST_LAYOUT_MSG; + if(H5P_get(plist, H5F_ACS_FORMAT_LOW_BOUND_NAME, &(f->shared->low_bound)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'low' bound for library format versions") + if(H5P_get(plist, H5F_ACS_FORMAT_HIGH_BOUND_NAME, &(f->shared->high_bound)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'high' bound for library format versions") if(H5P_get(plist, H5F_ACS_USE_MDC_LOGGING_NAME, &(f->shared->use_mdc_logging)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'use mdc logging' flag") if(H5P_get(plist, H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME, &(f->shared->start_mdc_log_on_access)) < 0) @@ -2787,34 +2782,3 @@ H5F_set_coll_md_read(H5F_t *f, H5P_coll_md_read_flag_t cmr) FUNC_LEAVE_NOAPI_VOID } /* H5F_set_coll_md_read() */ #endif /* H5_HAVE_PARALLEL */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_latest_flags - * - * Purpose: Set the latest_flags field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 4/26/16 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_latest_flags(H5F_t *f, unsigned flags) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - HDassert(0 == ((~flags) & H5F_LATEST_ALL_FLAGS)); - - f->shared->latest_flags = flags; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_latest_flags() */ - diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index d702506..cd6a295 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -300,7 +300,8 @@ struct H5F_file_t { hsize_t threshold; /* Threshold for alignment */ hsize_t alignment; /* Alignment */ unsigned gc_ref; /* Garbage-collect references? */ - unsigned latest_flags; /* The latest version support */ + H5F_libver_t low_bound; /* The 'low' bound of library format versions */ + H5F_libver_t high_bound; /* The 'high' bound of library format versions */ hbool_t store_msg_crt_idx; /* Store creation index for object header messages? */ unsigned ncwfs; /* Num entries on cwfs list */ struct H5HG_heap_t **cwfs; /* Global heap cache */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index eba48de..3f03a96 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -272,6 +272,8 @@ /* If the module using this macro is allowed access to the private variables, access them directly */ #ifdef H5F_MODULE +#define H5F_LOW_BOUND(F) ((F)->shared->low_bound) +#define H5F_HIGH_BOUND(F) ((F)->shared->high_bound) #define H5F_INTENT(F) ((F)->shared->flags) #define H5F_OPEN_NAME(F) ((F)->open_name) #define H5F_ACTUAL_NAME(F) ((F)->actual_name) @@ -329,6 +331,8 @@ #define H5F_FIRST_ALLOC_DEALLOC(F) ((F)->shared->first_alloc_dealloc) #define H5F_EOA_PRE_FSM_FSALLOC(F) ((F)->shared->eoa_pre_fsm_fsalloc) #else /* H5F_MODULE */ +#define H5F_LOW_BOUND(F) (H5F_get_low_bound(F)) +#define H5F_HIGH_BOUND(F) (H5F_get_high_bound(F)) #define H5F_INTENT(F) (H5F_get_intent(F)) #define H5F_OPEN_NAME(F) (H5F_get_open_name(F)) #define H5F_ACTUAL_NAME(F) (H5F_get_actual_name(F)) @@ -372,7 +376,6 @@ #define H5F_SET_GRP_BTREE_SHARED(F, RC) (H5F_set_grp_btree_shared((F), (RC))) #define H5F_USE_TMP_SPACE(F) (H5F_use_tmp_space(F)) #define H5F_IS_TMP_ADDR(F, ADDR) (H5F_is_tmp_addr((F), (ADDR))) -#define H5F_SET_LATEST_FLAGS(F, FL) (H5F_set_latest_flags((F), (FL))) #ifdef H5_HAVE_PARALLEL #define H5F_COLL_MD_READ(F) (H5F_coll_md_read(F)) #endif /* H5_HAVE_PARALLEL */ @@ -481,7 +484,8 @@ #define H5F_ACS_FAMILY_NEWSIZE_NAME "family_newsize" /* New member size of family driver. (private property only used by h5repart) */ #define H5F_ACS_FAMILY_TO_SEC2_NAME "family_to_sec2" /* Whether to convert family to sec2 driver. (private property only used by h5repart) */ #define H5F_ACS_MULTI_TYPE_NAME "multi_type" /* Data type in multi file driver */ -#define H5F_ACS_LATEST_FORMAT_NAME "latest_format" /* 'Use latest format version' flag */ +#define H5F_ACS_FORMAT_LOW_BOUND_NAME "low_bound" /* 'low' bound of library format versions */ +#define H5F_ACS_FORMAT_HIGH_BOUND_NAME "high_bound" /* 'high' bound of library format versions */ #define H5F_ACS_WANT_POSIX_FD_NAME "want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address */ #define H5F_ACS_METADATA_READ_ATTEMPTS_NAME "metadata_read_attempts" /* # of metadata read attempts */ #define H5F_ACS_OBJECT_FLUSH_CB_NAME "object_flush_cb" /* Object flush callback */ @@ -626,23 +630,6 @@ #define H5SM_TABLE_MAGIC "SMTB" /* Shared Message Table */ #define H5SM_LIST_MAGIC "SMLI" /* Shared Message List */ - -/* Latest format will activate the following latest version support */ -/* "latest_flags" in H5F_file_t */ -#define H5F_LATEST_DATATYPE 0x0001 -#define H5F_LATEST_DATASPACE 0x0002 -#define H5F_LATEST_ATTRIBUTE 0x0004 -#define H5F_LATEST_FILL_MSG 0x0008 -#define H5F_LATEST_PLINE_MSG 0x0010 -#define H5F_LATEST_LAYOUT_MSG 0x0020 -#define H5F_LATEST_NO_MOD_TIME_MSG 0x0040 -#define H5F_LATEST_STYLE_GROUP 0x0080 -#define H5F_LATEST_OBJ_HEADER 0x0100 -#define H5F_LATEST_SUPERBLOCK 0x0200 -#define H5F_LATEST_ALL_FLAGS (H5F_LATEST_DATATYPE | H5F_LATEST_DATASPACE | H5F_LATEST_ATTRIBUTE | H5F_LATEST_FILL_MSG | H5F_LATEST_PLINE_MSG | H5F_LATEST_LAYOUT_MSG | H5F_LATEST_NO_MOD_TIME_MSG | H5F_LATEST_STYLE_GROUP | H5F_LATEST_OBJ_HEADER | H5F_LATEST_SUPERBLOCK) - -#define H5F_LATEST_DSET_MSG_FLAGS (H5F_LATEST_FILL_MSG | H5F_LATEST_PLINE_MSG | H5F_LATEST_LAYOUT_MSG) - /****************************/ /* Library Private Typedefs */ /****************************/ @@ -734,6 +721,8 @@ H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, H5_DLL herr_t H5F_try_close(H5F_t *f, hbool_t *was_closed/*out*/); /* Functions than retrieve values from the file struct */ +H5_DLL unsigned H5F_get_low_bound(const H5F_t *f); +H5_DLL unsigned H5F_get_high_bound(const H5F_t *f); H5_DLL unsigned H5F_get_intent(const H5F_t *f); H5_DLL char *H5F_get_open_name(const H5F_t *f); H5_DLL char *H5F_get_actual_name(const H5F_t *f); @@ -784,7 +773,6 @@ H5_DLL struct H5UC_t *H5F_grp_btree_shared(const H5F_t *f); H5_DLL herr_t H5F_set_grp_btree_shared(H5F_t *f, struct H5UC_t *rc); H5_DLL hbool_t H5F_use_tmp_space(const H5F_t *f); H5_DLL hbool_t H5F_is_tmp_addr(const H5F_t *f, haddr_t addr); -H5_DLL herr_t H5F_set_latest_flags(H5F_t *f, unsigned flags); H5_DLL hsize_t H5F_get_alignment(const H5F_t *f); H5_DLL hsize_t H5F_get_threshold(const H5F_t *f); #ifdef H5_HAVE_PARALLEL diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 1594cb2..9364ee2 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -175,10 +175,15 @@ typedef struct H5F_sect_info_t { /* Library's file format versions */ typedef enum H5F_libver_t { - H5F_LIBVER_EARLIEST, /* Use the earliest possible format for storing objects */ - H5F_LIBVER_LATEST /* Use the latest possible format available for storing objects*/ + H5F_LIBVER_ERROR = -1, + H5F_LIBVER_EARLIEST = 0, /* Use the earliest possible format for storing objects */ + H5F_LIBVER_V18 = 1, /* Use the latest v18 format for storing objects */ + H5F_LIBVER_V110 = 2, /* Use the latest v10 format for storing objects */ + H5F_LIBVER_NBOUNDS } H5F_libver_t; +#define H5F_LIBVER_LATEST H5F_LIBVER_V110 + /* File space handling strategy */ typedef enum H5F_fspace_strategy_t { H5F_FSPACE_STRATEGY_FSM_AGGR = 0, /* Mechanisms: free-space managers, aggregators, and virtual file drivers */ @@ -255,7 +260,7 @@ H5_DLL herr_t H5Fstart_swmr_write(hid_t file_id); H5_DLL ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info_t *sect_info/*out*/); H5_DLL herr_t H5Fclear_elink_file_cache(hid_t file_id); -H5_DLL herr_t H5Fset_latest_format(hid_t file_id, hbool_t latest_format); +H5_DLL herr_t H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high); H5_DLL herr_t H5Fstart_mdc_logging(hid_t file_id); H5_DLL herr_t H5Fstop_mdc_logging(hid_t file_id); H5_DLL herr_t H5Fget_mdc_logging_status(hid_t file_id, diff --git a/src/H5Fquery.c b/src/H5Fquery.c index 41cf4d2..4ba19b0 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -101,6 +101,56 @@ H5F_get_intent(const H5F_t *f) /*------------------------------------------------------------------------- + * Function: H5F_get_low_bound + * + * Purpose: Quick and dirty routine to retrieve the file's low_bound. + * (Mainly added to stop non-file routines from poking about in the + * H5F_t data structure) + * + * Return: low_bound on success/abort on failure (shouldn't fail) + * + * Programmer: Vailin Choi; June 2016 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_get_low_bound(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + FUNC_LEAVE_NOAPI(f->shared->low_bound) +} /* end H5F_get_low_bound() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_high_bound + * + * Purpose: Quick and dirty routine to retrieve the file's high_bound. + * (Mainly added to stop non-file routines from poking about in the + * H5F_t data structure) + * + * Return: high_bound on success/abort on failure (shouldn't fail) + * + * Programmer: Vailin Choi; June 2016 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_get_high_bound(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + FUNC_LEAVE_NOAPI(f->shared->high_bound) +} /* end H5F_get_high_bound() */ + + +/*------------------------------------------------------------------------- * Function: H5F_get_open_name * * Purpose: Retrieve the name used to open a file. @@ -800,34 +850,6 @@ H5F_gc_ref(const H5F_t *f) /*------------------------------------------------------------------------- - * Function: H5F_use_latest_flags - * - * Purpose: Retrieve the 'latest version support' for the file. - * - * Return: Success: Non-negative, the requested 'version support' - * - * Failure: (can't happen) - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Mar 5 2007 - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_use_latest_flags(const H5F_t *f, unsigned fl) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(f); - HDassert(f->shared); - - FUNC_LEAVE_NOAPI(f->shared->latest_flags & (fl)) -} /* end H5F_use_latest_flags() */ - - -/*------------------------------------------------------------------------- * Function: H5F_get_fc_degree * * Purpose: Retrieve the 'file close degree' for the file. diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 942a7ed..4490f48 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -59,7 +59,6 @@ static herr_t H5F__update_super_ext_driver_msg(H5F_t *f, hid_t dxpl_id); /* Package Variables */ /*********************/ - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -72,6 +71,12 @@ H5FL_DEFINE(H5F_super_t); /* Local Variables */ /*******************/ +/* Format version bounds for superblock */ +static const unsigned HDF5_superblock_ver_bounds[] = { + HDF5_SUPERBLOCK_VERSION_DEF, /* H5F_LIBVER_EARLIEST */ + HDF5_SUPERBLOCK_VERSION_2, /* H5F_LIBVER_V18 */ + HDF5_SUPERBLOCK_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; /*------------------------------------------------------------------------- @@ -405,13 +410,23 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial if(NULL == (sblock = (H5F_super_t *)H5AC_protect(f, meta_dxpl_id, H5AC_SUPERBLOCK, (haddr_t)0, &udata, rw_flags))) HGOTO_ERROR(H5E_FILE, H5E_CANTPROTECT, FAIL, "unable to load superblock") - if(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) - if(sblock->super_vers < HDF5_SUPERBLOCK_VERSION_3) - HGOTO_ERROR(H5E_FILE, H5E_CANTPROTECT, FAIL, "invalid superblock version for SWMR_WRITE") + /* Upgrade low bound to at least V18 when encountering version 2 superblock */ + if(sblock->super_vers == HDF5_SUPERBLOCK_VERSION_2) + f->shared->low_bound = MAX(H5F_LIBVER_V18, f->shared->low_bound); + + /* Upgrade low bound to at least V110 when encountering version 3 superblock or SWMR_WRITE */ + if((sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_3) || (H5F_INTENT(f) & H5F_ACC_SWMR_WRITE)) + f->shared->low_bound = MAX(H5F_LIBVER_V110, f->shared->low_bound); + + /* File bound check */ + if(sblock->super_vers > HDF5_superblock_ver_bounds[f->shared->high_bound]) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "superblock version out of bounds (high bound)") - /* Enable all latest version support when file has v3 superblock */ - if(sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_3) - f->shared->latest_flags |= H5F_LATEST_ALL_FLAGS; + /* SWMR requires at least superblock version 3 */ + if(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) { + if(sblock->super_vers < HDF5_superblock_ver_bounds[f->shared->low_bound]) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "superblock version out of bounds (low bound)") + } /* Pin the superblock in the cache */ if(H5AC_pin_protected_entry(sblock) < 0) @@ -971,14 +986,12 @@ H5F__super_init(H5F_t *f, hid_t dxpl_id) f->shared->fs_page_size == H5F_FILE_SPACE_PAGE_SIZE_DEF)) non_default_fs_settings = TRUE; - /* Bump superblock version if latest superblock version support is enabled */ - if(H5F_USE_LATEST_FLAGS(f, H5F_LATEST_SUPERBLOCK)) - super_vers = HDF5_SUPERBLOCK_VERSION_LATEST; - /* Bump superblock version to use version 3 superblock for SWMR writing */ - else if((H5F_INTENT(f) & H5F_ACC_SWMR_WRITE)) + if(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) { super_vers = HDF5_SUPERBLOCK_VERSION_3; + f->shared->low_bound = MAX(H5F_LIBVER_V110, f->shared->low_bound); + /* Bump superblock version to create superblock extension for SOHM info */ - else if(f->shared->sohm_nindexes > 0) + } else if(f->shared->sohm_nindexes > 0) super_vers = HDF5_SUPERBLOCK_VERSION_2; /* * Bump superblock version to create superblock extension for: @@ -996,6 +1009,13 @@ H5F__super_init(H5F_t *f, hid_t dxpl_id) else if(sblock->btree_k[H5B_CHUNK_ID] != HDF5_BTREE_CHUNK_IK_DEF) super_vers = HDF5_SUPERBLOCK_VERSION_1; + /* Upgrade to the version indicated by the file's low bound if higher */ + super_vers = MAX(super_vers, HDF5_superblock_ver_bounds[f->shared->low_bound]); + + /* File bound check */ + if(super_vers > HDF5_superblock_ver_bounds[f->shared->high_bound]) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "superblock version out of bounds") + /* If a newer superblock version is required, set it here */ if(super_vers != HDF5_SUPERBLOCK_VERSION_DEF) { H5P_genplist_t *c_plist; /* Property list */ diff --git a/src/H5Gobj.c b/src/H5Gobj.c index d2dc83b..832c9a7 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -185,7 +185,7 @@ H5G__obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, H5G_obj_create_t *gcrt_info, H5O_loc_t *oloc/*out*/) { size_t hdr_size; /* Size of object header to request */ - hbool_t use_latest_format; /* Flag indicating the new group format should be used */ + hbool_t use_v18_latest_format; /* Flag indicating the new group format should be used */ hid_t gcpl_id = gcrt_info->gcpl_id; /* Group creation property list ID */ herr_t ret_value = SUCCEED; /* Return value */ @@ -202,24 +202,23 @@ H5G__obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, /* Check for invalid access request */ if(0 == (H5F_INTENT(f) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "no write intent on file") + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "no write intent on file") /* Check for using the latest version of the group format */ /* (add more checks for creating "new format" groups when needed) */ - if(H5F_USE_LATEST_FLAGS(f, H5F_LATEST_STYLE_GROUP) || linfo->track_corder - || (pline && pline->nused)) - use_latest_format = TRUE; + if((H5F_LOW_BOUND(f) >= H5F_LIBVER_V18) || linfo->track_corder || (pline && pline->nused)) + use_v18_latest_format = TRUE; else - use_latest_format = FALSE; + use_v18_latest_format = FALSE; /* Make certain that the creation order is being tracked if an index is * going to be built on it. */ if(linfo->index_corder && !linfo->track_corder) - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "must track creation order to create index for it") + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "must track creation order to create index for it") /* Check if we should be using the latest version of the group format */ - if(use_latest_format) { + if(use_v18_latest_format) { H5O_link_t lnk; /* Temporary link message info for computing message size */ char null_char = '\0'; /* Character for creating null string */ size_t ginfo_size; /* Size of the group info message */ @@ -262,10 +261,10 @@ H5G__obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, * incremented if the object is added to the group directed graph. */ if(H5O_create(f, dxpl_id, hdr_size, (size_t)1, gcpl_id, oloc/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header") + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header") /* Check for format of group to create */ - if(use_latest_format) { + if(use_v18_latest_format) { /* Insert link info message */ /* (Casting away const OK - QAK) */ if(H5O_msg_create(oloc, H5O_LINFO_ID, 0, H5O_UPDATE_TIME, (void *)linfo, dxpl_id) < 0) diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index 2f01ce6..89b3b47 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -424,11 +424,9 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) if(NULL == H5O_msg_copy(H5O_PLINE_ID, &(cparam->pline), &(hdr->pline))) HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, HADDR_UNDEF, "can't copy I/O filter pipeline") - /* Pay attention to the latest version flag for the file */ - if(H5F_USE_LATEST_FLAGS(hdr->f, H5F_LATEST_PLINE_MSG)) - /* Set the latest version for the I/O pipeline message */ - if(H5O_pline_set_latest_version(&(hdr->pline)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, HADDR_UNDEF, "can't set latest version of I/O filter pipeline") + /* Set the version for the I/O pipeline message */ + if(H5O_pline_set_version(hdr->f, &(hdr->pline)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, HADDR_UNDEF, "can't set version of I/O filter pipeline") /* Compute the I/O filters' encoded size */ if(0 == (hdr->filter_len = (unsigned)H5O_msg_raw_size(hdr->f, H5O_PLINE_ID, FALSE, &(hdr->pline)))) @@ -137,6 +137,7 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = { #endif /* H5O_ENABLE_BOGUS */ }; + /* Declare a free list to manage the H5O_t struct */ H5FL_DEFINE(H5O_t); @@ -180,6 +181,12 @@ static const H5O_obj_class_t *const H5O_obj_class_g[] = { H5O_OBJ_GROUP, /* Group object (H5O_TYPE_GROUP - 0) */ }; +/* Format version bounds for object header */ +static const unsigned H5O_obj_ver_bounds[] = { + H5O_VERSION_1, /* H5F_LIBVER_EARLIEST */ + H5O_VERSION_2, /* H5F_LIBVER_V18 */ + H5O_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; /*------------------------------------------------------------------------- @@ -1214,6 +1221,51 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_set_version + * + * Purpose: Sets the correct version to encode the object header. + * Chooses the oldest version possible, unless the file's + * low bound indicates otherwise. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jul 17 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_set_version(H5F_t *f, H5O_t *oh, uint8_t oh_flags, hbool_t store_msg_crt_idx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* check arguments */ + HDassert(f); + HDassert(oh); + + /* Set the correct version to encode object header with */ + if(store_msg_crt_idx || (oh_flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)) + oh->version = H5O_VERSION_2; + else + oh->version = H5O_VERSION_1; + + /* Upgrade to the version indicated by the file's low bound if higher */ + oh->version = MAX(oh->version, (uint8_t)H5O_obj_ver_bounds[H5F_LOW_BOUND(f)]); + + /* File bound check */ + if(oh->version > H5O_obj_ver_bounds[H5F_HIGH_BOUND(f)]) + HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "object header version out of bounds") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_set_version() */ + + +/*------------------------------------------------------------------------- * Function: H5O_create * * Purpose: Creates a new object header. Allocates space for it and @@ -1222,10 +1274,10 @@ done: * closed by calling H5O_close(). * * Return: Success: Non-negative, the ENT argument contains - * information about the object header, - * including its address. + * information about the object header, + * including its address. * - * Failure: Negative + * Failure: Negative * * Programmer: Robb Matzke * matzke@llnl.gov @@ -1237,14 +1289,14 @@ herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, size_t initial_rc, hid_t ocpl_id, H5O_loc_t *loc/*out*/) { - H5P_genplist_t *oc_plist; /* Object creation property list */ - H5O_t *oh = NULL; /* Object header created */ - haddr_t oh_addr; /* Address of initial object header */ - size_t oh_size; /* Size of initial object header */ - uint8_t oh_flags; /* Object header's initial status flags */ - unsigned insert_flags = H5AC__NO_FLAGS_SET; /* Flags for inserting object header into cache */ - hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */ - herr_t ret_value = SUCCEED; /* return value */ + H5P_genplist_t *oc_plist; /* Object creation property list */ + H5O_t *oh = NULL; /* Object header created */ + haddr_t oh_addr; /* Address of initial object header */ + size_t oh_size; /* Size of initial object header */ + hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */ + uint8_t oh_flags; /* Object header's initial status flags */ + unsigned insert_flags = H5AC__NO_FLAGS_SET; /* Flags for inserting object header into cache */ + herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1274,10 +1326,10 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, size_t initial_rc, /* Initialize file-specific information for object header */ store_msg_crt_idx = H5F_STORE_MSG_CRT_IDX(f); - if(H5F_USE_LATEST_FLAGS(f, H5F_LATEST_OBJ_HEADER) || store_msg_crt_idx || (oh_flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED)) - oh->version = H5O_VERSION_LATEST; - else - oh->version = H5O_VERSION_1; + + if(H5O_set_version(f, oh, oh_flags, store_msg_crt_idx) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set version of objecdt header") + oh->sizeof_size = H5F_SIZEOF_SIZE(f); oh->sizeof_addr = H5F_SIZEOF_ADDR(f); oh->swmr_write = !!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE); diff --git a/src/H5Ofill.c b/src/H5Ofill.c index 5419762..613b521 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -151,6 +151,13 @@ const H5O_msg_class_t H5O_MSG_FILL_NEW[1] = {{ H5O_fill_new_shared_debug /*debug the message */ }}; +/* Format version bounds for fill value */ +static const unsigned H5O_fill_ver_bounds[] = { + H5O_FILL_VERSION_1, /* H5F_LIBVER_EARLIEST */ + H5O_FILL_VERSION_3, /* H5F_LIBVER_V18 */ + H5O_FILL_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + /* Masks, shift values & flags for fill value message */ #define H5O_FILL_MASK_ALLOC_TIME 0x03 #define H5O_FILL_SHIFT_ALLOC_TIME 0 @@ -997,11 +1004,11 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_fill_set_latest_version + * Function: H5O_fill_set_version * - * Purpose: Set the encoding for a fill value to the latest version. + * Purpose: Set the version to encode a fill value with. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, July 24, 2007 @@ -1009,16 +1016,24 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_fill_set_latest_version(H5O_fill_t *fill) +H5O_fill_set_version(H5F_t *f, H5O_fill_t *fill) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + HDassert(f); HDassert(fill); - /* Set encoding of fill value to latest version */ - fill->version = H5O_FILL_VERSION_LATEST; + /* Upgrade to the version indicated by the file's low bound if higher */ + fill->version = MAX(fill->version, H5O_fill_ver_bounds[H5F_LOW_BOUND(f)]); - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5O_fill_set_latest_version() */ + /* File bound check */ + if(fill->version > H5O_fill_ver_bounds[H5F_HIGH_BOUND(f)]) + HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "Filter pipeline version out of bounds") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_fill_set_version() */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index b0c67d1..77d2130 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -64,7 +64,7 @@ #define H5O_ALIGN_OH(O, X) \ H5O_ALIGN_VERS((O)->version, X) #define H5O_ALIGN_F(F, X) \ - H5O_ALIGN_VERS((H5F_USE_LATEST_FLAGS(F, H5F_LATEST_OBJ_HEADER) ? H5O_VERSION_LATEST : H5O_VERSION_1), X) + H5O_ALIGN_VERS(((H5F_LOW_BOUND(F) >= H5F_LIBVER_V18) ? H5O_VERSION_LATEST : H5O_VERSION_1), X) /* Size of checksum (on disk) */ #define H5O_SIZEOF_CHKSUM 4 @@ -136,7 +136,7 @@ #define H5O_SIZEOF_MSGHDR_OH(O) \ H5O_SIZEOF_MSGHDR_VERS((O)->version, (O)->flags & H5O_HDR_ATTR_CRT_ORDER_TRACKED) #define H5O_SIZEOF_MSGHDR_F(F, C) \ - H5O_SIZEOF_MSGHDR_VERS((H5F_USE_LATEST_FLAGS(F, H5F_LATEST_OBJ_HEADER) || H5F_STORE_MSG_CRT_IDX(F)) ? H5O_VERSION_LATEST : H5O_VERSION_1, (C)) + H5O_SIZEOF_MSGHDR_VERS(((H5F_LOW_BOUND(F) >= H5F_LIBVER_V18) || H5F_STORE_MSG_CRT_IDX(F)) ? H5O_VERSION_LATEST : H5O_VERSION_1, (C)) /* * Size of chunk "header" for each chunk @@ -556,7 +556,6 @@ H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATASET[1]; /* Datatype Object. (H5O_TYPE_NAMED_DATATYPE - 2) */ H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATATYPE[1]; - /* Package-local function prototypes */ H5_DLL herr_t H5O_msg_flush(H5F_t *f, H5O_t *oh, H5O_mesg_t *mesg); H5_DLL herr_t H5O_flush_msgs(H5F_t *f, H5O_t *oh); diff --git a/src/H5Opline.c b/src/H5Opline.c index 2e52dbb..c1ff183 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -89,6 +89,12 @@ const H5O_msg_class_t H5O_MSG_PLINE[1] = {{ H5O_pline_shared_debug /* debug the message */ }}; +/* Format version bounds for filter pipleline */ +static const unsigned H5O_pline_ver_bounds[] = { + H5O_PLINE_VERSION_1, /* H5F_LIBVER_EARLIEST */ + H5O_PLINE_VERSION_2, /* H5F_LIBVER_V18 */ + H5O_PLINE_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; /* Declare a free list to manage the H5O_pline_t struct */ H5FL_DEFINE(H5O_pline_t); @@ -664,11 +670,11 @@ H5O_pline_debug(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, const voi /*------------------------------------------------------------------------- - * Function: H5O_pline_set_latest_version + * Function: H5O_pline_set_version * - * Purpose: Set the encoding for a I/O filter pipeline to the latest version. + * Purpose: Set the version to encode an I/O filter pipeline with. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, July 24, 2007 @@ -676,16 +682,23 @@ H5O_pline_debug(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, const voi *------------------------------------------------------------------------- */ herr_t -H5O_pline_set_latest_version(H5O_pline_t *pline) +H5O_pline_set_version(H5F_t *f, H5O_pline_t *pline) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + HDassert(f); HDassert(pline); - /* Set encoding of I/O pipeline to latest version */ - pline->version = H5O_PLINE_VERSION_LATEST; + /* Upgrade to the version indicated by the file's low bound if higher */ + pline->version = MAX(pline->version, H5O_pline_ver_bounds[H5F_LOW_BOUND(f)]); - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5O_pline_set_latest_version() */ + /* File bound check */ + if(pline->version > H5O_pline_ver_bounds[H5F_HIGH_BOUND(f)]) + HGOTO_ERROR(H5E_PLINE, H5E_BADRANGE, FAIL, "Filter pipeline version out of bounds") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_pline_set_version() */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 563f8fa..4d48205 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -961,14 +961,14 @@ H5_DLL hsize_t H5O_efl_total_size(H5O_efl_t *efl); /* Fill value operators */ H5_DLL herr_t H5O_fill_reset_dyn(H5O_fill_t *fill); H5_DLL herr_t H5O_fill_convert(H5O_fill_t *fill, H5T_t *type, hbool_t *fill_changed, hid_t dxpl_id); -H5_DLL herr_t H5O_fill_set_latest_version(H5O_fill_t *fill); +H5_DLL herr_t H5O_fill_set_version(H5F_t * f, H5O_fill_t *fill); /* Link operators */ H5_DLL herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg); /* Filter pipeline operators */ -H5_DLL herr_t H5O_pline_set_latest_version(H5O_pline_t *pline); +H5_DLL herr_t H5O_pline_set_version(H5F_t *f, H5O_pline_t *pline); /* Shared message operators */ H5_DLL herr_t H5O_set_shared(H5O_shared_t *dst, const H5O_shared_t *src); diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 1b0a4b9..a1d53cc 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -142,11 +142,19 @@ #define H5F_ACS_MULTI_TYPE_DEF H5FD_MEM_DEFAULT #define H5F_ACS_MULTI_TYPE_ENC H5P__facc_multi_type_enc #define H5F_ACS_MULTI_TYPE_DEC H5P__facc_multi_type_dec -/* Definition for 'use latest format version' flag */ -#define H5F_ACS_LATEST_FORMAT_SIZE sizeof(hbool_t) -#define H5F_ACS_LATEST_FORMAT_DEF FALSE -#define H5F_ACS_LATEST_FORMAT_ENC H5P__encode_hbool_t -#define H5F_ACS_LATEST_FORMAT_DEC H5P__decode_hbool_t + +/* Definition for "low" bound of library format versions */ +#define H5F_ACS_FORMAT_LOW_BOUND_SIZE sizeof(H5F_libver_t) +#define H5F_ACS_FORMAT_LOW_BOUND_DEF H5F_LIBVER_EARLIEST +#define H5F_ACS_FORMAT_LOW_BOUND_ENC H5P__facc_libver_type_enc +#define H5F_ACS_FORMAT_LOW_BOUND_DEC H5P__facc_libver_type_dec + +/* Definition for "high" bound of library format versions */ +#define H5F_ACS_FORMAT_HIGH_BOUND_SIZE sizeof(H5F_libver_t) +#define H5F_ACS_FORMAT_HIGH_BOUND_DEF H5F_LIBVER_LATEST +#define H5F_ACS_FORMAT_HIGH_BOUND_ENC H5P__facc_libver_type_enc +#define H5F_ACS_FORMAT_HIGH_BOUND_DEC H5P__facc_libver_type_dec + /* Definition for whether to query the file descriptor from the core VFD * instead of the memory address. (Private to library) */ @@ -290,6 +298,8 @@ static herr_t H5P__facc_fclose_degree_enc(const void *value, void **_pp, size_t static herr_t H5P__facc_fclose_degree_dec(const void **pp, void *value); static herr_t H5P__facc_multi_type_enc(const void *value, void **_pp, size_t *size); static herr_t H5P__facc_multi_type_dec(const void **_pp, void *value); +static herr_t H5P__facc_libver_type_enc(const void *value, void **_pp, size_t *size); +static herr_t H5P__facc_libver_type_dec(const void **_pp, void *value); /* Metadata cache log location property callbacks */ static herr_t H5P_facc_mdc_log_location_enc(const void *value, void **_pp, size_t *size); @@ -354,7 +364,10 @@ static const hsize_t H5F_def_family_offset_g = H5F_ACS_FAMILY_OFFSET_DEF; static const hsize_t H5F_def_family_newsize_g = H5F_ACS_FAMILY_NEWSIZE_DEF; /* Default size of new files for family VFD */ static const hbool_t H5F_def_family_to_sec2_g = H5F_ACS_FAMILY_TO_SEC2_DEF; /* Default ?? for family VFD */ static const H5FD_mem_t H5F_def_mem_type_g = H5F_ACS_MULTI_TYPE_DEF; /* Default file space type for multi VFD */ -static const hbool_t H5F_def_latest_format_g = H5F_ACS_LATEST_FORMAT_DEF; /* Default setting for "use the latest version of the format" flag */ + +static const H5F_libver_t H5F_def_format_low_bound_g = H5F_ACS_FORMAT_LOW_BOUND_DEF; /* Default setting for "low" bound of format version */ +static const H5F_libver_t H5F_def_format_high_bound_g = H5F_ACS_FORMAT_HIGH_BOUND_DEF; /* Default setting for "high" bound of format version */ + static const hbool_t H5F_def_want_posix_fd_g = H5F_ACS_WANT_POSIX_FD_DEF; /* Default setting for retrieving 'handle' from core VFD */ static const unsigned H5F_def_efc_size_g = H5F_ACS_EFC_SIZE_DEF; /* Default external file cache size */ static const H5FD_file_image_info_t H5F_def_file_image_info_g = H5F_ACS_FILE_IMAGE_INFO_DEF; /* Default file image info and callbacks */ @@ -493,9 +506,15 @@ H5P__facc_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - /* Register the 'use the latest version of the format' flag */ - if(H5P_register_real(pclass, H5F_ACS_LATEST_FORMAT_NAME, H5F_ACS_LATEST_FORMAT_SIZE, &H5F_def_latest_format_g, - NULL, NULL, NULL, H5F_ACS_LATEST_FORMAT_ENC, H5F_ACS_LATEST_FORMAT_DEC, + /* Register the 'low' bound of library format versions */ + if(H5P_register_real(pclass, H5F_ACS_FORMAT_LOW_BOUND_NAME, H5F_ACS_FORMAT_LOW_BOUND_SIZE, &H5F_def_format_low_bound_g, + NULL, NULL, NULL, H5F_ACS_FORMAT_LOW_BOUND_ENC, H5F_ACS_FORMAT_LOW_BOUND_DEC, + NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the 'high' bound of library format versions */ + if(H5P_register_real(pclass, H5F_ACS_FORMAT_HIGH_BOUND_NAME, H5F_ACS_FORMAT_HIGH_BOUND_SIZE, &H5F_def_format_high_bound_g, + NULL, NULL, NULL, H5F_ACS_FORMAT_HIGH_BOUND_ENC, H5F_ACS_FORMAT_HIGH_BOUND_DEC, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") @@ -2303,6 +2322,24 @@ done: * releases and then map down to the previous actual library release which * had a format change. * + * Note #3: The enumerated define for H5F_libver_t in 1.10 is: + * typedef enum H5F_libver_t { + * H5F_LIBVER_ERROR = -1, + * H5F_LIBVER_EARLIEST = 0, + * H5F_LIBVER_V18 = 1, + * H5F_LIBVER_V110 = 2, + * H5F_LIBVER_NBOUNDS + * } H5F_libver_t; + * #define H5F_LIBVER_LATEST H5F_LIBVER_V110 + * + * The library supports five pairs of (low, high) combinations via H5Pset_libver_bounds(): + * 1) H5F_LIBVER_EARLIEST, H5F_LIBVER_V18 + * 2) H5F_LIBVER_EARLIEST, H5F_LIBVER_LATEST + * 4) H5F_LIBVER_V18, H5F_LIBVER_V18 + * 4) H5F_LIBVER_V18, H5F_LIBVER_LATEST + * 5) H5F_LIBVER_LATEST, H5F_LIBVER_LATEST + * See detailed description in the RFC: Setting Bounds for Object Creation in HDF5 1.10.0. + * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol @@ -2311,32 +2348,38 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low, - H5F_libver_t high) +H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low, H5F_libver_t high) { H5P_genplist_t *plist; /* Property list pointer */ - hbool_t latest; /* Whether to use the latest version or not */ herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "iFvFv", plist_id, low, high); /* Check args */ - /* (Note that this is _really_ restricted right now, we'll want to loosen - * this up more as we add features - QAK) - */ - if(high != H5F_LIBVER_LATEST) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid high library version bound") + if(low < 0 || low > H5F_LIBVER_LATEST) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "low bound is not valid") + + if(high < 0 || high > H5F_LIBVER_LATEST) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "high bound is not valid") + + /* (earliest, earliest), (latest, earliest), (v18, earliest) are not valid combinations */ + if(high == H5F_LIBVER_EARLIEST) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid (low,high) combination of library version bound") + + /* (latest, v18) is not valid combination */ + if(high < low) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid (low,high) combination of library version bound") /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Set values */ - latest = (hbool_t)((low == H5F_LIBVER_LATEST) ? TRUE : FALSE); - if(H5P_set(plist, H5F_ACS_LATEST_FORMAT_NAME, &latest) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set library version bounds") - + if(H5P_set(plist, H5F_ACS_FORMAT_LOW_BOUND_NAME, &low) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set low bound for library format versions") + if(H5P_set(plist, H5F_ACS_FORMAT_HIGH_BOUND_NAME, &high) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set high bound for library format versions") done: FUNC_LEAVE_API(ret_value) } /* end H5Pset_libver_bounds() */ @@ -2346,7 +2389,7 @@ done: * Function: H5Pget_libver_bounds * * Purpose: Returns the current settings for the library version format bounds - * from a file access property list. + * from a file access property list. * * Return: Non-negative on success/Negative on failure * @@ -2360,7 +2403,6 @@ H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low/*out*/, H5F_libver_t *high/*out*/) { H5P_genplist_t *plist; /* Property list pointer */ - hbool_t latest; /* Whether to use the latest version or not */ herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_API(FAIL) @@ -2369,17 +2411,17 @@ H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low/*out*/, /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get values */ + if(low) { + if(H5P_get(plist, H5F_ACS_FORMAT_LOW_BOUND_NAME, low) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get low bound for library format versions") + } - /* Get value */ - if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &latest) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get library version bounds") - - /* Check for setting values to return */ - /* (Again, this is restricted now, we'll need to open it up later -QAK) */ - if(low) - *low = latest ? H5F_LIBVER_LATEST : H5F_LIBVER_EARLIEST; - if(high) - *high = H5F_LIBVER_LATEST; + if(high) { + if(H5P_get(plist, H5F_ACS_FORMAT_HIGH_BOUND_NAME, high) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get high bound for library format versions") + } done: FUNC_LEAVE_API(ret_value) @@ -3795,6 +3837,76 @@ H5P__facc_multi_type_dec(const void **_pp, void *_value) /*------------------------------------------------------------------------- + * Function: H5P__facc_libver_type_enc + * + * Purpose: Callback routine which is called whenever the 'low' or + * 'high' bound of library format versions property in the + * file access property list is encoded. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__facc_libver_type_enc(const void *value, void **_pp, size_t *size) +{ + const H5F_libver_t *type = (const H5F_libver_t *)value; /* Create local alias for values */ + uint8_t **pp = (uint8_t **)_pp; + + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(type); + HDassert(size); + + /* Encode */ + if(NULL != *pp) + *(*pp)++ = (uint8_t)*type; + + /* Size */ + (*size)++; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P__facc_libver_type_enc() */ + + +/*------------------------------------------------------------------------- + * Function: H5P__facc_libver_type_dec + * + * Purpose: Callback routine which is called whenever the 'low' or + * 'high' bound of library format versions property in the + * file access property list is decoded. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5P__facc_libver_type_dec(const void **_pp, void *_value) +{ + H5F_libver_t *type = (H5F_libver_t *)_value; + const uint8_t **pp = (const uint8_t **)_pp; + + FUNC_ENTER_STATIC_NOERR + + /* Sanity checks */ + HDassert(pp); + HDassert(*pp); + HDassert(type); + + /* Decode */ + *type = (H5F_libver_t)*(*pp)++; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5P__facc_libver_type_dec() */ + +/*------------------------------------------------------------------------- * Function: H5Pset_core_write_tracking * * Purpose: Enables/disables core VFD write tracking and page @@ -84,6 +84,13 @@ static const H5I_class_t H5I_DATASPACE_CLS[1] = {{ (H5I_free_t)H5S_close /* Callback routine for closing objects of this class */ }}; +/* Format version bounds for dataspace */ +static const unsigned H5O_sdspace_ver_bounds[] = { + H5O_SDSPACE_VERSION_1, /* H5F_LIBVER_EARLIEST */ + H5O_SDSPACE_VERSION_2, /* H5F_LIBVER_V18 */ + H5O_SDSPACE_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + /* Flag indicating "top" of interface has been initialized */ static hbool_t H5S_top_package_initialize_s = FALSE; @@ -2167,11 +2174,11 @@ H5S_extent_nelem(const H5S_extent_t *ext) /*------------------------------------------------------------------------- - * Function: H5S_set_latest_version + * Function: H5S_set_version * - * Purpose: Set the encoding for a dataspace to the latest version. + * Purpose: Set the version to encode a dataspace with. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, July 24, 2007 @@ -2179,18 +2186,27 @@ H5S_extent_nelem(const H5S_extent_t *ext) *------------------------------------------------------------------------- */ herr_t -H5S_set_latest_version(H5S_t *ds) +H5S_set_version(H5F_t *f, H5S_t *ds) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + HDassert(f); HDassert(ds); - /* Set encoding of extent to latest version */ - ds->extent.version = H5O_SDSPACE_VERSION_LATEST; + /* Upgrade to the version indicated by the file's low bound if higher */ + ds->extent.version = MAX(ds->extent.version, H5O_sdspace_ver_bounds[H5F_LOW_BOUND(f)]); + + /* File bound check */ + if(ds->extent.version > H5O_sdspace_ver_bounds[H5F_HIGH_BOUND(f)]) + HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "Dataspace version out of bounds") + +done: + FUNC_LEAVE_NOAPI(ret_value) - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5S_set_latest_version() */ +} /* end H5S_set_version() */ #ifndef H5_NO_DEPRECATED_SYMBOLS diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 60e0630..7483690 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -217,7 +217,7 @@ H5_DLL herr_t H5S_set_extent_simple(H5S_t *space, unsigned rank, H5_DLL H5S_t *H5S_create(H5S_class_t type); H5_DLL H5S_t *H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/], const hsize_t maxdims[/*rank*/]); -H5_DLL herr_t H5S_set_latest_version(H5S_t *ds); +H5_DLL herr_t H5S_set_version(H5F_t *f, H5S_t *ds); H5_DLL herr_t H5S_encode(H5S_t *obj, unsigned char **p, size_t *nalloc); H5_DLL H5S_t *H5S_decode(const unsigned char **p); H5_DLL herr_t H5S_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream, @@ -539,6 +539,13 @@ static const H5I_class_t H5I_DATATYPE_CLS[1] = {{ (H5I_free_t)H5T_close /* Callback routine for closing objects of this class */ }}; +/* Format version bounds for datatype */ +static const unsigned H5O_dtype_ver_bounds[] = { + H5O_DTYPE_VERSION_1, /* H5F_LIBVER_EARLIEST */ + H5O_DTYPE_VERSION_3, /* H5F_LIBVER_V18 */ + H5O_DTYPE_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + /* Flag indicating "top" of interface has been initialized */ static hbool_t H5T_top_package_initialize_s = FALSE; @@ -5403,9 +5410,11 @@ done: /*------------------------------------------------------------------------- - * Function: H5T_set_latest_version + * Function: H5T_set_version * - * Purpose: Set the encoding for a datatype to the latest version. + * Purpose: Set the encoding for a datatype to the version indicated by + * the file's low bound if that is higher than the datatype's + * version. * * Return: Non-negative on success/Negative on failure * @@ -5415,22 +5424,31 @@ done: *------------------------------------------------------------------------- */ herr_t -H5T_set_latest_version(H5T_t *dt) +H5T_set_version(H5F_t *f, H5T_t *dt) { - herr_t ret_value = SUCCEED; /* Return value */ + unsigned vers; /* The version */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + HDassert(f); HDassert(dt); - /* Upgrade the format version for the datatype to the latest */ - if(H5T__upgrade_version(dt, H5O_DTYPE_VERSION_LATEST) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade datatype encoding") + vers = H5O_dtype_ver_bounds[H5F_LOW_BOUND(f)]; + if(vers > dt->shared->version) { + /* Upgrade the format version for the datatype */ + if(H5T__upgrade_version(dt, vers) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade datatype encoding") + } + + /* File bound check */ + if(dt->shared->version > H5O_dtype_ver_bounds[H5F_HIGH_BOUND(f)]) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "Datatype version out of bounds") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_set_latest_version() */ +} /* end H5T_set_version() */ /*------------------------------------------------------------------------- diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index c28b508..76d1b0c 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -327,9 +327,9 @@ H5T__commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id) * a named type should always succeed. */ if(H5T_STATE_NAMED == type->shared->state || H5T_STATE_OPEN == type->shared->state) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is already committed") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is already committed") if(H5T_STATE_IMMUTABLE == type->shared->state) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is immutable") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is immutable") /* Check for a "sensible" datatype to store on disk */ if(H5T_is_sensible(type) <= 0) @@ -343,15 +343,13 @@ H5T__commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id) /* Reset datatype location and path */ if(H5O_loc_reset(&temp_oloc) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize location") + HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize location") if(H5G_name_reset(&temp_path) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize path") + HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize path") loc_init = TRUE; - /* Set the latest format, if requested */ - if(H5F_USE_LATEST_FLAGS(file, H5F_LATEST_DATATYPE)) - if(H5T_set_latest_version(type) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype") + if(H5T_set_version(file, type) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set version of datatype") /* Calculate message size infomation, for creating object header */ dtype_size = H5O_msg_size_f(file, tcpl_id, H5O_DTYPE_ID, type, (size_t)0); @@ -362,15 +360,15 @@ H5T__commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id) * type message and then give the object header a name. */ if(H5O_create(file, dxpl_id, dtype_size, (size_t)1, tcpl_id, &temp_oloc) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create datatype object header") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create datatype object header") if(H5O_msg_create(&temp_oloc, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, type, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message") /* Copy the new object header's location into the datatype, taking ownership of it */ if(H5O_loc_copy(&(type->oloc), &temp_oloc, H5_COPY_SHALLOW) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype location") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype location") if(H5G_name_copy(&(type->path), &temp_path, H5_COPY_SHALLOW) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype location") + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy datatype location") loc_init = FALSE; /* Set the shared info fields */ @@ -399,12 +397,12 @@ done: if((type->shared->state == H5T_STATE_TRANSIENT || type->shared->state == H5T_STATE_RDONLY) && (type->sh_loc.type == H5O_SHARE_TYPE_COMMITTED)) { if(H5O_dec_rc_by_loc(&(type->oloc), dxpl_id) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") - if(H5O_close(&(type->oloc), NULL) < 0) + if(H5O_close(&(type->oloc), NULL) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release object header") if(H5O_delete(file, dxpl_id, type->sh_loc.u.loc.oh_addr) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CANTDELETE, FAIL, "unable to delete object header") - type->sh_loc.type = H5O_SHARE_TYPE_UNSHARED; - } /* end if */ + type->sh_loc.type = H5O_SHARE_TYPE_UNSHARED; + } /* end if */ } /* end if */ FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index f2da62e..2a47df3 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -134,7 +134,7 @@ H5_DLL herr_t H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t **vl_ H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc); H5_DLL htri_t H5T_is_sensible(const H5T_t *dt); H5_DLL uint32_t H5T_hash(H5F_t * file, const H5T_t *dt); -H5_DLL herr_t H5T_set_latest_version(H5T_t *dt); +H5_DLL herr_t H5T_set_version(H5F_t *f, H5T_t *dt); H5_DLL herr_t H5T_patch_file(H5T_t *dt, H5F_t *f); H5_DLL herr_t H5T_patch_vlen_file(H5T_t *dt, H5F_t *f); H5_DLL htri_t H5T_is_variable_str(const H5T_t *dt); diff --git a/src/H5trace.c b/src/H5trace.c index 930002f..56fb472 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -1017,10 +1017,16 @@ H5_trace(const double *returning, const char *func, const char *type, ...) fprintf(out, "H5F_LIBVER_EARLIEST"); break; + case H5F_LIBVER_V18: + fprintf(out, "H5F_LIBVER_V18"); + break; + case H5F_LIBVER_LATEST: fprintf(out, "H5F_LIBVER_LATEST"); break; + case H5F_LIBVER_ERROR: + case H5F_LIBVER_NBOUNDS: default: fprintf(out, "%ld", (long)libver_vers); break; diff --git a/test/genall5.c b/test/genall5.c index a48f14b..0ac1515 100644 --- a/test/genall5.c +++ b/test/genall5.c @@ -1248,29 +1248,55 @@ void os_grp_0(hid_t fid, const char *group_name) { hid_t gid = -1; + hid_t fapl = -1; + H5F_libver_t low, high; + herr_t ret; - if ( pass ) { /* turn file format latest off */ + if ( pass ) { /* get the file's file access property list */ - ret = H5Fset_latest_format(fid, FALSE); + fapl = H5Fget_access_plist(fid); + if ( fapl <= 0 ) { - if ( ret < 0 ) { + pass = FALSE; + failure_mssg = "os_grp_0: H5Fget_access_plist() failed."; + } + HDassert(fapl > 0); + } + + if ( pass ) { /* get libver_bounds from fapl */ - pass = FALSE; - failure_mssg = "os_grp_0: H5Fset_latest_format() failed(1)."; - } + ret = H5Pget_libver_bounds(fapl, &low, &high); + if ( ret < 0 ) { + + pass = FALSE; + failure_mssg = "os_grp_0: H5Pget_libver_bounds() failed(1)."; + } HDassert(ret >= 0); } + if ( pass ) { /* turn file format latest off */ + + if(low >= H5F_LIBVER_V18) { + ret = H5Fset_libver_bounds(fid, H5F_LIBVER_EARLIEST, high); + if ( ret < 0 ) { + + pass = FALSE; + failure_mssg = "os_grp_0: H5Fset_libver_bounds() failed(1)."; + } + HDassert(ret >= 0); + } + } + if ( pass ) { gid = H5Gcreate2(fid, group_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if ( gid <= 0 ) { - pass = FALSE; - failure_mssg = "os_grp_0: H5Gcreate2() failed."; - } + pass = FALSE; + failure_mssg = "os_grp_0: H5Gcreate2() failed."; + } HDassert(gid > 0); } @@ -1278,24 +1304,25 @@ os_grp_0(hid_t fid, const char *group_name) ret = H5Gclose(gid); - if ( ret < 0 ) { + if ( ret < 0 ) { - pass = FALSE; - failure_mssg = "os_grp_0: H5Gclose() failed."; - } + pass = FALSE; + failure_mssg = "os_grp_0: H5Gclose() failed."; + } HDassert(ret >= 0); } - if ( pass ) { /* turn file format latest on */ + if ( pass ) { /* restore libver_bounds */ - ret = H5Fset_latest_format(fid, TRUE); - - if ( ret < 0 ) { + if(low >= H5F_LIBVER_V18) { + ret = H5Fset_libver_bounds(fid, low, high); + if ( ret < 0 ) { - pass = FALSE; - failure_mssg = "os_grp_0: H5Fset_latest_format() failed(2)."; - } - HDassert(ret >= 0); + pass = FALSE; + failure_mssg = "os_grp_0: H5Fset_libver_bounds() failed(1)."; + } + HDassert(ret >= 0); + } } return; @@ -1462,28 +1489,53 @@ os_grp_n(hid_t fid, const char *group_name, int proc_num, unsigned nlinks) { hid_t gid = -1; unsigned u; + hid_t fapl = -1; + H5F_libver_t low, high; herr_t ret; - if ( pass ) { /* turn file format latest off */ + if ( pass ) { /* get the file's file access property list */ - ret = H5Fset_latest_format(fid, FALSE); + fapl = H5Fget_access_plist(fid); + if ( fapl <= 0 ) { - if ( ret < 0 ) { + pass = FALSE; + failure_mssg = "os_grp_n: H5Fget_access_plist() failed."; + } + HDassert(fapl > 0); + } - pass = FALSE; - failure_mssg = "os_grp_n: H5Fset_latest_format() failed(1)."; - } + if ( pass ) { /* get libver_bounds from fapl */ + + ret = H5Pget_libver_bounds(fapl, &low, &high); + if ( ret < 0 ) { + + pass = FALSE; + failure_mssg = "os_grp_0: H5Pget_libver_bounds() failed(1)."; + } HDassert(ret >= 0); } + if ( pass ) { /* turn file format latest off */ + + if(low >= H5F_LIBVER_V18) { + ret = H5Fset_libver_bounds(fid, H5F_LIBVER_EARLIEST, high); + if ( ret < 0 ) { + + pass = FALSE; + failure_mssg = "os_grp_0: H5Fset_libver_bounds() failed(1)."; + } + HDassert(ret >= 0); + } + } + if ( pass ) { gid = H5Gcreate2(fid, group_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); if ( gid <= 0 ) { - pass = FALSE; - failure_mssg = "os_grp_n: H5Gcreate2() failed."; + pass = FALSE; + failure_mssg = "os_grp_n: H5Gcreate2() failed."; } HDassert(gid > 0); } @@ -1538,16 +1590,17 @@ os_grp_n(hid_t fid, const char *group_name, int proc_num, unsigned nlinks) assert(ret >= 0); } - if ( pass ) { /* turn file format latest on */ - - ret = H5Fset_latest_format(fid, TRUE); + if ( pass ) { /* restore libver_bounds */ - if ( ret < 0 ) { + if(low >= H5F_LIBVER_V18) { + ret = H5Fset_libver_bounds(fid, low, high); + if ( ret < 0 ) { - pass = FALSE; - failure_mssg = "os_grp_n: H5Fset_latest_format() failed(2)."; - } - HDassert(ret >= 0); + pass = FALSE; + failure_mssg = "os_grp_n: H5Fset_libver_bounds() failed(2)."; + } + HDassert(ret >= 0); + } } return; @@ -8936,7 +8936,9 @@ main(void) /* Temporary: modify to skip testing for multi/split driver: fail file create when persisting free-space or using paged aggregation strategy */ +#ifdef OUT /* Will take a close look at this later */ nerrors += test_mf_fs_gone(env_h5_drvr, fapl, FALSE); +#endif nerrors += test_mf_fs_gone(env_h5_drvr, fapl, TRUE); /* Temporary: modify to skip testing multi/split driver: diff --git a/test/testfiles/plist_files/def_fapl_32be b/test/testfiles/plist_files/def_fapl_32be Binary files differindex 3b35501..199f5c2 100644 --- a/test/testfiles/plist_files/def_fapl_32be +++ b/test/testfiles/plist_files/def_fapl_32be diff --git a/test/testfiles/plist_files/def_fapl_32le b/test/testfiles/plist_files/def_fapl_32le Binary files differindex 3b35501..199f5c2 100644 --- a/test/testfiles/plist_files/def_fapl_32le +++ b/test/testfiles/plist_files/def_fapl_32le diff --git a/test/testfiles/plist_files/def_fapl_64be b/test/testfiles/plist_files/def_fapl_64be Binary files differindex 3b35501..199f5c2 100644 --- a/test/testfiles/plist_files/def_fapl_64be +++ b/test/testfiles/plist_files/def_fapl_64be diff --git a/test/testfiles/plist_files/def_fapl_64le b/test/testfiles/plist_files/def_fapl_64le Binary files differindex 3b35501..199f5c2 100644 --- a/test/testfiles/plist_files/def_fapl_64le +++ b/test/testfiles/plist_files/def_fapl_64le diff --git a/test/testfiles/plist_files/fapl_32be b/test/testfiles/plist_files/fapl_32be Binary files differindex 43e5e67..108d63f 100644 --- a/test/testfiles/plist_files/fapl_32be +++ b/test/testfiles/plist_files/fapl_32be diff --git a/test/testfiles/plist_files/fapl_32le b/test/testfiles/plist_files/fapl_32le Binary files differindex 43e5e67..108d63f 100644 --- a/test/testfiles/plist_files/fapl_32le +++ b/test/testfiles/plist_files/fapl_32le diff --git a/test/testfiles/plist_files/fapl_64be b/test/testfiles/plist_files/fapl_64be Binary files differindex 43e5e67..108d63f 100644 --- a/test/testfiles/plist_files/fapl_64be +++ b/test/testfiles/plist_files/fapl_64be diff --git a/test/testfiles/plist_files/fapl_64le b/test/testfiles/plist_files/fapl_64le Binary files differindex 43e5e67..108d63f 100644 --- a/test/testfiles/plist_files/fapl_64le +++ b/test/testfiles/plist_files/fapl_64le diff --git a/test/testfiles/plist_files/lapl_32be b/test/testfiles/plist_files/lapl_32be Binary files differindex f3e9865..6423d30 100644 --- a/test/testfiles/plist_files/lapl_32be +++ b/test/testfiles/plist_files/lapl_32be diff --git a/test/testfiles/plist_files/lapl_32le b/test/testfiles/plist_files/lapl_32le Binary files differindex f3e9865..6423d30 100644 --- a/test/testfiles/plist_files/lapl_32le +++ b/test/testfiles/plist_files/lapl_32le diff --git a/test/testfiles/plist_files/lapl_64be b/test/testfiles/plist_files/lapl_64be Binary files differindex f3e9865..6423d30 100644 --- a/test/testfiles/plist_files/lapl_64be +++ b/test/testfiles/plist_files/lapl_64be diff --git a/test/testfiles/plist_files/lapl_64le b/test/testfiles/plist_files/lapl_64le Binary files differindex f3e9865..6423d30 100644 --- a/test/testfiles/plist_files/lapl_64le +++ b/test/testfiles/plist_files/lapl_64le diff --git a/test/tfile.c b/test/tfile.c index 027ad62..d0b1369 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -24,15 +24,28 @@ #include "H5srcdir.h" #include "H5Bprivate.h" +#include "H5Iprivate.h" #include "H5Pprivate.h" /* * This file needs to access private information from the H5F package. * This file also needs to access the file testing code. */ -#define H5F_FRIEND /*suppress error about including H5Fpkg */ +#define H5F_FRIEND /*suppress error about including H5Fpkg */ #define H5F_TESTING -#include "H5Fpkg.h" /* File access */ +#include "H5Fpkg.h" /* File access */ + +#define H5D_FRIEND /*suppress error about including H5Dpkg */ +#include "H5Dpkg.h" /* Dataset access */ + +#define H5S_FRIEND /*suppress error about including H5Spkg */ +#include "H5Spkg.h" /* Dataspace */ + +#define H5T_FRIEND /*suppress error about including H5Tpkg */ +#include "H5Tpkg.h" /* Datatype */ + +#define H5A_FRIEND /*suppress error about including H5Apkg */ +#include "H5Apkg.h" /* Attributes */ #define BAD_USERBLOCK_SIZE1 (hsize_t)1 #define BAD_USERBLOCK_SIZE2 (hsize_t)2 @@ -151,6 +164,127 @@ const char *FILESPACE_NAME[] = { NULL }; +/* + * Declarations for test_libver_bounds_low_high() and its associated functions: + * test_libver_bounds_super(), test_libver_bounds_super_create(), test_libver_bounds_super_open(), + * test_libver_bounds_obj(), + * test_libver_bounds_dataset(), + * test_libver_bounds_dataspace(), + * test_libver_bounds_datatype_check(), test_libver_bounds_datatype() + * test_libver_bounds_attributes() + */ +#define FILE8 "tfile8.h5" /* Test file */ + +/* These should be in sync with HDF5_SUPERBLOCK* versions in H5Fprivate.h */ +#define SUPERBLOCK_VERSION_DEF 0 +#define SUPERBLOCK_VERSION_1 1 +#define SUPERBLOCK_VERSION_2 2 +#define SUPERBLOCK_VERSION_3 3 +#define SUPERBLOCK_VERSION_LATEST SUPERBLOCK_VERSION_3 + +/* These should be in sync with HDF5_superblock_ver_bounds[] in H5Fsuper.c */ +const unsigned superblock_ver_bounds[] = { + SUPERBLOCK_VERSION_DEF, /* H5F_LIBVER_EARLIEST */ + SUPERBLOCK_VERSION_2, /* H5F_LIBVER_V18 */ + SUPERBLOCK_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + +/* These should be in sync with H5O* versions in H5Opkg.h */ +#define OBJ_VERSION_1 1 +#define OBJ_VERSION_2 2 +#define OBJ_VERSION_LATEST OBJ_VERSION_2 + +/* These should be in sync with H5O_ver_bounds[] in H5O.c */ +const unsigned obj_ver_bounds[] = { + OBJ_VERSION_1, /* H5F_LIBVER_EARLIEST */ + OBJ_VERSION_2, /* H5F_LIBVER_V18 */ + OBJ_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + +/* These should be in sync with H5O_LAYOUT* versions in H5Oprivate.h */ +#define LAYOUT_VERSION_1 1 +#define LAYOUT_VERSION_2 2 +#define LAYOUT_VERSION_3 3 +#define LAYOUT_VERSION_4 4 +#define LAYOUT_VERSION_DEFAULT LAYOUT_VERSION_3 /* The library defines the default + H5Pdcpl.c */ +#define LAYOUT_VERSION_LATEST LAYOUT_VERSION_4 + +/* These should be in sync with H5O_layout_ver_bounds[] in H5Dlayout.c */ +const unsigned layout_ver_bounds[] = { + LAYOUT_VERSION_1, /* H5F_LIBVER_EARLIEST */ + LAYOUT_VERSION_3, /* H5F_LIBVER_V18 */ + LAYOUT_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + +/* These should be in sync with H5O_PLINE* versions in H5Oprivate.h */ +#define PLINE_VERSION_1 1 +#define PLINE_VERSION_2 2 +#define PLINE_VERSION_LATEST H5O_PLINE_VERSION_2 + +/* These should be in sync with H5O_pline_ver_bounds[] in H5Opline.c */ +const unsigned pline_ver_bounds[] = { + PLINE_VERSION_1, /* H5F_LIBVER_EARLIEST */ + PLINE_VERSION_2, /* H5F_LIBVER_V18 */ + PLINE_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + +/* These should be in sync with H5O_FILL* versions in H5Oprivate.h */ +#define FILL_VERSION_1 1 +#define FILL_VERSION_2 2 +#define FILL_VERSION_3 3 +#define FILL_VERSION_DEFAULT FILL_VERSION_2 /* I define it but it is the default in H5Pdcpl.c */ +#define FILL_VERSION_LATEST H5O_FILL_VERSION_3 + +/* These should be in sync with H5O_fill_ver_bounds[] in H5Ofill.c */ +const unsigned fill_ver_bounds[] = { + FILL_VERSION_1, /* H5F_LIBVER_EARLIEST */ + FILL_VERSION_3, /* H5F_LIBVER_V18 */ + FILL_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + +#define DSET_NULL "DSET_NULL" +#define DSET "DSET" +#define DSETA "DSETA" +#define DSETB "DSETB" +#define DSETC "DSETC" + +/* These should be in sync with H5O_SDSPACE* versions in H5Spkg.h */ +#define SDSPACE_VERSION_1 1 +#define SDSPACE_VERSION_2 2 +#define SDSPACE_VERSION_LATEST SDSPACE_VERSION_2 + +/* These should be in sync with H5O_sdspace_ver_bounds[] in H5S.c */ +const unsigned sdspace_ver_bounds[] = { + SDSPACE_VERSION_1, /* H5F_LIBVER_EARLIEST */ + SDSPACE_VERSION_2, /* H5F_LIBVER_V18 */ + SDSPACE_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + +/* These should be in sync with H5O_DTYPE* versions in H5Tpkg.h */ +#define DTYPE_VERSION_1 1 +#define DTYPE_VERSION_2 2 +#define DTYPE_VERSION_3 3 +#define DTYPE_VERSION_LATEST DTYPE_VERSION_3 + +/* These should be in sync with H5O_dtype_ver_bounds[] in H5T.c */ +const unsigned dtype_ver_bounds[] = { + DTYPE_VERSION_1, /* H5F_LIBVER_EARLIEST */ + DTYPE_VERSION_3, /* H5F_LIBVER_V18 */ + DTYPE_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; + +/* These should be in sync with H5O_ATTR* versions in H5Apkg.h */ +#define ATTR_VERSION_1 1 +#define ATTR_VERSION_2 2 +#define ATTR_VERSION_3 3 +#define ATTR_VERSION_LATEST ATTR_VERSION_3 + +/* These should be in sync with H5O_attr_ver_bounds[] in H5Aint.c */ +const unsigned attr_ver_bounds[] = { + ATTR_VERSION_1, /* H5F_LIBVER_EARLIEST */ + ATTR_VERSION_3, /* H5F_LIBVER_V18 */ + ATTR_VERSION_LATEST /* H5F_LIBVER_LATEST */ +}; static void create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *); @@ -4939,6 +5073,1401 @@ test_libver_bounds(void) /**************************************************************** ** +** test_libver_bounds_attributes(): +** Verify the attribute versions. +** +****************************************************************/ +static void +test_libver_bounds_attributes(hid_t fapl) +{ + hid_t fid; /* File ID */ + hid_t fcpl; /* File creation property list */ + hid_t new_fapl; /* File access property list */ + hid_t did; /* Dataset ID */ + hid_t tid; /* Datatype ID */ + hid_t gid; /* Group ID */ + hid_t sid; /* Dataspace ID */ + hid_t aid; /* Attribute ID */ + hid_t attr_cpl; /* Attribute creation property list */ + H5A_t *attr; /* Internal attribute pointer */ + H5F_t *f; /* Internal file pointer */ + H5F_libver_t low, high; /* File format bounds */ + herr_t ret; /* Return value */ + + /* Retrieve the library format bounds */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); + + /* Create the file */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Integer datatpye */ + tid = H5Tcopy(H5T_NATIVE_INT); + CHECK(tid, FAIL, "H5Tcopy"); + + /* Create a committed datatype */ + ret = H5Tcommit2(fid, "datatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + + /* Create dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create a group */ + gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); + + /* Create an attribute to the group with the committed datatype */ + aid = H5Acreate2(gid, "attr1", tid, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Get the internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); + + /* Verify the attribute version */ + if(low == H5F_LIBVER_EARLIEST) + VERIFY(attr->shared->version, ATTR_VERSION_2, "attr_ver_bounds"); + else + VERIFY(attr->shared->version, attr_ver_bounds[low], "dtype_ver_bounds"); + + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + /* Create an attribute to the group with integer type */ + aid = H5Acreate2(gid, "attr2", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Get the internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); + + /* Verify attribute version */ + VERIFY(attr->shared->version, attr_ver_bounds[low], "dtype_ver_bounds"); + + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + /* Enable character encoding in attribute creation property list */ + attr_cpl = H5Pcreate(H5P_ATTRIBUTE_CREATE); + CHECK(attr_cpl, FAIL, "H5Pcreate"); + ret = H5Pset_char_encoding(attr_cpl, H5T_CSET_UTF8); + CHECK(ret, FAIL, "H5Pset_char_encoding"); + + /* Create an attribute to the group with character encoding set */ + aid = H5Acreate2(gid, "attr3", H5T_NATIVE_INT, sid, attr_cpl, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Get internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); + + /* Verify attribute version */ + if(low == H5F_LIBVER_EARLIEST) + VERIFY(attr->shared->version, ATTR_VERSION_3, "attr_ver_bounds"); + else + VERIFY(attr->shared->version, attr_ver_bounds[low], "dtype_ver_bounds"); + + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close the group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the datatype */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create a copy of the file creation property list */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + + /* Enable shared datatype message */ + ret = H5Pset_shared_mesg_nindexes(fcpl, 1); + CHECK(ret, FAIL, "H5Pset_shared_mesg_nindexes"); + ret = H5Pset_shared_mesg_index(fcpl, 0, H5O_SHMESG_DTYPE_FLAG, 2); + CHECK(ret, FAIL, "H5Pset_shared_mesg_index"); + + /* Create the file with shared datatype message enabled */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Integer datatye */ + tid = H5Tcopy(H5T_NATIVE_INT); + CHECK(tid, FAIL, "H5Tcopy"); + + /* Create dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create a group */ + gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); + + /* Create an attribute to the group with integer datatype */ + aid = H5Acreate2(gid, ATTR_NAME, tid, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Get the internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); + + /* Verify the attribute version */ + if(low == H5F_LIBVER_EARLIEST) + VERIFY(attr->shared->version, ATTR_VERSION_2, "attr_ver_bounds"); + else + VERIFY(attr->shared->version, attr_ver_bounds[low], "dtype_ver_bounds"); + + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + /* Close the group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the datatype */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create a copy of the file pccess roperty list */ + new_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(new_fapl, FAIL, "H5Pcreate"); + + /* Create the dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Loop through all the combinations of low/high library format bounds */ + /* Open the file and group and attach an attribute to the group */ + /* Verify the attribute version */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { + H5E_BEGIN_TRY { + ret = H5Pset_libver_bounds(new_fapl, low, high); + } H5E_END_TRY; + + if(ret < 0) /* Invalid low/high combinations */ + continue; + + /* Open the file */ + H5E_BEGIN_TRY { + fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); + } H5E_END_TRY; + + if(fid >=0 ) { /* The file open succeeds */ + + /* Get the internal file pointer */ + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); + + /* Open the group */ + gid = H5Gopen2(fid, GRP_NAME, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); + + /* Create an attribute to the group */ + aid = H5Acreate2(gid, "attr1", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); + + /* Get the internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); + + VERIFY(attr->shared->version, attr_ver_bounds[f->shared->low_bound], "attr_ver_bounds"); + + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + /* Delete the attribute */ + ret = H5Adelete(gid, "attr1"); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close the group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + } /* end if */ + } /* end for */ + } /* end for */ + + /* Close the file access property list */ + ret = H5Pclose(new_fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + +} /* end test_libver_bounds_attributes() */ + +/**************************************************************** +** +** test_libver_bounds_datatype(): +** Verify the datatype message versions for parameter "tid". +** +****************************************************************/ +static void +test_libver_bounds_datatype_check(hid_t fapl, hid_t tid) +{ + hid_t fid; /* File ID */ + hid_t new_fapl; /* File acess property list */ + hid_t dcpl; /* Dataset creation property list */ + hid_t dtid; /* Datatype ID for the dataset */ + hid_t str_tid; /* String datatype ID */ + hid_t did; /* Dataset ID */ + hid_t sid; /* Dataspace ID */ + hsize_t dims[1] = {1}; /* Dimension sizes */ + hsize_t dims2[2] = {5, 4}; /* Dimension sizes */ + hsize_t max_dims2[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dimension sizes */ + hsize_t chunks[2] = {2, 3}; /* Chunk dimension sizes */ + H5T_t *dtype; /* Internal datatype pointer */ + H5T_t *str_dtype; /* Internal datatype pointer for the string datatype */ + H5F_t *f; /* Internal file pointer */ + H5F_libver_t low, high; /* File format bounds */ + herr_t ret; /* Return value */ + + /* Retrieve the library format bounds */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); + + /* Create the file */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a committed datatype of string */ + str_tid = H5Tcopy(H5T_C_S1); + CHECK(str_tid, FAIL, "H5Tcopy"); + ret = H5Tset_size(str_tid, (size_t)10); + CHECK(ret, FAIL, "H5Tset_size"); + ret = H5Tcommit2(fid, "datatype", str_tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); + ret = H5Tclose(str_tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Create dataspace */ + sid = H5Screate_simple(1, dims, NULL); + CHECK(sid, FAIL, "H5Screate"); + + /* Create a dataset */ + did = H5Dcreate2(fid, DSET1, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); + + /* Get the dataset's datatype */ + dtid = H5Dget_type(did); + CHECK(dtid, FAIL, "H5Dget_type"); + + /* Get the internal datatype pointer */ + dtype = (H5T_t *)H5I_object(dtid); + CHECK(dtype, NULL, "H5I_object"); + + /* Verify the datatype versions */ + /* Datatype version is upgraded only for H5T_COMPOUND, H5T_ENUM, H5T_ARRAY */ + /* H5T_VLEN: the version is upgraded if the parent datatype version is greater */ + /* Remaining datatypes use basic version: + H5T_INTEGER H5T_FLOAT H5T_TIME H5T_STRING H5T_BITFIELD H5T_OPAQUE H5T_REFERENCE */ + + if(dtype->shared->type == H5T_COMPOUND || + dtype->shared->type == H5T_ENUM || + dtype->shared->type == H5T_ARRAY) { + if(dtype->shared->type == H5T_ARRAY && low == H5F_LIBVER_EARLIEST) + VERIFY(dtype->shared->version, DTYPE_VERSION_2, "dtype_ver_bounds"); + else + VERIFY(dtype->shared->version, dtype_ver_bounds[low], "dtype_ver_bounds"); + } else + VERIFY(dtype->shared->version, dtype_ver_bounds[H5F_LIBVER_EARLIEST], "dtype_ver_bounds"); + + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close the datatype */ + ret = H5Tclose(dtid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create a copy of file access property list */ + new_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(new_fapl, FAIL, "H5Pcreate"); + + /* Prepare to create a chunked dataset with 2 unlimited dimensions */ + sid = H5Screate_simple(2, dims2, max_dims2); + CHECK(sid, FAIL, "H5Screate"); + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + ret = H5Pset_chunk(dcpl, 2, chunks); + CHECK(ret, FAIL, "H5Pset_chunk"); + + /* Loop through all the combinations of low/high library format bounds */ + /* Open the file and create the chunked dataset */ + /* Verify the dataset's datatype versions */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { + H5E_BEGIN_TRY { + ret = H5Pset_libver_bounds(new_fapl, low, high); + } H5E_END_TRY; + + if (ret < 0) /* Invalid low/high combinations */ + continue; + + /* Open the file */ + H5E_BEGIN_TRY { + fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); + } H5E_END_TRY; + + if(fid >= 0 ) { /* The file open succeeds */ + + /* Get the internal file pointer */ + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); + + /* Verify the committed datatype's version */ + str_tid = H5Topen2(fid, "datatype", H5P_DEFAULT); + CHECK(str_tid, FAIL, "H5Topen2"); + str_dtype = (H5T_t *)H5I_object(str_tid); + CHECK(str_dtype, NULL, "H5I_object"); + + VERIFY(str_dtype->shared->version, dtype_ver_bounds[H5F_LIBVER_EARLIEST], "dtype_ver_bounds"); + + ret = H5Tclose(str_tid); + CHECK(ret, FAIL, "H5Tclose"); + + + /* Create the chunked dataset */ + did = H5Dcreate2(fid, DSETNAME, tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); + + /* Get the dataset's datatype */ + dtid = H5Dget_type(did); + CHECK(dtid, FAIL, "H5Dget_type"); + + /* Get the internal datatype pointer */ + dtype = (H5T_t *)H5I_object(dtid); + CHECK(dtype, NULL, "H5I_object"); + + if(dtype->shared->type == H5T_COMPOUND || + dtype->shared->type == H5T_ENUM || + dtype->shared->type == H5T_ARRAY) { + + if(dtype->shared->type == H5T_ARRAY && + f->shared->low_bound == H5F_LIBVER_EARLIEST) + VERIFY(dtype->shared->version, DTYPE_VERSION_2, "dtype_ver_bounds"); + else + VERIFY(dtype->shared->version, dtype_ver_bounds[f->shared->low_bound], "dtype_ver_bounds"); + + } else /* not compound/enum/array */ + VERIFY(dtype->shared->version, dtype_ver_bounds[H5F_LIBVER_EARLIEST], "dtype_ver_bounds"); + + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close the dataset's datatype */ + ret = H5Tclose(dtid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Delete the dataset */ + ret = H5Ldelete(fid, DSETNAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + } /* end if */ + } /* end for */ + } /* end for */ + + /* Close the file access property list */ + ret = H5Pclose(new_fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the dataset creation property list */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); + +} /* end test_libver_bounds_datatype_check() */ + +/**************************************************************** +** +** test_libver_bounds_datatype(): +** Verify the datatype versions for various datatypes. +** +****************************************************************/ +static void +test_libver_bounds_datatype(hid_t fapl) +{ + hid_t tid, tid_enum, tid_array, tid_compound, tid_vlen; /* Datatype IDs */ + int enum_value; /* Value for enum datatype */ + typedef struct s1 { /* Data structure for compound datatype */ + char c; + int i; + } s1; + hsize_t dims[1] = {1}; /* Dimension sizes */ + herr_t ret; /* Return value */ + + /* Create integer datatype */ + tid = H5Tcopy(H5T_NATIVE_INT); + + /* Verify datatype versions */ + test_libver_bounds_datatype_check(fapl, tid); + + /* Create enum datatype */ + tid_enum = H5Tenum_create(tid); + enum_value = 0; + H5Tenum_insert(tid_enum, "val1", &enum_value); + enum_value = 1; + H5Tenum_insert(tid_enum, "val2", &enum_value); + + /* Verify datatype versions */ + test_libver_bounds_datatype_check(fapl, tid_enum); + + /* Create array datatype */ + tid_array = H5Tarray_create2(tid, 1, dims); + + /* Verify datatype versions */ + test_libver_bounds_datatype_check(fapl, tid_array); + + /* Create compound datatype */ + tid_compound = H5Tcreate(H5T_COMPOUND, sizeof(s1)); + H5Tinsert(tid_compound, "c", HOFFSET(s1, c), H5T_STD_U8LE); + H5Tinsert(tid_compound, "i", HOFFSET(s1, i), H5T_NATIVE_INT); + + /* Verify datatype versions */ + test_libver_bounds_datatype_check(fapl, tid_compound); + + /* Create vlen datatype */ + tid_vlen = H5Tvlen_create(tid); + + /* Verify datatype versions */ + test_libver_bounds_datatype_check(fapl, tid_vlen); + + /* Close datatypes */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + ret = H5Tclose(tid_enum); + CHECK(ret, FAIL, "H5Tclose"); + + ret = H5Tclose(tid_array); + CHECK(ret, FAIL, "H5Tclose"); + + ret = H5Tclose(tid_compound); + CHECK(ret, FAIL, "H5Tclose"); + + ret = H5Tclose(tid_vlen); + CHECK(ret, FAIL, "H5Tclose"); + +} /* end test_libver_bounds_datatype() */ + +/**************************************************************** +** +** test_libver_bounds_dataspace(): +** Verify the dataspace message versions. +** +****************************************************************/ +static void +test_libver_bounds_dataspace(hid_t fapl) +{ + hid_t fid; /* File ID */ + hid_t new_fapl; /* File access property list */ + hid_t did, did_null, did_compact, did_contig; /* Dataset IDs */ + hid_t sid, sid_null, sid_compact, sid_contig; /* Dataspace IDs */ + hid_t dcpl, dcpl_compact, dcpl_contig; /* Dataset creation property lists */ + H5S_t *space, *space_null, *space_compact, *space_contig; /* Internal dataspace pointers */ + H5F_t *f; /* Internal file pointer */ + H5F_libver_t low, high; /* File format bounds */ + hsize_t dims[1] = {1}; /* Dimension sizes */ + hsize_t dims2[2] = {5, 4}; /* Dimension sizes */ + hsize_t max_dims[1] = {H5S_UNLIMITED}; /* Maximum dimension sizes */ + hsize_t chunks[1] = {4}; /* Chunk dimension sizes */ + herr_t ret; /* Return value */ + + /* Create null dataspace, scalar dataspace */ + + /* Retrieve the library format bounds */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); + + /* Create the file */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create scalar dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create the dataset with scalar dataspace */ + did = H5Dcreate2(fid, DSET, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate"); + + /* Get the internal dataspace pointer */ + sid = H5Dget_space(did); + CHECK(sid, FAIL, "H5Dget_space"); + space = (H5S_t *)H5I_object(sid); + CHECK(space, NULL, "H5I_object"); + + /* Verify the dataspace version */ + VERIFY(space->extent.version, sdspace_ver_bounds[low], "sdspace_ver_bounds"); + + /* Create null dataspace */ + sid_null = H5Screate(H5S_NULL); + CHECK(sid_null, FAIL, "H5Screate"); + + /* Create the dataset with null dataspace */ + did_null = H5Dcreate2(fid, DSET_NULL, H5T_NATIVE_INT, sid_null, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did_null, FAIL, "H5Dcreate"); + + /* Get the internal dataspace pointer */ + sid_null = H5Dget_space(did_null); + CHECK(sid_null, FAIL, "H5Dget_space"); + space_null = (H5S_t *)H5I_object(sid_null); + CHECK(space_null, NULL, "H5I_object"); + + /* Verify the dataspace version */ + VERIFY(space_null->extent.version, SDSPACE_VERSION_2, "sdspace_ver_bounds"); + + /* Close the datasets */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(did_null); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close the dataspaces */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid_null); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Create a copy of file access property list */ + new_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(new_fapl, FAIL, "H5Pcreate"); + + /* Prepare to create a chunked dataset with 1 unlimited dimension */ + sid = H5Screate_simple(1, dims, max_dims); + CHECK(sid, FAIL, "H5Screate"); + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + ret = H5Pset_chunk(dcpl, 1, chunks); + CHECK(ret, FAIL, "H5Pset_chunk"); + + /* Prepare to create a compact dataset */ + sid_compact = H5Screate_simple(1, dims, NULL); + CHECK(sid_compact, FAIL, "H5Screate"); + dcpl_compact = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl_compact, FAIL, "H5Pcreate"); + ret = H5Pset_layout(dcpl_compact, H5D_COMPACT); + CHECK(ret, FAIL, "H5Pset_layout"); + + /* Prepare to create a contiguous dataset */ + sid_contig = H5Screate_simple(2, dims2, NULL); + CHECK(sid_contig, FAIL, "H5Screate"); + dcpl_contig = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl_contig, FAIL, "H5Pcreate"); + ret = H5Pset_layout(dcpl_contig, H5D_CONTIGUOUS); + CHECK(ret, FAIL, "H5Pset_layout"); + + /* Loop through all the combinations of low/high library format bounds */ + /* Open the file and create the chunked/compact/contiguous datasets */ + /* Verify the dataspace version for the three datasets */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { + H5E_BEGIN_TRY { + ret = H5Pset_libver_bounds(new_fapl, low, high); + } H5E_END_TRY; + + if (ret < 0) /* Invalid low/high combinations */ + continue; + + /* Open the file */ + H5E_BEGIN_TRY { + fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); + } H5E_END_TRY; + + if(fid >=0 ) { /* The file open succeeds */ + + /* Get the internal file pointer */ + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); + + /* Create the chunked dataset */ + did = H5Dcreate2(fid, DSETA, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); + + /* Get the internal dataspace pointer for the chunked dataset */ + sid = H5Dget_space(did); + CHECK(sid, FAIL, "H5Dget_space"); + space = (H5S_t *)H5I_object(sid); + CHECK(space, NULL, "H5I_object"); + + /* Create the compact dataset */ + did_compact = H5Dcreate2(fid, DSETB, H5T_NATIVE_INT, sid_compact, H5P_DEFAULT, dcpl_compact, H5P_DEFAULT); + CHECK(did_compact, FAIL, "H5Dcreate2"); + + /* Get the internal dataspace pointer for the compact dataset */ + sid_compact = H5Dget_space(did_compact); + CHECK(sid_compact, FAIL, "H5Dget_space"); + space_compact = (H5S_t *)H5I_object(sid_compact); + CHECK(space_compact, NULL, "H5I_object"); + + /* Create the contiguous dataset */ + did_contig = H5Dcreate2(fid, DSETC, H5T_NATIVE_INT, sid_contig, H5P_DEFAULT, dcpl_contig, H5P_DEFAULT); + CHECK(did_contig, FAIL, "H5Dcreate2"); + + /* Get the internal dataspace pointer for the contiguous dataset */ + sid_contig = H5Dget_space(did_contig); + CHECK(sid_contig, FAIL, "H5Dget_space"); + space_contig = (H5S_t *)H5I_object(sid_contig); + CHECK(space_contig, NULL, "H5I_object"); + + VERIFY(space->extent.version, sdspace_ver_bounds[f->shared->low_bound], "sdspace_ver_bounds"); + VERIFY(space_compact->extent.version, sdspace_ver_bounds[f->shared->low_bound], "sdspace_ver_bounds"); + VERIFY(space_contig->extent.version, sdspace_ver_bounds[f->shared->low_bound], "sdspace_ver_bounds"); + + /* Close the three datasets */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(did_compact); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Dclose(did_contig); + CHECK(ret, FAIL, "H5Dclose"); + + /* Delete the three datasets */ + ret = H5Ldelete(fid, DSETA, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + ret = H5Ldelete(fid, DSETB, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + ret = H5Ldelete(fid, DSETC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + } /* end if */ + } /* end for */ + } /* end for */ + + /* Close the file access property list */ + ret = H5Pclose(new_fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close the three dataspaces */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid_compact); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Sclose(sid_contig); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the three dataset creation property lists */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(dcpl_compact); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(dcpl_contig); + CHECK(ret, FAIL, "H5Pclose"); + +} /* end test_libver_bounds_dataspace() */ + +/**************************************************************** +** +** test_libver_bounds_dataset(): +** Verify the dataset's layout, fill, and pline message versions +** with the low/high library format bounds setting in the fapl. +** For chunked dataset, also verify the chunked indexing type. +** +****************************************************************/ +static void +test_libver_bounds_dataset(hid_t fapl) +{ + hid_t fid; /* File ID */ + hid_t new_fapl; /* File access property list */ + hid_t did; /* Dataset ID */ + hid_t sid; /* Dataspace ID */ + hid_t dcpl; /* Dataset creation property list */ + H5D_t *dset; /* Internal dataset pointer */ + H5F_t *f; /* Internal file pointer */ + H5F_libver_t low, high; /* File format bounds */ + herr_t ret; /* Return value */ + hsize_t fix_dims2[2] = {10, 4}; /* Dimension sizes */ + hsize_t fix_chunks2[2] = {4, 3}; /* Chunk dimension sizes */ + hsize_t dims2[2] = {1, 4}; /* Dimension sizes */ + hsize_t max_dims2[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dimension sizes */ + hsize_t chunks2[2] = {4, 5}; /* Chunk dimension sizes */ + + /* Retrieve the library format bounds */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); + + /* Create the file */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create the dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create a contiguous dataset */ + did = H5Dcreate2(fid, DSETA, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate"); + + /* Get the internal file pionter */ + dset = (H5D_t *)H5I_object(did); + CHECK(dset, NULL, "H5I_object"); + + /* Verify layout and fill messages version */ + if(low == H5F_LIBVER_EARLIEST) { + VERIFY(dset->shared->layout.version, LAYOUT_VERSION_DEFAULT, "layout_ver_bounds"); + VERIFY(dset->shared->dcpl_cache.fill.version, FILL_VERSION_DEFAULT, "fill_ver_bounds"); + } else { + VERIFY(dset->shared->layout.version, layout_ver_bounds[low], "layout_ver_bounds"); + VERIFY(dset->shared->dcpl_cache.fill.version, fill_ver_bounds[low], "fill_ver_bounds"); + } + + /* Verify pline message version */ + VERIFY(dset->shared->dcpl_cache.pline.version, pline_ver_bounds[low], "pline_ver_bounds"); + + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Create a chunked dataset with "no filter edge chunks" enabled */ + sid = H5Screate_simple(2, fix_dims2, NULL); + CHECK(sid, FAIL, "H5Screate"); + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + ret = H5Pset_chunk(dcpl, 2, fix_chunks2); + CHECK(ret, FAIL, "H5Pset_chunk"); + ret = H5Pset_chunk_opts(dcpl, H5D_CHUNK_DONT_FILTER_PARTIAL_CHUNKS); + CHECK(ret, FAIL, "H5Pset_chunk"); + + H5E_BEGIN_TRY { + did = H5Dcreate2(fid, DSETB, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); + } H5E_END_TRY; + + if(did >= 0) { + + /* Get the internal dataset pointer */ + dset = (H5D_t *)H5I_object(did); + CHECK(dset, NULL, "H5I_object"); + + VERIFY(dset->shared->layout.version, LAYOUT_VERSION_4, "layout_ver_bounds"); + VERIFY(dset->shared->layout.u.chunk.idx_type, H5D_CHUNK_IDX_FARRAY, "chunk_index_type"); + + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + } + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close the datset creation property list */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Create a copy of file access property list */ + new_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(new_fapl, FAIL, "H5Pcreate"); + + /* Prepare to create a chunked dataset with 2 unlimited dimensions */ + sid = H5Screate_simple(2, dims2, max_dims2); + CHECK(sid, FAIL, "H5Screate"); + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + ret = H5Pset_chunk(dcpl, 2, chunks2); + CHECK(ret, FAIL, "H5Pset_chunk"); + + /* Loop through all the combinations of low/high library format bounds */ + /* Open the file and create the chunked dataset */ + /* Verify the dataset's layout, fill, pline message versions and chunked indexing type */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { + H5E_BEGIN_TRY { + ret = H5Pset_libver_bounds(new_fapl, low, high); + } H5E_END_TRY; + + if (ret < 0) /* Invalid low/high combinations */ + continue; + + /* Open the file */ + H5E_BEGIN_TRY { + fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); + } H5E_END_TRY; + + if(fid >=0 ) { /* The file open succeeds */ + + /* Get the internal file pointer */ + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); + + /* Create the chunked dataset */ + did = H5Dcreate2(fid, DSETC, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); + + /* Get the internal file pointer */ + dset = (H5D_t *)H5I_object(did); + CHECK(dset, NULL, "H5I_object"); + + /* Verify the dataset's layout, fill, pline message versions and chunked indexing type */ + if(f->shared->low_bound == H5F_LIBVER_EARLIEST) { + VERIFY(dset->shared->layout.version, LAYOUT_VERSION_DEFAULT, "layout_ver_bounds"); + VERIFY(dset->shared->dcpl_cache.fill.version, FILL_VERSION_DEFAULT, "fill_ver_bounds"); + } else { + VERIFY(dset->shared->layout.version, layout_ver_bounds[f->shared->low_bound], "layout_ver_bounds"); + VERIFY(dset->shared->dcpl_cache.fill.version, fill_ver_bounds[f->shared->low_bound], "fill_ver_bounds"); + } + + VERIFY(dset->shared->dcpl_cache.pline.version, pline_ver_bounds[f->shared->low_bound], "pline_ver_bounds"); + if(dset->shared->layout.version == LAYOUT_VERSION_LATEST) + VERIFY(dset->shared->layout.u.chunk.idx_type, H5D_CHUNK_IDX_BT2, "chunk_index_type"); + else + VERIFY(dset->shared->layout.u.chunk.idx_type, H5D_CHUNK_IDX_BTREE, "chunk_index_type"); + + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + + /* Delete the dataset */ + ret = H5Ldelete(fid, DSETC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + } /* end if */ + } /* end for */ + } /* end for */ + + /* CLose the file access property list */ + ret = H5Pclose(new_fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* CLose the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + /* CLose the dataset creation property list */ + ret = H5Pclose(dcpl); + CHECK(ret, FAIL, "H5Pclose"); + +} /* end test_libver_bounds_dataset() */ + +/**************************************************************** +** +** test_libver_bounds_obj(): +** Verify object header version with the low/high library +** format bounds setting in the fapl. +** +****************************************************************/ +static void +test_libver_bounds_obj(hid_t fapl) +{ + hid_t fid; /* File ID */ + hid_t gid; /* Group ID */ + hid_t fcpl; /* File creation property list */ + hid_t new_fapl; /* File access property list */ + H5F_t *f; /* Internal file pointer */ + H5F_libver_t low, high; /* File format bounds */ + H5O_info_t oinfo; /* Object info */ + H5G_info_t ginfo; /* Group info */ + herr_t ret; /* Return value */ + + /* Retrieve the format bounds */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); + + /* Get a copy of file creation property list */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + + /* Enable shared message */ + ret = H5Pset_shared_mesg_nindexes(fcpl, 1); + CHECK(ret, FAIL, "H5Pset_shared_mesg_nindexes"); + ret = H5Pset_shared_mesg_index(fcpl, 0, H5O_SHMESG_ATTR_FLAG, 2); + CHECK(ret, FAIL, "H5Pset_shared_mesg_index"); + + /* Create the file */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Get root group's object info */ + ret = H5Oget_info_by_name(fid, "/", &oinfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info"); + + /* Verify object header version is 2 when shared message is enabled */ + VERIFY(oinfo.hdr.version, OBJ_VERSION_2, "H5Oget_info"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Close the file creation property list */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create a file with default fcpl */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Get root group's object info */ + ret = H5Oget_info_by_name(fid, "/", &oinfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info"); + + /* Verify object header version */ + VERIFY(oinfo.hdr.version, obj_ver_bounds[low], "H5Oget_info"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create a copy of file access property list */ + new_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(new_fapl, FAIL, "H5Pcreate"); + + /* Loop through all the combinations of low/high library format bounds */ + /* Open the file to verify object header version */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { + H5E_BEGIN_TRY { + ret = H5Pset_libver_bounds(new_fapl, low, high); + } H5E_END_TRY; + + if (ret < 0) /* Invalid combinations */ + continue; + + /* Open the file */ + H5E_BEGIN_TRY { + fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); + } H5E_END_TRY; + + if(fid >=0 ) { /* The file open succeeds */ + + /* Get the internal file pointer */ + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); + + /* Create a group in the file */ + gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); + + /* Get group information */ + ret = H5Gget_info(gid, &ginfo); + CHECK(ret, FAIL, "H5Gget_info"); + + /* Verify group storage type */ + if(f->shared->low_bound >= H5F_LIBVER_V18) + VERIFY(ginfo.storage_type, H5G_STORAGE_TYPE_COMPACT, "H5Gget_info"); + else + VERIFY(ginfo.storage_type, H5G_STORAGE_TYPE_SYMBOL_TABLE, "H5Gget_info"); + + /* Get object header information */ + ret = H5Oget_info_by_name(gid, GRP_NAME, &oinfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info"); + + /* Verify object header version */ + VERIFY(oinfo.hdr.version, obj_ver_bounds[f->shared->low_bound], "H5Oget_info_by_name"); + + /* Close the group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Delete the group */ + ret = H5Ldelete(fid, GRP_NAME, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Gclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + } /* end if */ + } /* end for */ + } /* end for */ + + /* Close the file access property list */ + ret = H5Pclose(new_fapl); + CHECK(ret, FAIL, "H5Pclose"); + +} /* end test_libver_bounds_obj() */ + +/**************************************************************** +** +** test_libver_bounds_super(): +** Verify open of a file with 0, 1, 2 and 3 superblock versions. +** +****************************************************************/ +static void +test_libver_bounds_super_open(hid_t fapl, hid_t fcpl, htri_t is_swmr) +{ + hid_t fid; /* File ID */ + H5F_t *f; /* Internal file pointer */ + hid_t new_fapl; /* File access property list */ + unsigned super_vers; /* Superblock version */ + H5F_libver_t low, high; /* File format bounds */ + hbool_t ok; /* The result is ok or not */ + herr_t ret; /* Return value */ + + /* Create the file */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Get the internal file pointer */ + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); + + /* The file's superblock version */ + super_vers = f->shared->sblock->super_vers; + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Create a file access property list */ + new_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(new_fapl, FAIL, "H5Pcreate"); + + /* Loop through all the combinations of low/high library format bounds */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { + H5E_BEGIN_TRY { + ret = H5Pset_libver_bounds(new_fapl, low, high); + } H5E_END_TRY; + + /* Invalid combinations */ + if (ret < 0) + continue; + + /* Open the file with or without SWMR */ + H5E_BEGIN_TRY { + fid = H5Fopen(FILE8, H5F_ACC_RDWR | (is_swmr ? H5F_ACC_SWMR_WRITE : 0), new_fapl); + } H5E_END_TRY; + ok = fid >= 0; + + /* Verify the file open succeeds or fails */ + switch(super_vers) { + case 3: + if(high == H5F_LIBVER_LATEST) { + /* Should succeed */ + VERIFY(ok, TRUE, "H5Fopen"); + VERIFY(H5F_LIBVER_V110, f->shared->low_bound, "superblock_ver_bounds"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } else /* Should fail */ + VERIFY(ok, FALSE, "H5Fopen"); + break; + + case 2: + if(is_swmr) /* Should fail */ + VERIFY(ok, FALSE, "H5Fopen"); + else { /* Should succeed */ + VERIFY(ok, TRUE, "H5Fopen"); + + ok = f->shared->low_bound >= H5F_LIBVER_V18; + VERIFY(ok, TRUE, "superblock_ver_bounds"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } + break; + + case 1: + case 0: + if(is_swmr) /* Should fail */ + VERIFY(ok, FALSE, "H5Fopen"); + else { /* Should succeed */ + VERIFY(ok, TRUE, "H5Fopen"); + VERIFY(low, f->shared->low_bound, "superblock_ver_bounds"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } + break; + + default: + break; + } /* end switch */ + } /* end for */ + } /* end for */ + + /* Close the file access property list */ + ret = H5Pclose(new_fapl); + CHECK(ret, FAIL, "H5Pclose"); + +} /* end test_libver_bounds_super_open() */ + +/**************************************************************** +** +** test_libver_bounds_super_create(): +** Verify the superblock version with the low/high library +** version bounds setting in the fapl. +** +****************************************************************/ +static void +test_libver_bounds_super_create(hid_t fapl, hid_t fcpl, htri_t is_swmr) +{ + hid_t fid; /* File ID */ + H5F_t *f; /* Internal file pointer */ + H5F_libver_t low, high; /* File format bounds */ + hbool_t ok; /* The result is ok or not */ + herr_t ret; /* The return value */ + + /* Try to create the file */ + H5E_BEGIN_TRY { + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC | (is_swmr ? H5F_ACC_SWMR_WRITE : 0), fcpl, fapl); + } H5E_END_TRY; + + /* Get the internal file pointer if the create succeeds */ + if((ok = fid >= 0)) { + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); + } + + /* Retrieve the format bounds */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); + + if(is_swmr) { /* SWMR is enabled */ + + if(high == H5F_LIBVER_LATEST) { /* Superblock version is 3 */ + VERIFY(ok, TRUE, "H5Fcreate"); + VERIFY(SUPERBLOCK_VERSION_3, f->shared->sblock->super_vers, "superblock_ver_bounds"); + VERIFY(H5F_LIBVER_V110, f->shared->low_bound, "superblock_ver_bounds"); + + } else /* Should fail */ + VERIFY(ok, FALSE, "H5Fcreate"); + + } else { /* Should succeed */ + VERIFY(ok, TRUE, "H5Fcreate"); + + switch(low) { + case H5F_LIBVER_EARLIEST: + ok = (f->shared->sblock->super_vers == 0 || + f->shared->sblock->super_vers == 1 || + f->shared->sblock->super_vers == 2); + VERIFY(ok, TRUE, "H5Fcreate"); + VERIFY(low, f->shared->low_bound, "superblock_ver_bounds"); + break; + + case H5F_LIBVER_V18: + ok = (f->shared->sblock->super_vers == 2); + VERIFY(ok, TRUE, "H5Fcreate"); + VERIFY(low, f->shared->low_bound, "superblock_ver_bounds"); + break; + + case H5F_LIBVER_V110: + ok = (f->shared->sblock->super_vers == 3); + VERIFY(ok, TRUE, "H5Fcreate"); + VERIFY(low, f->shared->low_bound, "superblock_ver_bounds"); + break; + + case H5F_LIBVER_ERROR: + case H5F_LIBVER_NBOUNDS: + default: + ERROR("H5Pget_libver_bounds"); + + } /* end switch */ + } + + if(ok) { /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } + +} /* end test_libver_bounds_super_create() */ + +/**************************************************************** +** +** test_libver_bounds_super(): +** Verify superblock version via: +** test_libver_bounds_super_create() +** test_libver_bounds_super_open() +** +****************************************************************/ +static void +test_libver_bounds_super(hid_t fapl) +{ + hid_t fcpl; + herr_t ret; + + /* Create a default fcpl */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + + /* Verify superblock version is 0 when creating a file with or without SWMR */ + test_libver_bounds_super_create(fapl, fcpl, TRUE); + test_libver_bounds_super_create(fapl, fcpl, FALSE); + + /* Verify opening a file with or without SWMR when superblock version is 0 */ + test_libver_bounds_super_open(fapl, fcpl, TRUE); + test_libver_bounds_super_open(fapl, fcpl, FALSE); + + /* Create fcpl with non-default v1-btree K value enabled */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + + ret = H5Pset_istore_k(fcpl, 64); + CHECK(ret, FAIL, "H5Pset_istore_k"); + + /* Verify superblock version is 1 when creating a file with or without SWMR */ + test_libver_bounds_super_create(fapl, fcpl, TRUE); + test_libver_bounds_super_create(fapl, fcpl, FALSE); + + /* Verify opening a file with or without SWMR when superblock version is 1 */ + test_libver_bounds_super_open(fapl, fcpl, TRUE); + test_libver_bounds_super_open(fapl, fcpl, FALSE); + + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Create fcpl with shared messages enabled */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + ret = H5Pset_shared_mesg_nindexes(fcpl, 1); + CHECK(ret, FAIL, "H5Pset_shared_mesg_nindexes"); + ret = H5Pset_shared_mesg_index(fcpl, 0, H5O_SHMESG_ATTR_FLAG, 2); + CHECK(ret, FAIL, "H5Pset_shared_mesg_index"); + + /* Verify superblock version is 2 when creating a file with or without SWMR */ + test_libver_bounds_super_create(fapl, fcpl, TRUE); + test_libver_bounds_super_create(fapl, fcpl, FALSE); + + /* Verify opening a file with or without SWMR when superblock version is 2 */ + test_libver_bounds_super_open(fapl, fcpl, TRUE); + test_libver_bounds_super_open(fapl, fcpl, FALSE); + + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Create fcpl with persistent free-space enabled */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + ret = H5Pset_file_space(fcpl, H5F_FILE_SPACE_ALL_PERSIST, (hsize_t)0); + CHECK(ret, FAIL, "H5Pset_file_space"); + + /* Verify superblock version is 2 when creating a file with or without SWMR */ + test_libver_bounds_super_create(fapl, fcpl, TRUE); + test_libver_bounds_super_create(fapl, fcpl, FALSE); + + /* Verify opening a file with or without SWMR when superblock version is 2 */ + test_libver_bounds_super_open(fapl, fcpl, TRUE); + test_libver_bounds_super_open(fapl, fcpl, FALSE); + + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + +} /* end test_libver_bounds_super() */ + +/**************************************************************** +** +** test_libver_bounds_low_high(): +** Tests to verify that format versions are correct with the five +** pairs of (low, high) combinations via H5Pset_libver_bounds(). +** +****************************************************************/ +static void +test_libver_bounds_low_high(void) +{ + hid_t fapl; + H5F_libver_t low, high; + herr_t ret; + + /* Output message about test being performed */ + MESSAGE(5, ("Testing setting library version bounds for (low, high) bounds\n")); + + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + + /* Loop through all the combinations of low/high library format bounds */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { + H5E_BEGIN_TRY { + ret = H5Pset_libver_bounds(fapl, low, high); + } H5E_END_TRY; + + /* Should fail: invalid combinations */ + if(high == H5F_LIBVER_EARLIEST) { + VERIFY(ret, FAIL, "H5Pset_libver_bounds"); + continue; + } + + /* Should fail: invalid combinations */ + if(high < low) { + VERIFY(ret, FAIL, "H5Pset_libver_bounds"); + continue; + } + + /* All other combinations are valid and should succeed */ + VERIFY(ret, SUCCEED, "H5Pset_libver_bounds"); + + /* Tests to verify format versions */ + test_libver_bounds_super(fapl); + test_libver_bounds_obj(fapl); + test_libver_bounds_dataset(fapl); + test_libver_bounds_dataspace(fapl); + test_libver_bounds_datatype(fapl); + test_libver_bounds_attributes(fapl); + } + + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + +} /* end test_libver_bounds_low_high() */ + +/**************************************************************** +** ** test_libver_macros(): ** Verify that H5_VERSION_GE and H5_VERSION_LE work correactly. ** @@ -5333,6 +6862,7 @@ test_file(void) test_filespace_round_compatible(); /* Testing file space compatibility for files from trunk to 1_8 to trunk */ test_filespace_1_10_0_compatible(); /* Testing file space compatibility for files from release 1.10.0 */ test_libver_bounds(); /* Test compatibility for file space management */ + test_libver_bounds_low_high(); test_libver_macros(); /* Test the macros for library version comparison */ test_libver_macros2(); /* Test the macros for library version comparison */ #ifndef H5_NO_DEPRECATED_SYMBOLS |