diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2001-05-02 15:04:55 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2001-05-02 15:04:55 (GMT) |
commit | 076efa3382acdff44b9560909c9c28832c0ff1fe (patch) | |
tree | 822177177ff8eecd0ef1e2f64236352ea73059b8 /src/H5Dseq.c | |
parent | f21aa7af8ccc49e57156e2d0f99eb2770f837517 (diff) | |
download | hdf5-076efa3382acdff44b9560909c9c28832c0ff1fe.zip hdf5-076efa3382acdff44b9560909c9c28832c0ff1fe.tar.gz hdf5-076efa3382acdff44b9560909c9c28832c0ff1fe.tar.bz2 |
[svn-r3885] Purpose:
Document bug fix
Description:
IMPORTANT! IMPORTANT! IMPORTANT!
A case where metadata in a file could get corrupted in certain unusual
sitations was detected and fixed.
In certain circumstances, metadata could get cached in the raw data cache,
and if that particular piece of metadata was updated on disk while
incorrectly cached, the new metadata would get overwritten with the stale
metadata from the raw data cache when it was flushed out.
Additionally, I've patched up the raw data cache to be smarter about how
much it caches and how much I/O it triggers, leading to some speedups.
Solution:
Changed the raw data I/O routines which perform caching to require a
parameter with the size of the dataset being accessed and limited the
cache to no more than that many bytes.
Platforms tested:
FreeBSD 4.3 (hawkwind)
Diffstat (limited to 'src/H5Dseq.c')
-rw-r--r-- | src/H5Dseq.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/src/H5Dseq.c b/src/H5Dseq.c index 4c77052..c6e29a1 100644 --- a/src/H5Dseq.c +++ b/src/H5Dseq.c @@ -57,8 +57,8 @@ static intn interface_initialize_g = 0; */ herr_t H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, const H5O_fill_t *fill, - const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, + const struct H5O_pline_t *pline, const H5O_fill_t *fill, + const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, hsize_t seq_len, hsize_t file_offset, void *buf/*out*/) { hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ @@ -67,7 +67,9 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative yperslab sizes (in elements) */ hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */ intn ndims; + hsize_t max_data = 0; /*bytes in dataset */ haddr_t addr=0; /*address in file */ + uintn u; /*counters */ intn i,j; /*counters */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; @@ -118,6 +120,13 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, addr = 0; } else { addr = layout->addr; + + /* Compute the size of the dataset in bytes */ + for(u=0, max_data=1; u<layout->ndims; u++) + max_data *= layout->dim[u]; + + /* Adjust the maximum size of the data by the offset into it */ + max_data -= file_offset; } addr += file_offset; @@ -150,18 +159,18 @@ H5F_seq_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, #endif /* Read directly from file if the dataset is in an external file */ - /* Note: We can't use data sieve buffers for datasets in external files - * because the 'addr' of all external files is set to 0 (above) and - * all datasets in external files would alias to the same set of - * file offsets, totally mixing up the data sieve buffer information. -QAK - */ if (efl && efl->nused>0) { + /* Note: We can't use data sieve buffers for datasets in external files + * because the 'addr' of all external files is set to 0 (above) and + * all datasets in external files would alias to the same set of + * file offsets, totally mixing up the data sieve buffer information. -QAK + */ if (H5O_efl_read(f, efl, addr, seq_len, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed"); } } else { - if (H5F_contig_read(f, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) { + if (H5F_contig_read(f, max_data, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed"); } @@ -491,8 +500,8 @@ printf("%s: partial_size=%lu, coords[%d]=%ld, hslab_size[%d]=%ld\n",FUNC,(unsign */ herr_t H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, const H5O_fill_t *fill, - const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, + const struct H5O_pline_t *pline, const H5O_fill_t *fill, + const struct H5O_efl_t *efl, const H5S_t *file_space, size_t elmt_size, hsize_t seq_len, hsize_t file_offset, const void *buf) { hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */ @@ -501,7 +510,9 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative hyperslab sizes (in elements) */ hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */ intn ndims; + hsize_t max_data = 0; /*bytes in dataset */ haddr_t addr; /*address in file */ + uintn u; /*counters */ intn i,j; /*counters */ #ifdef H5_HAVE_PARALLEL H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; @@ -552,6 +563,13 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, addr = 0; } else { addr = layout->addr; + + /* Compute the size of the dataset in bytes */ + for(u=0, max_data=1; u<layout->ndims; u++) + max_data *= layout->dim[u]; + + /* Adjust the maximum size of the data by the offset into it */ + max_data -= file_offset; } addr += file_offset; @@ -584,18 +602,18 @@ H5F_seq_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, #endif /* Write directly to file if the dataset is in an external file */ - /* Note: We can't use data sieve buffers for datasets in external files - * because the 'addr' of all external files is set to 0 (above) and - * all datasets in external files would alias to the same set of - * file offsets, totally mixing up the data sieve buffer information. -QAK - */ if (efl && efl->nused>0) { + /* Note: We can't use data sieve buffers for datasets in external files + * because the 'addr' of all external files is set to 0 (above) and + * all datasets in external files would alias to the same set of + * file offsets, totally mixing up the data sieve buffer information. -QAK + */ if (H5O_efl_write(f, efl, addr, seq_len, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed"); } } else { - if (H5F_contig_write(f, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) { + if (H5F_contig_write(f, max_data, H5FD_MEM_DRAW, addr, seq_len, dxpl_id, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed"); } |