diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5AC.c | 4 | ||||
-rw-r--r-- | src/H5ACprivate.h | 2 | ||||
-rw-r--r-- | src/H5Aint.c | 5 | ||||
-rw-r--r-- | src/H5Cprivate.h | 2 | ||||
-rw-r--r-- | src/H5Ctag.c | 14 | ||||
-rw-r--r-- | src/H5D.c | 20 | ||||
-rw-r--r-- | src/H5Dint.c | 37 | ||||
-rw-r--r-- | src/H5Dpkg.h | 1 | ||||
-rw-r--r-- | src/H5Dtest.c | 41 | ||||
-rw-r--r-- | src/H5Fint.c | 16 | ||||
-rw-r--r-- | src/H5Fio.c | 2 | ||||
-rw-r--r-- | src/H5Fpkg.h | 1 | ||||
-rw-r--r-- | src/H5Fprivate.h | 4 | ||||
-rw-r--r-- | src/H5Fquery.c | 27 | ||||
-rw-r--r-- | src/H5G.c | 4 | ||||
-rw-r--r-- | src/H5Gint.c | 4 | ||||
-rw-r--r-- | src/H5O.c | 2 | ||||
-rw-r--r-- | src/H5Odtype.c | 9 | ||||
-rw-r--r-- | src/H5Pfapl.c | 99 | ||||
-rw-r--r-- | src/H5Ppublic.h | 2 | ||||
-rw-r--r-- | src/H5Znbit.c | 99 | ||||
-rw-r--r-- | src/H5public.h | 4 |
22 files changed, 327 insertions, 72 deletions
@@ -2383,7 +2383,7 @@ done: *------------------------------------------------------------------------------ */ herr_t -H5AC_evict_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id) +H5AC_evict_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hbool_t match_global, hid_t dxpl_id) { /* Variable Declarations */ herr_t ret_value = SUCCEED; @@ -2396,7 +2396,7 @@ H5AC_evict_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id) HDassert(f->shared); /* Call cache level function to evict metadata entries with specified tag */ - if(H5C_evict_tagged_entries(f, dxpl_id, metadata_tag) < 0) + if(H5C_evict_tagged_entries(f, dxpl_id, metadata_tag, match_global) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict metadata") done: diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index d1d41c9..84c9e93 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -364,7 +364,7 @@ H5_DLL herr_t H5AC_validate_config(H5AC_cache_config_t *config_ptr); /* Tag & Ring routines */ H5_DLL herr_t H5AC_tag(hid_t dxpl_id, haddr_t metadata_tag, haddr_t *prev_tag); H5_DLL herr_t H5AC_flush_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id); -H5_DLL herr_t H5AC_evict_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id); +H5_DLL herr_t H5AC_evict_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hbool_t match_global, hid_t dxpl_id); H5_DLL herr_t H5AC_retag_copied_metadata(const H5F_t *f, haddr_t metadata_tag); H5_DLL herr_t H5AC_ignore_tags(const H5F_t *f); H5_DLL herr_t H5AC_cork(H5F_t *f, haddr_t obj_addr, unsigned action, hbool_t *corked); diff --git a/src/H5Aint.c b/src/H5Aint.c index ea90118..66af0ff 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -2106,10 +2106,9 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si HDmemcpy(buf, attr_src->shared->data, attr_src->shared->data_size); /* Allocate background memory */ - if(H5T_path_bkg(tpath_src_mem) || H5T_path_bkg(tpath_mem_dst)) { + if(H5T_path_bkg(tpath_src_mem) || H5T_path_bkg(tpath_mem_dst)) if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") - } + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, NULL, "memory allocation failed") /* Convert from source file to memory */ if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, bkg_buf, dxpl_id) < 0) diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 975ea3e..4137edf 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -1970,7 +1970,7 @@ H5_DLL herr_t H5C_expunge_entry(H5F_t *f, hid_t dxpl_id, const H5C_class_t *type, haddr_t addr, unsigned flags); H5_DLL herr_t H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags); H5_DLL herr_t H5C_flush_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag); -H5_DLL herr_t H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag); +H5_DLL herr_t H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag, hbool_t match_global); H5_DLL herr_t H5C_expunge_tag_type_metadata(H5F_t *f, hid_t dxpl_id, haddr_t tag, int type_id, unsigned flags); #if H5C_DO_TAGGING_SANITY_CHECKS herr_t H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality); diff --git a/src/H5Ctag.c b/src/H5Ctag.c index d560e25..e1b4df6 100644 --- a/src/H5Ctag.c +++ b/src/H5Ctag.c @@ -352,7 +352,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag) +H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag, hbool_t match_global) { H5C_t *cache; /* Pointer to cache structure */ H5C_tag_iter_evict_ctx_t ctx; /* Context for iterator callback */ @@ -374,15 +374,15 @@ H5C_evict_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag) /* Start evicting entries */ do { - /* Reset pinned/evicted tracking flags */ - ctx.pinned_entries_need_evicted = FALSE; - ctx.evicted_entries_last_pass = FALSE; + /* Reset pinned/evicted tracking flags */ + ctx.pinned_entries_need_evicted = FALSE; + ctx.evicted_entries_last_pass = FALSE; - /* Iterate through entries in the cache */ - if(H5C__iter_tagged_entries(cache, tag, TRUE, H5C__evict_tagged_entries_cb, &ctx) < 0) + /* Iterate through entries in the cache */ + if(H5C__iter_tagged_entries(cache, tag, match_global, H5C__evict_tagged_entries_cb, &ctx) < 0) HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "Iteration of tagged entries failed") - /* Keep doing this until we have stopped evicted entries */ + /* Keep doing this until we have stopped evicted entries */ } while(TRUE == ctx.evicted_entries_last_pass); /* Fail if we have finished evicting entries and pinned entries still need evicted */ @@ -308,37 +308,37 @@ done: /*------------------------------------------------------------------------- - * Function: H5Dclose + * Function: H5Dclose * - * Purpose: Closes access to a dataset (DATASET_ID) and releases - * resources used by it. It is illegal to subsequently use that - * same dataset ID in calls to other dataset functions. + * Purpose: Closes access to a dataset (DATASET_ID) and releases + * resources used by it. It is illegal to subsequently use that + * same dataset ID in calls to other dataset functions. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Thursday, December 4, 1997 + * Programmer: Robb Matzke + * Thursday, December 4, 1997 * *------------------------------------------------------------------------- */ herr_t H5Dclose(hid_t dset_id) { - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); /* Check args */ if(NULL == H5I_object_verify(dset_id, H5I_DATASET)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") /* * Decrement the counter on the dataset. It will be freed if the count * reaches zero. */ if(H5I_dec_app_ref_always_close(dset_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Dint.c b/src/H5Dint.c index 8a00be2..59fe3e9 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1780,9 +1780,9 @@ done: herr_t H5D_close(H5D_t *dataset) { - hbool_t free_failed = FALSE; - hbool_t corked; /* Whether the dataset is corked or not */ - herr_t ret_value = SUCCEED; /* Return value */ + hbool_t free_failed = FALSE; /* Set if freeing sub-components failed */ + hbool_t corked; /* Whether the dataset is corked or not */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1797,6 +1797,7 @@ H5D_close(H5D_t *dataset) dataset->shared->fo_count--; if(dataset->shared->fo_count == 0) { + /* Flush the dataset's information. Continue to close even if it fails. */ if(H5D__flush_real(dataset, H5AC_ind_read_dxpl_id) < 0) HDONE_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to flush cached dataset info") @@ -1891,12 +1892,12 @@ H5D_close(H5D_t *dataset) (H5O_msg_reset(H5O_FILL_ID, &dataset->shared->dcpl_cache.fill) < 0) || (H5O_msg_reset(H5O_EFL_ID, &dataset->shared->dcpl_cache.efl) < 0); - /* Uncork cache entries with object address tag */ - if(H5AC_cork(dataset->oloc.file, dataset->oloc.addr, H5AC__GET_CORKED, &corked) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status") - if(corked) - if(H5AC_cork(dataset->oloc.file, dataset->oloc.addr, H5AC__UNCORK, NULL) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTUNCORK, FAIL, "unable to uncork an object") + /* Uncork cache entries with object address tag */ + if(H5AC_cork(dataset->oloc.file, dataset->oloc.addr, H5AC__GET_CORKED, &corked) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status") + if(corked) + if(H5AC_cork(dataset->oloc.file, dataset->oloc.addr, H5AC__UNCORK, NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTUNCORK, FAIL, "unable to uncork an object") /* * Release datatype, dataspace and creation property list -- there isn't @@ -1917,6 +1918,14 @@ H5D_close(H5D_t *dataset) if(H5O_close(&(dataset->oloc)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release object header") + /* Evict dataset metadata if evicting on close */ + if(H5F_SHARED(dataset->oloc.file) && H5F_EVICT_ON_CLOSE(dataset->oloc.file)) { + if(H5AC_flush_tagged_metadata(dataset->oloc.file, dataset->oloc.addr, H5AC_ind_read_dxpl_id) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") + if(H5AC_evict_tagged_metadata(dataset->oloc.file, dataset->oloc.addr, FALSE, H5AC_ind_read_dxpl_id) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to evict tagged metadata") + } /* end if */ + /* * Free memory. Before freeing the memory set the file pointer to NULL. * We always check for a null file pointer in other H5D functions to be @@ -1924,8 +1933,8 @@ H5D_close(H5D_t *dataset) * above). */ dataset->oloc.file = NULL; - dataset->shared = H5FL_FREE(H5D_shared_t, dataset->shared); + } /* end if */ else { /* Decrement the ref. count for this object in the top file */ @@ -1943,16 +1952,16 @@ H5D_close(H5D_t *dataset) HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "problem attempting to free location") } /* end else */ - /* Release the dataset's path info */ - if(H5G_name_free(&(dataset->path)) < 0) - free_failed = TRUE; + /* Release the dataset's path info */ + if(H5G_name_free(&(dataset->path)) < 0) + free_failed = TRUE; /* Free the dataset's memory structure */ dataset = H5FL_FREE(H5D_t, dataset); /* Check if anything failed in the middle... */ if(free_failed) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't free a component of the dataset, but the dataset was freed anyway.") + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "couldn't free a component of the dataset, but the dataset was freed anyway.") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 05f49d1..2190f8c 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -770,6 +770,7 @@ H5_DLL htri_t H5D__mpio_opt_possible(const H5D_io_info_t *io_info, H5_DLL herr_t H5D__layout_version_test(hid_t did, unsigned *version); H5_DLL herr_t H5D__layout_contig_size_test(hid_t did, hsize_t *size); H5_DLL herr_t H5D__layout_idx_type_test(hid_t did, H5D_chunk_index_t *idx_type); +H5_DLL herr_t H5D__layout_type_test(hid_t did, H5D_layout_t *layout_type); H5_DLL herr_t H5D__current_cache_size_test(hid_t did, size_t *nbytes_used, int *nused); #endif /* H5D_TESTING */ diff --git a/src/H5Dtest.c b/src/H5Dtest.c index c3b0b19..56f14f7 100644 --- a/src/H5Dtest.c +++ b/src/H5Dtest.c @@ -144,6 +144,47 @@ done: /*-------------------------------------------------------------------------- NAME + H5D__layout_type_test + PURPOSE + Determine the storage layout type for a dataset + USAGE + herr_t H5D__layout_type_test(did, layout_type) + hid_t did; IN: Dataset to query + H5D_layout_t *layout_type; OUT: Pointer to location to place layout info + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Checks the layout type for a dataset. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5D__layout_type_test(hid_t did, H5D_layout_t *layout_type) +{ + H5D_t *dset; /* Pointer to dataset to query */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_PACKAGE + + HDassert(layout_type); + + /* Check args */ + if(NULL == (dset = (H5D_t *)H5I_object_verify(did, H5I_DATASET))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + if(layout_type) + *layout_type = dset->shared->layout.type; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D__layout_type_test() */ + + +/*-------------------------------------------------------------------------- + NAME H5D__layout_idx_type_test PURPOSE Determine the storage layout index type for a dataset's layout information diff --git a/src/H5Fint.c b/src/H5Fint.c index 80c593b..5b7fdda 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -954,6 +954,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_class_t *drvr; /*file driver class info */ H5P_genplist_t *a_plist; /*file access property list */ H5F_close_degree_t fc_degree; /*file close degree */ + hbool_t evict_on_close; /* evict on close value from plist */ H5F_t *ret_value = NULL; /*actual return value */ FUNC_ENTER_NOAPI(NULL) @@ -1118,6 +1119,21 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") } /* end if */ + /* Record the evict-on-close MDC behavior. If it's the first time opening + * the file, set it to access property list value; if it's the second time + * or later, verify that the access property list value matches the value + * in shared file structure. + */ + if(H5P_get(a_plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, &evict_on_close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get evict on close value") + + if(shared->nrefs == 1) { + shared->evict_on_close = evict_on_close; + } else if(shared->nrefs > 1) { + if(shared->evict_on_close != evict_on_close) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file evict-on-close value doesn't match") + } /* end if */ + /* Formulate the absolute path for later search of target file for external links */ if(H5_build_extpath(name, &file->extpath) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") diff --git a/src/H5Fio.c b/src/H5Fio.c index b9bd354..2ccd3f3 100644 --- a/src/H5Fio.c +++ b/src/H5Fio.c @@ -271,7 +271,7 @@ H5F_evict_tagged_metadata(H5F_t * f, haddr_t tag, hid_t dxpl_id) f->shared->sblock = NULL; /* Evict the object's metadata */ - if(H5AC_evict_tagged_metadata(f, tag, dxpl_id)<0) + if(H5AC_evict_tagged_metadata(f, tag, TRUE, dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "unable to evict tagged metadata") /* Re-read the superblock. */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index c5aed3b..8ec2a93 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -261,6 +261,7 @@ struct H5F_file_t { /* not change thereafter. */ hid_t fcpl_id; /* File creation property list ID */ H5F_close_degree_t fc_degree; /* File close behavior degree */ + hbool_t evict_on_close; /* If the file's objects should be evicted from the metadata cache on close */ size_t rdcc_nslots; /* Size of raw data chunk cache (slots) */ size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */ double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index b5c24e9..40e5ff2 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -303,6 +303,7 @@ #define H5F_SET_SOHM_NINDEXES(F, N) ((F)->shared->sohm_nindexes = (N)) #define H5F_FCPL(F) ((F)->shared->fcpl_id) #define H5F_GET_FC_DEGREE(F) ((F)->shared->fc_degree) +#define H5F_EVICT_ON_CLOSE(F) ((F)->shared->evict_on_close) #define H5F_RDCC_NSLOTS(F) ((F)->shared->rdcc_nslots) #define H5F_RDCC_NBYTES(F) ((F)->shared->rdcc_nbytes) #define H5F_RDCC_W0(F) ((F)->shared->rdcc_w0) @@ -348,6 +349,7 @@ #define H5F_SET_SOHM_NINDEXES(F, N) (H5F_set_sohm_nindexes((F), (N))) #define H5F_FCPL(F) (H5F_get_fcpl(F)) #define H5F_GET_FC_DEGREE(F) (H5F_get_fc_degree(F)) +#define H5F_EVICT_ON_CLOSE(F) (H5F_get_evict_on_close(F)) #define H5F_RDCC_NSLOTS(F) (H5F_rdcc_nslots(F)) #define H5F_RDCC_NBYTES(F) (H5F_rdcc_nbytes(F)) #define H5F_RDCC_W0(F) (H5F_rdcc_w0(F)) @@ -463,6 +465,7 @@ #define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */ #define H5F_ACS_FILE_IMAGE_INFO_NAME "file_image_info" /* struct containing initial file image and callback info */ #define H5F_ACS_CORE_WRITE_TRACKING_FLAG_NAME "core_write_tracking_flag" /* Whether or not core VFD backing store write tracking is enabled */ +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME "evict_on_close_flag" /* Whether or not the metadata cache will evict objects on close */ #define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_NAME "core_write_tracking_page_size" /* The page size in kiB when core VFD write tracking is enabled */ #define H5F_ACS_COLL_MD_WRITE_FLAG_NAME "collective_metadata_write" /* property indicating whether metadata writes are done collectively or not */ @@ -660,6 +663,7 @@ H5_DLL unsigned H5F_get_sohm_nindexes(const H5F_t *f); H5_DLL herr_t H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes); H5_DLL hid_t H5F_get_fcpl(const H5F_t *f); H5_DLL H5F_close_degree_t H5F_get_fc_degree(const H5F_t *f); +H5_DLL hbool_t H5F_get_evict_on_close(const H5F_t *f); H5_DLL size_t H5F_rdcc_nbytes(const H5F_t *f); H5_DLL size_t H5F_rdcc_nslots(const H5F_t *f); H5_DLL double H5F_rdcc_w0(const H5F_t *f); diff --git a/src/H5Fquery.c b/src/H5Fquery.c index dd6e8e3..f59a9b7 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -835,6 +835,33 @@ H5F_get_fc_degree(const H5F_t *f) /*------------------------------------------------------------------------- + * Function: H5F_get_evict_on_close + * + * Purpose: Retrieve the 'file close degree' for the file. + * + * Return: Success: Flag indicating whether the evict-on-close + * property was set for the file. + * Failure: (can't happen) + * + * Programmer: Dana Robinson + * Spring 2016 + * + *------------------------------------------------------------------------- + */ +hbool_t +H5F_get_evict_on_close(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + HDassert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->evict_on_close) +} /* end H5F_get_evict_on_close() */ + + +/*------------------------------------------------------------------------- * Function: H5F_store_msg_crt_idx * * Purpose: Retrieve the 'store message creation index' flag for the file. @@ -715,14 +715,14 @@ done: herr_t H5Gclose(hid_t group_id) { - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", group_id); /* Check args */ if(NULL == H5I_object_verify(group_id,H5I_GROUP)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") /* * Decrement the counter on the group atom. It will be freed if the count diff --git a/src/H5Gint.c b/src/H5Gint.c index f5bccc3..a0e06f3 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -486,7 +486,7 @@ H5G_close(H5G_t *grp) if(0 == grp->shared->fo_count) { HDassert(grp != H5G_rootof(H5G_fileof(grp))); - /* Uncork cache entries with object address tag */ + /* Uncork cache entries with object address tag */ if(H5AC_cork(grp->oloc.file, grp->oloc.addr, H5AC__GET_CORKED, &corked) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status") if(corked) @@ -500,6 +500,8 @@ H5G_close(H5G_t *grp) HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't remove group from list of open objects") if(H5O_close(&(grp->oloc)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close") + + /* Free memory */ grp->shared = H5FL_FREE(H5G_shared_t, grp->shared); } else { /* Decrement the ref. count for this object in the top file */ @@ -1051,7 +1051,7 @@ done: * the same effect as calling H5Gclose, H5Dclose, or H5Tclose. * * Return: Success: Non-negative - * Failure: Negative + * Failure: Negative * * Programmer: James Laird * July 14 2006 diff --git a/src/H5Odtype.c b/src/H5Odtype.c index e51d319..799f475 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -311,7 +311,11 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p if(version == H5O_DTYPE_VERSION_1) { /* Decode the number of dimensions */ ndims = *(*pp)++; - HDassert(ndims <= 4); + + /* Check that ndims is valid */ + if(ndims > 4) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "invalid number of dimensions for array") + *pp += 3; /*reserved bytes */ /* Skip dimension permutation */ @@ -519,7 +523,8 @@ H5O_dtype_decode_helper(H5F_t *f, unsigned *ioflags/*in,out*/, const uint8_t **p dt->shared->u.array.ndims = *(*pp)++; /* Double-check the number of dimensions */ - HDassert(dt->shared->u.array.ndims <= H5S_MAX_RANK); + if(dt->shared->u.array.ndims > H5S_MAX_RANK) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTLOAD, FAIL, "too many dimensions for array datatype") /* Skip reserved bytes, if version has them */ if(version < H5O_DTYPE_VERSION_3) diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 96de39c..8801061 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -181,6 +181,11 @@ /* Definition for object flush callback */ #define H5F_ACS_OBJECT_FLUSH_CB_SIZE sizeof(H5F_object_flush_t) #define H5F_ACS_OBJECT_FLUSH_CB_DEF {NULL, NULL} +/* Definition for evict on close property */ +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_SIZE sizeof(hbool_t) +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_DEF FALSE +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_ENC H5P__encode_hbool_t +#define H5F_ACS_EVICT_ON_CLOSE_FLAG_DEC H5P__decode_hbool_t #ifdef H5_HAVE_PARALLEL /* Definition of collective metadata read mode flag */ #define H5F_ACS_COLL_MD_READ_FLAG_SIZE sizeof(H5P_coll_md_read_flag_t) @@ -296,6 +301,7 @@ static const H5FD_file_image_info_t H5F_def_file_image_info_g = H5F_ACS_FILE_IMA static const hbool_t H5F_def_core_write_tracking_flag_g = H5F_ACS_CORE_WRITE_TRACKING_FLAG_DEF; /* Default setting for core VFD write tracking */ static const size_t H5F_def_core_write_tracking_page_size_g = H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEF; /* Default core VFD write tracking page size */ static const H5F_object_flush_t H5F_def_object_flush_cb_g = H5F_ACS_OBJECT_FLUSH_CB_DEF; /* Default setting for object flush callback */ +static const hbool_t H5F_def_evict_on_close_flag_g = H5F_ACS_EVICT_ON_CLOSE_FLAG_DEF; /* Default setting for evict on close property */ #ifdef H5_HAVE_PARALLEL static const H5P_coll_md_read_flag_t H5F_def_coll_md_read_flag_g = H5F_ACS_COLL_MD_READ_FLAG_DEF; /* Default setting for the collective metedata read flag */ static const hbool_t H5F_def_coll_md_write_flag_g = H5F_ACS_COLL_MD_WRITE_FLAG_DEF; /* Default setting for the collective metedata write flag */ @@ -462,6 +468,12 @@ H5P__facc_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the evict on close flag */ + if(H5P_register_real(pclass, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, H5F_ACS_EVICT_ON_CLOSE_FLAG_SIZE, &H5F_def_evict_on_close_flag_g, + NULL, NULL, NULL, H5F_ACS_EVICT_ON_CLOSE_FLAG_ENC, H5F_ACS_EVICT_ON_CLOSE_FLAG_DEC, + NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + #ifdef H5_HAVE_PARALLEL /* Register the metadata collective read flag */ if(H5P_register_real(pclass, H5_COLL_MD_READ_FLAG_NAME, H5F_ACS_COLL_MD_READ_FLAG_SIZE, &H5F_def_coll_md_read_flag_g, @@ -3605,6 +3617,93 @@ done: FUNC_LEAVE_API(ret_value) } /* H5Pget_obj_flush_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_evict_on_close + * + * Purpose: Sets the evict_on_close property value. + * + * When this property is set, closing an HDF5 object will + * cause the object's metadata cache entries to be flushed + * and evicted from the cache. + * + * Currently only implemented for datasets. + * + * Return: SUCCEED/FAIL + * + * Programmer: Dana Robinson + * Spring 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close) +{ + H5P_genplist_t *plist; /* property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ib", fapl_id, evict_on_close); + + /* Compare the property list's class against the other class */ + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property list is not a file access plist") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set values */ + if(H5P_set(plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, &evict_on_close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set evict on close property") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_evict_on_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_evict_on_close + * + * Purpose: Gets the evict_on_close property value. + * + * When this property is set, closing an HDF5 object will + * cause the object's metadata cache entries to be flushed + * and evicted from the cache. + * + * Currently only implemented for datasets. + * + * Return: SUCCEED/FAIL + * + * Programmer: Dana Robinson + * Spring 2016 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_evict_on_close(hid_t fapl_id, hbool_t *evict_on_close) +{ + H5P_genplist_t *plist; /* property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*b", fapl_id, evict_on_close); + + /* Compare the property list's class against the other class */ + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "property list is not an access plist") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + if(H5P_get(plist, H5F_ACS_EVICT_ON_CLOSE_FLAG_NAME, evict_on_close) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get evict on close property") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_evict_on_close() */ + #ifdef H5_HAVE_PARALLEL /*------------------------------------------------------------------------- diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 0318c8f..b807a37 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -353,6 +353,8 @@ H5_DLL herr_t H5Pset_core_write_tracking(hid_t fapl_id, hbool_t is_enabled, size H5_DLL herr_t H5Pget_core_write_tracking(hid_t fapl_id, hbool_t *is_enabled, size_t *page_size); H5_DLL herr_t H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata); H5_DLL herr_t H5Pget_object_flush_cb(hid_t plist_id, H5F_flush_cb_t *func, void **udata); +H5_DLL herr_t H5Pset_evict_on_close(hid_t fapl_id, hbool_t evict_on_close); +H5_DLL herr_t H5Pget_evict_on_close(hid_t fapl_id, hbool_t *evict_on_close); #ifdef H5_HAVE_PARALLEL H5_DLL herr_t H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective); H5_DLL herr_t H5Pget_all_coll_metadata_ops(hid_t plist_id, hbool_t *is_collective); diff --git a/src/H5Znbit.c b/src/H5Znbit.c index 04e8869..7a41d16 100644 --- a/src/H5Znbit.c +++ b/src/H5Znbit.c @@ -65,13 +65,13 @@ static void H5Z_nbit_decompress_one_nooptype(unsigned char *data, size_t data_of unsigned char *buffer, size_t *j, size_t *buf_len, unsigned size); static void H5Z_nbit_decompress_one_atomic(unsigned char *data, size_t data_offset, unsigned char *buffer, size_t *j, size_t *buf_len, const parms_atomic *p); -static void H5Z_nbit_decompress_one_array(unsigned char *data, size_t data_offset, +static herr_t H5Z__nbit_decompress_one_array(unsigned char *data, size_t data_offset, unsigned char *buffer, size_t *j, size_t *buf_len, const unsigned parms[], unsigned *parms_index); -static void H5Z_nbit_decompress_one_compound(unsigned char *data, size_t data_offset, +static herr_t H5Z__nbit_decompress_one_compound(unsigned char *data, size_t data_offset, unsigned char *buffer, size_t *j, size_t *buf_len, const unsigned parms[], unsigned *parms_index); -static void H5Z_nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, +static herr_t H5Z__nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, const unsigned parms[]); static void H5Z_nbit_compress_one_nooptype(unsigned char *data, size_t data_offset, unsigned char *buffer, size_t *j, size_t *buf_len, unsigned size); @@ -1011,7 +1011,8 @@ H5Z_filter_nbit(unsigned flags, size_t cd_nelmts, const unsigned cd_values[], HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, 0, "memory allocation failed for nbit decompression") /* decompress the buffer */ - H5Z_nbit_decompress(outbuf, d_nelmts, (unsigned char *)*buf, cd_values); + if(H5Z__nbit_decompress(outbuf, d_nelmts, (unsigned char *)*buf, cd_values) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, 0, "can't decompress buffer") } /* end if */ /* output; compress */ else { @@ -1166,13 +1167,16 @@ H5Z_nbit_decompress_one_atomic(unsigned char *data, size_t data_offset, } } -static void -H5Z_nbit_decompress_one_array(unsigned char *data, size_t data_offset, +static herr_t +H5Z__nbit_decompress_one_array(unsigned char *data, size_t data_offset, unsigned char *buffer, size_t *j, size_t *buf_len, const unsigned parms[], unsigned *parms_index) { unsigned i, total_size, base_class, base_size, n, begin_index; parms_atomic p; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC total_size = parms[(*parms_index)++]; base_class = parms[(*parms_index)++]; @@ -1183,6 +1187,11 @@ H5Z_nbit_decompress_one_array(unsigned char *data, size_t data_offset, p.order = parms[(*parms_index)++]; p.precision = parms[(*parms_index)++]; p.offset = parms[(*parms_index)++]; + + /* Check values of precision and offset */ + if(p.precision > p.size * 8 || (p.precision + p.offset) > p.size * 8) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "invalid datatype precision/offset") + n = total_size / p.size; for(i = 0; i < n; i++) H5Z_nbit_decompress_one_atomic(data, data_offset + i * p.size, @@ -1194,8 +1203,9 @@ H5Z_nbit_decompress_one_array(unsigned char *data, size_t data_offset, n = total_size / base_size; /* number of base_type elements inside the array datatype */ begin_index = *parms_index; for(i = 0; i < n; i++) { - H5Z_nbit_decompress_one_array(data, data_offset + i * base_size, - buffer, j, buf_len, parms, parms_index); + if(H5Z__nbit_decompress_one_array(data, data_offset + i * base_size, + buffer, j, buf_len, parms, parms_index) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "can't decompress array") *parms_index = begin_index; } break; @@ -1205,8 +1215,9 @@ H5Z_nbit_decompress_one_array(unsigned char *data, size_t data_offset, n = total_size / base_size; /* number of base_type elements inside the array datatype */ begin_index = *parms_index; for(i = 0; i < n; i++) { - H5Z_nbit_decompress_one_compound(data, data_offset + i * base_size, - buffer, j, buf_len, parms, parms_index); + if(H5Z__nbit_decompress_one_compound(data, data_offset + i * base_size, + buffer, j, buf_len, parms, parms_index) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "can't decompress compound") *parms_index = begin_index; } break; @@ -1219,56 +1230,81 @@ H5Z_nbit_decompress_one_array(unsigned char *data, size_t data_offset, default: HDassert(0 && "This Should never be executed!"); } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) } -static void -H5Z_nbit_decompress_one_compound(unsigned char *data, size_t data_offset, +static herr_t +H5Z__nbit_decompress_one_compound(unsigned char *data, size_t data_offset, unsigned char *buffer, size_t *j, size_t *buf_len, const unsigned parms[], unsigned *parms_index) { - unsigned i, nmembers, member_offset, member_class, size; + unsigned i, nmembers, member_offset, member_class, member_size, used_size = 0, size; parms_atomic p; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC - (*parms_index)++; /* skip total size of compound datatype */ + size = parms[(*parms_index)++]; nmembers = parms[(*parms_index)++]; for(i = 0; i < nmembers; i++) { member_offset = parms[(*parms_index)++]; member_class = parms[(*parms_index)++]; + + /* Check for overflow */ + member_size = parms[*parms_index]; + used_size += member_size; + if(used_size > size) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "compound member offset overflowed compound size") switch(member_class) { case H5Z_NBIT_ATOMIC: - p.size = parms[(*parms_index)++]; + p.size = member_size; + /* Advance past member size */ + (*parms_index)++; p.order = parms[(*parms_index)++]; p.precision = parms[(*parms_index)++]; p.offset = parms[(*parms_index)++]; + + /* Check values of precision and offset */ + if(p.precision > p.size * 8 || (p.precision + p.offset) > p.size * 8) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "invalid datatype precision/offset") + H5Z_nbit_decompress_one_atomic(data, data_offset + member_offset, buffer, j, buf_len, &p); break; case H5Z_NBIT_ARRAY: - H5Z_nbit_decompress_one_array(data, data_offset + member_offset, - buffer, j, buf_len, parms, parms_index); + if(H5Z__nbit_decompress_one_array(data, data_offset + member_offset, + buffer, j, buf_len, parms, parms_index) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "can't decompress array") break; case H5Z_NBIT_COMPOUND: - H5Z_nbit_decompress_one_compound(data, data_offset+member_offset, - buffer, j, buf_len, parms, parms_index); + if(H5Z__nbit_decompress_one_compound(data, data_offset+member_offset, + buffer, j, buf_len, parms, parms_index) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "can't decompress compound") break; case H5Z_NBIT_NOOPTYPE: - size = parms[(*parms_index)++]; + /* Advance past member size */ + (*parms_index)++; H5Z_nbit_decompress_one_nooptype(data, data_offset+member_offset, - buffer, j, buf_len, size); + buffer, j, buf_len, member_size); break; default: HDassert(0 && "This Should never be executed!"); } /* end switch */ } + +done: + FUNC_LEAVE_NOAPI(ret_value) } -static void -H5Z_nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, +static herr_t +H5Z__nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, const unsigned parms[]) { /* i: index of data, j: index of buffer, @@ -1278,6 +1314,9 @@ H5Z_nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffe size_t buf_len; parms_atomic p; unsigned parms_index; /* index in array parms used by compression/decompression functions */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC /* may not have to initialize to zeros */ HDmemset(data, 0, d_nelmts * parms[4]); @@ -1292,6 +1331,11 @@ H5Z_nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffe p.order = parms[5]; p.precision = parms[6]; p.offset = parms[7]; + + /* Check values of precision and offset */ + if(p.precision > p.size * 8 || (p.precision + p.offset) > p.size * 8) + HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "invalid datatype precision/offset") + for(i = 0; i < d_nelmts; i++) H5Z_nbit_decompress_one_atomic(data, i * p.size, buffer, &j, &buf_len, &p); break; @@ -1300,7 +1344,8 @@ H5Z_nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffe size = parms[4]; parms_index = 4; /* set the index before goto function call */ for(i = 0; i < d_nelmts; i++) { - H5Z_nbit_decompress_one_array(data, i * size, buffer, &j, &buf_len, parms, &parms_index); + if(H5Z__nbit_decompress_one_array(data, i * size, buffer, &j, &buf_len, parms, &parms_index) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "can't decompress array") parms_index = 4; } break; @@ -1309,7 +1354,8 @@ H5Z_nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffe size = parms[4]; parms_index = 4; /* set the index before goto function call */ for(i = 0; i < d_nelmts; i++) { - H5Z_nbit_decompress_one_compound(data, i * size, buffer, &j, &buf_len, parms, &parms_index); + if(H5Z__nbit_decompress_one_compound(data, i * size, buffer, &j, &buf_len, parms, &parms_index) < 0) + HGOTO_ERROR(H5E_PLINE, H5E_CANTFILTER, FAIL, "can't decompress compound") parms_index = 4; } break; @@ -1317,6 +1363,9 @@ H5Z_nbit_decompress(unsigned char *data, unsigned d_nelmts, unsigned char *buffe default: HDassert(0 && "This Should never be executed!"); } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) } static void diff --git a/src/H5public.h b/src/H5public.h index 2f21648..84c98fa 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -94,10 +94,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 234 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 235 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.234" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.235" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) |