summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLarry Knox <lrknox@hdfgroup.org>2018-03-13 18:04:03 (GMT)
committerLarry Knox <lrknox@hdfgroup.org>2018-03-13 18:04:03 (GMT)
commitf30873136be7cb444166d019c57d3508ff79fc76 (patch)
tree559406eb3860a27fe1bfc6fcc7b5febe8454cba7 /src
parent8a77c7a3e4cd49cc0de824476b04b4926582e1ed (diff)
parent9247388c3d14510341ea3f07847ce2cbb6e44a8e (diff)
downloadhdf5-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.c94
-rw-r--r--src/H5Fint.c41
-rw-r--r--src/H5Fpkg.h3
-rw-r--r--src/H5Fprivate.h4
-rw-r--r--src/H5Fpublic.h2
-rw-r--r--src/H5Fsuper.c112
-rw-r--r--src/H5Gcache.c3
-rw-r--r--src/H5Gent.c7
-rw-r--r--src/H5Gpkg.h2
-rw-r--r--src/H5Ocache.c39
-rw-r--r--src/H5Oint.c1
-rw-r--r--src/H5Opkg.h1
-rw-r--r--src/H5Pfapl.c21
13 files changed, 281 insertions, 49 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 8e5f65a..2cd65cb 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -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)