From 39fc26566e18ac81c43986ed2013676e2918ded2 Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Tue, 8 Oct 2013 01:11:44 -0500 Subject: [svn-r24263] Changes to do re-reads for metadata with checksums when a file is opened with SWMR access. There are debugging printfs which will be removed when coding is finalized. Also some bug fixes: 1) accum.c--clean up some warning messages and use new_argv/new_envp for the call to execve. 2) hl/tools/h5watch--clean up some warning messages and a bug fix for h5watch.c. This checkin is awaiting code review feedback. --- hl/src/H5HLprivate2.h | 43 +-- hl/tools/h5watch/extend_dset.c | 14 +- hl/tools/h5watch/h5watch.c | 18 +- hl/tools/h5watch/h5watchgentest.c | 1 + src/H5B2cache.c | 42 ++- src/H5EAcache.c | 56 ++-- src/H5F.c | 27 +- src/H5FAcache.c | 32 +-- src/H5FScache.c | 26 +- src/H5Fio.c | 106 +++++++ src/H5Fpkg.h | 1 + src/H5Fprivate.h | 14 + src/H5Fquery.c | 23 ++ src/H5Fsuper_cache.c | 135 +++++---- src/H5HFcache.c | 465 ++++++++++++++++++------------ src/H5HFpkg.h | 8 + src/H5Ocache.c | 147 ++++++---- src/H5Pfapl.c | 92 +++++- src/H5Ppublic.h | 2 + src/H5SMcache.c | 27 +- test/accum.c | 133 ++++----- test/swmr_generator.c | 1 + test/testfiles/plist_files/fapl_be | Bin 1402 -> 1421 bytes test/testfiles/plist_files/fapl_le | Bin 1402 -> 1421 bytes test/testfiles/plist_files/lapl_be | Bin 1502 -> 1521 bytes test/testfiles/plist_files/lapl_le | Bin 1502 -> 1521 bytes test/tfile.c | 566 +++++++++++++++++++++++++++++++++++++ 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 #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 #include #include +#include /* * 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 Binary files a/test/testfiles/plist_files/fapl_be and b/test/testfiles/plist_files/fapl_be differ diff --git a/test/testfiles/plist_files/fapl_le b/test/testfiles/plist_files/fapl_le index 8fcefa2..24e944c 100644 Binary files a/test/testfiles/plist_files/fapl_le and b/test/testfiles/plist_files/fapl_le differ diff --git a/test/testfiles/plist_files/lapl_be b/test/testfiles/plist_files/lapl_be index 30f52a4..2ab61ed 100644 Binary files a/test/testfiles/plist_files/lapl_be and b/test/testfiles/plist_files/lapl_be differ diff --git a/test/testfiles/plist_files/lapl_le b/test/testfiles/plist_files/lapl_le index 30f52a4..2ab61ed 100644 Binary files a/test/testfiles/plist_files/lapl_le and b/test/testfiles/plist_files/lapl_le 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 */ -- cgit v0.12