summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.distdep599
-rw-r--r--src/H5.c6
-rw-r--r--src/H5D.c2
-rw-r--r--src/H5Distore.c12
-rw-r--r--src/H5F.c202
-rw-r--r--src/H5FD.c145
-rw-r--r--src/H5FDcore.c34
-rw-r--r--src/H5FDfamily.c44
-rw-r--r--src/H5FDmpio.c36
-rw-r--r--src/H5FDmulti.c1393
-rw-r--r--src/H5FDmulti.h31
-rw-r--r--src/H5FDprivate.h4
-rw-r--r--src/H5FDpublic.h25
-rw-r--r--src/H5FDsec2.c4
-rw-r--r--src/H5Fistore.c12
-rw-r--r--src/H5Fprivate.h10
-rw-r--r--src/H5R.c2
-rw-r--r--src/H5Rpublic.h4
-rw-r--r--src/H5T.c8
-rw-r--r--src/H5Tpublic.h2
-rw-r--r--src/H5private.h1
-rw-r--r--src/Makefile.in18
-rw-r--r--src/hdf5.h1
23 files changed, 2514 insertions, 81 deletions
diff --git a/src/.distdep b/src/.distdep
index 458112d..4fef9a8 100644
--- a/src/.distdep
+++ b/src/.distdep
@@ -1490,3 +1490,602 @@ H5Z.lo: \
H5Dpublic.h \
H5Zprivate.h \
H5Zpublic.h
+H5.lo: \
+ H5.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5ACprivate.h \
+ H5ACpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5Ipublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5FDprivate.h \
+ H5Iprivate.h \
+ H5MMprivate.h \
+ H5Pprivate.h \
+ H5Ppublic.h \
+ H5Dpublic.h \
+ H5Zpublic.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h
+H5D.lo: \
+ H5D.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Iprivate.h \
+ H5Ipublic.h \
+ H5ACprivate.h \
+ H5ACpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Dprivate.h \
+ H5Dpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5HLprivate.h \
+ H5HLpublic.h \
+ H5MMprivate.h \
+ H5Pprivate.h \
+ H5Ppublic.h
+H5F.lo: \
+ H5F.c \
+ H5FDsec2.h \
+ H5Ipublic.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5FDfamily.h \
+ H5FDmpio.h \
+ H5FDpublic.h \
+ H5private.h \
+ H5Aprivate.h \
+ H5Apublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5MMpublic.h \
+ H5Dprivate.h \
+ H5Dpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Iprivate.h \
+ H5ACprivate.h \
+ H5ACpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h
+H5Fistore.lo: \
+ H5Fistore.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Dprivate.h \
+ H5Dpublic.h \
+ H5Ipublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Iprivate.h \
+ H5MFprivate.h \
+ H5MMprivate.h
+H5FD.lo: \
+ H5FD.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Ipublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5FDprivate.h \
+ H5Iprivate.h \
+ H5MMprivate.h \
+ H5Pprivate.h \
+ H5Ppublic.h \
+ H5Dpublic.h
+H5FDsec2.lo: \
+ H5FDsec2.c \
+ hdf5.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Ipublic.h \
+ H5Apublic.h \
+ H5ACpublic.h \
+ H5Bpublic.h \
+ H5Dpublic.h \
+ H5Epublic.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5Gpublic.h \
+ H5HGpublic.h \
+ H5HLpublic.h \
+ H5MMpublic.h \
+ H5Opublic.h \
+ H5Ppublic.h \
+ H5Zpublic.h \
+ H5Rpublic.h \
+ H5RApublic.h \
+ H5Spublic.h \
+ H5Tpublic.h \
+ H5FDcore.h \
+ H5FDfamily.h \
+ H5FDmpio.h \
+ H5FDsec2.h \
+ H5FDmulti.h
+H5FDfamily.lo: \
+ H5FDfamily.c \
+ hdf5.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Ipublic.h \
+ H5Apublic.h \
+ H5ACpublic.h \
+ H5Bpublic.h \
+ H5Dpublic.h \
+ H5Epublic.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5Gpublic.h \
+ H5HGpublic.h \
+ H5HLpublic.h \
+ H5MMpublic.h \
+ H5Opublic.h \
+ H5Ppublic.h \
+ H5Zpublic.h \
+ H5Rpublic.h \
+ H5RApublic.h \
+ H5Spublic.h \
+ H5Tpublic.h \
+ H5FDcore.h \
+ H5FDfamily.h \
+ H5FDmpio.h \
+ H5FDsec2.h \
+ H5FDmulti.h
+H5FDmpio.lo: \
+ H5FDmpio.c \
+ hdf5.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Ipublic.h \
+ H5Apublic.h \
+ H5ACpublic.h \
+ H5Bpublic.h \
+ H5Dpublic.h \
+ H5Epublic.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5Gpublic.h \
+ H5HGpublic.h \
+ H5HLpublic.h \
+ H5MMpublic.h \
+ H5Opublic.h \
+ H5Ppublic.h \
+ H5Zpublic.h \
+ H5Rpublic.h \
+ H5RApublic.h \
+ H5Spublic.h \
+ H5Tpublic.h \
+ H5FDcore.h \
+ H5FDfamily.h \
+ H5FDmpio.h \
+ H5FDsec2.h \
+ H5FDmulti.h
+H5FDcore.lo: \
+ H5FDcore.c \
+ hdf5.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Ipublic.h \
+ H5Apublic.h \
+ H5ACpublic.h \
+ H5Bpublic.h \
+ H5Dpublic.h \
+ H5Epublic.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5Gpublic.h \
+ H5HGpublic.h \
+ H5HLpublic.h \
+ H5MMpublic.h \
+ H5Opublic.h \
+ H5Ppublic.h \
+ H5Zpublic.h \
+ H5Rpublic.h \
+ H5RApublic.h \
+ H5Spublic.h \
+ H5Tpublic.h \
+ H5FDcore.h \
+ H5FDfamily.h \
+ H5FDmpio.h \
+ H5FDsec2.h \
+ H5FDmulti.h
+H5I.lo: \
+ H5I.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Iprivate.h \
+ H5Ipublic.h \
+ H5Eprivate.h
+H5Oattr.lo: \
+ H5Oattr.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Ipublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5MMprivate.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Dpublic.h
+H5Odtype.lo: \
+ H5Odtype.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Ipublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5MMprivate.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Dpublic.h
+H5P.lo: \
+ H5P.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Iprivate.h \
+ H5Ipublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Dprivate.h \
+ H5Dpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5FDprivate.h \
+ H5MMprivate.h
+H5R.lo: \
+ H5R.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Iprivate.h \
+ H5Ipublic.h \
+ H5Dprivate.h \
+ H5Dpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h
+H5Sall.lo: \
+ H5Sall.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Ipublic.h \
+ H5Iprivate.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Dpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h
+H5Shyper.lo: \
+ H5Shyper.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Dprivate.h \
+ H5Dpublic.h \
+ H5Ipublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Iprivate.h \
+ H5MMprivate.h \
+ H5Pprivate.h
+H5Snone.lo: \
+ H5Snone.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Ipublic.h \
+ H5Iprivate.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Dpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h
+H5Spoint.lo: \
+ H5Spoint.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Ipublic.h \
+ H5Iprivate.h \
+ H5MMprivate.h \
+ H5MMpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Dpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h
+H5Sselect.lo: \
+ H5Sselect.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5Ipublic.h \
+ H5Iprivate.h \
+ H5MMprivate.h \
+ H5MMpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Dpublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h
+H5T.lo: \
+ H5T.c \
+ H5private.h \
+ H5public.h \
+ H5config.h \
+ H5api_adpt.h \
+ H5Dprivate.h \
+ H5Dpublic.h \
+ H5Ipublic.h \
+ H5Fprivate.h \
+ H5Fpublic.h \
+ H5FDpublic.h \
+ H5MMpublic.h \
+ H5Gprivate.h \
+ H5Gpublic.h \
+ H5Bprivate.h \
+ H5Bpublic.h \
+ H5Oprivate.h \
+ H5Opublic.h \
+ H5HGprivate.h \
+ H5HGpublic.h \
+ H5Tprivate.h \
+ H5Tpublic.h \
+ H5Rprivate.h \
+ H5Rpublic.h \
+ H5Sprivate.h \
+ H5Spublic.h \
+ H5Zprivate.h \
+ H5Zpublic.h \
+ H5Iprivate.h \
+ H5Eprivate.h \
+ H5Epublic.h \
+ H5MMprivate.h \
+ H5Pprivate.h
diff --git a/src/H5.c b/src/H5.c
index c4e366a..aefff9e 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -1871,12 +1871,6 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...)
case H5FD_MEM_DRAW:
fprintf(out, "H5FD_MEM_DRAW");
break;
- case H5FD_MEM_META:
- fprintf(out, "H5FD_MEM_META");
- break;
- case H5FD_MEM_GROUP:
- fprintf(out, "H5FD_MEM_GROUP");
- break;
case H5FD_MEM_GHEAP:
fprintf(out, "H5FD_MEM_GHEAP");
break;
diff --git a/src/H5D.c b/src/H5D.c
index 87c684d..b299ec3 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -2475,7 +2475,7 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space)
* If the dataset is accessed via parallel I/O, allocate file space
* for all chunks now and initialize each chunk with the fill value.
*/
- if (H5FD_MPIO==dset->ent.file->shared->fapl->driver_id) {
+ if (H5FD_MPIO==dset->ent.file->shared->driver_id) {
/* We only handle simple data spaces so far */
if ((ndims=H5S_get_simple_extent_dims(space, dim, NULL))<0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 4849e98..eca1cd2 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -806,9 +806,8 @@ H5F_istore_init (H5F_t *f)
FUNC_ENTER (H5F_istore_init, FAIL);
HDmemset (rdcc, 0, sizeof(H5F_rdcc_t));
- if (f->shared->fapl->rdcc_nbytes>0 &&
- f->shared->fapl->rdcc_nelmts>0) {
- rdcc->nslots = f->shared->fapl->rdcc_nelmts;
+ if (f->shared->rdcc_nbytes>0 && f->shared->rdcc_nelmts>0) {
+ rdcc->nslots = f->shared->rdcc_nelmts;
rdcc->slot = H5MM_calloc (rdcc->nslots*sizeof(H5F_rdcc_ent_t*));
if (NULL==rdcc->slot) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
@@ -1111,7 +1110,7 @@ H5F_istore_prune (H5F_t *f, size_t size)
{
intn i, j, nerrors=0;
H5F_rdcc_t *rdcc = &(f->shared->rdcc);
- size_t total = f->shared->fapl->rdcc_nbytes;
+ size_t total = f->shared->rdcc_nbytes;
const int nmeth=2; /*number of methods */
intn w[1]; /*weighting as an interval */
H5F_rdcc_ent_t *p[2], *cur; /*list pointers */
@@ -1129,7 +1128,7 @@ H5F_istore_prune (H5F_t *f, size_t size)
* begins. The pointers participating in the list traversal are each
* given a chance at preemption before any of the pointers are advanced.
*/
- w[0] = rdcc->nused * f->shared->fapl->rdcc_w0;
+ w[0] = rdcc->nused * f->shared->rdcc_w0;
p[0] = rdcc->head;
p[1] = NULL;
@@ -1353,8 +1352,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
}
assert (found || chunk_size>0);
- if (!found && rdcc->nslots>0 &&
- chunk_size<=f->shared->fapl->rdcc_nbytes &&
+ if (!found && rdcc->nslots>0 && chunk_size<=f->shared->rdcc_nbytes &&
(!ent || !ent->locked)) {
/*
* Add the chunk to the cache only if the slot is not already locked.
diff --git a/src/H5F.c b/src/H5F.c
index 0aacbd4..4a03a63 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -57,7 +57,7 @@ const H5F_create_t H5F_create_dflt = {
0, /* unused */
0, /* unused */
},
- sizeof(hsize_t), /* Default offset size */
+ sizeof(haddr_t), /* Default offset size */
sizeof(hsize_t), /* Default length size */
HDF5_BOOTBLOCK_VERSION, /* Current Boot-Block version # */
HDF5_FREESPACE_VERSION, /* Current Free-Space info version # */
@@ -453,7 +453,7 @@ hid_t
H5Fget_access_plist(hid_t file_id)
{
H5F_t *f = NULL;
- H5F_access_t *plist = NULL;
+ H5F_access_t *fapl=NULL, _fapl;
hid_t ret_value = FAIL;
FUNC_ENTER(H5Fget_access_plist, FAIL);
@@ -464,15 +464,30 @@ H5Fget_access_plist(hid_t file_id)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
}
- /* Create the property list object to return */
- if (NULL==(plist=H5P_copy(H5P_FILE_ACCESS, f->shared->fapl))) {
+ /* Initialize the property list */
+ HDmemset(&_fapl, 0, sizeof _fapl);
+ _fapl.mdc_nelmts = f->shared->mdc_nelmts;
+ _fapl.rdcc_nelmts = f->shared->rdcc_nelmts;
+ _fapl.rdcc_nbytes = f->shared->rdcc_nbytes;
+ _fapl.rdcc_w0 = f->shared->rdcc_w0;
+ _fapl.threshold = f->shared->threshold;
+ _fapl.alignment = f->shared->alignment;
+ _fapl.gc_ref = f->shared->gc_ref;
+ _fapl.driver_id = f->shared->driver_id;
+ _fapl.driver_info = NULL; /*just for now */
+
+ /* Copy properties */
+ if (NULL==(fapl=H5P_copy(H5P_FILE_ACCESS, &_fapl))) {
HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL,
"unable to copy file access properties");
}
+ /* Get the properties for the file driver */
+ fapl->driver_info = H5FD_fapl_get(f->shared->lf);
+
/* Create an atom */
- if ((ret_value = H5P_create(H5P_FILE_ACCESS, plist))<0) {
- H5P_close(H5P_FILE_ACCESS, plist);
+ if ((ret_value = H5P_create(H5P_FILE_ACCESS, fapl))<0) {
+ H5P_close(H5P_FILE_ACCESS, fapl);
HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL,
"unable to register property list");
}
@@ -675,9 +690,10 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
f->shared->boot_addr = HADDR_UNDEF;
f->shared->base_addr = HADDR_UNDEF;
f->shared->freespace_addr = HADDR_UNDEF;
+ f->shared->driver_addr = HADDR_UNDEF;
/*
- * Deep-copy the file creation and file access property lists into the
+ * Copy the file creation and file access property lists into the
* new file handle. We do this early because some values might need
* to change as the file is being opened.
*/
@@ -688,10 +704,14 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
}
fapl = (H5P_DEFAULT==fapl_id)? &H5F_access_dflt : H5I_object(fapl_id);
- if (NULL==(f->shared->fapl=H5P_copy(H5P_FILE_ACCESS, fapl))) {
- HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, NULL,
- "unable to copy file access property list");
- }
+ f->shared->mdc_nelmts = fapl->mdc_nelmts;
+ f->shared->rdcc_nelmts = fapl->rdcc_nelmts;
+ f->shared->rdcc_nbytes = fapl->rdcc_nbytes;
+ f->shared->rdcc_w0 = fapl->rdcc_w0;
+ f->shared->threshold = fapl->threshold;
+ f->shared->alignment = fapl->alignment;
+ f->shared->gc_ref = fapl->gc_ref;
+ f->shared->driver_id = H5I_inc_ref(fapl->driver_id);
#ifdef HAVE_PARALLEL
/*
@@ -710,11 +730,11 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
* The cache might be created with a different number of elements and
* the access property list should be updated to reflect that.
*/
- if ((n=H5AC_create(f, f->shared->fapl->mdc_nelmts))<0) {
+ if ((n=H5AC_create(f, f->shared->mdc_nelmts))<0) {
HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, NULL,
"unable to create meta data cache");
}
- f->shared->fapl->mdc_nelmts = n;
+ f->shared->mdc_nelmts = n;
/* Create the chunk cache */
H5F_istore_init(f);
@@ -784,9 +804,20 @@ H5F_dest(H5F_t *f)
ret_value = FAIL; /*but keep going*/
}
f->shared->cwfs = H5MM_xfree (f->shared->cwfs);
+
+ /* Destroy file creation properties */
H5P_close(H5P_FILE_CREATE, f->shared->fcpl);
- H5P_close(H5P_FILE_ACCESS, f->shared->fapl);
+
+ /* Destroy file access properties (most don't need destruction) */
+ H5I_dec_ref(f->shared->driver_id);
+
+ /* Destroy shared file struct */
+ if (H5FD_close(f->shared->lf)<0) {
+ HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file");
+ ret_value = FAIL; /*but keep going*/
+ }
f->shared = H5MM_xfree(f->shared);
+
} else if (f->shared->nrefs>0) {
/*
* There are other references to the shared part of the file.
@@ -869,6 +900,11 @@ H5F_dest(H5F_t *f)
*
* Robb Matzke, 1999-08-02
* Rewritten to use the virtual file layer.
+ *
+ * Robb Matzke, 1999-08-16
+ * Added decoding of file driver information block, which uses a
+ * formerly reserved address slot in the boot block in order to
+ * be compatible with previous versions of the file format.
*-------------------------------------------------------------------------
*/
H5F_t *
@@ -882,11 +918,12 @@ H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id)
const uint8_t *p; /*ptr into temp I/O buffer */
size_t fixed_size=24; /*fixed sizeof superblock */
size_t variable_size; /*variable sizeof superblock */
+ size_t driver_size; /*size of driver info block */
H5G_entry_t root_ent; /*root symbol table entry */
haddr_t eof; /*end of file address */
- haddr_t reserved_addr; /*unused */
haddr_t stored_eoa; /*relative end-of-addr in file */
uintn tent_flags; /*tentative flags */
+ char driver_name[9]; /*file driver name/version */
FUNC_ENTER(H5F_open, NULL);
@@ -1102,11 +1139,51 @@ H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id)
H5F_addr_decode(file, &p, &(shared->base_addr)/*out*/);
H5F_addr_decode(file, &p, &(shared->freespace_addr)/*out*/);
H5F_addr_decode(file, &p, &stored_eoa/*out*/);
- H5F_addr_decode(file, &p, &reserved_addr/*out*/);
+ H5F_addr_decode(file, &p, &(shared->driver_addr)/*out*/);
if (H5G_ent_decode(file, &p, &root_ent/*out*/)<0) {
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
"unable to read root symbol entry");
}
+
+ /* Decode the optional driver information block */
+ if (H5F_addr_defined(shared->driver_addr)) {
+ haddr_t drv_addr = shared->base_addr + shared->driver_addr;
+ if (H5FD_set_eoa(lf, drv_addr+16)<0 ||
+ H5FD_read(lf, H5P_DEFAULT, drv_addr, 16, buf)<0) {
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
+ "unable to read driver information block");
+ }
+ p = buf;
+
+ /* Version number */
+ if (HDF5_DRIVERINFO_VERSION!=*p++) {
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
+ "bad driver information block version number");
+ }
+
+ /* Reserved */
+ p += 3;
+
+ /* Driver info size */
+ UINT32DECODE(p, driver_size);
+
+ /* Driver name and/or version */
+ strncpy(driver_name, p, 8);
+ driver_name[8] = '\0';
+
+ /* Read driver information and decode */
+ if (H5FD_set_eoa(lf, drv_addr+16+driver_size)<0 ||
+ H5FD_read(lf, H5P_DEFAULT, drv_addr+16, driver_size, buf)<0) {
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
+ "unable to read file driver information");
+ }
+ if (H5FD_sb_decode(lf, driver_name, buf)<0) {
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
+ "unable to decode driver information");
+ }
+ }
+
+ /* Make sure we can open the root group */
if (H5G_mkroot(file, &root_ent)<0) {
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL,
"unable to read root group");
@@ -1118,7 +1195,6 @@ H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id)
*/
shared->fcpl->userblock_size = shared->base_addr;
-
/*
* Make sure that the data is not truncated. One case where this is
* possible is if the first file of a family of files was opened
@@ -1472,18 +1548,24 @@ H5Fflush(hid_t object_id, H5F_scope_t scope)
* H5F_SCOPE_DOWN means flush the specified file and all
* children.
*
- * Robb Matzke, 1998-08-02
+ * Robb Matzke, 1999-08-02
* If ALLOC_ONLY is non-zero then all this function does is
* allocate space for the userblock and superblock. Also
* rewritten to use the virtual file layer.
+ *
+ * Robb Matzke, 1999-08-16
+ * The driver information block is encoded and either allocated
+ * or written to disk.
*-------------------------------------------------------------------------
*/
static herr_t
H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
hbool_t alloc_only)
{
- uint8_t buf[2048], *p = buf;
+ uint8_t sbuf[2048], dbuf[2048], *p=NULL;
uintn nerrors=0, i;
+ hsize_t superblock_size, driver_size;
+ char driver_name[9];
FUNC_ENTER(H5F_flush, FAIL);
@@ -1523,6 +1605,7 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
}
/* encode the file boot block */
+ p = sbuf;
HDmemcpy(p, H5F_SIGNATURE, H5F_SIGNATURE_LEN);
p += H5F_SIGNATURE_LEN;
*p++ = f->shared->fcpl->bootblock_ver;
@@ -1541,31 +1624,91 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
H5F_addr_encode(f, &p, f->shared->base_addr);
H5F_addr_encode(f, &p, f->shared->freespace_addr);
H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf));
- H5F_addr_encode(f, &p, HADDR_UNDEF);
+ H5F_addr_encode(f, &p, f->shared->driver_addr);
H5G_ent_encode(f, &p, H5G_entof(f->shared->root_grp));
+ superblock_size = p-sbuf;
/*
- * Allocate space for the userblock and superblock if that hasn't been
- * done yet, which is the case just after a new file is created.
- * Otherwise write the superblock at the specified address. Since these
- * addresses are absolute we must use the virtual file layer directly.
+ * Encode the driver information block.
*/
+ if ((driver_size=H5FD_sb_size(f->shared->lf))) {
+ driver_size += 16; /*driver block header */
+ assert(driver_size<=sizeof dbuf);
+ p = dbuf;
+
+ /* Version */
+ *p++ = HDF5_DRIVERINFO_VERSION;
+
+ /* Reserved*/
+ p += 3;
+
+ /* Driver info size, excluding header */
+ UINT32ENCODE(p, driver_size-16);
+
+ /* Encode driver-specific data */
+ if (H5FD_sb_encode(f->shared->lf, driver_name, dbuf+16)<0) {
+ HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL,
+ "unable to encode driver information");
+ }
+
+ /* Driver name */
+ HDmemcpy(dbuf+8, driver_name, 8);
+ }
+
if (alloc_only) {
- assert(0==H5FD_get_eoa(f->shared->lf));
- if (H5FD_set_eoa(f->shared->lf, f->shared->boot_addr+(p-buf))<0) {
+ /*
+ * Allocate space for the userblock, superblock, and driver info
+ * block. We do it with one allocation request because the userblock
+ * and superblock need to be at the beginning of the file and only
+ * the first allocation request is required to return memory at
+ * format address zero.
+ */
+ haddr_t addr = H5FD_alloc(f->shared->lf, H5FD_MEM_SUPER,
+ (f->shared->base_addr +
+ superblock_size +
+ driver_size));
+ if (HADDR_UNDEF==addr) {
HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL,
"unable to allocate file space for userblock "
"and/or superblock");
}
+ if (0!=addr) {
+ HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL,
+ "file driver failed to allocate userblock "
+ "and/or superblock at address zero");
+ }
+
+ /*
+ * The file driver information block begins immediately after the
+ * superblock.
+ */
+ if (driver_size>0) {
+ f->shared->driver_addr = superblock_size;
+ }
+
} else {
+ /* Write superblock */
#ifdef HAVE_PARALLEL
H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/
#endif
if (H5FD_write(f->shared->lf, H5P_DEFAULT, f->shared->boot_addr,
- p-buf, buf)<0) {
+ superblock_size, sbuf)<0) {
HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
"unable to write superblock");
}
+
+ /* Write driver information block */
+ if (HADDR_UNDEF!=f->shared->driver_addr) {
+#ifdef HAVE_PARALLLEL
+ H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/
+#endif
+ if (H5FD_write(f->shared->lf, H5P_DEFAULT,
+ f->shared->base_addr+superblock_size, driver_size,
+ dbuf)<0) {
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
+ "unable to write driver information block");
+ }
+ }
}
/* Flush file buffers to disk */
@@ -1692,9 +1835,6 @@ H5F_close(H5F_t *f)
/* Dump debugging info */
H5AC_debug(f);
H5F_istore_stats(f, FALSE);
-
- /* Close files and release resources */
- H5FD_close(f->shared->lf);
} else {
/*
* Flush all caches but do not destroy. As long as all handles for
@@ -2493,6 +2633,8 @@ H5F_debug(H5F_t *f, haddr_t UNUSED addr, FILE * stream, intn indent,
"Base address:", f->shared->base_addr);
HDfprintf(stream, "%*s%-*s %a (rel)\n", indent, "", fwidth,
"Free list address:", f->shared->freespace_addr);
+ HDfprintf(stream, "%*s%-*s %a (rel)\n", indent, "", fwidth,
+ "Driver information block:", f->shared->driver_addr);
HDfprintf(stream, "%*s%-*s %lu bytes\n", indent, "", fwidth,
"Size of user block:",
(unsigned long) (f->shared->fcpl->userblock_size));
diff --git a/src/H5FD.c b/src/H5FD.c
index e8b13b7..86759d7 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -247,6 +247,151 @@ H5FDunregister(hid_t driver_id)
/*-------------------------------------------------------------------------
+ * Function: H5FD_sb_size
+ *
+ * Purpose: Obtains the number of bytes required to store the driver file
+ * access data in the HDF5 superblock.
+ *
+ * Return: Success: Number of bytes required.
+ *
+ * Failure: 0 if an error occurs or if the driver has no
+ * data to store in the superblock.
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 16, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+H5FD_sb_size(H5FD_t *file)
+{
+ hsize_t ret_value=0;
+
+ FUNC_ENTER(H5FD_sb_size, 0);
+
+ assert(file && file->cls);
+ if (file->cls->sb_size) {
+ ret_value = (file->cls->sb_size)(file);
+ }
+
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_sb_encode
+ *
+ * Purpose: Encode driver-specific data into the output arguments. The
+ * NAME is a nine-byte buffer which should get an
+ * eight-character driver name and/or version followed by a null
+ * terminator. The BUF argument is a buffer to receive the
+ * encoded driver-specific data. The size of the BUF array is
+ * the size returned by the H5FD_sb_size() call.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 16, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf)
+{
+ FUNC_ENTER(H5FD_sb_encode, FAIL);
+
+ assert(file && file->cls);
+ if (file->cls->sb_encode &&
+ (file->cls->sb_encode)(file, name/*out*/, buf/*out*/)<0) {
+ HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL,
+ "driver sb_encode request failed");
+ }
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_sb_decode
+ *
+ * Purpose: Decodes the driver information block.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 16, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf)
+{
+ FUNC_ENTER(H5FD_sb_decode, FAIL);
+
+ assert(file && file->cls);
+ if (file->cls->sb_decode &&
+ (file->cls->sb_decode)(file, name, buf)<0) {
+ HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL,
+ "driver sb_decode request failed");
+ }
+
+ FUNC_LEAVE(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_fapl_get
+ *
+ * Purpose: Gets the file access property list associated with a file.
+ * Usually the file will copy what it needs from the original
+ * file access property list when the file is created. The
+ * purpose of this function is to create a new file access
+ * property list based on the settings in the file, which may
+ * have been modified from the original file access property
+ * list.
+ *
+ * Return: Success: Pointer to a new file access property list
+ * with all members copied. If the file is
+ * closed then this property list lives on, and
+ * vice versa.
+ *
+ * Failure: NULL, including when the file has no
+ * properties.
+ *
+ * Programmer: Robb Matzke
+ * Friday, August 13, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5FD_fapl_get(H5FD_t *file)
+{
+ void *ret_value=NULL;
+
+ FUNC_ENTER(H5FD_fapl_get, NULL);
+ assert(file);
+
+ if (file->cls->fapl_get) {
+ ret_value = (file->cls->fapl_get)(file);
+ }
+
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5FD_fapl_copy
*
* Purpose: Copies the driver-specific part of the file access property
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 4be868e..9920678 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -67,6 +67,7 @@ typedef struct H5FD_core_fapl_t {
(size_t)((A)+(Z))<(size_t)(A))
/* Prototypes */
+static void *H5FD_core_fapl_get(H5FD_t *_file);
static H5FD_t *H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr);
static herr_t H5FD_core_close(H5FD_t *_file);
@@ -82,7 +83,11 @@ static herr_t H5FD_core_write(H5FD_t *_file, hid_t fapl_id, haddr_t addr,
static const H5FD_class_t H5FD_core_g = {
"core", /*name */
MAXADDR, /*maxaddr */
+ NULL, /*sb_size */
+ NULL, /*sb_encode */
+ NULL, /*sb_decode */
sizeof(H5FD_core_fapl_t), /*fapl_size */
+ H5FD_core_fapl_get, /*fapl_get */
NULL, /*fapl_copy */
NULL, /*fapl_free */
0, /*dxpl_size */
@@ -189,6 +194,33 @@ H5Pget_fapl_core(hid_t fapl_id, size_t *increment/*out*/)
/*-------------------------------------------------------------------------
+ * Function: H5FD_core_fapl_get
+ *
+ * Purpose: Returns a copy of the file access properties.
+ *
+ * Return: Success: Ptr to new file access properties.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Friday, August 13, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5FD_core_fapl_get(H5FD_t *_file)
+{
+ H5FD_core_t *file = (H5FD_core_t*)_file;
+ H5FD_core_fapl_t *fa = calloc(1, sizeof(H5FD_core_fapl_t));
+
+ fa->increment = file->increment;
+ return fa;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5FD_core_open
*
* Purpose: Create memory as an HDF5 file.
@@ -426,7 +458,7 @@ H5FD_core_read(H5FD_t *_file, hid_t dxpl_id/*unused*/, haddr_t addr,
memcpy(buf, file->mem+addr, nbytes);
size -= nbytes;
addr += nbytes;
- (char*)buf += nbytes;
+ buf = (char*)buf + nbytes;
}
/* Read zeros for the part which is after the EOF markers */
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c
index bf46efc..4f0536c 100644
--- a/src/H5FDfamily.c
+++ b/src/H5FDfamily.c
@@ -58,6 +58,7 @@ typedef struct H5FD_family_dxpl_t {
} H5FD_family_dxpl_t;
/* Callback prototypes */
+static void *H5FD_family_fapl_get(H5FD_t *_file);
static void *H5FD_family_fapl_copy(const void *_old_fa);
static herr_t H5FD_family_fapl_free(void *_fa);
static void *H5FD_family_dxpl_copy(const void *_old_dx);
@@ -79,7 +80,11 @@ static herr_t H5FD_family_flush(H5FD_t *_file);
static const H5FD_class_t H5FD_family_g = {
"family", /*name */
HADDR_MAX, /*maxaddr */
+ NULL, /*sb_size */
+ NULL, /*sb_encode */
+ NULL, /*sb_decode */
sizeof(H5FD_family_fapl_t), /*fapl_size */
+ H5FD_family_fapl_get, /*fapl_get */
H5FD_family_fapl_copy, /*fapl_copy */
H5FD_family_fapl_free, /*fapl_free */
sizeof(H5FD_family_dxpl_t), /*dxpl_size */
@@ -159,7 +164,10 @@ H5Pset_fapl_family(hid_t fapl_id, hsize_t memb_size, hid_t memb_fapl_id)
if (H5P_DEFAULT!=memb_fapl_id &&
H5P_FILE_ACCESS!=H5Pget_class(memb_fapl_id)) return -1;
- /* Initialize driver specific information */
+ /*
+ * Initialize driver specific information. No need to copy it into the FA
+ * struct since all members will be copied by H5Pset_driver().
+ */
fa.memb_size = memb_size;
fa.memb_fapl_id = memb_fapl_id;
return H5Pset_driver(fapl_id, H5FD_FAMILY, &fa);
@@ -201,6 +209,35 @@ H5Pget_fapl_family(hid_t fapl_id, hsize_t *memb_size/*out*/,
/*-------------------------------------------------------------------------
+ * Function: H5FD_family_fapl_get
+ *
+ * Purpose: Gets a file access property list which could be used to
+ * create an identical file.
+ *
+ * Return: Success: Ptr to new file access property list.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Friday, August 13, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5FD_family_fapl_get(H5FD_t *_file)
+{
+ H5FD_family_t *file = (H5FD_family_t*)_file;
+ H5FD_family_fapl_t *fa = calloc(1, sizeof(H5FD_family_fapl_t*));
+
+ fa->memb_size = file->memb_size;
+ fa->memb_fapl_id = H5Pcopy(file->memb_fapl_id);
+ return fa;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5FD_family_fapl_copy
*
* Purpose: Copies the family-specific file access properties.
@@ -348,7 +385,7 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id,
file->memb_size = 1024*1024*1024; /*1GB*/
} else {
H5FD_family_fapl_t *fa = H5Pget_driver_info(fapl_id);
- file->memb_fapl_id = fa->memb_fapl_id;
+ file->memb_fapl_id = H5Pcopy(fa->memb_fapl_id);
file->memb_size = fa->memb_size;
}
file->name = malloc(strlen(name)+1);
@@ -408,6 +445,9 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id,
for (i=0; i<file->nmembs; i++) {
if (file->memb[i]) H5FDclose(file->memb[i]);
}
+ if (file->memb) free(file->memb);
+ H5Pclose(file->memb_fapl_id);
+ if (file->name) free(file->name);
free(file);
}
return NULL;
diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c
index ca9ce12..ac853c5 100644
--- a/src/H5FDmpio.c
+++ b/src/H5FDmpio.c
@@ -67,6 +67,7 @@ static haddr_t MPIOff_to_haddr(MPI_Offset mpi_off);
static herr_t haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off/*out*/);
/* Callbacks */
+static void *H5FD_mpio_fapl_get(H5FD_t *_file);
static H5FD_t *H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr);
static herr_t H5FD_mpio_close(H5FD_t *_file);
@@ -89,7 +90,11 @@ typedef struct H5FD_mpio_fapl_t {
static const H5FD_class_t H5FD_mpio_g = {
"mpio", /*name */
HADDR_MAX, /*maxaddr */
+ NULL, /*sb_size */
+ NULL, /*sb_encode */
+ NULL, /*sb_decode */
sizeof(H5FD_mpio_fapl_t), /*fapl_size */
+ H5FD_mpio_fapl_get, /*fapl_get */
NULL, /*fapl_copy */
NULL, /*fapl_free */
sizeof(H5FD_mpio_dxpl_t), /*dxpl_size */
@@ -564,6 +569,37 @@ H5FD_mpio_signal_right_neighbor(H5FD_t *_file)
/*-------------------------------------------------------------------------
+ * Function: H5FD_mpio_fapl_get
+ *
+ * Purpose: Returns a file access property list which could be used to
+ * create another file the same as this one.
+ *
+ * Return: Success: Ptr to new file access property list with all
+ * fields copied from the file pointer.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Friday, August 13, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5FD_mpio_fapl_get(H5FD_t *_file)
+{
+ H5FD_mpio_t *file = (H5FD_mpio_t*)_file;
+ H5FD_mpio_fapl_t *fa = calloc(1, sizeof(H5FD_mpio_fapl_t));
+
+ /* These should both be copied. --rpm, 1999-08-13 */
+ fa->comm = file->comm;
+ fa->info = file->info;
+ return fa;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5FD_mpio_open
*
* Purpose: Opens a file with name NAME. The FLAGS are a bit field with
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
new file mode 100644
index 0000000..a8c9325
--- /dev/null
+++ b/src/H5FDmulti.c
@@ -0,0 +1,1393 @@
+/*
+ * Copyright (C) 1997 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Monday, November 10, 1997
+ *
+ * Purpose: Implements a file driver which dispatches I/O requests to
+ * other file drivers depending on the purpose of the address
+ * region being accessed. For instance, all meta-data could be
+ * place in one file while all raw data goes to some other file.
+ */
+#include <assert.h>
+#include <hdf5.h>
+#include <stdlib.h>
+
+/*
+ * Define H5FD_MULTI_DEBUG if you want the ability to print debugging
+ * messages to the standard error stream. Messages are only printed if the
+ * file is opened with the H5F_ACC_DEBUG flag.
+ */
+#define H5FD_MULTI_DEBUG
+
+/* Our versions of MIN and MAX */
+#undef MAX
+#define MAX(X,Y) ((X)>(Y)?(X):(Y))
+#undef MIN
+#define MIN(X,Y) ((X)<(Y)?(X):(Y))
+
+/* The driver identification number, initialized at runtime */
+static hid_t H5FD_MULTI_g = 0;
+
+/*
+ * The description of a file belonging to this driver. The file access
+ * properties and member names do not have to be copied into this struct
+ * since they will be held open by the file access property list which is
+ * copied into the parent file struct in H5F_open().
+ */
+typedef struct H5FD_multi_t {
+ H5FD_t pub; /*public stuff, must be first */
+ H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; /*map from usage to file */
+ haddr_t memb_addr[H5FD_MEM_NTYPES];/*starting address per member*/
+ haddr_t memb_next[H5FD_MEM_NTYPES];/*addr of next member */
+ H5FD_t *memb[H5FD_MEM_NTYPES]; /*member pointers */
+ hid_t memb_fapl[H5FD_MEM_NTYPES];/*member file access props */
+ char *memb_name[H5FD_MEM_NTYPES];/*name generators */
+ haddr_t eoa; /*end of allocated addresses */
+ unsigned flags; /*file open flags saved for debugging */
+} H5FD_multi_t;
+
+/* Driver-specific file access properties */
+typedef struct H5FD_multi_fapl_t {
+ H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; /*memory usage map */
+ hid_t memb_fapl[H5FD_MEM_NTYPES];/*member access properties */
+ char *memb_name[H5FD_MEM_NTYPES];/*name generators */
+ haddr_t memb_addr[H5FD_MEM_NTYPES];/*starting addr per member */
+} H5FD_multi_fapl_t;
+
+/* Driver specific data transfer properties */
+typedef struct H5FD_multi_dxpl_t {
+ hid_t memb_dxpl[H5FD_MEM_NTYPES];/*member data xfer properties*/
+} H5FD_multi_dxpl_t;
+
+/* Private functions */
+static char *my_strdup(const char *s);
+
+/* Callback prototypes */
+static hsize_t H5FD_multi_sb_size(H5FD_t *file);
+static herr_t H5FD_multi_sb_encode(H5FD_t *file, char *name/*out*/,
+ unsigned char *buf/*out*/);
+static herr_t H5FD_multi_sb_decode(H5FD_t *file, const char *name,
+ const unsigned char *buf);
+static void *H5FD_multi_fapl_get(H5FD_t *file);
+static void *H5FD_multi_fapl_copy(const void *_old_fa);
+static herr_t H5FD_multi_fapl_free(void *_fa);
+static void *H5FD_multi_dxpl_copy(const void *_old_dx);
+static herr_t H5FD_multi_dxpl_free(void *_dx);
+static H5FD_t *H5FD_multi_open(const char *name, unsigned flags,
+ hid_t fapl_id, haddr_t maxaddr);
+static herr_t H5FD_multi_close(H5FD_t *_file);
+static int H5FD_multi_cmp(const H5FD_t *_f1, const H5FD_t *_f2);
+static haddr_t H5FD_multi_get_eoa(H5FD_t *_file);
+static herr_t H5FD_multi_set_eoa(H5FD_t *_file, haddr_t eoa);
+static haddr_t H5FD_multi_get_eof(H5FD_t *_file);
+static haddr_t H5FD_multi_alloc(H5FD_t *_file, H5FD_mem_t type, hsize_t size);
+static herr_t H5FD_multi_free(H5FD_t *_file, H5FD_mem_t type, haddr_t addr,
+ hsize_t size);
+static herr_t H5FD_multi_read(H5FD_t *_file, hid_t dxpl_id, haddr_t addr,
+ hsize_t size, void *_buf/*out*/);
+static herr_t H5FD_multi_write(H5FD_t *_file, hid_t dxpl_id, haddr_t addr,
+ hsize_t size, const void *_buf);
+static herr_t H5FD_multi_flush(H5FD_t *_file);
+
+/* The class struct */
+static const H5FD_class_t H5FD_multi_g = {
+ "multi", /*name */
+ HADDR_MAX, /*maxaddr */
+ H5FD_multi_sb_size, /*sb_size */
+ H5FD_multi_sb_encode, /*sb_encode */
+ H5FD_multi_sb_decode, /*sb_decode */
+ sizeof(H5FD_multi_fapl_t), /*fapl_size */
+ H5FD_multi_fapl_get, /*fapl_get */
+ H5FD_multi_fapl_copy, /*fapl_copy */
+ H5FD_multi_fapl_free, /*fapl_free */
+ sizeof(H5FD_multi_dxpl_t), /*dxpl_size */
+ H5FD_multi_dxpl_copy, /*dxpl_copy */
+ H5FD_multi_dxpl_free, /*dxpl_free */
+ H5FD_multi_open, /*open */
+ H5FD_multi_close, /*close */
+ H5FD_multi_cmp, /*cmp */
+ H5FD_multi_alloc, /*alloc */
+ H5FD_multi_free, /*free */
+ H5FD_multi_get_eoa, /*get_eoa */
+ H5FD_multi_set_eoa, /*set_eoa */
+ H5FD_multi_get_eof, /*get_eof */
+ H5FD_multi_read, /*read */
+ H5FD_multi_write, /*write */
+ H5FD_multi_flush, /*flush */
+ H5FD_FLMAP_DEFAULT, /*fl_map */
+};
+
+
+/*-------------------------------------------------------------------------
+ * Function: my_strdup
+ *
+ * Purpose: Private version of strdup()
+ *
+ * Return: Success: Ptr to new copy of string
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Friday, August 13, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static char *
+my_strdup(const char *s)
+{
+ char *x;
+ if (!s) return NULL;
+ if (NULL==(x=malloc(strlen(s)+1))) return NULL;
+ strcpy(x, s);
+ return x;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_init
+ *
+ * Purpose: Initialize this driver by registering the driver with the
+ * library.
+ *
+ * Return: Success: The driver ID for the multi driver.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5FD_multi_init(void)
+{
+ if (!H5FD_MULTI_g) {
+ H5FD_MULTI_g = H5FDregister(&H5FD_multi_g);
+ }
+ return H5FD_MULTI_g;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_fapl_split
+ *
+ * Purpose: Compatability function. Makes the multi driver act like the
+ * old split driver which stored meta data in one file and raw
+ * data in another file.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 11, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_fapl_split(hid_t fapl, const char *meta_ext, hid_t meta_plist_id,
+ const char *raw_ext, hid_t raw_plist_id)
+{
+ H5FD_mem_t mt, memb_map[H5FD_MEM_NTYPES];
+ hid_t memb_fapl[H5FD_MEM_NTYPES];
+ const char *memb_name[H5FD_MEM_NTYPES];
+ char meta_name[1024], raw_name[1024];
+ haddr_t memb_addr[H5FD_MEM_NTYPES];
+
+ /*NO TRACE*/
+
+ /* Initialize */
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ memb_map[mt] = (H5FD_MEM_DRAW==mt?mt:H5FD_MEM_SUPER);
+ memb_fapl[mt] = -1;
+ memb_name[mt] = NULL;
+ memb_addr[mt] = HADDR_UNDEF;
+ }
+
+ /* The file access properties */
+ memb_fapl[H5FD_MEM_SUPER] = meta_plist_id;
+ memb_fapl[H5FD_MEM_DRAW] = raw_plist_id;
+
+ /* The names */
+ sprintf(meta_name, "%%s%s", meta_ext?meta_ext:".meta");
+ memb_name[H5FD_MEM_SUPER] = meta_name;
+ sprintf(raw_name, "%%s%s", raw_ext?raw_ext:".raw");
+ memb_name[H5FD_MEM_DRAW] = raw_name;
+
+ /* The sizes */
+ memb_addr[H5FD_MEM_SUPER] = 0;
+ memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2;
+
+ return H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_fapl_multi
+ *
+ * Purpose: Sets the file access property list FAPL_ID to use the multi
+ * driver. The MEMB_MAP array maps memory usage types to other
+ * memory usage types and is the mechanism which allows the
+ * caller to specify how many files are created. The array
+ * contains H5FD_MEM_NTYPES entries which are either the value
+ * H5FD_MEM_DEFAULT or a memory usage type and the number of
+ * unique values determines the number of files which are
+ * opened. For each memory usage type which will be associated
+ * with a file the MEMB_FAPL array should have a property list
+ * and the MEMB_NAME array should be a name generator (a
+ * printf-style format with a %s which will be replaced with the
+ * name passed to H5FDopen(), usually from H5Fcreate() or
+ * H5Fopen()).
+ *
+ * Example: To set up a multi file access property list which partitions
+ * data into meta and raw files each being 1/2 of the address
+ * space one would say:
+ *
+ * H5FD_mem_t mt, memb_map[H5FD_MEM_NTYPES];
+ * hid_t memb_fapl[H5FD_MEM_NTYPES];
+ * const char *memb[H5FD_MEM_NTYPES];
+ * haddr_t memb_addr[H5FD_MEM_NTYPES];
+ *
+ * // The mapping...
+ * for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ * memb_map[mt] = H5FD_MEM_SUPER;
+ * }
+ * memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW;
+ *
+ * // Member information
+ * memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT;
+ * memb_name[H5FD_MEM_SUPER] = "%s.meta";
+ * memb_addr[H5FD_MEM_SUPER] = 0;
+ *
+ * memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT;
+ * memb_name[H5FD_MEM_DRAW] = "%s.raw";
+ * memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2;
+ *
+ * hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);
+ * H5Pset_fapl_multi(fapl, memb_map, memb_fapl,
+ * memb_name, memb_addr);
+ *
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map,
+ const hid_t *memb_fapl, const char **memb_name,
+ const haddr_t *memb_addr)
+{
+ H5FD_multi_fapl_t fa;
+ H5FD_mem_t mt, mmt;
+
+ /*NO TRACE*/
+
+ /* Check arguments */
+ if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1;
+ if (!memb_map) return -1;
+ if (!memb_fapl) return -1;
+ if (!memb_name) return -1;
+ if (!memb_addr) return -1;
+
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ /* Map usage type */
+ mmt = memb_map[mt];
+ if (mmt<0 || mmt>=H5FD_MEM_NTYPES) return -1;
+ if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+
+ /*
+ * All members of MEMB_FAPL must be either defaults or actual file
+ * access property lists.
+ */
+ if (H5P_DEFAULT!=memb_fapl[mmt] &&
+ H5P_FILE_ACCESS!=H5Pget_class(memb_fapl[mmt])) return -1;
+
+ /* All names must be defined */
+ if (!memb_name[mmt] || !memb_name[mmt][0]) return -1;
+ }
+
+ /*
+ * Initialize driver specific information. No need to copy it into the FA
+ * struct since all members will be copied by H5Pset_driver().
+ */
+ memcpy(fa.memb_map, memb_map, H5FD_MEM_NTYPES*sizeof(H5FD_mem_t));
+ memcpy(fa.memb_fapl, memb_fapl, H5FD_MEM_NTYPES*sizeof(hid_t));
+ memcpy(fa.memb_name, memb_name, H5FD_MEM_NTYPES*sizeof(char*));
+ memcpy(fa.memb_addr, memb_addr, H5FD_MEM_NTYPES*sizeof(haddr_t));
+ return H5Pset_driver(fapl_id, H5FD_MULTI, &fa);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_fapl_multi
+ *
+ * Purpose: Returns information about the multi file access property
+ * list though the function arguments which are the same as for
+ * H5Pset_fapl_multi() above.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map/*out*/,
+ hid_t *memb_fapl/*out*/, char **memb_name/*out*/,
+ haddr_t *memb_addr/*out*/)
+{
+ H5FD_multi_fapl_t *fa;
+ H5FD_mem_t mt;
+
+ /*NO TRACE*/
+
+ if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1;
+ if (H5FD_MULTI!=H5Pget_driver(fapl_id)) return -1;
+ if (NULL==(fa=H5Pget_driver_info(fapl_id))) return -1;
+
+ if (memb_map) {
+ memcpy(memb_map, fa->memb_map, H5FD_MEM_NTYPES*sizeof(H5FD_mem_t));
+ }
+ if (memb_fapl) {
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (fa->memb_fapl[mt]>=0) {
+ memb_fapl[mt] = H5Pcopy(fa->memb_fapl[mt]);
+ } else {
+ memb_fapl[mt] = fa->memb_fapl[mt]; /*default or bad ID*/
+ }
+ }
+ }
+ if (memb_name) {
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (fa->memb_name[mt]) {
+ memb_name[mt] = malloc(strlen(fa->memb_name[mt])+1);
+ strcpy(memb_name[mt], fa->memb_name[mt]);
+ } else {
+ memb_name[mt] = NULL;
+ }
+ }
+ }
+ if (memb_addr) {
+ memcpy(memb_addr, fa->memb_addr, H5FD_MEM_NTYPES*sizeof(haddr_t));
+ }
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_dxpl_multi
+ *
+ * Purpose: Set the data transfer property list DXPL_ID to use the multi
+ * driver with the specified data transfer properties for each
+ * memory usage type MEMB_DXPL[] (after the usage map is
+ * applied).
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, August 10, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_dxpl_multi(hid_t dxpl_id, const hid_t *memb_dxpl)
+{
+ H5FD_multi_dxpl_t dx;
+ H5FD_mem_t mt;
+
+ /*NO TRACE*/
+
+ /* Check arguments */
+ if (H5P_DATA_XFER!=H5Pget_class(dxpl_id)) return -1;
+ if (!memb_dxpl) return -1;
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (H5P_DEFAULT!=memb_dxpl[mt] &&
+ H5P_DATA_XFER!=H5Pget_class(memb_dxpl[mt])) return -1;
+ }
+
+ /* Initialize the data transfer property list */
+ memcpy(dx.memb_dxpl, memb_dxpl, H5FD_MEM_NTYPES*sizeof(hid_t));
+ return H5Pset_driver(dxpl_id, H5FD_MULTI, &dx);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_dxpl_multi
+ *
+ * Purpose: Returns information which was set with H5Pset_dxpl_multi()
+ * above.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, August 10, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_dxpl_multi(hid_t dxpl_id, hid_t *memb_dxpl/*out*/)
+{
+ H5FD_multi_dxpl_t *dx;
+ H5FD_mem_t mt;
+
+ /*NO TRACE*/
+
+ if (H5P_FILE_ACCESS!=H5Pget_class(dxpl_id)) return -1;
+ if (H5FD_MULTI!=H5Pget_driver(dxpl_id)) return -1;
+ if (NULL==(dx=H5Pget_driver_info(dxpl_id))) return -1;
+
+ if (memb_dxpl) {
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (dx->memb_dxpl[mt]>=0) {
+ memb_dxpl[mt] = H5Pcopy(dx->memb_dxpl[mt]);
+ } else {
+ memb_dxpl[mt] = dx->memb_dxpl[mt]; /*default or bad ID */
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_sb_size
+ *
+ * Purpose: Returns the size of the private information to be stored in
+ * the superblock.
+ *
+ * Return: Success: The super block driver data size.
+ *
+ * Failure: never fails
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 16, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static hsize_t
+H5FD_multi_sb_size(H5FD_t *_file/*unused*/)
+{
+ return H5FD_MEM_NTYPES * 8;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_sb_encode
+ *
+ * Purpose: Encode driver information for the superblock. The NAME
+ * argument is a nine-byte buffer which will be initialized with
+ * an eight-character name/version number and null termination.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 16, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_sb_encode(H5FD_t *_file, char *name/*out*/,
+ unsigned char *buf/*out*/)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mt;
+ haddr_t memb_eoa;
+
+ /* Name and version number */
+ strcpy(name, "NCSAmulti");
+
+ /* Copy EOA values into buffer */
+ assert(sizeof(haddr_t)<=8);
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (file->memb[mt]) {
+ memb_eoa = H5FDget_eoa(file->memb[mt]);
+ } else {
+ memb_eoa = HADDR_UNDEF;
+ }
+ memcpy(buf+mt*sizeof(memb_eoa), &memb_eoa, sizeof(memb_eoa));
+ }
+
+ /* Convert to destination type */
+ if (H5Tconvert(H5T_NATIVE_HADDR, H5T_STD_U64LE, H5FD_MEM_NTYPES,
+ buf, NULL, H5P_DEFAULT)<0) return -1;
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_sb_decode
+ *
+ * Purpose: Decodes the superblock information for this driver. The NAME
+ * argument is the eight-character (plus null termination) name
+ * stored in the file.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Monday, August 16, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mt;
+ char x[H5FD_MEM_NTYPES*8];
+
+ /* Make sure the name/version number is correct */
+ if (strcmp(name, "NCSAmult")) return -1;
+
+ /* Decode EOA values */
+ assert(sizeof(haddr_t)<=8);
+ memcpy(x, buf, H5FD_MEM_NTYPES*8);
+ if (H5Tconvert(H5T_STD_U64LE, H5T_NATIVE_HADDR, H5FD_MEM_NTYPES,
+ x, NULL, H5P_DEFAULT)<0) return -1;
+
+ /* Set EOA values */
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (file->memb[mt]) {
+ H5FDset_eoa(file->memb[mt], ((haddr_t*)x)[mt]);
+ }
+ }
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_fapl_get
+ *
+ * Purpose: Returns a file access property list which indicates how the
+ * specified file is being accessed. The return list could be
+ * used to access another file the same way.
+ *
+ * Return: Success: Ptr to new file access property list with all
+ * members copied from the file struct.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Friday, August 13, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5FD_multi_fapl_get(H5FD_t *_file)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_multi_fapl_t fa;
+
+ memset(&fa, 0, sizeof fa);
+ memcpy(fa.memb_map, file->memb_map, sizeof(fa.memb_map));
+ memcpy(fa.memb_fapl, file->memb_fapl, sizeof(fa.memb_fapl));
+ memcpy(fa.memb_name, file->memb_name, sizeof(fa.memb_name));
+ memcpy(fa.memb_addr, file->memb_addr, sizeof(fa.memb_addr));
+ return H5FD_multi_fapl_copy(&fa);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_fapl_copy
+ *
+ * Purpose: Copies the multi-specific file access properties.
+ *
+ * Return: Success: Ptr to a new property list
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5FD_multi_fapl_copy(const void *_old_fa)
+{
+ const H5FD_multi_fapl_t *old_fa = (const H5FD_multi_fapl_t*)_old_fa;
+ H5FD_multi_fapl_t *new_fa = malloc(sizeof(H5FD_multi_fapl_t));
+ H5FD_mem_t mt;
+ int nerrors = 0;
+
+ assert(new_fa);
+
+ memcpy(new_fa, old_fa, sizeof(H5FD_multi_fapl_t));
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (old_fa->memb_fapl[mt]>=0) {
+ new_fa->memb_fapl[mt] = H5Pcopy(old_fa->memb_fapl[mt]);
+ if (new_fa->memb_fapl[mt]<0) nerrors++;
+ }
+ if (old_fa->memb_name[mt]) {
+ new_fa->memb_name[mt] = malloc(strlen(old_fa->memb_name[mt])+1);
+ assert(new_fa->memb_name[mt]);
+ strcpy(new_fa->memb_name[mt], old_fa->memb_name[mt]);
+ }
+ }
+
+ if (nerrors) {
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (new_fa->memb_fapl[mt]>=0) H5Pclose(new_fa->memb_fapl[mt]);
+ if (new_fa->memb_name[mt]) free(new_fa->memb_name[mt]);
+ }
+ free(new_fa);
+ return NULL;
+ }
+ return new_fa;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_fapl_free
+ *
+ * Purpose: Frees the multi-specific file access properties.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_fapl_free(void *_fa)
+{
+ H5FD_multi_fapl_t *fa = (H5FD_multi_fapl_t*)_fa;
+ H5FD_mem_t mt;
+
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (fa->memb_fapl[mt]>=0) H5Pclose(fa->memb_fapl[mt]);
+ if (fa->memb_name[mt]) free(fa->memb_name[mt]);
+ }
+ free(fa);
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_dxpl_copy
+ *
+ * Purpose: Copes the multi-specific data transfer properties.
+ *
+ * Return: Success: Ptr to new property list
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5FD_multi_dxpl_copy(const void *_old_dx)
+{
+ const H5FD_multi_dxpl_t *old_dx = (const H5FD_multi_dxpl_t*)_old_dx;
+ H5FD_multi_dxpl_t *new_dx = malloc(sizeof(H5FD_multi_dxpl_t));
+ H5FD_mem_t mt;
+ int nerrors = 0;
+
+ assert(new_dx);
+
+ memcpy(new_dx, old_dx, sizeof(H5FD_multi_dxpl_t));
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (old_dx->memb_dxpl[mt]>=0) {
+ new_dx->memb_dxpl[mt] = H5Pcopy(old_dx->memb_dxpl[mt]);
+ if (new_dx->memb_dxpl[mt]<0) nerrors++;
+ }
+ }
+
+ if (nerrors) {
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ H5Pclose(new_dx->memb_dxpl[mt]);
+ }
+ free(new_dx);
+ return NULL;
+ }
+ return new_dx;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_dxpl_free
+ *
+ * Purpose: Frees the multi-specific data transfer properties.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_dxpl_free(void *_dx)
+{
+ H5FD_multi_dxpl_t *dx = (H5FD_multi_dxpl_t*)_dx;
+ H5FD_mem_t mt;
+
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (dx->memb_dxpl[mt]>=0) H5Pclose(dx->memb_dxpl[mt]);
+ }
+ free(dx);
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_open
+ *
+ * Purpose: Creates and/or opens a multi HDF5 file.
+ *
+ * Return: Success: A pointer to a new file data structure. The
+ * public fields will be initialized by the
+ * caller, which is always H5FD_open().
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5FD_t *
+H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id,
+ haddr_t maxaddr)
+{
+ H5FD_multi_t *file=NULL;
+ H5FD_mem_t mt, mmt, mt2, mmt2;
+ char tmp[4096];
+ int seen[H5FD_MEM_NTYPES];
+
+ /* Check arguments */
+ if (!name || !*name) return NULL;
+ if (0==maxaddr || HADDR_UNDEF==maxaddr) return NULL;
+
+ /*
+ * Initialize file from file access properties. The default mapping
+ * creates two files -- one for meta data and one for raw data. The
+ * default file extensions are ".meta" and ".raw" accessed by default
+ * file drivers. Half the address space is used for each.
+ */
+ if (NULL==(file=calloc(1, sizeof(H5FD_multi_t)))) return NULL;
+ if (H5P_DEFAULT==fapl_id || H5FD_MULTI!=H5Pget_driver(fapl_id)) {
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ file->memb_map[mt] = H5FD_MEM_DRAW==mt?mt:H5FD_MEM_SUPER;
+ file->memb_addr[mt] = HADDR_UNDEF;
+ file->memb_fapl[mt] = H5P_DEFAULT;
+ }
+ file->memb_name[H5FD_MEM_SUPER] = my_strdup("%s.meta");
+ file->memb_addr[H5FD_MEM_SUPER] = 0;
+
+ file->memb_name[H5FD_MEM_DRAW] = my_strdup("%s.raw");
+ file->memb_addr[H5FD_MEM_DRAW] = maxaddr/2;
+ } else {
+ H5FD_multi_fapl_t *fa = H5Pget_driver_info(fapl_id);
+ assert(fa);
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ file->memb_map[mt] = fa->memb_map[mt];
+ file->memb_addr[mt] = fa->memb_addr[mt];
+ if (fa->memb_fapl[mt]>=0) {
+ file->memb_fapl[mt] = H5Pcopy(fa->memb_fapl[mt]);
+ } else {
+ file->memb_fapl[mt] = fa->memb_fapl[mt];
+ }
+ if (fa->memb_name[mt]) {
+ file->memb_name[mt] = my_strdup(fa->memb_name[mt]);
+ } else {
+ file->memb_name[mt] = NULL;
+ }
+ }
+ }
+ file->flags = flags;
+
+ /*
+ * Figure out the memb_next[] values for each member. This is the
+ * beginning address of the next member.
+ */
+ memset(seen, 0, sizeof seen);
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ mmt = file->memb_map[mt];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+ assert(mmt>0 && mmt<H5FD_MEM_NTYPES);
+ if (seen[mmt]++) continue;
+
+ file->memb_next[mmt] = HADDR_UNDEF;
+ for (mt2=1; mt2<H5FD_MEM_NTYPES; mt2++) {
+ mmt2 = file->memb_map[mt2];
+ if (H5FD_MEM_DEFAULT==mmt2) mmt2 = mt2;
+ assert(mmt2>0 && mmt2<H5FD_MEM_NTYPES);
+ if (mmt==mmt2) continue;
+
+ if (file->memb_addr[mmt]<file->memb_addr[mmt2] &&
+ (HADDR_UNDEF==file->memb_next[mmt] ||
+ file->memb_next[mmt]>file->memb_addr[mmt2])) {
+ file->memb_next[mmt] = file->memb_addr[mmt2];
+ }
+ }
+ }
+
+ /*
+ * Open all the multi members.
+ */
+ memset(seen, 0, sizeof seen);
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ mmt = file->memb_map[mt];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+ assert(mmt>0 && mmt<H5FD_MEM_NTYPES);
+ if (seen[mmt]++) continue;
+ assert(file->memb_name[mmt]);
+ sprintf(tmp, file->memb_name[mmt], name);
+
+#ifdef H5FD_MULTI_DEBUG
+ if (file->flags & H5F_ACC_DEBUG) {
+ fprintf(stderr, "H5FD_MULTI: opening \"%s\"\n", tmp);
+ }
+#endif
+ H5E_BEGIN_TRY {
+ file->memb[mmt] = H5FDopen(tmp, flags, file->memb_fapl[mmt],
+ HADDR_UNDEF);
+ } H5E_END_TRY;
+ if (!file->memb[mmt]) {
+#ifdef H5FD_MULTI_DEBUG
+ if (file->flags & H5F_ACC_DEBUG) {
+ fprintf(stderr, "H5FD_MULTI: open failed\n");
+ }
+#endif
+ goto error;
+ }
+ }
+
+ /* Write index file */
+ if ((flags & H5F_ACC_RDWR) &&
+ H5FD_multi_flush((H5FD_t*)file)<0) goto error;
+ return (H5FD_t*)file;
+
+ error:
+ /* Cleanup and fail */
+ if (file) {
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (file->memb[mt]) H5FDclose(file->memb[mt]);
+ if (file->memb_fapl[mt]>=0) H5Pclose(file->memb_fapl[mt]);
+ if (file->memb_name[mt]) free(file->memb_name[mt]);
+ }
+ free(file);
+ }
+ return NULL;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_close
+ *
+ * Purpose: Closes a multi file.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative with as many members closed as
+ * possible. The only subsequent operation
+ * permitted on the file is a close operation.
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_close(H5FD_t *_file)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mt;
+ int nerrors=0;
+
+ /* Flush our own data */
+ if (H5FD_multi_flush(_file)<0) nerrors++;
+
+ /* Close as many members as possible */
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (file->memb[mt]) {
+#ifdef H5FD_MULTI_DEBUG
+ if (file->flags & H5F_ACC_DEBUG) {
+ fprintf(stderr, "H5FD_MULTI: closing member %d\n", (int)mt);
+ }
+#endif
+ if (H5FDclose(file->memb[mt])<0) {
+#ifdef H5FD_MULTI_DEBUG
+ if (file->flags & H5F_ACC_DEBUG) {
+ fprintf(stderr, "H5FD_MULTI: close failed\n");
+ }
+#endif
+ nerrors++;
+ } else {
+ file->memb[mt] = NULL;
+ }
+ }
+ }
+ if (nerrors) return -1;
+
+ /* Clean up other stuff */
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (file->memb_fapl[mt]>=0) H5Pclose(file->memb_fapl[mt]);
+ if (file->memb_name[mt]) free(file->memb_name[mt]);
+ }
+ free(file);
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_cmp
+ *
+ * Purpose: Compares two file families to see if they are the same. It
+ * does this by comparing the first common member of the two
+ * families. If the families have no members in common then the
+ * file with the earliest member is smaller than the other file.
+ * We abort if neither file has any members.
+ *
+ * Return: Success: like strcmp()
+ *
+ * Failure: never fails (arguments were checked by the
+ * caller).
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5FD_multi_cmp(const H5FD_t *_f1, const H5FD_t *_f2)
+{
+ const H5FD_multi_t *f1 = (const H5FD_multi_t*)_f1;
+ const H5FD_multi_t *f2 = (const H5FD_multi_t*)_f2;
+ H5FD_mem_t mt;
+ int cmp=0;
+
+ for (mt=0; mt<H5FD_MEM_NTYPES; mt++) {
+ if (f1->memb[mt] && f2->memb[mt]) break;
+ if (!cmp) {
+ if (f1->memb[mt]) cmp = -1;
+ else if (f2->memb[mt]) cmp = 1;
+ }
+ }
+ assert(cmp || mt<H5FD_MEM_NTYPES);
+ if (mt>=H5FD_MEM_NTYPES) return cmp;
+
+ return H5FDcmp(f1->memb[mt], f2->memb[mt]);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_get_eoa
+ *
+ * Purpose: Returns the end-of-address marker for the file. The EOA
+ * marker is the first address past the last byte allocated in
+ * the format address space.
+ *
+ * Return: Success: The end-of-address-marker
+ *
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5FD_multi_get_eoa(H5FD_t *_file)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ return file->eoa;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_set_eoa
+ *
+ * Purpose: Set the end-of-address marker for the file by savig the new
+ * EOA value in the file struct. Also set the EOA marker for the
+ * subfile in which the new EOA value falls. We don't set the
+ * EOA values of any other subfiles.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_set_eoa(H5FD_t *_file, haddr_t eoa)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mt, mmt;
+ herr_t status;
+
+ /* Find the subfile in which the new EOA value falls */
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ mmt = file->memb_map[mt];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+ assert(mmt>0 && mmt<H5FD_MEM_NTYPES);
+
+ if (eoa>=file->memb_addr[mmt] && eoa<file->memb_next[mmt]) {
+ break;
+ }
+ }
+ assert(mt<H5FD_MEM_NTYPES);
+
+ /* Set subfile eoa */
+ H5E_BEGIN_TRY {
+ status = H5FDset_eoa(file->memb[mmt], eoa-file->memb_addr[mmt]);
+ } H5E_END_TRY;
+ if (status<0) return -1;
+
+ /* Save new eoa for return later */
+ file->eoa = eoa;
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_get_eof
+ *
+ * Purpose: Returns the end-of-file marker, which is the greater of
+ * either the total multi size or the current EOA marker.
+ *
+ * Return: Success: End of file address, the first address past
+ * the end of the multi of files or the current
+ * EOA, whichever is larger.
+ *
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5FD_multi_get_eof(H5FD_t *_file)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ haddr_t eof=0, tmp;
+ H5FD_mem_t mt, mmt;
+ int seen[H5FD_MEM_NTYPES];
+
+ memset(seen, 0, sizeof seen);
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ mmt = file->memb_map[mt];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+ assert(mmt>0 && mmt<H5FD_MEM_NTYPES);
+ if (seen[mmt]++) continue;
+
+ H5E_BEGIN_TRY {
+ tmp = H5FDget_eof(file->memb[mmt]);
+ } H5E_END_TRY;
+ if (HADDR_UNDEF==tmp) return HADDR_UNDEF;
+ if (tmp>0) tmp += file->memb_addr[mmt];
+ if (tmp>eof) eof = tmp;
+ }
+
+ return MAX(file->eoa, eof);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_alloc
+ *
+ * Purpose: Allocate file memory.
+ *
+ * Return: Success: Address of new memory
+ *
+ * Failure: HADDR_UNDEF
+ *
+ * Programmer: Robb Matzke
+ * Thursday, August 12, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static haddr_t
+H5FD_multi_alloc(H5FD_t *_file, H5FD_mem_t type, hsize_t size)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mmt;
+ haddr_t addr;
+
+ mmt = file->memb_map[type];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = type;
+
+ if (HADDR_UNDEF==(addr=H5FDalloc(file->memb[mmt], type, size))) {
+ return HADDR_UNDEF;
+ }
+ addr += file->memb_addr[mmt];
+ if (addr+size>file->eoa) file->eoa = addr+size;
+ return addr;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_free
+ *
+ * Purpose: Frees memory
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, August 12, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_free(H5FD_t *_file, H5FD_mem_t type, haddr_t addr, hsize_t size)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mmt;
+
+ mmt = file->memb_map[type];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = type;
+
+ assert(addr>=file->memb_addr[mmt]);
+ assert(addr+size<=file->memb_next[mmt]);
+ return H5FDfree(file->memb[mmt], type, addr-file->memb_addr[mmt], size);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_read
+ *
+ * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR
+ * into buffer BUF according to data transfer properties in
+ * DXPL_ID.
+ *
+ * Return: Success: Zero. Result is stored in caller-supplied
+ * buffer BUF.
+ *
+ * Failure: -1, contents of buffer BUF are undefined.
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_read(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, hsize_t size,
+ void *_buf/*out*/)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_multi_dxpl_t *dx=NULL;
+ H5FD_mem_t mt, mmt, hi=H5FD_MEM_DEFAULT;
+ haddr_t start_addr=0;
+
+ /* Get the data transfer properties */
+ if (H5P_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) {
+ dx = H5Pget_driver_info(dxpl_id);
+ }
+
+ /* Find the file to which this address belongs */
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ mmt = file->memb_map[mt];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+ assert(mmt>0 && mmt<H5FD_MEM_NTYPES);
+
+ if (file->memb_addr[mmt]>addr) continue;
+ if (file->memb_addr[mmt]>=start_addr) {
+ start_addr = file->memb_addr[mmt];
+ hi = mmt;
+ }
+ }
+ assert(hi>0);
+
+ /* Read from that member */
+ return H5FDread(file->memb[hi], dx?dx->memb_dxpl[hi]:H5P_DEFAULT,
+ addr-start_addr, size, _buf);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_write
+ *
+ * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR
+ * from buffer BUF according to data transfer properties in
+ * DXPL_ID.
+ *
+ * Return: Success: Zero
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_write(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, hsize_t size,
+ const void *_buf)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_multi_dxpl_t *dx=NULL;
+ H5FD_mem_t mt, mmt, hi=H5FD_MEM_DEFAULT;
+ haddr_t start_addr=0;
+
+ /* Get the data transfer properties */
+ if (H5P_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) {
+ dx = H5Pget_driver_info(dxpl_id);
+ }
+
+ /* Find the file to which this address belongs */
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ mmt = file->memb_map[mt];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+ assert(mmt>0 && mmt<H5FD_MEM_NTYPES);
+
+ if (file->memb_addr[mmt]>addr) continue;
+ if (file->memb_addr[mmt]>=start_addr) {
+ start_addr = file->memb_addr[mmt];
+ hi = mmt;
+ }
+ }
+ assert(hi>0);
+
+ /* Write to that member */
+ return H5FDwrite(file->memb[hi], dx?dx->memb_dxpl[hi]:H5P_DEFAULT,
+ addr-start_addr, size, _buf);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_multi_flush
+ *
+ * Purpose: Flushes all multi members.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1, as many files flushed as possible.
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, August 4, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_multi_flush(H5FD_t *_file)
+{
+ H5FD_multi_t *file = (H5FD_multi_t*)_file;
+ H5FD_mem_t mt, mmt;
+ int nerrors=0;
+
+#if 0
+ /* Debugging stuff... */
+ fprintf(stderr, "multifile access information:\n");
+
+ /* print the map */
+ fprintf(stderr, " map=");
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ mmt = file->memb_map[mt];
+ if (H5FD_MEM_DEFAULT==mmt) mmt = mt;
+ fprintf(stderr, "%s%d", 1==mt?"":",", (int)mmt);
+ }
+ fprintf(stderr, "\n");
+
+ /* print info about each file */
+ fprintf(stderr, " File Starting Allocated Next Member\n");
+ fprintf(stderr, " Number Address Size Address Name\n");
+ fprintf(stderr, " ------ -------------------- -------------------- -------------------- ------------------------------\n");
+
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ if (HADDR_UNDEF!=file->memb_addr[mt]) {
+ haddr_t eoa = H5FDget_eoa(file->memb[mt]);
+ fprintf(stderr, " %6d %20llu %20llu %20llu %s\n",
+ (int)mt, (unsigned long long)(file->memb_addr[mt]),
+ (unsigned long long)eoa,
+ (unsigned long long)(file->memb_next[mt]),
+ file->memb_name[mt]);
+ }
+ }
+#endif
+
+ /* Flush each file */
+ for (mt=1; mt<H5FD_MEM_NTYPES; mt++) {
+ if (file->memb[mt]) {
+ H5E_BEGIN_TRY {
+ if (H5FDflush(file->memb[mt])<0) nerrors++;
+ } H5E_END_TRY;
+ }
+ }
+
+ return nerrors ? -1 : 0;
+}
+
diff --git a/src/H5FDmulti.h b/src/H5FDmulti.h
new file mode 100644
index 0000000..dbe7c8e
--- /dev/null
+++ b/src/H5FDmulti.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 1999 NCSA
+ * All rights reserved.
+ *
+ * Programmer: Robb Matzke <matzke@llnl.gov>
+ * Monday, August 2, 1999
+ *
+ * Purpose: The public header file for the "multi" driver.
+ */
+#ifndef H5FDmulti_H
+#define H5FDmulti_H
+
+#include <H5Ipublic.h>
+
+#define H5FD_MULTI (H5FD_multi_init())
+
+hid_t H5FD_multi_init(void);
+herr_t H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map,
+ const hid_t *memb_fapl, const char **memb_name,
+ const haddr_t *memb_addr);
+herr_t H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map/*out*/,
+ hid_t *memb_fapl/*out*/, char **memb_name/*out*/,
+ haddr_t *memb_addr/*out*/);
+herr_t H5Pset_dxpl_multi(hid_t dxpl_id, const hid_t *memb_dxpl);
+herr_t H5Pget_dxpl_multi(hid_t dxpl_id, hid_t *memb_dxpl/*out*/);
+
+herr_t H5Pset_fapl_split(hid_t fapl, const char *meta_ext,
+ hid_t meta_plist_id, const char *raw_ext,
+ hid_t raw_plist_id);
+
+#endif
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index a987b60..93fa724 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -11,6 +11,10 @@
#include <H5FDpublic.h>
intn H5FD_term_interface(void);
+hsize_t H5FD_sb_size(H5FD_t *file);
+herr_t H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf);
+herr_t H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf);
+void *H5FD_fapl_get(H5FD_t *file);
void *H5FD_fapl_copy(hid_t driver_id, const void *fapl);
herr_t H5FD_fapl_free(hid_t driver_id, void *fapl);
void *H5FD_dxpl_copy(hid_t driver_id, const void *dxpl);
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index 8af79d2..a63e982 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -15,8 +15,6 @@ typedef enum H5FD_mem_t {
H5FD_MEM_SUPER,
H5FD_MEM_BTREE,
H5FD_MEM_DRAW,
- H5FD_MEM_META,
- H5FD_MEM_GROUP,
H5FD_MEM_GHEAP,
H5FD_MEM_LHEAP,
H5FD_MEM_OHDR,
@@ -35,8 +33,6 @@ typedef enum H5FD_mem_t {
H5FD_MEM_SUPER, /*super*/ \
H5FD_MEM_SUPER, /*btree*/ \
H5FD_MEM_SUPER, /*draw*/ \
- H5FD_MEM_SUPER, /*meta*/ \
- H5FD_MEM_SUPER, /*group*/ \
H5FD_MEM_SUPER, /*gheap*/ \
H5FD_MEM_SUPER, /*lheap*/ \
H5FD_MEM_SUPER /*ohdr*/ \
@@ -47,15 +43,13 @@ typedef enum H5FD_mem_t {
* pools.
*/
#define H5FD_FLMAP_DICHOTOMY { \
- H5FD_MEM_META, /*default*/ \
- H5FD_MEM_META, /*super*/ \
- H5FD_MEM_META, /*btree*/ \
+ H5FD_MEM_SUPER, /*default*/ \
+ H5FD_MEM_SUPER, /*super*/ \
+ H5FD_MEM_SUPER, /*btree*/ \
H5FD_MEM_DRAW, /*draw*/ \
- H5FD_MEM_META, /*meta*/ \
- H5FD_MEM_META, /*group*/ \
- H5FD_MEM_META, /*gheap*/ \
- H5FD_MEM_META, /*lheap*/ \
- H5FD_MEM_META /*ohdr*/ \
+ H5FD_MEM_SUPER, /*gheap*/ \
+ H5FD_MEM_SUPER, /*lheap*/ \
+ H5FD_MEM_SUPER /*ohdr*/ \
}
/*
@@ -67,8 +61,6 @@ typedef enum H5FD_mem_t {
H5FD_MEM_DEFAULT, /*super*/ \
H5FD_MEM_DEFAULT, /*btree*/ \
H5FD_MEM_DEFAULT, /*draw*/ \
- H5FD_MEM_DEFAULT, /*meta*/ \
- H5FD_MEM_DEFAULT, /*group*/ \
H5FD_MEM_DEFAULT, /*gheap*/ \
H5FD_MEM_DEFAULT, /*lheap*/ \
H5FD_MEM_DEFAULT /*ohdr*/ \
@@ -83,7 +75,12 @@ typedef struct H5FD_t H5FD_t;
typedef struct H5FD_class_t {
const char *name;
haddr_t maxaddr;
+ hsize_t (*sb_size)(H5FD_t *file);
+ herr_t (*sb_encode)(H5FD_t *file, char *name/*out*/,
+ unsigned char *p/*out*/);
+ herr_t (*sb_decode)(H5FD_t *f, const char *name, const unsigned char *p);
size_t fapl_size;
+ void *(*fapl_get)(H5FD_t *file);
void *(*fapl_copy)(const void *fapl);
herr_t (*fapl_free)(void *fapl);
size_t dxpl_size;
diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c
index b383b92..e1ed9c3 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -133,7 +133,11 @@ static herr_t H5FD_sec2_flush(H5FD_t *_file);
static const H5FD_class_t H5FD_sec2_g = {
"sec2", /*name */
MAXADDR, /*maxaddr */
+ NULL, /*sb_size */
+ NULL, /*sb_encode */
+ NULL, /*sb_decode */
0, /*fapl_size */
+ NULL, /*fapl_get */
NULL, /*fapl_copy */
NULL, /*fapl_free */
0, /*dxpl_size */
diff --git a/src/H5Fistore.c b/src/H5Fistore.c
index 4849e98..eca1cd2 100644
--- a/src/H5Fistore.c
+++ b/src/H5Fistore.c
@@ -806,9 +806,8 @@ H5F_istore_init (H5F_t *f)
FUNC_ENTER (H5F_istore_init, FAIL);
HDmemset (rdcc, 0, sizeof(H5F_rdcc_t));
- if (f->shared->fapl->rdcc_nbytes>0 &&
- f->shared->fapl->rdcc_nelmts>0) {
- rdcc->nslots = f->shared->fapl->rdcc_nelmts;
+ if (f->shared->rdcc_nbytes>0 && f->shared->rdcc_nelmts>0) {
+ rdcc->nslots = f->shared->rdcc_nelmts;
rdcc->slot = H5MM_calloc (rdcc->nslots*sizeof(H5F_rdcc_ent_t*));
if (NULL==rdcc->slot) {
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
@@ -1111,7 +1110,7 @@ H5F_istore_prune (H5F_t *f, size_t size)
{
intn i, j, nerrors=0;
H5F_rdcc_t *rdcc = &(f->shared->rdcc);
- size_t total = f->shared->fapl->rdcc_nbytes;
+ size_t total = f->shared->rdcc_nbytes;
const int nmeth=2; /*number of methods */
intn w[1]; /*weighting as an interval */
H5F_rdcc_ent_t *p[2], *cur; /*list pointers */
@@ -1129,7 +1128,7 @@ H5F_istore_prune (H5F_t *f, size_t size)
* begins. The pointers participating in the list traversal are each
* given a chance at preemption before any of the pointers are advanced.
*/
- w[0] = rdcc->nused * f->shared->fapl->rdcc_w0;
+ w[0] = rdcc->nused * f->shared->rdcc_w0;
p[0] = rdcc->head;
p[1] = NULL;
@@ -1353,8 +1352,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
}
assert (found || chunk_size>0);
- if (!found && rdcc->nslots>0 &&
- chunk_size<=f->shared->fapl->rdcc_nbytes &&
+ if (!found && rdcc->nslots>0 && chunk_size<=f->shared->rdcc_nbytes &&
(!ent || !ent->locked)) {
/*
* Add the chunk to the cache only if the slot is not already locked.
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index efe8bd9..d26f406 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -305,9 +305,17 @@ typedef struct H5F_file_t {
haddr_t boot_addr; /* Absolute address of boot block */
haddr_t base_addr; /* Absolute base address for rel.addrs. */
haddr_t freespace_addr; /* Relative address of free-space info */
+ haddr_t driver_addr; /* File driver information block address*/
struct H5AC_t *cache; /* The object cache */
H5F_create_t *fcpl; /* File-creation property list */
- H5F_access_t *fapl; /* File-access property list */
+ intn mdc_nelmts; /* Size of meta data cache (elements) */
+ intn rdcc_nelmts; /* Size of raw data chunk cache (elmts) */
+ size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */
+ double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/
+ hsize_t threshold; /* Threshold for alignment */
+ hsize_t alignment; /* Alignment */
+ uintn gc_ref; /* Garbage-collect references? */
+ hid_t driver_id; /* File driver ID */
struct H5G_t *root_grp; /* Open root group */
intn ncwfs; /* Num entries on cwfs list */
struct H5HG_heap_t **cwfs; /* Global heap cache */
diff --git a/src/H5R.c b/src/H5R.c
index 60cdb9c..8ab44cf 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -177,7 +177,7 @@ H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type,
/* Set up information for dataset region */
/* Return any previous heap block to the free list if we are garbage collecting */
- if(loc->file->shared->fapl->gc_ref) {
+ if(loc->file->shared->gc_ref) {
/* Check for an existing heap ID in the reference */
for(u=0, heapid_found=0; u<H5R_DSET_REG_REF_BUF_SIZE; u++)
if(ref->heapid[u]!=0) {
diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h
index 61e96b7..fd97859 100644
--- a/src/H5Rpublic.h
+++ b/src/H5Rpublic.h
@@ -45,14 +45,14 @@ typedef struct {
* to be defined at run-time, so we have to go with the worst case sizes for
* them. -QAK
*/
-#define H5R_OBJ_REF_BUF_SIZE sizeof(hsize_t)
+#define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t)
/* Object reference structure for user's code */
typedef struct {
unsigned char oid[H5R_OBJ_REF_BUF_SIZE]; /* Buffer to store OID of object referenced */
/* Needs to be large enough to store largest haddr_t in a worst case machine (ie. 8 bytes currently) */
} hobj_ref_t;
-#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(hsize_t)+sizeof(int))
+#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t)+sizeof(int))
/* Dataset Region reference structure for user's code */
typedef struct {
unsigned char heapid[H5R_DSET_REG_REF_BUF_SIZE]; /* Buffer to store heap ID and index */
diff --git a/src/H5T.c b/src/H5T.c
index d8549cb..66ed3d1 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -94,6 +94,7 @@ hid_t H5T_NATIVE_B16_g = FAIL;
hid_t H5T_NATIVE_B32_g = FAIL;
hid_t H5T_NATIVE_B64_g = FAIL;
hid_t H5T_NATIVE_OPAQUE_g = FAIL;
+hid_t H5T_NATIVE_HADDR_g = FAIL;
hid_t H5T_NATIVE_HSIZE_g = FAIL;
hid_t H5T_NATIVE_HSSIZE_g = FAIL;
hid_t H5T_NATIVE_HERR_g = FAIL;
@@ -471,6 +472,13 @@ H5T_init_interface(void)
"unable to initialize H5T layer");
}
+ /* haddr_t */
+ dt = H5I_object(H5T_NATIVE_HADDR_g=H5Tcopy(H5T_NATIVE_UINT_g));
+ dt->state = H5T_STATE_IMMUTABLE;
+ dt->size = sizeof(haddr_t);
+ dt->u.atomic.prec = 8*dt->size;
+ dt->u.atomic.offset = 0;
+
/* hsize_t */
dt = H5I_object (H5T_NATIVE_HSIZE_g = H5Tcopy (H5T_NATIVE_UINT_g));
dt->state = H5T_STATE_IMMUTABLE;
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 12dd593..e595da6 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -357,6 +357,7 @@ __DLLVAR__ hid_t H5T_FORTRAN_S1_g;
#define H5T_NATIVE_B32 (H5open(), H5T_NATIVE_B32_g)
#define H5T_NATIVE_B64 (H5open(), H5T_NATIVE_B64_g)
#define H5T_NATIVE_OPAQUE (H5open(), H5T_NATIVE_OPAQUE_g)
+#define H5T_NATIVE_HADDR (H5open(), H5T_NATIVE_HADDR_g)
#define H5T_NATIVE_HSIZE (H5open(), H5T_NATIVE_HSIZE_g)
#define H5T_NATIVE_HSSIZE (H5open(), H5T_NATIVE_HSSIZE_g)
#define H5T_NATIVE_HERR (H5open(), H5T_NATIVE_HERR_g)
@@ -379,6 +380,7 @@ __DLLVAR__ hid_t H5T_NATIVE_B16_g;
__DLLVAR__ hid_t H5T_NATIVE_B32_g;
__DLLVAR__ hid_t H5T_NATIVE_B64_g;
__DLLVAR__ hid_t H5T_NATIVE_OPAQUE_g;
+__DLLVAR__ hid_t H5T_NATIVE_HADDR_g;
__DLLVAR__ hid_t H5T_NATIVE_HSIZE_g;
__DLLVAR__ hid_t H5T_NATIVE_HSSIZE_g;
__DLLVAR__ hid_t H5T_NATIVE_HERR_g;
diff --git a/src/H5private.h b/src/H5private.h
index bd9e348..253fbad 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -177,6 +177,7 @@
#define HDF5_FREESPACE_VERSION 0 /* of the Free-Space Info */
#define HDF5_OBJECTDIR_VERSION 0 /* of the Object Directory format */
#define HDF5_SHAREDHEADER_VERSION 0 /* of the Shared-Header Info */
+#define HDF5_DRIVERINFO_VERSION 0 /* of the Driver Information Block*/
/*
* Status return values for the `herr_t' type.
diff --git a/src/Makefile.in b/src/Makefile.in
index ec675a1..da03c0e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -22,12 +22,12 @@ CLEAN=libhdf5.settings
## Source and object files for the library (lexicographically)...
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fistore.c \
- H5FD.c H5FDsec2.c H5FDfamily.c H5FDmpio.c H5FDcore.c H5G.c H5Gent.c \
- H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c \
- H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.c \
- H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5R.c H5RA.c \
- H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c \
- H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5V.c H5Z.c
+ H5FD.c H5FDsec2.c H5FDfamily.c H5FDmpio.c H5FDcore.c H5FDmulti.c H5G.c \
+ H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c \
+ H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c \
+ H5Omtime.c H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c \
+ H5R.c H5RA.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \
+ H5Sselect.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5V.c H5Z.c
LIB_OBJ=$(LIB_SRC:.c=.lo)
@@ -37,9 +37,9 @@ MOSTLYCLEAN=H5detect.o H5detect H5Tinit.o H5Tinit.c
## Public header files (to be installed)...
PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \
H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDfamily.h H5FDmpio.h H5FDsec2.h \
- H5FDcore.h H5Gpublic.h H5HGpublic.h H5HLpublic.h H5Ipublic.h H5MMpublic.h \
- H5Opublic.h H5Ppublic.h H5Rpublic.h H5RApublic.h H5Spublic.h H5Tpublic.h \
- H5Zpublic.h H5config.h hdf5.h H5api_adpt.h
+ H5FDcore.h H5FDmulti.h H5Gpublic.h H5HGpublic.h H5HLpublic.h H5Ipublic.h \
+ H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5RApublic.h H5Spublic.h \
+ H5Tpublic.h H5Zpublic.h H5config.h hdf5.h H5api_adpt.h
## Other header files (not to be installed)...
PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \
diff --git a/src/hdf5.h b/src/hdf5.h
index 401238f..f5560fd 100644
--- a/src/hdf5.h
+++ b/src/hdf5.h
@@ -44,5 +44,6 @@
#include <H5FDfamily.h> /* File families */
#include <H5FDmpio.h> /* Parallel files using MPI-2 I/O */
#include <H5FDsec2.h> /* POSIX unbuffered file I/O */
+#include <H5FDmulti.h> /* Usage-partitioned file family */
#endif