From b6494f0fc9159fae1418e033126826cf61a3ff21 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 24 Aug 2009 14:09:36 -0500 Subject: [svn-r17415] Description: Bring r17408, 17411, 17412, 17413 & 17414 from trunk back to 1.8 branch: r17408: Move flush operation on mounted file hierarchy into H5Fmount module. r17411: Make H5AC_flush just flush the cache and make H5AC_dest perform the proper parallel synchronization before destroying the cache. Also, further discriminate between 'closing' and 'non-closing' actions in H5F_flush. r17412: Seperate 'flush' functionality from 'destroy' functionality at the H5F level also. r17413: Remove vestigial intermediate routine for flushing file and move it into API routine. Also, remove private, unused (now) 'H5F_FLUSH_DOWN' symbol from public header file. r17414: Flush the core VFD's buffer before closing the file, also flush the metadata accumulator before reseting it. Write the driver info message out in the superblock flush routine more directly, instead of using wrapper routine, since the wrapper routine won't work when the superblock is being shutdown. Tested on: FreeBSD/32 6.3 (duty) in debug mode (h5committest performed on trunk) --- src/H5AC.c | 310 ++++++++++++++++++++------------------------------- src/H5ACprivate.h | 2 +- src/H5C.c | 113 ++++--------------- src/H5Cprivate.h | 2 - src/H5F.c | 189 +++++++++++-------------------- src/H5FDcore.c | 20 ++-- src/H5Faccum.c | 14 ++- src/H5Fmount.c | 77 +++++++++++++ src/H5Fpkg.h | 4 +- src/H5Fpublic.h | 3 +- src/H5Fsuper_cache.c | 12 +- src/H5trace.c | 4 - test/ohdr.c | 28 +++-- test/tsohm.c | 20 ++-- testpar/t_cache.c | 2 +- 15 files changed, 355 insertions(+), 445 deletions(-) diff --git a/src/H5AC.c b/src/H5AC.c index ec4fb39..f24f7b1 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -193,6 +193,8 @@ static herr_t H5AC_receive_and_apply_clean_list(H5F_t * f, static herr_t H5AC_log_renamed_entry(H5AC_t * cache_ptr, haddr_t old_addr, haddr_t new_addr); + +static herr_t H5AC_flush_entries(H5F_t *f); #endif /* H5_HAVE_PARALLEL */ @@ -757,64 +759,52 @@ done: herr_t H5AC_dest(H5F_t *f, hid_t dxpl_id) { - H5AC_t *cache = NULL; - herr_t ret_value=SUCCEED; /* Return value */ #ifdef H5_HAVE_PARALLEL H5AC_aux_t * aux_ptr = NULL; #endif /* H5_HAVE_PARALLEL */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5AC_dest, FAIL) - assert(f); - assert(f->shared->cache); - cache = f->shared->cache; -#ifdef H5_HAVE_PARALLEL - aux_ptr = cache->aux_ptr; - - if ( aux_ptr != NULL ) { - - HDassert ( aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC ); - } -#endif /* H5_HAVE_PARALLEL */ + /* Sanity check */ + HDassert(f); + HDassert(f->shared->cache); #if H5AC__TRACE_FILE_ENABLED - if ( H5AC_close_trace_file(cache) < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "H5AC_close_trace_file() failed.") - } + if(H5AC_close_trace_file(f->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_close_trace_file() failed.") #endif /* H5AC__TRACE_FILE_ENABLED */ - if ( H5C_dest(f, dxpl_id, H5AC_noblock_dxpl_id, cache) < 0 ) { +#ifdef H5_HAVE_PARALLEL + aux_ptr = f->shared->cache->aux_ptr; + if(aux_ptr) + /* Sanity check */ + HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC); - HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache") - } + /* Attempt to flush all entries from rank 0 & Bcast clean list to other ranks */ + if(H5AC_flush_entries(f) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.") +#endif /* H5_HAVE_PARALLEL */ + /* Destroy the cache */ + if(H5C_dest(f, dxpl_id, H5AC_noblock_dxpl_id, f->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache") f->shared->cache = NULL; #ifdef H5_HAVE_PARALLEL - if ( aux_ptr != NULL ) { - - if ( aux_ptr->d_slist_ptr != NULL ) { - + if(aux_ptr != NULL) { + if(aux_ptr->d_slist_ptr != NULL) H5SL_close(aux_ptr->d_slist_ptr); - } - - if ( aux_ptr->c_slist_ptr != NULL ) { - + if(aux_ptr->c_slist_ptr != NULL) H5SL_close(aux_ptr->c_slist_ptr); - } - aux_ptr->magic = 0; H5FL_FREE(H5AC_aux_t, aux_ptr); aux_ptr = NULL; - } + } /* end if */ #endif /* H5_HAVE_PARALLEL */ done: - FUNC_LEAVE_NOAPI(ret_value) - } /* H5AC_dest() */ @@ -914,43 +904,11 @@ done: * Purpose: Flush (and possibly destroy) the metadata cache associated * with the specified file. * - * This is a re-write of an earlier version of the function - * which was reputedly capable of flushing (and destroying - * if requested) individual entries, individual entries if - * they match the supplied type, all entries of a given type, - * as well as all entries in the cache. - * - * As only this last capability is actually used at present, - * I have not implemented the other capabilities in this - * version of the function. - * - * The type and addr parameters are retained to avoid source - * code changed, but values other than NULL and HADDR_UNDEF - * respectively are errors. If all goes well, they should - * be removed, and the function renamed to something more - * descriptive -- perhaps H5AC_flush_cache. - * * If the cache contains protected entries, the function will * fail, as protected entries cannot be flushed. However * all unprotected entries should be flushed before the * function returns failure. * - * For historical purposes, the original version of the - * purpose section is reproduced below: - * - * ============ Original Version of "Purpose:" ============ - * - * Flushes (and destroys if DESTROY is non-zero) the specified - * entry from the cache. If the entry TYPE is CACHE_FREE and - * ADDR is HADDR_UNDEF then all types of entries are - * flushed. If TYPE is CACHE_FREE and ADDR is defined then - * whatever is cached at ADDR is flushed. Otherwise the thing - * at ADDR is flushed if it is the correct type. - * - * If there are protected objects they will not be flushed. - * However, an attempt will be made to flush all non-protected - * items before this function returns failure. - * * Return: Non-negative on success/Negative on failure if there was a * request to flush all items and something was protected. * @@ -958,45 +916,16 @@ done: * matzke@llnl.gov * Jul 9 1997 * - * Modifications: - * Robb Matzke, 1999-07-27 - * The ADDR argument is passed by value. - * - * Complete re-write. See above for details. -- JRM 5/11/04 - * - * Abstracted the guts of the function to H5C_flush_cache() - * in H5C.c, and then re-wrote the function as a wrapper for - * H5C_flush_cache(). - * - * JRM - 6/7/04 - * - * JRM - 7/5/05 - * Modified function as part of a fix for a cache coherency - * bug in PHDF5. See the header comments on the H5AC_aux_t - * structure for details. - * - * JRM -- 5/11/06 - * Added call to the write_done callback. - * - * JRM -- 6/6/06 - * Added trace file support. - * *------------------------------------------------------------------------- */ herr_t -H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags) +H5AC_flush(H5F_t *f, hid_t dxpl_id) { - herr_t status; - herr_t ret_value = SUCCEED; /* Return value */ -#ifdef H5_HAVE_PARALLEL - H5AC_aux_t * aux_ptr = NULL; - int mpi_code; -#endif /* H5_HAVE_PARALLEL */ #if H5AC__TRACE_FILE_ENABLED char trace[128] = ""; FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ - + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5AC_flush, FAIL) @@ -1007,108 +936,31 @@ H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags) /* For the flush, only the flags are really necessary in the trace file. * Write the result to catch occult errors. */ - if ( ( f != NULL ) && - ( f->shared != NULL ) && - ( f->shared->cache != NULL ) && - ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0 ) && - ( trace_file_ptr != NULL ) ) { - - sprintf(trace, "H5AC_flush 0x%x", flags); - } + if((f != NULL) && + (f->shared != NULL) && + (f->shared->cache != NULL) && + (H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0) && + (trace_file_ptr != NULL)) + sprintf(trace, "H5AC_flush"); #endif /* H5AC__TRACE_FILE_ENABLED */ #ifdef H5_HAVE_PARALLEL - aux_ptr = f->shared->cache->aux_ptr; - - if ( aux_ptr != NULL ) { - -#if H5AC_DEBUG_DIRTY_BYTES_CREATION - HDfprintf(stdout, - "%d::H5AC_flush: (u/uu/i/iu/r/ru) = %d/%d/%d/%d/%d/%d\n", - (int)(aux_ptr->mpi_rank), - (int)(aux_ptr->unprotect_dirty_bytes), - (int)(aux_ptr->unprotect_dirty_bytes_updates), - (int)(aux_ptr->insert_dirty_bytes), - (int)(aux_ptr->insert_dirty_bytes_updates), - (int)(aux_ptr->rename_dirty_bytes), - (int)(aux_ptr->rename_dirty_bytes_updates)); -#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */ - - /* to prevent "messages from the future" we must synchronize all - * processes before we start the flush. Hence the following - * barrier. - */ - if ( MPI_SUCCESS != (mpi_code = MPI_Barrier(aux_ptr->mpi_comm)) ) { - - HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code) - } - - /* if the clear only flag is set, this flush will not involve any - * disk I/O. In such cases, it is not necessary to let process 0 - * flush first. - */ - if ( ( aux_ptr->mpi_rank == 0 ) && - ( (flags & H5AC__FLUSH_CLEAR_ONLY_FLAG) == 0 ) ) { - - unsigned init_flush_flags = H5AC__NO_FLAGS_SET; - - if ( ( (flags & H5AC__FLUSH_MARKED_ENTRIES_FLAG) != 0 ) && - ( (flags & H5AC__FLUSH_INVALIDATE_FLAG) == 0 ) ) { - - init_flush_flags |= H5AC__FLUSH_MARKED_ENTRIES_FLAG; - } - - aux_ptr->write_permitted = TRUE; - - status = H5C_flush_cache(f, - H5AC_noblock_dxpl_id, - H5AC_noblock_dxpl_id, - f->shared->cache, - init_flush_flags); - - aux_ptr->write_permitted = FALSE; - - if ( status < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.") - } - - if ( aux_ptr->write_done != NULL ) { - - (aux_ptr->write_done)(); - } - - } /* end if ( aux_ptr->mpi_rank == 0 ) */ - - status = H5AC_propagate_flushed_and_still_clean_entries_list(f, - H5AC_noblock_dxpl_id, - f->shared->cache, - FALSE); - } /* end if ( aux_ptr != NULL ) */ + /* Attempt to flush all entries from rank 0 & Bcast clean list to other ranks */ + if(H5AC_flush_entries(f) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.") #endif /* H5_HAVE_PARALLEL */ - status = H5C_flush_cache(f, - dxpl_id, - H5AC_noblock_dxpl_id, - f->shared->cache, - flags); - - if ( status < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush entry.") - } + /* Flush the cache */ + if(H5C_flush_cache(f, dxpl_id, H5AC_noblock_dxpl_id, f->shared->cache, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush cache.") done: - #if H5AC__TRACE_FILE_ENABLED - if ( trace_file_ptr != NULL ) { - + if(trace_file_ptr != NULL) HDfprintf(trace_file_ptr, "%s %d\n", trace, (int)ret_value); - } #endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_LEAVE_NOAPI(ret_value) - } /* H5AC_flush() */ @@ -4762,5 +4614,89 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5AC_receive_and_apply_clean_list() */ + + +/*------------------------------------------------------------------------- + * Function: H5AC_flush_entries + * + * Purpose: Flush the metadata cache associated with the specified file, + * only writing from rank 0, but propagating the cleaned entries + * to all ranks. + * + * Return: Non-negative on success/Negative on failure if there was a + * request to flush all items and something was protected. + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Aug 22 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_flush_entries(H5F_t *f) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5AC_flush_entries) + + HDassert(f); + HDassert(f->shared->cache); + + /* Check if we have >1 ranks */ + if(f->shared->cache->aux_ptr) { + H5AC_aux_t * aux_ptr = f->shared->cache->aux_ptr; + int mpi_code; + +#if H5AC_DEBUG_DIRTY_BYTES_CREATION + HDfprintf(stdout, + "%d::H5AC_flush: (u/uu/i/iu/r/ru) = %d/%d/%d/%d/%d/%d\n", + (int)(aux_ptr->mpi_rank), + (int)(aux_ptr->unprotect_dirty_bytes), + (int)(aux_ptr->unprotect_dirty_bytes_updates), + (int)(aux_ptr->insert_dirty_bytes), + (int)(aux_ptr->insert_dirty_bytes_updates), + (int)(aux_ptr->rename_dirty_bytes), + (int)(aux_ptr->rename_dirty_bytes_updates)); +#endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */ + + /* to prevent "messages from the future" we must synchronize all + * processes before we start the flush. Hence the following + * barrier. + */ + if(MPI_SUCCESS != (mpi_code = MPI_Barrier(aux_ptr->mpi_comm))) + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code) + + /* Flush data to disk, from rank 0 process */ + if(aux_ptr->mpi_rank == 0 ) { + herr_t status; + + aux_ptr->write_permitted = TRUE; + + status = H5C_flush_cache(f, + H5AC_noblock_dxpl_id, + H5AC_noblock_dxpl_id, + f->shared->cache, + H5AC__NO_FLAGS_SET); + + aux_ptr->write_permitted = FALSE; + + if(status < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush.") + + if(aux_ptr->write_done != NULL) + (aux_ptr->write_done)(); + } /* end if ( aux_ptr->mpi_rank == 0 ) */ + + /* Propagate cleaned entries to other ranks */ + if(H5AC_propagate_flushed_and_still_clean_entries_list(f, + H5AC_noblock_dxpl_id, + f->shared->cache, + FALSE) < 0 ) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't propagate clean entries list.") + } /* end if ( aux_ptr != NULL ) */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC_flush_entries() */ #endif /* H5_HAVE_PARALLEL */ diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 1459e05..f28783d 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -320,7 +320,7 @@ H5_DLL herr_t H5AC_unpin_entry(H5F_t * f, H5_DLL herr_t H5AC_unprotect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *thing, unsigned flags); -H5_DLL herr_t H5AC_flush(H5F_t *f, hid_t dxpl_id, unsigned flags); +H5_DLL herr_t H5AC_flush(H5F_t *f, hid_t dxpl_id); H5_DLL herr_t H5AC_mark_pinned_entry_dirty(H5F_t * f, void * thing, hbool_t size_changed, diff --git a/src/H5C.c b/src/H5C.c index 68b20a5..df13fb6 100644 --- a/src/H5C.c +++ b/src/H5C.c @@ -3445,10 +3445,6 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr, * Programmer: John Mainzer * 6/2/04 * - * Modifications: - * - * None. - * *------------------------------------------------------------------------- */ herr_t @@ -3461,21 +3457,20 @@ H5C_dest(H5F_t * f, FUNC_ENTER_NOAPI(H5C_dest, FAIL) - HDassert( cache_ptr ); - HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); - HDassert( cache_ptr->skip_file_checks || f ); - - if ( H5C_flush_cache(f, primary_dxpl_id, secondary_dxpl_id, - cache_ptr, H5C__FLUSH_INVALIDATE_FLAG) < 0 ) { + /* Sanity check */ + HDassert(cache_ptr); + HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); + HDassert(cache_ptr->skip_file_checks || f); + /* Flush and invalidate all cache entries */ + if(H5C_flush_invalidate_cache(f, primary_dxpl_id, secondary_dxpl_id, + cache_ptr, H5C__NO_FLAGS_SET) < 0 ) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") - } - - if ( cache_ptr->slist_ptr != NULL ) { + if(cache_ptr->slist_ptr != NULL) { H5SL_close(cache_ptr->slist_ptr); cache_ptr->slist_ptr = NULL; - } + } /* end if */ cache_ptr->magic = 0; @@ -3483,66 +3478,10 @@ H5C_dest(H5F_t * f, done: FUNC_LEAVE_NOAPI(ret_value) - } /* H5C_dest() */ /*------------------------------------------------------------------------- - * Function: H5C_dest_empty - * - * Purpose: Destroy an empty cache. - * - * This function fails if the cache is not empty on entry. - * - * Note that *cache_ptr has been freed upon successful return. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: John Mainzer - * 6/2/04 - * - * Modifications: - * - * None. - * - *------------------------------------------------------------------------- - */ -herr_t -H5C_dest_empty(H5C_t * cache_ptr) -{ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5C_dest_empty, FAIL) - - /* This would normally be an assert, but we need to use an HGOTO_ERROR - * call to shut up the compiler. - */ - if ( ( ! cache_ptr ) || - ( cache_ptr->magic != H5C__H5C_T_MAGIC ) || - ( cache_ptr->index_len != 0 ) ) { - - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "Bad cache_ptr or non-empty cache on entry.") - } - - - if ( cache_ptr->slist_ptr != NULL ) { - - H5SL_close(cache_ptr->slist_ptr); - cache_ptr->slist_ptr = NULL; - } - - cache_ptr->magic = 0; - - (void)H5FL_FREE(H5C_t, cache_ptr); - -done: - FUNC_LEAVE_NOAPI(ret_value) - -} /* H5C_dest_empty() */ - - -/*------------------------------------------------------------------------- * * Function: H5C_expunge_entry * @@ -9890,7 +9829,6 @@ H5C_flush_invalidate_cache(H5F_t * f, { herr_t status; herr_t ret_value = SUCCEED; - hbool_t done = FALSE; hbool_t first_flush = TRUE; int32_t protected_entries = 0; int32_t i; @@ -9966,7 +9904,7 @@ H5C_flush_invalidate_cache(H5F_t * f, cur_pel_len = cache_ptr->pel_len; old_pel_len = cache_ptr->pel_len; - while ( ! done ) + while ( cache_ptr->index_len > 0 ) { /* first, try to flush-destroy any dirty entries. Do this by * making a scan through the slist. Note that new dirty entries @@ -10082,12 +10020,10 @@ H5C_flush_invalidate_cache(H5F_t * f, /* increment node pointer now, before we delete its target * from the slist. */ - node_ptr = H5SL_next(node_ptr); if ( node_ptr != NULL ) { next_entry_ptr = (H5C_cache_entry_t *)H5SL_item(node_ptr); - if ( next_entry_ptr == NULL ) { HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ "next_entry_ptr == NULL 2 ?!?!"); @@ -10333,24 +10269,21 @@ H5C_flush_invalidate_cache(H5F_t * f, HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ "Maximum passes on flush exceeded.") } - - if ( cache_ptr->index_len <= 0 ) { - - done = TRUE; - HDassert( cache_ptr->index_size == 0 ); - HDassert( cache_ptr->clean_index_size == 0 ); - HDassert( cache_ptr->dirty_index_size == 0 ); - HDassert( cache_ptr->slist_len == 0 ); - HDassert( cache_ptr->slist_size == 0 ); - HDassert( cache_ptr->pel_len == 0 ); - HDassert( cache_ptr->pel_size == 0 ); - HDassert( cache_ptr->pl_len == 0 ); - HDassert( cache_ptr->pl_size == 0 ); - HDassert( cache_ptr->LRU_list_len == 0 ); - HDassert( cache_ptr->LRU_list_size == 0 ); - } } /* main while loop */ + /* Invariants, after destroying all entries in the hash table */ + HDassert( cache_ptr->index_size == 0 ); + HDassert( cache_ptr->clean_index_size == 0 ); + HDassert( cache_ptr->dirty_index_size == 0 ); + HDassert( cache_ptr->slist_len == 0 ); + HDassert( cache_ptr->slist_size == 0 ); + HDassert( cache_ptr->pel_len == 0 ); + HDassert( cache_ptr->pel_size == 0 ); + HDassert( cache_ptr->pl_len == 0 ); + HDassert( cache_ptr->pl_size == 0 ); + HDassert( cache_ptr->LRU_list_len == 0 ); + HDassert( cache_ptr->LRU_list_size == 0 ); + HDassert( protected_entries <= cache_ptr->pl_len ); diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index b3c16eb..47c6e7a 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -973,8 +973,6 @@ H5_DLL herr_t H5C_dest(H5F_t * f, hid_t secondary_dxpl_id, H5C_t * cache_ptr); -H5_DLL herr_t H5C_dest_empty(H5C_t * cache_ptr); - H5_DLL herr_t H5C_expunge_entry(H5F_t * f, hid_t primary_dxpl_id, hid_t secondary_dxpl_id, diff --git a/src/H5F.c b/src/H5F.c index 4212d6e..e74b047 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -71,8 +71,6 @@ static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_hand static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf); static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id); -static herr_t H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope); -static herr_t H5F_flush_real(H5F_t *f, hid_t dxpl_id, hbool_t closing); static herr_t H5F_close(H5F_t *f); /* Declare a free list to manage the H5F_t struct */ @@ -1021,11 +1019,22 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) H5AC_stats(f); #endif /* H5AC_DUMP_STATS_ON_CLOSE */ - /* Flush all caches and indicate we are closing the file */ - /* (The caches should already be clean and we should just be invalidating objects) */ - if(H5F_flush_real(f, dxpl_id, TRUE) < 0) + /* Shutdown file free space manager(s) */ + /* (We should release the free space information now (before truncating + * the file and before the metadata cache is shut down) since the + * free space manager is holding some data structures in memory + * and also because releasing free space can shrink the file's + * 'eoa' value) + */ + if(H5MF_close(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") + + /* Unpin the superblock, since we're about to destroy the cache */ + if(H5AC_unpin_entry(f, f->shared->sblock) < 0) /* Push error, but keep going*/ - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") + f->shared->sblock = NULL; } /* end if */ /* Remove shared file struct from list of open files */ @@ -1033,6 +1042,11 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + /* Shutdown the metadata cache */ + if(H5AC_dest(f, dxpl_id)) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + /* * Do not close the root group since we didn't count it, but free * the memory associated with it. @@ -1051,10 +1065,7 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) } /* end if */ /* Destroy other components of the file */ - if(H5AC_dest(f, dxpl_id)) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - if(H5F_accum_reset(f) < 0) + if(H5F_accum_reset(f, dxpl_id) < 0) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") if(H5FO_dest(f) < 0) @@ -1603,12 +1614,21 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) * Nothing to do if the file is read only. This determination is * made at the shared open(2) flags level, implying that opening a * file twice, once for read-only and once for read-write, and then - * calling H5F_flush() with the read-only handle, still causes data + * calling H5Fflush() with the read-only handle, still causes data * to be flushed. */ if(H5F_ACC_RDWR & f->shared->flags) { - if(H5F_flush(f, H5AC_dxpl_id, scope) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "flush failed") + /* Flush other files, depending on scope */ + if(H5F_SCOPE_GLOBAL == scope) { + /* Call the flush routine for mounted file hierarchies */ + if(H5F_flush_mounts(f, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy") + } /* end if */ + else { + /* Call the flush routine, for this file */ + if(H5F_flush(f, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") + } /* end else */ } /* end if */ done: @@ -1619,63 +1639,7 @@ done: /*------------------------------------------------------------------------- * Function: H5F_flush * - * Purpose: Flushes (and optionally invalidates) cached data, possibly - * in all mounted files, depending on the SCOPE. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 29 1997 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope) -{ - unsigned nerrors = 0; /* Errors from nested flushes */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5F_flush) - - /* Sanity check arguments */ - HDassert(f); - - /* Flush other files, depending on scope */ - if(H5F_SCOPE_GLOBAL == scope) { - /* Find the top file in the mount hierarchy */ - while(f->parent) - f = f->parent; - - /* Switch to 'down' scope for further flushing */ - scope = H5F_SCOPE_DOWN; - } /* end while */ - if(H5F_SCOPE_DOWN == scope) { - unsigned u; /* Index variable */ - - /* Flush all child files, not stopping for errors */ - for(u = 0; u < f->shared->mtab.nmounts; u++) - if(H5F_flush(f->shared->mtab.child[u].file, dxpl_id, scope) < 0) - nerrors++; - } /* end if */ - - /* Call the "real" flush routine, for this file */ - if(H5F_flush_real(f, dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") - - /* Check flush errors for children - errors are already on the stack */ - if(nerrors) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's child mounts") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_flush() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_flush_real - * - * Purpose: Flushes (and optionally invalidates) cached data. + * Purpose: Flushes cached data. * * Return: Non-negative on success/Negative on failure * @@ -1685,76 +1649,49 @@ done: * *------------------------------------------------------------------------- */ -static herr_t -H5F_flush_real(H5F_t *f, hid_t dxpl_id, hbool_t closing) +herr_t +H5F_flush(H5F_t *f, hid_t dxpl_id) { - unsigned H5AC_flags = H5AC__NO_FLAGS_SET; /* Flags for H5AC_flush() */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5F_flush_real) + FUNC_ENTER_NOAPI(H5F_flush, FAIL) /* Sanity check arguments */ HDassert(f); - /* If we will be closing the file, we don't need to flush the dataset info */ - if(!closing) { - /* Flush any cached dataset storage raw data */ - if(H5D_flush(f, dxpl_id) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache") - } /* end if */ + /* Flush any cached dataset storage raw data */ + if(H5D_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache") - /* If we will be closing the file, we should release the free space - * information now (needs to happen before truncating the file and - * before the metadata cache is shut down, since the free space manager is - * holding some data structures in memory and also because releasing free - * space can shrink the file's 'eoa' value) + /* Release any space allocated to space aggregators, so that the eoa value + * corresponds to the end of the space written to in the file. */ - if(closing) { - /* Shutdown file free space manager(s) */ - if(H5MF_close(f, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") - } /* end if */ - else { - /* Release any space allocated to space aggregators, so that the eoa value - * corresponds to the end of the space written to in the file. - */ - /* (needs to happen before superblock write, since the 'eoa' value is - * written in superblock -QAK) - */ - if(H5MF_free_aggrs(f, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") - } /* end else */ + /* (needs to happen before cache flush, with superblock write, since the + * 'eoa' value is written in superblock -QAK) + */ + if(H5MF_free_aggrs(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") - /* Flush (and invalidate, if requested) the entire metadata cache */ - if(closing) { - H5AC_flags |= H5AC__FLUSH_INVALIDATE_FLAG; + /* Flush the entire metadata cache */ + if(H5AC_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache") - /* Unpin the superblock, since we're about to destroy the cache */ - if(H5AC_unpin_entry(f, f->shared->sblock) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") - f->shared->sblock = NULL; - } /* end if */ - if(H5AC_flush(f, dxpl_id, H5AC_flags) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache") - - /* If we will be closing the file, we don't need to flush the accumulator info */ - if(!closing) { - /* Flush out the metadata accumulator */ - if(H5F_accum_flush(f, dxpl_id) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator") - } /* end if */ + /* Flush out the metadata accumulator */ + if(H5F_accum_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator") - /* If we will be closing the file, we don't need to flush file buffers */ - if(!closing) { - /* Flush file buffers to disk. */ - if(H5FD_flush(f->shared->lf, dxpl_id, closing) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed") - } /* end if */ + /* Flush file buffers to disk. */ + if(H5FD_flush(f->shared->lf, dxpl_id, FALSE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_flush_real() */ +} /* end H5F_flush() */ /*------------------------------------------------------------------------- @@ -1960,7 +1897,7 @@ H5F_try_close(H5F_t *f) */ if(f->intent&H5F_ACC_RDWR) { /* Flush all caches */ - if(H5F_flush_real(f, H5AC_dxpl_id, FALSE) < 0) + if(H5F_flush(f, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") } /* end if */ diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 9ecb6f5..40b014c 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -482,33 +482,33 @@ done: * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * Robb Matzke, 1999-10-19 - * The contents of memory are written to the backing store if - * one is open. *------------------------------------------------------------------------- */ static herr_t H5FD_core_close(H5FD_t *_file) { H5FD_core_t *file = (H5FD_core_t*)_file; - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5FD_core_close, FAIL) + /* Flush any changed buffers */ + if(H5FD_core_flush(_file, (hid_t)-1, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") + /* Release resources */ - if (file->fd>=0) + if(file->fd >= 0) HDclose(file->fd); - if (file->name) + if(file->name) H5MM_xfree(file->name); - if (file->mem) + if(file->mem) H5MM_xfree(file->mem); HDmemset(file, 0, sizeof(H5FD_core_t)); H5MM_xfree(file); done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_core_close() */ /*------------------------------------------------------------------------- @@ -971,7 +971,7 @@ H5FD_core_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) new_eof += file->increment; /* Extend the file to make sure it's large enough */ - if(!H5F_addr_eq((haddr_t)new_eof, file->eof)) { + if(!H5F_addr_eq(file->eof, (haddr_t)new_eof)) { unsigned char *x; /* Pointer to new buffer for file data */ /* (Re)allocate memory for the file buffer */ diff --git a/src/H5Faccum.c b/src/H5Faccum.c index d4e142b..d8b9820 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -722,13 +722,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_accum_reset(H5F_t *f) +H5F_accum_reset(H5F_t *f, hid_t dxpl_id) { - FUNC_ENTER_NOAPI_NOFUNC(H5F_accum_reset) + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5F_accum_reset, FAIL) HDassert(f); HDassert(f->shared); + /* Flush any dirty data in accumulator */ + if(H5F_accum_flush(f, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "can't flush metadata accumulator") + /* Check if we need to reset the metadata accumulator information */ if(f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) { /* Sanity check */ @@ -744,7 +750,7 @@ H5F_accum_reset(H5F_t *f) f->shared->accum.dirty = FALSE; } /* end if */ - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_accum_reset() */ - diff --git a/src/H5Fmount.c b/src/H5Fmount.c index ff4b1eb..f70a7c6 100644 --- a/src/H5Fmount.c +++ b/src/H5Fmount.c @@ -627,3 +627,80 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_mount_count_ids() */ + +/*------------------------------------------------------------------------- + * Function: H5F_flush_mounts_recurse + * + * Purpose: Flush a mount hierarchy, recursively + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Fri, August 21, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_flush_mounts_recurse(H5F_t *f, hid_t dxpl_id) +{ + unsigned nerrors = 0; /* Errors from recursive flushes */ + unsigned u; /* Index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_flush_mounts_recurse) + + /* Sanity check */ + HDassert(f); + + /* Flush all child files, not stopping for errors */ + for(u = 0; u < f->shared->mtab.nmounts; u++) + if(H5F_flush_mounts_recurse(f->shared->mtab.child[u].file, dxpl_id) < 0) + nerrors++; + + /* Call the "real" flush routine, for this file */ + if(H5F_flush(f, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") + + /* Check flush errors for children - errors are already on the stack */ + if(nerrors) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's child mounts") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_flush_mounts_recurse() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_flush_mounts + * + * Purpose: Flush a mount hierarchy + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Fri, August 21, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_flush_mounts(H5F_t *f, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5F_flush_mounts, FAIL) + + /* Sanity check */ + HDassert(f); + + /* Find the top file in the mount hierarchy */ + while(f->parent) + f = f->parent; + + /* Flush the mounted file hierarchy */ + if(H5F_flush_mounts_recurse(f, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_flush_mounts() */ + diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index e962977..c38d683 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -288,11 +288,13 @@ H5_DLLVAR const H5AC_class_t H5AC_SUPERBLOCK[1]; /* General routines */ H5_DLL herr_t H5F_init(void); H5_DLL haddr_t H5F_locate_signature(H5FD_t *file, hid_t dxpl_id); +H5_DLL herr_t H5F_flush(H5F_t *f, hid_t dxpl_id); /* File mount related routines */ H5_DLL herr_t H5F_close_mounts(H5F_t *f); H5_DLL int H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void *key); H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs); +H5_DLL herr_t H5F_flush_mounts(H5F_t *f, hid_t dxpl_id); /* Superblock related routines */ H5_DLL herr_t H5F_super_init(H5F_t *f, hid_t dxpl_id); @@ -313,7 +315,7 @@ H5_DLL htri_t H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, H5_DLL herr_t H5F_accum_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, hsize_t size); H5_DLL herr_t H5F_accum_flush(H5F_t *f, hid_t dxpl_id); -H5_DLL herr_t H5F_accum_reset(H5F_t *f); +H5_DLL herr_t H5F_accum_reset(H5F_t *f, hid_t dxpl_id); /* Shared file list related routines */ H5_DLL herr_t H5F_sfile_add(H5F_file_t *shared); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index e23ad2d..20814b6 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -79,8 +79,7 @@ /* The difference between a single file and a set of mounted files */ typedef enum H5F_scope_t { H5F_SCOPE_LOCAL = 0, /*specified file handle only */ - H5F_SCOPE_GLOBAL = 1, /*entire virtual file */ - H5F_SCOPE_DOWN = 2 /*for internal use only */ + H5F_SCOPE_GLOBAL = 1 /*entire virtual file */ } H5F_scope_t; /* Unlimited file size for H5Pset_external() */ diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c index 01514e0..46a05c5 100644 --- a/src/H5Fsuper_cache.c +++ b/src/H5Fsuper_cache.c @@ -726,7 +726,9 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F_sup H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t); if(driver_size > 0) { H5O_drvinfo_t drvinfo; /* Driver info */ + H5O_loc_t ext_loc; /* "Object location" for superblock extension */ uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Driver info block encoding buffer */ + htri_t status; /* Indicate whether the message exists or not */ /* Sanity check */ HDassert(driver_size <= H5F_MAX_DRVINFOBLOCK_SIZE); @@ -734,12 +736,20 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5F_sup /* Encode driver-specific data */ if(H5FD_sb_encode(f->shared->lf, drvinfo.name, dbuf) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information") + + /* Open the superblock extension's object header */ + if(H5F_super_ext_open(f, sblock->ext_addr, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension") /* Write driver info information to the superblock extension */ drvinfo.len = driver_size; drvinfo.buf = dbuf; - if(H5F_super_ext_write_msg(f, dxpl_id, &drvinfo, H5O_DRVINFO_ID, FALSE) < 0) + if(H5O_msg_write(&ext_loc, H5O_DRVINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &drvinfo, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "unable to update driver info header message") + + /* Close the superblock extension object header */ + if(H5F_super_ext_close(f, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close file's superblock extension") } /* end if */ } /* end if */ } /* end if */ diff --git a/src/H5trace.c b/src/H5trace.c index 172a7f7..5f1e128 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -674,10 +674,6 @@ H5_trace (const double *returning, const char *func, const char *type, ...) case H5F_SCOPE_GLOBAL: fprintf(out, "H5F_SCOPE_GLOBAL"); break; - case H5F_SCOPE_DOWN: - fprintf(out, "H5F_SCOPE_DOWN " - "/*FOR INTERNAL USE ONLY!*/"); - break; default: fprintf(out, "%ld", (long)scope); break; diff --git a/test/ohdr.c b/test/ohdr.c index 905551d..df5f63b 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -60,8 +60,8 @@ test_cont(char *filename, hid_t fapl) H5O_info_t oinfo; H5O_loc_t oh_locA, oh_locB; time_t time_new; - char *short_name = "T"; - char *long_name = "This is the message"; + const char *short_name = "T"; + const char *long_name = "This is the message"; size_t nchunks; TESTING("object header continuation block"); @@ -100,7 +100,9 @@ test_cont(char *filename, hid_t fapl) if(H5O_msg_create(&oh_locA, H5O_NAME_ID, 0, 0, &short_name, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_locA.addr, H5AC__NO_FLAGS_SET) < 0) FAIL_STACK_ERROR if(H5O_get_info(&oh_locA, H5P_DATASET_XFER_DEFAULT, FALSE, &oinfo) < 0) @@ -210,7 +212,9 @@ main(void) time_new = 11111111; if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) FAIL_STACK_ERROR if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) FAIL_STACK_ERROR @@ -226,7 +230,9 @@ main(void) time_new = 33333333; if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) FAIL_STACK_ERROR if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) FAIL_STACK_ERROR @@ -255,7 +261,9 @@ main(void) if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR } /* end for */ - if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) FAIL_STACK_ERROR /* Make certain that chunk #0 in the object header will be encoded with a 2-byte size */ @@ -294,7 +302,9 @@ main(void) time_new = (i + 1) * 1000 + 10; if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) FAIL_STACK_ERROR } /* end for */ PASSED(); @@ -322,7 +332,9 @@ main(void) time_new = 22222222; if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0) FAIL_STACK_ERROR - if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT, TRUE) < 0) + if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0) FAIL_STACK_ERROR if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT)) FAIL_STACK_ERROR diff --git a/test/tsohm.c b/test/tsohm.c index 348677d..b5b489b 100644 --- a/test/tsohm.c +++ b/test/tsohm.c @@ -544,8 +544,12 @@ error: static hid_t close_reopen_file(hid_t file, const char* filename, hid_t fapl_id) { - if(H5Fclose(file) < 0) goto error; - return H5Fopen(filename, H5F_ACC_RDWR, fapl_id); + hid_t fid; + + if(H5Fclose(file) < 0) FAIL_STACK_ERROR + if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl_id)) < 0) FAIL_STACK_ERROR + + return(fid); error: return -1; @@ -598,19 +602,19 @@ size1_helper(hid_t file, const char* filename, hid_t fapl_id, int test_file_clos dim1[0] = 1; if((space_id=H5Screate_simple(1,dim1,NULL)) < 0) TEST_ERROR - if((dset_id = H5Dcreate2(file,DSETNAME[0],dtype1_id,space_id,H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR + if((dset_id = H5Dcreate2(file,DSETNAME[0],dtype1_id,space_id,H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR /* Test writing and reading */ - if(H5Dwrite(dset_id,dtype1_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,&wdata) < 0) TEST_ERROR + if(H5Dwrite(dset_id,dtype1_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,&wdata) < 0) FAIL_STACK_ERROR - if(H5Dread(dset_id,dtype1_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,&rdata) < 0) TEST_ERROR + if(H5Dread(dset_id,dtype1_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,&rdata) < 0) FAIL_STACK_ERROR if(rdata.i1!=wdata.i1 || rdata.i2!=wdata.i2 || HDstrcmp(rdata.str, wdata.str)) { H5_FAILED(); AT(); printf("incorrect read data\n"); goto error; } /* end if */ - if(H5Dclose(dset_id) < 0) TEST_ERROR + if(H5Dclose(dset_id) < 0) FAIL_STACK_ERROR /* Close and re-open the file if requested*/ if(test_file_closing) { @@ -618,8 +622,8 @@ size1_helper(hid_t file, const char* filename, hid_t fapl_id, int test_file_clos } /* Create more datasets with the same datatype */ - if((dset_id = H5Dcreate2(file,DSETNAME[1],dtype1_id,space_id,H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR - if(H5Dclose(dset_id) < 0) TEST_ERROR + if((dset_id = H5Dcreate2(file,DSETNAME[1],dtype1_id,space_id,H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if(H5Dclose(dset_id) < 0) FAIL_STACK_ERROR /* Close and re-open the file if requested*/ if(test_file_closing) { diff --git a/testpar/t_cache.c b/testpar/t_cache.c index f8ecefa..aa6a7ed 100644 --- a/testpar/t_cache.c +++ b/testpar/t_cache.c @@ -5448,7 +5448,7 @@ trace_file_check(void) "H5AC_unpin_entry 4 0\n", "H5AC_rename 0 8a65 15 0\n", "H5AC_rename 8a65 0 15 0\n", - "H5AC_flush 0x0 0\n", + "H5AC_flush 0\n", NULL }; char buffer[256]; -- cgit v0.12