From 37318f109a294bb47e5040be5888963967c1badc Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Fri, 12 Jan 2018 14:36:03 -0600 Subject: Changes made based on code reviews. --- src/H5Aint.c | 17 +- src/H5Dint.c | 25 +- src/H5Dlayout.c | 19 +- src/H5F.c | 18 +- src/H5Fdeprec.c | 62 ++ src/H5Fint.c | 36 +- src/H5Fprivate.h | 1 + src/H5Fpublic.h | 3 +- src/H5Fquery.c | 11 +- src/H5Fsuper.c | 87 ++- src/H5Gobj.c | 12 +- src/H5Oattr.c | 2 + src/H5Ocopy.c | 6 + src/H5Odtype.c | 2 + src/H5Ofill.c | 22 +- src/H5Oint.c | 22 +- src/H5Olayout.c | 5 +- src/H5Opkg.h | 8 +- src/H5Opline.c | 19 +- src/H5Oprivate.h | 6 +- src/H5Osdspace.c | 2 + src/H5S.c | 15 +- src/H5T.c | 5 +- src/H5trace.c | 3 +- test/genall5.c | 8 +- test/mf.c | 10 +- test/tfile.c | 2236 +++++++++++++++++++++++++++++------------------------- 27 files changed, 1534 insertions(+), 1128 deletions(-) diff --git a/src/H5Aint.c b/src/H5Aint.c index 5c32e86..666f11d 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -1863,6 +1863,7 @@ herr_t 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 */ + uint8_t version; /* Message version */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1884,18 +1885,22 @@ H5A_set_version(const H5F_t *f, H5A_t *attr) /* Check which version to encode attribute with */ if(attr->shared->encoding != H5T_CSET_ASCII) - attr->shared->version = H5O_ATTR_VERSION_3; /* Write version which includes the character encoding */ + 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 */ + 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 */ + 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)]); + version = MAX(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)]) + /* Version bounds check */ + if(version > H5O_attr_ver_bounds[H5F_HIGH_BOUND(f)]) HGOTO_ERROR(H5E_ATTR, H5E_BADRANGE, FAIL, "attribute version out of bounds") + + /* Set the message version */ + attr->shared->version = version; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_set_version() */ diff --git a/src/H5Dint.c b/src/H5Dint.c index c1a66ca..89dff1e 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -623,10 +623,10 @@ done: static herr_t 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_v18_latest_format; /* Flag indicating the 'latest datatype version support' is enabled */ - herr_t ret_value = SUCCEED; /* Return value */ + htri_t relocatable; /* Flag whether the type is relocatable */ + htri_t immutable; /* Flag whether the type is immutable */ + hbool_t use_at_least_v18; /* Flag indicating to use at least v18 format versions */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -643,10 +643,11 @@ 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?") - use_v18_latest_format = (H5F_LOW_BOUND(file) >= H5F_LIBVER_V18); + /* To use at least v18 format versions or not */ + use_at_least_v18 = (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_v18_latest_format) { + if(!immutable || relocatable || use_at_least_v18) { /* 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") @@ -786,6 +787,7 @@ H5D__update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) H5D_fill_value_t fill_status; /* Fill value status */ hbool_t fill_changed = FALSE; /* Flag indicating the fill value was changed */ hbool_t layout_init = FALSE; /* Flag to indicate that chunk information was initialized */ + hbool_t use_at_least_v18; /* Flag indicating to use at least v18 format versions */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -800,6 +802,9 @@ H5D__update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) type = dset->shared->type; fill_prop = &dset->shared->dcpl_cache.fill; + /* To use at least v18 format versions or not */ + use_at_least_v18 = (H5F_LOW_BOUND(file) >= H5F_LIBVER_V18); + /* Retrieve "defined" status of fill value */ if(H5P_is_fill_value_defined(fill_prop, &fill_status) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined") @@ -878,8 +883,8 @@ H5D__update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update new fill value header message") /* 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_LOW_BOUND(file) < H5F_LIBVER_V18)) { + /* (only if we aren't using v18 format versions and above */ + if(fill_prop->buf && !use_at_least_v18) { H5O_fill_t old_fill_prop; /* Copy of fill value property, for writing as "old" fill value */ /* Shallow copy the fill value property */ @@ -931,10 +936,10 @@ H5D__update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id) #endif /* H5O_ENABLE_BOGUS */ /* Add a modification time message, if using older format. */ - /* (If using the latest 'no modification time message' version support, the modification time is part of the object + /* (If using v18 format versions and above, the the modification time is part of the object * header and doesn't use a separate message -QAK) */ - if(H5F_LOW_BOUND(file) < H5F_LIBVER_V18) + if(!use_at_least_v18) if(H5O_touch_oh(file, dxpl_id, oh, TRUE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time message") diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index 5a4d537..980b810 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -46,9 +46,10 @@ /* Package Variables */ /*********************/ +/* Format version bounds for layout */ const unsigned H5O_layout_ver_bounds[] = { H5O_LAYOUT_VERSION_1, /* H5F_LIBVER_EARLIEST */ - H5O_LAYOUT_VERSION_3, /* H5F_LIBVER_V18 */ + H5O_LAYOUT_VERSION_3, /* H5F_LIBVER_V18 */ /* H5O_LAYOUT_VERSION_DEFAULT */ H5O_LAYOUT_VERSION_LATEST /* H5F_LIBVER_LATEST */ }; @@ -289,16 +290,15 @@ done: * * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Thursday, January 15, 2009 + * Programmer: Vailin Choi; December 2017 * *------------------------------------------------------------------------- */ herr_t H5D__layout_set_version(H5F_t *f, H5O_layout_t *layout) { - unsigned vers; - herr_t ret_value = SUCCEED; /* Return value */ + unsigned version; /* Message version */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -307,12 +307,15 @@ H5D__layout_set_version(H5F_t *f, H5O_layout_t *layout) HDassert(f); /* 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)]); + version = MAX(layout->version, H5O_layout_ver_bounds[H5F_LOW_BOUND(f)]); - /* File bound check */ - if(layout->version > H5O_layout_ver_bounds[H5F_HIGH_BOUND(f)]) + /* Version bounds check */ + if(version > H5O_layout_ver_bounds[H5F_HIGH_BOUND(f)]) HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "layout version out of bounds") + /* Set the message version */ + layout->version = version; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D__layout_set_version() */ diff --git a/src/H5F.c b/src/H5F.c index c670e17..8e5f65a 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -1478,6 +1478,8 @@ 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->low_bound == H5F_LIBVER_V110) && (file->shared->high_bound == H5F_LIBVER_V110)); + /* Should not be marked for SWMR writing mode already */ if(file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file already in SWMR writing mode") @@ -1739,9 +1741,12 @@ done: /*------------------------------------------------------------------------- - * Function: H5Fset_libver_bounds (Internal library use) + * Function: H5Fset_libver_bounds * - * Purpose: Set .... the "latest format" flag while a file is open. + * Purpose: Set to a different low and high bounds while a file is open. + * This public routine is introduced in place of + * H5Fset_latest_format() starting release 1.10.2. + * See explanation for H5Fset_latest_format() in H5Fdeprec.c. * * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- @@ -1759,12 +1764,9 @@ H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high) if(NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "not a file ID") - /* 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") - - f->shared->low_bound = low; - f->shared->high_bound = high; + /* Call private set_libver_bounds function */ + if(H5F_set_libver_bounds(f, low, high) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set low/high bounds") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Fdeprec.c b/src/H5Fdeprec.c index 03f5df8..a9ffa43 100644 --- a/src/H5Fdeprec.c +++ b/src/H5Fdeprec.c @@ -143,5 +143,67 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_info1() */ + +/*------------------------------------------------------------------------- + * Function: H5Fset_latest_format + * + * Purpose: Enable switching between latest or non-latest format while + * a file is open. + * This is deprecated starting release 1.10.2 and is modified + * to call the private H5F_set_libver_bounds() to set the + * bounds. + * + * Before release 1.10.2, the library supports only two + * combinations of low/high bounds: + * (earliest, latest) + * (latest, latest) + * Thus, this public routine does the job in switching + * between the two combinations listed above. + * + * Starting release 1.10.2, we add v18 to the enumerated + * define H5F_libver_t and the library supports five combinations + * as below: + * (earliest, v18) + * (earliest, v10) + * (v18, v18) + * (v18, v10) + * (v10, v10) + * So we introduce the new public routine H5Fset_libver_bounds() + * in place of H5Fset_latest_format(). + * See also RFC: Setting Bounds for Object Creation in HDF5 1.10.0. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; December 2017 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fset_latest_format(hid_t file_id, hbool_t latest_format) +{ + H5F_t *f; /* File */ + H5F_libver_t low = H5F_LIBVER_LATEST; /* Low bound */ + H5F_libver_t high = H5F_LIBVER_LATEST; /* High bound */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ib", file_id, latest_format); + + /* 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") + + /* 'low' and 'high' are both initialized to LATEST. + If latest format is not expected, set 'low' to EARLIEST */ + if(!latest_format) + low = H5F_LIBVER_EARLIEST; + + /* Call private set_libver_bounds function to set the bounds */ + if(H5F_set_libver_bounds(f, low, high) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set low/high bounds") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fset_latest_format() */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Fint.c b/src/H5Fint.c index f223195..79f0d06 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -671,9 +671,9 @@ H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_IMAGE_CONFIG_NAME, &(f->shared->mdc_initCacheImageCfg)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config") - /* File format version high bound does not allow the generation of metadata cache image */ + /* Format version high bound does not allow the generation of metadata cache image */ if(f->shared->mdc_initCacheImageCfg.generate_image && f->shared->high_bound < H5F_LIBVER_V110) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "file format version out of bound for cache image") + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "format version out of bound for cache image") /* Get the VFD values to cache */ f->shared->maxaddr = H5FD_get_maxaddr(lf); @@ -2313,6 +2313,38 @@ H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_set_store_msg_crt_idx() */ +/*------------------------------------------------------------------------- + * Function: H5F_set_libver_bounds() + * + * Purpose: Set the file's low and high bound to the input parameters + * 'low' and 'high' respectively. + * This is done only if the existing setting is different + * from the inputs. + * + * Return: SUCCEED on success, and FAIL on failure. + * + * Programmer: Vailin Choi; December 2017 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_libver_bounds(H5F_t * f, H5F_libver_t low, H5F_libver_t high) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity checks */ + HDassert(f); + HDassert(f->shared); + + /* Set the bounds only if the existing setting is different from the inputs */ + if(f->shared->low_bound != low || f->shared->high_bound != high) { + f->shared->low_bound = low; + f->shared->high_bound = high; + } + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_libver_bounds() */ + /*------------------------------------------------------------------------- * Function: H5F_get_file_image diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 50325bb..ec98468 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -769,6 +769,7 @@ H5_DLL unsigned H5F_gc_ref(const H5F_t *f); H5_DLL unsigned H5F_use_latest_flags(const H5F_t *f, unsigned fl); H5_DLL hbool_t H5F_store_msg_crt_idx(const H5F_t *f); H5_DLL herr_t H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag); +H5_DLL herr_t H5F_set_libver_bounds(H5F_t * f, H5F_libver_t low, H5F_libver_t high); 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); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 9364ee2..d333fa7 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -173,7 +173,7 @@ typedef struct H5F_sect_info_t { hsize_t size; /* Size of free space section */ } H5F_sect_info_t; -/* Library's file format versions */ +/* Library's format versions */ typedef enum H5F_libver_t { H5F_LIBVER_ERROR = -1, H5F_LIBVER_EARLIEST = 0, /* Use the earliest possible format for storing objects */ @@ -300,6 +300,7 @@ typedef struct H5F_info1_t { /* Function prototypes */ H5_DLL herr_t H5Fget_info1(hid_t obj_id, H5F_info1_t *finfo); +H5_DLL herr_t H5Fset_latest_format(hid_t file_id, hbool_t latest_format); #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Fquery.c b/src/H5Fquery.c index 6b641f1..5d7de9d 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -716,9 +716,14 @@ H5F_sieve_buf_size(const H5F_t *f) * Purpose: Replaced a macro to retrieve the "garbage collect * references flag" now that the generic properties are being used * to store the values. - e - * is returned. - * Failure: (should not happen) + * + * Return: Success: The "garbage collect references flag" is returned. + * Failure: (should not happen) + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Jul 8 2005 + * *------------------------------------------------------------------------- */ unsigned diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 4c12cb9..d30434d 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -457,23 +457,46 @@ 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") - /* Upgrade low bound to at least V18 when encountering version 2 superblock */ + /* + * When opening a file with SWMR-write access, the library will first + * check to ensure that superblock version 3 is used. Otherwise fail + * file open. + * + * Then the library will upgrade the file's low_bound depending on + * superblock version as follows: + * --version 0 or 1: no change to low_bound + * --version 2: upgrade low_bound to at least V18 + * --version 3: upgrade low_bound to at least V110 + * + * Upgrading low_bound will give the best format versions available for + * that superblock version. Due to the possible upgrade, the fapl returned + * from H5Fget_access_plist() might indicate a low_bound higher than what + * the user originally set. + * + * After upgrading low_bound, the library will check to ensure that the + * superblock version does not exceed the version allowed by high_bound. + * Otherise fail file open. + * + * For details, please see RFC:Setting Bounds for Object Creation in HDF5 1.10.0. + */ + + /* Check to ensure that superblock version 3 is used for SWMR-write access */ + if(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) { + if(sblock->super_vers < HDF5_SUPERBLOCK_VERSION_3) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "superblock version for SWMR is less than 3") + } + + /* 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)) + /* Upgrade low_bound to at least V110 when encountering version 3 superblock */ + if(sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_3) f->shared->low_bound = MAX(H5F_LIBVER_V110, f->shared->low_bound); - /* File bound check */ + /* Version bounds 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)") - - /* 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)") - } + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "superblock version exceeds high bound") /* Pin the superblock in the cache */ if(H5AC_pin_protected_entry(sblock) < 0) @@ -833,9 +856,9 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial hbool_t rw = ((rw_flags & H5AC__READ_ONLY_FLAG) == 0); H5O_mdci_t mdci_msg; - /* Message exists but file format version high bound does not allow it */ + /* Message exists but version high bound does not allow it */ if(f->shared->high_bound < H5F_LIBVER_V110) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file format version out of bound for metadata cache image") + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "format version out of bound for metadata cache image") /* if the metadata cache image superblock extension message exists, * read its contents and pass the data on to the metadata cache. @@ -1037,6 +1060,36 @@ 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; + /* + * When creating a file with write access, the library will: + * -- set superblock version to 0, 1 or 2 based on feature enabled + * -- no change to low_bound + * When creating a file with SWMR-write access, the library will: + * (See explanation (#) below.) + * -- set superblock version to 3 + * -- upgrade low_bound to at least V110 + * + * Then the library will finalize superblock version to that allowed by + * low_bound if that is higher. + * Lastly, the library will check to ensure the superblock version does not + * exceed the version allowed by high_bound. Otherwise fail file open. + * + * For details, please see RFC:Setting Bounds for Object Creation in HDF5 1.10.0. + * + * (#) + * Version 3 superblock is introduced in 1.10 for SWMR due to the problem of + * the status_flags field in the superblock. The problem is discussed in + * jira issue SWMR-79 and also in the RFC: File Format Changes in HDF5 1.10.0. + * The file's low_bound is upgraded for SWMR so that the library will + * use the best format versions available in 1.10. + * Due to the possible upgrade, the fapl returned from H5Fget_access_plist() + * might indicate a low_bound higher than what the user originally set. + */ + + /* + * Creating a file with SWMR-write access will + * upgrade superblock version and low_bound + */ 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); @@ -1060,10 +1113,10 @@ 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 */ + /* Finalize superblock version to that allowed by the file's low bound if higher */ super_vers = MAX(super_vers, HDF5_superblock_ver_bounds[f->shared->low_bound]); - /* File bound check */ + /* Version bounds check */ if(super_vers > HDF5_superblock_ver_bounds[f->shared->high_bound]) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "superblock version out of bounds") @@ -1091,8 +1144,8 @@ H5F__super_init(H5F_t *f, hid_t dxpl_id) /* Sanity check the userblock size vs. the file's allocation alignment */ if(userblock_size > 0) { - /* Set up the alignment to use for page or aggr fs */ - hsize_t alignment = H5F_PAGED_AGGR(f) ? f->shared->fs_page_size : f->shared->alignment; + /* Set up the alignment to use for page or aggr fs */ + hsize_t alignment = H5F_PAGED_AGGR(f) ? f->shared->fs_page_size : f->shared->alignment; if(userblock_size < alignment) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "userblock size must be > file object alignment") diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 832c9a7..5f9bdc8 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_v18_latest_format; /* Flag indicating the new group format should be used */ + hbool_t use_at_least_v18; /* 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 */ @@ -204,12 +204,12 @@ H5G__obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, if(0 == (H5F_INTENT(f) & H5F_ACC_RDWR)) HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "no write intent on file") - /* Check for using the latest version of the group format */ + /* Check for using the latest version of the group format which is introduced in v18 */ /* (add more checks for creating "new format" groups when needed) */ if((H5F_LOW_BOUND(f) >= H5F_LIBVER_V18) || linfo->track_corder || (pline && pline->nused)) - use_v18_latest_format = TRUE; + use_at_least_v18 = TRUE; else - use_v18_latest_format = FALSE; + use_at_least_v18 = FALSE; /* Make certain that the creation order is being tracked if an index is * going to be built on it. @@ -218,7 +218,7 @@ H5G__obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, 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_v18_latest_format) { + if(use_at_least_v18) { 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 */ @@ -264,7 +264,7 @@ H5G__obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header") /* Check for format of group to create */ - if(use_v18_latest_format) { + if(use_at_least_v18) { /* 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/H5Oattr.c b/src/H5Oattr.c index 5c45e82..773a16b 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -635,6 +635,8 @@ H5O_attr_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *native_src, HDassert(cpy_info); HDassert(cpy_info->file_dst); + /* Check to ensure that the version of the message to be copied does not exceed + the message version allowed by the destination file's high bound */ if(attr_src->shared->version > H5O_attr_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "attribute message version out of bounds") diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index aa26f05..74c02f4 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -416,6 +416,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/, /* Initialize header information */ oh_dst->version = oh_src->version; + /* Version bounds check for destination object header */ if(oh_dst->version > H5O_obj_ver_bounds[H5F_HIGH_BOUND(oloc_dst->file)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "destination object header version out of bounds") @@ -494,7 +495,12 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out*/, /* Decode the message if necessary. */ H5O_LOAD_NATIVE(oloc_src->file, dxpl_id, 0, oh_src, mesg_src, FAIL) + /* Save destination file pointer in cpy_info so that it can be used + in the pre_copy_file callback to obtain the destination file's + high bound. The high bound is used to index into the corresponding + message's array of versions for doing version bounds check. */ cpy_info->file_dst = oloc_dst->file; + /* Perform "pre copy" operation on message */ if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->native, &(deleted[mesgno]), cpy_info, cpy_udata) < 0) diff --git a/src/H5Odtype.c b/src/H5Odtype.c index f6331df..c51e31d 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -1531,6 +1531,8 @@ H5O_dtype_pre_copy_file(H5F_t *file_src, const void *mesg_src, HDassert(cpy_info); HDassert(cpy_info->file_dst); + /* Check to ensure that the version of the message to be copied does not exceed + the message version as indicated by the destination file's high bound */ if(dt_src->shared->version > H5O_dtype_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "datatype message version out of bounds") diff --git a/src/H5Ofill.c b/src/H5Ofill.c index cf64594..6dc3064 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -156,7 +156,7 @@ const H5O_msg_class_t H5O_MSG_FILL_NEW[1] = {{ /* Format version bounds for fill value */ const unsigned H5O_fill_ver_bounds[] = { H5O_FILL_VERSION_1, /* H5F_LIBVER_EARLIEST */ - H5O_FILL_VERSION_3, /* H5F_LIBVER_V18 */ + H5O_FILL_VERSION_2, /* H5F_LIBVER_V18 */ H5O_FILL_VERSION_LATEST /* H5F_LIBVER_LATEST */ }; @@ -809,8 +809,7 @@ H5O_fill_free(void *fill) * Return: Success: Non-negative * Failure: Negative * - * Programmer: Quincey Koziol - * Friday, March 9, 2007 + * Programmer: Vailin Choi; Dec 2017 * *------------------------------------------------------------------------- */ @@ -827,6 +826,8 @@ H5O_fill_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src, HDassert(cpy_info); HDassert(cpy_info->file_dst); + /* Check to ensure that the version of the message to be copied does not exceed + the message version allowed by the destination file's high bound */ if(fill_src->version > H5O_fill_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "fill value message version out of bounds") @@ -1047,15 +1048,15 @@ done: * * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Tuesday, July 24, 2007 + * Programmer: Vailin Choi; December 2017 * *------------------------------------------------------------------------- */ herr_t H5O_fill_set_version(H5F_t *f, H5O_fill_t *fill) { - herr_t ret_value = SUCCEED; /* Return value */ + unsigned version; /* Message version */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1064,12 +1065,15 @@ H5O_fill_set_version(H5F_t *f, H5O_fill_t *fill) HDassert(fill); /* 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)]); + version = MAX(fill->version, H5O_fill_ver_bounds[H5F_LOW_BOUND(f)]); - /* File bound check */ - if(fill->version > H5O_fill_ver_bounds[H5F_HIGH_BOUND(f)]) + /* Version bounds check */ + if(version > H5O_fill_ver_bounds[H5F_HIGH_BOUND(f)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "Filter pipeline version out of bounds") + /* Set the message version */ + fill->version = version; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_fill_set_version() */ diff --git a/src/H5Oint.c b/src/H5Oint.c index 0df7467..08eb28d 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -216,18 +216,17 @@ H5O__init_package(void) * 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 - * Jul 17 2007 + * Programmer: Vailin Choi; December 2017 * *------------------------------------------------------------------------- */ static herr_t H5O_set_version(H5F_t *f, H5O_t *oh, uint8_t oh_flags, hbool_t store_msg_crt_idx) { + uint8_t version; /* Message version */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -238,17 +237,20 @@ H5O_set_version(H5F_t *f, H5O_t *oh, uint8_t oh_flags, hbool_t store_msg_crt_idx /* 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; + version = H5O_VERSION_LATEST; else - oh->version = H5O_VERSION_1; + 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)]); + version = MAX(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)]) + /* Version bounds check */ + if(version > H5O_obj_ver_bounds[H5F_HIGH_BOUND(f)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "object header version out of bounds") + /* Set the message version */ + oh->version = version; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_set_version() */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 3745f6d..85d7791 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -1055,8 +1055,7 @@ done: * Return: Success: Non-negative * Failure: Negative * - * Programmer: Quincey Koziol - * Friday, March 9, 2007 + * Programmer: Vailin Choi; Dec 2017 * *------------------------------------------------------------------------- */ @@ -1073,6 +1072,8 @@ H5O__layout_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src, HDassert(cpy_info); HDassert(cpy_info->file_dst); + /* Check to ensure that the version of the message to be copied does not exceed + the message version allowed by the destination file's high bound */ if(layout_src->version > H5O_layout_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "layout message version out of bounds") diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 13e0e3e..498938a 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -63,8 +63,8 @@ ) #define H5O_ALIGN_OH(O, X) \ H5O_ALIGN_VERS((O)->version, X) -#define H5O_ALIGN_F(F, X) \ - H5O_ALIGN_VERS(((H5F_LOW_BOUND(F) >= H5F_LIBVER_V18) ? H5O_VERSION_LATEST : H5O_VERSION_1), X) +#define H5O_ALIGN_F(F, X) \ + H5O_ALIGN_VERS(MAX(H5O_VERSION_1, (uint8_t)H5O_obj_ver_bounds[H5F_LOW_BOUND(F)]), 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_LOW_BOUND(F) >= H5F_LIBVER_V18) || H5F_STORE_MSG_CRT_IDX(F)) ? H5O_VERSION_LATEST : H5O_VERSION_1, (C)) + H5O_SIZEOF_MSGHDR_VERS(MAX((H5F_STORE_MSG_CRT_IDX(F) ? H5O_VERSION_LATEST : H5O_VERSION_1), (uint8_t)H5O_obj_ver_bounds[H5F_LOW_BOUND(F)]), (C)) /* * Size of chunk "header" for each chunk @@ -641,6 +641,8 @@ H5_DLL herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg H5_DLL herr_t H5O_attr_count_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hsize_t *nattrs); +/* Arrays of versions for: + Object header, Layout/Attribute/Datatype/Fill value/Filter pipeline/Dataspace messages */ H5_DLLVAR const unsigned H5O_obj_ver_bounds[H5F_LIBVER_NBOUNDS]; H5_DLLVAR const unsigned H5O_layout_ver_bounds[H5F_LIBVER_NBOUNDS]; H5_DLLVAR const unsigned H5O_attr_ver_bounds[H5F_LIBVER_NBOUNDS]; diff --git a/src/H5Opline.c b/src/H5Opline.c index ea913da..e817f9a 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -576,7 +576,7 @@ H5O_pline_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src, { const H5O_pline_t *pline_src = (const H5O_pline_t *)mesg_src; /* Source pline */ H5O_copy_file_ud_common_t *udata = (H5O_copy_file_ud_common_t *)_udata; /* Object copying user data */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -585,6 +585,8 @@ H5O_pline_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src, HDassert(cpy_info); HDassert(cpy_info->file_dst); + /* Check to ensure that the version of the message to be copied does not exceed + the message version allowed by the destination file's high bound */ if(pline_src->version > H5O_pline_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "pline message version out of bounds") @@ -681,15 +683,15 @@ H5O_pline_debug(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, const voi * * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Tuesday, July 24, 2007 + * Programmer: Vailin Choi; December 2017 * *------------------------------------------------------------------------- */ herr_t H5O_pline_set_version(H5F_t *f, H5O_pline_t *pline) { - herr_t ret_value = SUCCEED; /* Return value */ + unsigned version; /* Message version */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -698,12 +700,15 @@ H5O_pline_set_version(H5F_t *f, H5O_pline_t *pline) HDassert(pline); /* 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)]); + version = MAX(pline->version, H5O_pline_ver_bounds[H5F_LOW_BOUND(f)]); - /* File bound check */ - if(pline->version > H5O_pline_ver_bounds[H5F_HIGH_BOUND(f)]) + /* Version bounds check */ + if(version > H5O_pline_ver_bounds[H5F_HIGH_BOUND(f)]) HGOTO_ERROR(H5E_PLINE, H5E_BADRANGE, FAIL, "Filter pipeline version out of bounds") + /* Set the message version */ + pline->version = version; + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_pline_set_version() */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 5cf9dce..2253bb2 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -178,7 +178,11 @@ typedef struct H5O_copy_t { hbool_t dst_dt_list_complete; /* Whether the destination datatype list is complete (i.e. not only populated with "suggestions" from H5Padd_merge_committed_dtype_path) */ H5O_t *oh_dst; /* The destination object header */ H5F_t *file_dst; /* The destination file pointer */ - void *shared_fo; /* The shared pointer for the object */ + /* This is used in the pre_copy_file callback to obtain + the destination file's high bound. The high bound + is used to index into the corresponding message's + array of versions for doing version bounds check. */ + void *shared_fo; /* The shared pointer for the src object */ H5O_mcdt_search_cb_t mcdt_cb; /* The callback to invoke before searching the global list of committed datatypes at destination */ void *mcdt_ud; /* User data passed to callback */ } H5O_copy_t; diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index 9a9d020..12a9bb6 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -455,6 +455,8 @@ H5O_sdspace_pre_copy_file(H5F_t H5_ATTR_UNUSED *file_src, const void *mesg_src, HDassert(cpy_info); HDassert(cpy_info->file_dst); + /* Check to ensure that the version of the message to be copied does not exceed + the message version allowed by the destination file's high bound */ if(src_space_extent->version > H5O_sdspace_ver_bounds[H5F_HIGH_BOUND(cpy_info->file_dst)]) HGOTO_ERROR(H5E_OHDR, H5E_BADRANGE, FAIL, "dataspace message version out of bounds") diff --git a/src/H5S.c b/src/H5S.c index 8046357..8f3e132 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -2180,15 +2180,15 @@ H5S_extent_nelem(const H5S_extent_t *ext) * * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Tuesday, July 24, 2007 + * Programmer: Vailin Choi; December 2017 * *------------------------------------------------------------------------- */ herr_t H5S_set_version(H5F_t *f, H5S_t *ds) { - herr_t ret_value = SUCCEED; /* Return value */ + unsigned version; /* Message version */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -2197,12 +2197,15 @@ H5S_set_version(H5F_t *f, H5S_t *ds) HDassert(ds); /* 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)]); + 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)]) + /* Version bounds check */ + if(version > H5O_sdspace_ver_bounds[H5F_HIGH_BOUND(f)]) HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "Dataspace version out of bounds") + /* Set the message version */ + ds->extent.version = version; + done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5T.c b/src/H5T.c index aa61358..eca0132 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -5418,8 +5418,7 @@ done: * * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol - * Thursday, July 19, 2007 + * Programmer: Vailin Choi; December 2017 * *------------------------------------------------------------------------- */ @@ -5442,7 +5441,7 @@ H5T_set_version(H5F_t *f, H5T_t *dt) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade datatype encoding") } - /* File bound check */ + /* Version bounds 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") diff --git a/src/H5trace.c b/src/H5trace.c index 5f8ccd1..b1f05ba 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -1021,7 +1021,8 @@ H5_trace(const double *returning, const char *func, const char *type, ...) fprintf(out, "H5F_LIBVER_V18"); break; - case H5F_LIBVER_LATEST: + case H5F_LIBVER_V110: + HDassert(H5F_LIBVER_LATEST == H5F_LIBVER_V110); fprintf(out, "H5F_LIBVER_LATEST"); break; diff --git a/test/genall5.c b/test/genall5.c index 0ac1515..e3a9c96 100644 --- a/test/genall5.c +++ b/test/genall5.c @@ -1264,7 +1264,7 @@ os_grp_0(hid_t fid, const char *group_name) HDassert(fapl > 0); } - if ( pass ) { /* get libver_bounds from fapl */ + if ( pass ) { /* get low and high bounds from fapl */ ret = H5Pget_libver_bounds(fapl, &low, &high); if ( ret < 0 ) { @@ -1312,7 +1312,7 @@ os_grp_0(hid_t fid, const char *group_name) HDassert(ret >= 0); } - if ( pass ) { /* restore libver_bounds */ + if ( pass ) { /* restore low and high bounds */ if(low >= H5F_LIBVER_V18) { ret = H5Fset_libver_bounds(fid, low, high); @@ -1504,7 +1504,7 @@ os_grp_n(hid_t fid, const char *group_name, int proc_num, unsigned nlinks) HDassert(fapl > 0); } - if ( pass ) { /* get libver_bounds from fapl */ + if ( pass ) { /* get low and high bounds from fapl */ ret = H5Pget_libver_bounds(fapl, &low, &high); if ( ret < 0 ) { @@ -1590,7 +1590,7 @@ os_grp_n(hid_t fid, const char *group_name, int proc_num, unsigned nlinks) assert(ret >= 0); } - if ( pass ) { /* restore libver_bounds */ + if ( pass ) { /* restore low and high bounds */ if(low >= H5F_LIBVER_V18) { ret = H5Fset_libver_bounds(fid, low, high); diff --git a/test/mf.c b/test/mf.c index 289f04a..35dfab3 100644 --- a/test/mf.c +++ b/test/mf.c @@ -6920,6 +6920,7 @@ test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, hbool_t new_format) H5FD_mem_t type; /* File allocation type */ H5FS_stat_t fs_stat; /* Information for free-space manager */ haddr_t addr1, addr2, addr3, addr4; /* File address for H5FD_MEM_SUPER */ + haddr_t addrx; H5FD_mem_t fs_type; hbool_t contig_addr_vfd; hbool_t ran_H5MF_tidy_self_referential_fsm_hack = FALSE; @@ -7054,6 +7055,12 @@ test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, hbool_t new_format) if(H5MF_xfree(f, type, H5AC_ind_read_dxpl_id, addr4, (hsize_t)TBLOCK_SIZE4) < 0) FAIL_STACK_ERROR + if(!new_format) { + /* Need to take up this space so that the free-space manager will go away */ + if(HADDR_UNDEF == (addrx = H5MF_alloc(f, type, H5AC_ind_read_dxpl_id, (hsize_t)103))) + FAIL_STACK_ERROR + } + /* The H5FD_MEM_SUPER free-space manager will go away at H5MF_close() */ if(H5Fclose(file) < 0) FAIL_STACK_ERROR @@ -7065,7 +7072,6 @@ test_mf_fs_gone(const char *env_h5_drvr, hid_t fapl, hbool_t new_format) /* Get a pointer to the internal file object */ if(NULL == (f = (H5F_t *)H5I_object(file))) FAIL_STACK_ERROR - /* Verify that the H5FD_MEM_SUPER free-space manager is not there */ if(H5F_addr_defined(f->shared->fs_addr[fs_type])) TEST_ERROR @@ -8936,9 +8942,7 @@ 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/tfile.c b/test/tfile.c index 653fd12..03a5233 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -44,8 +44,11 @@ #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 H5A_FRIEND /*suppress error about including H5Apkg */ +#include "H5Apkg.h" /* Attributes */ + +#define H5O_FRIEND /*suppress error about including H5Opkg */ +#include "H5Opkg.h" /* Object headers */ #define BAD_USERBLOCK_SIZE1 (hsize_t)1 #define BAD_USERBLOCK_SIZE2 (hsize_t)2 @@ -164,73 +167,19 @@ 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 */ - -/* See HDF5_SUPERBLOCK* versions in H5Fprivate.h */ -#define SUPERBLOCK_VERSION_3 3 - -/* See 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_obj_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 */ -}; - -/* See H5O_LAYOUT* versions in H5Oprivate.h */ -/* The library defines LAYOUT_VERSION_3 as the default--see H5Pdcpl.c */ -#define LAYOUT_VERSION_1 1 -#define LAYOUT_VERSION_3 3 -#define LAYOUT_VERSION_4 4 -#define LAYOUT_VERSION_DEFAULT LAYOUT_VERSION_3 -#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 */ -}; - -/* See 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 */ -}; +/* Local test function declarations for version bounds */ +static void test_libver_bounds_low_high(void); +static void test_libver_bounds_super(hid_t fapl); +static void test_libver_bounds_super_create(hid_t fapl, hid_t fcpl, htri_t is_swmr); +static void test_libver_bounds_super_open(hid_t fapl, hid_t fcpl, htri_t is_swmr); +static void test_libver_bounds_obj(hid_t fapl); +static void test_libver_bounds_dataset(hid_t fapl); +static void test_libver_bounds_dataspace(hid_t fapl); +static void test_libver_bounds_datatype(hid_t fapl); +static void test_libver_bounds_datatype_check(hid_t fapl, hid_t tid); +static void test_libver_bounds_attributes(hid_t fapl); -/* See H5O_FILL* versions in H5Oprivate.h */ -/* FILL_VERSION_2 is the default--see H5Pdcpl.c */ -#define FILL_VERSION_1 1 -#define FILL_VERSION_2 2 -#define FILL_VERSION_3 3 -#define FILL_VERSION_DEFAULT FILL_VERSION_2 -#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 FILE8 "tfile8.h5" /* Test file */ #define DSET_NULL "DSET_NULL" #define DSET "DSET" @@ -238,44 +187,6 @@ const unsigned fill_ver_bounds[] = { #define DSETB "DSETB" #define DSETC "DSETC" -/* See 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 */ -}; - -/* See 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 */ -}; - -/* See 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 *); static void @@ -2259,7 +2170,7 @@ test_file_double_file_dataset_open(hbool_t new_format) /* Create a chunked dataset with fixed array indexing */ sid1 = H5Screate_simple(1, dims, max_dims0); - CHECK(sid1, FAIL, "H5Screate"); + CHECK(sid1, FAIL, "H5Screate_simple"); tid1 = H5Tcopy(H5T_C_S1); CHECK(tid1, FAIL, "H5Tcopy"); ret = H5Tset_size(tid1, H5T_VARIABLE); @@ -2285,7 +2196,7 @@ test_file_double_file_dataset_open(hbool_t new_format) /* Create a chunked dataset with extensible array indexing */ sid1 = H5Screate_simple(1, dims, max_dims1); - CHECK(sid1, FAIL, "H5Screate"); + CHECK(sid1, FAIL, "H5Screate_simple"); tid1 = H5Tcopy(H5T_C_S1); CHECK(tid1, FAIL, "H5Tcopy"); ret = H5Tset_size(tid1, H5T_VARIABLE); @@ -2314,7 +2225,7 @@ test_file_double_file_dataset_open(hbool_t new_format) /* Create a chunked dataset with v2 btree indexing */ sid2 = H5Screate_simple(2, dims2, max_dims2); - CHECK(sid2, FAIL, "H5Screate"); + CHECK(sid2, FAIL, "H5Screate_simple"); dcpl = H5Pcreate(H5P_DATASET_CREATE); CHECK(dcpl, FAIL, "H5Pcreate"); @@ -5008,8 +4919,8 @@ test_libver_bounds_real(H5F_libver_t libver_create, unsigned oh_vers_create, CHECK(group, FAIL, "H5Gcreate"); ret = H5Oget_info(group, &oinfo); - CHECK(ret, FAIL, "H5Oget_info_by_name"); - VERIFY(oinfo.hdr.version, oh_vers_mod, "H5Oget_info_by_name"); + CHECK(ret, FAIL, "H5Oget_info"); + VERIFY(oinfo.hdr.version, oh_vers_mod, "H5Oget_info"); ret = H5Gclose(group); CHECK(ret, FAIL, "H5Gclose"); @@ -5061,252 +4972,472 @@ test_libver_bounds(void) test_libver_bounds_real(H5F_LIBVER_LATEST, 2, H5F_LIBVER_EARLIEST, 2); } /* end test_libver_bounds() */ -/**************************************************************** +/************************************************************************************** ** -** test_libver_bounds_attributes(): -** Verify the attribute versions. +** test_libver_bounds_low_high(): +** Tests to verify that format versions are correct with the following five +** pairs of low/high version bounds set in fapl via H5Pset_libver_bounds(): +** (1) (earliest, v18) +** (2) (earliest, v110) +** (3) (v18, v18) +** (4) (v18, v110) +** (5) (v110, v110) ** -****************************************************************/ +** For each pair of setting in fapl, verify format versions with the following +** six tests: +** (1) test_libver_bounds_super(fapl): superblock versions +** (2) test_libver_bounds_obj(fapl): object header versions +** (3) test_libver_bounds_dataset(fapl): message versions associated with dataset +** (4) test_libver_bounds_dataspace(fapl): dataspace message versions +** (5) test_libver_bounds_datatype(fapl): datatype message versions +** (6) test_libver_bounds_attributes(fapl): attribute message versions +** +**************************************************************************************/ static void -test_libver_bounds_attributes(hid_t fapl) +test_libver_bounds_low_high(void) { - 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"); + hid_t fapl = -1; /* File access property list */ + H5F_libver_t low, high; /* Low and high bounds */ + herr_t ret; /* The return value */ - /* 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"); + /* Output message about test being performed */ + MESSAGE(5, ("Testing setting (low, high) format version bounds\n")); - /* Create an attribute to the group with the committed datatype */ - aid = H5Acreate2(gid, "attr1", tid, sid, H5P_DEFAULT, H5P_DEFAULT); - CHECK(aid, FAIL, "H5Acreate2"); + /* Create a file access property list */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); - /* Get the internal attribute pointer */ - attr = (H5A_t *)H5I_object(aid); - CHECK(attr, NULL, "H5I_object"); + /* Loop through all the combinations of low/high version bounds */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { + + H5E_BEGIN_TRY { + /* Set the low/high version bounds */ + ret = H5Pset_libver_bounds(fapl, low, high); + } H5E_END_TRY; - /* 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], "attr_ver_bounds"); + /* Should fail: invalid combinations */ + if(high == H5F_LIBVER_EARLIEST) { + VERIFY(ret, FAIL, "H5Pset_libver_bounds"); + continue; + } - /* Close the attribute */ - ret = H5Aclose(aid); - CHECK(ret, FAIL, "H5Aclose"); + /* Should fail: invalid combinations */ + if(high < low) { + VERIFY(ret, FAIL, "H5Pset_libver_bounds"); + continue; + } - /* 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"); + /* All other combinations are valid and should succeed */ + VERIFY(ret, SUCCEED, "H5Pset_libver_bounds"); - /* Get the internal attribute pointer */ - attr = (H5A_t *)H5I_object(aid); - CHECK(attr, NULL, "H5I_object"); + /* Tests to verify version bounds */ + 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); + } - /* Verify attribute version */ - VERIFY(attr->shared->version, attr_ver_bounds[low], "attr_ver_bounds"); + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); - /* Close the attribute */ - ret = H5Aclose(aid); - CHECK(ret, FAIL, "H5Aclose"); +} /* end test_libver_bounds_low_high() */ - /* 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"); +/*********************************************************************** +** +** test_libver_bounds_super(): +** Verify superblock version with the following two tests: +** (1) test_libver_bounds_super_create(): +** --when creating a file with the input fapl and the fcpl +** that has the following feature enabled: +** (A) default fcpl +** (B) fcpl with v1-btee K value enabled +** (C) fcpl with shared messages enabled +** (D) fcpl with persistent free-space manager enabled +** +** (2) test_libver_bounds_super_open(): +** --when opening a file which is created with the input fapl +** and the fcpl setting as #A to #D above. +** +** These two tests are run with or without SWMR file access. +** +*************************************************************************/ +static void +test_libver_bounds_super(hid_t fapl) +{ + hid_t fcpl = -1; /* File creation property list */ + herr_t ret; /* The return value */ - /* Get internal attribute pointer */ - attr = (H5A_t *)H5I_object(aid); - CHECK(attr, NULL, "H5I_object"); + /* Create a default fcpl: #A */ + /* This will result in superblock version 0 */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); - /* 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], "attr_ver_bounds"); + /* Verify superblock version when creating a file with input fapl, + fcpl #A and with/without SWMR access */ + test_libver_bounds_super_create(fapl, fcpl, TRUE); + test_libver_bounds_super_create(fapl, fcpl, FALSE); - /* Close the attribute */ - ret = H5Aclose(aid); - CHECK(ret, FAIL, "H5Aclose"); + /* Verify superblock version when opening a file which is created + with input fapl, fcpl #A and with/without SWMR access */ + test_libver_bounds_super_open(fapl, fcpl, TRUE); + test_libver_bounds_super_open(fapl, fcpl, FALSE); - /* Close the attribute creation property list */ - ret = H5Pclose(attr_cpl); + /* Close the fcpl */ + ret = H5Pclose(fcpl); CHECK(ret, FAIL, "H5Pclose"); - /* Close the group */ - ret = H5Gclose(gid); - CHECK(ret, FAIL, "H5Gclose"); + /* Create a fcpl with v1-btree K value enabled: #B */ + /* This will result in superblock version 1 */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + ret = H5Pset_istore_k(fcpl, 64); + CHECK(ret, FAIL, "H5Pset_istore_k"); - /* Close the dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); + /* Verify superblock version when creating a file with input fapl, + fcpl #B and with/without SWMR access */ + test_libver_bounds_super_create(fapl, fcpl, TRUE); + test_libver_bounds_super_create(fapl, fcpl, FALSE); - /* Close the datatype */ - ret = H5Tclose(tid); - CHECK(ret, FAIL, "H5Tclose"); + /* Verify superblock version when opening a file which is created + with input fapl, fcpl #B and with/without SWMR access */ + test_libver_bounds_super_open(fapl, fcpl, TRUE); + test_libver_bounds_super_open(fapl, fcpl, FALSE); - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); + /* Close the fcpl */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); - /* Create a copy of the file creation property list */ + /* Create a fcpl with shared messages enabled: #C */ + /* This will result in superblock version 2 */ 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); + ret = H5Pset_shared_mesg_index(fcpl, 0, H5O_SHMESG_ATTR_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"); + /* Verify superblock version when creating a file with input fapl, + fcpl #C and with/without SWMR access */ + test_libver_bounds_super_create(fapl, fcpl, TRUE); + test_libver_bounds_super_create(fapl, fcpl, FALSE); - /* Create dataspace */ - sid = H5Screate(H5S_SCALAR); - CHECK(sid, FAIL, "H5Screate"); + /* Verify superblock version when opening a file which is created + with input fapl, fcpl #C and with/without SWMR access */ + test_libver_bounds_super_open(fapl, fcpl, TRUE); + test_libver_bounds_super_open(fapl, fcpl, FALSE); - /* Create a group */ - gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(gid, FAIL, "H5Gcreate2"); + /* Close the fcpl */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); - /* Create an attribute to the group with integer datatype */ - aid = H5Acreate2(gid, ATTR_NAME, tid, sid, H5P_DEFAULT, H5P_DEFAULT); - CHECK(aid, FAIL, "H5Acreate2"); + /* Create a fcpl with persistent free-space manager enabled: #D */ + /* This will result in superblock version 2 */ + 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"); - /* Get the internal attribute pointer */ - attr = (H5A_t *)H5I_object(aid); - CHECK(attr, NULL, "H5I_object"); + /* Verify superblock version when creating a file with input fapl, + fcpl #D and with/without SWMR access */ + test_libver_bounds_super_create(fapl, fcpl, TRUE); + test_libver_bounds_super_create(fapl, fcpl, FALSE); - /* 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], "attr_ver_bounds"); + /* Verify superblock version when opening a file which is created + with input fapl, fcpl #D and with/without SWMR access */ + test_libver_bounds_super_open(fapl, fcpl, TRUE); + test_libver_bounds_super_open(fapl, fcpl, FALSE); - /* Close the attribute */ - ret = H5Aclose(aid); - CHECK(ret, FAIL, "H5Aclose"); + /* Close the fcpl */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); - /* Close the group */ - ret = H5Gclose(gid); - CHECK(ret, FAIL, "H5Gclose"); +} /* end test_libver_bounds_super() */ - /* Close the dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); - /* Close the datatype */ - ret = H5Tclose(tid); - CHECK(ret, FAIL, "H5Tclose"); +/************************************************************************************************** +** +** test_libver_bounds_super_create(): +** Verify the following when the file is created with the input fapl, fcpl, and +** with/without SWMR access: +** (a) the superblock version # +** (b) the file's low bound setting +** (c) fail or succeed in creating the file +** +** For file creation, the bounds setting in fapl, the feature enabled in fcpl, +** and with/without SWMR file access will determine the results for #a to #c. +** +** The first row for the following two tables is the 5 pairs of low/high bounds setting +** in the input fapl. The next three rows list the expected results for #a to #c. +** "-->" indicates "upgrade to" +** +** Creating a file with write access +** -------------------------------------------------------------------------------- +** | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) | +** |______________________________________________________________________________| +** Superblock version | vers 0, 1, 2 | vers 0, 1, 2 | vers 2 | vers 2 | vers 3 | +** |------------------------------------------------------------------------------| +** File's low bound | no change | +** |------------------------------------------------------------------------------| +** File creation | succeed | +** |______________________________________________________________________________| +** +** Creating a file with SWMR-write access +** -------------------------------------------------------------------------------- +** | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) | +** |______________________________________________________________________________| +** Superblock version | -- | vers 3 | -- | vers 3 | vers 3 | +** |------------------------------------------------------------------------------| +** File's low bound | -- | ->v110 | -- | ->v110 | no change | +** |------------------------------------------------------------------------------| +** File creation | fail | succeed | fail | succeed | succed | +** |______________________________________________________________________________| +** +******************************************************************************************************/ +static void +test_libver_bounds_super_create(hid_t fapl, hid_t fcpl, htri_t is_swmr) +{ + hid_t fid = -1; /* File ID */ + H5F_t *f = NULL; /* Internal file pointer */ + H5F_libver_t low, high; /* Low and high bounds */ + hbool_t ok; /* The result is ok or not */ + herr_t ret; /* The return value */ - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); + /* 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; - /* Create a copy of the file access property list */ - new_fapl = H5Pcreate(H5P_FILE_ACCESS); - CHECK(new_fapl, FAIL, "H5Pcreate"); + /* Get the internal file pointer if the create succeeds */ + if((ok = fid >= 0)) { + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); + } - /* Create the dataspace */ - sid = H5Screate(H5S_SCALAR); - CHECK(sid, FAIL, "H5Screate"); + /* Retrieve the low/high bounds */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); - /* 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(is_swmr) { /* SWMR is enabled */ - if(ret < 0) /* Invalid low/high combinations */ - continue; + if(high == H5F_LIBVER_LATEST) { /* Should succeed */ + VERIFY(ok, TRUE, "H5Fcreate"); + VERIFY(HDF5_SUPERBLOCK_VERSION_3, f->shared->sblock->super_vers, "HDF5_superblock_ver_bounds"); + VERIFY(H5F_LIBVER_V110, f->shared->low_bound, "HDF5_superblock_ver_bounds"); - /* Open the file */ + } else /* Should fail */ + VERIFY(ok, FALSE, "H5Fcreate"); + + } else { /* Should succeed */ + VERIFY(ok, TRUE, "H5Fcreate"); + VERIFY(low, f->shared->low_bound, "HDF5_superblock_ver_bounds"); + + 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, "HDF5_superblock_ver_bounds"); + break; + + case H5F_LIBVER_V18: + ok = (f->shared->sblock->super_vers == 2); + VERIFY(ok, TRUE, "HDF5_superblock_ver_bounds"); + break; + + case H5F_LIBVER_V110: + ok = (f->shared->sblock->super_vers == 3); + VERIFY(ok, TRUE, "HDF5_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_open(): +** Verify the following when opening a file which is created with the input fapl, fcpl, +** and with/without SWMR access: +** (a) the file's low bound setting +** (b) fail or succeed in opening the file +** +** (1) Create a file with the input fapl, fcpl and with/without SWMR access +** (2) Close the file +** (3) Reopen the file with a new fapl that is set to the 5 pairs of low/high bounds +** in a for loop. For each pair of setting in the new fapl: +** --Verify the expected results for #a and #b above. +** --Close the file. +** +** For file open, the file's superblock version, the low/high bounds setting in fapl, +** and with/without SWMR file access will determine the results for #a and #b. +** +** The first row for the following tables is the 5 pairs of low/high bounds setting +** in the input fapl. The next two rows list the expected results for #a and #b. +** "-->" indicates "upgrade to" +** +** Opening a file with write access +** +** Superblock version 0, 1 +** -------------------------------------------------------------------------------- +** | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) | +** |______________________________________________________________________________| +** File's low bound | no change | +** |------------------------------------------------------------------------------| +** File open | succeed | +** |______________________________________________________________________________| +** +** +** Superblock version 2 +** -------------------------------------------------------------------------------- +** | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) | +** |______________________________________________________________________________| +** File's low bound | -->v18 | no change | +** |------------------------------------------------------------------------------| +** File open | succeed | +** |______________________________________________________________________________| +** +** Superblock version 3 +** -------------------------------------------------------------------------------- +** | (earliest, v18) | (earliest, v110) | (v18, v18) | (v18, v110) | (v110, v110) | +** |______________________________________________________________________________| +** File's low bound | -- | -->v110 | -- | -->v110 | no change | +** |------------------------------------------------------------------------------| +** File open | fail | succeed | fail | succeed | succeed | +** |______________________________________________________________________________| +** +** +** +** Opening a file with SWMR-write access +** +** Superblock version 0, 1, 2 +** ------------------------------------------------------------------------------- +** | (earliest, v18) | (earliest, v10) | (v18, v18) | (v18, v110) | (v110, v110) | +** |_____________________________________________________________________________| +** File's low bound | ---- +** |-----------------------------------------------------------------------------| +** File open | fail +** |_____________________________________________________________________________| +** +** +** Superblock version 3 +** ------------------------------------------------------------------------------- +** | (earliest, v18) | (earliest, v10) | (v18, v18) | (v18, v110) | (v110, v110) | +** |_____________________________________________________________________________| +** File's low bound | -- | -->v110 | -- | -->v110 | no change | +** |-----------------------------------------------------------------------------| +** File open | fail | succeed | fail | succeed | succeed | +** |_____________________________________________________________________________| +** +** +******************************************************************************************************/ +static void +test_libver_bounds_super_open(hid_t fapl, hid_t fcpl, htri_t is_swmr) +{ + hid_t fid = -1; /* File ID */ + H5F_t *f = NULL; /* Internal file pointer */ + hid_t new_fapl = -1; /* File access property list */ + unsigned super_vers; /* Superblock version */ + H5F_libver_t low, high; /* Low and high bounds */ + hbool_t ok; /* The result is ok or not */ + herr_t ret; /* Return value */ + + /* Create the file with the input fcpl and fapl */ + 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 default file access property list */ + new_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(new_fapl, FAIL, "H5Pcreate"); + + /* Loop through all the combinations of low/high bounds in new_fapl */ + for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) { + for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { H5E_BEGIN_TRY { - fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); + ret = H5Pset_libver_bounds(new_fapl, low, high); } 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"); + /* Invalid combinations */ + if (ret < 0) + continue; - /* Open the group */ - gid = H5Gopen2(fid, GRP_NAME, H5P_DEFAULT); - CHECK(gid, FAIL, "H5Dcreate2"); + /* Open the file with or without SWMR access */ + H5E_BEGIN_TRY { + fid = H5Fopen(FILE8, H5F_ACC_RDWR | (is_swmr ? H5F_ACC_SWMR_WRITE : 0), new_fapl); + } H5E_END_TRY; + ok = fid >= 0; - /* Create an attribute to the group */ - aid = H5Acreate2(gid, "attr1", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT); - CHECK(aid, FAIL, "H5Acreate2"); + /* 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, "HDF5_superblock_ver_bounds"); - /* Get the internal attribute pointer */ - attr = (H5A_t *)H5I_object(aid); - CHECK(attr, NULL, "H5I_object"); + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } else /* Should fail */ + VERIFY(ok, FALSE, "H5Fopen"); + break; - VERIFY(attr->shared->version, attr_ver_bounds[f->shared->low_bound], "attr_ver_bounds"); + case 2: + if(is_swmr) /* Should fail */ + VERIFY(ok, FALSE, "H5Fopen"); + else { /* Should succeed */ + VERIFY(ok, TRUE, "H5Fopen"); - /* Close the attribute */ - ret = H5Aclose(aid); - CHECK(ret, FAIL, "H5Aclose"); + ok = f->shared->low_bound >= H5F_LIBVER_V18; + VERIFY(ok, TRUE, "HDF5_superblock_ver_bounds"); - /* Delete the attribute */ - ret = H5Adelete(gid, "attr1"); - CHECK(ret, FAIL, "H5Ldelete"); + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } + break; - /* Close the group */ - ret = H5Gclose(gid); - CHECK(ret, FAIL, "H5Gclose"); + 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, "HDF5_superblock_ver_bounds"); - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + } + break; - } /* end if */ + default: + break; + } /* end switch */ } /* end for */ } /* end for */ @@ -5314,126 +5445,111 @@ test_libver_bounds_attributes(hid_t fapl) ret = H5Pclose(new_fapl); CHECK(ret, FAIL, "H5Pclose"); - /* Close the dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); - -} /* end test_libver_bounds_attributes() */ +} /* end test_libver_bounds_super_open() */ /**************************************************************** ** -** test_libver_bounds_datatype(): -** Verify the datatype message versions for parameter "tid". +** test_libver_bounds_obj(): +** Verify object header versions: +** +** (a) Create a file with: +** --the input fapl +** --a fcpl that has shared message enabled +** Verify the root group's object header version. +** Close the file. +** +** (b) Create another file with: +** --the input fapl +** --a default fcpl +** Verify the root group's object header version. +** Close the file. +** +** (c) Reopen the same file in (b) with a new fapl. +** The new fapl is set to the 5 pairs of low/high +** bounds in a "for" loop. For each setting in fapl: +** --Create a group in the file +** --Verify the group's object header version +** --Close and delete the group +** --Close the file ** ****************************************************************/ static void -test_libver_bounds_datatype_check(hid_t fapl, hid_t tid) +test_libver_bounds_obj(hid_t fapl) { - 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 */ + hid_t fid = -1; /* File ID */ + hid_t gid = -1; /* Group ID */ + hid_t fcpl = -1; /* File creation property list */ + hid_t new_fapl = -1; /* File access property list */ + H5F_t *f = NULL; /* Internal file pointer */ + H5F_libver_t low, high; /* Low and high bounds */ + H5O_info_t oinfo; /* Object info */ + H5G_info_t ginfo; /* Group info */ + herr_t ret; /* Return value */ + + /* Retrieve the low/high bounds from the input fapl */ 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 a default file creation property list */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); - /* Create dataspace */ - sid = H5Screate_simple(1, dims, NULL); - CHECK(sid, FAIL, "H5Screate"); + /* Enable shared message in the fcpl */ + /* This will result in a version 2 object header */ + 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 a dataset */ - did = H5Dcreate2(fid, DSET1, tid, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(did, FAIL, "H5Dcreate2"); + /* Create the file with the fcpl and the input fapl */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); - /* Get the dataset's datatype */ - dtid = H5Dget_type(did); - CHECK(dtid, FAIL, "H5Dget_type"); + /* Get root group's object info */ + ret = H5Oget_info_by_name(fid, "/", &oinfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name"); - /* Get the internal datatype pointer */ - dtype = (H5T_t *)H5I_object(dtid); - CHECK(dtype, NULL, "H5I_object"); + /* Verify object header version is 2 because shared message is enabled */ + VERIFY(oinfo.hdr.version, H5O_VERSION_2, "H5O_obj_ver_bounds"); - /* 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 */ + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); - 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 file creation property list */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); - /* Close the dataset */ - ret = H5Dclose(did); - CHECK(ret, FAIL, "H5Dclose"); + /* Create a file with the default fcpl and input fapl */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid, FAIL, "H5Fcreate"); - /* Close the dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Dclose"); + /* Get root group's object info */ + ret = H5Oget_info_by_name(fid, "/", &oinfo, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Oget_info_by_name"); - /* Close the datatype */ - ret = H5Tclose(dtid); - CHECK(ret, FAIL, "H5Fclose"); + /* Verify object header version is as indicated by low_bound */ + VERIFY(oinfo.hdr.version, H5O_obj_ver_bounds[low], "H5O_obj_ver_bounds"); /* Close the file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); - /* Create a copy of file access property list */ + /* Create a new default file access property list which + is used to open the file in the "for" loop */ 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 */ + /* Loop through all the combinations of low/high bounds in new_fapl */ + /* Open the file with the fapl; create a group and verify the + object header version, then delete the group and close the file.*/ 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 */ + if (ret < 0) /* Invalid combinations */ continue; /* Open the file */ @@ -5441,59 +5557,41 @@ test_libver_bounds_datatype_check(hid_t fapl, hid_t tid) fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); } H5E_END_TRY; - if(fid >= 0 ) { /* The file open succeeds */ + 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"); + /* Create a group in the file */ + gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); - VERIFY(str_dtype->shared->version, dtype_ver_bounds[H5F_LIBVER_EARLIEST], "dtype_ver_bounds"); + /* Get group information */ + ret = H5Gget_info(gid, &ginfo); + CHECK(ret, FAIL, "H5Gget_info"); - ret = H5Tclose(str_tid); - CHECK(ret, FAIL, "H5Tclose"); + /* Verify group storage type */ + if(f->shared->low_bound >= H5F_LIBVER_V18) + /* Links in group are stored in object header */ + VERIFY(ginfo.storage_type, H5G_STORAGE_TYPE_COMPACT, "H5Gget_info"); + else + /* Links in group are stored with a "symbol table" */ + 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_by_name"); - /* Create the chunked dataset */ - did = H5Dcreate2(fid, DSETNAME, tid, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); - CHECK(did, FAIL, "H5Dcreate2"); + /* Verify object header version as indicated by low_bound */ + VERIFY(oinfo.hdr.version, H5O_obj_ver_bounds[f->shared->low_bound], "H5O_obj_ver_bounds"); - /* 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"); + /* Close the group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); - /* Delete the dataset */ - ret = H5Ldelete(fid, DSETNAME, H5P_DEFAULT); + /* Delete the group */ + ret = H5Ldelete(fid, GRP_NAME, H5P_DEFAULT); CHECK(ret, FAIL, "H5Ldelete"); /* Close the file */ @@ -5508,118 +5606,282 @@ test_libver_bounds_datatype_check(hid_t fapl, hid_t tid) ret = H5Pclose(new_fapl); CHECK(ret, FAIL, "H5Pclose"); +} /* end test_libver_bounds_obj() */ + +/**************************************************************** +** +** test_libver_bounds_dataset(): +** Verify message versions associated with datasets: +** +** (a) Create a file with default fcpl and the input fapl. +** Create the following two datasets: +** --A contiguous dataset +** --A chunked dataset with "no filter edge chunks" +** For both datasets, verify the versions for the layout, +** fill value and filter pipeline messages. +** Close the file. +** +** (b) Create a new fapl that is set to the 5 pairs of low/high +** bounds in a "for" loop. For each pair of setting in the +** new fapl: +** --Open the same file in (a) with the fapl +** --Create a chunked dataset with 2 unlimited +** dimensions +** --Verify the versions for the layout, fill value +** and filter pipeline messages +** --Close and delete the dataset +** --Close the file +** +****************************************************************/ +static void +test_libver_bounds_dataset(hid_t fapl) +{ + hid_t fid = -1; /* File ID */ + hid_t new_fapl = -1; /* File access property list */ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* Dataset creation property list */ + H5D_t *dset = NULL; /* Internal dataset pointer */ + H5F_t *f = NULL; /* Internal file pointer */ + H5F_libver_t low, high; /* Low and high 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 low/high bounds from the input fapl */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); + + /* Create the file with the input fapl */ + 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 dataset pointer */ + dset = (H5D_t *)H5I_object(did); + CHECK(dset, NULL, "H5I_object"); + + /* Verify version for layout and fill value messages */ + if(low == H5F_LIBVER_EARLIEST) { + /* For layout message: the earliest version the library will set is 3 */ + /* For fill value message: the earliest version the library will set is 2 */ + VERIFY(dset->shared->layout.version, H5O_LAYOUT_VERSION_DEFAULT, "H5O_layout_ver_bounds"); + VERIFY(dset->shared->dcpl_cache.fill.version, H5O_FILL_VERSION_2, "H5O_fill_ver_bounds"); + } else { + VERIFY(dset->shared->layout.version, H5O_layout_ver_bounds[low], "H5O_layout_ver_bounds"); + VERIFY(dset->shared->dcpl_cache.fill.version, H5O_fill_ver_bounds[low], "H5O_fill_ver_bounds"); + } + + /* Verify filter pipleline message version */ + VERIFY(dset->shared->dcpl_cache.pline.version, H5O_pline_ver_bounds[low], "H5O_pline_ver_bounds"); + + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + /* Close the dataspace */ ret = H5Sclose(sid); CHECK(ret, FAIL, "H5Sclose"); - /* Close the dataset creation property list */ + /* Set up dataspace and dcpl for creating a chunked dataset + with "no filter edge chunks" enabled. + This will result in a version 4 layout message */ + sid = H5Screate_simple(2, fix_dims2, NULL); + CHECK(sid, FAIL, "H5Screate_simple"); + 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_opts"); + + /* Create the chunked dataset */ + 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 layout message version and chunk indexing type */ + VERIFY(dset->shared->layout.version, H5O_LAYOUT_VERSION_4, "H5O_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"); -} /* end test_libver_bounds_datatype_check() */ + /* Create a default file access property list which is used + to open the file in the 'for' loop */ + new_fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(new_fapl, FAIL, "H5Pcreate"); -/**************************************************************** -** -** 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 */ + /* Set up dataspace and dcpl for creating a chunked dataset with + 2 unlimited dimensions in the 'for' loop */ + sid = H5Screate_simple(2, dims2, max_dims2); + CHECK(sid, FAIL, "H5Screate_simple"); + dcpl = H5Pcreate(H5P_DATASET_CREATE); + CHECK(dcpl, FAIL, "H5Pcreate"); + ret = H5Pset_chunk(dcpl, 2, chunks2); + CHECK(ret, FAIL, "H5Pset_chunk"); - /* Create integer datatype */ - tid = H5Tcopy(H5T_NATIVE_INT); + /* Loop through all the combinations of low/high bounds in new_fapl */ + /* Open the file with the fapl and create the chunked dataset */ + /* Verify the dataset's layout, fill value and filter pipleline message 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; - /* Verify datatype versions */ - test_libver_bounds_datatype_check(fapl, tid); + if (ret < 0) /* Invalid low/high combinations */ + continue; - /* 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); + /* Open the file */ + H5E_BEGIN_TRY { + fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); + } H5E_END_TRY; - /* Verify datatype versions */ - test_libver_bounds_datatype_check(fapl, tid_enum); + if(fid >=0 ) { /* The file open succeeds */ - /* Create array datatype */ - tid_array = H5Tarray_create2(tid, 1, dims); + /* Get the internal file pointer */ + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); - /* Verify datatype versions */ - test_libver_bounds_datatype_check(fapl, tid_array); + /* Create the chunked dataset */ + did = H5Dcreate2(fid, DSETC, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate2"); - /* 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); + /* Get the internal file pointer */ + dset = (H5D_t *)H5I_object(did); + CHECK(dset, NULL, "H5I_object"); - /* Verify datatype versions */ - test_libver_bounds_datatype_check(fapl, tid_compound); + /* Verify the dataset's layout, fill value and filter pipeline message versions */ + /* Also verify the chunk indexing type */ + if(f->shared->low_bound == H5F_LIBVER_EARLIEST) { + /* For layout message: the earliest version the library will set is 3 */ + /* For fill value message: the earliest version the library will set is 2 */ + VERIFY(dset->shared->layout.version, H5O_LAYOUT_VERSION_DEFAULT, "H5O_layout_ver_bounds"); + VERIFY(dset->shared->dcpl_cache.fill.version, H5O_FILL_VERSION_2, "H5O_fill_ver_bounds"); + } else { + VERIFY(dset->shared->layout.version, H5O_layout_ver_bounds[f->shared->low_bound], "H5O_layout_ver_bounds"); + VERIFY(dset->shared->dcpl_cache.fill.version, H5O_fill_ver_bounds[f->shared->low_bound], "H5O_fill_ver_bounds"); + } - /* Create vlen datatype */ - tid_vlen = H5Tvlen_create(tid); + /* Verify the filter pipeline message version */ + VERIFY(dset->shared->dcpl_cache.pline.version, H5O_pline_ver_bounds[f->shared->low_bound], "H5O_pline_ver_bounds"); - /* Verify datatype versions */ - test_libver_bounds_datatype_check(fapl, tid_vlen); + /* Verify the dataset's chunk indexing type */ + if(dset->shared->layout.version == H5O_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 datatypes */ - ret = H5Tclose(tid); - CHECK(ret, FAIL, "H5Tclose"); + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); - ret = H5Tclose(tid_enum); - CHECK(ret, FAIL, "H5Tclose"); + /* Delete the dataset */ + ret = H5Ldelete(fid, DSETC, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Ldelete"); - ret = H5Tclose(tid_array); - CHECK(ret, FAIL, "H5Tclose"); + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); - ret = H5Tclose(tid_compound); - CHECK(ret, FAIL, "H5Tclose"); + } /* end if */ + } /* end for */ + } /* end for */ - ret = H5Tclose(tid_vlen); - CHECK(ret, FAIL, "H5Tclose"); + /* Close the file access property list */ + ret = H5Pclose(new_fapl); + CHECK(ret, FAIL, "H5Pclose"); -} /* end test_libver_bounds_datatype() */ + /* 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_dataspace(): -** Verify the dataspace message versions. +** Verify dataspace message versions: +** +** (a) Create a file with default fcpl and the input fapl. +** Create the following two datasets: +** --A dataset with scalar dataspace +** --A dataset with null dataspace +** For both datasets, verify the dataspace message versions. +** Close the file. +** +** (b) Create a new fapl that is set to the 5 pairs of low/high +** bounds in a "for" loop. For each pair of setting in the +** new fapl: +** --Open the same file in (a) with the fapl +** --Create a chunked dataset, a compact dataset and +** a contigous dataset +** --Verify the dataspace message version for these +** three datasets +** --Delete the three datasets and the dataspaces +** --Close the file ** ****************************************************************/ 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; /* 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 */ + hid_t fid = -1; /* File ID */ + hid_t new_fapl = -1; /* File access property list */ + hid_t did = -1, did_null = -1; /* Dataset IDs */ + hid_t did_compact = -1, did_contig = -1; /* Dataset IDs */ + hid_t sid = -1, sid_null = -1; /* Dataspace IDs */ + hid_t sid_compact = -1, sid_contig = -1; /* Dataspace IDs */ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t dcpl_compact = -1, dcpl_contig = -1; /* Dataset creation property lists */ + H5S_t *space = NULL, *space_null = NULL; /* Internal dataspace pointers */ + H5F_t *f = NULL; /* Internal file pointer */ + H5F_libver_t low, high; /* Low and high 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 */ + + /* Retrieve the low/high bounds from the input fapl */ ret = H5Pget_libver_bounds(fapl, &low, &high); CHECK(ret, FAIL, "H5Pget_libver_bounds"); - /* Create the file */ + /* Create the file with the input fapl */ fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); CHECK(fid, FAIL, "H5Fcreate"); @@ -5627,7 +5889,7 @@ test_libver_bounds_dataspace(hid_t fapl) sid = H5Screate(H5S_SCALAR); CHECK(sid, FAIL, "H5Screate"); - /* Create the dataset with scalar dataspace */ + /* Create a dataset with the scalar dataspace */ did = H5Dcreate2(fid, DSET, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(did, FAIL, "H5Dcreate"); @@ -5638,13 +5900,13 @@ test_libver_bounds_dataspace(hid_t fapl) CHECK(space, NULL, "H5I_object"); /* Verify the dataspace version */ - VERIFY(space->extent.version, sdspace_ver_bounds[low], "sdspace_ver_bounds"); + VERIFY(space->extent.version, H5O_sdspace_ver_bounds[low], "H5O_sdspace_ver_bounds"); /* Create null dataspace */ sid_null = H5Screate(H5S_NULL); CHECK(sid_null, FAIL, "H5Screate"); - /* Create the dataset with null dataspace */ + /* Create a dataset with the null dataspace */ did_null = H5Dcreate2(fid, DSET_NULL, H5T_NATIVE_INT, sid_null, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(did_null, FAIL, "H5Dcreate"); @@ -5655,7 +5917,7 @@ test_libver_bounds_dataspace(hid_t fapl) CHECK(space_null, NULL, "H5I_object"); /* Verify the dataspace version */ - VERIFY(space_null->extent.version, SDSPACE_VERSION_2, "sdspace_ver_bounds"); + VERIFY(space_null->extent.version, H5O_SDSPACE_VERSION_2, "H5O_sdspace_ver_bounds"); /* Close the datasets */ ret = H5Dclose(did); @@ -5673,38 +5935,38 @@ test_libver_bounds_dataspace(hid_t fapl) ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); - - /* Create a copy of file access property list */ + /* Create a default file access property list which is used + to open the file in the 'for' loop */ new_fapl = H5Pcreate(H5P_FILE_ACCESS); CHECK(new_fapl, FAIL, "H5Pcreate"); - /* Prepare to create a chunked dataset with 1 unlimited dimension */ + /* Set up dataspace and dcpl for creating a chunked dataset */ sid = H5Screate_simple(1, dims, max_dims); - CHECK(sid, FAIL, "H5Screate"); + CHECK(sid, FAIL, "H5Screate_simple"); 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 */ + /* Set up dataspace and dcpl for creating a compact dataset */ sid_compact = H5Screate_simple(1, dims, NULL); - CHECK(sid_compact, FAIL, "H5Screate"); + CHECK(sid_compact, FAIL, "H5Screate_simple"); 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 */ + /* Set up dataspace and dcpl for creating a contiguous dataset */ sid_contig = H5Screate_simple(2, dims2, NULL); - CHECK(sid_contig, FAIL, "H5Screate"); + CHECK(sid_contig, FAIL, "H5Screate_simple"); 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 */ + /* Loop through all the combinations of low/high bounds in new_fapl */ /* Open the file and create the chunked/compact/contiguous datasets */ - /* Verify the dataspace version for the three datasets */ + /* Verify the dataspace message 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++) { hid_t tmp_sid, tmp_sid_compact, tmp_sid_contig; /* Dataspace IDs */ @@ -5758,9 +6020,10 @@ test_libver_bounds_dataspace(hid_t fapl) tmp_space_contig = (H5S_t *)H5I_object(tmp_sid_contig); CHECK(tmp_space_contig, NULL, "H5I_object"); - VERIFY(tmp_space->extent.version, sdspace_ver_bounds[f->shared->low_bound], "sdspace_ver_bounds"); - VERIFY(tmp_space_compact->extent.version, sdspace_ver_bounds[f->shared->low_bound], "sdspace_ver_bounds"); - VERIFY(tmp_space_contig->extent.version, sdspace_ver_bounds[f->shared->low_bound], "sdspace_ver_bounds"); + /* Verify versions for the three dataspaces */ + VERIFY(tmp_space->extent.version, H5O_sdspace_ver_bounds[f->shared->low_bound], "H5O_sdspace_ver_bounds"); + VERIFY(tmp_space_compact->extent.version, H5O_sdspace_ver_bounds[f->shared->low_bound], "H5O_sdspace_ver_bounds"); + VERIFY(tmp_space_contig->extent.version, H5O_sdspace_ver_bounds[f->shared->low_bound], "H5O_sdspace_ver_bounds"); /* Close the three datasets */ ret = H5Dclose(did); @@ -5770,6 +6033,7 @@ test_libver_bounds_dataspace(hid_t fapl) ret = H5Dclose(did_contig); CHECK(ret, FAIL, "H5Dclose"); + /* Close the three dataspaces */ ret = H5Sclose(tmp_sid); CHECK(ret, FAIL, "H5Sclose"); ret = H5Sclose(tmp_sid_compact); @@ -5815,127 +6079,218 @@ test_libver_bounds_dataspace(hid_t fapl) } /* 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. +** test_libver_bounds_datatype(): +** Verify the datatype message version: +** +** (a) Create the following datatypes: +** 1) integer +** 2) enum +** 3) array +** 4) compound +** 5) vlen +** (b) Call test_libver_bounds_datatype_check() for each +** datatype in (a) to verify the datatype message version. ** ****************************************************************/ static void -test_libver_bounds_dataset(hid_t fapl) +test_libver_bounds_datatype(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 */ + hid_t tid = -1, tid_enum = -1, tid_array = -1; /* Datatype IDs */ + hid_t tid_compound = -1, tid_vlen = -1; /* 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 */ - /* Retrieve the library format bounds */ - ret = H5Pget_libver_bounds(fapl, &low, &high); - CHECK(ret, FAIL, "H5Pget_libver_bounds"); + /* Create integer datatype */ + tid = H5Tcopy(H5T_NATIVE_INT); - /* Create the file */ - fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - CHECK(fid, FAIL, "H5Fcreate"); + /* Verify datatype message version */ + test_libver_bounds_datatype_check(fapl, tid); - /* Create the dataspace */ - sid = H5Screate(H5S_SCALAR); - CHECK(sid, FAIL, "H5Screate"); + /* 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); - /* Create a contiguous dataset */ - did = H5Dcreate2(fid, DSETA, H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - CHECK(did, FAIL, "H5Dcreate"); + /* Verify datatype message version */ + test_libver_bounds_datatype_check(fapl, tid_enum); - /* Get the internal dataset pointer */ - dset = (H5D_t *)H5I_object(did); - CHECK(dset, NULL, "H5I_object"); + /* Create array datatype */ + tid_array = H5Tarray_create2(tid, 1, dims); - /* 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 datatype message version */ + test_libver_bounds_datatype_check(fapl, tid_array); - /* Verify pline message version */ - VERIFY(dset->shared->dcpl_cache.pline.version, pline_ver_bounds[low], "pline_ver_bounds"); + /* 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); - /* Close the dataset */ - ret = H5Dclose(did); - CHECK(ret, FAIL, "H5Dclose"); + /* Verify datatype message version */ + test_libver_bounds_datatype_check(fapl, tid_compound); - /* Close the dataspace */ - ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); + /* Create vlen datatype */ + tid_vlen = H5Tvlen_create(tid); - /* 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_opts"); + /* Verify datatype message version */ + test_libver_bounds_datatype_check(fapl, tid_vlen); - H5E_BEGIN_TRY { - did = H5Dcreate2(fid, DSETB, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); - } H5E_END_TRY; + /* Close the datatypes */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); - if(did >= 0) { + ret = H5Tclose(tid_enum); + CHECK(ret, FAIL, "H5Tclose"); - /* Get the internal dataset pointer */ - dset = (H5D_t *)H5I_object(did); - CHECK(dset, NULL, "H5I_object"); + ret = H5Tclose(tid_array); + CHECK(ret, FAIL, "H5Tclose"); - 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"); + ret = H5Tclose(tid_compound); + CHECK(ret, FAIL, "H5Tclose"); - /* Close the dataset */ - ret = H5Dclose(did); - CHECK(ret, FAIL, "H5Dclose"); - } + ret = H5Tclose(tid_vlen); + CHECK(ret, FAIL, "H5Tclose"); - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); +} /* end test_libver_bounds_datatype() */ + +/**************************************************************** +** +** test_libver_bounds_datatype_check(): +** Helper routine called by test_libver_bounds_datatype() +** to verify the datatype message version for the input tid: +** +** (a) Create a file with default fcpl and the input fapl. +** Create a contiguous dataset with the input tid. +** Verify the datatype message version. +** Create a committed datatype of string to be +** used later. +** Close the file. +** +** (b) Create a new fapl that is set to the 5 pairs of low/high +** bounds in a "for" loop. For each pair of setting in +** the new fapl: +** --Open the same file in (a) with the fapl +** --Verify the message version for the committed +** datatype created earlier +** --Create a chunked dataset with the input tid +** --Verify the datatype message version +** --Close and delete the dataset +** --Close the file +** +****************************************************************/ +static void +test_libver_bounds_datatype_check(hid_t fapl, hid_t tid) +{ + hid_t fid = -1; /* File ID */ + hid_t new_fapl = -1; /* File acess property list */ + hid_t dcpl = -1; /* Dataset creation property list */ + hid_t dtid = -1; /* Datatype ID for the dataset */ + hid_t str_tid = -1; /* String datatype ID */ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* 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 = NULL; /* Internal datatype pointer */ + H5T_t *str_dtype = NULL; /* Internal datatype pointer for the string datatype */ + H5F_t *f = NULL; /* Internal file pointer */ + H5F_libver_t low, high; /* Low and high bounds */ + herr_t ret; /* Return value */ + + /* Retrieve the low/high version bounds from the input fapl */ + ret = H5Pget_libver_bounds(fapl, &low, &high); + CHECK(ret, FAIL, "H5Pget_libver_bounds"); + + /* Create the file with the input fapl */ + fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create a committed datatype of string which will be used + later inside the 'for' loop */ + 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_simple"); + + /* Create a dataset with the input tid */ + 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 message version */ + /* H5T_COMPOUND, H5T_ENUM, H5T_ARRAY: + * --the library will set version according to low_bound + * --H5T_ARRAY: the earliest version the library will set is 2 + * H5T_INTEGER, H5T_FLOAT, H5T_TIME, H5T_STRING, H5T_BITFIELD, H5T_OPAQUE, H5T_REFERENCE: + * --the library will only use basic version + */ + 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, H5O_DTYPE_VERSION_2, "H5O_dtype_ver_bounds"); + else + VERIFY(dtype->shared->version, H5O_dtype_ver_bounds[low], "H5O_dtype_ver_bounds"); + } else + VERIFY(dtype->shared->version, H5O_dtype_ver_bounds[H5F_LIBVER_EARLIEST], "H5O_dtype_ver_bounds"); + + /* Close the dataset */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); /* Close the dataspace */ ret = H5Sclose(sid); - CHECK(ret, FAIL, "H5Sclose"); + CHECK(ret, FAIL, "H5Dclose"); - /* Close the datset creation property list */ - ret = H5Pclose(dcpl); - CHECK(ret, FAIL, "H5Pclose"); + /* 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 */ + /* Create a default 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 */ + /* Set up dataspace and dcpl for creating a chunked dataset */ sid = H5Screate_simple(2, dims2, max_dims2); - CHECK(sid, FAIL, "H5Screate"); + CHECK(sid, FAIL, "H5Screate_simple"); dcpl = H5Pcreate(H5P_DATASET_CREATE); CHECK(dcpl, FAIL, "H5Pcreate"); - ret = H5Pset_chunk(dcpl, 2, chunks2); + 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 layout, fill, pline message versions and chunked indexing type */ + /* Loop through all the combinations of low/high bounds */ + /* Open the file and create the chunked dataset with the input tid */ + /* Verify the dataset's datatype message version */ + /* Also verify the committed atatype message version */ for(low = H5F_LIBVER_EARLIEST; low < H5F_LIBVER_NBOUNDS; low++) { for(high = H5F_LIBVER_EARLIEST; high < H5F_LIBVER_NBOUNDS; high++) { H5E_BEGIN_TRY { @@ -5950,41 +6305,66 @@ test_libver_bounds_dataset(hid_t fapl) fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); } H5E_END_TRY; - if(fid >=0 ) { /* The file open succeeds */ + 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 committed datatype */ + 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 the committed datatype message version */ + VERIFY(str_dtype->shared->version, H5O_dtype_ver_bounds[H5F_LIBVER_EARLIEST], "H5O_dtype_ver_bounds"); + + /* Close the committed datatype */ + ret = H5Tclose(str_tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Create the chunked dataset */ - did = H5Dcreate2(fid, DSETC, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); + did = H5Dcreate2(fid, DSETNAME, tid, 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"); + /* Get the dataset's datatype */ + dtid = H5Dget_type(did); + CHECK(dtid, FAIL, "H5Dget_type"); - /* 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"); - } + /* Get the internal datatype pointer */ + dtype = (H5T_t *)H5I_object(dtid); + CHECK(dtype, NULL, "H5I_object"); - 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"); + /* Verify the dataset's datatype message version */ + /* H5T_COMPOUND, H5T_ENUM, H5T_ARRAY: + * --the library will set version according to low_bound + * --H5T_ARRAY: the earliest version the library will set is 2 + * H5T_INTEGER, H5T_FLOAT, H5T_TIME, H5T_STRING, H5T_BITFIELD, H5T_OPAQUE, H5T_REFERENCE: + * --the library will only use basic version + */ + 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, H5O_DTYPE_VERSION_2, "H5O_dtype_ver_bounds"); + else + VERIFY(dtype->shared->version, H5O_dtype_ver_bounds[f->shared->low_bound], "H5O_dtype_ver_bounds"); + } else + VERIFY(dtype->shared->version, H5O_dtype_ver_bounds[H5F_LIBVER_EARLIEST], "H5O_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, DSETC, H5P_DEFAULT); + ret = H5Ldelete(fid, DSETNAME, H5P_DEFAULT); CHECK(ret, FAIL, "H5Ldelete"); /* Close the file */ @@ -6007,242 +6387,283 @@ test_libver_bounds_dataset(hid_t fapl) ret = H5Pclose(dcpl); CHECK(ret, FAIL, "H5Pclose"); -} /* end test_libver_bounds_dataset() */ +} /* end test_libver_bounds_datatype_check() */ /**************************************************************** ** -** test_libver_bounds_obj(): -** Verify object header version with the low/high library -** format bounds setting in the fapl. +** test_libver_bounds_attributes(): +** Verify the attribute message versions: +** +** (a) Create a file with default fcpl and the input fapl. +** Create a group and attach the following three attributes +** to the group: +** (1) Attribute with a committed datatype +** (2) Attribute with integer type +** (3) Attribute with character encoding set +** Verify the three attributes' message versions. +** Close the file. +** +** (b) Create a fcpl that has shared datatype message enabled. +** Create a file with the fcpl and the input fapl. +** Create a group and attach an attribute with shared +** integer type to the group. +** Verify the attribute message version. +** Close the file +** +** (b) Create a new fapl that is set to the 5 pairs of low/high +** bounds in a "for" loop. For each pair of setting in +** the new fapl: +** --Open the same file in (b) with the fapl +** --Open the group and attach an attribute with integer +** type to the group +** --Verify the attribute message version +** --Delete the attribute +** --Close the group and the file ** ****************************************************************/ static void -test_libver_bounds_obj(hid_t fapl) +test_libver_bounds_attributes(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 */ + hid_t fid = -1; /* File ID */ + hid_t fcpl = -1; /* File creation property list */ + hid_t new_fapl = -1; /* File access property list */ + hid_t tid = -1; /* Datatype ID */ + hid_t gid = -1; /* Group ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t aid = -1; /* Attribute ID */ + hid_t attr_cpl = -1; /* Attribute creation property list */ + H5A_t *attr = NULL; /* Internal attribute pointer */ + H5F_t *f = NULL; /* Internal file pointer */ + H5F_libver_t low, high; /* Low and high bounds */ herr_t ret; /* Return value */ - /* Retrieve the format bounds */ + /* Retrieve the low/high bounds from the input fapl */ 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); + 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"); + /* Integer datatpye */ + tid = H5Tcopy(H5T_NATIVE_INT); + CHECK(tid, FAIL, "H5Tcopy"); - /* Verify object header version is 2 when shared message is enabled */ - VERIFY(oinfo.hdr.version, OBJ_VERSION_2, "H5Oget_info"); + /* Create a committed datatype */ + ret = H5Tcommit2(fid, "datatype", tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Tcommit2"); - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); + /* Create dataspace */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); - /* Close the file creation property list */ - ret = H5Pclose(fcpl); - CHECK(ret, FAIL, "H5Fclose"); + /* Create a group */ + gid = H5Gcreate2(fid, GRP_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gcreate2"); - /* Create a file with default fcpl */ - fid = H5Fcreate(FILE8, H5F_ACC_TRUNC, H5P_DEFAULT, fapl); - CHECK(fid, FAIL, "H5Fcreate"); + /* Attach an attribute to the group with the committed datatype */ + aid = H5Acreate2(gid, "attr1", tid, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); - /* Get root group's object info */ - ret = H5Oget_info_by_name(fid, "/", &oinfo, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info"); + /* Get the internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); - /* Verify object header version */ - VERIFY(oinfo.hdr.version, obj_ver_bounds[low], "obj_ver_bounds"); + /* Verify the attribute version */ + if(low == H5F_LIBVER_EARLIEST) + /* The earliest version the library can set for an attribute with committed datatype is 2 */ + VERIFY(attr->shared->version, H5O_ATTR_VERSION_2, "H5O_attr_ver_bounds"); + else + VERIFY(attr->shared->version, H5O_attr_ver_bounds[low], "H5O_attr_ver_bounds"); - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); - /* Create a copy of file access property list */ - new_fapl = H5Pcreate(H5P_FILE_ACCESS); - CHECK(new_fapl, FAIL, "H5Pcreate"); + /* 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"); - /* 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; + /* Get the internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); - if (ret < 0) /* Invalid combinations */ - continue; + /* Verify attribute version */ + VERIFY(attr->shared->version, H5O_attr_ver_bounds[low], "H5O_attr_ver_bounds"); - /* Open the file */ - H5E_BEGIN_TRY { - fid = H5Fopen(FILE8, H5F_ACC_RDWR, new_fapl); - } H5E_END_TRY; + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); - if(fid >=0 ) { /* The file open succeeds */ + /* 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"); - /* 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"); + /* Attach 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"); - /* 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 internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); - /* Get object header information */ - ret = H5Oget_info_by_name(gid, GRP_NAME, &oinfo, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Oget_info"); + /* Verify attribute version */ + if(low == H5F_LIBVER_EARLIEST) + /* The earliest version the library can set for an attribute with character encoding is 3 */ + VERIFY(attr->shared->version, H5O_ATTR_VERSION_3, "H5O_attr_ver_bounds"); + else + VERIFY(attr->shared->version, H5O_attr_ver_bounds[low], "H5O_attr_ver_bounds"); - /* Verify object header version */ - VERIFY(oinfo.hdr.version, obj_ver_bounds[f->shared->low_bound], "obj_ver_bounds"); + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); - /* Close the group */ - ret = H5Gclose(gid); - CHECK(ret, FAIL, "H5Gclose"); + /* Close the attribute creation property list */ + ret = H5Pclose(attr_cpl); + CHECK(ret, FAIL, "H5Pclose"); - /* Delete the group */ - ret = H5Ldelete(fid, GRP_NAME, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Gclose"); + /* Close the group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); - /* Close the file */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); - } /* end if */ - } /* end for */ - } /* end for */ + /* Close the datatype */ + ret = H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); - /* Close the file access property list */ - ret = H5Pclose(new_fapl); - CHECK(ret, FAIL, "H5Pclose"); + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); -} /* end test_libver_bounds_obj() */ + /* Create a copy of the file creation property list */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); -/**************************************************************** -** -** 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 */ + /* 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 */ + /* Create the file with shared datatype message enabled */ 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"); + /* Create an integer datatye */ + tid = H5Tcopy(H5T_NATIVE_INT); + CHECK(tid, FAIL, "H5Tcopy"); - /* The file's superblock version */ - super_vers = f->shared->sblock->super_vers; + /* 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"); + + /* Attach an attribute to the group with shared 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) + /* The earliest version the library can set for an attribute with shared datatype is 2 */ + VERIFY(attr->shared->version, H5O_ATTR_VERSION_2, "H5O_attr_ver_bounds"); + else + VERIFY(attr->shared->version, H5O_attr_ver_bounds[low], "H5O_attr_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, "H5Tclose"); /* Close the file */ ret = H5Fclose(fid); CHECK(ret, FAIL, "H5Fclose"); - /* Create a file access property list */ + /* Create a default 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 */ + /* Create a scalar dataspace to be used later for the attribute */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Loop through all the combinations of low/high 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; - /* Invalid combinations */ - if (ret < 0) + if(ret < 0) /* Invalid low/high combinations */ continue; - /* Open the file with or without SWMR */ + /* Open the file */ H5E_BEGIN_TRY { - fid = H5Fopen(FILE8, H5F_ACC_RDWR | (is_swmr ? H5F_ACC_SWMR_WRITE : 0), new_fapl); + fid = H5Fopen(FILE8, H5F_ACC_RDWR, 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"); + if(fid >=0 ) { /* The file open succeeds */ - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - } else /* Should fail */ - VERIFY(ok, FALSE, "H5Fopen"); - break; + /* Get the internal file pointer */ + f = (H5F_t *)H5I_object(fid); + CHECK(f, NULL, "H5I_object"); - case 2: - if(is_swmr) /* Should fail */ - VERIFY(ok, FALSE, "H5Fopen"); - else { /* Should succeed */ - VERIFY(ok, TRUE, "H5Fopen"); + /* Open the group */ + gid = H5Gopen2(fid, GRP_NAME, H5P_DEFAULT); + CHECK(gid, FAIL, "H5Gopen2"); - ok = f->shared->low_bound >= H5F_LIBVER_V18; - VERIFY(ok, TRUE, "superblock_ver_bounds"); + /* Attach an attribute to the group */ + aid = H5Acreate2(gid, "attr1", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate2"); - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - } - break; + /* Get the internal attribute pointer */ + attr = (H5A_t *)H5I_object(aid); + CHECK(attr, NULL, "H5I_object"); - 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"); + /* Verify the attribute message version */ + VERIFY(attr->shared->version, H5O_attr_ver_bounds[f->shared->low_bound], "H5O_attr_ver_bounds"); - ret = H5Fclose(fid); - CHECK(ret, FAIL, "H5Fclose"); - } - break; + /* Close the attribute */ + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); - default: - break; - } /* end switch */ + /* Delete the attribute */ + ret = H5Adelete(gid, "attr1"); + CHECK(ret, FAIL, "H5Adelete"); + + /* 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 */ @@ -6250,232 +6671,11 @@ test_libver_bounds_super_open(hid_t fapl, hid_t fcpl, htri_t is_swmr) 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); - - /* Close fcpl */ - ret = H5Pclose(fcpl); - CHECK(ret, FAIL, "H5Pclose"); - - /* 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); - - /* Close fcpl */ - 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); - - /* Close fcpl */ - 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); - - /* Close fcpl */ - 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"); + /* Close the dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); -} /* end test_libver_bounds_low_high() */ +} /* end test_libver_bounds_attributes() */ /**************************************************************** ** -- cgit v0.12