diff options
author | Larry Knox <lrknox@hdfgroup.org> | 2018-03-13 18:04:03 (GMT) |
---|---|---|
committer | Larry Knox <lrknox@hdfgroup.org> | 2018-03-13 18:04:03 (GMT) |
commit | f30873136be7cb444166d019c57d3508ff79fc76 (patch) | |
tree | 559406eb3860a27fe1bfc6fcc7b5febe8454cba7 /src | |
parent | 8a77c7a3e4cd49cc0de824476b04b4926582e1ed (diff) | |
parent | 9247388c3d14510341ea3f07847ce2cbb6e44a8e (diff) | |
download | hdf5-f30873136be7cb444166d019c57d3508ff79fc76.zip hdf5-f30873136be7cb444166d019c57d3508ff79fc76.tar.gz hdf5-f30873136be7cb444166d019c57d3508ff79fc76.tar.bz2 |
Merge pull request #943 in HDFFV/hdf5 from develop to hdf5_1_10
* commit '9247388c3d14510341ea3f07847ce2cbb6e44a8e':
Rework new tests into one macro
Added a "won't fix" RELEASE.txt entry for HDFFV-10356.
Fix CMake test names
Fixed typo
Add release note for HDFFFV-10397.
Added a fix for HDFFV-10358.
Fixed documentation Description: - Updated the description of copy constructor for clarification. - Removed unnecessary comments. Platforms tested: Linux/64 (jelly)
Enhancement to the tool h5clear (HDFFV-10360)
Fix for HDFFV-10209 VDS SWMR test failure Free the object header when there are chksum retries.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5F.c | 94 | ||||
-rw-r--r-- | src/H5Fint.c | 41 | ||||
-rw-r--r-- | src/H5Fpkg.h | 3 | ||||
-rw-r--r-- | src/H5Fprivate.h | 4 | ||||
-rw-r--r-- | src/H5Fpublic.h | 2 | ||||
-rw-r--r-- | src/H5Fsuper.c | 112 | ||||
-rw-r--r-- | src/H5Gcache.c | 3 | ||||
-rw-r--r-- | src/H5Gent.c | 7 | ||||
-rw-r--r-- | src/H5Gpkg.h | 2 | ||||
-rw-r--r-- | src/H5Ocache.c | 39 | ||||
-rw-r--r-- | src/H5Oint.c | 1 | ||||
-rw-r--r-- | src/H5Opkg.h | 1 | ||||
-rw-r--r-- | src/H5Pfapl.c | 21 |
13 files changed, 281 insertions, 49 deletions
@@ -845,8 +845,6 @@ herr_t H5Fget_filesize(hid_t file_id, hsize_t *size) { H5F_t *file; /* File object for file ID */ - haddr_t eof; /* End of file address */ - haddr_t eoa; /* End of allocation address */ haddr_t max_eof_eoa; /* Maximum of the EOA & EOF */ haddr_t base_addr; /* Base address for the file */ herr_t ret_value = SUCCEED; /* Return value */ @@ -859,11 +857,9 @@ H5Fget_filesize(hid_t file_id, hsize_t *size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Go get the actual file size */ - eof = H5FD_get_eof(file->shared->lf, H5FD_MEM_DEFAULT); - eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT); - max_eof_eoa = MAX(eof, eoa); - if(HADDR_UNDEF == max_eof_eoa) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file get eof/eoa requests failed") + if(H5F__get_max_eof_eoa(file, &max_eof_eoa) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") + base_addr = H5FD_get_base_addr(file->shared->lf); if(size) @@ -1949,3 +1945,87 @@ done: FUNC_LEAVE_API(ret_value) } /* H5Fget_mdc_image_info() */ + +/*------------------------------------------------------------------------- + * Function: H5Fget_eoa + * + * Purpose: Returns the address of the first byte after the last + * allocated memory in the file. + * (See H5FDget_eoa() in H5FD.c) + * + * Return: Success: First byte after allocated memory. + * Failure: HADDR_UNDEF + * + * Return: Non-negative on success/Negative on errors + *------------------------------------------------------------------------- + */ +herr_t +H5Fget_eoa(hid_t file_id, haddr_t *eoa) +{ + H5F_t *file; /* File object for file ID */ + haddr_t rel_eoa; /* Relative address of EOA */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*a", file_id, eoa); + + /* Check args */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + + /* This public routine will work only for drivers with this feature enabled.*/ + /* We might introduce a new feature flag in the future */ + if(!H5F_HAS_FEATURE(file, H5FD_FEAT_SUPPORTS_SWMR_IO)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must use a SWMR-compatible VFD for this public routine") + + /* The real work */ + if(HADDR_UNDEF == (rel_eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get_eoa request failed") + + /* (Note compensating for base address subtraction in internal routine) */ + if(eoa) + *eoa = rel_eoa + H5FD_get_base_addr(file->shared->lf); +done: + FUNC_LEAVE_API(ret_value) +} /* H5Fget_eoa() */ + + +/*------------------------------------------------------------------------- + * Function: H5Fincrement_filesize + * + * Purpose: Set the EOA for the file to the maximum of (EOA, EOF) + increment + * + * Return: Non-negative on success/Negative on errors + *------------------------------------------------------------------------- + */ +herr_t +H5Fincrement_filesize(hid_t file_id, hsize_t increment) +{ + H5F_t *file; /* File object for file ID */ + haddr_t max_eof_eoa; /* Maximum of the relative EOA & EOF */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ih", file_id, increment); + + /* Check args */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID") + + /* This public routine will work only for drivers with this feature enabled.*/ + /* We might introduce a new feature flag in the future */ + if(!H5F_HAS_FEATURE(file, H5FD_FEAT_SUPPORTS_SWMR_IO)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "must use a SWMR-compatible VFD for this public routine") + + /* Get the maximum of EOA and EOF */ + if(H5F__get_max_eof_eoa(file, &max_eof_eoa) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ") + + /* Set EOA to the maximum value + increment */ + /* H5FD_set_eoa() will add base_addr to max_eof_eoa */ + if(H5FD_set_eoa(file->shared->lf, H5FD_MEM_DEFAULT, max_eof_eoa + increment) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set_eoa request failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Fincrement_filesize() */ diff --git a/src/H5Fint.c b/src/H5Fint.c index cc5931a..24844a4 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -124,7 +124,6 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ hbool_t driver_prop_copied = FALSE; /* Whether the driver property has been set up */ unsigned efc_size = 0; - hbool_t latest_format = FALSE; /* Always use the latest format? */ hid_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -820,7 +819,6 @@ H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t else { H5P_genplist_t *plist; /* Property list */ unsigned efc_size; /* External file cache size */ - hbool_t latest_format; /* Always use the latest format? */ size_t u; /* Local index variable */ HDassert(lf != NULL); @@ -1602,7 +1600,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, } /* end if */ else if (1 == shared->nrefs) { /* Read the superblock if it hasn't been read before. */ - if(H5F__super_read(file, meta_dxpl_id, raw_dxpl_id, TRUE) < 0) + if(H5F__super_read(file, meta_dxpl_id, raw_dxpl_id, fapl_id, TRUE) < 0) HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") /* Create the page buffer before initializing the superblock */ @@ -2921,6 +2919,43 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F__set_paged_aggr() */ +/*------------------------------------------------------------------------- + * Function: H5F__get_max_eof_eoa + * + * Purpose: Determine the maximum of (EOA, EOF) for the file + * + * Return: Non-negative on success/Negative on failure + *------------------------------------------------------------------------- + */ +herr_t +H5F__get_max_eof_eoa(const H5F_t *f, haddr_t *max_eof_eoa) +{ + haddr_t eof; /* Relative address for EOF */ + haddr_t eoa; /* Relative address for EOA */ + haddr_t tmp_max; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(f); + HDassert(f->shared); + + /* Get the relative EOA and EOF */ + eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT); + eof = H5FD_get_eof(f->shared->lf, H5FD_MEM_DEFAULT); + + /* Determine the maximum */ + tmp_max = MAX(eof, eoa); + if(HADDR_UNDEF == tmp_max) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file get eof/eoa requests failed") + + *max_eof_eoa = tmp_max; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F__get_max_eof_eoa() */ + #ifdef H5_HAVE_PARALLEL /*------------------------------------------------------------------------- diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index c9aba56..a4c1a24 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -412,7 +412,7 @@ H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nop /* Superblock related routines */ H5_DLL herr_t H5F__super_init(H5F_t *f, hid_t dxpl_id); -H5_DLL herr_t H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, +H5_DLL herr_t H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hid_t fapl_id, hbool_t initial_read); H5_DLL herr_t H5F__super_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_size, hsize_t *super_ext_size); H5_DLL herr_t H5F__super_free(H5F_super_t *sblock); @@ -457,6 +457,7 @@ H5_DLL htri_t H5F_try_extend(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, H5_DLL herr_t H5F__set_eoa(const H5F_t *f, H5F_mem_t type, haddr_t addr); H5_DLL herr_t H5F__set_base_addr(const H5F_t *f, haddr_t addr); H5_DLL herr_t H5F__set_paged_aggr(const H5F_t *f, hbool_t paged); +H5_DLL herr_t H5F__get_max_eof_eoa(const H5F_t *f, haddr_t *max_eof_eoa); /* Functions that flush or evict */ H5_DLL herr_t H5F__evict_cache_entries(H5F_t *f, hid_t dxpl_id); diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index dadbbac..1886c5c 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -492,6 +492,10 @@ typedef struct H5F_t H5F_t; #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_CLEAR_STATUS_FLAGS_NAME "clear_status_flags" /* Whether to clear superblock status_flags (private property only used by h5clear) */ +#define H5F_ACS_NULL_FSM_ADDR_NAME "null_fsm_addr" /* Nullify addresses of free-space managers */ + /* Private property used only by h5clear */ +#define H5F_ACS_SKIP_EOF_CHECK_NAME "skip_eof_check" /* Skip EOF check */ + /* Private property used only by h5clear */ #define H5F_ACS_USE_MDC_LOGGING_NAME "use_mdc_logging" /* Whether to use metadata cache logging */ #define H5F_ACS_MDC_LOG_LOCATION_NAME "mdc_log_location" /* Name of metadata cache log location */ #define H5F_ACS_START_MDC_LOG_ON_ACCESS_NAME "start_mdc_log_on_access" /* Whether logging starts on file create/open */ diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index d333fa7..73c59f5 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -241,6 +241,8 @@ H5_DLL herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist); H5_DLL herr_t H5Funmount(hid_t loc, const char *name); H5_DLL hssize_t H5Fget_freespace(hid_t file_id); H5_DLL herr_t H5Fget_filesize(hid_t file_id, hsize_t *size); +H5_DLL herr_t H5Fget_eoa(hid_t file_id, haddr_t *eoa); +H5_DLL herr_t H5Fincrement_filesize(hid_t file_id, hsize_t increment); H5_DLL ssize_t H5Fget_file_image(hid_t file_id, void * buf_ptr, size_t buf_len); H5_DLL herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t * config_ptr); diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 4250ff0..3db9b2f 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -324,7 +324,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial_read) +H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hid_t fapl_id, hbool_t initial_read) { H5P_genplist_t *dxpl = NULL; /* DXPL object */ H5AC_ring_t ring, orig_ring = H5AC_RING_INV; @@ -337,7 +337,8 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial haddr_t eof; /* End of file address */ unsigned rw_flags; /* Read/write permissions for file */ hbool_t skip_eof_check = FALSE; /* Whether to skip checking the EOF value */ - herr_t ret_value = SUCCEED; /* Return value */ + H5P_genplist_t *a_plist; /* File access property list */ + herr_t ret_value = SUCCEED; /* Return value */ #ifdef H5_HAVE_PARALLEL int mpi_rank = 0, mpi_size = 1; int mpi_result; @@ -595,6 +596,20 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial * as the file can appear truncated if only part of it has been * been flushed to disk by the SWMR writer process. */ + /* The EOF check is also skipped when the private property + * H5F_ACS_SKIP_EOF_CHECK_NAME exists in the fapl. + * This property is enabled by the tool h5clear with these + * two options: (1) --filesize (2) --increment + */ + + /* Check if this private property exists in fapl */ + if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") + if(H5P_exist_plist(a_plist, H5F_ACS_SKIP_EOF_CHECK_NAME) > 0) { + if(H5P_get(a_plist, H5F_ACS_SKIP_EOF_CHECK_NAME, &skip_eof_check) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get clearance for persisting fsm addr") + } + if(H5F_INTENT(f) & H5F_ACC_SWMR_READ) { /* * When the file is opened for SWMR read access, skip the check if: @@ -757,6 +772,7 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial if(status) { H5O_fsinfo_t fsinfo; /* File space info message from superblock extension */ uint8_t flags; /* Message flags */ + hbool_t null_fsm_addr = FALSE; /* Whether to drop free-space to the floor */ /* Get message flags */ if(H5O_msg_get_flags(&ext_loc, H5O_FSINFO_ID, meta_dxpl_id, &flags) < 0) @@ -765,6 +781,13 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial /* If message is NOT marked "unknown"--set up file space info */ if(!(flags & H5O_MSG_FLAG_WAS_UNKNOWN)) { + /* The tool h5clear uses this property to tell the library + to drop free-space to the floor */ + if(H5P_exist_plist(a_plist, H5F_ACS_NULL_FSM_ADDR_NAME) > 0) { + if(H5P_get(a_plist, H5F_ACS_NULL_FSM_ADDR_NAME, &null_fsm_addr) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get clearance for persisting fsm addr") + } + /* Retrieve the 'file space info' structure */ if(NULL == H5O_msg_read(&ext_loc, H5O_FSINFO_ID, &fsinfo, meta_dxpl_id)) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get free-space manager info message") @@ -808,13 +831,30 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial if(f->shared->eoa_pre_fsm_fsalloc != fsinfo.eoa_pre_fsm_fsalloc) f->shared->eoa_pre_fsm_fsalloc = fsinfo.eoa_pre_fsm_fsalloc; - /* f->shared->eoa_pre_fsm_fsalloc must always be HADDR_UNDEF - * in the absence of persistant free space managers. + /* f->shared->eoa_pre_fsm_fsalloc must always be HADDR_UNDEF + * in the absence of persistant free space managers. + */ + /* If the following two conditions are true: + * (1) skipping EOF check (skip_eof_check) + * (2) dropping free-space to the floor (null_fsm_addr) + * skip the asserts as "eoa_pre_fsm_fsalloc" may be undefined + * for a crashed file with persistant free space managers. + * #1 and #2 are enabled when the tool h5clear --increment + * option is used. */ - HDassert((!f->shared->fs_persist) || (f->shared->eoa_pre_fsm_fsalloc != HADDR_UNDEF)); - HDassert(!f->shared->first_alloc_dealloc); + if(!skip_eof_check && !null_fsm_addr) { + HDassert((!f->shared->fs_persist) || (f->shared->eoa_pre_fsm_fsalloc != HADDR_UNDEF)); + HDassert(!f->shared->first_alloc_dealloc); + } - if((f->shared->eoa_pre_fsm_fsalloc != HADDR_UNDEF) && + /* As "eoa_pre_fsm_fsalloc" may be undefined for a crashed file + * with persistant free space managers, therefore, set + * "first_alloc_dealloc" when the condition + * "dropping free-space to the floor is true. + * This will ensure that no action is done to settle things on file + * close via H5MF_settle_meta_data_fsm() and H5MF_settle_raw_data_fsm(). + */ + if((f->shared->eoa_pre_fsm_fsalloc != HADDR_UNDEF || null_fsm_addr) && (H5F_INTENT(f) & H5F_ACC_RDWR)) f->shared->first_alloc_dealloc = TRUE; @@ -822,7 +862,20 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial for(u = 1; u < NELMTS(f->shared->fs_addr); u++) f->shared->fs_addr[u] = fsinfo.fs_addr[u - 1]; - if(fsinfo.mapped && (rw_flags & H5AC__READ_ONLY_FLAG) == 0) { + /* If the following two conditions are true: + * (1) file is persisting free-space + * (2) dropping free-space to the floor (null_fsm_addr) + * nullify the addresses of the FSMs + */ + if(f->shared->fs_persist && null_fsm_addr) { + for(u = 0; u < NELMTS(fsinfo.fs_addr); u++) + f->shared->fs_addr[u] = fsinfo.fs_addr[u] = HADDR_UNDEF; + } + + /* For fsinfo.mapped: remove the FSINFO message from the superblock extension + and write a new message to the extension */ + /* For null_fsm_addr: just update FSINFO message in the superblock extension */ + if(((fsinfo.mapped || null_fsm_addr) && (rw_flags & H5AC__READ_ONLY_FLAG) == 0)) { /* Do the same kluge until we know for sure. VC */ #if 1 /* bug fix test code -- tidy this up if all goes well */ /* JRM */ @@ -836,11 +889,16 @@ H5F__super_read(H5F_t *f, hid_t meta_dxpl_id, hid_t raw_dxpl_id, hbool_t initial f->shared->sblock = sblock; #endif /* JRM */ - if(H5F_super_ext_remove_msg(f, meta_dxpl_id, H5O_FSINFO_ID) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTDELETE, FAIL, "error in removing message from superblock extension") + if(null_fsm_addr) { + if(H5F_super_ext_write_msg(f, meta_dxpl_id, H5O_FSINFO_ID, &fsinfo, FALSE, H5O_MSG_FLAG_MARK_IF_UNKNOWN) < 0) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing fsinfo message to superblock extension") + } else { + if(H5F_super_ext_remove_msg(f, meta_dxpl_id, H5O_FSINFO_ID) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDELETE, FAIL, "error in removing message from superblock extension") - if(H5F_super_ext_write_msg(f, meta_dxpl_id, H5O_FSINFO_ID, &fsinfo, TRUE, H5O_MSG_FLAG_MARK_IF_UNKNOWN) < 0) - HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing fsinfo message to superblock extension") + if(H5F_super_ext_write_msg(f, meta_dxpl_id, H5O_FSINFO_ID, &fsinfo, TRUE, H5O_MSG_FLAG_MARK_IF_UNKNOWN) < 0) + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing fsinfo message to superblock extension") + } #if 1 /* bug fix test code -- tidy this up if all goes well */ /* JRM */ f->shared->sblock = NULL; #endif /* JRM */ @@ -1637,13 +1695,13 @@ H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, unsigned id, void *mesg, /* Open/create the superblock extension object header */ if(H5F_addr_defined(f->shared->sblock->ext_addr)) { - if(H5F_super_ext_open(f, f->shared->sblock->ext_addr, &ext_loc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension") + if(H5F_super_ext_open(f, f->shared->sblock->ext_addr, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open file's superblock extension") } /* end if */ else { HDassert(may_create); - if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to create file's superblock extension") + if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to create file's superblock extension") ext_created = TRUE; } /* end else */ HDassert(H5F_addr_defined(ext_loc.addr)); @@ -1651,24 +1709,24 @@ H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, unsigned id, void *mesg, /* Check if message with ID does not exist in the object header */ if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check object header for message or message exists") + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check object header for message or message exists") /* Check for creating vs. writing */ if(may_create) { - if(status) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "Message should not exist") + if(status) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "Message should not exist") - /* Create the message with ID in the superblock extension */ - if(H5O_msg_create(&ext_loc, id, (mesg_flags | H5O_MSG_FLAG_DONTSHARE), H5O_UPDATE_TIME, mesg, dxpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to create the message in object header") + /* Create the message with ID in the superblock extension */ + if(H5O_msg_create(&ext_loc, id, (mesg_flags | H5O_MSG_FLAG_DONTSHARE), H5O_UPDATE_TIME, mesg, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to create the message in object header") } /* end if */ else { - if(!status) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "Message should exist") + if(!status) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "Message should exist") - /* Update the message with ID in the superblock extension */ - if(H5O_msg_write(&ext_loc, id, (mesg_flags | H5O_MSG_FLAG_DONTSHARE), H5O_UPDATE_TIME, mesg, dxpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to write the message in object header") + /* Update the message with ID in the superblock extension */ + if(H5O_msg_write(&ext_loc, id, (mesg_flags | H5O_MSG_FLAG_DONTSHARE), H5O_UPDATE_TIME, mesg, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to write the message in object header") } /* end else */ done: diff --git a/src/H5Gcache.c b/src/H5Gcache.c index 65115a5..b447cad 100644 --- a/src/H5Gcache.c +++ b/src/H5Gcache.c @@ -170,6 +170,7 @@ H5G__cache_node_deserialize(const void *_image, size_t len, void *_udata, H5F_t *f = (H5F_t *)_udata; /* User data for callback */ H5G_node_t *sym = NULL; /* Symbol table node created */ const uint8_t *image = (const uint8_t *)_image; /* Pointer to image to deserialize */ + const uint8_t *image_end = image + len - 1; /* Pointer to end of image buffer */ void *ret_value = NULL; /* Return value */ FUNC_ENTER_STATIC @@ -203,7 +204,7 @@ H5G__cache_node_deserialize(const void *_image, size_t len, void *_udata, UINT16DECODE(image, sym->nsyms); /* entries */ - if(H5G__ent_decode_vec(f, &image, sym->entry, sym->nsyms) < 0) + if(H5G__ent_decode_vec(f, &image, image_end, sym->entry, sym->nsyms) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "unable to decode symbol table entries") /* Set return value */ diff --git a/src/H5Gent.c b/src/H5Gent.c index 7987850..6e076ae 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -91,7 +91,7 @@ H5FL_BLK_EXTERN(str_buf); *------------------------------------------------------------------------- */ herr_t -H5G__ent_decode_vec(const H5F_t *f, const uint8_t **pp, H5G_entry_t *ent, unsigned n) +H5G__ent_decode_vec(const H5F_t *f, const uint8_t **pp, const uint8_t *p_end, H5G_entry_t *ent, unsigned n) { unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -104,9 +104,12 @@ H5G__ent_decode_vec(const H5F_t *f, const uint8_t **pp, H5G_entry_t *ent, unsign HDassert(ent); /* decode entries */ - for(u = 0; u < n; u++) + for(u = 0; u < n; u++) { + if(*pp > p_end) + HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "ran off the end of the image buffer") if(H5G_ent_decode(f, pp, ent + u) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode") + } done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 76bf08b..20e595f 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -395,7 +395,7 @@ H5_DLL void H5G__ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5_copy_depth_t depth); H5_DLL void H5G__ent_reset(H5G_entry_t *ent); H5_DLL herr_t H5G__ent_decode_vec(const H5F_t *f, const uint8_t **pp, - H5G_entry_t *ent, unsigned n); + const uint8_t *p_end, H5G_entry_t *ent, unsigned n); H5_DLL herr_t H5G__ent_encode_vec(const H5F_t *f, uint8_t **pp, const H5G_entry_t *ent, unsigned n); H5_DLL herr_t H5G__ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 94049ef..2260e12 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -262,12 +262,23 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) uint32_t stored_chksum; /* Stored metadata checksum value */ uint32_t computed_chksum; /* Computed metadata checksum value */ - /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); - - if(stored_chksum != computed_chksum) - ret_value = FALSE; + /* Get stored and computed checksums */ + H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + + if(stored_chksum != computed_chksum) { + /* These fields are not deserialized yet in H5O__prefix_deserialize() */ + HDassert(udata->oh->chunk == NULL); + HDassert(udata->oh->mesg == NULL); + HDassert(udata->oh->proxy == NULL); + + /* Indicate that udata->oh is to be freed later + in H5O__prefix_deserialize() */ + udata->free_oh = TRUE; + ret_value = FALSE; + } /* end if */ } /* end if */ + else + HDassert(!(udata->common.file_intent & H5F_ACC_SWMR_WRITE)); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__cache_verify_chksum() */ @@ -1263,8 +1274,22 @@ H5O__prefix_deserialize(const uint8_t *_image, H5O_cache_ud_t *udata) /* Verify object header prefix length */ HDassert((size_t)(image - _image) == (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh))); - /* Save the object header for later use in 'deserialize' callback */ - udata->oh = oh; + /* If udata->oh is to be freed (see H5O__cache_verify_chksum), + save the pointer to udata->oh and free it later after setting + udata->oh with the new object header */ + if(udata->free_oh) { + H5O_t *saved_oh = udata->oh; + HDassert(udata->oh); + + /* Save the object header for later use in 'deserialize' callback */ + udata->oh = oh; + if(H5O__free(saved_oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't destroy object header") + udata->free_oh = FALSE; + } else + /* Save the object header for later use in 'deserialize' callback */ + udata->oh = oh; + oh = NULL; done: diff --git a/src/H5Oint.c b/src/H5Oint.c index 08eb28d..2351779 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -875,6 +875,7 @@ H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, unsigned prot_flags, udata.v1_pfx_nmesgs = 0; udata.chunk0_size = 0; udata.oh = NULL; + udata.free_oh = FALSE; udata.common.f = loc->file; udata.common.dxpl_id = dxpl_id; udata.common.file_intent = file_intent; diff --git a/src/H5Opkg.h b/src/H5Opkg.h index e970406..9392fa8 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -379,6 +379,7 @@ typedef struct H5O_cache_ud_t { unsigned v1_pfx_nmesgs; /* Number of messages from v1 prefix header */ size_t chunk0_size; /* Size of serialized first chunk */ H5O_t *oh; /* Partially deserialized object header, for later use */ + hbool_t free_oh; /* Whether to free the object header or not */ H5O_common_cache_ud_t common; /* Common object header cache callback info */ } H5O_cache_ud_t; diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 13409d2..a7c8218 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -193,6 +193,14 @@ /* Definition for status_flags in the superblock */ #define H5F_ACS_CLEAR_STATUS_FLAGS_SIZE sizeof(hbool_t) #define H5F_ACS_CLEAR_STATUS_FLAGS_DEF FALSE + +/* Definition for dropping free-space to the floor when reading in the superblock */ +#define H5F_ACS_NULL_FSM_ADDR_SIZE sizeof(hbool_t) +#define H5F_ACS_NULL_FSM_ADDR_DEF FALSE +/* Definition for skipping EOF check when reading in the superblock */ +#define H5F_ACS_SKIP_EOF_CHECK_SIZE sizeof(hbool_t) +#define H5F_ACS_SKIP_EOF_CHECK_DEF FALSE + /* Definition for 'use metadata cache logging' flag */ #define H5F_ACS_USE_MDC_LOGGING_SIZE sizeof(hbool_t) #define H5F_ACS_USE_MDC_LOGGING_DEF FALSE @@ -374,6 +382,9 @@ static const size_t H5F_def_core_write_tracking_page_size_g = H5F_ACS_CORE_WRITE static const unsigned H5F_def_metadata_read_attempts_g = H5F_ACS_METADATA_READ_ATTEMPTS_DEF; /* Default setting for the # of metadata read attempts */ 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_clear_status_flags_g = H5F_ACS_CLEAR_STATUS_FLAGS_DEF; /* Default to clear the superblock status_flags */ +static const hbool_t H5F_def_skip_eof_check_g = H5F_ACS_SKIP_EOF_CHECK_DEF; /* Default setting for skipping EOF check */ +static const hbool_t H5F_def_null_fsm_addr_g = H5F_ACS_NULL_FSM_ADDR_DEF; /* Default setting for dropping free-space to the floor */ + static const hbool_t H5F_def_use_mdc_logging_g = H5F_ACS_USE_MDC_LOGGING_DEF; /* Default metadata cache logging flag */ static const char *H5F_def_mdc_log_location_g = H5F_ACS_MDC_LOG_LOCATION_DEF; /* Default mdc log location */ static const hbool_t H5F_def_start_mdc_log_on_access_g = H5F_ACS_START_MDC_LOG_ON_ACCESS_DEF; /* Default mdc log start on access flag */ @@ -565,6 +576,16 @@ 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 private property of whether to skip EOF check. It's used by h5clear only. */ + if(H5P_register_real(pclass, H5F_ACS_SKIP_EOF_CHECK_NAME, H5F_ACS_SKIP_EOF_CHECK_SIZE, &H5F_def_skip_eof_check_g, + 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 private property of whether to drop free-space to the floor. It's used by h5clear only. */ + if(H5P_register_real(pclass, H5F_ACS_NULL_FSM_ADDR_NAME, H5F_ACS_NULL_FSM_ADDR_SIZE, &H5F_def_null_fsm_addr_g, + 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 metadata cache logging flag. */ if(H5P_register_real(pclass, H5F_ACS_USE_MDC_LOGGING_NAME, H5F_ACS_USE_MDC_LOGGING_SIZE, &H5F_def_use_mdc_logging_g, NULL, NULL, NULL, H5F_ACS_USE_MDC_LOGGING_ENC, H5F_ACS_USE_MDC_LOGGING_DEC, NULL, NULL, NULL, NULL) < 0) |