summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1999-08-17 19:12:59 (GMT)
committerRobb Matzke <matzke@llnl.gov>1999-08-17 19:12:59 (GMT)
commitcc89b8a605dfc7370cb760e6c3d7339cbf1e9884 (patch)
tree82e0552ea6a80a2e362fdc77960a3483648aae75 /src
parent5ef0237e2fe5ac6aee0d97fdc6bcf22f72d47162 (diff)
downloadhdf5-cc89b8a605dfc7370cb760e6c3d7339cbf1e9884.zip
hdf5-cc89b8a605dfc7370cb760e6c3d7339cbf1e9884.tar.gz
hdf5-cc89b8a605dfc7370cb760e6c3d7339cbf1e9884.tar.bz2
[svn-r1572] Changes since 19990810
---------------------- ./MANIFEST ./src/H5FDmulti.c [NEW] ./src/H5FDmulti.h [NEW] ./src/Makefile.in ./src/hdf5.h The split driver was reimplemented as a more general "multi" driver which is capable of splitting data into multiple files like the family driver except the partioning is done by memory usage type instead of address. The H5Pset_fapl_split() function just calls H5Pset_fapl_multi() with arguments which prepare to split the address space into two files: meta and raw data. This is the first version. I plan to allow the open() call to relax a bit which would allow one to open an hdf5 file when only the meta-data file is present. This would allow a very large file to be split and stored on tape and the relatively small meta file to be mirrored on disk to allow limited browsing of the file (any request for raw data would fail). ./src/H5private.h ./src/H5F.c ./src/H5FD.c ./src/H5FDprivate.h ./src/H5FDpublic.h ./src/H5FDcore.c ./src/H5FDfamily.c ./src/H5FDmpio.c ./src/H5FDsec2.c Added the ability for a file driver to store information in the superblock which would be needed if the file were opened again later for reading. The format is driver-defined which allows users to extend it however they like. ./doc/html/H5.format.html Added information about the new driver information block of the superblock. This is where file drivers store information they need in order to reopen the file later. ./src/H5F.c ./src/H5Fprivate.h ./src/H5FD.c ./src/H5FDprivate.h ./src/H5FDpublic.h ./src/H5FDcore.c ./src/H5FDfamily.c ./src/H5FDmpio.c ./src/H5FDsec2.c ./src/H5Fistore.c ./src/H5R.c The file access properties and the file access property list were decoupled, which allows the property list to more cleanly contain properties for various levels of the file and which allows the property list to be modified more cleanly when opening files. ./src/H5.c ./src/H5FDpublic.h Removed H5FD_MEM_META and H5FD_MEM_GROUP since they're never used. ./src/H5D.c Changed the way we detect the MPIO driver in all these special cases. ./src/H5F.c ./src/H5Rpublic.h ./test/tfile.c The default file sizeof(offset) was changed to be a function of haddr_t instead of hsize_t. THE H5RPUBLIC.H DEFINITIONS WILL HAVE PROBLEMS IF THE USER CREATES A FILE WITH NON-DEFAULT OFFSET AND SIZE SIZES! ./src/H5F.c Fixed an uninitialized memory access bug in file closing related to the VFL. ./src/H5T.c ./src/H5Tpublic.h Added an H5T_NATIVE_HADDR predefined datatype which corresponds to the `haddr_t' type. ./test/Makefile.in Reformatted long lines. ./test/big.c ./test/cmpd_dset.c ./test/dsets.c ./test/dtypes.c ./test/extend.c ./test/external.c Removed the H5F_ACC_DEBUG flag from file creation/open calls. ./test/big.c Plugged a memory leak. ./test/h5test.c Added support for the `multi' driver. Removed #warning about not having the stdio driver. Plans are to not implement it since the sec2 driver serves the same purpose and testing didn't show any difference in execution times between the two.
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