summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hl/src/H5HLprivate2.h43
-rw-r--r--hl/tools/h5watch/extend_dset.c14
-rw-r--r--hl/tools/h5watch/h5watch.c18
-rw-r--r--hl/tools/h5watch/h5watchgentest.c1
-rw-r--r--src/H5B2cache.c42
-rw-r--r--src/H5EAcache.c56
-rw-r--r--src/H5F.c27
-rw-r--r--src/H5FAcache.c32
-rw-r--r--src/H5FScache.c26
-rw-r--r--src/H5Fio.c106
-rw-r--r--src/H5Fpkg.h1
-rw-r--r--src/H5Fprivate.h14
-rw-r--r--src/H5Fquery.c23
-rw-r--r--src/H5Fsuper_cache.c135
-rw-r--r--src/H5HFcache.c465
-rw-r--r--src/H5HFpkg.h8
-rw-r--r--src/H5Ocache.c147
-rw-r--r--src/H5Pfapl.c92
-rw-r--r--src/H5Ppublic.h2
-rw-r--r--src/H5SMcache.c27
-rw-r--r--test/accum.c133
-rw-r--r--test/swmr_generator.c1
-rw-r--r--test/testfiles/plist_files/fapl_bebin1402 -> 1421 bytes
-rw-r--r--test/testfiles/plist_files/fapl_lebin1402 -> 1421 bytes
-rw-r--r--test/testfiles/plist_files/lapl_bebin1502 -> 1521 bytes
-rw-r--r--test/testfiles/plist_files/lapl_lebin1502 -> 1521 bytes
-rw-r--r--test/tfile.c566
27 files changed, 1484 insertions, 495 deletions
diff --git a/hl/src/H5HLprivate2.h b/hl/src/H5HLprivate2.h
index 7480bd8..556c86f 100644
--- a/hl/src/H5HLprivate2.h
+++ b/hl/src/H5HLprivate2.h
@@ -60,12 +60,16 @@
#ifndef TRUE
# define TRUE 1
#endif
+#ifndef HDassert
+ #define HDassert(X) assert(X)
+#endif /* HDassert */
#ifndef HDcalloc
#define HDcalloc(N,Z) calloc(N,Z)
#endif /* HDcalloc */
-#ifndef HDrealloc
- #define HDrealloc(M,Z) realloc(M,Z)
-#endif /* HDrealloc */
+#ifndef HDfflush
+ #define HDfflush(F) fflush(F)
+#endif /* HDfflush */
+H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...);
#ifndef HDfree
#define HDfree(M) free(M)
#endif /* HDfree */
@@ -75,33 +79,30 @@
#ifndef HDmemset
#define HDmemset(X,C,Z) memset(X,C,Z)
#endif /* HDmemset */
-#ifndef HDassert
- #define HDassert(X) assert(X)
-#endif /* HDassert */
-#ifndef HDstrlen
- #define HDstrlen(S) strlen(S)
-#endif /* HDstrlen */
+#ifndef HDrealloc
+ #define HDrealloc(M,Z) realloc(M,Z)
+#endif /* HDrealloc */
+#ifndef HDsleep
+ #define HDsleep(N) sleep(N)
+#endif /* HDsleep */
#ifndef HDstrcat
#define HDstrcat(X,Y) strcat(X,Y)
#endif /* HDstrcat */
+#ifndef HDstrcmp
+ #define HDstrcmp(X,Y) strcmp(X,Y)
+#endif /* HDstrcmp */
+#ifndef HDstrlen
+ #define HDstrlen(S) strlen(S)
+#endif /* HDstrlen */
#ifndef HDstrrchr
#define HDstrrchr(S,C) strrchr(S,C)
#endif /* HDstrrchr */
-#ifndef HDstrtol
- #define HDstrtol(S,R,N) strtol(S,R,N)
-#endif /* HDstrtol */
#ifndef HDstrtod
#define HDstrtod(S,R) strtod(S,R)
#endif /* HDstrtod */
-#ifndef HDsleep
- #define HDsleep(N) sleep(N)
-#endif /* HDsleep */
-#ifndef HDfflush
- #define HDfflush(F) fflush(F)
-#endif /* HDfflush */
-#ifndef HDstrcmp
- #define HDstrcmp(X,Y) strcmp(X,Y)
-#endif /* HDstrcmp */
+#ifndef HDstrtol
+ #define HDstrtol(S,R,N) strtol(S,R,N)
+#endif /* HDstrtol */
/*
* And now for a couple non-Posix functions... Watch out for systems that
* define these in terms of macros.
diff --git a/hl/tools/h5watch/extend_dset.c b/hl/tools/h5watch/extend_dset.c
index 61cc09f..b58dce8 100644
--- a/hl/tools/h5watch/extend_dset.c
+++ b/hl/tools/h5watch/extend_dset.c
@@ -139,8 +139,8 @@ extend_dset_two(const char *file, char *dname)
goto done;
/* Set up the new extended dimension sizes */
- ext_dims[0] = cur_dims[0] + two_tests[i][0];
- ext_dims[1] = cur_dims[1] + two_tests[i][1];
+ ext_dims[0] = cur_dims[0] + (hsize_t)two_tests[i][0];
+ ext_dims[1] = cur_dims[1] + (hsize_t)two_tests[i][1];
/* Extend the dataset */
if(H5Dset_extent(did, ext_dims) < 0)
@@ -148,7 +148,7 @@ extend_dset_two(const char *file, char *dname)
num_elmts = 1;
for(j = 0; j < (unsigned)ndims; j++)
- num_elmts *= ext_dims[j];
+ num_elmts *= (unsigned)ext_dims[j];
/* Compound type */
if(!HDstrcmp(dname, DSET_CMPD_TWO)) {
@@ -172,7 +172,7 @@ extend_dset_two(const char *file, char *dname)
} else { /* Integer type */
HDmemset(ibuf, 0, sizeof(ibuf));
for(j = 0; j < num_elmts; j++)
- ibuf[j] = i + 1;
+ ibuf[j] = (int)(i + 1);
/* Write to the dataset */
if(H5Dwrite(did, dtid, H5S_ALL, H5S_ALL, H5P_DEFAULT, ibuf) < 0)
@@ -261,7 +261,7 @@ extend_dset_one(const char *file, char *dname)
goto done;
/* Set up the new extended dimension sizes */
- ext_dims[0] = cur_dims[0] + one_tests[i];
+ ext_dims[0] = cur_dims[0] + (hsize_t)one_tests[i];
/* Extend the dataset */
if(H5Dset_extent(did, ext_dims) < 0)
@@ -272,7 +272,7 @@ extend_dset_one(const char *file, char *dname)
/* Select the extended region */
offset[0] = cur_dims[0];
- count[0] = one_tests[i];
+ count[0] = (hsize_t)one_tests[i];
if((sid = H5Dget_space(did)) < 0)
goto done;
if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0)
@@ -305,7 +305,7 @@ extend_dset_one(const char *file, char *dname)
goto done;
} else { /* Integer type */
for(j = 0; j < (unsigned)one_tests[i]; j++)
- ibuf[j] = j;
+ ibuf[j] = (int)j;
/* Write to the extended region of the dataset */
if(H5Dwrite(did, dtid, mid, sid, H5P_DEFAULT, ibuf) < 0)
diff --git a/hl/tools/h5watch/h5watch.c b/hl/tools/h5watch/h5watch.c
index 7cf8ff6..8b33fa3 100644
--- a/hl/tools/h5watch/h5watch.c
+++ b/hl/tools/h5watch/h5watch.c
@@ -20,6 +20,7 @@
#include <float.h>
#include "h5tools.h"
+#include "h5tools_dump.h"
#include "h5tools_utils.h"
#include "h5tools_ref.h"
#include "h5trav.h"
@@ -189,7 +190,7 @@ doprint(hid_t did, hsize_t *start, hsize_t *block, int rank)
info.line_per_line = 1;
}
else
- info.line_ncols = g_display_width;
+ info.line_ncols = (unsigned)g_display_width;
info.line_multi_new = 1;
@@ -313,7 +314,6 @@ done:
static herr_t
monitor_dataset(hid_t fid, char *dsetname)
{
- char drivername[50];/* Driver's name for opening the file */
hid_t did; /* dataset id */
hid_t sid; /* dataspace id */
int ndims; /* # of dimensions in the dataspace */
@@ -404,7 +404,7 @@ monitor_dataset(hid_t fid, char *dsetname)
}
/* Save the current dimension sizes */
- HDmemcpy(prev_dims, cur_dims, ndims * sizeof(hsize_t));
+ HDmemcpy(prev_dims, cur_dims, (size_t)ndims * sizeof(hsize_t));
/* Sleep before next monitor */
HDsleep(g_polling_interval);
@@ -516,9 +516,9 @@ done:
static herr_t
check_dataset(hid_t fid, char *dsetname)
{
- hid_t did; /* Dataset id */
- hid_t dcp; /* Dataset creation property */
- hid_t sid; /* Dataset's dataspace id */
+ hid_t did=-1; /* Dataset id */
+ hid_t dcp=-1; /* Dataset creation property */
+ hid_t sid=-1; /* Dataset's dataspace id */
int ndims; /* # of dimensions in the dataspace */
unsigned u; /* Local index variable */
hsize_t cur_dims[H5S_MAX_RANK]; /* size of dataspace dimensions */
@@ -583,6 +583,8 @@ check_dataset(hid_t fid, char *dsetname)
}
done:
+ H5Eset_auto2(H5E_DEFAULT, func, edata);
+
/* Closing */
H5E_BEGIN_TRY
H5Sclose(sid);
@@ -590,8 +592,6 @@ done:
H5Dclose(did);
H5E_END_TRY
- H5Eset_auto2(H5E_DEFAULT, func, edata);
-
return(ret_value);
} /* check_dataset() */
@@ -712,7 +712,7 @@ parse_command_line(int argc, const char *argv[])
break;
case 'w': /* --width=N */
- g_display_width = HDstrtol(opt_arg, NULL, 0);
+ g_display_width = (int)HDstrtol(opt_arg, NULL, 0);
if(g_display_width < 0) {
usage(h5tools_getprogname());
leave(EXIT_FAILURE);
diff --git a/hl/tools/h5watch/h5watchgentest.c b/hl/tools/h5watch/h5watchgentest.c
index 36c90e6..e30dc03 100644
--- a/hl/tools/h5watch/h5watchgentest.c
+++ b/hl/tools/h5watch/h5watchgentest.c
@@ -4,6 +4,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <stdlib.h>
+#include <string.h>
/*
* WATCH.h5: file with various types of datasets for testing--
diff --git a/src/H5B2cache.c b/src/H5B2cache.c
index d06d9c0..e9030d8 100644
--- a/src/H5B2cache.c
+++ b/src/H5B2cache.c
@@ -187,9 +187,9 @@ H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, hdr->hdr_size)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't get actual buffer")
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header")
+ /* Read and validate header from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, hdr->hdr_size, dxpl_id, buf, &computed_chksum) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 B-tree header")
/* Get temporary pointer to serialized header */
p = buf;
@@ -232,10 +232,7 @@ H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Sanity check */
HDassert((size_t)(p - (const uint8_t *)buf) == hdr->hdr_size);
- /* Compute checksum on entire header */
- computed_chksum = H5_checksum_metadata(buf, (hdr->hdr_size - H5B2_SIZEOF_CHKSUM), 0);
-
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 B-tree header")
@@ -578,6 +575,7 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
unsigned u; /* Local index variable */
+ uint32_t chk_size; /* Exact size of the node with checksum at the end */
H5B2_internal_t *ret_value; /* Return value */
FUNC_ENTER_STATIC
@@ -605,9 +603,12 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
internal->shadowed_next = NULL;
internal->shadowed_prev = NULL;
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree internal node")
+ /* Internal node prefix header + records + child pointer triplets: size with checksum at the end */
+ chk_size = H5B2_INT_PREFIX_SIZE + (udata->nrec * udata->hdr->rrec_size) + ((udata->nrec + 1) * H5B2_INT_POINTER_SIZE(udata->hdr, udata->depth));
+
+ /* Read and validate internal node from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, chk_size, dxpl_id, udata->hdr->page, &computed_chksum) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 internal node")
p = udata->hdr->page;
@@ -663,9 +664,6 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
int_node_ptr++;
} /* end for */
- /* Compute checksum on internal node */
- computed_chksum = H5_checksum_metadata(udata->hdr->page, (size_t)(p - (const uint8_t *)udata->hdr->page), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
@@ -945,10 +943,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5B2_cache_internal_size
-=======
* Function: H5B2__cache_internal_size
->>>>>>> .merge-right.r23988
*
* Purpose: Compute the size in bytes of a B-tree internal node
* on disk, and return it in *size_ptr. On failure,
@@ -1003,6 +998,7 @@ H5B2__cache_leaf_load(H5F_t UNUSED *f, hid_t dxpl_id, haddr_t addr, void *_udata
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
unsigned u; /* Local index variable */
+ uint32_t chk_size; /* Exact size of the node with checksum at the end */
H5B2_leaf_t *ret_value; /* Return value */
FUNC_ENTER_STATIC
@@ -1030,9 +1026,12 @@ H5B2__cache_leaf_load(H5F_t UNUSED *f, hid_t dxpl_id, haddr_t addr, void *_udata
leaf->shadowed_next = NULL;
leaf->shadowed_prev = NULL;
- /* Read header from disk */
- if(H5F_block_read(udata->f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree leaf node")
+ /* Leaf node prefix header + records: size with checksum at the end */
+ chk_size = H5B2_LEAF_PREFIX_SIZE + (udata->nrec * udata->hdr->rrec_size);
+
+ /* Read and validate leaf node from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, chk_size, dxpl_id, udata->hdr->page, &computed_chksum) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 leaf node")
p = udata->hdr->page;
@@ -1068,16 +1067,13 @@ H5B2__cache_leaf_load(H5F_t UNUSED *f, hid_t dxpl_id, haddr_t addr, void *_udata
native += udata->hdr->cls->nrec_size;
} /* end for */
- /* Compute checksum on internal node */
- computed_chksum = H5_checksum_metadata(udata->hdr->page, (size_t)(p - (const uint8_t *)udata->hdr->page), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check parsing */
HDassert((size_t)(p - (const uint8_t *)udata->hdr->page) <= udata->hdr->node_size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 leaf node")
diff --git a/src/H5EAcache.c b/src/H5EAcache.c
index 055293e..381b364 100644
--- a/src/H5EAcache.c
+++ b/src/H5EAcache.c
@@ -233,9 +233,9 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata))
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
H5E_THROW(H5E_CANTGET, "can't get actual buffer")
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_EARRAY_HDR, addr, size, dxpl_id, buf) < 0)
- H5E_THROW(H5E_READERROR, "can't read extensible array header")
+ /* Read and validate header from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_EARRAY_HDR, addr, size, size, dxpl_id, buf, &computed_chksum) < 0)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array header")
/* Get temporary pointer to serialized header */
p = buf;
@@ -300,17 +300,13 @@ H5EA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata))
/* (allow for checksum not decoded yet) */
HDassert((size_t)(p - buf) == (size - H5EA_SIZEOF_CHKSUM));
- /* Compute checksum on entire header */
- /* (including the filter information, if present) */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array header")
@@ -601,9 +597,9 @@ H5EA__cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata))
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
H5E_THROW(H5E_CANTGET, "can't get actual buffer")
- /* Read index block from disk */
- if(H5F_block_read(f, H5FD_MEM_EARRAY_IBLOCK, addr, size, dxpl_id, buf) < 0)
- H5E_THROW(H5E_READERROR, "can't read extensible array index block")
+ /* Read and validate index block from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_EARRAY_IBLOCK, addr, size, size, dxpl_id, buf, &computed_chksum) < 0)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array index block")
/* Get temporary pointer to serialized header */
p = buf;
@@ -661,16 +657,13 @@ H5EA__cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata))
/* Save the index block's size */
iblock->size = size;
- /* Compute checksum on index block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == iblock->size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array index block")
@@ -1018,9 +1011,9 @@ H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata))
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
H5E_THROW(H5E_CANTGET, "can't get actual buffer")
- /* Read super block from disk */
- if(H5F_block_read(f, H5FD_MEM_EARRAY_SBLOCK, addr, size, dxpl_id, buf) < 0)
- H5E_THROW(H5E_READERROR, "can't read extensible array super block")
+ /* Read and validate super block from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_EARRAY_SBLOCK, addr, size, size, dxpl_id, buf, &computed_chksum) < 0)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array super block")
/* Get temporary pointer to serialized header */
p = buf;
@@ -1068,16 +1061,13 @@ H5EA__cache_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata))
/* Save the super block's size */
sblock->size = size;
- /* Compute checksum on super block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == sblock->size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array super block")
@@ -1417,9 +1407,9 @@ H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata))
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
H5E_THROW(H5E_CANTGET, "can't get actual buffer")
- /* Read data block from disk */
- if(H5F_block_read(f, H5FD_MEM_EARRAY_DBLOCK, addr, size, dxpl_id, buf) < 0)
- H5E_THROW(H5E_READERROR, "can't read extensible array data block")
+ /* Read and validate data block from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_EARRAY_DBLOCK, addr, size, size, dxpl_id, buf, &computed_chksum) < 0)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible data block")
/* Get temporary pointer to serialized header */
p = buf;
@@ -1463,16 +1453,13 @@ H5EA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata))
/* Set the data block's size */
dblock->size = H5EA_DBLOCK_SIZE(dblock);
- /* Compute checksum on data block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array data block - # pages = %d", dblock->npages)
@@ -1816,9 +1803,9 @@ HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr);
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
H5E_THROW(H5E_CANTGET, "can't get actual buffer")
- /* Read data block page from disk */
- if(H5F_block_read(f, H5FD_MEM_EARRAY_DBLK_PAGE, addr, size, dxpl_id, buf) < 0)
- H5E_THROW(H5E_READERROR, "can't read extensible array data block page")
+ /* Read and validate data block page from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_EARRAY_DBLK_PAGE, addr, size, size, dxpl_id, buf, &computed_chksum) < 0)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array data block page")
/* Get temporary pointer to serialized header */
p = buf;
@@ -1838,16 +1825,13 @@ HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr);
/* Set the data block page's size */
dblk_page->size = size;
- /* Compute checksum on data block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == dblk_page->size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for extensible array data block page")
diff --git a/src/H5F.c b/src/H5F.c
index e442803..60b9b3e 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -338,6 +338,7 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
/* Make a copy of the default file access property list */
if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_FILE_ACCESS_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+
if((ret_value = H5P_copy_plist(old_plist, app_ref)) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy file access property list")
if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(ret_value)))
@@ -366,6 +367,8 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size")
if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag")
+ if(H5P_set(new_plist, H5F_ACS_READ_ATTEMPTS_NAME, &(f->read_attempts)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag")
if(f->shared->efc)
efc_size = H5F_efc_max_nfiles(f->shared->efc);
if(H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0)
@@ -930,6 +933,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
/* Get the FAPL values to cache */
if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
+
if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0)
@@ -960,6 +964,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
if(NULL == (f->shared->efc = H5F_efc_create(efc_size)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache")
+
/* Get the VFD values to cache */
f->shared->maxaddr = H5FD_get_maxaddr(lf);
if(!H5F_addr_defined(f->shared->maxaddr))
@@ -1355,6 +1360,22 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
file->intent = flags;
file->open_name = H5MM_xstrdup(name);
+ /* Get the file access property list, for future queries */
+ if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
+
+ /* Retrieve the # of read attempts here so that sohm in superblock will get the correct # of attempts */
+ if(H5P_get(a_plist, H5F_ACS_READ_ATTEMPTS_NAME, &file->read_attempts) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get the # of read attempts")
+
+ /* When opening file with SWMR access, the # of read attempts is H5_SWMR_READ_ATTEMPTS if not set */
+ /* When opening file with non-SWMR access, the # of read attempts is always H5F_READ_ATTEMPTS (set or not set) */
+ if(file->intent & H5F_ACC_SWMR_READ || file->intent & H5F_ACC_SWMR_WRITE) {
+ if(!file->read_attempts)
+ file->read_attempts = H5F_SWMR_READ_ATTEMPTS;
+ } else
+ file->read_attempts = H5F_READ_ATTEMPTS;
+
/*
* Read or write the file superblock, depending on whether the file is
* empty or not.
@@ -1386,9 +1407,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group")
} /* end if */
- /* Get the file access property list, for future queries */
- if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
/*
* Decide the file close degree. If it's the first time to open the
@@ -2120,6 +2138,9 @@ H5Freopen(hid_t file_id)
/* Keep old file's read/write intent in new file */
new_file->intent = old_file->intent;
+ /* Keep old file's read attempts in new file */
+ new_file->read_attempts = old_file->read_attempts;
+
/* Duplicate old file's names */
new_file->open_name = H5MM_xstrdup(old_file->open_name);
new_file->actual_name = H5MM_xstrdup(old_file->actual_name);
diff --git a/src/H5FAcache.c b/src/H5FAcache.c
index 2f62fe0..9b2d32c 100644
--- a/src/H5FAcache.c
+++ b/src/H5FAcache.c
@@ -194,9 +194,9 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata))
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
H5E_THROW(H5E_CANTGET, "can't get actual buffer")
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_FARRAY_HDR, addr, size, dxpl_id, buf) < 0)
- H5E_THROW(H5E_READERROR, "can't read fixed array header")
+ /* Read and vaildate header from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_FARRAY_HDR, addr, size, size, dxpl_id, buf, &computed_chksum) < 0)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array header")
/* Get temporary pointer to serialized header */
p = buf;
@@ -252,17 +252,13 @@ H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata))
/* (allow for checksum not decoded yet) */
HDassert((size_t)(p - buf) == (size - H5FA_SIZEOF_CHKSUM));
- /* Compute checksum on entire header */
- /* (including the filter information, if present) */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array header")
@@ -542,9 +538,9 @@ H5FA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata))
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
H5E_THROW(H5E_CANTGET, "can't get actual buffer")
- /* Read data block from disk */
- if(H5F_block_read(f, H5FD_MEM_FARRAY_DBLOCK, addr, size, dxpl_id, buf) < 0)
- H5E_THROW(H5E_READERROR, "can't read fixed array data block")
+ /* Read and validate data block from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_FARRAY_DBLOCK, addr, size, size, dxpl_id, buf, &computed_chksum) < 0)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array data block")
/* Get temporary pointer to serialized header */
p = buf;
@@ -589,16 +585,13 @@ H5FA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata))
/* Set the data block's size */
dblock->size = H5FA_DBLOCK_SIZE(dblock);
- /* Compute checksum on data block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array data block")
@@ -938,9 +931,9 @@ HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr);
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
H5E_THROW(H5E_CANTGET, "can't get actual buffer")
- /* Read data block page from disk */
- if(H5F_block_read(f, H5FD_MEM_FARRAY_DBLK_PAGE, addr, size, dxpl_id, buf) < 0)
- H5E_THROW(H5E_READERROR, "can't read fixed array data block page")
+ /* Read and validate data block page from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_FARRAY_DBLK_PAGE, addr, size, size, dxpl_id, buf, &computed_chksum) < 0)
+ H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array data block page")
/* Get temporary pointer to serialized header */
p = buf;
@@ -960,9 +953,6 @@ HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr);
/* Set the data block page's size */
dblk_page->size = size;
- /* Compute checksum on data block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
diff --git a/src/H5FScache.c b/src/H5FScache.c
index c8caf47..9e93fdf 100644
--- a/src/H5FScache.c
+++ b/src/H5FScache.c
@@ -182,9 +182,9 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
if(NULL == (hdr = (uint8_t *)H5WB_actual(wb, fspace->hdr_size)))
HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, NULL, "can't get actual buffer")
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_FSPACE_HDR, addr, fspace->hdr_size, dxpl_id, hdr) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_READERROR, NULL, "can't read free space header")
+ /* Read and validate header from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_FSPACE_HDR, addr, fspace->hdr_size, fspace->hdr_size, dxpl_id, hdr, &computed_chksum) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, NULL, "incorrect metadata checksum for free space header")
p = hdr;
@@ -241,17 +241,14 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Allocated size of serialized free space sections */
H5F_DECODE_LENGTH(udata->f, p, fspace->alloc_sect_size);
- /* Compute checksum on indirect block */
- computed_chksum = H5_checksum_metadata(hdr, (size_t)(p - (const uint8_t *)hdr), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
HDassert((size_t)(p - (const uint8_t *)hdr) == fspace->hdr_size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
- HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap indirect block")
+ HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, NULL, "incorrect metadata checksum for free space header")
/* Set return value */
ret_value = fspace;
@@ -577,9 +574,9 @@ H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata
if(NULL == (buf = H5FL_BLK_MALLOC(sect_block, (size_t)udata->fspace->sect_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- /* Read buffer from disk */
- if(H5F_block_read(f, H5FD_MEM_FSPACE_SINFO, udata->fspace->sect_addr, (size_t)udata->fspace->sect_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_READERROR, NULL, "can't read free space sections")
+ /* Read and validate free space sections from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_FSPACE_SINFO, udata->fspace->sect_addr, (size_t)udata->fspace->sect_size, (size_t)udata->fspace->sect_size, dxpl_id, buf, &computed_chksum) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, NULL, "incorrect metadata checksum for free space sections")
/* Deserialize free sections from buffer available */
p = buf;
@@ -671,15 +668,12 @@ H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata
HDassert(old_tot_space == udata->fspace->tot_space);
} /* end if */
- /* Compute checksum on indirect block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - (const uint8_t *)buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
- HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap indirect block")
+ HGOTO_ERROR(H5E_FSPACE, H5E_BADVALUE, NULL, "incorrect metadata checksum for free space sections")
/* Sanity check */
HDassert((size_t)(p - (const uint8_t *)buf) == old_sect_size);
diff --git a/src/H5Fio.c b/src/H5Fio.c
index 4f15017..bd8c39a 100644
--- a/src/H5Fio.c
+++ b/src/H5Fio.c
@@ -236,3 +236,109 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5F_evict_tagged_metadata */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_get_checksums
+ *
+ * Purpose: Decode checksum stored in the buffer
+ * Calculate checksum for the data in the buffer
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Sept 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_get_checksums(uint8_t *buf, size_t chk_size, uint32_t *s_chksum/*out*/, uint32_t *c_chksum/*out*/)
+{
+ uint32_t stored_chksum; /* Stored metadata checksum value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ const uint8_t *chk_p; /* Pointer into raw data buffer */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /* Check arguments */
+ HDassert(buf);
+ HDassert(chk_size);
+
+ /* Compute checksum for the buffer */
+ computed_chksum = H5_checksum_metadata(buf, chk_size - H5_SIZEOF_CHKSUM, 0);
+
+ /* Offset to the checksum in the buffer */
+ chk_p = buf + chk_size - H5_SIZEOF_CHKSUM;
+
+ /* Decode the checksum stored in the buffer */
+ UINT32DECODE(chk_p, stored_chksum);
+
+ /* Return the stored checksum */
+ if(s_chksum)
+ *s_chksum = stored_chksum;
+
+ /* Return the computed checksum */
+ if(c_chksum)
+ *c_chksum = computed_chksum;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5F_get_chksums() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_read_check_meatadata
+ *
+ * Purpose: Attempts to read and validate a piece of meatadata that has
+ * checksum as follows:
+ * a) read the piece of metadata
+ * b) calculate checksum for the buffer of metadata
+ * c) decode the checksum stored in the buffer of metadata
+ d) compare the computed checksum with its stored checksum
+ * The library will perform (a) to (d) above for "f->read_attempts"
+ * times or until the checksum comparison in (d) passes.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Sept 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_read_check_metadata(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t read_size, size_t chk_size,
+ hid_t dxpl_id, uint8_t *buf/*out*/, uint32_t *chksum/*out*/)
+{
+ size_t tries, max_tries;
+ uint32_t stored_chksum; /* Stored metadata checksum value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Get the # of read attempts */
+ max_tries = tries = f->read_attempts;
+
+ do {
+ /* Read header from disk */
+ if(H5F_block_read(f, type, addr, read_size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read metadata")
+
+ /* Get stored and computed checksums */
+ H5F_get_checksums(buf, chk_size, &stored_chksum, &computed_chksum);
+
+ /* Verify checksum */
+ if(stored_chksum == computed_chksum)
+ break;
+
+ } while(--tries);
+
+ if(tries == 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "incorrect metadatda checksum after all read attempts (%u) for %u bytes:c_chksum=%u, s_chkum=%u",
+ max_tries, chk_size, computed_chksum, stored_chksum)
+ else if((max_tries - tries + 1) > 1)
+ HDfprintf(stderr, "%s: SUCCESS after %u attempts; type=%u\n", FUNC, max_tries - tries + 1, type);
+
+ /* Return the computed checksum */
+ if(chksum)
+ *chksum = computed_chksum;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5F_read_check_metadata */
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 59e50e3..a13e5e9 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -264,6 +264,7 @@ struct H5F_file_t {
*/
struct H5F_t {
unsigned intent; /* The flags passed to H5F_open()*/
+ unsigned read_attempts; /* The # of reads to try when reading metadata with checksum */
char *open_name; /* Name used to open file */
char *actual_name; /* Actual name of the file, after resolving symlinks, etc. */
char *extpath; /* Path for searching target external link file */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index ee478c2..6d20749 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -292,6 +292,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t;
#define H5F_FILE_ID(F) ((F)->file_id)
#define H5F_PARENT(F) ((F)->parent)
#define H5F_NMOUNTS(F) ((F)->nmounts)
+#define H5F_GET_READ_ATTEMPTS(F) ((F)->read_attempts)
#define H5F_DRIVER_ID(F) ((F)->shared->lf->driver_id)
#define H5F_GET_FILENO(F,FILENUM) ((FILENUM) = (F)->shared->lf->fileno)
#define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags & (FL))
@@ -334,6 +335,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t;
#define H5F_FILE_ID(F) (H5F_get_file_id(F))
#define H5F_PARENT(F) (H5F_get_parent(F))
#define H5F_NMOUNTS(F) (H5F_get_nmounts(F))
+#define H5F_GET_READ_ATTEMPTS(F) (H5F_get_read_attempts(F))
#define H5F_DRIVER_ID(F) (H5F_get_driver_id(F))
#define H5F_GET_FILENO(F,FILENUM) (H5F_get_fileno((F), &(FILENUM)))
#define H5F_HAS_FEATURE(F,FL) (H5F_has_feature(F,FL))
@@ -460,6 +462,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t;
#define H5F_ACS_MULTI_TYPE_NAME "multi_type" /* Data type in multi file driver */
#define H5F_ACS_LATEST_FORMAT_NAME "latest_format" /* 'Use latest format version' flag */
#define H5F_ACS_WANT_POSIX_FD_NAME "want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address */
+#define H5F_ACS_READ_ATTEMPTS_NAME "read_attempts" /* # of read attempts */
#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 */
@@ -502,6 +505,11 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t;
/* (all on-disk signatures should be this length) */
#define H5_SIZEOF_MAGIC 4
+#define H5_SIZEOF_CHKSUM 4
+
+#define H5F_READ_ATTEMPTS 1 /* Default # of read attempts for non-swmr access */
+#define H5F_SWMR_READ_ATTEMPTS 100 /* Default # of read attempts for swmr access */
+
/* v1 B-tree node signature */
#define H5B_MAGIC "TREE"
@@ -571,6 +579,7 @@ H5_DLL unsigned H5F_decr_nopen_objs(H5F_t *f);
H5_DLL hid_t H5F_get_file_id(const H5F_t *f);
H5_DLL H5F_t *H5F_get_parent(const H5F_t *f);
H5_DLL unsigned H5F_get_nmounts(const H5F_t *f);
+H5_DLL unsigned H5F_get_read_attempts(const H5F_t *f);
H5_DLL hid_t H5F_get_access_plist(H5F_t *f, hbool_t app_ref);
H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref);
H5_DLL herr_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr);
@@ -629,6 +638,11 @@ H5_DLL herr_t H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr,
H5_DLL herr_t H5F_flush_tagged_metadata(H5F_t * f, haddr_t tag, hid_t dxpl_id);
H5_DLL herr_t H5F_evict_tagged_metadata(H5F_t * f, haddr_t tag, hid_t dxpl_id);
+/* Function that read and verify a piece of metadata with checksum */
+H5_DLL herr_t H5F_read_check_metadata(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t read_size, size_t chk_size,
+ hid_t dxpl_id, uint8_t *buf/*out*/, uint32_t *chksum/*out*/);
+H5_DLL herr_t H5F_get_checksums(uint8_t *buf, size_t chk_size, uint32_t *s_chksum, uint32_t *c_chksum);
+
/* Address-related functions */
H5_DLL void H5F_addr_encode(const H5F_t *f, uint8_t **pp, haddr_t addr);
H5_DLL void H5F_addr_encode_len(size_t addr_len, uint8_t **pp, haddr_t addr);
diff --git a/src/H5Fquery.c b/src/H5Fquery.c
index c04ba24..cffb006 100644
--- a/src/H5Fquery.c
+++ b/src/H5Fquery.c
@@ -322,6 +322,29 @@ H5F_get_nmounts(const H5F_t *f)
/*-------------------------------------------------------------------------
+ * Function: H5F_get_read_attempts
+ *
+ * Purpose: Retrieve the file's 'read_attempts' value
+ *
+ * Return: '# of read attempts' on success/abort on failure (shouldn't fail)
+ *
+ * Programmer: Vaili Choi; Sept 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5F_get_read_attempts(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(f);
+
+ FUNC_LEAVE_NOAPI(f->read_attempts)
+} /* end H5F_get_read_attempts() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_get_fcpl
*
* Purpose: Retrieve the value of a file's FCPL.
diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c
index 705507d..3d906c7 100644
--- a/src/H5Fsuper_cache.c
+++ b/src/H5Fsuper_cache.c
@@ -128,7 +128,11 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata)
uint8_t *p; /* Temporary pointer into encoding buffer */
unsigned super_vers; /* Superblock version */
hbool_t *dirtied = (hbool_t *)_udata; /* Set up dirtied out value */
- H5F_super_t *ret_value; /* Return value */
+ size_t tries, max_tries; /* The # of read attempts to try */
+ size_t fixed_tries; /* The # of read attempts to try */
+ uint32_t computed_chksum; /* Computed checksum */
+ uint32_t stored_chksum; /* Checksum read from file */
+ H5F_super_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -159,40 +163,85 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata)
sblock->cache_info.flush_me_collectively = TRUE;
#endif
- /* Read fixed-size portion of the superblock */
- p = sbuf;
- H5_CHECK_OVERFLOW(fixed_size, size_t, haddr_t);
- if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)fixed_size) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
- if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)0, fixed_size, p) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")
-
- /* Skip over signature (already checked when locating the superblock) */
- p += H5F_SIGNATURE_LEN;
-
- /* Superblock version */
- super_vers = *p++;
- if(super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad superblock version number")
- if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set superblock version")
-
- /* Record the superblock version */
- sblock->super_vers = super_vers;
+ /* Get the # of read attempts */
+ tries = max_tries = f->read_attempts;
+ do {
+ fixed_tries = max_tries;
+ do {
+ /* Read fixed-size portion of the superblock */
+ p = sbuf;
+ H5_CHECK_OVERFLOW(fixed_size, size_t, haddr_t);
+ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)fixed_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
+ if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)0, fixed_size, p) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")
+
+ /* Skip over signature (already checked when locating the superblock) */
+ p += H5F_SIGNATURE_LEN;
+
+ /* Superblock version */
+ super_vers = *p++;
+
+ /* A valid version # */
+ if(super_vers <= HDF5_SUPERBLOCK_VERSION_LATEST)
+ break;
+
+ } while (--fixed_tries);
+
+ if(fixed_tries == 0)
+ /* After all tries (for SWMR access) or after 1 try (for non-SWMR) */
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad superblock version number after all tries")
+ else if((max_tries - fixed_tries + 1) > 1)
+ HDfprintf(stderr, "%s: SUCCESS after %u attempts for fixed data\n", FUNC, max_tries - fixed_tries + 1);
+
+ /* Set superblock version in property list */
+ if(H5P_set(c_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set superblock version")
+
+ /* Record the superblock version */
+ sblock->super_vers = super_vers;
+
+ /* Sanity check */
+ HDassert(((size_t)(p - sbuf)) == fixed_size);
+
+ /* Determine the size of the variable-length part of the superblock */
+ variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, f);
+ HDassert(variable_size > 0);
+ HDassert(fixed_size + variable_size <= sizeof(sbuf));
+
+ /* Read in variable-sized portion of superblock */
+ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)(fixed_size + variable_size)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
+ if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)fixed_size, variable_size, p) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read superblock")
+
+ /* No checksum for version 0 & 1 */
+ if(super_vers < HDF5_SUPERBLOCK_VERSION_2)
+ break;
+
+ /* Decode size of file addresses at this point to get the correct H5F_SIZEOF_ADDR(f) for checksum */
+ sizeof_addr = *p++;
+ if(sizeof_addr == 2 || sizeof_addr == 4 ||
+ sizeof_addr == 8 || sizeof_addr == 16 || sizeof_addr == 32) {
- /* Sanity check */
- HDassert(((size_t)(p - sbuf)) == fixed_size);
+ if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address")
+ shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */
+
+ /* Retrieve stored and computed checksum */
+ H5F_get_checksums(sbuf, fixed_size + H5F_SUPERBLOCK_VARLEN_SIZE_V2(f), &stored_chksum, &computed_chksum);
- /* Determine the size of the variable-length part of the superblock */
- variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, f);
- HDassert(variable_size > 0);
- HDassert(fixed_size + variable_size <= sizeof(sbuf));
+ /* Verify correct checksum */
+ if(stored_chksum == computed_chksum)
+ break;
+ }
+ } while (--tries);
- /* Read in variable-sized portion of superblock */
- if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, (haddr_t)(fixed_size + variable_size)) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "set end of space allocation request failed")
- if(H5FD_read(lf, dxpl_id, H5FD_MEM_SUPER, (haddr_t)fixed_size, variable_size, p) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read superblock")
+ if(tries == 0)
+ /* After all tries (for SWMR access) or after 1 try (for non-SWMR) */
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad checksum or bad byte number in superblock")
+ else if((max_tries - tries + 1) > 1)
+ HDfprintf(stderr, "%s: SUCCESS after %u attempts\n", FUNC, max_tries - tries + 1);
/* Check for older version of superblock format */
if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
@@ -386,17 +435,8 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata)
} /* end if */
} /* end if */
else {
- uint32_t computed_chksum; /* Computed checksum */
- uint32_t read_chksum; /* Checksum read from file */
- /* Size of file addresses */
- sizeof_addr = *p++;
- if(sizeof_addr != 2 && sizeof_addr != 4 &&
- sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32)
- HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad byte number in an address")
- if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "unable to set byte number in an address")
- shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */
+ /* Already decode sizeof_addr when validating checksum up there */
/* Size of file sizes */
sizeof_size = *p++;
@@ -418,15 +458,12 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata)
H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &sblock->root_addr/*out*/);
- /* Compute checksum for superblock */
- computed_chksum = H5_checksum_metadata(sbuf, (size_t)(p - sbuf), 0);
-
/* Decode checksum */
- UINT32DECODE(p, read_chksum);
+ UINT32DECODE(p, stored_chksum);
- /* Verify correct checksum */
- if(read_chksum != computed_chksum)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad checksum on driver information block")
+ /* Verify correct checksum with checksum computed via H5F_get_checksums() */
+ if(stored_chksum != computed_chksum)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad checksum on superblock")
/*
* Check if superblock address is different from base address and
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index ddff0e0..2b098be 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -78,6 +78,10 @@
static herr_t H5HF_dtable_encode(H5F_t *f, uint8_t **pp, const H5HF_dtable_t *dtable);
static herr_t H5HF_dtable_decode(H5F_t *f, const uint8_t **pp, H5HF_dtable_t *dtable);
+/* Decode minimum header and full header routines */
+static herr_t H5HF_min_header_decode(const uint8_t **pp, H5HF_hdr_t *hdr);
+static herr_t H5HF_full_header_decode(H5F_t *f, hid_t dxpl_id, const uint8_t **pp, H5HF_hdr_t *hdr);
+
/* Metadata cache (H5AC) callbacks */
static H5HF_hdr_t *H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
static herr_t H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_hdr_t *hdr, unsigned UNUSED * flags_ptr);
@@ -247,166 +251,251 @@ H5HF_dtable_encode(H5F_t *f, uint8_t **pp, const H5HF_dtable_t *dtable)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5HF_dtable_encode() */
+
/*-------------------------------------------------------------------------
- * Function: H5HF_cache_hdr_load
+ * Function: H5HF_min_header_decode
*
- * Purpose: Loads a fractal heap header from the disk.
+ * Purpose: Decodes enough info in the header to determine full header size
*
- * Return: Success: Pointer to a new fractal heap
- * Failure: NULL
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 24 2006
+ * Programmer: Vailin Choi; Sept 2013
*
*-------------------------------------------------------------------------
*/
-static H5HF_hdr_t *
-H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
+static herr_t
+H5HF_min_header_decode(const uint8_t **pp, H5HF_hdr_t *hdr)
{
- H5HF_hdr_t *hdr = NULL; /* Fractal heap info */
- H5HF_hdr_cache_ud_t *udata = (H5HF_hdr_cache_ud_t *)_udata;
- size_t size; /* Header size */
- H5WB_t *wb = NULL; /* Wrapped buffer for header data */
- uint8_t hdr_buf[H5HF_HDR_BUF_SIZE]; /* Buffer for header */
- uint8_t *buf; /* Pointer to header buffer */
- const uint8_t *p; /* Pointer into raw data buffer */
- uint32_t stored_chksum; /* Stored metadata checksum value */
- uint32_t computed_chksum; /* Computed metadata checksum value */
- uint8_t heap_flags; /* Status flags for heap */
- H5HF_hdr_t *ret_value; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/* Check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
- HDassert(udata);
-
- /* Allocate space for the fractal heap data structure */
- if(NULL == (hdr = H5HF_hdr_alloc(udata->f)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDassert(pp && *pp);
+ HDassert(hdr);
- /* Wrap the local buffer for serialized header info */
- if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't wrap buffer")
+ /* Magic number */
+ if(HDmemcmp(*pp, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "wrong fractal heap header signature")
+ *pp += H5_SIZEOF_MAGIC;
- /* Compute the 'base' size of the fractal heap header on disk */
- size = (size_t)H5HF_HEADER_SIZE(hdr);
+ /* Version */
+ if(**pp != H5HF_HDR_VERSION)
+ HGOTO_ERROR(H5E_HEAP, H5E_VERSION, FAIL, "wrong fractal heap header version")
+ (*pp)++;
- /* Get a pointer to a buffer that's large enough for serialized header */
- if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
+ /* General heap information */
+ UINT16DECODE(*pp, hdr->id_len); /* Heap ID length */
+ UINT16DECODE(*pp, hdr->filter_len); /* I/O filters' encoded length */
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_min_header_decode() */
- /* Get temporary pointer to serialized header */
- p = buf;
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_full_header_decode
+ *
+ * Purpose: Decodes info for the full header (fixed-len + variable-len)
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Sept 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_full_header_decode(H5F_t *f, hid_t dxpl_id, const uint8_t **pp, H5HF_hdr_t *hdr)
+{
+ uint8_t heap_flags; /* Status flags for heap */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Magic number */
- if(HDmemcmp(p, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap header signature")
- p += H5_SIZEOF_MAGIC;
+ FUNC_ENTER_NOAPI_NOINIT
- /* Version */
- if(*p++ != H5HF_HDR_VERSION)
- HGOTO_ERROR(H5E_HEAP, H5E_VERSION, NULL, "wrong fractal heap header version")
+ /* Check arguments */
+ HDassert(pp && *pp);
+ HDassert(hdr);
- /* General heap information */
- UINT16DECODE(p, hdr->id_len); /* Heap ID length */
- UINT16DECODE(p, hdr->filter_len); /* I/O filters' encoded length */
+ /* Decode the minimum header info */
+ if(H5HF_min_header_decode(pp, hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, FAIL, "can't decode minimum header info")
/* Heap status flags */
/* (bit 0: "huge" object IDs have wrapped) */
/* (bit 1: checksum direct blocks) */
- heap_flags = *p++;
+ heap_flags = **pp;
+ (*pp)++;
+
hdr->huge_ids_wrapped = heap_flags & H5HF_HDR_FLAGS_HUGE_ID_WRAPPED;
hdr->checksum_dblocks = heap_flags & H5HF_HDR_FLAGS_CHECKSUM_DBLOCKS;
/* "Huge" object information */
- UINT32DECODE(p, hdr->max_man_size); /* Max. size of "managed" objects */
- H5F_DECODE_LENGTH(udata->f, p, hdr->huge_next_id); /* Next ID to use for "huge" object */
- H5F_addr_decode(udata->f, &p, &hdr->huge_bt2_addr); /* Address of "huge" object tracker B-tree */
+ UINT32DECODE(*pp, hdr->max_man_size); /* Max. size of "managed" objects */
+ H5F_DECODE_LENGTH(f, *pp, hdr->huge_next_id); /* Next ID to use for "huge" object */
+ H5F_addr_decode(f, pp, &hdr->huge_bt2_addr); /* Address of "huge" object tracker B-tree */
/* "Managed" object free space information */
- H5F_DECODE_LENGTH(udata->f, p, hdr->total_man_free); /* Internal free space in managed direct blocks */
- H5F_addr_decode(udata->f, &p, &hdr->fs_addr); /* Address of free section header */
+ H5F_DECODE_LENGTH(f, *pp, hdr->total_man_free); /* Internal free space in managed direct blocks */
+ H5F_addr_decode(f, pp, &hdr->fs_addr); /* Address of free section header */
/* Heap statistics */
- H5F_DECODE_LENGTH(udata->f, p, hdr->man_size);
- H5F_DECODE_LENGTH(udata->f, p, hdr->man_alloc_size);
- H5F_DECODE_LENGTH(udata->f, p, hdr->man_iter_off);
- H5F_DECODE_LENGTH(udata->f, p, hdr->man_nobjs);
- H5F_DECODE_LENGTH(udata->f, p, hdr->huge_size);
- H5F_DECODE_LENGTH(udata->f, p, hdr->huge_nobjs);
- H5F_DECODE_LENGTH(udata->f, p, hdr->tiny_size);
- H5F_DECODE_LENGTH(udata->f, p, hdr->tiny_nobjs);
+ H5F_DECODE_LENGTH(f, *pp, hdr->man_size);
+ H5F_DECODE_LENGTH(f, *pp, hdr->man_alloc_size);
+ H5F_DECODE_LENGTH(f, *pp, hdr->man_iter_off);
+ H5F_DECODE_LENGTH(f, *pp, hdr->man_nobjs);
+ H5F_DECODE_LENGTH(f, *pp, hdr->huge_size);
+ H5F_DECODE_LENGTH(f, *pp, hdr->huge_nobjs);
+ H5F_DECODE_LENGTH(f, *pp, hdr->tiny_size);
+ H5F_DECODE_LENGTH(f, *pp, hdr->tiny_nobjs);
/* Managed objects' doubling-table info */
- if(H5HF_dtable_decode(hdr->f, &p, &(hdr->man_dtable)) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, NULL, "unable to encode managed obj. doubling table info")
-
- /* Sanity check */
- /* (allow for checksum not decoded yet) */
- HDassert((size_t)(p - (const uint8_t *)buf) == (size - H5HF_SIZEOF_CHKSUM));
+ if(H5HF_dtable_decode(f, pp, &(hdr->man_dtable)) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "unable to encode managed obj. doubling table info")
/* Check for I/O filter information to decode */
if(hdr->filter_len > 0) {
- size_t filter_info_off; /* Offset in header of filter information */
- size_t filter_info_size; /* Size of filter information */
H5O_pline_t *pline; /* Pipeline information from the header on disk */
- /* Compute the offset of the filter info in the header */
- filter_info_off = (size_t)(p - (const uint8_t *)buf);
-
- /* Compute the size of the extra filter information */
- filter_info_size = (size_t)(hdr->sizeof_size /* Size of size for filtered root direct block */
- + (unsigned)4 /* Size of filter mask for filtered root direct block */
- + hdr->filter_len); /* Size of encoded I/O filter info */
-
- /* Compute the heap header's size */
- hdr->heap_size = size + filter_info_size;
-
- /* Re-size current buffer */
- if(NULL == (buf = (uint8_t *)H5WB_actual(wb, hdr->heap_size)))
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
-
- /* Read in I/O filter information */
- /* (and the checksum) */
- if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, (addr + filter_info_off), (filter_info_size + H5HF_SIZEOF_CHKSUM), dxpl_id, (buf + filter_info_off)) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header's I/O pipeline filter info")
-
- /* Point at correct offset in header for the filter information */
- p = buf + filter_info_off;
-
/* Decode the size of a filtered root direct block */
- H5F_DECODE_LENGTH(udata->f, p, hdr->pline_root_direct_size);
+ H5F_DECODE_LENGTH(f, *pp, hdr->pline_root_direct_size);
/* Decode the filter mask for a filtered root direct block */
- UINT32DECODE(p, hdr->pline_root_direct_filter_mask);
+ UINT32DECODE(*pp, hdr->pline_root_direct_filter_mask);
/* Decode I/O filter information */
- if(NULL == (pline = (H5O_pline_t *)H5O_msg_decode(hdr->f, udata->dxpl_id, NULL, H5O_PLINE_ID, p)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't decode I/O pipeline filters")
- p += hdr->filter_len;
+ if(NULL == (pline = (H5O_pline_t *)H5O_msg_decode(f, dxpl_id, NULL, H5O_PLINE_ID, *pp)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, FAIL, "can't decode I/O pipeline filters")
+ *pp += hdr->filter_len;
/* Copy the information into the header's I/O pipeline structure */
if(NULL == H5O_msg_copy(H5O_PLINE_ID, pline, &(hdr->pline)))
- HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, NULL, "can't copy I/O filter pipeline")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, FAIL, "can't copy I/O filter pipeline")
/* Release the space allocated for the I/O pipeline filters */
H5O_msg_free(H5O_PLINE_ID, pline);
} /* end if */
- else
- /* Set the heap header's size */
- hdr->heap_size = size;
- /* Compute checksum on entire header */
- /* (including the filter information, if present) */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - (const uint8_t *)buf), 0);
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_full_header_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_cache_hdr_load
+ *
+ * Purpose: Loads a fractal heap header from the disk.
+ *
+ * Return: Success: Pointer to a new fractal heap
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Feb 24 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5HF_hdr_t *
+H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
+{
+ H5HF_hdr_t *hdr = NULL; /* Fractal heap info */
+ H5HF_hdr_cache_ud_t *udata = (H5HF_hdr_cache_ud_t *)_udata;
+ size_t size, new_size; /* Header size */
+ H5WB_t *wb = NULL; /* Wrapped buffer for header data */
+ uint8_t hdr_buf[H5HF_HDR_BUF_SIZE]; /* Buffer for header */
+ uint8_t *buf; /* Pointer to header buffer */
+ const uint8_t *p; /* Pointer into raw data buffer */
+ uint32_t stored_chksum; /* Stored metadata checksum value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ size_t tries, max_tries; /* The # of read attempts */
+ size_t fixed_tries;
+ H5HF_hdr_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(udata);
+
+ /* Allocate space for the fractal heap data structure */
+ if(NULL == (hdr = H5HF_hdr_alloc(udata->f)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't wrap buffer")
+
+ /* Compute the minimum size of the fractal heap header to determine filter info */
+ size = (size_t)H5HF_MIN_HEADER_SIZE;
+
+ /* Get the # of read attempts */
+ tries = max_tries = H5F_GET_READ_ATTEMPTS(f);
+ do {
+ /* Get a pointer to a buffer that's large enough for serialized header */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
+
+ fixed_tries = max_tries;
+ do {
+ /* Read minimum header from disk */
+ if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header")
+
+ /* Get temporary pointer to serialized header */
+ p = buf;
+
+ /* Decode minimum header info */
+ if(H5HF_min_header_decode(&p, hdr) >= 0)
+ break;
+ } while (--fixed_tries);
+
+ if(fixed_tries == 0)
+ /* After all tries (for SWMR access) or after 1 try (for non-SWMR) */
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad minimum header info in fractal heap header after all tries")
+ else if((max_tries - fixed_tries + 1) > 1)
+ HDfprintf(stderr, "%s: SUCCESS after %u attempts for minimum header in fractal heap\n", FUNC, max_tries - fixed_tries + 1);
+
+ /* Full header size */
+ new_size = (size_t)H5HF_HEADER_SIZE(hdr);
+
+ /* Check for I/O filter information to decode */
+ if(hdr->filter_len > 0)
+ /* Compute the heap header's size: fixed-len header size + variable-len I/O filter information */
+ hdr->heap_size = new_size
+ + (size_t)(hdr->sizeof_size /* Size of size for filtered root direct block */
+ + (unsigned)4 /* Size of filter mask for filtered root direct block */
+ + hdr->filter_len); /* Size of encoded I/O filter info */
+ else
+ /* Set the heap header's size: fixed-len header size */
+ hdr->heap_size = new_size;
+
+ /* Re-size current buffer */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, hdr->heap_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
+
+ /* Read the whole header with possibly filter info */
+ if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, addr, hdr->heap_size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header's I/O pipeline filter info")
+
+ /* Retrieve stored and computed checksums */
+ H5F_get_checksums(buf, hdr->heap_size, &stored_chksum, &computed_chksum);
+
+ /* Verify checksum */
+ if(stored_chksum == computed_chksum)
+ break;
+ } while (--tries);
+
+ if(tries == 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, NULL, "incorrect metadata checksum after all tries (%u) for fractal heap header", max_tries)
+ else if((max_tries - tries + 1) > 1)
+ HDfprintf(stderr, "%s: SUCCESS after %u attempts\n", FUNC, max_tries - tries + 1);
+
+ p = buf;
+
+ /* Decode full header info */
+ if(H5HF_full_header_decode(hdr->f, udata->dxpl_id, &p, hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, NULL, "unable to decode full header info")
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
@@ -414,7 +503,7 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Sanity check */
HDassert((size_t)(p - (const uint8_t *)buf) == hdr->heap_size);
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_get_checksums() */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap header")
@@ -755,9 +844,9 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, iblock->size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
- /* Read indirect block from disk */
- if(H5F_block_read(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap indirect block")
+ /* Read and validate indirect block from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, iblock->size, dxpl_id, buf, &computed_chksum) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap indirect block")
/* Get temporary pointer to serialized indirect block */
p = buf;
@@ -847,9 +936,6 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Sanity check */
HDassert(iblock->nchildren); /* indirect blocks w/no children should have been deleted */
- /* Compute checksum on indirect block */
- computed_chksum = H5_checksum_metadata(buf, (size_t)(p - (const uint8_t *)buf), 0);
-
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
@@ -1219,7 +1305,13 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
H5HF_direct_t *dblock = NULL; /* Direct block info */
const uint8_t *p; /* Pointer into raw data buffer */
haddr_t heap_addr; /* Address of heap header in the file */
- H5HF_direct_t *ret_value; /* Return value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ uint32_t stored_chksum; /* Metadata checksum value */
+ size_t tries, max_tries; /* The # of read attempts */
+ size_t chk_size; /* The size for validating checksum */
+ uint8_t *chk_p; /* Pointer to the area for validating checksum */
+ size_t read_size; /* Size of filtered direct block to read */
+ H5HF_direct_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -1256,58 +1348,91 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
if(NULL == (dblock->blk = H5FL_BLK_MALLOC(direct_block, (size_t)dblock->size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- /* Check for I/O filters on this heap */
+ /* Determine read_size for filter buffer */
if(hdr->filter_len > 0) {
- H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */
- size_t nbytes; /* Number of bytes used in buffer, after applying reverse filters */
- void *read_buf; /* Pointer to buffer to read in */
- size_t read_size; /* Size of filtered direct block to read */
- unsigned filter_mask; /* Excluded filters for direct block */
-
- /* Check for root direct block */
- if(par_info->iblock == NULL) {
- /* Sanity check */
- HDassert(H5F_addr_eq(hdr->man_dtable.table_addr, addr));
-
- /* Set up parameters to read filtered direct block */
- read_size = hdr->pline_root_direct_size;
- } /* end if */
- else {
- /* Sanity check */
- HDassert(H5F_addr_eq(par_info->iblock->ents[par_info->entry].addr, addr));
-
- /* Set up parameters to read filtered direct block */
- read_size = par_info->iblock->filt_ents[par_info->entry].size;
- } /* end else */
+ /* Check for root direct block */
+ if(par_info->iblock == NULL) {
+ /* Sanity check */
+ HDassert(H5F_addr_eq(hdr->man_dtable.table_addr, addr));
+
+ /* Set up parameters to read filtered direct block */
+ read_size = hdr->pline_root_direct_size;
+ } /* end if */
+ else {
+ /* Sanity check */
+ HDassert(H5F_addr_eq(par_info->iblock->ents[par_info->entry].addr, addr));
+
+ /* Set up parameters to read filtered direct block */
+ read_size = par_info->iblock->filt_ents[par_info->entry].size;
+ } /* end else */
+ } /* end if */
- /* Allocate buffer to perform I/O filtering on */
- if(NULL == (read_buf = H5MM_malloc(read_size)))
- HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "memory allocation failed for pipeline buffer")
+ tries = max_tries = H5F_GET_READ_ATTEMPTS(f);
+ do {
+ /* Check for I/O filters on this heap */
+ if(hdr->filter_len > 0) {
+ H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */
+ size_t nbytes; /* Number of bytes used in buffer, after applying reverse filters */
+ void *read_buf; /* Pointer to buffer to read in */
+ unsigned filter_mask; /* Excluded filters for direct block */
+
+ /* Allocate buffer to perform I/O filtering on */
+ if(NULL == (read_buf = H5MM_malloc(read_size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "memory allocation failed for pipeline buffer")
+
+ /* Read filtered direct block from disk */
+ if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, read_size, dxpl_id, read_buf) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block")
+
+ /* Push direct block data through I/O filter pipeline */
+ nbytes = read_size;
+ filter_mask = udata->filter_mask;
+ if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_ENABLE_EDC, filter_cb, &nbytes, &read_size, &read_buf) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, NULL, "output pipeline failed")
+
+ /* Sanity check */
+ HDassert(nbytes == dblock->size);
+
+ /* Copy un-filtered data into block's buffer */
+ HDmemcpy(dblock->blk, read_buf, dblock->size);
+
+ /* Release the read buffer */
+ H5MM_xfree(read_buf);
+ } /* end if */
+ else {
+ /* Read direct block from disk */
+ if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, dblock->size, dxpl_id, dblock->blk) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block")
+ } /* end else */
+
+ /* Get out if data block is not checksummed */
+ if(!(hdr->checksum_dblocks))
+ break;
+
+ /* Decode checksum on direct block, if requested */
+ chk_size = (size_t)(H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr) - H5HF_SIZEOF_CHKSUM);
+ chk_p = dblock->blk + chk_size;
+ /* Metadata checksum */
+ UINT32DECODE(chk_p, stored_chksum);
- /* Read filtered direct block from disk */
- if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, read_size, dxpl_id, read_buf) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block")
+ chk_p -= H5HF_SIZEOF_CHKSUM;
+ /* Reset checksum field, for computing the checksum */
+ /* (Casting away const OK - QAK) */
+ HDmemset(chk_p, 0, (size_t)H5HF_SIZEOF_CHKSUM);
- /* Push direct block data through I/O filter pipeline */
- nbytes = read_size;
- filter_mask = udata->filter_mask;
- if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_ENABLE_EDC, filter_cb, &nbytes, &read_size, &read_buf) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, NULL, "output pipeline failed")
+ /* Compute checksum on entire direct block */
+ computed_chksum = H5_checksum_metadata(dblock->blk, dblock->size, 0);
- /* Sanity check */
- HDassert(nbytes == dblock->size);
+ /* Verify checksum */
+ if(stored_chksum == computed_chksum)
+ break;
- /* Copy un-filtered data into block's buffer */
- HDmemcpy(dblock->blk, read_buf, dblock->size);
+ } while (--tries);
- /* Release the read buffer */
- H5MM_xfree(read_buf);
- } /* end if */
- else {
- /* Read direct block from disk */
- if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, dblock->size, dxpl_id, dblock->blk) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block")
- } /* end else */
+ if(tries == 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, NULL, "incorrect metadata checksum after all tries (%u) for fractal heap direct block", max_tries)
+ else if((max_tries - tries + 1) > 1)
+ HDfprintf(stderr, "%s: SUCCESS after %u attempts\n", FUNC, max_tries - tries + 1);
/* Start decoding direct block */
p = dblock->blk;
@@ -1339,24 +1464,8 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
UINT64DECODE_VAR(p, dblock->block_off, hdr->heap_off_size);
/* Decode checksum on direct block, if requested */
- if(hdr->checksum_dblocks) {
- uint32_t stored_chksum; /* Metadata checksum value */
- uint32_t computed_chksum; /* Computed metadata checksum value */
-
- /* Metadata checksum */
- UINT32DECODE(p, stored_chksum);
-
- /* Reset checksum field, for computing the checksum */
- /* (Casting away const OK - QAK) */
- HDmemset((uint8_t *)p - H5HF_SIZEOF_CHKSUM, 0, (size_t)H5HF_SIZEOF_CHKSUM);
-
- /* Compute checksum on entire direct block */
- computed_chksum = H5_checksum_metadata(dblock->blk, dblock->size, 0);
-
- /* Verify checksum */
- if(stored_chksum != computed_chksum)
- HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, NULL, "incorrect metadata checksum for fractal heap direct block")
- } /* end if */
+ if(hdr->checksum_dblocks)
+ p += H5HF_SIZEOF_CHKSUM;
/* Sanity check */
HDassert((size_t)(p - dblock->blk) == (size_t)H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr));
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 1252b9c..e602fc1 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -105,6 +105,14 @@
+ H5HF_DTABLE_INFO_SIZE(h) /* Size of managed obj. doubling-table info */ \
)
+/* Size of minimum header to decode for determining the full header size */
+#define H5HF_MIN_HEADER_SIZE ( \
+ H5_SIZEOF_MAGIC + /* Signature */ \
+ 1 + /* Version */ \
+ 2 + /* Heap ID len */ \
+ 2 /* I/O filters' encoded len */ \
+ )
+
/* Size of overhead for a direct block */
#define H5HF_MAN_ABS_DIRECT_OVERHEAD(h) ( \
/* General metadata fields */ \
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
index 80f5c05..3a087e5 100644
--- a/src/H5Ocache.c
+++ b/src/H5Ocache.c
@@ -92,7 +92,6 @@ static herr_t H5O_chunk_serialize(const H5F_t *f, H5O_t *oh, unsigned chunkno);
/* Misc. routines */
static herr_t H5O_add_cont_msg(H5O_cont_msgs_t *cont_msg_info,
const H5O_cont_t *cont);
-
static herr_t H5O_decode_prefix(H5F_t *f, H5O_t *oh, const uint8_t *buf, void *_udata);
@@ -315,12 +314,15 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
H5O_cache_ud_t *udata = (H5O_cache_ud_t *)_udata; /* User data for callback */
H5WB_t *wb = NULL; /* Wrapped buffer for prefix data */
uint8_t read_buf[H5O_SPEC_READ_SIZE]; /* Buffer for speculative read */
- const uint8_t *p; /* Pointer into buffer to decode */
uint8_t *buf; /* Buffer to decode */
size_t spec_read_size; /* Size of buffer to speculatively read in */
size_t buf_size; /* Size of prefix+chunk #0 buffer */
haddr_t eoa; /* Relative end of file address */
- H5O_t *ret_value; /* Return value */
+ size_t tries, max_tries; /* The # of read attempts */
+ size_t fixed_tries; /* The # of read attempts for prefix */
+ uint32_t stored_chksum; /* Stored metadata checksum value */
+ uint32_t computed_chksum; /* Computed metadata checksum value */
+ H5O_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -338,15 +340,89 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Compute the size of the speculative object header buffer */
H5_ASSIGN_OVERFLOW(spec_read_size, MIN(eoa - addr, H5O_SPEC_READ_SIZE), /* From: */ hsize_t, /* To: */ size_t);
- /* Attempt to speculatively read both object header prefix and first chunk */
- if(H5F_block_read(f, H5FD_MEM_OHDR, addr, spec_read_size, dxpl_id, read_buf) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header")
- p = read_buf;
-
/* Allocate space for the object header data structure */
if(NULL == (oh = H5FL_CALLOC(H5O_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ /* Wrap the local buffer for serialized header info */
+ if(NULL == (wb = H5WB_wrap(read_buf, sizeof(read_buf))))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't wrap buffer")
+
+ /* Get the # of read attempts */
+ tries = max_tries = H5F_GET_READ_ATTEMPTS(f);
+ do {
+ /* Get a pointer to a buffer that's large enough for serialized header */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, spec_read_size)))
+ HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer")
+
+ fixed_tries = max_tries;
+ do {
+ /* Attempt to speculatively read both object header prefix and first chunk */
+ if(H5F_block_read(f, H5FD_MEM_OHDR, addr, spec_read_size, dxpl_id, read_buf) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header")
+
+ /* Decode header prefix */
+ if(H5O_decode_prefix(f, oh, read_buf, udata) >= 0)
+ break;
+
+ } while (--fixed_tries);
+
+ if(fixed_tries == 0)
+ /* After all tries (for SWMR access) or after 1 try (for non-SWMR) */
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad object header prefix after all tries")
+ else if((max_tries - fixed_tries + 1) > 1)
+ HDfprintf(stderr, "%s: SUCCESS after %u attempts for fixed data\n", FUNC, max_tries - fixed_tries + 1);
+
+ /* Compute the size of the buffer used */
+ buf_size = oh->chunk0_size + (size_t)H5O_SIZEOF_HDR(oh);
+
+ /* Check if the speculative read was large enough to parse the first chunk */
+ if(spec_read_size < buf_size) {
+
+ /* Get a pointer to a buffer that's large enough for serialized header */
+ if(NULL == (buf = (uint8_t *)H5WB_actual(wb, buf_size)))
+ HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer")
+
+ /* SWMR access */
+ if(H5F_INTENT(f) & H5F_ACC_SWMR_READ || H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) {
+ /* Read the chunk that is bigger than the speculative read size */
+ if(H5F_block_read(f, H5FD_MEM_OHDR, addr, buf_size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header")
+ /* See if the data read now is the same as what is read initially */
+ if(HDmemcmp(buf, read_buf, spec_read_size)) {
+ HDmemset(oh, 0, sizeof(oh));
+ /* Decode the prefix again */
+ if(H5O_decode_prefix(f, oh, buf, udata) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't decode object header prefix")
+ }
+ } else {
+ /* Copy existing raw data into new buffer */
+ HDmemcpy(buf, read_buf, spec_read_size);
+
+ /* Read rest of the raw data */
+ if(H5F_block_read(f, H5FD_MEM_OHDR, (addr + spec_read_size), (buf_size - spec_read_size), dxpl_id, (buf + spec_read_size)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data")
+ }
+ } else
+ buf = read_buf;
+
+ /* There is no checksum for version 1 */
+ if(oh->version == H5O_VERSION_1)
+ break;
+
+ /* For version 2: retrieve the stored checksum and compute the checksum */
+ H5F_get_checksums(buf, buf_size, &stored_chksum, &computed_chksum);
+
+ /* Verify checksums */
+ if(stored_chksum == computed_chksum)
+ break;
+ } while (--tries);
+
+ if(tries == 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect metadata checksum for object header chunk after all read tries (%u) for %u bytes", max_tries, buf_size)
+ else if((max_tries - tries + 1) > 1)
+ HDfprintf(stderr, "%s: SUCCESS after %u attempts\n", FUNC, max_tries - tries + 1);
+
/* File-specific, non-stored information */
oh->sizeof_size = H5F_SIZEOF_SIZE(udata->common.f);
oh->sizeof_addr = H5F_SIZEOF_ADDR(udata->common.f);
@@ -355,49 +431,11 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Create object header proxy if doing SWMR writes */
HDassert(!oh->proxy_present);
if(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) {
- if(H5O_proxy_create(f, dxpl_id, oh) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, NULL, "can't create object header proxy")
+ if(H5O_proxy_create(f, dxpl_id, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, NULL, "can't create object header proxy")
} /* end if */
else
- oh->proxy_addr = HADDR_UNDEF;
-
- if(H5O_decode_prefix(f, oh, read_buf, udata) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't decode object header prefix")
-
- /* Compute the size of the buffer used */
- buf_size = oh->chunk0_size + (size_t)H5O_SIZEOF_HDR(oh);
-
- /* Check if the speculative read was large enough to parse the first chunk */
- if(spec_read_size < buf_size) {
- /* Wrap the local buffer for serialized header info */
- if(NULL == (wb = H5WB_wrap(read_buf, sizeof(read_buf))))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't wrap buffer")
-
- /* Get a pointer to a buffer that's large enough for serialized header */
- if(NULL == (buf = (uint8_t *)H5WB_actual(wb, buf_size)))
- HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer")
-
- /* SWMR access */
- if(H5F_INTENT(f) & H5F_ACC_SWMR_READ || H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) {
- /* Read the chunk that is bigger than the speculative read size */
- if(H5F_block_read(f, H5FD_MEM_OHDR, addr, buf_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header")
- /* See if the data read now is the same as what is read initially */
- if(HDmemcmp(buf, read_buf, spec_read_size)) {
- HDmemset(oh, 0, sizeof(oh));
- if(H5O_decode_prefix(f, oh, buf, udata) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't decode object header prefix")
- }
- } else {
- /* Copy existing raw data into new buffer */
- HDmemcpy(buf, read_buf, spec_read_size);
-
- /* Read rest of the raw data */
- if(H5F_block_read(f, H5FD_MEM_OHDR, (addr + spec_read_size), (buf_size - spec_read_size), dxpl_id, (buf + spec_read_size)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data")
- }
- } else
- buf = read_buf;
+ oh->proxy_addr = HADDR_UNDEF;
/* Parse the first chunk */
if(H5O_chunk_deserialize(oh, udata->common.addr, oh->chunk0_size, buf, &(udata->common), &oh->cache_info.is_dirty) < 0)
@@ -778,8 +816,15 @@ H5O_cache_chk_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read rest of the raw data */
- if(H5F_block_read(f, H5FD_MEM_OHDR, addr, udata->size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header continuation chunk")
+ if(udata->oh->version == H5O_VERSION_2 && udata->decoding) {
+ /* Read and validate object header continuation chunk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_OHDR, addr, udata->size, udata->size, dxpl_id, buf, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "incorrect metadata checksum for object header continuation chunk")
+ } else {
+ /* Read the header object continuation chunk */
+ if(H5F_block_read(f, H5FD_MEM_OHDR, addr, udata->size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header continuation chunk")
+ }
/* Check if we are still decoding the object header */
/* (as opposed to bringing a piece of it back from the file) */
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index a416b00..adae24f 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -160,7 +160,11 @@
#define H5F_ACS_FILE_IMAGE_INFO_DEL H5P_file_image_info_del
#define H5F_ACS_FILE_IMAGE_INFO_COPY H5P_file_image_info_copy
#define H5F_ACS_FILE_IMAGE_INFO_CLOSE H5P_file_image_info_close
-
+/* Definition for # of read attempts */
+#define H5F_ACS_READ_ATTEMPTS_SIZE sizeof(unsigned)
+#define H5F_ACS_READ_ATTEMPTS_DEF 0
+#define H5F_ACS_READ_ATTEMPTS_ENC H5P__encode_unsigned
+#define H5F_ACS_READ_ATTEMPTS_DEC H5P__decode_unsigned
/******************/
/* Local Typedefs */
@@ -247,7 +251,7 @@ static const hbool_t H5F_def_latest_format_g = H5F_ACS_LATEST_FORMAT_DEF;
static const hbool_t H5F_def_want_posix_fd_g = H5F_ACS_WANT_POSIX_FD_DEF; /* Default setting for retrieving 'handle' from core VFD */
static const unsigned H5F_def_efc_size_g = H5F_ACS_EFC_SIZE_DEF; /* Default external file cache size */
static const H5FD_file_image_info_t H5F_def_file_image_info_g = H5F_ACS_FILE_IMAGE_INFO_DEF; /* Default file image info and callbacks */
-
+static const unsigned H5F_def_read_attempts_g = H5F_ACS_READ_ATTEMPTS_DEF; /* Default setting for the # of read attempts */
/*-------------------------------------------------------------------------
@@ -397,6 +401,11 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass)
H5F_ACS_FILE_IMAGE_INFO_DEL, H5F_ACS_FILE_IMAGE_INFO_COPY, NULL, H5F_ACS_FILE_IMAGE_INFO_CLOSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the # of read attempts */
+ if(H5P_register_real(pclass, H5F_ACS_READ_ATTEMPTS_NAME, H5F_ACS_READ_ATTEMPTS_SIZE, &H5F_def_read_attempts_g,
+ NULL, NULL, NULL, H5F_ACS_READ_ATTEMPTS_ENC, H5F_ACS_READ_ATTEMPTS_DEC,
+ NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P_facc_reg_prop() */
@@ -2980,3 +2989,82 @@ H5P__facc_multi_type_dec(const void **_pp, void *_value)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5P__facc_multi_type_dec() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_read_attempts
+ *
+ * Purpose: Sets the # of read attempts in the file access property list
+ * when reading metadata with checksum.
+ * The # of read attempts set via this routine will apply only
+ * when opening file with SWMR access. When opening file with
+ * non-SWMR access, the # of read attempts will always be 1.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Sept 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_read_attempts(hid_t plist_id, unsigned attempts)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "iIu", plist_id, attempts);
+
+ /* Cannot set the # of attempts to 0 */
+ if(attempts <= 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of attempts must be greater than 0");
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Set values */
+ if(H5P_set(plist, H5F_ACS_READ_ATTEMPTS_NAME, &attempts) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set # of read attempts")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pset_read_attempts() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_read_attempts
+ *
+ * Purpose: Returns the # of read attempts set in the file access property list.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Sept 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_read_attempts(hid_t plist_id, unsigned *attempts/*out*/)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ix", plist_id, attempts);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get values */
+ if(attempts) {
+ /* Get the # of read attempts set */
+ if(H5P_get(plist, H5F_ACS_READ_ATTEMPTS_NAME, attempts) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get alignment")
+ /* If not set, return the default value */
+ if(*attempts == H5F_ACS_READ_ATTEMPTS_DEF) /* 0 */
+ *attempts = H5F_READ_ATTEMPTS;
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_read_attempts() */
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index efcba65..f2b9e8f 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -344,6 +344,8 @@ H5_DLL herr_t H5Pset_file_image_callbacks(hid_t fapl_id,
H5FD_file_image_callbacks_t *callbacks_ptr);
H5_DLL herr_t H5Pget_file_image_callbacks(hid_t fapl_id,
H5FD_file_image_callbacks_t *callbacks_ptr);
+H5_DLL herr_t H5Pset_read_attempts(hid_t plist_id, unsigned attempts);
+H5_DLL herr_t H5Pget_read_attempts(hid_t plist_id, unsigned *attempts/*out*/);
/* Dataset creation property list (DCPL) routines */
H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout);
diff --git a/src/H5SMcache.c b/src/H5SMcache.c
index 9955f39..c5b333f 100644
--- a/src/H5SMcache.c
+++ b/src/H5SMcache.c
@@ -158,9 +158,9 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *udata)
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, table->table_size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer")
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_SOHM_TABLE, addr, table->table_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM table")
+ /* Read and validate shared message table from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_SOHM_TABLE, addr, table->table_size, table->table_size, dxpl_id, buf, &computed_chksum) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message table")
/* Get temporary pointer to serialized table */
p = buf;
@@ -214,10 +214,7 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *udata)
/* Sanity check */
HDassert((size_t)(p - (const uint8_t *)buf) == table->table_size);
- /* Compute checksum on entire header */
- computed_chksum = H5_checksum_metadata(buf, (table->table_size - H5SM_SIZEOF_CHECKSUM), 0);
-
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message table")
@@ -466,6 +463,7 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
size_t x; /* Counter variable for messages in list */
+ uint32_t chk_size; /* Exact size with checksum at the end */
H5SM_list_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -492,9 +490,13 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
if(NULL == (buf = (uint8_t *)H5WB_actual(wb, udata->header->list_size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer")
- /* Read list from disk */
- if(H5F_block_read(f, H5FD_MEM_SOHM_INDEX, addr, udata->header->list_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM list")
+ /* Exact size with checksum at the end */
+ chk_size = H5SM_LIST_SIZE(udata->f, udata->header->num_messages);
+
+ /* Read and validate shared message list from disk */
+ if(H5F_read_check_metadata(f, H5FD_MEM_SOHM_INDEX, addr, udata->header->list_size, chk_size, dxpl_id, buf, &computed_chksum) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message list")
+
/* Get temporary pointer to serialized list index */
p = buf;
@@ -518,10 +520,7 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Sanity check */
HDassert((size_t)(p - buf) <= udata->header->list_size);
- /* Compute checksum on entire header */
- computed_chksum = H5_checksum_metadata(buf, ((size_t)(p - buf) - H5SM_SIZEOF_CHECKSUM), 0);
-
- /* Verify checksum */
+ /* Verify checksum with checksum computed via H5F_read_check_metadata() */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message list")
diff --git a/test/accum.c b/test/accum.c
index 6c89765..1a218c6 100644
--- a/test/accum.c
+++ b/test/accum.c
@@ -168,7 +168,7 @@ test_write_read(void)
/* Allocate buffers */
write_buf = (int *)HDmalloc(1024 * sizeof(int));
HDassert(write_buf);
- read_buf = (int *)HDcalloc(1024, sizeof(int));
+ read_buf = (int *)HDcalloc((size_t)1024, sizeof(int));
HDassert(read_buf);
/* Fill buffer with data, zero out read buffer */
@@ -179,7 +179,7 @@ test_write_read(void)
/* Write 1KB at Address 0 */
if(accum_write(0, 1024, write_buf) < 0) FAIL_STACK_ERROR;
if(accum_read(0, 1024, read_buf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(write_buf, read_buf, 1024) != 0) TEST_ERROR;
+ if(HDmemcmp(write_buf, read_buf, (size_t)1024) != 0) TEST_ERROR;
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -224,7 +224,7 @@ test_write_read_nonacc_front(void)
/* Allocate buffers */
write_buf = (int *)HDmalloc(2048 * sizeof(int));
HDassert(write_buf);
- read_buf = (int *)HDcalloc(2048, sizeof(int));
+ read_buf = (int *)HDcalloc((size_t)2048, sizeof(int));
HDassert(read_buf);
/* Fill buffer with data, zero out read buffer */
@@ -238,7 +238,7 @@ test_write_read_nonacc_front(void)
if(accum_reset() < 0) FAIL_STACK_ERROR;
if(accum_write(1024, 1024, write_buf) < 0) FAIL_STACK_ERROR;
if(accum_read(0, 1024, read_buf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(write_buf, read_buf, 1024) != 0) TEST_ERROR;
+ if(HDmemcmp(write_buf, read_buf, (size_t)1024) != 0) TEST_ERROR;
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -283,7 +283,7 @@ test_write_read_nonacc_end(void)
/* Allocate buffers */
write_buf = (int *)HDmalloc(2048 * sizeof(int));
HDassert(write_buf);
- read_buf = (int *)HDcalloc(2048, sizeof(int));
+ read_buf = (int *)HDcalloc((size_t)2048, sizeof(int));
HDassert(read_buf);
/* Fill buffer with data, zero out read buffer */
@@ -297,7 +297,7 @@ test_write_read_nonacc_end(void)
if(accum_reset() < 0) FAIL_STACK_ERROR;
if(accum_write(0, 1024, write_buf) < 0) FAIL_STACK_ERROR;
if(accum_read(1024, 1024, read_buf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(write_buf, read_buf, 1024) != 0) TEST_ERROR;
+ if(HDmemcmp(write_buf, read_buf, (size_t)1024) != 0) TEST_ERROR;
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -529,7 +529,7 @@ test_accum_overlap(void)
/* Allocate buffers */
wbuf = (int32_t *)HDmalloc(4096 * sizeof(int32_t));
HDassert(wbuf);
- rbuf = (int32_t *)HDcalloc(4096, sizeof(int32_t));
+ rbuf = (int32_t *)HDcalloc((size_t)4096, sizeof(int32_t));
HDassert(rbuf);
/* Case 1: No metadata in accumulator */
@@ -701,7 +701,7 @@ test_accum_overlap_clean(void)
/* Allocate buffers */
wbuf = (int32_t *)HDmalloc(4096 * sizeof(int32_t));
HDassert(wbuf);
- rbuf = (int32_t *)HDcalloc(4096, sizeof(int32_t));
+ rbuf = (int32_t *)HDcalloc((size_t)4096, sizeof(int32_t));
HDassert(rbuf);
/* Case 1: No metadata in accumulator */
@@ -880,7 +880,7 @@ test_accum_non_overlap_size(void)
/* Allocate buffers */
wbuf = (int *)HDmalloc(4096 * sizeof(int32_t));
HDassert(wbuf);
- rbuf = (int *)HDcalloc(4096, sizeof(int32_t));
+ rbuf = (int *)HDcalloc((size_t)4096, sizeof(int32_t));
HDassert(rbuf);
/* Case 1: No metadata in accumulator */
@@ -947,7 +947,7 @@ test_accum_overlap_size(void)
/* Allocate buffers */
wbuf = (int32_t *)HDmalloc(4096 * sizeof(int32_t));
HDassert(wbuf);
- rbuf = (int32_t *)HDcalloc(4096, sizeof(int32_t));
+ rbuf = (int32_t *)HDcalloc((size_t)4096, sizeof(int32_t));
HDassert(rbuf);
/* Case 1: No metadata in accumulator */
@@ -1054,11 +1054,11 @@ test_accum_adjust(void)
/* Read back and verify first write */
if(accum_read((1024 * 1024), (1024 * 1024) - 1, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, (1024 * 1024) - 1) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)((1024 * 1024) - 1)) != 0) TEST_ERROR;
/* Read back and verify second write */
if(accum_read((1024 * 1024) - 1024, 1024, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, 1024) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)1024) != 0) TEST_ERROR;
/* Reset accumulator for next case */
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1084,10 +1084,10 @@ test_accum_adjust(void)
/* Read back and verify both pieces of data */
if(accum_read(1048576, 1048575, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, 1048576) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)1048576) != 0) TEST_ERROR;
if(accum_read(5, 1048571, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, 1048571) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)1048571) != 0) TEST_ERROR;
/* Reset accumulator for next case */
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1122,7 +1122,7 @@ test_accum_adjust(void)
/* Read in the piece we wrote to disk above, and then verify that
the data is as expected */
if(accum_read((1024 * 1024) - 1, 1024, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, 1024) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)1024) != 0) TEST_ERROR;
/* Reset accumulator for next case */
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1162,7 +1162,7 @@ test_accum_adjust(void)
/* Read in the piece we wrote to disk above, and then verify that
the data is as expected */
if(accum_read(1048571, 349523, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, 349523) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)349523) != 0) TEST_ERROR;
/* Reset accumulator for next case */
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1199,7 +1199,7 @@ test_accum_adjust(void)
/* Read in the piece we wrote to disk above, and then verify that
the data is as expected */
if(accum_read((1024 * 1024) - 5, 10, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, 10) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)10) != 0) TEST_ERROR;
/* Reset accumulator for next case */
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1231,7 +1231,7 @@ test_accum_adjust(void)
/* Read in the piece we wrote to disk above, and then verify that
the data is as expected */
if(accum_read(1048571, 349523, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, 349523) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)349523) != 0) TEST_ERROR;
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1314,7 +1314,7 @@ test_read_after(void)
/* Read in the piece we wrote to disk above, and then verify that
the data is as expected */
if(accum_read(512, 512, rbuf) < 0) FAIL_STACK_ERROR;
- if(HDmemcmp(wbuf, rbuf, 128) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)128) != 0) TEST_ERROR;
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1356,13 +1356,13 @@ test_big(void)
unsigned u; /* Local index variable */
/* Allocate space for the write & read buffers */
- wbuf = (uint8_t *)HDmalloc(BIG_BUF_SIZE);
+ wbuf = (uint8_t *)HDmalloc((size_t)BIG_BUF_SIZE);
HDassert(wbuf);
- wbuf2 = (uint8_t *)HDmalloc(BIG_BUF_SIZE);
+ wbuf2 = (uint8_t *)HDmalloc((size_t)BIG_BUF_SIZE);
HDassert(wbuf2);
- rbuf = (uint8_t *)HDcalloc(BIG_BUF_SIZE + 1536, 1);
+ rbuf = (uint8_t *)HDcalloc((size_t)(BIG_BUF_SIZE + 1536), (size_t)1);
HDassert(rbuf);
- zbuf = (uint8_t *)HDcalloc(BIG_BUF_SIZE + 1536, 1);
+ zbuf = (uint8_t *)HDcalloc((size_t)(BIG_BUF_SIZE + 1536), (size_t)1);
HDassert(zbuf);
/* Initialize write buffers */
@@ -1380,12 +1380,12 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(wbuf, rbuf, BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(0, BIG_BUF_SIZE, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE);
+ HDmemset(rbuf, 0, (size_t)BIG_BUF_SIZE);
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1397,14 +1397,14 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(zbuf, rbuf, 1024) != 0) TEST_ERROR;
- if(HDmemcmp(wbuf, rbuf + 1024, 1024) != 0) TEST_ERROR;
- if(HDmemcmp(zbuf, rbuf + 2048, (BIG_BUF_SIZE - 2048)) != 0) TEST_ERROR;
+ if(HDmemcmp(zbuf, rbuf, (size_t)1024) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf + 1024, (size_t)1024) != 0) TEST_ERROR;
+ if(HDmemcmp(zbuf, rbuf + 2048, (size_t)(BIG_BUF_SIZE - 2048)) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(1024, 1024, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE);
+ HDmemset(rbuf, 0, (size_t)BIG_BUF_SIZE);
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1416,13 +1416,13 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(zbuf, rbuf, (BIG_BUF_SIZE - 512)) != 0) TEST_ERROR;
- if(HDmemcmp(wbuf, rbuf + (BIG_BUF_SIZE - 512), 512) != 0) TEST_ERROR;
+ if(HDmemcmp(zbuf, rbuf, (size_t)(BIG_BUF_SIZE - 512)) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf + (BIG_BUF_SIZE - 512), (size_t)512) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(BIG_BUF_SIZE - 512, 1024, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE);
+ HDmemset(rbuf, 0, (size_t)BIG_BUF_SIZE);
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1434,13 +1434,13 @@ test_big(void)
if(accum_read(512, BIG_BUF_SIZE, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(wbuf + 512, rbuf, 512) != 0) TEST_ERROR;
- if(HDmemcmp(zbuf, rbuf + 512, (BIG_BUF_SIZE - 512)) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf + 512, rbuf, (size_t)512) != 0) TEST_ERROR;
+ if(HDmemcmp(zbuf, rbuf + 512, (size_t)(BIG_BUF_SIZE - 512)) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(0, 1024, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE);
+ HDmemset(rbuf, 0, (size_t)BIG_BUF_SIZE);
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1457,12 +1457,12 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(wbuf2, rbuf, BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf2, rbuf, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(0, BIG_BUF_SIZE, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE);
+ HDmemset(rbuf, 0, (size_t)BIG_BUF_SIZE);
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1479,13 +1479,13 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE + 512, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(wbuf2, rbuf, BIG_BUF_SIZE) != 0) TEST_ERROR;
- if(HDmemcmp(wbuf + 512, rbuf + BIG_BUF_SIZE, 512) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf2, rbuf, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf + 512, rbuf + BIG_BUF_SIZE, (size_t)512) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(0, BIG_BUF_SIZE + 512, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE + 512);
+ HDmemset(rbuf, 0, (size_t)(BIG_BUF_SIZE + 512));
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1506,14 +1506,14 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE + 1024, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(wbuf2, rbuf, BIG_BUF_SIZE) != 0) TEST_ERROR;
- if(HDmemcmp(zbuf, rbuf + BIG_BUF_SIZE, 512) != 0) TEST_ERROR;
- if(HDmemcmp(wbuf, rbuf + BIG_BUF_SIZE + 512, 512) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf2, rbuf, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(zbuf, rbuf + BIG_BUF_SIZE, (size_t)512) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf + BIG_BUF_SIZE + 512, (size_t)512) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(0, BIG_BUF_SIZE + 1536, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE + 1024);
+ HDmemset(rbuf, 0, (size_t)(BIG_BUF_SIZE + 1024));
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1535,13 +1535,13 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE + 1536, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(zbuf, rbuf, 1536) != 0) TEST_ERROR;
- if(HDmemcmp(wbuf2, rbuf + 1536, BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(zbuf, rbuf, (size_t)1536) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf2, rbuf + 1536, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(1536, BIG_BUF_SIZE, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE + 1536);
+ HDmemset(rbuf, 0, (size_t)(BIG_BUF_SIZE + 1536));
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1562,13 +1562,13 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE + 512, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(zbuf, rbuf, 512) != 0) TEST_ERROR;
- if(HDmemcmp(wbuf2, rbuf + 512, BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(zbuf, rbuf, (size_t)512) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf2, rbuf + 512, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(512, BIG_BUF_SIZE, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE + 512);
+ HDmemset(rbuf, 0, (size_t)(BIG_BUF_SIZE + 512));
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1589,14 +1589,14 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE + 1536, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(wbuf, rbuf, 1024) != 0) TEST_ERROR;
- if(HDmemcmp(zbuf, rbuf + 1024, 512) != 0) TEST_ERROR;
- if(HDmemcmp(wbuf2, rbuf + 1536, BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)1024) != 0) TEST_ERROR;
+ if(HDmemcmp(zbuf, rbuf + 1024, (size_t)512) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf2, rbuf + 1536, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
/* Reset data in file back to zeros & reset the read buffer */
if(accum_write(0, BIG_BUF_SIZE + 1536, zbuf) < 0) FAIL_STACK_ERROR;
- HDmemset(rbuf, 0, BIG_BUF_SIZE + 1536);
+ HDmemset(rbuf, 0, (size_t)(BIG_BUF_SIZE + 1536));
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1617,8 +1617,8 @@ test_big(void)
if(accum_read(0, BIG_BUF_SIZE + 512, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read */
- if(HDmemcmp(wbuf, rbuf, 512) != 0) TEST_ERROR;
- if(HDmemcmp(wbuf2, rbuf + 512, BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)512) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf2, rbuf + 512, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1670,9 +1670,9 @@ test_random_write(void)
unsigned u; /* Local index variable */
/* Allocate space for the write & read buffers */
- wbuf = (uint8_t *)malloc(RANDOM_BUF_SIZE);
+ wbuf = (uint8_t *)malloc((size_t)RANDOM_BUF_SIZE);
HDassert(wbuf);
- rbuf = (uint8_t *)calloc(RANDOM_BUF_SIZE, 1);
+ rbuf = (uint8_t *)calloc((size_t)RANDOM_BUF_SIZE, (size_t)1);
HDassert(rbuf);
/* Initialize write buffer */
@@ -1756,7 +1756,7 @@ HDfprintf(stderr, "Random # seed was: %u\n", seed);
if(accum_read(RANDOM_BASE_OFF, RANDOM_BUF_SIZE, rbuf) < 0) FAIL_STACK_ERROR;
/* Verify data read back in */
- if(HDmemcmp(wbuf, rbuf, RANDOM_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)RANDOM_BUF_SIZE) != 0) TEST_ERROR;
if(accum_reset() < 0) FAIL_STACK_ERROR;
@@ -1810,6 +1810,8 @@ test_swmr_write_big(void)
unsigned u; /* Local index variable */
pid_t pid; /* Process ID */
int status; /* Status returned from child process */
+ char *new_argv[] = {NULL};
+ char *new_envp[] = {NULL};
TESTING("SWMR write of large metadata");
@@ -1845,9 +1847,9 @@ test_swmr_write_big(void)
FAIL_STACK_ERROR;
/* Allocate space for the write & read buffers */
- if((wbuf2 = (uint8_t *)HDmalloc(BIG_BUF_SIZE)) == NULL)
+ if((wbuf2 = (uint8_t *)HDmalloc((size_t)BIG_BUF_SIZE)) == NULL)
FAIL_STACK_ERROR;
- if((rbuf = (uint8_t *)HDmalloc(BIG_BUF_SIZE)) == NULL)
+ if((rbuf = (uint8_t *)HDmalloc((size_t)BIG_BUF_SIZE)) == NULL)
FAIL_STACK_ERROR;
/* Initialize wbuf with "0, 1, 2...1024"*/
@@ -1861,7 +1863,7 @@ test_swmr_write_big(void)
if(H5F_block_read(rf, H5FD_MEM_DEFAULT, (haddr_t)1024, (size_t)1024, H5P_DATASET_XFER_DEFAULT, rbuf) < 0)
FAIL_STACK_ERROR;
/* Verify the data read is correct */
- if(HDmemcmp(wbuf, rbuf, 1024) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)1024) != 0) TEST_ERROR;
/* Flush the data to disk */
if(H5F_accum_reset(rf, H5P_DATASET_XFER_DEFAULT, TRUE) < 0)
FAIL_STACK_ERROR;
@@ -1881,7 +1883,7 @@ test_swmr_write_big(void)
if(H5F_block_read(rf, H5FD_MEM_DEFAULT, (haddr_t)1024, (size_t)1024, H5P_DATASET_XFER_DEFAULT, rbuf) < 0)
FAIL_STACK_ERROR;
/* Verify the data read is correct */
- if(HDmemcmp(wbuf, rbuf, 1024) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf, rbuf, (size_t)1024) != 0) TEST_ERROR;
/* The data stays in the accumulator */
/* Write a large piece of metadata [2048, BIG_BUF_SIZE] with wbuf2 */
@@ -1891,7 +1893,7 @@ test_swmr_write_big(void)
if(H5F_block_read(rf, H5FD_MEM_DEFAULT, (haddr_t)2048, (size_t)BIG_BUF_SIZE, H5P_DATASET_XFER_DEFAULT, rbuf) < 0)
FAIL_STACK_ERROR;
/* Verify the data read is correct */
- if(HDmemcmp(wbuf2, rbuf, BIG_BUF_SIZE) != 0) TEST_ERROR;
+ if(HDmemcmp(wbuf2, rbuf, (size_t)BIG_BUF_SIZE) != 0) TEST_ERROR;
/* Fork child process to verify that the data at [1024, 2014] does get written to disk */
if((pid = HDfork()) < 0) {
@@ -1899,7 +1901,8 @@ test_swmr_write_big(void)
FAIL_STACK_ERROR;
} else if(0 == pid) { /* Child process */
/* Run the reader */
- status = HDexecve(SWMR_READER, NULL, NULL);
+ status = HDexecve(SWMR_READER, new_argv, new_envp);
+ printf("errno from execve = %s\n", strerror(errno));
FAIL_STACK_ERROR;
}
diff --git a/test/swmr_generator.c b/test/swmr_generator.c
index f0fcee6..bad992b 100644
--- a/test/swmr_generator.c
+++ b/test/swmr_generator.c
@@ -332,6 +332,7 @@ int main(int argc, const char *argv[])
gettimeofday(&t, NULL);
random_seed = (unsigned)((t.tv_sec * 1000) + t.tv_usec);
} /* end if */
+ /* random_seed = 125092666; */
srandom(random_seed);
/* ALWAYS emit the random seed for possible debugging */
fprintf(stderr, "Using generator random seed (used in sparse test only): %u\n", random_seed);
diff --git a/test/testfiles/plist_files/fapl_be b/test/testfiles/plist_files/fapl_be
index 8fcefa2..24e944c 100644
--- a/test/testfiles/plist_files/fapl_be
+++ b/test/testfiles/plist_files/fapl_be
Binary files differ
diff --git a/test/testfiles/plist_files/fapl_le b/test/testfiles/plist_files/fapl_le
index 8fcefa2..24e944c 100644
--- a/test/testfiles/plist_files/fapl_le
+++ b/test/testfiles/plist_files/fapl_le
Binary files differ
diff --git a/test/testfiles/plist_files/lapl_be b/test/testfiles/plist_files/lapl_be
index 30f52a4..2ab61ed 100644
--- a/test/testfiles/plist_files/lapl_be
+++ b/test/testfiles/plist_files/lapl_be
Binary files differ
diff --git a/test/testfiles/plist_files/lapl_le b/test/testfiles/plist_files/lapl_le
index 30f52a4..2ab61ed 100644
--- a/test/testfiles/plist_files/lapl_le
+++ b/test/testfiles/plist_files/lapl_le
Binary files differ
diff --git a/test/tfile.c b/test/tfile.c
index 07e6ab1..200279c 100644
--- a/test/tfile.c
+++ b/test/tfile.c
@@ -3566,6 +3566,571 @@ test_swmr_read(void)
/****************************************************************
**
+** test_read_attempts():
+** This test checks whether the public routines H5Pset_read_attempts()
+** and H5Pget_read_attempts() work properly.
+**
+*****************************************************************/
+static void
+test_read_attempts(void)
+{
+ hid_t fapl; /* File access property list */
+ hid_t file_fapl; /* The file's access property list */
+ hid_t fid, fid1, fid2, fid3; /* File IDs */
+ unsigned attempts; /* The # of read attempts */
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing H5Fget/set_read_attempts()\n"));
+
+ /*
+ * Set A:
+ * Tests on verifying the # of read attempts when:
+ * --setting/getting read attemps from a copy of the
+ * file access property list.
+ */
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Get # of read attempts -- should be the default: 1 */
+ ret = H5Pget_read_attempts(fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, 1, "H5Pget_read_attempts");
+
+ /* Set the # of read attempts to 0--should fail */
+ ret = H5Pset_read_attempts(fapl, 0);
+ VERIFY(ret, FAIL, "H5Pset_read_attempts");
+
+ /* Set the # of read attempts to a # > 0--should succeed */
+ ret = H5Pset_read_attempts(fapl, 9);
+ VERIFY(ret, 0, "H5Pset_read_attempts");
+
+ /* Retrieve the # of read attempts -- should succeed and equal to 9 */
+ ret = H5Pget_read_attempts(fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, 9, "H5Pget_read_attempts");
+
+ /* Set the # of read attempts to the non-SWMR access default: H5F_READ_ATTEMPTS --should succeed */
+ ret = H5Pset_read_attempts(fapl, H5F_READ_ATTEMPTS);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+
+ /* Retrieve the # of read attempts -- should succeed and equal to H5F_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Set the # of read attempts to the SWMR access default: H5F_SWMR_READ_ATEMPTS --should succeed */
+ ret = H5Pset_read_attempts(fapl, H5F_SWMR_READ_ATTEMPTS);
+ VERIFY(ret, 0, "H5Pset_read_attempts");
+
+ /* Retrieve the # of read attempts -- should succeed and equal to H5F_SWMR_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_SWMR_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ ret = H5Pclose(fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /*
+ * Set B:
+ * Tests on verifying read attempts when:
+ * --create a file with non-SWMR access
+ * --opening files with SWMR access
+ * --using default or non-default file access property list
+ */
+ /* Test 1 */
+ /* Create a file with non-SWMR access and default fapl */
+ fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file's fapl -- should be H5F_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Test 2 */
+ /* Open the file with SWMR access and default fapl */
+ fid = H5Fopen(FILE1, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file's fapl -- should be H5F_SWMR_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_SWMR_READ_ATTEMPTS, "H5Fget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Test 3 */
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Set the # of read attempts */
+ ret = H5Pset_read_attempts(fapl, 9);
+ CHECK(ret, FAIL, "H5Pset_read_attempts");
+
+ /* Open the file with SWMR access and fapl (non-default & set to 9) */
+ fid = H5Fopen(FILE1, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file's fapl -- should be 9 */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, 9, "H5Pget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Test 4 */
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Set the # of read attempts */
+ ret = H5Pset_read_attempts(fapl, 1);
+ CHECK(ret, FAIL, "H5Pset_read_attempts");
+
+ /* Open the file with SWMR access and fapl (non-default & set to 1) */
+ fid = H5Fopen(FILE1, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file fapl -- should succeed and equal to 1 */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, 1, "H5Pget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Test 5 */
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Open the file with SWMR_READ and fapl (non-default but unset) */
+ fid = H5Fopen(FILE1, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file's fapl -- should be H5F_SWMR_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_SWMR_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /*
+ * Set C:
+ * Tests on verifying read attempts when:
+ * --create a file with SWMR access
+ * --opening files with non-SWMR access
+ * --using default or non-default file access property list
+ */
+ /* Test 1 */
+ /* Create a file with non-SWMR access and default fapl */
+ fid = H5Fcreate(FILE1, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file's fapl -- should be H5F_SWMR_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_SWMR_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Test 2 */
+ /* Open the file with non-SWMR access and default fapl */
+ fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file's fapl -- should be H5F_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Test 3 */
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Set the # of read attempts */
+ ret = H5Pset_read_attempts(fapl, 9);
+ CHECK(ret, FAIL, "H5Pset_read_attempts");
+
+ /* Open the file with SWMR access and fapl (non-default & set to 9) */
+ fid = H5Fopen(FILE1, H5F_ACC_RDONLY, fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file's fapl -- should be H5F_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Test 4 */
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Set the # of read attempts */
+ ret = H5Pset_read_attempts(fapl, 1);
+ CHECK(ret, FAIL, "H5Pset_read_attempts");
+
+ /* Open the file with SWMR access and fapl (non-default & set to 1) */
+ fid = H5Fopen(FILE1, H5F_ACC_RDONLY, fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file fapl -- should succeed and equal to 1 */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, 1, "H5Fget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Test 5 */
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Open the file with SWMR_READ and fapl (non-default but unset) */
+ fid = H5Fopen(FILE1, H5F_ACC_RDONLY, fapl);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Pget_access_plist");
+
+ /* Retrieve the # of read attempts from file's fapl -- should be H5F_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_READ_ATTEMPTS, "H5Fget_read_attempts");
+
+ /* Close the file */
+ ret=H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+
+
+
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Set the # of read attempts */
+ ret = H5Pset_read_attempts(fapl, 9);
+ CHECK(ret, FAIL, "H5Pset_read_attempts");
+
+ /* Create a file */
+ fid = H5Fcreate(FILE1, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, fapl);
+ CHECK(fid1, FAIL, "H5Fcreate");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Open file again with SWMR access and default fapl */
+ fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file fapl -- should be H5F_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Close the file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Open file again with SWMR access and default fapl */
+ fid = H5Fopen(FILE1, H5F_ACC_SWMR_READ, H5P_DEFAULT);
+ CHECK(fid2, FAIL, "H5Fopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file fapl -- should be H5F_SWMR_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_SWMR_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Close the file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /*
+ * Set D:
+ * Tests on verifying read attempts when:
+ * --create with non-SWMR access
+ * --opening files with SWMR access
+ * --H5reopen the files
+ */
+
+ /* Create a file */
+ fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid1, FAIL, "H5Fcreate");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Open file again with SWMR access and default fapl */
+ fid1 = H5Fopen(FILE1, H5F_ACC_RDONLY|H5F_ACC_SWMR_READ, H5P_DEFAULT);
+ CHECK(fid2, FAIL, "H5Fopen");
+
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Set the # of read attempts */
+ ret = H5Pset_read_attempts(fapl, 9);
+ CHECK(ret, FAIL, "H5Pset_read_attempts");
+
+ /* Open file again with SWMR access and fapl (non-default & set to 9) */
+ fid2 = H5Fopen(FILE1, (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ), fapl);
+ CHECK(fid3, FAIL, "H5Fopen");
+
+ /* Re-open fid1 */
+ fid = H5Freopen(fid1);
+ CHECK(fid, FAIL, "H5Freopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file fapl -- should be H5F_SWMR_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_SWMR_READ_ATTEMPTS, "H5Fget_read_attempts");
+
+ /* Close the file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Re-open fid2 */
+ fid = H5Freopen(fid2);
+ CHECK(fid, FAIL, "H5Pclose");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file fapl -- should be 9 */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, 9, "H5Pget_read_attempts");
+
+ /* Close the file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close all the files */
+ ret=H5Fclose(fid1);
+ CHECK(ret, FAIL, "H5Fclose");
+ ret=H5Fclose(fid2);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /*
+ * Set E:
+ * Tests on verifying read attempts when:
+ * --create with SWMR access
+ * --opening files with non-SWMR access
+ * --H5reopen the files
+ */
+
+ /* Create a file */
+ fid = H5Fcreate(FILE1, H5F_ACC_TRUNC|H5F_ACC_SWMR_WRITE, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid1, FAIL, "H5Fcreate");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Open file again with non-SWMR access and default fapl */
+ fid1 = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
+ CHECK(fid2, FAIL, "H5Fopen");
+
+ /* Create a copy of file access property list */
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ CHECK(fapl, FAIL, "H5Pcreate");
+
+ /* Set the # of read attempts */
+ ret = H5Pset_read_attempts(fapl, 9);
+ CHECK(ret, FAIL, "H5Pset_read_attempts");
+
+ /* Open file again with non-SWMR access and fapl (non-default & set to 9) */
+ fid2 = H5Fopen(FILE1, H5F_ACC_RDONLY, fapl);
+ CHECK(fid3, FAIL, "H5Fopen");
+
+ /* Re-open fid1 */
+ fid = H5Freopen(fid1);
+ CHECK(fid, FAIL, "H5Freopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+ /* Retrieve the # of read attempts from file fapl -- should be H5F_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_READ_ATTEMPTS, "H5Fget_read_attempts");
+
+ /* Close the file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Re-open fid2 */
+ fid = H5Freopen(fid2);
+ CHECK(fid, FAIL, "H5Freopen");
+
+ /* Get file's fapl */
+ file_fapl = H5Fget_access_plist(fid);
+ CHECK(file_fapl, FAIL, "H5Fget_access_plist");
+
+ /* Retrieve the # of read attempts from file fapl -- should be H5F_READ_ATTEMPTS */
+ ret = H5Pget_read_attempts(file_fapl, &attempts);
+ CHECK(ret, FAIL, "H5Pget_read_attempts");
+ VERIFY(attempts, H5F_READ_ATTEMPTS, "H5Pget_read_attempts");
+
+ /* Close the file's fapl */
+ ret = H5Pclose(file_fapl);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close the file */
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Close all the files */
+ ret=H5Fclose(fid1);
+ CHECK(ret, FAIL, "H5Fclose");
+ ret=H5Fclose(fid2);
+ CHECK(ret, FAIL, "H5Fclose");
+
+
+} /* end test_read_attempts() */
+
+/****************************************************************
+**
** test_deprec():
** Test deprecated functionality.
**
@@ -3749,6 +4314,7 @@ test_file(void)
test_libver_macros2(); /* Test the macros for library version comparison */
test_swmr_write(); /* Tests for SWMR write access flag */
test_swmr_read(); /* Tests for SWMR read access flag */
+ test_read_attempts(); /* Tests for public routine H5Fget/set_read_attempts() */
#ifndef H5_NO_DEPRECATED_SYMBOLS
test_deprec(); /* Test deprecated routines */
#endif /* H5_NO_DEPRECATED_SYMBOLS */