summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5Distore.c82
-rw-r--r--test/dsets.c106
-rw-r--r--test/istore.c14
4 files changed, 196 insertions, 9 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 9f6ec10..888590c 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -174,6 +174,9 @@ Bug Fixes since HDF5-1.6.0 release
Library
-------
+ - Changed H5Dread() to not overwrite data in an application's buffer
+ with garbage when accessing a chunked dataset with an undefined
+ fill value and an unwritten chunk is uncountered. QAK - 2004/08/25
- Fixed error which could cause a core dump when a type conversion
routine was registered after a compound datatype had been
converted and then an equivalment compound datatype was converted
diff --git a/src/H5Distore.c b/src/H5Distore.c
index cbd7a0f..5182d29 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -1821,9 +1821,7 @@ H5D_istore_readvv(H5F_t *f, const struct H5D_dxpl_cache_t *dxpl_cache, hid_t dxp
{
H5D_istore_ud1_t udata; /*B-tree pass-through */
haddr_t chunk_addr; /* Chunk address on disk */
-#ifndef NDEBUG
size_t u; /* Local index variables */
-#endif
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_readvv, FAIL);
@@ -1886,6 +1884,86 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a
unsigned idx_hint=0; /* Cache index hint */
ssize_t naccessed; /* Number of bytes accessed in chunk */
+ /* If the chunk address is not defined, check if the fill value is
+ * undefined also. If both situations hold, don't bother copying
+ * values to the destination buffer, since they will just be
+ * garbage.
+ *
+ * Ideally, this will eventually be checked at a higher level and
+ * the entire I/O operation on the chunk will be skipped. -QAK
+ */
+ if(!H5F_addr_defined(chunk_addr)) {
+ const H5O_fill_t *fill=&(dset->dcpl_cache.fill); /* Fill value info */
+ H5D_fill_time_t fill_time=dset->dcpl_cache.fill_time; /* Fill time */
+ H5D_fill_value_t fill_status;
+ H5D_rdcc_t *rdcc = &(dset->cache.chunk);/*raw data chunk cache*/
+ hbool_t found = FALSE; /*already in cache? */
+
+ /* Check if the chunk is in the cache (but hasn't been written to disk yet) */
+ if (rdcc->nslots>0) {
+ unsigned idx=H5D_HASH(dset,store->chunk.index); /* Cache entry index */
+ H5D_rdcc_ent_t *ent = rdcc->slot[idx]; /* Cache entry */
+
+ /* Potential match... */
+ if (ent) {
+ for (u=0, found=TRUE; u<dset->layout.u.chunk.ndims; u++) {
+ if (store->chunk.offset[u]!=ent->offset[u]) {
+ found = FALSE;
+ break;
+ } /* end if */
+ } /* end for */
+ } /* end if */
+ } /* end if */
+
+ /* If the chunk is in the cache, then it must have valid data */
+ if(!found) {
+ /* Check if the fill value is defined */
+ if (H5P_is_fill_value_defined(fill, &fill_status) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined");
+
+ /* If we are never to return fill values, or if we would return them
+ * but they aren't set, process the entire set of I/O vectors and
+ * get out now.
+ */
+ if(fill_time==H5D_FILL_TIME_NEVER ||
+ (fill_time==H5D_FILL_TIME_IFSET && fill_status!=H5D_FILL_VALUE_USER_DEFINED)) {
+ size_t size; /* Size of sequence in bytes */
+ size_t v; /* Local index variable */
+ ssize_t bytes_processed=0; /* Eventual return value */
+
+ /* Work through all the sequences */
+ for(u=*mem_curr_seq, v=*chunk_curr_seq; u<mem_max_nseq && v<chunk_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(chunk_len_arr[v]<mem_len_arr[u])
+ size=chunk_len_arr[v];
+ else
+ size=mem_len_arr[u];
+
+ /* Update source information */
+ chunk_len_arr[v]-=size;
+ chunk_offset_arr[v]+=size;
+ if(chunk_len_arr[v]==0)
+ v++;
+
+ /* Update destination information */
+ mem_len_arr[u]-=size;
+ mem_offset_arr[u]+=size;
+ if(mem_len_arr[u]==0)
+ u++;
+
+ /* Increment number of bytes copied */
+ bytes_processed+=(ssize_t)size;
+ } /* end for */
+
+ /* Update current sequence vectors */
+ *mem_curr_seq=u;
+ *chunk_curr_seq=v;
+
+ HGOTO_DONE(bytes_processed);
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
/*
* Lock the chunk, copy from application to chunk, then unlock the
* chunk.
diff --git a/test/dsets.c b/test/dsets.c
index cd3cbc5..6b29031 100644
--- a/test/dsets.c
+++ b/test/dsets.c
@@ -117,6 +117,10 @@ const char *FILENAME[] = {
/* Names for zero-dim test */
#define ZERODIM_DATASET "zerodim"
+/* Parameters for zero-dim test */
+#define MISSING_CHUNK_DATASET "missing_chunk"
+#define MISSING_CHUNK_DIM 100
+
/* Shared global arrays */
#define DSET_DIM1 100
#define DSET_DIM2 200
@@ -3677,6 +3681,107 @@ error:
/*-------------------------------------------------------------------------
+ * Function: test_missing_chunk
+ *
+ * Purpose: Tests that reads from chunked dataset with undefined fill value and
+ * not all chunks written don't overwrite data in user's buffer
+ * for missing chunks.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 25, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+test_missing_chunk(hid_t file)
+{
+ hid_t s=-1, d=-1, dcpl=-1;
+ hssize_t hs_start[1];
+ hsize_t hs_stride[1],
+ hs_count[1],
+ hs_block[1];
+ int wdata[MISSING_CHUNK_DIM],
+ rdata[MISSING_CHUNK_DIM];
+ hsize_t dsize=100, dmax=H5S_UNLIMITED, csize=5;
+ size_t u;
+
+ TESTING("Read dataset with unwritten chunk & undefined fill value");
+
+ /* Initialize data */
+ for(u=0; u<MISSING_CHUNK_DIM; u++) {
+ wdata[u]=u;
+ rdata[u]=911;
+ } /* end for */
+
+ /* Create dataspace */
+ if((s = H5Screate_simple(1, &dsize, &dmax))<0) TEST_ERROR;
+
+ /* Create dataset creation property list */
+ if((dcpl = H5Pcreate(H5P_DATASET_CREATE))<0) TEST_ERROR;
+
+ /* Set to chunked */
+ if(H5Pset_chunk(dcpl, 1, &csize)<0) TEST_ERROR;
+
+ /* Undefine fill value */
+ if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, NULL)<0) TEST_ERROR;
+
+ /* Create dataset */
+ if((d = H5Dcreate(file, MISSING_CHUNK_DATASET, H5T_NATIVE_INT, s, dcpl))<0) TEST_ERROR;
+
+ /* Select elements in every other chunk */
+ hs_start[0]=0;
+ hs_stride[0]=10;
+ hs_count[0]=10;
+ hs_block[0]=5;
+ if (H5Sselect_hyperslab(s, H5S_SELECT_SET, hs_start, hs_stride, hs_count,
+ hs_block)<0) TEST_ERROR;
+
+ /* Write selected data */
+ if(H5Dwrite(d, H5T_NATIVE_INT, s, s, H5P_DEFAULT, wdata)<0) TEST_ERROR;
+
+ /* Read all data */
+ if(H5Dread(d, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata)<0) TEST_ERROR;
+
+ /* Validata values read */
+ for(u=0; u<MISSING_CHUNK_DIM; u++) {
+ if((u%10)>=5) {
+ if(rdata[u]!=911) {
+ printf(" Line %d: Incorrect value, rdata[%u]=%d\n",__LINE__,(unsigned)u,rdata[u]);
+ TEST_ERROR;
+ } /* end if */
+ } /* end if */
+ else {
+ if(rdata[u]!=wdata[u]) {
+ printf(" Line %d: Incorrect value, wdata[%u]=%d, rdata[%u]=%d\n",__LINE__,(unsigned)u,wdata[u],(unsigned)u,rdata[u]);
+ TEST_ERROR;
+ } /* end if */
+ } /* end else */
+ } /* end for */
+
+ /* Close everything */
+ if(H5Pclose(dcpl)<0) TEST_ERROR;
+ if(H5Sclose(s)<0) TEST_ERROR;
+ if(H5Dclose(d)<0) TEST_ERROR;
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Pclose(dcpl);
+ H5Dclose(d);
+ H5Sclose(s);
+ } H5E_END_TRY;
+ return -1;
+} /* end test_zero_dims() */
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Tests the dataset interface (H5D)
@@ -3745,6 +3850,7 @@ main(void)
nerrors += test_filter_delete(file)<0 ?1:0;
nerrors += test_filters_endianess()<0 ?1:0;
nerrors += test_zero_dims(file)<0 ?1:0;
+ nerrors += test_missing_chunk(file)<0 ?1:0;
if (H5Fclose(file)<0) goto error;
if (nerrors) goto error;
diff --git a/test/istore.c b/test/istore.c
index 0830ff4..f7baf31 100644
--- a/test/istore.c
+++ b/test/istore.c
@@ -298,17 +298,17 @@ test_extend(hid_t f, const char *prefix,
#if 0
if (0 == ctr)
fprintf(stderr,"\n");
- fprintf(stderr," Insert: ctr=%d, corner=(%d", ctr, offset[0]);
+ fprintf(stderr," Insert: ctr=%lu, corner=(%ld", (unsigned long)ctr, (long)offset[0]);
if (ndims > 1)
- fprintf(stderr,",%d", offset[1]);
+ fprintf(stderr,",%ld", (long)offset[1]);
if (ndims > 2)
- fprintf(stderr,",%d", offset[2]);
- fprintf(stderr,"), size=(%d", size[0]);
+ fprintf(stderr,",%ld", (long)offset[2]);
+ fprintf(stderr,"), size=(%lu", (unsigned long)size[0]);
if (ndims > 1)
- fprintf(stderr,",%d", size[1]);
+ fprintf(stderr,",%lu", (unsigned long)size[1]);
if (ndims > 2)
- fprintf(stderr,",%d", size[2]);
- fprintf(stderr,"), %d element%s", nelmts, 1 == nelmts ? "" : "s");
+ fprintf(stderr,",%lu", (unsigned long)size[2]);
+ fprintf(stderr,"), %lu element%s", (unsigned long)nelmts, 1 == nelmts ? "" : "s");
if (0 == nelmts)
fprintf(stderr," *SKIPPED*");
fprintf(stderr,"\n");