diff options
author | Robb Matzke <matzke@llnl.gov> | 1999-08-10 20:21:32 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1999-08-10 20:21:32 (GMT) |
commit | cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28 (patch) | |
tree | b7075c9f11db1b343593b5e0619a285ccc8418af /src | |
parent | 7d949c9da91b33955d4e253c1093a4f23fb63523 (diff) | |
download | hdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.zip hdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.tar.gz hdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.tar.bz2 |
[svn-r1568] Changes since 19990730
----------------------
This extensive change is the virtual file layer implementation. I've
ported and tested the sec2, family, and core drivers and only ported
the mpio driver (Albert will test it). So if you need MPIO I would
recommend sticking with the previous version for a while.
You will get a few compile warnings about split and stdio drivers not
being implemented and possibly tracing information not inserted in
some of the drivers. You can safely ignore them but I plan to fix
them.
I'm still working on the split driver because I just realized that it
needs a part of the VFL that isn't written yet.
Documentation is being updated also because there were some minor
changes (mostly just name changes). It should be available on my web
site later this week.
./MANIFEST
./src/Makefile.in
./src/hdf5.h
./src/H5Flow.c [REMOVED]
./src/H5Fstdio.c [REMOVED]
./src/H5Fsec2.c [REMOVED]
./src/H5Fsplit.c [REMOVED]
./src/H5Fmpio.c [REMOVED]
./src/H5Ffamily.c [REMOVED]
./src/H5Fcore.c [REMOVED]
./src/H5MFpublic.h [REMOVED]
./src/H5FD.c [NEW]
./src/H5FDcore.c [NEW]
./src/H5FDcore.h [NEW]
./src/H5FDfamily.c [NEW]
./src/H5FDfamily.h [NEW]
./src/H5FDmpio.c [NEW]
./src/H5FDmpio.h [NEW]
./src/H5FDprivate.h [NEW]
./src/H5FDpublic.h [NEW]
./src/H5FDsec2.c [NEW]
./src/H5FDsec2.h [NEW]
Removed/added files for virtual file layer.
./bin/trace
./src/H5.c
Removed unused public datatypes and added new VFL public
datatypes.
Changed an error message.
./config/BlankForm
./config/dec-flags
./config/gnu-flags
./config/hpux10.20
./config/hpux9.03
./config/irix5.x
./config/irix6.x
./config/solaris2.x
./config/unicosmk
Removed the H5F_OPT_SEEK and H5F_LOW_DFLT constants from the
configuration since they're no longer applicable. The default
file driver is always the sec2 driver and it always optimizes
calls to lseek() or lseek64().
./config/depend.in
C preprocessor errors generated during automatic dependency
building are sent to /dev/null to prevent them from appearing
twice in the make output.
./src/H5AC.c
./src/H5B.c
./src/H5D.c
./src/H5F.c
./src/H5G.c
./src/H5Gent.c
./src/H5Gnode.c
./src/H5HG.c
./src/H5HL.c
./src/H5O.c
./src/H5Oattr.c
./src/H5Odtype.c
./src/H5Oefl.c
./src/H5Oshared.c
./src/H5T.c
./src/H5detect.c
./test/ohdr.c
Changed H5F_ADDR_UNDEF to HADDR_UNDEF to be more consistent
with the `haddr_t' datatype which is now a public type.
./src/H5D.c
./src/H5P.c
./src/H5Ppublic.h
./src/H5Tconv.c
./test/cmpd_dset.c
./test/dsets.c
./test/overhead.c
./test/tselect.c
./test/tvltypes.c
The H5P_DATASET_XFER constant was changed to H5P_DATA_XFER
because the properties apply to all types of I/O operations,
not just datasets.
./src/H5B.c
./src/H5Bprivate.h
./src/H5D.c
./src/H5Dpublic.h
./src/H5F.c
./src/H5Farray.c
./src/H5Fistore.c
./src/H5Fprivate.h
./src/H5Fpublic.h
./src/H5Gnode.c
./src/H5Gpkg.h
./src/H5HG.c
./src/H5HL.c
./src/H5O.c
./src/H5R.c
./src/H5Sall.c
./src/H5Shyper.c
./src/H5Smpio.c
./src/H5Spoint.c
./src/H5Sprivate.h
./test/big.c
./test/h5test.c
./test/istore.c
./testpar/t_dset.c
./testpar/t_file.c
./tools/h5debug.c
./tools/h5ls.c
Modified to work with the virtual file layer by calling H5FD_*
functions instead of H5F_low_* functions and by passing file
access and data transfer properties by object ID instead of
pointer.
Changed H5D_transfer_t to H5FD_mpio_xfer_t since the
COLLECTIVE vs. INDEPENDENT transfer mode is specific to the
MPIO file driver.
Moved MPIO-specific stuff into the MPIO driver.
./src/H5B.c
./src/H5D.c
./src/H5Fprivate.h
The H5F_mpio_* private functions were renamed and placed in
the H5FDmpio driver except those which appeared in H5Smpio.c.
./src/H5E.c
./src/H5Epublic.h
Added major error number H5E_VFL for virtual file layer
related errors.
./src/H5F.c
./src/H5Fprivate.h
Changed the logic that controls whether the boot block is
written. Instead of assuming that the first call to write the
boot block is only to allocate space, I've added a function
argument which makes this explicit.
Changed the way files are compared so that a driver-defined
comparison function can be called. Files which belong to
different drivers are always considered different.
Removed H5F_driver_t since file drivers are now identified by
object ID instead of a special non-user-extendible datatype.
Removed all the hard-coded low-level file properties which
have been replaced by the various file drivers.
./src/H5I.c
./src/H5Iprivate.h
Added the H5I_inc_ref() which was removed a few months ago
since we finally have a use for it.
./src/H5Ipublic.h
Added the H5I_VFL object ID type to identify file drivers in
the virtual file layer.
./src/H5MF.c
./src/H5MFprivate.h
Moved all the allocation/deallocation code into the virtual
file layer which allows file drivers to override much of it.
./src/H5P.c
./src/H5Ppublic.h
Moved file driver-specific code into the various file driver
files.
The H5Pcopy() and H5Pclose() functions make calls into the
virtual file driver to manage the memory for driver-specific
file access and data transfer properties.
./src/H5private.h
./src/H5public.h
The `haddr_t' type is now public.
./test/tfile.c
Added a few more comments.
Diffstat (limited to 'src')
-rw-r--r-- | src/.distdep | 824 | ||||
-rw-r--r-- | src/H5.c | 128 | ||||
-rw-r--r-- | src/H5AC.c | 6 | ||||
-rw-r--r-- | src/H5B.c | 55 | ||||
-rw-r--r-- | src/H5Bprivate.h | 2 | ||||
-rw-r--r-- | src/H5D.c | 142 | ||||
-rw-r--r-- | src/H5Distore.c | 256 | ||||
-rw-r--r-- | src/H5Dprivate.h | 1 | ||||
-rw-r--r-- | src/H5Dpublic.h | 10 | ||||
-rw-r--r-- | src/H5E.c | 1 | ||||
-rw-r--r-- | src/H5Epublic.h | 3 | ||||
-rw-r--r-- | src/H5F.c | 1343 | ||||
-rw-r--r-- | src/H5FD.c | 1642 | ||||
-rw-r--r-- | src/H5FDcore.c | 491 | ||||
-rw-r--r-- | src/H5FDcore.h | 21 | ||||
-rw-r--r-- | src/H5FDfamily.c | 777 | ||||
-rw-r--r-- | src/H5FDfamily.h | 23 | ||||
-rw-r--r-- | src/H5FDmpio.c | 1367 | ||||
-rw-r--r-- | src/H5FDmpio.h | 50 | ||||
-rw-r--r-- | src/H5FDprivate.h | 35 | ||||
-rw-r--r-- | src/H5FDpublic.h | 154 | ||||
-rw-r--r-- | src/H5FDsec2.c | 585 | ||||
-rw-r--r-- | src/H5FDsec2.h | 20 | ||||
-rw-r--r-- | src/H5Farray.c | 266 | ||||
-rw-r--r-- | src/H5Fcore.c | 280 | ||||
-rw-r--r-- | src/H5Ffamily.c | 626 | ||||
-rw-r--r-- | src/H5Fistore.c | 256 | ||||
-rw-r--r-- | src/H5Flow.c | 778 | ||||
-rw-r--r-- | src/H5Fmpio.c | 1138 | ||||
-rw-r--r-- | src/H5Fprivate.h | 301 | ||||
-rw-r--r-- | src/H5Fpublic.h | 28 | ||||
-rw-r--r-- | src/H5Fsec2.c | 355 | ||||
-rw-r--r-- | src/H5Fsplit.c | 523 | ||||
-rw-r--r-- | src/H5Fstdio.c | 398 | ||||
-rw-r--r-- | src/H5G.c | 7 | ||||
-rw-r--r-- | src/H5Gent.c | 2 | ||||
-rw-r--r-- | src/H5Gnode.c | 13 | ||||
-rw-r--r-- | src/H5Gpkg.h | 2 | ||||
-rw-r--r-- | src/H5HG.c | 15 | ||||
-rw-r--r-- | src/H5HL.c | 34 | ||||
-rw-r--r-- | src/H5I.c | 38 | ||||
-rw-r--r-- | src/H5Iprivate.h | 2 | ||||
-rw-r--r-- | src/H5Ipublic.h | 1 | ||||
-rw-r--r-- | src/H5MF.c | 267 | ||||
-rw-r--r-- | src/H5MFprivate.h | 15 | ||||
-rw-r--r-- | src/H5MFpublic.h | 31 | ||||
-rw-r--r-- | src/H5O.c | 34 | ||||
-rw-r--r-- | src/H5Oattr.c | 2 | ||||
-rw-r--r-- | src/H5Odtype.c | 8 | ||||
-rw-r--r-- | src/H5Oefl.c | 2 | ||||
-rw-r--r-- | src/H5Oshared.c | 2 | ||||
-rw-r--r-- | src/H5P.c | 1118 | ||||
-rw-r--r-- | src/H5Ppublic.h | 36 | ||||
-rw-r--r-- | src/H5R.c | 2 | ||||
-rw-r--r-- | src/H5Sall.c | 50 | ||||
-rw-r--r-- | src/H5Shyper.c | 90 | ||||
-rw-r--r-- | src/H5Smpio.c | 78 | ||||
-rw-r--r-- | src/H5Spoint.c | 34 | ||||
-rw-r--r-- | src/H5Sprivate.h | 38 | ||||
-rw-r--r-- | src/H5T.c | 22 | ||||
-rw-r--r-- | src/H5Tconv.c | 2 | ||||
-rw-r--r-- | src/H5Tpkg.h | 2 | ||||
-rw-r--r-- | src/H5Tprivate.h | 2 | ||||
-rw-r--r-- | src/H5detect.c | 2 | ||||
-rw-r--r-- | src/H5private.h | 5 | ||||
-rw-r--r-- | src/H5public.h | 20 | ||||
-rw-r--r-- | src/Makefile.in | 31 | ||||
-rw-r--r-- | src/hdf5.h | 44 |
68 files changed, 7561 insertions, 7375 deletions
diff --git a/src/.distdep b/src/.distdep index cee970e..458112d 100644 --- a/src/.distdep +++ b/src/.distdep @@ -9,16 +9,18 @@ H5.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5Eprivate.h \ H5Epublic.h \ + H5FDprivate.h \ H5Iprivate.h \ H5MMprivate.h \ - H5MMpublic.h \ H5Pprivate.h \ H5Ppublic.h \ + H5Dpublic.h \ H5Zpublic.h \ H5Rpublic.h \ H5Sprivate.h \ @@ -26,7 +28,10 @@ H5.lo: \ H5Gprivate.h \ H5Gpublic.h \ H5Oprivate.h \ - H5Opublic.h + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h H5A.lo: \ H5A.c \ H5private.h \ @@ -39,8 +44,10 @@ H5A.lo: \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Dprivate.h \ + H5Dpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Oprivate.h \ @@ -49,6 +56,8 @@ H5A.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ H5Sprivate.h \ H5Spublic.h \ H5Zprivate.h \ @@ -56,11 +65,7 @@ H5A.lo: \ H5Eprivate.h \ H5Epublic.h \ H5MMprivate.h \ - H5MMpublic.h \ - H5Pprivate.h \ - H5Ppublic.h \ - H5Apkg.h \ - H5Aprivate.h + H5Pprivate.h H5AC.lo: \ H5AC.c \ H5private.h \ @@ -72,9 +77,9 @@ H5AC.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ - H5Eprivate.h \ - H5Epublic.h + H5FDpublic.h \ + H5MMpublic.h \ + H5Eprivate.h H5B.lo: \ H5B.c \ H5private.h \ @@ -86,13 +91,13 @@ H5B.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5Eprivate.h \ H5Epublic.h \ H5MFprivate.h \ - H5MFpublic.h \ H5MMprivate.h H5D.lo: \ H5D.c \ @@ -106,8 +111,10 @@ H5D.lo: \ H5ACpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Dprivate.h \ + H5Dpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -118,6 +125,8 @@ H5D.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ H5Sprivate.h \ H5Spublic.h \ H5Zprivate.h \ @@ -126,13 +135,9 @@ H5D.lo: \ H5Epublic.h \ H5HLprivate.h \ H5HLpublic.h \ - H5MFprivate.h \ - H5MFpublic.h \ H5MMprivate.h \ - H5MMpublic.h \ H5Pprivate.h \ - H5Ppublic.h \ - H5TBprivate.h + H5Ppublic.h H5E.lo: \ H5E.c \ H5private.h \ @@ -144,27 +149,34 @@ H5E.lo: \ H5Eprivate.h H5F.lo: \ H5F.c \ - H5private.h \ + H5FDsec2.h \ + H5Ipublic.h \ H5public.h \ H5config.h \ H5api_adpt.h \ + H5FDfamily.h \ + H5FDmpio.h \ + H5FDpublic.h \ + H5private.h \ H5Aprivate.h \ H5Apublic.h \ - H5Ipublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.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 \ @@ -173,9 +185,7 @@ H5F.lo: \ H5ACprivate.h \ H5ACpublic.h \ H5Eprivate.h \ - H5Epublic.h \ - H5MMprivate.h \ - H5MMpublic.h + H5Epublic.h H5Farray.lo: \ H5Farray.c \ H5private.h \ @@ -187,6 +197,8 @@ H5Farray.lo: \ H5Ipublic.h \ H5Fprivate.h \ H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -197,32 +209,17 @@ H5Farray.lo: \ 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 \ - H5MFpublic.h -H5Fcore.lo: \ - H5Fcore.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5Ipublic.h -H5Ffamily.lo: \ - H5Ffamily.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5Ipublic.h + H5Pprivate.h H5Fistore.lo: \ H5Fistore.c \ H5private.h \ @@ -234,6 +231,8 @@ H5Fistore.lo: \ H5Ipublic.h \ H5Fprivate.h \ H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -244,79 +243,140 @@ H5Fistore.lo: \ 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 \ - H5MFpublic.h -H5Flow.lo: \ - H5Flow.c \ + H5MMprivate.h +H5FD.lo: \ + H5FD.c \ H5private.h \ H5public.h \ H5config.h \ H5api_adpt.h \ H5Eprivate.h \ H5Epublic.h \ - H5Ipublic.h -H5Fmpio.lo: \ - H5Fmpio.c \ - H5private.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 \ - H5Eprivate.h \ - H5Epublic.h \ H5Ipublic.h \ - H5Dprivate.h \ + H5Apublic.h \ + H5ACpublic.h \ + H5Bpublic.h \ H5Dpublic.h \ - H5Fprivate.h \ + H5Epublic.h \ H5Fpublic.h \ - H5Gprivate.h \ + H5FDpublic.h \ H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5HGprivate.h \ H5HGpublic.h \ - H5Tprivate.h \ + H5HLpublic.h \ + H5MMpublic.h \ + H5Opublic.h \ + H5Ppublic.h \ + H5Zpublic.h \ + H5Rpublic.h \ + H5RApublic.h \ + H5Spublic.h \ H5Tpublic.h \ - H5Sprivate.h -H5Fsec2.lo: \ - H5Fsec2.c \ - H5private.h \ + H5FDcore.h \ + H5FDfamily.h \ + H5FDmpio.h \ + H5FDsec2.h +H5FDfamily.lo: \ + H5FDfamily.c \ + hdf5.h \ H5public.h \ H5config.h \ H5api_adpt.h \ - H5Eprivate.h \ + H5Ipublic.h \ + H5Apublic.h \ + H5ACpublic.h \ + H5Bpublic.h \ + H5Dpublic.h \ H5Epublic.h \ - H5Ipublic.h -H5Fsplit.lo: \ - H5Fsplit.c \ - H5private.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 +H5FDmpio.lo: \ + H5FDmpio.c \ + hdf5.h \ H5public.h \ H5config.h \ H5api_adpt.h \ - H5Eprivate.h \ - H5Epublic.h \ H5Ipublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ + H5Apublic.h \ + H5ACpublic.h \ + H5Bpublic.h \ H5Dpublic.h \ - H5MFprivate.h \ - H5MFpublic.h -H5Fstdio.lo: \ - H5Fstdio.c \ - H5private.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.lo: \ + H5FDcore.c \ + hdf5.h \ H5public.h \ H5config.h \ H5api_adpt.h \ - H5Eprivate.h \ + H5Ipublic.h \ + H5Apublic.h \ + H5ACpublic.h \ + H5Bpublic.h \ + H5Dpublic.h \ H5Epublic.h \ - H5Ipublic.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 H5G.lo: \ H5G.c \ H5private.h \ @@ -332,14 +392,18 @@ H5G.lo: \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.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 \ @@ -350,7 +414,8 @@ H5G.lo: \ H5ACprivate.h \ H5ACpublic.h \ H5HLprivate.h \ - H5HLpublic.h + H5HLpublic.h \ + H5Iprivate.h H5Gent.lo: \ H5Gent.c \ H5private.h \ @@ -365,11 +430,11 @@ H5Gent.lo: \ H5ACpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h + H5Bprivate.h H5Gnode.lo: \ H5Gnode.c \ H5private.h \ @@ -381,7 +446,8 @@ H5Gnode.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5Eprivate.h \ @@ -392,18 +458,22 @@ H5Gnode.lo: \ H5HLprivate.h \ H5HLpublic.h \ H5MFprivate.h \ - H5MFpublic.h \ H5MMprivate.h \ - H5MMpublic.h \ H5Oprivate.h \ H5Opublic.h \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ H5Sprivate.h \ H5Spublic.h \ - H5Zprivate.h + H5Dpublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Pprivate.h \ + H5Ppublic.h H5Gstab.lo: \ H5Gstab.c \ H5private.h \ @@ -415,7 +485,8 @@ H5Gstab.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Eprivate.h \ H5Epublic.h \ H5Gpkg.h \ @@ -426,14 +497,17 @@ H5Gstab.lo: \ H5HLprivate.h \ H5HLpublic.h \ H5MMprivate.h \ - H5MMpublic.h \ H5Oprivate.h \ H5Opublic.h \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ - H5Sprivate.h + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h H5HG.lo: \ H5HG.c \ H5private.h \ @@ -445,13 +519,13 @@ H5HG.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Eprivate.h \ H5Epublic.h \ H5HGprivate.h \ H5HGpublic.h \ H5MFprivate.h \ - H5MFpublic.h \ H5MMprivate.h H5HL.lo: \ H5HL.c \ @@ -464,13 +538,13 @@ H5HL.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Eprivate.h \ H5Epublic.h \ H5HLprivate.h \ H5HLpublic.h \ H5MFprivate.h \ - H5MFpublic.h \ H5MMprivate.h H5I.lo: \ H5I.c \ @@ -489,7 +563,12 @@ H5MF.lo: \ H5api_adpt.h \ H5Eprivate.h \ H5Epublic.h \ - H5Ipublic.h + H5Ipublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5FDprivate.h H5MM.lo: \ H5MM.c \ H5private.h \ @@ -510,14 +589,13 @@ H5O.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Eprivate.h \ H5Epublic.h \ H5Iprivate.h \ H5MFprivate.h \ - H5MFpublic.h \ H5MMprivate.h \ - H5MMpublic.h \ H5Oprivate.h \ H5Opublic.h \ H5Gprivate.h \ @@ -527,7 +605,13 @@ H5O.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h \ + H5Zprivate.h H5Oattr.lo: \ H5Oattr.c \ H5private.h \ @@ -543,20 +627,20 @@ H5Oattr.lo: \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ - H5MMprivate.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 \ - H5Zprivate.h \ - H5Zpublic.h \ - H5Apkg.h + H5Dpublic.h H5Ocomp.lo: \ H5Ocomp.c \ H5private.h \ @@ -572,7 +656,7 @@ H5Ocomp.lo: \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -580,7 +664,12 @@ H5Ocomp.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h H5Ocont.lo: \ H5Ocont.c \ H5private.h \ @@ -596,7 +685,7 @@ H5Ocont.lo: \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -604,7 +693,12 @@ H5Ocont.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h H5Odtype.lo: \ H5Odtype.c \ H5private.h \ @@ -620,20 +714,20 @@ H5Odtype.lo: \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ - H5MMprivate.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 \ - H5Zprivate.h \ - H5Zpublic.h \ - H5Tpkg.h + H5Dpublic.h H5Oefl.lo: \ H5Oefl.c \ H5private.h \ @@ -647,9 +741,9 @@ H5Oefl.lo: \ H5HLpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ - H5MMprivate.h \ + H5FDpublic.h \ H5MMpublic.h \ + H5MMprivate.h \ H5Oprivate.h \ H5Opublic.h \ H5Gprivate.h \ @@ -660,9 +754,9 @@ H5Oefl.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ - H5Zprivate.h + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h H5Ofill.lo: \ H5Ofill.c \ H5private.h \ @@ -679,14 +773,19 @@ H5Ofill.lo: \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5HGprivate.h \ H5HGpublic.h \ - H5Tprivate.h + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h H5Olayout.lo: \ H5Olayout.c \ H5private.h \ @@ -698,6 +797,8 @@ H5Olayout.lo: \ H5Ipublic.h \ H5Fprivate.h \ H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -708,9 +809,12 @@ H5Olayout.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ H5Sprivate.h \ H5Spublic.h \ - H5Zprivate.h + H5Zprivate.h \ + H5Zpublic.h H5Omtime.lo: \ H5Omtime.c \ H5private.h \ @@ -726,7 +830,7 @@ H5Omtime.lo: \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -734,7 +838,12 @@ H5Omtime.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h H5Oname.lo: \ H5Oname.c \ H5private.h \ @@ -750,7 +859,7 @@ H5Oname.lo: \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -758,7 +867,12 @@ H5Oname.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h H5Onull.lo: \ H5Onull.c \ H5private.h \ @@ -770,14 +884,19 @@ H5Onull.lo: \ H5Fprivate.h \ H5Fpublic.h \ H5Ipublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5HGprivate.h \ H5HGpublic.h \ - H5Tprivate.h + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h H5Osdspace.lo: \ H5Osdspace.c \ H5private.h \ @@ -793,15 +912,20 @@ H5Osdspace.lo: \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ - H5MMprivate.h \ + H5FDpublic.h \ H5MMpublic.h \ + H5MMprivate.h \ H5Oprivate.h \ H5Opublic.h \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h H5Oshared.lo: \ H5Oshared.c \ H5private.h \ @@ -817,7 +941,7 @@ H5Oshared.lo: \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -825,7 +949,12 @@ H5Oshared.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h H5Ostab.lo: \ H5Ostab.c \ H5private.h \ @@ -841,15 +970,20 @@ H5Ostab.lo: \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ - H5MMprivate.h \ + H5FDpublic.h \ H5MMpublic.h \ + H5MMprivate.h \ H5Oprivate.h \ H5Opublic.h \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h H5P.lo: \ H5P.c \ H5private.h \ @@ -862,8 +996,10 @@ H5P.lo: \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Dprivate.h \ + H5Dpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Oprivate.h \ @@ -872,12 +1008,15 @@ H5P.lo: \ 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 \ @@ -891,6 +1030,8 @@ H5R.lo: \ H5Dpublic.h \ H5Fprivate.h \ H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -901,13 +1042,11 @@ H5R.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ H5Sprivate.h \ H5Spublic.h \ - H5Zprivate.h \ - H5Zpublic.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5MMprivate.h + H5Zprivate.h H5RA.lo: \ H5RA.c \ H5RAprivate.h \ @@ -921,6 +1060,8 @@ H5RA.lo: \ H5private.h \ H5Fprivate.h \ H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -931,12 +1072,15 @@ H5RA.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ H5Sprivate.h \ H5Spublic.h \ H5Zprivate.h \ H5Zpublic.h \ H5Eprivate.h \ - H5Epublic.h + H5Epublic.h \ + H5Iprivate.h H5S.lo: \ H5S.c \ H5private.h \ @@ -953,14 +1097,19 @@ H5S.lo: \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5HGprivate.h \ H5HGpublic.h \ - H5Tprivate.h + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h H5Sall.lo: \ H5Sall.c \ H5private.h \ @@ -970,11 +1119,14 @@ H5Sall.lo: \ H5Eprivate.h \ H5Epublic.h \ H5Ipublic.h \ + H5Iprivate.h \ H5Sprivate.h \ H5Spublic.h \ + H5Dpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -984,21 +1136,22 @@ H5Sall.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h H5Shyper.lo: \ H5Shyper.c \ H5private.h \ H5public.h \ H5config.h \ H5api_adpt.h \ - H5Eprivate.h \ - H5Epublic.h \ + H5Dprivate.h \ + H5Dpublic.h \ H5Ipublic.h \ - H5Sprivate.h \ - H5Spublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -1009,11 +1162,17 @@ H5Shyper.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ H5Zprivate.h \ H5Zpublic.h \ - H5Vprivate.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Iprivate.h \ H5MMprivate.h \ - H5MMpublic.h + H5Pprivate.h H5Smpio.lo: \ H5Smpio.c \ H5private.h \ @@ -1023,11 +1182,14 @@ H5Smpio.lo: \ H5Eprivate.h \ H5Epublic.h \ H5Ipublic.h \ + H5FDprivate.h \ + H5FDpublic.h \ H5Sprivate.h \ H5Spublic.h \ + H5Dpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -1037,7 +1199,9 @@ H5Smpio.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h H5Snone.lo: \ H5Snone.c \ H5private.h \ @@ -1047,11 +1211,14 @@ H5Snone.lo: \ H5Eprivate.h \ H5Epublic.h \ H5Ipublic.h \ + H5Iprivate.h \ H5Sprivate.h \ H5Spublic.h \ + H5Dpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -1061,7 +1228,9 @@ H5Snone.lo: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h H5Spoint.lo: \ H5Spoint.c \ H5private.h \ @@ -1071,13 +1240,15 @@ H5Spoint.lo: \ H5Eprivate.h \ H5Epublic.h \ H5Ipublic.h \ + H5Iprivate.h \ H5MMprivate.h \ H5MMpublic.h \ H5Sprivate.h \ H5Spublic.h \ + H5Dpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -1088,9 +1259,7 @@ H5Spoint.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ - H5Zprivate.h \ - H5Zpublic.h \ - H5Vprivate.h + H5Rprivate.h H5Sselect.lo: \ H5Sselect.c \ H5private.h \ @@ -1105,9 +1274,10 @@ H5Sselect.lo: \ H5MMpublic.h \ H5Sprivate.h \ H5Spublic.h \ + H5Dpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -1118,8 +1288,7 @@ H5Sselect.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ - H5Zprivate.h \ - H5Zpublic.h + H5Rprivate.h H5T.lo: \ H5T.c \ H5private.h \ @@ -1131,6 +1300,8 @@ H5T.lo: \ H5Ipublic.h \ H5Fprivate.h \ H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ @@ -1141,6 +1312,8 @@ H5T.lo: \ H5HGpublic.h \ H5Tprivate.h \ H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ H5Sprivate.h \ H5Spublic.h \ H5Zprivate.h \ @@ -1148,7 +1321,8 @@ H5T.lo: \ H5Iprivate.h \ H5Eprivate.h \ H5Epublic.h \ - H5MMprivate.h + H5MMprivate.h \ + H5Pprivate.h H5Tbit.lo: \ H5Tbit.c \ H5private.h \ @@ -1164,10 +1338,15 @@ H5Tbit.lo: \ H5HGpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ H5Rprivate.h \ H5Rpublic.h \ - H5Tprivate.h + H5Tprivate.h \ + H5Tpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h H5Tconv.lo: \ H5Tconv.c \ H5Iprivate.h \ @@ -1180,20 +1359,20 @@ H5Tconv.lo: \ H5Epublic.h \ H5MMprivate.h \ H5MMpublic.h \ + H5Pprivate.h \ + H5Ppublic.h \ + H5Dpublic.h \ + H5Fpublic.h \ + H5Zpublic.h \ + H5Fprivate.h \ + H5FDpublic.h \ H5Tpkg.h \ H5HGprivate.h \ H5HGpublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Dpublic.h \ H5Rprivate.h \ H5Rpublic.h \ H5Tprivate.h \ - H5Tpublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h + H5Tpublic.h H5Tinit.lo: \ H5Tinit.c \ H5private.h \ @@ -1211,7 +1390,7 @@ H5Tinit.lo: \ H5HGpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Rprivate.h \ H5Rpublic.h \ H5Tprivate.h \ @@ -1231,17 +1410,17 @@ H5Tvlen.lo: \ H5HGpublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ - H5MMprivate.h \ + H5FDpublic.h \ H5MMpublic.h \ + H5Iprivate.h \ + H5MMprivate.h \ H5Tpkg.h \ H5Rprivate.h \ H5Rpublic.h \ H5Tprivate.h \ H5Tpublic.h \ H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h + H5Gpublic.h H5TB.lo: \ H5TB.c \ H5private.h \ @@ -1264,193 +1443,24 @@ H5V.lo: \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h -H5Z.lo: \ - H5Z.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5Ipublic.h \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Dpublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.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 \ - H5Dpublic.h \ - H5Dprivate.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ - H5Zprivate.h \ - H5Zpublic.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5HLprivate.h \ - H5HLpublic.h \ - H5MFprivate.h \ - H5MFpublic.h \ - H5MMprivate.h \ + H5FDpublic.h \ H5MMpublic.h \ - H5Pprivate.h \ - H5Ppublic.h \ - H5TBprivate.h -H5T.lo: \ - H5T.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Dprivate.h \ - H5Dpublic.h \ - H5Ipublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ - H5Zprivate.h \ - H5Zpublic.h \ - H5Iprivate.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5MMprivate.h -H5TB.lo: \ - H5TB.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Iprivate.h \ - H5Ipublic.h \ - H5Eprivate.h -H5A.lo: \ - H5A.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Iprivate.h \ - H5Ipublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Dpublic.h \ - H5Dprivate.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 \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Pprivate.h \ - H5Ppublic.h \ - H5Apkg.h \ - H5Aprivate.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 \ H5Dpublic.h \ - H5Dprivate.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ - H5Zprivate.h \ - H5Zpublic.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5HLprivate.h \ - H5HLpublic.h \ - H5MFprivate.h \ - H5MFpublic.h \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Pprivate.h \ - H5Ppublic.h \ - H5TBprivate.h -H5Ofill.lo: \ - H5Ofill.c \ + H5Zprivate.h +H5Z.lo: \ + H5Z.c \ H5private.h \ H5public.h \ H5config.h \ @@ -1458,111 +1468,25 @@ H5Ofill.lo: \ H5Eprivate.h \ H5Epublic.h \ H5Ipublic.h \ - H5Iprivate.h \ H5MMprivate.h \ H5MMpublic.h \ H5Oprivate.h \ H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Dpublic.h \ + H5FDpublic.h \ H5Gprivate.h \ H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5HGprivate.h \ H5HGpublic.h \ - H5Tprivate.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 \ - H5Dpublic.h \ - H5Dprivate.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 \ - H5MMprivate.h -H5T.lo: \ - H5T.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Dprivate.h \ H5Dpublic.h \ - H5Ipublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h \ - H5Oprivate.h \ - H5Opublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ H5Zprivate.h \ - H5Zpublic.h \ - H5Iprivate.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5MMprivate.h -H5Tconv.lo: \ - H5Tconv.c \ - H5Iprivate.h \ - H5Ipublic.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5private.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5MMprivate.h \ - H5MMpublic.h \ - H5Tpkg.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Fprivate.h \ - H5Fpublic.h \ - H5Dpublic.h \ - H5Rprivate.h \ - H5Rpublic.h \ - H5Tprivate.h \ - H5Tpublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ - H5Bprivate.h \ - H5Bpublic.h -H5TB.lo: \ - H5TB.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5api_adpt.h \ - H5Iprivate.h \ - H5Ipublic.h \ - H5Eprivate.h + H5Zpublic.h @@ -21,6 +21,7 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5ACprivate.h> /*cache */ #include <H5Bprivate.h> /*B-link trees */ #include <H5Eprivate.h> /*error handling */ +#include <H5FDprivate.h> /*file driver */ #include <H5Iprivate.h> /*atoms */ #include <H5MMprivate.h> /*memory management */ #include <H5Pprivate.h> /*property lists */ @@ -29,6 +30,10 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5Tprivate.h> /*data types */ #include <H5Zprivate.h> /*filters */ +/* datatypes of predefined drivers needed by H5_trace() */ +#include <H5FDmpio.h> + + /* We need this on Irix64 even though we've included stdio.h as documented */ FILE *fdopen(int fd, const char *mode); @@ -152,6 +157,7 @@ H5_term_library(void) do { pending = 0; pending += DOWN(F); + pending += DOWN(FD); pending += DOWN(D); pending += DOWN(TB); pending += DOWN(Z); @@ -1124,6 +1130,9 @@ H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds) * Tuesday, June 16, 1998 * * Modifications: + * Robb Matzke, 1999-08-02 + * Added the `a' type letter for haddr_t arguments and `Mt' for + * H5FD_mem_t arguments. * *------------------------------------------------------------------------- */ @@ -1193,6 +1202,19 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) /* The value */ if (ptr) vp = va_arg (ap, void*); switch (type[0]) { + case 'a': + if (ptr) { + if (vp) { + fprintf(out, "0x%lx", (unsigned long)vp); + } else { + fprintf(out, "NULL"); + } + } else { + haddr_t addr = va_arg(ap, haddr_t); + HDfprintf(out, "%a", addr); + } + break; + case 'b': if (ptr) { if (vp) { @@ -1260,16 +1282,13 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) fprintf(out, "NULL"); } } else { - H5D_transfer_t transfer = va_arg (ap, H5D_transfer_t); + H5FD_mpio_xfer_t transfer = va_arg(ap, H5FD_mpio_xfer_t); switch (transfer) { - case H5D_XFER_INDEPENDENT: - fprintf (out, "H5D_XFER_INDEPENDENT"); - break; - case H5D_XFER_COLLECTIVE: - fprintf (out, "H5D_XFER_COLLECTIVE"); + case H5FD_MPIO_INDEPENDENT: + fprintf (out, "H5FD_MPIO_INDEPENDENT"); break; - case H5D_XFER_DFLT: - fprintf (out, "H5D_XFER_DFLT"); + case H5FD_MPIO_COLLECTIVE: + fprintf (out, "H5FD_MPIO_COLLECTIVE"); break; default: fprintf (out, "%ld", (long)transfer); @@ -1345,44 +1364,6 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) case 'F': switch (type[1]) { - case 'd': - if (ptr) { - if (vp) { - fprintf(out, "0x%lx", (unsigned long)vp); - } else { - fprintf(out, "NULL"); - } - } else { - H5F_driver_t driver = va_arg(ap, H5F_driver_t); - switch (driver) { - case H5F_LOW_ERROR: - fprintf(out, "H5F_LOW_ERROR"); - break; - case H5F_LOW_STDIO: - fprintf(out, "H5F_LOW_STDIO"); - break; - case H5F_LOW_SEC2: - fprintf(out, "H5F_LOW_SEC2"); - break; - case H5F_LOW_MPIO: - fprintf(out, "H5F_LOW_MPIO"); - break; - case H5F_LOW_CORE: - fprintf(out, "H5F_LOW_CORE"); - break; - case H5F_LOW_SPLIT: - fprintf(out, "H5F_LOW_SPLIT"); - break; - case H5F_LOW_FAMILY: - fprintf(out, "H5F_LOW_FAMILY"); - break; - default: - fprintf(out, "%ld", (long)driver); - break; - } - } - break; - case 's': if (ptr) { if (vp) { @@ -1783,8 +1764,8 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) case H5P_DATASET_CREATE: fprintf(out, "H5P_DATASET_CREATE"); break; - case H5P_DATASET_XFER: - fprintf(out, "H5P_DATASET_XFER"); + case H5P_DATA_XFER: + fprintf(out, "H5P_DATA_XFER"); break; case H5P_MOUNT: fprintf(out, "H5P_MOUNT"); @@ -1865,6 +1846,53 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) #endif } break; + case 't': + if (ptr) { + if (vp) { + fprintf(out, "0x%lx", (unsigned long)vp); + } else { + fprintf(out, "NULL"); + } + } else { + H5FD_mem_t mt = va_arg(ap, H5FD_mem_t); + switch (mt) { + case H5FD_MEM_NOLIST: + fprintf(out, "H5FD_MEM_NOLIST"); + break; + case H5FD_MEM_DEFAULT: + fprintf(out, "H5FD_MEM_DEFAULT"); + break; + case H5FD_MEM_SUPER: + fprintf(out, "H5FD_MEM_SUPER"); + break; + case H5FD_MEM_BTREE: + fprintf(out, "H5FD_MEM_BTREE"); + break; + 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; + case H5FD_MEM_LHEAP: + fprintf(out, "H5FD_MEM_LHEAP"); + break; + case H5FD_MEM_OHDR: + fprintf(out, "H5FD_MEM_OHDR"); + break; + default: + fprintf(out, "%lu", (unsigned long)mt); + break; + } + } + break; + default: goto error; } @@ -1905,8 +1933,8 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) case H5P_DATASET_CREATE: fprintf (out, "H5P_DATASET_CREATE"); break; - case H5P_DATASET_XFER: - fprintf (out, "H5P_DATASET_XFER"); + case H5P_DATA_XFER: + fprintf (out, "H5P_DATA_XFER"); break; default: fprintf (out, "%ld", (long)plist_class); @@ -114,7 +114,7 @@ H5AC_dest(H5F_t *f) assert(f->shared->cache); cache = f->shared->cache; - if (H5AC_flush(f, NULL, H5F_ADDR_UNDEF, TRUE) < 0) { + if (H5AC_flush(f, NULL, HADDR_UNDEF, TRUE) < 0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); } @@ -320,7 +320,7 @@ H5AC_compare(const void *_a, const void *_b) * * Purpose: Flushes (and destroys if DESTROY is non-zero) the specified * entry from the cache. If the entry TYPE is CACHE_FREE and - * ADDR is H5F_ADDR_UNDEF then all types of entries are + * ADDR is HADDR_UNDEF then all types of entries are * flushed. If TYPE is CACHE_FREE and ADDR is defined then * whatever is cached at ADDR is flushed. Otherwise the thing * at ADDR is flushed if it is the correct type. @@ -666,7 +666,7 @@ H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, cache->diagnostics[slot->type->id].nhits++; thing = slot->thing; slot->type = NULL; - slot->addr = H5F_ADDR_UNDEF; + slot->addr = HADDR_UNDEF; slot->thing = NULL; } else if (slot->type && H5F_addr_eq(slot->addr, addr)) { @@ -87,13 +87,16 @@ *------------------------------------------------------------------------- */ /* private headers */ -#include <H5private.h> /*library */ -#include <H5ACprivate.h> /*cache */ -#include <H5Bprivate.h> /*B-link trees */ -#include <H5Eprivate.h> /*error handling */ -#include <H5Fprivate.h> /*file access */ -#include <H5MFprivate.h> /*File memory management */ -#include <H5MMprivate.h> /*Core memory management */ +#include <H5private.h> /*library */ +#include <H5ACprivate.h> /*cache */ +#include <H5Bprivate.h> /*B-link trees */ +#include <H5Eprivate.h> /*error handling */ +#include <H5Fprivate.h> /*file access */ +#include <H5MFprivate.h> /*file memory management */ +#include <H5MMprivate.h> /*core memory management */ +#include <H5Pprivate.h> /*property lists */ + +#include <H5FDmpio.h> /*for H5FD_mpio_tas_allsame() */ #define PABLO_MASK H5B_mask @@ -187,8 +190,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, */ sizeof_rkey = (type->get_sizeof_rkey) (f, udata); size = H5B_nodesize(f, type, &total_native_keysize, sizeof_rkey); - if (H5MF_alloc(f, H5MF_META, (hsize_t)size, addr_p/*out*/) < 0) { - *addr_p = H5F_ADDR_UNDEF; + if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, size))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree root node"); } @@ -202,8 +204,8 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, bt->ndirty = 0; bt->type = type; bt->level = 0; - bt->left = H5F_ADDR_UNDEF; - bt->right = H5F_ADDR_UNDEF; + bt->left = HADDR_UNDEF; + bt->right = HADDR_UNDEF; bt->nchildren = 0; if (NULL==(bt->page=H5MM_calloc(size)) || NULL==(bt->native=H5MM_malloc(total_native_keysize)) || @@ -225,7 +227,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, bt->key[i].dirty = FALSE; bt->key[i].rkey = bt->page + offset; bt->key[i].nkey = NULL; - bt->child[i] = H5F_ADDR_UNDEF; + bt->child[i] = HADDR_UNDEF; } /* @@ -249,7 +251,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, done: if (ret_value<0) { - H5MF_xfree (f, *addr_p, (hsize_t)size); + H5MF_xfree(f, H5FD_MEM_BTREE, *addr_p, size); if (bt) { H5MM_xfree (bt->page); H5MM_xfree (bt->native); @@ -315,7 +317,7 @@ H5B_load(H5F_t *f, haddr_t addr, const void *_type, void *udata) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - if (H5F_block_read(f, addr, (hsize_t)size, &H5F_xfer_dflt, bt->page) < 0) { + if (H5F_block_read(f, addr, (hsize_t)size, H5P_DEFAULT, bt->page)<0) { HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node"); } @@ -353,7 +355,7 @@ H5B_load(H5F_t *f, haddr_t addr, const void *_type, void *udata) if (i < bt->nchildren) { H5F_addr_decode(f, (const uint8_t **) &p, bt->child + i); } else { - bt->child[i] = H5F_ADDR_UNDEF; + bt->child[i] = HADDR_UNDEF; p += H5F_SIZEOF_ADDR(f); } } @@ -461,10 +463,9 @@ H5B_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt) * for the final unchanged children. */ #ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame(f->shared->lf, TRUE); /* only p0 will write */ + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /* only p0 will write */ #endif /* HAVE_PARALLEL */ - if (H5F_block_write(f, addr, (hsize_t)size, &H5F_xfer_dflt, - bt->page) < 0) { + if (H5F_block_write(f, addr, (hsize_t)size, H5P_DEFAULT, bt->page)<0) { HRETURN_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree node to disk"); } @@ -924,7 +925,7 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - if (H5MF_alloc(f, H5MF_META, (hsize_t)size, &old_root/*out*/) < 0) { + if (HADDR_UNDEF==(old_root=H5MF_alloc(f, H5FD_MEM_BTREE, size))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file space to move root"); } @@ -932,11 +933,11 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr, HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to flush B-tree root node"); } - if (H5F_block_read(f, addr, (hsize_t)size, &H5F_xfer_dflt, buf) < 0) { + if (H5F_block_read(f, addr, (hsize_t)size, H5P_DEFAULT, buf)<0) { HGOTO_ERROR(H5E_BTREE, H5E_READERROR, FAIL, "unable to read B-tree root node"); } - if (H5F_block_write(f, old_root, (hsize_t)size, &H5F_xfer_dflt, buf)<0) { + if (H5F_block_write(f, old_root, (hsize_t)size, H5P_DEFAULT, buf)<0) { HGOTO_ERROR(H5E_BTREE, H5E_WRITEERROR, FAIL, "unable to move B-tree root node"); } @@ -960,8 +961,8 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr, } bt->dirty = TRUE; bt->ndirty = 0; - bt->left = H5F_ADDR_UNDEF; - bt->right = H5F_ADDR_UNDEF; + bt->left = HADDR_UNDEF; + bt->right = HADDR_UNDEF; bt->nchildren = 0; /* the new root */ @@ -1508,7 +1509,7 @@ H5B_iterate (H5F_t *f, const H5B_class_t *type, haddr_t addr, void *udata) { H5B_t *bt = NULL; haddr_t next_addr; - haddr_t cur_addr = H5F_ADDR_UNDEF; + haddr_t cur_addr = HADDR_UNDEF; haddr_t *child = NULL; uint8_t *key = NULL; intn i, nchildren; @@ -1774,13 +1775,13 @@ H5B_remove_helper(H5F_t *f, haddr_t addr, const H5B_class_t *type, sibling->left = bt->left; sibling->dirty = TRUE; } - bt->left = H5F_ADDR_UNDEF; - bt->right = H5F_ADDR_UNDEF; + bt->left = HADDR_UNDEF; + bt->right = HADDR_UNDEF; sizeof_rkey = (type->get_sizeof_rkey)(f, udata); sizeof_node = H5B_nodesize(f, type, NULL, sizeof_rkey); if (H5AC_unprotect(f, H5AC_BT, addr, bt)<0 || H5AC_flush(f, H5AC_BT, addr, TRUE)<0 || - H5MF_xfree(f, addr, sizeof_node)<0) { + H5MF_xfree(f, H5FD_MEM_BTREE, addr, sizeof_node)<0) { bt = NULL; HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5B_INS_ERROR, "unable to free B-tree node"); diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h index 8ba0321..cb60768 100644 --- a/src/H5Bprivate.h +++ b/src/H5Bprivate.h @@ -40,7 +40,7 @@ 2*H5F_SIZEOF_ADDR(F)) /*left and right sibling addresses */ #define H5B_K(F,TYPE) /*K value given file and Btree subclass */ \ - ((F)->shared->create_parms->btree_k[(TYPE)->id]) + ((F)->shared->fcpl->btree_k[(TYPE)->id]) typedef enum H5B_ins_t { H5B_INS_ERROR = -1, /*error return value */ @@ -23,7 +23,6 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5Eprivate.h> /* Error handling */ #include <H5Gprivate.h> /* Group headers */ #include <H5HLprivate.h> /* Name heap */ -#include <H5MFprivate.h> /* File space allocation header */ #include <H5MMprivate.h> /* Memory management */ #include <H5Oprivate.h> /* Object headers */ #include <H5Pprivate.h> /* Property lists */ @@ -32,6 +31,13 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5Vprivate.h> /* Vector and array functions */ #include <H5Zprivate.h> /* Data filters */ +/* + * The MPIO driver is needed because there are kludges in this file and + * places where we check for things that aren't handled by this driver. + */ +#include <H5FDmpio.h> + + #ifdef HAVE_PARALLEL /* Remove this if H5R_DATASET_REGION is no longer used in this file */ #include <H5Rpublic.h> @@ -62,7 +68,7 @@ const H5D_create_t H5D_create_dflt = { {NULL, 0, NULL}, /* No fill value */ /* External file list */ - {H5F_ADDR_UNDEF, /* External file list heap address */ + {HADDR_UNDEF, /* External file list heap address */ 0, /*...slots allocated */ 0, /*...slots used */ NULL}, /*...slot array */ @@ -628,7 +634,7 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, "selection+offset not within extent"); } } - if (H5P_DEFAULT != plist_id && H5P_DATASET_XFER != H5P_get_class(plist_id)) { + if (H5P_DEFAULT != plist_id && H5P_DATA_XFER != H5P_get_class(plist_id)) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); } if (!buf) { @@ -723,7 +729,7 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, "selection+offset not within extent"); } } - if (H5P_DEFAULT != plist_id && H5P_DATASET_XFER != H5P_get_class(plist_id)) { + if (H5P_DEFAULT != plist_id && H5P_DATA_XFER != H5P_get_class(plist_id)) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); } if (!buf) { @@ -819,7 +825,7 @@ H5D_new(const H5D_create_t *create_parms) ret_value->create_parms = H5P_copy (H5P_DATASET_CREATE, &H5D_create_dflt); } - ret_value->ent.header = H5F_ADDR_UNDEF; + ret_value->ent.header = HADDR_UNDEF; /* Success */ @@ -894,7 +900,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, #ifdef HAVE_PARALLEL /* If MPIO is used, no filter support yet. */ - if (f->shared->access_parms->driver == H5F_LOW_MPIO && + if (H5FD_MPIO==f->shared->fapl->driver_id && create_parms->pline.nfilters>0) { HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL, "Parallel IO does not support filters yet"); @@ -1039,7 +1045,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, "unable to initialize storage"); } } else { - new_dset->layout.addr = H5F_ADDR_UNDEF; + new_dset->layout.addr = HADDR_UNDEF; } /* Update layout message */ @@ -1271,8 +1277,8 @@ H5D_open_oid(H5G_entry_t *ent) #ifdef HAVE_PARALLEL /* If MPIO is used, no filter support yet. */ - if (dataset->ent.file->shared->access_parms->driver == H5F_LOW_MPIO && - dataset->create_parms->pline.nfilters>0){ + if (H5FD_MPIO==dataset->ent.file->shared->fapl->driver_id && + dataset->create_parms->pline.nfilters>0){ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL, "Parallel IO does not support filters yet"); } @@ -1425,25 +1431,23 @@ H5D_close(H5D_t *dataset) * Thursday, December 4, 1997 * * Modifications: - * Robb Matzke, 9 Jun 1998 - * The data space is no longer cached in the dataset struct. + * Robb Matzke, 1998-06-09 + * The data space is no longer cached in the dataset struct. * - * Robb Matzke, 11 Aug 1998 - * Added timing calls around all the data space I/O functions. + * Robb Matzke, 1998-08-11 + * Added timing calls around all the data space I/O functions. * - * rky 980918 - * Added must_convert to do non-optimized read when necessary. - * - * Quincey Koziol, 2 July 1999 - * Changed xfer_parms parameter to xfer plist parameter, so it could be passed - * to H5T_convert + * rky, 1998-09-18 + * Added must_convert to do non-optimized read when necessary. * + * Quincey Koziol, 1999-07-02 + * Changed xfer_parms parameter to xfer plist parameter, so it + * could be passed to H5T_convert. *------------------------------------------------------------------------- */ herr_t H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, hid_t dset_xfer_plid, - void *buf/*out*/) + const H5S_t *file_space, hid_t dxpl_id, void *buf/*out*/) { const H5F_xfer_t *xfer_parms = NULL; hssize_t nelmts; /*number of elements */ @@ -1486,10 +1490,10 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, HDmemset(&file_iter,0,sizeof(H5S_sel_iter_t)); /* Get the dataset transfer property list */ - if (H5P_DEFAULT == dset_xfer_plid) { + if (H5P_DEFAULT == dxpl_id) { xfer_parms = &H5F_xfer_dflt; - } else if (H5P_DATASET_XFER != H5P_get_class(dset_xfer_plid) || - NULL == (xfer_parms = H5I_object(dset_xfer_plid))) { + } else if (H5P_DATA_XFER != H5P_get_class(dxpl_id) || + NULL == (xfer_parms = H5I_object(dxpl_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); } @@ -1504,19 +1508,15 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, nelmts = H5S_get_select_npoints(mem_space); #ifdef HAVE_PARALLEL - /* - * Check if collective data transfer requested. - */ - if (xfer_parms->xfer_mode == H5D_XFER_COLLECTIVE){ - /* - * Verify that the file can support collective access. The check may - * not be necessarily since collective access can always be simulated - * by independent access. Nevertheless, must check driver is MPIO - * before using those access_mode which exists only for MPIO case. - */ - if (dataset->ent.file->shared->access_parms->driver != H5F_LOW_MPIO) + { + /* Collective access is not permissible with the MPIO driver */ + H5FD_mpio_dxpl_t *dx; + if (H5FD_MPIO==dataset->ent.file->shared->fapl->driver_id && + (dx=dataset->ent.file->shared->fapl->driver_info) && + H5FD_MPIO_COLLECTIVE==dx->xfer_mode) { HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access not permissible"); + } } #endif @@ -1556,7 +1556,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * (the latter in case the arguments to sconv_funcs * turn out to be inappropriate for MPI-IO). */ if (H5_mpi_opt_types_g && - H5F_LOW_MPIO==dataset->ent.file->shared->access_parms->driver) { + H5FD_MPIO==dataset->ent.file->shared->fapl->driver_id) { sconv->read = H5S_mpio_spaces_read; } #endif /*HAVE_PARALLEL*/ @@ -1573,7 +1573,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &(dataset->create_parms->pline), &(dataset->create_parms->efl), H5T_get_size (dataset->type), file_space, - mem_space, xfer_parms, buf/*out*/, + mem_space, dxpl_id, buf/*out*/, &must_convert); if (status<0) { /* Supports only no conversion, type or space, for now. */ @@ -1697,7 +1697,7 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d, min_e &(dataset->create_parms->fill), &(dataset->create_parms->efl), src_type_size, file_space, &file_iter, smine_nelmts, - xfer_parms, tconv_buf/*out*/); + dxpl_id, tconv_buf/*out*/); #ifdef H5S_DEBUG H5_timer_end(&(sconv->stats[1].gath_timer), &timer); sconv->stats[1].gath_nbytes += n * src_type_size; @@ -1751,7 +1751,7 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d, min_e * Perform data type conversion. */ if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, tconv_buf, - bkg_buf, dset_xfer_plid)<0) { + bkg_buf, dxpl_id)<0) { HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed"); } @@ -1826,8 +1826,7 @@ printf("%s: check 2.0, src_type_size=%d, dst_type_size=%d, target_size=%d, min_e */ herr_t H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, - const H5S_t *file_space, hid_t dset_xfer_plid, - const void *buf) + const H5S_t *file_space, hid_t dxpl_id, const void *buf) { const H5F_xfer_t *xfer_parms = NULL; hssize_t nelmts; /*total number of elmts */ @@ -1868,8 +1867,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, /* If MPIO is used, no VL datatype support yet. */ /* This is because they use the global heap in the file and we don't */ /* support parallel access of that yet */ - if (H5F_LOW_MPIO==dataset->ent.file->shared->access_parms->driver && - H5T_get_class(mem_type)==H5T_VLEN) { + if (H5FD_MPIO==dataset->ent.file->shared->fapl->driver_id && + H5T_get_class(mem_type)==H5T_VLEN) { HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing VL datatypes yet"); } @@ -1878,9 +1877,9 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, /* If MPIO is used, no dataset region reference support yet. */ /* This is because they use the global heap in the file and we don't */ /* support parallel access of that yet */ - if (H5F_LOW_MPIO==dataset->ent.file->shared->access_parms->driver && - H5T_get_class(mem_type)==H5T_REFERENCE && - H5T_get_ref_type(mem_type)==H5R_DATASET_REGION) { + if (H5FD_MPIO==dataset->ent.file->shared->fapl->driver_id && + H5T_get_class(mem_type)==H5T_REFERENCE && + H5T_get_ref_type(mem_type)==H5R_DATASET_REGION) { HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing VL datatypes yet"); } @@ -1892,10 +1891,10 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, HDmemset(&file_iter,0,sizeof(H5S_sel_iter_t)); /* Get the dataset transfer property list */ - if (H5P_DEFAULT == dset_xfer_plid) { + if (H5P_DEFAULT == dxpl_id) { xfer_parms = &H5F_xfer_dflt; - } else if (H5P_DATASET_XFER != H5P_get_class(dset_xfer_plid) || - NULL == (xfer_parms = H5I_object(dset_xfer_plid))) { + } else if (H5P_DATA_XFER != H5P_get_class(dxpl_id) || + NULL == (xfer_parms = H5I_object(dxpl_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); } @@ -1915,19 +1914,15 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, nelmts = H5S_get_select_npoints(mem_space); #ifdef HAVE_PARALLEL - /* - * Check if collective data transfer requested. - */ - if (xfer_parms->xfer_mode == H5D_XFER_COLLECTIVE){ - /* - * Verify that the file can support collective access. The check may - * not be necessarily since collective access can always be simulated - * by independent access. Nevertheless, must check driver is MPIO - * before using those access_mode which exists only for MPIO case. - */ - if (dataset->ent.file->shared->access_parms->driver != H5F_LOW_MPIO) + { + /* Collective access is not permissible with the MPIO driver */ + H5FD_mpio_dxpl_t *dx; + if (H5FD_MPIO==dataset->ent.file->shared->fapl->driver_id && + (dx=dataset->ent.file->shared->fapl->driver_info) && + H5FD_MPIO_COLLECTIVE==dx->xfer_mode) { HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access not permissible"); + } } #endif @@ -1974,7 +1969,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * (the latter in case the arguments to sconv_funcs * turn out to be inappropriate for MPI-IO). */ if (H5_mpi_opt_types_g && - H5F_LOW_MPIO==dataset->ent.file->shared->access_parms->driver) { + H5FD_MPIO==dataset->ent.file->shared->fapl->driver_id) { sconv->write = H5S_mpio_spaces_write; } #endif /*HAVE_PARALLEL*/ @@ -1991,8 +1986,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &(dataset->create_parms->pline), &(dataset->create_parms->efl), H5T_get_size (dataset->type), file_space, - mem_space, xfer_parms, buf, - &must_convert/*out*/); + mem_space, dxpl_id, buf, &must_convert/*out*/); if (status<0) { /* Supports only no conversion, type or space, for now. */ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, @@ -2145,7 +2139,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &(dataset->create_parms->fill), &(dataset->create_parms->efl), dst_type_size, file_space, &bkg_iter, smine_nelmts, - xfer_parms, bkg_buf/*out*/); + dxpl_id, bkg_buf/*out*/); #ifdef H5S_DEBUG H5_timer_end(&(sconv->stats[0].bkg_timer), &timer); sconv->stats[0].bkg_nbytes += n * dst_type_size; @@ -2163,7 +2157,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * Perform data type conversion. */ if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, tconv_buf, - bkg_buf, dset_xfer_plid)<0) { + bkg_buf, dxpl_id)<0) { HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed"); } @@ -2182,7 +2176,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &(dataset->create_parms->fill), &(dataset->create_parms->efl), dst_type_size, file_space, &file_iter, smine_nelmts, - xfer_parms, tconv_buf); + dxpl_id, tconv_buf); #ifdef QAK printf("%s: check 6.35\n",FUNC); #endif @@ -2405,14 +2399,14 @@ H5D_get_file (const H5D_t *dset) static herr_t H5D_init_storage(H5D_t *dset, const H5S_t *space) { - intn ndims; - hsize_t dim[H5O_LAYOUT_NDIMS]; hssize_t npoints, ptsperbuf; size_t size, bufsize=8*1024; hid_t buf_id = -1; haddr_t addr; herr_t ret_value = FAIL; void *buf = NULL; + intn ndims; + hsize_t dim[H5O_LAYOUT_NDIMS]; FUNC_ENTER(H5D_init_storage, FAIL); assert(dset); @@ -2459,7 +2453,7 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space) } } else { if (H5F_block_write(dset->ent.file, addr, size, - &H5F_xfer_dflt, buf)<0) { + H5P_DEFAULT, buf)<0) { HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset"); } @@ -2481,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 (H5F_LOW_MPIO==dset->ent.file->shared->access_parms->driver) { + if (H5FD_MPIO==dset->ent.file->shared->fapl->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, @@ -2490,8 +2484,8 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space) dim[ndims] = dset->layout.dim[ndims]; ndims++; - if (H5F_istore_allocate(dset->ent.file, &(dset->layout), - dim, H5F_xfer_dflt.split_ratios, + if (H5F_istore_allocate(dset->ent.file, H5P_DEFAULT, + &(dset->layout), dim, &(dset->create_parms->pline), &(dset->create_parms->fill))<0) { HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, @@ -2713,14 +2707,14 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf) /* Retrieve dataset transfer property list */ if (H5P_DEFAULT == plist_id) { xfer_parms = &H5F_xfer_dflt; - } else if (H5P_DATASET_XFER != H5P_get_class(plist_id) || + } else if (H5P_DATA_XFER != H5P_get_class(plist_id) || NULL == (xfer_parms = H5I_object(plist_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); } /* Call H5Diterate with args, etc. */ ret_value=H5Diterate(buf,type_id,space_id,H5T_vlen_reclaim, - (void*)xfer_parms); + (void*/*FIXME*/)xfer_parms); FUNC_LEAVE(ret_value); } /* end H5Dvlen_reclaim() */ diff --git a/src/H5Distore.c b/src/H5Distore.c index 6052b31..4849e98 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -33,11 +33,16 @@ #include <H5Dprivate.h> #include <H5Eprivate.h> #include <H5Fprivate.h> +#include <H5Iprivate.h> #include <H5MFprivate.h> #include <H5MMprivate.h> #include <H5Oprivate.h> +#include <H5Pprivate.h> #include <H5Vprivate.h> +/* MPIO driver needed for special checks */ +#include <H5FDmpio.h> + /* * Feature: If this constant is defined then every cache preemption and load * causes a character to be printed on the standard error stream: @@ -487,7 +492,8 @@ H5F_istore_new_node(H5F_t *f, H5B_ins_t op, #ifdef AKC printf("calling H5MF_alloc for new chunk\n"); #endif - if (H5MF_alloc(f, H5MF_RAW, udata->key.nbytes, addr_p/*out*/) < 0) { + if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, + udata->key.nbytes))) { HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "couldn't allocate new file storage"); } @@ -669,8 +675,9 @@ H5F_istore_insert(H5F_t *f, haddr_t addr, void *_lt_key, #ifdef AKC printf("calling H5MF_realloc for new chunk\n"); #endif - if (H5MF_realloc (f, H5MF_RAW, lt_key->nbytes, addr, - udata->key.nbytes, new_node_p/*out*/)<0) { + if (HADDR_UNDEF==(*new_node_p=H5MF_realloc(f, H5FD_MEM_BTREE, addr, + lt_key->nbytes, + udata->key.nbytes))) { HRETURN_ERROR (H5E_STORAGE, H5E_WRITEERROR, H5B_INS_ERROR, "unable to reallocate chunk storage"); } @@ -707,7 +714,8 @@ H5F_istore_insert(H5F_t *f, haddr_t addr, void *_lt_key, #ifdef AKC printf("calling H5MF_alloc for new chunk\n"); #endif - if (H5MF_alloc(f, H5MF_RAW, udata->key.nbytes, new_node_p/*out*/)<0) { + if (HADDR_UNDEF==(*new_node_p=H5MF_alloc(f, H5FD_MEM_BTREE, + udata->key.nbytes))) { HRETURN_ERROR(H5E_IO, H5E_CANTINIT, H5B_INS_ERROR, "file allocation failed"); } @@ -798,9 +806,9 @@ H5F_istore_init (H5F_t *f) FUNC_ENTER (H5F_istore_init, FAIL); HDmemset (rdcc, 0, sizeof(H5F_rdcc_t)); - if (f->shared->access_parms->rdcc_nbytes>0 && - f->shared->access_parms->rdcc_nelmts>0) { - rdcc->nslots = f->shared->access_parms->rdcc_nelmts; + if (f->shared->fapl->rdcc_nbytes>0 && + f->shared->fapl->rdcc_nelmts>0) { + rdcc->nslots = f->shared->fapl->rdcc_nelmts; rdcc->slot = H5MM_calloc (rdcc->nslots*sizeof(H5F_rdcc_ent_t*)); if (NULL==rdcc->slot) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, @@ -830,7 +838,7 @@ H5F_istore_init (H5F_t *f) *------------------------------------------------------------------------- */ static herr_t -H5F_istore_flush_entry (H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) +H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) { herr_t ret_value=FAIL; /*return value */ H5F_istore_ud1_t udata; /*pass through B-tree */ @@ -839,16 +847,16 @@ H5F_istore_flush_entry (H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) size_t alloc; /*bytes allocated for BUF */ hbool_t point_of_no_return = FALSE; - FUNC_ENTER (H5F_istore_flush_entry, FAIL); + FUNC_ENTER(H5F_istore_flush_entry, FAIL); assert(f); assert(ent); - assert (!ent->locked); + assert(!ent->locked); buf = ent->chunk; if (ent->dirty) { udata.mesg = *(ent->layout); udata.key.filter_mask = 0; - udata.addr = H5F_ADDR_UNDEF; + udata.addr = HADDR_UNDEF; udata.key.nbytes = ent->chunk_size; for (i=0; i<ent->layout->ndims; i++) { udata.key.offset[i] = ent->offset[i]; @@ -893,13 +901,13 @@ H5F_istore_flush_entry (H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) */ if (H5B_insert(f, H5B_ISTORE, ent->layout->addr, ent->split_ratios, &udata)<0) { - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, - "unable to allocate chunk"); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "unable to allocate chunk"); } - if (H5F_block_write (f, udata.addr, udata.key.nbytes, - &H5F_xfer_dflt, buf)<0) { - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, - "unable to write raw data to file"); + if (H5F_block_write(f, udata.addr, udata.key.nbytes, H5P_DEFAULT, + buf)<0) { + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "unable to write raw data to file"); } /* Mark cache entry as clean */ @@ -933,7 +941,7 @@ H5F_istore_flush_entry (H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) ent->pline = H5O_free(H5O_PLINE, ent->pline); ent->chunk = H5MM_xfree(ent->chunk); } - FUNC_LEAVE (ret_value); + FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- @@ -1103,7 +1111,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->access_parms->rdcc_nbytes; + size_t total = f->shared->fapl->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 */ @@ -1121,7 +1129,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->access_parms->rdcc_w0; + w[0] = rdcc->nused * f->shared->fapl->rdcc_w0; p[0] = rdcc->head; p[1] = NULL; @@ -1214,14 +1222,16 @@ H5F_istore_prune (H5F_t *f, size_t size) * Thursday, May 21, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * The split ratios are passed in as part of the data transfer + * property list. *------------------------------------------------------------------------- */ static void * -H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, - const double split_ratios[], const H5O_pline_t *pline, - const H5O_fill_t *fill, const hssize_t offset[], - hbool_t relax, intn *idx_hint/*in,out*/) +H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, + const H5O_pline_t *pline, const H5O_fill_t *fill, + const hssize_t offset[], hbool_t relax, + intn *idx_hint/*in,out*/) { uintn idx=0; /*hash index number */ hbool_t found = FALSE; /*already in cache? */ @@ -1236,7 +1246,6 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, void *ret_value=NULL; /*return value */ FUNC_ENTER (H5F_istore_lock, NULL); - assert(split_ratios); if (rdcc->nslots>0) { /* We don't care about loss of precision in the following statement. */ @@ -1299,7 +1308,7 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, } chunk_alloc = chunk_size; udata.mesg = *layout; - udata.addr = H5F_ADDR_UNDEF; + udata.addr = HADDR_UNDEF; status = H5B_find (f, H5B_ISTORE, layout->addr, &udata); H5E_clear (); if (NULL==(chunk = H5MM_malloc (chunk_alloc))) { @@ -1310,8 +1319,8 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, /* * The chunk exists on disk. */ - if (H5F_block_read(f, udata.addr, udata.key.nbytes, - &H5F_xfer_dflt, chunk)<0) { + if (H5F_block_read(f, udata.addr, udata.key.nbytes, H5P_DEFAULT, + chunk)<0) { HGOTO_ERROR (H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk"); } @@ -1345,7 +1354,7 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, assert (found || chunk_size>0); if (!found && rdcc->nslots>0 && - chunk_size<=f->shared->access_parms->rdcc_nbytes && + chunk_size<=f->shared->fapl->rdcc_nbytes && (!ent || !ent->locked)) { /* * Add the chunk to the cache only if the slot is not already locked. @@ -1392,10 +1401,15 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, ent->rd_count = chunk_size; ent->wr_count = chunk_size; ent->chunk = chunk; - ent->split_ratios[0] = split_ratios[0]; - ent->split_ratios[1] = split_ratios[1]; - ent->split_ratios[2] = split_ratios[2]; - + + { + H5F_xfer_t *dxpl; + dxpl = (H5P_DEFAULT==dxpl_id)?&H5F_xfer_dflt:H5I_object(dxpl_id); + ent->split_ratios[0] = dxpl->split_ratios[0]; + ent->split_ratios[1] = dxpl->split_ratios[1]; + ent->split_ratios[2] = dxpl->split_ratios[2]; + } + /* Add it to the cache */ assert(NULL==rdcc->slot[idx]); rdcc->slot[idx] = ent; @@ -1485,15 +1499,16 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, * Thursday, May 21, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * The split_ratios are passed as part of the data transfer + * property list. *------------------------------------------------------------------------- */ static herr_t -H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout, - const double split_ratios[], - const H5O_pline_t *pline, hbool_t dirty, - const hssize_t offset[], intn *idx_hint, - uint8_t *chunk, size_t naccessed) +H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, + const H5O_pline_t *pline, hbool_t dirty, + const hssize_t offset[], intn *idx_hint, + uint8_t *chunk, size_t naccessed) { H5F_rdcc_t *rdcc = &(f->shared->rdcc); H5F_rdcc_ent_t *ent = NULL; @@ -1529,9 +1544,14 @@ H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout, } x.alloc_size = x.chunk_size; x.chunk = chunk; - x.split_ratios[0] = split_ratios[0]; - x.split_ratios[1] = split_ratios[1]; - x.split_ratios[2] = split_ratios[2]; + { + H5F_xfer_t *dxpl; + dxpl = (H5P_DEFAULT==dxpl_id)?&H5F_xfer_dflt:H5I_object(dxpl_id); + x.split_ratios[0] = dxpl->split_ratios[0]; + x.split_ratios[1] = dxpl->split_ratios[1]; + x.split_ratios[2] = dxpl->split_ratios[2]; + } + H5F_istore_flush_entry (f, &x, TRUE); } else { H5MM_xfree (chunk); @@ -1567,11 +1587,13 @@ H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout, * Wednesday, October 15, 1997 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * The data transfer property list is passed as an object ID + * since that's how the virtual file layer wants it. *------------------------------------------------------------------------- */ herr_t -H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, +H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, const hssize_t offset_f[], const hsize_t size[], void *buf) { @@ -1592,13 +1614,13 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, FUNC_ENTER(H5F_istore_read, FAIL); /* Check args */ - assert (f); - assert (layout && H5D_CHUNKED==layout->type); - assert (layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS); - assert (H5F_addr_defined(layout->addr)); - assert (offset_f); - assert (size); - assert (buf); + assert(f); + assert(layout && H5D_CHUNKED==layout->type); + assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS); + assert(H5F_addr_defined(layout->addr)); + assert(offset_f); + assert(size); + assert(buf); /* * For now, a hyperslab of the file must be read into an array in @@ -1611,9 +1633,9 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, #ifndef NDEBUG for (i=0; i<layout->ndims; i++) { - assert (offset_f[i]>=0); /*negative offsets not supported*/ - assert (offset_m[i]>=0); /*negative offsets not supported*/ - assert (size[i]<SIZET_MAX); + assert(offset_f[i]>=0); /*negative offsets not supported*/ + assert(offset_m[i]>=0); /*negative offsets not supported*/ + assert(size[i]<SIZET_MAX); assert(offset_m[i]+(hssize_t)size[i]<=(hssize_t)size_m[i]); assert(layout->dim[i]>0); } @@ -1634,7 +1656,7 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, while (1) { for (i=0, naccessed=1; i<layout->ndims; i++) { /* The location and size of the chunk being accessed */ - assert (layout->dim[i] < HSSIZET_MAX); + assert(layout->dim[i] < HSSIZET_MAX); chunk_offset[i] = idx_cur[i] * (hssize_t)(layout->dim[i]); /* The offset and size wrt the chunk */ @@ -1651,32 +1673,29 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, } #ifdef HAVE_PARALLEL /* - * If MPIO is used, must bypass the chunk-cache scheme - * because other MPI processes could be writing to other - * elements in the same chunk. + * If MPIO is used, must bypass the chunk-cache scheme because other + * MPI processes could be writing to other elements in the same chunk. * Do a direct write-through of only the elements requested. */ - if (f->shared->access_parms->driver==H5F_LOW_MPIO){ + if (H5FD_MPIO==f->shared->fapl->driver_id) { H5F_istore_ud1_t udata; H5O_layout_t l; /* temporary layout */ - H5F_xfer_t tmp_xfer = *xfer; + if (H5F_istore_get_addr(f, layout, chunk_offset, &udata)<0){ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk"); }; + /* * use default transfer mode as we do not support collective * transfer mode since each data write could decompose into - * multiple chunk writes and we are not doing the calculation - * yet. + * multiple chunk writes and we are not doing the calculation yet. */ l.type = H5D_CONTIGUOUS; l.ndims = layout->ndims; - for (i=l.ndims; i-- > 0;) - l.dim[i] = layout->dim[i]; + for (i=l.ndims; i-- > 0; /*void*/) l.dim[i] = layout->dim[i]; l.addr = udata.addr; - tmp_xfer.xfer_mode = H5D_XFER_DFLT; - if (H5F_arr_read(f, &tmp_xfer, &l, pline, fill, NULL/*no efl*/, + if (H5F_arr_read(f, H5P_DEFAULT, &l, pline, fill, NULL/*no efl*/, sub_size, size_m, sub_offset_m, offset_wrt_chunk, buf)<0){ HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, @@ -1696,19 +1715,19 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, * Lock the chunk, transfer data to the application, then unlock * the chunk. */ - if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios, - pline, fill, chunk_offset, - FALSE, &idx_hint))) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "unable to read raw data chunk"); + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, pline, fill, + chunk_offset, FALSE, + &idx_hint))) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "unable to read raw data chunk"); } H5V_hyper_copy(layout->ndims, sub_size, size_m, sub_offset_m, (void*)buf, layout->dim, offset_wrt_chunk, chunk); - if (H5F_istore_unlock (f, layout, xfer->split_ratios, pline, - FALSE, chunk_offset, &idx_hint, chunk, - naccessed)<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "unable to unlock raw data chunk"); + if (H5F_istore_unlock(f, dxpl_id, layout, pline, FALSE, + chunk_offset, &idx_hint, chunk, + naccessed)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "unable to unlock raw data chunk"); } #ifdef HAVE_PARALLEL } @@ -1737,11 +1756,13 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, * Wednesday, October 15, 1997 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * The data transfer property list is passed as an object ID + * since that's how the virtual file layer wants it. *------------------------------------------------------------------------- */ herr_t -H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, +H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, const hssize_t offset_f[], const hsize_t size[], const void *buf) @@ -1783,8 +1804,8 @@ H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, #ifndef NDEBUG for (i=0; i<layout->ndims; i++) { - assert (offset_f[i]>=0); /*negative offsets not supported*/ - assert (offset_m[i]>=0); /*negative offsets not supported*/ + assert(offset_f[i]>=0); /*negative offsets not supported*/ + assert(offset_m[i]>=0); /*negative offsets not supported*/ assert(size[i]<SIZET_MAX); assert(offset_m[i]+(hssize_t)size[i]<=(hssize_t)size_m[i]); assert(layout->dim[i]>0); @@ -1808,7 +1829,7 @@ H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, for (i=0, naccessed=1; i<layout->ndims; i++) { /* The location and size of the chunk being accessed */ - assert (layout->dim[i] < HSSIZET_MAX); + assert(layout->dim[i] < HSSIZET_MAX); chunk_offset[i] = idx_cur[i] * (hssize_t)(layout->dim[i]); /* The offset and size wrt the chunk */ @@ -1826,32 +1847,28 @@ H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, #ifdef HAVE_PARALLEL /* - * If MPIO is used, must bypass the chunk-cache scheme - * because other MPI processes could be writing to other - * elements in the same chunk. + * If MPIO is used, must bypass the chunk-cache scheme because other + * MPI processes could be writing to other elements in the same chunk. * Do a direct write-through of only the elements requested. */ - if (f->shared->access_parms->driver==H5F_LOW_MPIO){ + if (H5FD_MPIO==f->shared->fapl->driver_id) { H5F_istore_ud1_t udata; H5O_layout_t l; /* temporary layout */ - H5F_xfer_t tmp_xfer = *xfer; if (H5F_istore_get_addr(f, layout, chunk_offset, &udata)<0){ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk"); }; + /* * use default transfer mode as we do not support collective * transfer mode since each data write could decompose into - * multiple chunk writes and we are not doing the calculation - * yet. + * multiple chunk writes and we are not doing the calculation yet. */ l.type = H5D_CONTIGUOUS; l.ndims = layout->ndims; - for (i=l.ndims; i-- > 0;) - l.dim[i] = layout->dim[i]; + for (i=l.ndims; i-- > 0; /*void*/) l.dim[i] = layout->dim[i]; l.addr = udata.addr; - tmp_xfer.xfer_mode = H5D_XFER_DFLT; - if (H5F_arr_write(f, &tmp_xfer, &l, pline, fill, NULL/*no efl*/, + if (H5F_arr_write(f, H5P_DEFAULT, &l, pline, fill, NULL/*no efl*/, sub_size, size_m, sub_offset_m, offset_wrt_chunk, buf)<0){ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, @@ -1871,19 +1888,19 @@ H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, * Lock the chunk, copy from application to chunk, then unlock the * chunk. */ - if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios, - pline, fill, chunk_offset, - naccessed==chunk_size, - &idx_hint))) { + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, pline, fill, + chunk_offset, + naccessed==chunk_size, + &idx_hint))) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk"); } H5V_hyper_copy(layout->ndims, sub_size, layout->dim, offset_wrt_chunk, chunk, size_m, sub_offset_m, buf); - if (H5F_istore_unlock (f, layout, xfer->split_ratios, pline, TRUE, - chunk_offset, &idx_hint, chunk, - naccessed)<0) { + if (H5F_istore_unlock(f, dxpl_id, layout, pline, TRUE, + chunk_offset, &idx_hint, chunk, + naccessed)<0) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk"); } @@ -2151,7 +2168,7 @@ H5F_istore_get_addr(H5F_t *f, const H5O_layout_t *layout, udata->key.offset[i] = offset[i]; } udata->mesg = *layout; - udata->addr = H5F_ADDR_UNDEF; + udata->addr = HADDR_UNDEF; status = H5B_find (f, H5B_ISTORE, layout->addr, udata); H5E_clear (); if (status>=0 && H5F_addr_defined(udata->addr)) @@ -2180,20 +2197,23 @@ H5F_istore_get_addr(H5F_t *f, const H5O_layout_t *layout, * June 26, 1998 * * Modifications: + * rky, 1998-09-23 + * Added barrier to preclude racing with data writes. * - * rky 980923 - * Added barrier to preclude racing with data writes. - * - * rky 19981207 - * Added Wait-Signal wrapper around unlock-lock critical region - * to prevent race condition (unlock reads, lock writes the chunk). + * rky, 1998-12-07 + * Added Wait-Signal wrapper around unlock-lock critical region + * to prevent race condition (unlock reads, lock writes the + * chunk). * + * Robb Matzke, 1999-08-02 + * The split_ratios are passed in as part of the data transfer + * property list. *------------------------------------------------------------------------- */ herr_t -H5F_istore_allocate (H5F_t *f, const H5O_layout_t *layout, - const hsize_t *space_dim, const double split_ratios[], - const H5O_pline_t *pline, const H5O_fill_t *fill) +H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, + const hsize_t *space_dim, const H5O_pline_t *pline, + const H5O_fill_t *fill) { intn i, carry; @@ -2256,28 +2276,26 @@ H5F_istore_allocate (H5F_t *f, const H5O_layout_t *layout, #ifdef HAVE_PARALLEL /* rky 981207 Serialize access to this critical region. */ if (SUCCEED!= - H5PC_Wait_for_left_neighbor(f->shared->access_parms->u.mpio.comm)) - { + H5FD_mpio_wait_for_left_neighbor(f->shared->lf)) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to lock the data chunk"); } #endif - if (NULL==(chunk=H5F_istore_lock (f, layout, split_ratios, pline, + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, pline, fill, chunk_offset, FALSE, &idx_hint))) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk"); } - if (H5F_istore_unlock (f, layout, split_ratios, pline, TRUE, - chunk_offset, &idx_hint, chunk, - chunk_size)<0) { + if (H5F_istore_unlock(f, dxpl_id, layout, pline, TRUE, + chunk_offset, &idx_hint, chunk, + chunk_size)<0) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk"); } #ifdef HAVE_PARALLEL if (SUCCEED!= - H5PC_Signal_right_neighbor(f->shared->access_parms->u.mpio.comm)) - { + H5FD_mpio_signal_right_neighbor(f->shared->lf)) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to unlock the data chunk"); } @@ -2314,7 +2332,7 @@ H5F_istore_allocate (H5F_t *f, const H5O_layout_t *layout, * removed, when H5D_init_storage is changed to call H5MF_alloc directly * to allocate space, instead of calling H5F_istore_unlock. */ - if (MPI_Barrier( f->shared->access_parms->u.mpio.comm )) { + if (MPI_Barrier(H5FD_mpio_communicator(f->shared->lf))) { HRETURN_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Barrier failed"); } #endif diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 6fc03e2..ab289e6 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -51,6 +51,7 @@ typedef struct H5D_create_t { } H5D_create_t; typedef struct H5D_t H5D_t; + __DLLVAR__ const H5D_create_t H5D_create_dflt; /* Functions defined in H5D.c */ diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index adf617c..a0eddd1 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -31,17 +31,9 @@ typedef enum H5D_layout_t { H5D_NLAYOUTS = 3 /*this one must be last! */ } H5D_layout_t; -/* Values for the data transfer property */ -typedef enum H5D_transfer_t { - H5D_XFER_INDEPENDENT, /*Independent data transfer */ - H5D_XFER_COLLECTIVE, /*Collective data transfer */ - H5D_XFER_DFLT /*default data transfer mode */ -} H5D_transfer_t; - - /* Define the operator function pointer for H5Diterate() */ typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, hsize_t ndim, - hssize_t *point, void *operator_data); + hssize_t *point, void *operator_data); #ifdef __cplusplus extern "C" { @@ -59,6 +59,7 @@ static const H5E_major_mesg_t H5E_major_mesg_g[] = { {H5E_EFL, "External file list"}, {H5E_RAGGED, "Ragged array layer"}, {H5E_REFERENCE, "References layer"}, + {H5E_VFL, "Virtual File Layer"}, }; static const H5E_minor_mesg_t H5E_minor_mesg_g[] = { diff --git a/src/H5Epublic.h b/src/H5Epublic.h index e7877fb..7d835d2 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -75,7 +75,8 @@ typedef enum H5E_major_t { H5E_PLINE, /*Data filters */ H5E_EFL, /*External file list */ H5E_RAGGED, /*Ragged arrays */ - H5E_REFERENCE /*References */ + H5E_REFERENCE, /*References */ + H5E_VFL /*Virtual File Layer */ } H5E_major_t; /* Declare an enumerated type which holds all the valid minor HDF error codes */ @@ -20,6 +20,11 @@ static char RcsId[] = "@(#)$Revision$"; /* $Id$ */ +/* Predefined file drivers */ +#include <H5FDsec2.h> /*Posix unbuffered I/O */ +#include <H5FDfamily.h> /*family of files */ +#include <H5FDmpio.h> /*MPI-2 I/O */ + /* Packages needed by this file... */ #include <H5private.h> /*library functions */ #include <H5Aprivate.h> /*attributes */ @@ -28,6 +33,7 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5ACprivate.h> /*cache */ #include <H5Eprivate.h> /*error handling */ #include <H5Fprivate.h> /*file access */ +#include <H5FDprivate.h> /*file driver */ #include <H5Gprivate.h> /*symbol tables */ #include <H5MMprivate.h> /*core memory management */ #include <H5Pprivate.h> /*property lists */ @@ -67,28 +73,23 @@ H5F_access_t H5F_access_dflt; /* Default data transfer property list */ const H5F_xfer_t H5F_xfer_dflt = { - 1024*1024, /* Temporary buffer size */ - NULL, /* Type conversion buffer or NULL */ - NULL, /* Background buffer or NULL */ - H5T_BKG_NO, /* Type of background buffer needed */ - {0.1, 0.5, 0.9}, /* B-tree node splitting ratios */ + 1024*1024, /*Temporary buffer size */ + NULL, /*Type conversion buffer or NULL */ + NULL, /*Background buffer or NULL */ + H5T_BKG_NO, /*Type of background buffer needed */ + {0.1, 0.5, 0.9}, /*B-tree node splitting ratios */ #ifndef HAVE_PARALLEL - 1, /* Cache the hyperslab blocks by default*/ + 1, /*Cache the hyperslab blocks */ #else - 0, /* - * Don't cache the hyperslab blocks by - * default (for parallel) - */ + 0, /*Don't cache the hyperslab blocks */ #endif /* HAVE_PARALLEL */ - 0, /* - * Default to no upper limit on hyperslab - * block size to cache - */ - H5D_XFER_DFLT, /* Independent data transfer */ - NULL, /* Default to malloc for VL allocations */ - NULL, /* No information needed for malloc allocations */ - NULL, /* Default to free for VL frees */ - NULL, /* No information needed for free frees */ + 0, /*No limit on hyperslab block size to cache */ + NULL, /*Use malloc() for VL data allocations */ + NULL, /*No information needed for malloc() calls */ + NULL, /*Use free() for VL data frees */ + NULL, /*No information needed for free() calls */ + -2, /*See H5Pget_driver() */ + NULL, /*No file driver-specific information yet */ }; /* @@ -104,13 +105,11 @@ static intn interface_initialize_g = 0; static herr_t H5F_init_interface(void); /* PRIVATE PROTOTYPES */ -static H5F_t *H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, - const H5F_access_t *fapl); +static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id); static herr_t H5F_dest(H5F_t *f); -static herr_t H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate); -static herr_t H5F_locate_signature(H5F_low_t *f_handle, - const H5F_access_t *access_parms, - haddr_t *addr_p/*out*/); +static herr_t H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, + hbool_t alloc_only); +static haddr_t H5F_locate_signature(H5FD_t *file); static intn H5F_flush_all_cb(H5F_t *f, const void *_invalidate); @@ -167,6 +166,7 @@ static herr_t H5F_init_interface(void) { herr_t ret_value = SUCCEED; + herr_t status; FUNC_ENTER(H5F_init_interface, FAIL); @@ -196,6 +196,19 @@ H5F_init_interface(void) "unable to initialize interface"); } + /* Register predefined file drivers */ + H5E_BEGIN_TRY { + if ((status=H5FD_SEC2)<0) goto end_registration; + if ((status=H5FD_FAMILY)<0) goto end_registration; + /*...others just like above...*/ + + end_registration: + } H5E_END_TRY; + if (status<0) { + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, + "file driver registration failed"); + } + /* Initialize the default file access property list */ H5F_access_dflt.mdc_nelmts = H5AC_NSLOTS; H5F_access_dflt.rdcc_nelmts = 521; @@ -203,29 +216,9 @@ H5F_init_interface(void) H5F_access_dflt.rdcc_w0 = 0.75; /*preempt fully read chunks*/ H5F_access_dflt.threshold = 1; /*alignment applies to everything*/ H5F_access_dflt.alignment = 1; /*no alignment*/ - H5F_access_dflt.gc_ref = 0; /* Don't garbage-collect references unless user chooses to */ - H5F_access_dflt.driver = H5F_LOW_DFLT; -#if (H5F_LOW_DFLT == H5F_LOW_SEC2) - /* Nothing to initialize */ -#elif (H5F_LOW_DFLT == H5F_LOW_STDIO) - /* Nothing to initialize */ -#elif (H5F_LOW_DFLT == H5F_LOW_CORE) - H5F_access_dflt.u.core.increment = 10*1024; -#elif (H5F_LOW_DFLT == H5F_LOW_MPIO) - H5F_access_dflt.u.mpio.comm = MPI_COMM_SELF; - H5F_access_dflt.u.mpio.info = MPI_INFO_NULL; - H5F_access_dflt.u.mpio.btype = MPI_DATATYPE_NULL; - H5F_access_dflt.u.mpio.ftype = MPI_DATATYPE_NULL; - H5F_access_dflt.u.mpio.disp = 0; - H5F_access_dflt.u.mpio.use_types = 0; - H5F_access_dflt.u.mpio.old_use_types = 0; -#elif (H5F_LOW_DFLT == H5F_LOW_SPLIT) -# error "H5F_LOW_SPLIT cannot be a default file driver" -#elif (H5F_LOW_DFLT == H5F_LOW_FAMILY) -# error "H5F_LOW_FAMILY cannot be a default file driver" -#else -# error "Unknown default file driver" -#endif + H5F_access_dflt.gc_ref = 0; /*don't garbage-collect references*/ + H5F_access_dflt.driver_id = H5FD_SEC2; /*default driver*/ + H5F_access_dflt.driver_info = NULL; /*driver file access properties*/ FUNC_LEAVE(ret_value); } @@ -288,7 +281,7 @@ static intn H5F_flush_all_cb(H5F_t *f, const void *_invalidate) { hbool_t invalidate = *((const hbool_t*)_invalidate); - H5F_flush(f, H5F_SCOPE_LOCAL, invalidate); + H5F_flush(f, H5F_SCOPE_LOCAL, invalidate, FALSE); return 0; } @@ -422,7 +415,7 @@ H5Fget_create_plist(hid_t file_id) } /* Create the property list object to return */ - if (NULL==(plist=H5P_copy(H5P_FILE_CREATE, file->shared->create_parms))) { + if (NULL==(plist=H5P_copy(H5P_FILE_CREATE, file->shared->fcpl))) { HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file creation properties"); } @@ -472,7 +465,7 @@ H5Fget_access_plist(hid_t file_id) } /* Create the property list object to return */ - if (NULL==(plist=H5P_copy(H5P_FILE_ACCESS, f->shared->access_parms))) { + if (NULL==(plist=H5P_copy(H5P_FILE_ACCESS, f->shared->fapl))) { HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file access properties"); } @@ -486,42 +479,37 @@ H5Fget_access_plist(hid_t file_id) FUNC_LEAVE(ret_value); } - - -/*-------------------------------------------------------------------------- - NAME - H5F_compare_files -- compare file objects for the atom API - USAGE - intn HPcompare_filename(obj, key) - const void * obj; IN: pointer to the file record - const void * key; IN: pointer to the search key - ERRORS - - RETURNS - TRUE if the key matches the obj, FALSE otherwise - DESCRIPTION - Look inside the file record for the atom API and compare the the - keys. ---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function: H5F_equal + * + * Purpose: Compares NEEDLE to a file from the HAYSTACK. + * + * Return: Success: Returns positive if two files are equal, + * zero otherwise. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, August 2, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ static intn -H5F_compare_files(void * _obj, const void * _key) +H5F_equal(void *_haystack, const void *_needle) { - const H5F_t *obj = (const H5F_t *) _obj; - const H5F_search_t *key = (const H5F_search_t *) _key; - int ret_value = FALSE; - - FUNC_ENTER(H5F_compare_files, FALSE); -#if WIN32 - ret_value = (obj->shared->key.dev == key->dev && - obj->shared->key.fileindexhi == key->fileindexhi && - obj->shared->key.fileindexlo == key->fileindexlo); -#else - ret_value = (obj->shared->key.dev == key->dev && - obj->shared->key.ino == key->ino); -#endif - FUNC_LEAVE(ret_value); + H5F_t *haystack = (H5F_t*)_haystack; + const H5FD_t *needle = (const H5FD_t*)_needle; + intn retval; + + FUNC_ENTER(H5F_equal, FAIL); + retval = (0==H5FD_cmp(haystack->shared->lf, needle)); + FUNC_LEAVE(retval); } + /*------------------------------------------------------------------------- * Function: H5F_locate_signature @@ -530,106 +518,116 @@ H5F_compare_files(void * _obj, const void * _key) * can appear at address 0, or any power of two beginning with * 512. * - * Return: Success: SUCCEED. The address of the signature is - * returned through the ADDR argument. + * Return: Success: The absolute format address of the signature. * - * Failure: FAIL + * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Friday, November 7, 1997 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * Rewritten to use the virtual file layer. *------------------------------------------------------------------------- */ -static herr_t -H5F_locate_signature(H5F_low_t *f_handle, const H5F_access_t *access_parms, - haddr_t *addr_p/*out*/) +static haddr_t +H5F_locate_signature(H5FD_t *file) { - herr_t ret_value=FAIL; - haddr_t max_addr; + haddr_t addr, eoa; uint8_t buf[H5F_SIGNATURE_LEN]; - uintn n = 9; + uintn n, maxpow; - FUNC_ENTER(H5F_locate_signature, FAIL); + FUNC_ENTER(H5F_locate_signature, HADDR_UNDEF); - H5F_low_size(f_handle, &max_addr); - *addr_p = 0; - while (H5F_addr_lt(*addr_p, max_addr)) { - if (H5F_low_read(f_handle, access_parms, &H5F_xfer_dflt, *addr_p, - H5F_SIGNATURE_LEN, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read file"); - } - if (!HDmemcmp(buf, H5F_SIGNATURE, H5F_SIGNATURE_LEN)) { - ret_value=SUCCEED; - break; - } - *addr_p = H5F_addr_pow2(n++); + /* Find the least N such that 2^N is larger than the file size */ + if (HADDR_UNDEF==(addr=H5FD_get_eof(file)) || + HADDR_UNDEF==(eoa=H5FD_get_eoa(file))) { + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, HADDR_UNDEF, + "unable to obtain EOF/EOA value"); } + for (maxpow=0; addr; maxpow++) addr>>=1; - FUNC_LEAVE(ret_value); -} - - -/*-------------------------------------------------------------------------- - NAME - H5Fis_hdf5 - - PURPOSE - Check the file signature to detect an HDF5 file. + /* + * Search for the file signature at format address zero followed by + * powers of two larger than 9. + */ + for (n=8; n<maxpow; n++) { + addr = (8==n) ? 0 : (haddr_t)1 << n; + if (H5FD_set_eoa(file, addr+H5F_SIGNATURE_LEN)<0) { + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, HADDR_UNDEF, + "unable to set EOA value for file signature"); + } + if (H5FD_read(file, H5P_DEFAULT, addr, H5F_SIGNATURE_LEN, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, HADDR_UNDEF, + "unable to read file signature"); + } + if (!HDmemcmp(buf, H5F_SIGNATURE, H5F_SIGNATURE_LEN)) break; + } - USAGE - htri_t H5Fis_hdf5(filename) - const char *filename; IN: Name of the file to check - ERRORS - ARGS BADRANGE No filename specified. - FILE BADFILE Low-level file open failure. - IO READERROR Read error. - IO READERROR Seek error. - IO SEEKERROR Unable to determine length of file due to seek - failure. + /* + * If the signature was not found then reset the EOA value and return + * failure. + */ + if (n>=maxpow) { + H5FD_set_eoa(file, eoa); + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, HADDR_UNDEF, + "unable to find a valid file signature"); + } - RETURNS - TRUE/FALSE/FAIL + /* Success */ + FUNC_LEAVE(addr); +} - DESCRIPTION - This function determines if a file is an HDF5 format file. ---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function: H5Fis_hdf5 + * + * Purpose: Check the file signature to detect an HDF5 file. + * + * Bugs: This function is not robust: it only uses the default file + * driver when attempting to open the file when in fact it + * should use all known file drivers. + * + * Return: Success: TRUE/FALSE + * + * Failure: Negative + * + * Programmer: Unknown + * + * Modifications: + * Robb Matzke, 1999-08-02 + * Rewritten to use the virtual file layer. + *------------------------------------------------------------------------- + */ htri_t -H5Fis_hdf5(const char *filename) +H5Fis_hdf5(const char *name) { - H5F_low_t *f_handle = NULL; /* file handle */ - haddr_t addr; /* Address of file signature & header */ - hbool_t ret_value = FALSE; - const H5F_low_class_t *type = NULL; + H5FD_t *file = NULL; + hbool_t ret_value = FAIL; FUNC_ENTER(H5Fis_hdf5, FAIL); - H5TRACE1("b","s",filename); + H5TRACE1("b","s",name); /* Check args and all the boring stuff. */ - if (filename == NULL) { - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no filename specified"); + if (!name || !*name) { + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified"); } - /* Open the file at the low level driver */ - type = H5F_low_class (H5F_access_dflt.driver); - assert (type); - if (NULL == (f_handle = H5F_low_open(type, filename, &H5F_access_dflt, - 0, NULL))) { - HGOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, - "low-level file open failure"); - } - if (H5F_locate_signature(f_handle, &H5F_access_dflt, &addr/*out*/)>=0) { - ret_value = TRUE; - } - - done: - if (f_handle) { - H5F_low_close(f_handle, &H5F_access_dflt); /*close the file we opened*/ + /* Open the file at the virtual file layer */ + if (NULL==(file=H5FD_open(name, H5F_ACC_RDONLY, H5P_DEFAULT, + HADDR_UNDEF))) { + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file"); } - + + /* The file is an hdf5 file if the hdf5 file signature can be found */ + ret_value = (HADDR_UNDEF!=H5F_locate_signature(file)); + + done: + /* Close the file */ + if (file) H5FD_close(file); FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- * Function: H5F_new @@ -656,39 +654,43 @@ H5Fis_hdf5(const char *filename) *------------------------------------------------------------------------- */ static H5F_t * -H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl) +H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id) { H5F_t *f=NULL, *ret_value=NULL; intn n; + const H5F_create_t *fcpl=NULL; + const H5F_access_t *fapl=NULL; FUNC_ENTER(H5F_new, NULL); - if (NULL==(f = H5MM_calloc(sizeof(H5F_t)))) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); + if (NULL==(f=H5MM_calloc(sizeof(H5F_t)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); } if (shared) { f->shared = shared; } else { f->shared = H5MM_calloc(sizeof(H5F_file_t)); - f->shared->boot_addr = H5F_ADDR_UNDEF; - f->shared->base_addr = H5F_ADDR_UNDEF; - f->shared->freespace_addr = H5F_ADDR_UNDEF; - f->shared->hdf5_eof = H5F_ADDR_UNDEF; + f->shared->boot_addr = HADDR_UNDEF; + f->shared->base_addr = HADDR_UNDEF; + f->shared->freespace_addr = HADDR_UNDEF; /* * Deep-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. */ - if (NULL==(f->shared->create_parms=H5P_copy(H5P_FILE_CREATE, fcpl))) { - HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, NULL, - "unable to copy file creation property list"); + fcpl = (H5P_DEFAULT==fcpl_id)? &H5F_create_dflt : H5I_object(fcpl_id); + if (NULL==(f->shared->fcpl=H5P_copy(H5P_FILE_CREATE, fcpl))) { + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, NULL, + "unable to copy file creation property list"); } - if (NULL==(f->shared->access_parms=H5P_copy(H5P_FILE_ACCESS, fapl))) { - HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, NULL, - "unable to copy file access property list"); + + 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"); } #ifdef HAVE_PARALLEL @@ -697,9 +699,9 @@ H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl) * does not permit caching. (maybe able to relax it for * read only open.) */ - if (f->shared->access_parms->driver==H5F_LOW_MPIO){ - f->shared->access_parms->rdcc_nbytes = 0; - f->shared->access_parms->mdc_nelmts = 0; + if (H5FD_MPIO==f->shared->fapl->driver_id){ + f->shared->fapl->rdcc_nbytes = 0; + f->shared->fapl->mdc_nelmts = 0; } #endif @@ -708,14 +710,14 @@ H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl) * 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->access_parms->mdc_nelmts))<0) { - HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, NULL, - "unable to create meta data cache"); + if ((n=H5AC_create(f, f->shared->fapl->mdc_nelmts))<0) { + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, NULL, + "unable to create meta data cache"); } - f->shared->access_parms->mdc_nelmts = n; + f->shared->fapl->mdc_nelmts = n; /* Create the chunk cache */ - H5F_istore_init (f); + H5F_istore_init(f); } f->shared->nrefs++; @@ -724,8 +726,8 @@ H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl) done: if (!ret_value && f) { - if (!shared) H5MM_xfree (f->shared); - H5MM_xfree (f); + if (!shared) H5MM_xfree(f->shared); + H5MM_xfree(f); } FUNC_LEAVE(ret_value); @@ -756,7 +758,6 @@ H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, const H5F_access_t *fapl) * More careful about decrementing reference counts so they don't go * negative or wrap around to some huge value. Nothing happens if a * reference count is already zero. - * *------------------------------------------------------------------------- */ static herr_t @@ -772,19 +773,19 @@ H5F_dest(H5F_t *f) * Do not close the root group since we didn't count it, but free * the memory associated with it. */ - H5MM_xfree (f->shared->root_grp); + H5MM_xfree(f->shared->root_grp); f->shared->root_grp=NULL; if (H5AC_dest(f)) { - HERROR (H5E_FILE, H5E_CANTINIT, "problems closing file"); + HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file"); ret_value = FAIL; /*but keep going*/ } if (H5F_istore_dest (f)<0) { - HERROR (H5E_FILE, H5E_CANTINIT, "problems closing file"); + HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file"); ret_value = FAIL; /*but keep going*/ } f->shared->cwfs = H5MM_xfree (f->shared->cwfs); - H5P_close (H5P_FILE_CREATE, f->shared->create_parms); - H5P_close (H5P_FILE_ACCESS, f->shared->access_parms); + H5P_close(H5P_FILE_CREATE, f->shared->fcpl); + H5P_close(H5P_FILE_ACCESS, f->shared->fapl); f->shared = H5MM_xfree(f->shared); } else if (f->shared->nrefs>0) { /* @@ -799,7 +800,7 @@ H5F_dest(H5F_t *f) f->mtab.child = H5MM_xfree(f->mtab.child); f->mtab.nalloc = 0; H5MM_xfree(f); - } else if (f->nrefs>0) { + } else if (f && f->nrefs>0) { /* * There are other references to this file. Only decrement the * reference count. @@ -831,9 +832,9 @@ H5F_dest(H5F_t *f) * H5F_ACC_EXCL: This flag causes H5F_open() to fail if the * file already exists. * - * H5F_ACC_TRUNC: The file is truncated and a new HDF5 boot - * block is written. This operation will fail - * if the file is already open. + * H5F_ACC_TRUNC: The file is truncated and a new HDF5 superblock + * is written. This operation will fail if the + * file is already open. * * Unlinking the file name from the group directed graph while * the file is opened causes the file to continue to exist but @@ -849,44 +850,7 @@ H5F_dest(H5F_t *f) * The ACCESS_PARMS argument is optional. A null pointer will * cause the default file access parameters to be used. * - * Errors: - * ATOM BADATOM Can't unatomize default template - * id. - * FILE BADVALUE Can't create file without write - * intent. - * FILE BADVALUE Can't truncate without write intent. - * FILE CANTCREATE Can't create file. - * FILE CANTCREATE Can't truncate file. - * FILE CANTINIT Can't get default file create template - * id. - * FILE CANTINIT Can't write file boot block. - * FILE CANTOPENFILE Bad address size. - * FILE CANTOPENFILE Bad boot block version number. - * FILE CANTOPENFILE Bad free space version number. - * FILE CANTOPENFILE Bad length size. - * FILE CANTOPENFILE Bad object dir version number. - * FILE CANTOPENFILE Bad shared header version number. - * FILE CANTOPENFILE Bad small object heap version number. - * FILE CANTOPENFILE Bad symbol table internal node 1/2 - * rank. - * FILE CANTOPENFILE Bad symbol table leaf node 1/2 rank. - * FILE CANTOPENFILE Can't read root symbol entry. - * FILE CANTOPENFILE Cannot open existing file. - * FILE CANTOPENFILE File cannot be reopened with write - * access. - * FILE CANTOPENFILE File does not exist. - * FILE CANTOPENFILE Invalid file family name. - * FILE FILEEXISTS File already exists - CREAT EXCL - * failed. - * FILE FILEOPEN File already open - TRUNC failed. - * FILE NOTHDF5 Can't find signature. - * FILE NOTHDF5 Can't read boot block. - * FILE READERROR File is not readable. - * FILE TRUNCATED Truncated file? - * FILE WRITEERROR File is not writable. - * IO READERROR Can't read boot block. - * - * Return: Success: Ptr to the file pointer. + * Return: Success: A new file pointer. * * Failure: NULL * @@ -894,171 +858,112 @@ H5F_dest(H5F_t *f) * Tuesday, September 23, 1997 * * Modifications: + * Albert Cheng, 1998-02-05 + * Added the access_parms argument to pass down access template + * information. * - * Robb Matzke, 11 Nov 1997 - * If the name contains the pattern /[^%]%\d*[duxX]/ then the file is - * assumed to be a family of files. The TYPE argument is ignored and - * H5F_LOW_FAM is used instead. - * - * Albert Cheng, 5 Feb 1998 - * Added the access_parms argument to pass down access template - * information. - * - * Robb Matzke, 18 Feb 1998 - * The H5F_access_t changed to allow more generality. The low level - * driver is part of the file access template so the TYPE argument has - * been removed. + * Robb Matzke, 1998-02-18 + * The H5F_access_t changed to allow more generality. The low + * level driver is part of the file access template so the TYPE + * argument has been removed. * + * Robb Matzke, 1999-08-02 + * Rewritten to use the virtual file layer. *------------------------------------------------------------------------- */ H5F_t * -H5F_open(const char *name, uintn flags, - const H5F_create_t *create_parms, const H5F_access_t *access_parms) +H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id) { - H5F_t *f = NULL; /*return value */ - H5F_t *ret_value = NULL; /*a copy of `f' */ - H5F_t *old = NULL; /*a file already opened */ - H5F_search_t search; /*file search key */ - H5F_low_t *fd = NULL; /*low level file desc */ - hbool_t empty_file = FALSE; /*is file empty? */ - hbool_t file_exists = FALSE; /*file already exists */ - uint8_t buf[256]; /*I/O buffer.. */ - const uint8_t *p = NULL; /* ..and pointer into it */ - size_t fixed_size = 24; /*size of fixed part of boot blk*/ - size_t variable_size; /*variable part of boot block */ - H5F_create_t *cp = NULL; /*file creation parameters */ - haddr_t addr1, addr2; /*temporary address */ + H5F_t *file=NULL; /*the success return value */ + H5F_t *ret_value=NULL;/*actual return value */ + H5F_file_t *shared=NULL; /*shared part of `file' */ + H5FD_t *lf=NULL; /*file driver part of `shared' */ + uint8_t buf[256]; /*temporary I/O buffer */ + 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 */ H5G_entry_t root_ent; /*root symbol table entry */ - const H5F_low_class_t *type = NULL; /*low-level file driver */ - haddr_t reserved_addr; /*reserved address */ - + 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 */ + FUNC_ENTER(H5F_open, NULL); - assert(name && *name); - /* - * If no file creation parameters or file access parameters are supplied - * then use defaults. + * Open the file very carefully because we don't want to wipe out a file + * which is currently open (which is possible if this call specifies + * truncation of an existing file). So turn off truncation and file + * creation and try opening it. If that fails then open as normal. */ - if (!create_parms) create_parms = &H5F_create_dflt; - if (!access_parms) access_parms = &H5F_access_dflt; - - /* - * Does the file exist? If so, get the device and i-node values so we can - * compare them with other files already open. On Unix (and other systems - * with hard or soft links) it doesn't work to compare files based only on - * their full path name. - */ - type = H5F_low_class (access_parms->driver); - assert (type); - file_exists = H5F_low_access(type, name, access_parms, F_OK, &search); - - /* - * Open the low-level file (if necessary) and create an H5F_t struct that - * points to an H5F_file_t struct. - */ - if (file_exists) { - if (flags & H5F_ACC_EXCL) { - HRETURN_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, - "file already exists - CREAT EXCL failed"); - } - if (!H5F_low_access(type, name, access_parms, R_OK, NULL)) { - HRETURN_ERROR(H5E_FILE, H5E_READERROR, NULL, - "file is not readable"); - } - if ((flags & H5F_ACC_RDWR) && - !H5F_low_access(type, name, access_parms, W_OK, NULL)) { - HRETURN_ERROR(H5E_FILE, H5E_WRITEERROR, NULL, - "file is not writable"); + tent_flags = flags & ~(H5F_ACC_CREAT|H5F_ACC_TRUNC|H5F_ACC_EXCL); + if (NULL==(lf=H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { + H5E_clear(); + tent_flags = flags; + if (NULL==(lf=H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to open file"); } - if ((old = H5I_search(H5I_FILE, H5F_compare_files, &search)) || - (old = H5I_search(H5I_FILE_CLOSING, H5F_compare_files, &search))) { - if (flags & H5F_ACC_TRUNC) { - HRETURN_ERROR(H5E_FILE, H5E_FILEOPEN, NULL, - "file already open - TRUNC failed"); - } - if ((flags & H5F_ACC_RDWR) && - 0 == (old->shared->flags & H5F_ACC_RDWR)) { - if (NULL==(fd=H5F_low_open(type, name, access_parms, - H5F_ACC_RDWR, NULL))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "file cannot be reopened with write access"); - } - H5F_low_close(old->shared->lf, access_parms); - old->shared->lf = fd; - old->shared->flags |= H5F_ACC_RDWR; - fd = NULL; /*so we don't close it during error */ - } - f = H5F_new(old->shared, NULL, NULL); + } - } else if (flags & H5F_ACC_TRUNC) { - /* Truncate existing file */ - if (0 == (flags & H5F_ACC_RDWR)) { - HRETURN_ERROR(H5E_FILE, H5E_BADVALUE, NULL, - "unable to truncate without write intent"); - } - fd = H5F_low_open(type, name, access_parms, - H5F_ACC_RDWR | H5F_ACC_TRUNC, NULL); - if (!fd) { - HRETURN_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, - "unable to truncate file"); - } - f = H5F_new(NULL, create_parms, access_parms); - f->shared->key = search; - f->shared->flags = flags; - f->shared->lf = fd; - empty_file = TRUE; - - } else { - fd = H5F_low_open(type, name, access_parms, - (flags & H5F_ACC_RDWR), NULL); - if (!fd) { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "cannot open existing file"); - } - f = H5F_new(NULL, create_parms, access_parms); - f->shared->key = search; - f->shared->flags = flags; - f->shared->lf = fd; + /* Is the file already open? */ + if ((file=H5I_search(H5I_FILE, H5F_equal, lf)) || + (file=H5I_search(H5I_FILE_CLOSING, H5F_equal, lf))) { + /* + * The file is already open, so use that one instead of the one we + * just opened. We only one one H5FD_t* per file so one doesn't + * confuse the other. But fail if this request was to truncate the + * file (since we can't do that while the file is open), or if the + * request was to create a non-existent file (since the file already + * exists), or if the new request adds write access (since the + * readers don't expect the file to change under them). + */ + if (flags & H5F_ACC_TRUNC) { + file = NULL; /*to prevent destruction of wrong file*/ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to truncate a file which is already open"); } - - } else if (flags & H5F_ACC_CREAT) { - if (0 == (flags & H5F_ACC_RDWR)) { - HRETURN_ERROR(H5E_FILE, H5E_BADVALUE, NULL, - "unable to create file without write intent"); + if (flags & H5F_ACC_EXCL) { + file = NULL; /*to prevent destruction of wrong file*/ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "file exists"); } -#ifdef HAVE_PARALLEL + if ((flags & H5F_ACC_RDWR) && 0==(file->intent & H5F_ACC_RDWR)) { + file = NULL; /*to prevent destruction of wrong file*/ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "file is already open for read-only"); + } + H5FD_close(lf); + file = H5F_new(file->shared, fcpl_id, fapl_id); + lf = file->shared->lf; + } else if (flags!=tent_flags) { /* - * ROMIO cannot handle file-open with EXCL Create due to racing - * problem. The first process creates the file which then fails all - * other processes. Turn on TRUNC bit here. It does not matter since - * the file does not exist at this point. + * This file is not yet open by the library and the flags we used to + * open it are different than the desired flags. Close the tentative + * file and open it for real. */ - fd = H5F_low_open(type, name, access_parms, - H5F_ACC_RDWR | H5F_ACC_CREAT | - (flags & H5F_ACC_TRUNC), - &search); -#else - fd = H5F_low_open(type, name, access_parms, - H5F_ACC_RDWR | H5F_ACC_CREAT | - (flags & H5F_ACC_EXCL) | (flags & H5F_ACC_TRUNC), - &search); -#endif /*HAVE_PARALLEL*/ - if (!fd) { - HRETURN_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, - "unable to create file"); + H5FD_close(lf); + if (NULL==(lf=H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) { + file = NULL; /*to prevent destruction of wrong file*/ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to open file"); } - f = H5F_new(NULL, create_parms, access_parms); - f->shared->key = search; - f->shared->flags = flags; - f->shared->lf = fd; - empty_file = TRUE; - + file = H5F_new(NULL, fcpl_id, fapl_id); + file->shared->flags = flags; + file->shared->lf = lf; } else { - HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "file does not exist"); + /* + * This file is not yet open by the library and our tentative opening + * above is good enough. + */ + file = H5F_new(NULL, fcpl_id, fapl_id); + file->shared->flags = flags; + file->shared->lf = lf; } - assert(f); + + /* Short cuts */ + shared = file->shared; + lf = shared->lf; /* * The intent at the top level file struct are not necessarily the same as @@ -1066,198 +971,184 @@ H5F_open(const char *name, uintn flags, * accessed through the HDF5 library. The bottom level describes how the * file can be accessed through the C library. */ - f->intent = flags; - f->name = H5MM_xstrdup(name); + file->intent = flags; + file->name = H5MM_xstrdup(name); /* - * Some of the properties may need to be updated. We would like to - * eventually get rid of this step by not having redundant data! + * Read or write the file superblock, depending on whether the file is + * empty or not. */ - if (1 == f->shared->nrefs) { - if (H5F_LOW_FAMILY==f->shared->access_parms->driver) { - haddr_t x = f->shared->lf->u.fam.memb_size; - f->shared->access_parms->u.fam.memb_size = x; - } - } - cp = f->shared->create_parms; - - /* - * Read or write the file boot block. - */ - if (empty_file) { + if (0==H5FD_get_eof(lf) && (flags & H5F_ACC_RDWR)) { /* - * For new files we must write the boot block. The boot block starts - * immediately after the user-defined header, which we have already - * insured is a proper size. The base address is set to the same thing - * as the boot block. + * The superblock starts immediately after the user-defined header, + * which we have already insured is a proper size. The base address + * is set to the same thing as the superblock for now. */ - f->shared->boot_addr = f->shared->create_parms->userblock_size; - f->shared->base_addr = f->shared->boot_addr; - - f->shared->consist_flags = 0x03; - if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE) < 0) { + shared->boot_addr = shared->fcpl->userblock_size; + shared->base_addr = shared->boot_addr; + shared->consist_flags = 0x03; + if (H5F_flush(file, H5F_SCOPE_LOCAL, FALSE, TRUE)<0) { HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, - "unable to write file boot block"); + "unable to write file superblock"); } - } else if (1 == f->shared->nrefs) { - /* For existing files we must read the boot block. */ - if (H5F_locate_signature(f->shared->lf, - f->shared->access_parms, - &(f->shared->boot_addr)/*out*/) < 0) { + /* Create and open the root group */ + if (H5G_mkroot(file, NULL)<0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, + "unable to create/open root group"); + } + + } else if (1==shared->nrefs) { + /* Read the superblock if it hasn't been read before. */ + if (HADDR_UNDEF==(shared->boot_addr=H5F_locate_signature(lf))) { HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, NULL, - "unable to find signature"); + "unable to find file signature"); } - if (H5F_low_read(f->shared->lf, access_parms, &H5F_xfer_dflt, - f->shared->boot_addr, fixed_size, buf) < 0) { - HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, - "unable to read boot block"); + if (H5FD_set_eoa(lf, shared->boot_addr+fixed_size)<0 || + H5FD_read(lf, H5P_DEFAULT, shared->boot_addr, fixed_size, buf)<0) { + HGOTO_ERROR(H5E_FILE, H5E_IO, NULL, + "unable to read superblock"); } - - /* - * Decode the fixed size part of the boot block. For each of the - * version parameters, check that the library is able to handle that - * version. - */ - p = buf + H5F_SIGNATURE_LEN; /*already checked */ - cp->bootblock_ver = *p++; - if (cp->bootblock_ver != HDF5_BOOTBLOCK_VERSION) { + /* Signature, already checked */ + p = buf + H5F_SIGNATURE_LEN; + + /* Superblock version */ + shared->fcpl->bootblock_ver = *p++; + if (HDF5_BOOTBLOCK_VERSION!=shared->fcpl->bootblock_ver) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad boot block version number"); + "bad superblock version number"); } - cp->freespace_ver = *p++; - if (cp->freespace_ver != HDF5_FREESPACE_VERSION) { + + /* Freespace version */ + shared->fcpl->freespace_ver = *p++; + if (HDF5_FREESPACE_VERSION!=shared->fcpl->freespace_ver) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad free space version number"); } - cp->objectdir_ver = *p++; - if (cp->objectdir_ver != HDF5_OBJECTDIR_VERSION) { + + /* Root group version number */ + shared->fcpl->objectdir_ver = *p++; + if (HDF5_OBJECTDIR_VERSION!=shared->fcpl->objectdir_ver) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad object dir version number"); + "bad root group version number"); } - p++; /*reserved*/ - cp->sharedheader_ver = *p++; - if (cp->sharedheader_ver != HDF5_SHAREDHEADER_VERSION) { + + /* reserved */ + p++; + + /* Shared header version number */ + shared->fcpl->sharedheader_ver = *p++; + if (HDF5_SHAREDHEADER_VERSION!=shared->fcpl->sharedheader_ver) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad shared header version number"); } - cp->sizeof_addr = *p++; - if (cp->sizeof_addr != 2 && - cp->sizeof_addr != 4 && - cp->sizeof_addr != 8 && - cp->sizeof_addr != 16 && - cp->sizeof_addr != 32) { + + /* Size of file addresses */ + shared->fcpl->sizeof_addr = *p++; + if (shared->fcpl->sizeof_addr != 2 && + shared->fcpl->sizeof_addr != 4 && + shared->fcpl->sizeof_addr != 8 && + shared->fcpl->sizeof_addr != 16 && + shared->fcpl->sizeof_addr != 32) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad address size"); + "bad file sizeof(address)"); } - cp->sizeof_size = *p++; - if (cp->sizeof_size != 2 && - cp->sizeof_size != 4 && - cp->sizeof_size != 8 && - cp->sizeof_size != 16 && - cp->sizeof_size != 32) { + + /* Size of file sizes */ + shared->fcpl->sizeof_size = *p++; + if (shared->fcpl->sizeof_size != 2 && + shared->fcpl->sizeof_size != 4 && + shared->fcpl->sizeof_size != 8 && + shared->fcpl->sizeof_size != 16 && + shared->fcpl->sizeof_size != 32) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "bad length size"); + "bad file sizeof(size)"); } /* Reserved byte */ p++; - UINT16DECODE(p, cp->sym_leaf_k); - if (cp->sym_leaf_k < 1) { + /* Various B-tree sizes */ + UINT16DECODE(p, shared->fcpl->sym_leaf_k); + if (shared->fcpl->sym_leaf_k < 1) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad symbol table leaf node 1/2 rank"); } - UINT16DECODE(p, cp->btree_k[H5B_SNODE_ID]); - if (cp->btree_k[H5B_SNODE_ID] < 1) { + UINT16DECODE(p, shared->fcpl->btree_k[H5B_SNODE_ID]); + if (shared->fcpl->btree_k[H5B_SNODE_ID] < 1) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad symbol table internal node 1/2 rank"); } - UINT32DECODE(p, f->shared->consist_flags); - - /* nothing to check for consistency flags */ + /* File consistency flags. Not really used yet */ + UINT32DECODE(p, shared->consist_flags); assert((size_t)(p-buf) == fixed_size); - /* Read the variable length part of the boot block... */ - variable_size = H5F_SIZEOF_ADDR(f) + /*base address */ - H5F_SIZEOF_ADDR(f) + /*global free list addr */ - H5F_SIZEOF_ADDR(f) + /*logical file size */ - H5F_SIZEOF_ADDR(f) + /*reserved address*/ - H5G_SIZEOF_ENTRY(f); - assert(variable_size <= sizeof buf); - addr1 = f->shared->boot_addr + (hsize_t)fixed_size; - if (H5F_low_read(f->shared->lf, access_parms, &H5F_xfer_dflt, - addr1, variable_size, buf) < 0) { - HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, NULL, - "unable to read boot block"); + /* Decode the variable-length part of the superblock... */ + variable_size = H5F_SIZEOF_ADDR(file) + /*base addr*/ + H5F_SIZEOF_ADDR(file) + /*global free list*/ + H5F_SIZEOF_ADDR(file) + /*end-of-address*/ + H5F_SIZEOF_ADDR(file) + /*reserved address*/ + H5G_SIZEOF_ENTRY(file); /*root group ptr*/ + assert(variable_size<=sizeof buf); + if (H5FD_set_eoa(lf, shared->boot_addr+fixed_size+variable_size)<0 || + H5FD_read(lf, H5P_DEFAULT, shared->boot_addr+fixed_size, + variable_size, buf)<0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to read superblock"); } p = buf; - H5F_addr_decode(f, &p, &(f->shared->base_addr)/*out*/); - H5F_addr_decode(f, &p, &(f->shared->freespace_addr)/*out*/); - H5F_addr_decode(f, &p, &(f->shared->hdf5_eof)/*out*/); - H5F_addr_decode(f, &p, &reserved_addr/*out*/); - if (H5G_ent_decode(f, &p, &root_ent/*out*/) < 0) { + 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*/); + if (H5G_ent_decode(file, &p, &root_ent/*out*/)<0) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root symbol entry"); } - if (H5G_mkroot(f, &root_ent)<0) { - HGOTO_ERROR (H5E_FILE, H5E_CANTOPENFILE, NULL, - "unable to read root group"); + if (H5G_mkroot(file, &root_ent)<0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to read root group"); } /* - * The userdefined data is the area of the file before the base + * The user-defined data is the area of the file before the base * address. */ - f->shared->create_parms->userblock_size = f->shared->base_addr; - } - - /* - * What is the current size of the file? The max_addr field is a relative - * address while H5F_low_size() returns an absolute address. - */ - H5F_low_size(f->shared->lf, &addr1/*out*/); - addr2 = f->shared->hdf5_eof + f->shared->base_addr; - if (H5F_addr_lt(addr1, addr2)) { + shared->fcpl->userblock_size = shared->base_addr; + + /* - * Truncated file? This might happen if one tries to open the first - * member of a file family. + * 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 + * individually. */ - HGOTO_ERROR(H5E_FILE, H5E_TRUNCATED, NULL, "truncated file"); - - } else if (H5F_addr_gt(addr1, addr2)) { + if (HADDR_UNDEF==(eof=H5FD_get_eof(lf))) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to determine file size"); + } + if (eof<stored_eoa) { + HGOTO_ERROR(H5E_FILE, H5E_TRUNCATED, NULL, "truncated file"); + } + /* - * The file is larger than the hdf5 data. It either has extra junk at - * the end, or a wrapper. In either case, make the file think it's - * shorter so when we allocate memory from the file for hdf5 it's - * allocated immediately after the end of the previous hdf5 data. This - * will cause internal wrappers to be overwritten if they follow the - * hdf5 data. + * Tell the file driver how much address space has already been + * allocated so that it knows how to allocated additional memory. */ -#ifdef H5F_DEBUG - if (H5DEBUG(F)) { - HDfprintf(H5DEBUG(F), "H5F: resetting EOF from %a to %a (abs)\n", - addr1, addr2); + if (H5FD_set_eoa(lf, stored_eoa)<0) { + HRETURN_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to set end-of-address marker for file"); } -#endif - H5F_low_seteof(f->shared->lf, addr2); } - /* Create and/or open the root group if we haven't already done so */ - if (H5G_mkroot (f, NULL)<0) { - HGOTO_ERROR (H5E_FILE, H5E_CANTINIT, NULL, - "unable to create/open root group"); - } - - /* Success! */ - ret_value = f; + /* Success */ + ret_value = file; - done: + done: if (!ret_value) { - if (f) H5F_dest(f); - H5F_low_close(fd, access_parms); + if (file) H5F_dest(file); + if (lf) H5FD_close(lf); } FUNC_LEAVE(ret_value); } @@ -1289,44 +1180,39 @@ H5F_open(const char *name, uintn flags, * Programmer: Unknown * * Modifications: - * - * Robb Matzke, 18 Jul 1997 - * File struct creation and destruction is through H5F_new() and - * H5F_dest(). Writing the root symbol table entry is done with - * H5G_encode(). + * Robb Matzke, 1997-07-18 + * File struct creation and destruction is through H5F_new() and + * H5F_dest(). Writing the root symbol table entry is done with + * H5G_encode(). * - * Robb Matzke, 29 Aug 1997 - * Moved creation of the boot block to H5F_flush(). + * Robb Matzke, 1997-08-29 + * Moved creation of the boot block to H5F_flush(). * - * Robb Matzke, 23 Sep 1997 - * Most of the work is now done by H5F_open() since H5Fcreate() and - * H5Fopen() originally contained almost identical code. - * - * Robb Matzke, 18 Feb 1998 - * Better error checking for the creation and access property lists. It - * used to be possible to swap the two and core the library. Also, zero - * is no longer valid as a default property list; one must use - * H5P_DEFAULT instead. - * + * Robb Matzke, 1997-09-23 + * Most of the work is now done by H5F_open() since H5Fcreate() + * and H5Fopen() originally contained almost identical code. + * + * Robb Matzke, 1998-02-18 + * Better error checking for the creation and access property + * lists. It used to be possible to swap the two and core the + * library. Also, zero is no longer valid as a default property + * list; one must use H5P_DEFAULT instead. + * + * Robb Matzke, 1999-08-02 + * The file creation and file access property lists are passed + * to the H5F_open() as object IDs. *------------------------------------------------------------------------- */ hid_t -H5Fcreate(const char *filename, unsigned flags, hid_t create_id, - hid_t access_id) +H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, + hid_t fapl_id) { - H5F_t *new_file = NULL; /* file struct for new file */ - const H5F_create_t *create_parms; /* pointer to the parameters to - * use when creating the file - */ - const H5F_access_t *access_parms; /* pointer to the file access - * parameters to use when - * creating the file - */ - hid_t ret_value = FAIL; + H5F_t *new_file = NULL; /*file struct for new file */ + hid_t ret_value = FAIL; /*return value */ FUNC_ENTER(H5Fcreate, FAIL); - H5TRACE4("i","sIuii",filename,flags,create_id,access_id); + H5TRACE4("i","sIuii",filename,flags,fcpl_id,fapl_id); /* Check/fix arguments */ if (!filename || !*filename) { @@ -1339,17 +1225,15 @@ H5Fcreate(const char *filename, unsigned flags, hid_t create_id, HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "mutually exclusive flags for file creation"); } - if (H5P_DEFAULT==create_id) { - create_parms = &H5F_create_dflt; - } else if (H5P_FILE_CREATE!=H5P_get_class (create_id) || - NULL == (create_parms = H5I_object(create_id))) { + if (H5P_DEFAULT!=fcpl_id && + (H5P_FILE_CREATE!=H5P_get_class(fcpl_id) || + NULL==H5I_object(fcpl_id))) { HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file creation property list"); } - if (H5P_DEFAULT==access_id) { - access_parms = &H5F_access_dflt; - } else if (H5P_FILE_ACCESS!=H5P_get_class (access_id) || - NULL == (access_parms = H5I_object(access_id))) { + if (H5P_DEFAULT!=fapl_id && + (H5P_FILE_ACCESS!=H5P_get_class(fapl_id) || + NULL==H5I_object(fapl_id))) { HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); } @@ -1367,23 +1251,18 @@ H5Fcreate(const char *filename, unsigned flags, hid_t create_id, /* * Create a new file or truncate an existing file. */ - if (NULL == (new_file = H5F_open(filename, flags, create_parms, - access_parms))) { + if (NULL==(new_file=H5F_open(filename, flags, fcpl_id, fapl_id))) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file"); } /* Get an atom for the file */ - if ((ret_value = H5I_register(H5I_FILE, new_file)) < 0) { + if ((ret_value = H5I_register(H5I_FILE, new_file))<0) { HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file"); } done: - if (ret_value < 0 && new_file) { - /* Error condition cleanup */ - H5F_close(new_file); - } - + if (ret_value<0 && new_file) H5F_close(new_file); FUNC_LEAVE(ret_value); } @@ -1408,35 +1287,34 @@ H5Fcreate(const char *filename, unsigned flags, hid_t create_id, * Programmer: Unknown * * Modifications: - * - * Robb Matzke, 18 Jul 1997 - * File struct creation and destruction is through H5F_new() and - * H5F_dest(). Reading the root symbol table entry is done with - * H5G_decode(). + * Robb Matzke, 1997-07-18 + * File struct creation and destruction is through H5F_new() and + * H5F_dest(). Reading the root symbol table entry is done with + * H5G_decode(). * - * Robb Matzke, 23 Sep 1997 - * Most of the work is now done by H5F_open() since H5Fcreate() and - * H5Fopen() originally contained almost identical code. - * - * Robb Matzke, 18 Feb 1998 - * Added better error checking for the flags and the file access - * property list. It used to be possible to make the library dump core - * by passing an object ID that was not a file access property list. + * Robb Matzke, 1997-09-23 + * Most of the work is now done by H5F_open() since H5Fcreate() + * and H5Fopen() originally contained almost identical code. + * + * Robb Matzke, 1998-02-18 + * Added better error checking for the flags and the file access + * property list. It used to be possible to make the library + * dump core by passing an object ID that was not a file access + * property list. * + * Robb Matzke, 1999-08-02 + * The file access property list is passed to the H5F_open() as + * object IDs. *------------------------------------------------------------------------- */ hid_t -H5Fopen(const char *filename, unsigned flags, hid_t access_id) +H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) { - H5F_t *new_file = NULL; /* file struct for new file */ - const H5F_access_t *access_parms; /* pointer to the file access - * parameters to use when - * creating the file - */ - hid_t ret_value = FAIL; + H5F_t *new_file = NULL; /*file struct for new file */ + hid_t ret_value = FAIL; /*return value */ FUNC_ENTER(H5Fopen, FAIL); - H5TRACE3("i","sIui",filename,flags,access_id); + H5TRACE3("i","sIui",filename,flags,fapl_id); /* Check/fix arguments. */ if (!filename || !*filename) { @@ -1446,31 +1324,26 @@ H5Fopen(const char *filename, unsigned flags, hid_t access_id) (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL)) { HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags"); } - if (H5P_DEFAULT==access_id) { - access_parms = &H5F_access_dflt; - } else if (H5P_FILE_ACCESS!=H5P_get_class (access_id) || - NULL == (access_parms = H5I_object(access_id))) { + if (H5P_DEFAULT!=fapl_id && + (H5P_FILE_ACCESS!=H5P_get_class(fapl_id) || + NULL==H5I_object(fapl_id))) { HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); } /* Open the file */ - if (NULL==(new_file=H5F_open(filename, flags, NULL, access_parms))) { + if (NULL==(new_file=H5F_open(filename, flags, H5P_DEFAULT, fapl_id))) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file"); } /* Get an atom for the file */ - if ((ret_value = H5I_register(H5I_FILE, new_file)) < 0) { + if ((ret_value = H5I_register(H5I_FILE, new_file))<0) { HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle"); } done: - if (ret_value < 0 && new_file) { - H5F_close(new_file); - } - /* Normal function cleanup */ - + if (ret_value<0 && new_file) H5F_close(new_file); FUNC_LEAVE(ret_value); } @@ -1565,7 +1438,7 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) } /* Flush the file */ - if (H5F_flush(f, scope, FALSE)<0) { + if (H5F_flush(f, scope, FALSE, FALSE)<0) { HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "flush failed"); } @@ -1581,10 +1454,6 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) * file boot block. If the logical file size field is zero * then it is updated to be the length of the boot block. * - * Errors: - * CACHE CANTFLUSH Can't flush cache. - * IO WRITEERROR Can't write header. - * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke @@ -1592,7 +1461,8 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) * Aug 29 1997 * * Modifications: - * rky 980828 Only p0 writes metadata to disk. + * rky 1998-08-28 + * Only p0 writes metadata to disk. * * Robb Matzke, 1998-10-16 * Added the `scope' argument to indicate what should be @@ -1602,13 +1472,17 @@ 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 + * 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. *------------------------------------------------------------------------- */ static herr_t -H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate) +H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, + hbool_t alloc_only) { uint8_t buf[2048], *p = buf; - uintn firsttime_bootblock=0; uintn nerrors=0, i; FUNC_ENTER(H5F_flush, FAIL); @@ -1630,20 +1504,20 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate) } if (H5F_SCOPE_DOWN==scope) { for (i=0; i<f->mtab.nmounts; i++) { - if (H5F_flush(f->mtab.child[i].file, scope, invalidate)<0) { + if (H5F_flush(f->mtab.child[i].file, scope, invalidate, FALSE)<0) { nerrors++; } } } /* flush the entire raw data cache */ - if (H5F_istore_flush (f, invalidate)<0) { + if (!alloc_only && H5F_istore_flush (f, invalidate)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush raw data cache"); } /* flush (and invalidate) the entire meta data cache */ - if (H5AC_flush(f, NULL, H5F_ADDR_UNDEF, invalidate) < 0) { + if (!alloc_only && H5AC_flush(f, NULL, HADDR_UNDEF, invalidate)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush meta data cache"); } @@ -1651,57 +1525,52 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate) /* encode the file boot block */ HDmemcpy(p, H5F_SIGNATURE, H5F_SIGNATURE_LEN); p += H5F_SIGNATURE_LEN; - - *p++ = f->shared->create_parms->bootblock_ver; - *p++ = f->shared->create_parms->freespace_ver; - *p++ = f->shared->create_parms->objectdir_ver; + *p++ = f->shared->fcpl->bootblock_ver; + *p++ = f->shared->fcpl->freespace_ver; + *p++ = f->shared->fcpl->objectdir_ver; *p++ = 0; /*reserved*/ - *p++ = f->shared->create_parms->sharedheader_ver; + *p++ = f->shared->fcpl->sharedheader_ver; assert (H5F_SIZEOF_ADDR(f)<=255); *p++ = (uint8_t)H5F_SIZEOF_ADDR(f); assert (H5F_SIZEOF_SIZE(f)<=255); *p++ = (uint8_t)H5F_SIZEOF_SIZE(f); *p++ = 0; /*reserved */ - UINT16ENCODE(p, f->shared->create_parms->sym_leaf_k); - UINT16ENCODE(p, f->shared->create_parms->btree_k[H5B_SNODE_ID]); + UINT16ENCODE(p, f->shared->fcpl->sym_leaf_k); + UINT16ENCODE(p, f->shared->fcpl->btree_k[H5B_SNODE_ID]); UINT32ENCODE(p, f->shared->consist_flags); H5F_addr_encode(f, &p, f->shared->base_addr); H5F_addr_encode(f, &p, f->shared->freespace_addr); - H5F_addr_encode(f, &p, f->shared->hdf5_eof); - H5F_addr_encode(f, &p, H5F_ADDR_UNDEF); + H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf)); + H5F_addr_encode(f, &p, HADDR_UNDEF); H5G_ent_encode(f, &p, H5G_entof(f->shared->root_grp)); - /* update file length if necessary */ - if (!H5F_addr_defined(f->shared->hdf5_eof)) { - haddr_t t_addr; /*temporary address */ - - /* Set the HDF5 file size */ - f->shared->hdf5_eof = (hsize_t)(p-buf); - - /* Set the logical file size, including the userblock data */ - t_addr = f->shared->hdf5_eof + f->shared->base_addr; - H5F_low_seteof(f->shared->lf, t_addr); - - /* Indicate that the boot block needs to be flushed out */ - firsttime_bootblock=1; - } - - /* write the boot block to disk */ - if(!firsttime_bootblock) { + /* + * 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. + */ + 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) { + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, + "unable to allocate file space for userblock " + "and/or superblock"); + } + } else { #ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame(f->shared->lf, TRUE); /* only p0 will write */ + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/ #endif - if (H5F_low_write(f->shared->lf, f->shared->access_parms, - &H5F_xfer_dflt, f->shared->boot_addr, - (size_t)(p-buf), buf)<0) { + if (H5FD_write(f->shared->lf, H5P_DEFAULT, f->shared->boot_addr, + p-buf, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "unable to write header"); + "unable to write superblock"); } - - /* Flush file buffers to disk */ - if (H5F_low_flush(f->shared->lf, f->shared->access_parms) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed"); - } + } + + /* Flush file buffers to disk */ + if (!alloc_only && H5FD_flush(f->shared->lf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed"); } /* Check flush errors for children - errors are already on the stack */ @@ -1733,12 +1602,13 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate) * Tuesday, September 23, 1997 * * Modifications: + * Robb Matzke, 1998-10-14 + * Nothing happens unless the H5F_t reference count is one (the + * file is flushed anyway). The reference count is decremented + * by H5F_dest(). * - * Robb Matzke, 1998-10-14 - * Nothing happens unless the H5F_t reference count is one (the - * file is flushed anyway). The reference count is decremented by - * H5F_dest(). - * + * Robb Matzke, 1999-08-02 + * Modified to use the virtual file layer. *------------------------------------------------------------------------- */ herr_t @@ -1754,7 +1624,7 @@ H5F_close(H5F_t *f) * count, flush the file, and return. */ if (f->nrefs>1) { - if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE)<0) { + if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE, FALSE)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); } @@ -1781,7 +1651,7 @@ H5F_close(H5F_t *f) * H5I_FILE_CLOSING list instead. */ if (f->nopen_objs>0) { - if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE)<0) { + if (H5F_flush(f, H5F_SCOPE_LOCAL, FALSE, FALSE)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); } @@ -1814,7 +1684,7 @@ H5F_close(H5F_t *f) assert(1==f->nrefs); if (1==f->shared->nrefs) { /* Flush and destroy all caches */ - if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE)<0) { + if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE, FALSE)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); } @@ -1824,14 +1694,14 @@ H5F_close(H5F_t *f) H5F_istore_stats(f, FALSE); /* Close files and release resources */ - H5F_low_close(f->shared->lf, f->shared->access_parms); + H5FD_close(f->shared->lf); } else { /* * Flush all caches but do not destroy. As long as all handles for * this file are closed the flush isn't really necessary, but lets * just be safe. */ - if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE)<0) { + if (H5F_flush(f, H5F_SCOPE_LOCAL, TRUE, FALSE)<0) { HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache"); } @@ -1843,8 +1713,7 @@ H5F_close(H5F_t *f) * struct reaches zero then destroy it also. */ if (H5F_dest(f)<0) { - HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, - "problems closing file"); + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file"); } FUNC_LEAVE(SUCCEED); } @@ -2323,7 +2192,7 @@ H5Freopen(hid_t file_id) NULL==(old_file=H5I_object(file_id))) { HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file"); } - if (NULL==(new_file=H5F_new(old_file->shared, NULL, NULL))) { + if (NULL==(new_file=H5F_new(old_file->shared, H5P_DEFAULT, H5P_DEFAULT))) { HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file"); } if ((ret_value=H5I_register(H5I_FILE, new_file))<0) { @@ -2361,26 +2230,31 @@ H5Freopen(hid_t file_id) * * Robb Matzke, 1999-07-28 * The ADDR argument is passed by value. + * + * Robb Matzke, 1999-08-02 + * Modified to use the virtual file layer. The data transfer + * property list is passed in by object ID since that's how the + * virtual file layer needs it. *------------------------------------------------------------------------- */ herr_t -H5F_block_read(H5F_t *f, haddr_t addr, hsize_t size, - const H5F_xfer_t *xfer_parms, void *buf) +H5F_block_read(H5F_t *f, haddr_t addr, hsize_t size, hid_t dxpl_id, + void *buf/*out*/) { haddr_t abs_addr; FUNC_ENTER(H5F_block_read, FAIL); - assert (size < SIZET_MAX); + assert(size<SIZET_MAX); /* convert the relative address to an absolute address */ abs_addr = f->shared->base_addr + addr; /* Read the data */ - if (H5F_low_read(f->shared->lf, f->shared->access_parms, xfer_parms, - abs_addr, (size_t)size, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "low-level read failed"); + if (H5FD_read(f->shared->lf, dxpl_id, abs_addr, size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed"); } + FUNC_LEAVE(SUCCEED); } @@ -2407,19 +2281,24 @@ H5F_block_read(H5F_t *f, haddr_t addr, hsize_t size, * * Robb Matzke, 1999-07-28 * The ADDR argument is passed by value. + * + * Robb Matzke, 1999-08-02 + * Modified to use the virtual file layer. The data transfer + * property list is passed in by object ID since that's how the + * virtual file layer needs it. *------------------------------------------------------------------------- */ herr_t -H5F_block_write(H5F_t *f, haddr_t addr, hsize_t size, - const H5F_xfer_t *xfer_parms, const void *buf) +H5F_block_write(H5F_t *f, haddr_t addr, hsize_t size, hid_t dxpl_id, + const void *buf) { haddr_t abs_addr; FUNC_ENTER(H5F_block_write, FAIL); - assert (size < SIZET_MAX); + assert (size<SIZET_MAX); - if (0 == (f->intent & H5F_ACC_RDWR)) { + if (0==(f->intent & H5F_ACC_RDWR)) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "no write intent"); } @@ -2427,13 +2306,138 @@ H5F_block_write(H5F_t *f, haddr_t addr, hsize_t size, abs_addr = f->shared->base_addr + addr; /* Write the data */ - if (H5F_low_write(f->shared->lf, f->shared->access_parms, xfer_parms, - abs_addr, (size_t)size, buf)) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low-level write failed"); + if (H5FD_write(f->shared->lf, dxpl_id, abs_addr, size, buf)) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed"); } FUNC_LEAVE(SUCCEED); } + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_encode + * + * Purpose: Encodes an address into the buffer pointed to by *PP and + * then increments the pointer to the first byte after the + * address. An undefined value is stored as all 1's. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + * Modifications: + * Robb Matzke, 1999-07-28 + * The ADDR argument is passed by value. + *------------------------------------------------------------------------- + */ +void +H5F_addr_encode(H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) +{ + uintn i; + haddr_t tmp; + + assert(f); + assert(pp && *pp); + + if (H5F_addr_defined(addr)) { + tmp = addr; + for (i=0; i<H5F_SIZEOF_ADDR(f); i++) { + *(*pp)++ = (uint8_t)(tmp & 0xff); + tmp >>= 8; + } + assert("overflow" && 0 == tmp); + + } else { + for (i=0; i<H5F_SIZEOF_ADDR(f); i++) { + *(*pp)++ = 0xff; + } + } +} + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_decode + * + * Purpose: Decodes an address from the buffer pointed to by *PP and + * updates the pointer to point to the next byte after the + * address. + * + * If the value read is all 1's then the address is returned + * with an undefined value. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_decode(H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +{ + uintn i; + haddr_t tmp; + uint8_t c; + hbool_t all_zero = TRUE; + + assert(f); + assert(pp && *pp); + assert(addr_p); + + *addr_p = 0; + + for (i=0; i<H5F_SIZEOF_ADDR(f); i++) { + c = *(*pp)++; + if (c != 0xff) all_zero = FALSE; + + if (i<sizeof(*addr_p)) { + tmp = c; + tmp <<= i * 8; /*use tmp to get casting right */ + *addr_p |= tmp; + } else if (!all_zero) { + assert(0 == **pp); /*overflow */ + } + } + if (all_zero) *addr_p = HADDR_UNDEF; +} + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_pack + * + * Purpose: Converts a long[2] array (usually returned from + * H5G_get_objinfo) back into a haddr_t + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, October 23, 1998 + * + * Modifications: + * Albert Cheng, 1999-02-18 + * Changed objno to unsigned long type to be consistent with + * addr->offset and how it is being called. + *------------------------------------------------------------------------- + */ +herr_t +H5F_addr_pack(H5F_t UNUSED *f, haddr_t *addr_p/*out*/, + const unsigned long objno[2]) +{ + assert(f); + assert(objno); + assert(addr_p); + + *addr_p = objno[0]; +#if SIZEOF_LONG<SIZEOF_UINT64_T + *addr_p |= ((uint64_t)objno[1]) << (8*sizeof(long)); +#endif + + return(SUCCEED); +} + /*------------------------------------------------------------------------- * Function: H5F_debug @@ -2483,53 +2487,46 @@ H5F_debug(H5F_t *f, haddr_t UNUSED addr, FILE * stream, intn indent, HDfprintf(stream, "%*s%-*s 0x%08lx\n", indent, "", fwidth, "Consistency flags:", (unsigned long) (f->shared->consist_flags)); - HDfprintf(stream, "%*s%-*s %a (abs)\n", indent, "", fwidth, "Address of boot block:", f->shared->boot_addr); - HDfprintf(stream, "%*s%-*s %a (abs)\n", indent, "", fwidth, "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 bytes\n", indent, "", fwidth, - "Total size of hdf5 data:", f->shared->hdf5_eof); - HDfprintf(stream, "%*s%-*s %lu bytes\n", indent, "", fwidth, "Size of user block:", - (unsigned long) (f->shared->create_parms->userblock_size)); + (unsigned long) (f->shared->fcpl->userblock_size)); HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth, "Size of file size_t type:", - (unsigned) (f->shared->create_parms->sizeof_size)); + (unsigned) (f->shared->fcpl->sizeof_size)); HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth, "Size of file haddr_t type:", - (unsigned) (f->shared->create_parms->sizeof_addr)); + (unsigned) (f->shared->fcpl->sizeof_addr)); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Symbol table leaf node 1/2 rank:", - (unsigned) (f->shared->create_parms->sym_leaf_k)); + (unsigned) (f->shared->fcpl->sym_leaf_k)); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Symbol table internal node 1/2 rank:", - (unsigned) (f->shared->create_parms->btree_k[H5B_SNODE_ID])); + (unsigned) (f->shared->fcpl->btree_k[H5B_SNODE_ID])); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Boot block version number:", - (unsigned) (f->shared->create_parms->bootblock_ver)); + (unsigned) (f->shared->fcpl->bootblock_ver)); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Free list version number:", - (unsigned) (f->shared->create_parms->freespace_ver)); + (unsigned) (f->shared->fcpl->freespace_ver)); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Object directory version number:", - (unsigned) (f->shared->create_parms->objectdir_ver)); + (unsigned) (f->shared->fcpl->objectdir_ver)); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Shared header version number:", - (unsigned) (f->shared->create_parms->sharedheader_ver)); + (unsigned) (f->shared->fcpl->sharedheader_ver)); HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Root group symbol table entry:", f->shared->root_grp ? "" : "(none)"); if (f->shared->root_grp) { H5G_ent_debug(f, H5G_entof(f->shared->root_grp), stream, - indent+3, MAX(0, fwidth-3), H5F_ADDR_UNDEF); + indent+3, MAX(0, fwidth-3), HADDR_UNDEF); } FUNC_LEAVE(SUCCEED); } diff --git a/src/H5FD.c b/src/H5FD.c new file mode 100644 index 0000000..e8b13b7 --- /dev/null +++ b/src/H5FD.c @@ -0,0 +1,1642 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, July 26, 1999 + * + * Purpose: The Virtual File Layer as described in documentation. This is + * the greatest common denominator for all types of storage + * access whether a file, memory, network, etc. This layer + * usually just dispatches the request to an actual file driver + * layer. + */ + +/* Packages needed by this file */ +#include <H5private.h> /*library functions */ +#include <H5Eprivate.h> /*error handling */ +#include <H5Fprivate.h> /*files */ +#include <H5FDprivate.h> /*virtual file driver */ +#include <H5Iprivate.h> /*interface abstraction layer */ +#include <H5MMprivate.h> /*memory management */ +#include <H5Pprivate.h> /*property lists */ + +/* Interface initialization */ +#define PABLO_MASK H5FD_mask +#define INTERFACE_INIT H5FD_init_interface +static intn interface_initialize_g = 0; + +/* static prototypes */ +static herr_t H5FD_init_interface(void); +static herr_t H5FD_free_cls(H5FD_class_t *cls); + + +/*------------------------------------------------------------------------- + * Function: H5FD_init_interface + * + * Purpose: Initialize the virtual file layer. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, July 26, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_init_interface(void) +{ + FUNC_ENTER(H5FD_init_interface, FAIL); + + if (H5I_init_group(H5I_VFL, H5I_VFL_HASHSIZE, 0, + (H5I_free_t)H5FD_free_cls)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "unable to initialize interface"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_term_interface + * + * Purpose: Terminate this interface: free all memory and reset global + * variables to their initial values. Release all ID groups + * associated with this interface. + * + * Return: Success: Positive if anything was done that might + * have affected other interfaces; zero + * otherwise. + * + * Failure: Never fails. + * + * Programmer: Robb Matzke + * Friday, February 19, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +intn +H5FD_term_interface(void) +{ + intn n = 0; + + if (interface_initialize_g) { + if ((n=H5I_nmembers(H5I_VFL))) { + H5I_clear_group(H5I_VFL, FALSE); + } else { + H5I_destroy_group(H5I_VFL); + interface_initialize_g = 0; + n = 1; /*H5I*/ + } + } + return n; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_free_cls + * + * Purpose: Frees a file driver class struct and returns an indication of + * success. This function is used as the free callback for the + * virtual file layer object identifiers (cf H5FD_init_interface). + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, July 26, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_free_cls(H5FD_class_t *cls) +{ + FUNC_ENTER(H5FD_free_cls, FAIL); + H5MM_xfree(cls); + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDregister + * + * Purpose: Registers a new file driver as a member of the virtual file + * driver class. Certain fields of the class struct are + * required and that is checked here so it doesn't have to be + * checked every time the field is accessed. + * + * Return: Success: A file driver ID which is good until the + * library is closed or the driver is + * unregistered. + * + * Failure: A negative value. + * + * Programmer: Robb Matzke + * Monday, July 26, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5FDregister(const H5FD_class_t *cls) +{ + hid_t retval; + H5FD_class_t *saved; + H5FD_mem_t type; + + FUNC_ENTER(H5FDregister, FAIL); + H5TRACE1("i","x",cls); + + /* Check arguments */ + if (!cls) { + HRETURN_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, + "null class pointer is disallowed"); + } + if (!cls->open || !cls->close) { + HRETURN_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, + "`open' and/or `close' methods are not defined"); + } + if (!cls->get_eoa || !cls->set_eoa) { + HRETURN_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, + "`get_eoa' and/or `set_eoa' methods are not defined"); + } + if (!cls->get_eof) { + HRETURN_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, + "`get_eof' method is not defined"); + } + if (!cls->read || !cls->write) { + HRETURN_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, + "`read' and/or `write' method is not defined"); + } + for (type=0; type<H5FD_MEM_NTYPES; type++) { + if (cls->fl_map[type]<H5FD_MEM_NOLIST || + cls->fl_map[type]>=H5FD_MEM_NTYPES) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "invalid free-list mapping"); + } + } + + /* Copy the class structure so the caller can reuse or free it */ + if (NULL==(saved=H5MM_malloc(sizeof(H5FD_class_t)))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for file driver class struct"); + } + *saved = *cls; + + /* Create the new class ID */ + if ((retval=H5I_register(H5I_VFL, saved))<0) { + HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, + "unable to register file driver ID"); + } + + FUNC_LEAVE(retval); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDunregister + * + * Purpose: Removes a driver ID from the library. This in no way affects + * file access property lists which have been defined to use + * this driver or files which are already opened under this + * driver. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, July 26, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FDunregister(hid_t driver_id) +{ + FUNC_ENTER(H5FDunregister, FAIL); + H5TRACE1("e","i",driver_id); + + /* Check arguments */ + if (H5I_VFL!=H5I_get_type(driver_id) || + NULL==H5I_object(driver_id)) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file driver"); + } + + /* The H5FD_class_t struct will be freed by this function */ + if (H5I_dec_ref(driver_id)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "unable to unregister file driver"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_fapl_copy + * + * Purpose: Copies the driver-specific part of the file access property + * list. + * + * Return: Success: Pointer to new driver-specific file access + * properties. + * + * Failure: NULL, but also returns null with no error + * pushed onto the error stack if the OLD_FAPL + * is null. + * + * Programmer: Robb Matzke + * Tuesday, August 3, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void * +H5FD_fapl_copy(hid_t driver_id, const void *old_fapl) +{ + void *new_fapl = NULL; + H5FD_class_t *driver=NULL; + + FUNC_ENTER(H5FD_fapl_copy, NULL); + + /* Check args */ + if (H5I_VFL!=H5I_get_type(driver_id) || + NULL==(driver=H5I_object(driver_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a driver ID"); + } + if (!old_fapl) HRETURN(NULL); /*but no error*/ + + /* Allow the driver to copy or do it ourselves */ + if (driver->fapl_copy) { + new_fapl = (driver->fapl_copy)(old_fapl); + } else if (driver->fapl_size>0) { + new_fapl = H5MM_malloc(driver->fapl_size); + HDmemcpy(new_fapl, old_fapl, driver->fapl_size); + } else { + HRETURN_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, + "no way to copy driver file access property list"); + } + + FUNC_LEAVE(new_fapl); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_fapl_free + * + * Purpose: Frees the driver-specific file access property list. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Robb Matzke + * Tuesday, August 3, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_fapl_free(hid_t driver_id, void *fapl) +{ + H5FD_class_t *driver=NULL; + + FUNC_ENTER(H5FD_fapl_free, FAIL); + H5TRACE2("e","ix",driver_id,fapl); + + /* Check args */ + if (H5I_VFL!=H5I_get_type(driver_id) || + NULL==(driver=H5I_object(driver_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID"); + } + + /* Allow driver to free or do it ourselves */ + if (fapl && driver->fapl_free) { + if ((driver->fapl_free)(fapl)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver fapl_free request failed"); + } + } else { + H5MM_xfree(fapl); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_dxpl_copy + * + * Purpose: Copies the driver-specific part of the data transfer property + * list. + * + * Return: Success: Pointer to new driver-specific data transfer + * properties. + * + * Failure: NULL, but also returns null with no error + * pushed onto the error stack if the OLD_DXPL + * is null. + * + * Programmer: Robb Matzke + * Tuesday, August 3, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void * +H5FD_dxpl_copy(hid_t driver_id, const void *old_dxpl) +{ + void *new_dxpl = NULL; + H5FD_class_t *driver=NULL; + + FUNC_ENTER(H5FD_dxpl_copy, NULL); + + /* Check args */ + if (H5I_VFL!=H5I_get_type(driver_id) || + NULL==(driver=H5I_object(driver_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, + "not a driver ID"); + } + if (!old_dxpl) HRETURN(NULL); /*but no error*/ + + /* Allow the driver to copy or do it ourselves */ + if (driver->dxpl_copy) { + new_dxpl = (driver->dxpl_copy)(old_dxpl); + } else if (driver->dxpl_size>0) { + new_dxpl = H5MM_malloc(driver->dxpl_size); + HDmemcpy(new_dxpl, old_dxpl, driver->dxpl_size); + } else { + HRETURN_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, + "no way to copy driver file access property list"); + } + + FUNC_LEAVE(new_dxpl); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_dxpl_free + * + * Purpose: Frees the driver-specific data transfer property list. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Robb Matzke + * Tuesday, August 3, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_dxpl_free(hid_t driver_id, void *dxpl) +{ + H5FD_class_t *driver=NULL; + + FUNC_ENTER(H5FD_dxpl_free, FAIL); + H5TRACE2("e","ix",driver_id,dxpl); + + /* Check args */ + if (H5I_VFL!=H5I_get_type(driver_id) || + NULL==(driver=H5I_object(driver_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID"); + } + + /* Allow driver to free or do it ourselves */ + if (dxpl && driver->dxpl_free) { + if ((driver->dxpl_free)(dxpl)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver dxpl_free request failed"); + } + } else { + H5MM_xfree(dxpl); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDopen + * + * Purpose: Opens a file named NAME for the type(s) of access described + * by the bit vector FLAGS according to a file access property + * list FAPL_ID (which may be the constant H5P_DEFAULT). The + * file should expect to handle format addresses in the range [0, + * MAXADDR] (if MAXADDR is the undefined address then the caller + * doesn't care about the address range). + * + * Possible values for the FLAGS bits are: + * + * H5F_ACC_RDWR: Open the file for read and write access. If + * this bit is not set then open the file for + * read only access. It is permissible to open a + * file for read and write access when only read + * access is requested by the library (the + * library will never attempt to write to a file + * which it opened with only read access). + * + * H5F_ACC_CREATE: Create the file if it doesn't already exist. + * However, see H5F_ACC_EXCL below. + * + * H5F_ACC_TRUNC: Truncate the file if it already exists. This + * is equivalent to deleting the file and then + * creating a new empty file. + * + * H5F_ACC_EXCL: When used with H5F_ACC_CREATE, if the file + * already exists then the open should fail. + * Note that this is unsupported/broken with + * some file drivers (e.g., sec2 across nfs) and + * will contain a race condition when used to + * perform file locking. + * + * The MAXADDR is the maximum address which will be requested by + * the library during an allocation operation. Usually this is + * the same value as the MAXADDR field of the class structure, + * but it can be smaller if the driver is being used under some + * other driver. + * + * Note that when the driver `open' callback gets control that + * the public part of the file struct (the H5FD_t part) will be + * incomplete and will be filled in after that callback returns. + * + * Return: Success: Pointer to a new file driver struct. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Tuesday, July 27, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5FD_t * +H5FDopen(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) +{ + H5FD_t *ret_value=NULL; + + FUNC_ENTER(H5FDopen, NULL); + + if (NULL==(ret_value=H5FD_open(name, flags, fapl_id, maxaddr))) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, NULL, + "unable to open file"); + } + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_open + * + * Purpose: Private version of H5FDopen() + * + * Return: Success: Pointer to a new file driver struct + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5FD_t * +H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) +{ + const H5F_access_t *fapl=NULL; + H5FD_class_t *driver; + H5FD_t *file=NULL; + + FUNC_ENTER(H5FD_open, NULL); + + /* Check arguments */ + if (H5P_DEFAULT==fapl_id) { + fapl = &H5F_access_dflt; + } else if (H5P_FILE_ACCESS != H5P_get_class(fapl_id) || + NULL == (fapl = H5I_object(fapl_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, + "not a file access property list"); + } + if (0==maxaddr) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, + "zero format address range"); + } + + /* Get driver info */ + if (H5I_VFL!=H5I_get_type(fapl->driver_id) || + NULL==(driver=H5I_object(fapl->driver_id))) { + HRETURN_ERROR(H5E_VFL, H5E_BADVALUE, NULL, + "invalid driver ID in file access property list"); + } + if (NULL==driver->open) { + HRETURN_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, + "file driver has no `open' method"); + } + + /* Dispatch to file driver */ + if (HADDR_UNDEF==maxaddr) maxaddr = driver->maxaddr; + if (NULL==(file=(driver->open)(name, flags, fapl_id, maxaddr))) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed"); + } + + /* + * Fill in public fields. We must increment the reference count on the + * driver ID to prevent it from being freed while this file is open. + */ + file->driver_id = fapl->driver_id; + H5I_inc_ref(file->driver_id); + file->cls = driver; + file->maxaddr = maxaddr; + HDmemset(file->fl, 0, sizeof(file->fl)); + + FUNC_LEAVE(file); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDclose + * + * Purpose: Closes the file by calling the driver `close' callback, which + * should free all driver-private data and free the file struct. + * Note that the public part of the file struct (the H5FD_t part) + * will be all zero during the driver close callback like during + * the `open' callback. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Tuesday, July 27, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FDclose(H5FD_t *file) +{ + FUNC_ENTER(H5FDclose, FAIL); + H5TRACE1("e","x",file); + + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + } + + if (H5FD_close(file)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to close file"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_close + * + * Purpose: Private version of H5FDclose() + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_close(H5FD_t *file) +{ + const H5FD_class_t *driver; + H5FD_free_t *cur, *next; + H5FD_mem_t i; +#ifdef H5F_DEBUG + uintn nblocks=0; + hsize_t nbytes=0; +#endif + + FUNC_ENTER(H5FD_close, FAIL); + assert(file && file->cls); + + /* Free all free-lists, leaking any memory thus described */ + for (i=0; i<H5FD_MEM_NTYPES; i++) { + for (cur=file->fl[i]; cur; cur=next) { +#ifdef H5F_DEBUG + nblocks++; + nbytes += cur->size; +#endif + next = cur->next; + H5MM_xfree(cur); + } + file->fl[i]=NULL; + } +#ifdef H5F_DEBUG + if (nblocks && H5DEBUG(F)) { + fprintf(H5DEBUG(F), + "H5F: leaked %lu bytes of file memory in %u blocks\n", + (unsigned long)nbytes, nblocks); + } +#endif + + /* Prepare to close file by clearing all public fields */ + driver = file->cls; + H5I_dec_ref(file->driver_id); + HDmemset(file, 0, sizeof(H5FD_t)); + + /* + * Dispatch to the driver for actual close. If the driver fails to + * close the file then the file will be in an unusable state. + */ + assert(driver->close); + if ((driver->close)(file)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "close failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDcmp + * + * Purpose: Compare the keys of two files using the file driver callback + * if the files belong to the same driver, otherwise sort the + * files by driver class pointer value. + * + * Return: Success: A value like strcmp() + * + * Failure: Must never fail. If both file handles are + * invalid then they compare equal. If one file + * handle is invalid then it compares less than + * the other. If both files belong to the same + * driver and the driver doesn't provide a + * comparison callback then the file pointers + * themselves are compared. + * + * Programmer: Robb Matzke + * Tuesday, July 27, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5FDcmp(const H5FD_t *f1, const H5FD_t *f2) +{ + intn ret_value; + + FUNC_ENTER(H5FDcmp, -1); /*return value is arbitrary*/ + H5TRACE2("Is","xx",f1,f2); + + ret_value = H5FD_cmp(f1, f2); + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_cmp + * + * Purpose: Private version of H5FDcmp() + * + * Return: Success: A value like strcmp() + * + * Failure: Must never fail. + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2) +{ + intn ret_value; + + FUNC_ENTER(H5FD_cmp, -1); /*return value is arbitrary*/ + + if ((!f1 || !f1->cls) && (!f2 || !f2->cls)) return 0; + if (!f1 || !f1->cls) return -1; + if (!f2 || !f2->cls) return 1; + if (f1->cls < f2->cls) return -1; + if (f1->cls > f2->cls) return 1; + + /* Files are same driver; no cmp callback */ + if (!f1->cls->cmp) { + if (f1<f2) return -1; + if (f1>f2) return 1; + return 0; + } + + ret_value = (f1->cls->cmp)(f1, f2); + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDalloc + * + * Purpose: Allocates SIZE bytes of memory from the FILE. The memory will + * be used according to the allocation class TYPE. First we try + * to satisfy the request from one of the free lists, according + * to the free list map provided by the driver. The free list + * array has one entry for each request type and the value of + * that array element can be one of four possibilities: + * + * It can be the constant H5FD_MEM_DEFAULT (or zero) which + * indicates that the identity mapping is used. In other + * words, the request type maps to its own free list. + * + * It can be the request type itself, which has the same + * effect as the H5FD_MEM_DEFAULT value above. + * + * It can be the ID for another request type, which + * indicates that the free list for the specified type + * should be used instead. + * + * It can be the constant H5FD_MEM_NOLIST which means that + * no free list should be used for this type of request. + * + * If the request cannot be satisfied from a free list then + * either the driver's `alloc' callback is invoked (if one was + * supplied) or the end-of-address marker is extended. The + * `alloc' callback is always called with the same arguments as + * the H5FDalloc(). + * + * Return: Success: The format address of the new file memory. + * + * Failure: The undefined address HADDR_UNDEF + * + * Programmer: Robb Matzke + * Tuesday, July 27, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5FDalloc(H5FD_t *file, H5FD_mem_t type, hsize_t size) +{ + haddr_t ret_value = HADDR_UNDEF; + + FUNC_ENTER(H5FDalloc, HADDR_UNDEF); + H5TRACE3("a","xMth",file,type,size); + + /* Check args */ + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, + "invalid file pointer"); + } + if (type<0 || type>=H5FD_MEM_NTYPES) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, + "invalid request type"); + } + if (size<=0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, + "zero-size request"); + } + + /* Do the real work */ + if (HADDR_UNDEF==(ret_value=H5FD_alloc(file, type, size))) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, + "unable to allocate file memory"); + } + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_alloc + * + * Purpose: Private version of H5FDalloc() + * + * Return: Success: The format address of the new file memory. + * + * Failure: The undefined address HADDR_UNDEF + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size) +{ + haddr_t ret_value = HADDR_UNDEF; + H5FD_mem_t mapped_type; + + FUNC_ENTER(H5FD_alloc, HADDR_UNDEF); + + /* Check args */ + assert(file && file->cls); + assert(type>=0 && type<H5FD_MEM_NTYPES); + assert(size>0); + + /* Map the allocation request to a free list */ + if (H5FD_MEM_DEFAULT==file->cls->fl_map[type]) { + mapped_type = type; + } else { + mapped_type = file->cls->fl_map[type]; + } + + /* + * Try to satisfy the request from the free list. First try to find an + * exact match, otherwise use the best match. + */ + if (mapped_type>=0) { + H5FD_free_t *prev=NULL, *best=NULL; + H5FD_free_t *cur = file->fl[mapped_type]; + while (cur) { + if (cur->size==size) { + ret_value = cur->addr; + if (prev) prev->next = cur->next; + else file->fl[mapped_type] = cur->next; + H5MM_xfree(cur); + HRETURN(ret_value); + } else if (cur->size>size && + (!best || cur->size<best->size)) { + best = cur; + } + prev = cur; + cur = cur->next; + } + if (best) { + ret_value = best->addr; + best->addr += size; + best->size -= size; + HRETURN(ret_value); + } + } + + /* + * Dispatch to driver `alloc' callback or extend the end-of-address + * marker + */ + if (file->cls->alloc) { + ret_value = (file->cls->alloc)(file, type, size); + if (HADDR_UNDEF==ret_value) { + HRETURN_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, + "driver allocation request failed"); + } + } else { + haddr_t eoa = (file->cls->get_eoa)(file); + if (H5F_addr_overflow(eoa, size) || eoa+size>file->maxaddr) { + HRETURN_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, + "file allocation request failed"); + } + ret_value = eoa; + eoa += size; + if ((file->cls->set_eoa)(file, eoa)<0) { + HRETURN_ERROR(H5E_VFL, H5E_NOSPACE, HADDR_UNDEF, + "file allocation request failed"); + } + } + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDfree + * + * Purpose: Frees format addresses starting with ADDR and continuing for + * SIZE bytes in the file FILE. The type of space being freed is + * specified by TYPE, which is mapped to a free list as + * described for the H5FDalloc() function above. If the request + * doesn't map to a free list then either the application `free' + * callback is invoked (if defined) or the memory is leaked. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, July 28, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FDfree(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size) +{ + FUNC_ENTER(H5FDfree, FAIL); + H5TRACE4("e","xMtah",file,type,addr,size); + + /* Check args */ + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + } + if (type<0 || type>=H5FD_MEM_NTYPES) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid request type"); + } + + /* Do the real work */ + if (H5FD_free(file, type, addr, size)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "file deallocation request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_free + * + * Purpose: Private version of H5FDfree() + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_free(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size) +{ + H5FD_mem_t mapped_type; + + FUNC_ENTER(H5FD_free, FAIL); + + /* Check args */ + assert(file && file->cls); + assert(type>=0 && type<H5FD_MEM_NTYPES); + if (!H5F_addr_defined(addr) || addr>file->maxaddr || 0==size || + H5F_addr_overflow(addr, size) || addr+size>file->maxaddr) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid region"); + } + + /* Map request type to free list */ + if (H5FD_MEM_DEFAULT==file->cls->fl_map[type]) { + mapped_type = type; + } else { + mapped_type = file->cls->fl_map[type]; + } + + /* + * If the request maps to a free list then add memory to the free list + * without ever telling the driver that it was freed. Otherwise let the + * driver deallocate the memory. + */ + if (mapped_type>=0) { + H5FD_free_t *cur = H5MM_malloc(sizeof(H5FD_free_t)); + cur->addr = addr; + cur->size = size; + cur->next = file->fl[mapped_type]; + file->fl[mapped_type] = cur; + } else if (file->cls->free) { + if ((file->cls->free)(file, type, addr, size)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver free request failed"); + } + } else { + /* leak memory */ + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDrealloc + * + * Purpose: Changes the size of an allocated chunk of memory, possibly + * also changing its location in the file. + * + * Return: Success: New address of the block of memory, not + * necessarily the same as the original address. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Tuesday, August 3, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5FDrealloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size, + hsize_t new_size) +{ + haddr_t ret_value=HADDR_UNDEF; + + FUNC_ENTER(H5FDrealloc, HADDR_UNDEF); + H5TRACE5("a","xMtahh",file,type,old_addr,old_size,new_size); + + if (HADDR_UNDEF==(ret_value=H5FD_realloc(file, type, old_addr, old_size, + new_size))) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, + "file reallocation request failed"); + } + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_realloc + * + * Purpose: Private version of H5FDrealloc() + * + * Return: Success: New address of the block of memory, not + * necessarily the same as the original address. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5FD_realloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size, + hsize_t new_size) +{ + haddr_t new_addr=old_addr; + uint8_t _buf[8192]; + uint8_t *buf=_buf; + + FUNC_ENTER(H5FD_realloc, HADDR_UNDEF); + + if (new_size==old_size) { + /*nothing to do*/ + + } else if (0==old_size) { + /* allocate memory */ + assert(!H5F_addr_defined(old_addr)); + if (HADDR_UNDEF==(new_addr=H5FDalloc(file, type, new_size))) { + HRETURN_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, + "file allocation failed"); + } + + } else if (0==new_size) { + /* free memory */ + assert(H5F_addr_defined(old_addr)); + H5FDfree(file, type, old_addr, old_size); + new_addr = HADDR_UNDEF; + + } else if (new_size<old_size) { + /* free the end of the block */ + H5FDfree(file, type, old_addr+old_size, old_size-new_size); + + } else { + /* move memory to new location */ + if (HADDR_UNDEF==(new_addr=H5FDalloc(file, type, new_size))) { + HRETURN_ERROR(H5E_FILE, H5E_NOSPACE, HADDR_UNDEF, + "file allocation failed"); + } + if (old_size>sizeof(_buf) && NULL==(buf=H5MM_malloc(old_size))) { + H5FDfree(file, type, new_addr, new_size); + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, + "memory allocation failed"); + } + if (H5FDread(file, H5P_DEFAULT, old_addr, old_size, buf)<0 || + H5FDwrite(file, H5P_DEFAULT, new_addr, old_size, buf)) { + H5FDfree(file, type, new_addr, new_size); + H5MM_xfree(buf); + HRETURN_ERROR(H5E_FILE, H5E_READERROR, HADDR_UNDEF, + "unable to move file block"); + } + + if (buf!=_buf) H5MM_xfree(buf); + H5FDfree(file, type, old_addr, old_size); + } + + FUNC_LEAVE(new_addr); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDget_eoa + * + * Purpose: Returns the address of the first byte after the last + * allocated memory in the file. + * + * Return: Success: First byte after allocated memory. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Friday, July 30, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5FDget_eoa(H5FD_t *file) +{ + haddr_t addr; + + FUNC_ENTER(H5FDget_eoa, HADDR_UNDEF); + H5TRACE1("a","x",file); + + /* Check args */ + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, + "invalid file pointer"); + } + + /* The real work */ + if (HADDR_UNDEF==(addr=H5FD_get_eoa(file))) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, + "file get eoa request failed"); + } + + FUNC_LEAVE(addr); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_get_eoa + * + * Purpose: Private version of H5FDget_eoa() + * + * Return: Success: First byte after allocated memory. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5FD_get_eoa(H5FD_t *file) +{ + haddr_t addr; + + FUNC_ENTER(H5FD_get_eoa, HADDR_UNDEF); + assert(file && file->cls); + + /* Dispatch to driver */ + if (HADDR_UNDEF==(addr=(file->cls->get_eoa)(file))) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, + "driver get_eoa request failed"); + } + + FUNC_LEAVE(addr); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDset_eoa + * + * Purpose: Set the end-of-address marker for the file. The ADDR is the + * address of the first byte past the last allocated byte of the + * file. This function is called from two places: + * + * It is called after an existing file is opened in order to + * "allocate" enough space to read the superblock and then + * to "allocate" the entire hdf5 file based on the contents + * of the superblock. + * + * It is called during file memory allocation if the + * allocation request cannot be satisfied from the free list + * and the driver didn't supply an allocation callback. + * + * Return: Success: Non-negative + * + * Failure: Negative, no side effect + * + * Programmer: Robb Matzke + * Friday, July 30, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FDset_eoa(H5FD_t *file, haddr_t addr) +{ + FUNC_ENTER(H5FDset_eoa, FAIL); + H5TRACE2("e","xa",file,addr); + + /* Check args */ + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + } + if (!H5F_addr_defined(addr) || addr>file->maxaddr) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "invalid end-of-address value"); + } + + /* The real work */ + if (H5FD_set_eoa(file, addr)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "file set eoa request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_set_eoa + * + * Purpose: Private version of H5FDset_eoa() + * + * Return: Success: Non-negative + * + * Failure: Negative, no side effect + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_set_eoa(H5FD_t *file, haddr_t addr) +{ + FUNC_ENTER(H5FD_set_eoa, FAIL); + assert(file && file->cls); + assert(H5F_addr_defined(addr) && addr<=file->maxaddr); + + /* Dispatch to driver */ + if ((file->cls->set_eoa)(file, addr)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver set_eoa request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDget_eof + * + * Purpose: Returns the end-of-file address, which is the greater of the + * end-of-format address and the actual EOF marker. This + * function is called after an existing file is opened in order + * for the library to learn the true size of the underlying file + * and to determine whether the hdf5 data has been truncated. + * + * It is also used when a file is first opened to learn whether + * the file is empty or not. + * + * It is permissible for the driver to return the maximum address + * for the file size if the file is not empty. + * + * Return: Success: The EOF address. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5FDget_eof(H5FD_t *file) +{ + haddr_t addr; + + FUNC_ENTER(H5FDget_eof, HADDR_UNDEF); + H5TRACE1("a","x",file); + + /* Check arguments */ + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, + "invalid file pointer"); + } + + /* The real work */ + if (HADDR_UNDEF==(addr=H5FD_get_eof(file))) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, + "file get eof request failed"); + } + + FUNC_LEAVE(addr); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_get_eof + * + * Purpose: Private version of H5FDget_eof() + * + * Return: Success: The EOF address. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +haddr_t +H5FD_get_eof(H5FD_t *file) +{ + haddr_t addr=HADDR_UNDEF; + + FUNC_ENTER(H5FD_get_eof, HADDR_UNDEF); + assert(file && file->cls); + + /* Dispatch to driver */ + if (file->cls->get_eof) { + if (HADDR_UNDEF==(addr=(file->cls->get_eof)(file))) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, + "driver get_eof request failed"); + } + } else { + addr = file->maxaddr; + } + + FUNC_LEAVE(addr); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDread + * + * Purpose: Reads SIZE bytes from FILE beginning at address ADDR + * according to the data transfer property list DXPL_ID (which may + * be the constant H5P_DEFAULT). The result is written into the + * buffer BUF. + * + * Return: Success: Non-negative. The read result is written into + * the BUF buffer which should be allocated by + * the caller. + * + * Failure: Negative. The contents of BUF is undefined. + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FDread(H5FD_t *file, hid_t dxpl_id, haddr_t addr, hsize_t size, + void *buf/*out*/) +{ + FUNC_ENTER(H5FDread, FAIL); + H5TRACE5("e","xiahx",file,dxpl_id,addr,size,buf); + + /* Check args */ + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + } + if (H5P_DEFAULT!=dxpl_id && + (H5P_DATA_XFER!=H5P_get_class(dxpl_id) || + NULL==H5I_object(dxpl_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a data transfer property list"); + } + if (!buf) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null result buffer"); + } + + /* Do the real work */ + if (H5FD_read(file, dxpl_id, addr, size, buf)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file read request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_read + * + * Purpose: Private version of H5FDread() + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_read(H5FD_t *file, hid_t dxpl_id, haddr_t addr, hsize_t size, + void *buf/*out*/) +{ + FUNC_ENTER(H5FD_read, FAIL); + assert(file && file->cls); + assert(H5P_DEFAULT==dxpl_id || + (H5P_DATA_XFER==H5P_get_class(dxpl_id) || H5I_object(dxpl_id))); + assert(buf); + + /* The no-op case */ + if (0==size) HRETURN(SUCCEED); + + /* Dispatch to driver */ + if ((file->cls->read)(file, dxpl_id, addr, size, buf)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver read request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDwrite + * + * Purpose: Writes SIZE bytes to FILE beginning at address ADDR according + * to the data transfer property list DXPL_ID (which may be the + * constant H5P_DEFAULT). The bytes to be written come from the + * buffer BUF. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FDwrite(H5FD_t *file, hid_t dxpl_id, haddr_t addr, hsize_t size, + const void *buf) +{ + FUNC_ENTER(H5FDwrite, FAIL); + H5TRACE5("e","xiahx",file,dxpl_id,addr,size,buf); + + /* Check args */ + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + } + if (H5P_DEFAULT!=dxpl_id && + (H5P_DATA_XFER!=H5P_get_class(dxpl_id) || + NULL==H5I_object(dxpl_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a data transfer property list"); + } + if (!buf) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null buffer"); + } + + /* The real work */ + if (H5FD_write(file, dxpl_id, addr, size, buf)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "file write request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_write + * + * Purpose: Private version of H5FDwrite() + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_write(H5FD_t *file, hid_t dxpl_id, haddr_t addr, hsize_t size, + const void *buf) +{ + FUNC_ENTER(H5FD_write, FAIL); + assert(file && file->cls); + assert(H5P_DEFAULT==dxpl_id || + (H5P_DATA_XFER==H5P_get_class(dxpl_id) && H5I_object(dxpl_id))); + assert(buf); + + /* The no-op case */ + if (0==size) HRETURN(SUCCEED); + + /* Dispatch to driver */ + if ((file->cls->write)(file, dxpl_id, addr, size, buf)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver write request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FDflush + * + * Purpose: Notify driver to flush all cached data. If the driver has no + * flush method then nothing happens. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FDflush(H5FD_t *file) +{ + FUNC_ENTER(H5FDflush, FAIL); + H5TRACE1("e","x",file); + + /* Check args */ + if (!file || !file->cls) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer"); + } + + /* Do the real work */ + if (H5FD_flush(file)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "file flush request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_flush + * + * Purpose: Private version of H5FDflush() + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_flush(H5FD_t *file) +{ + FUNC_ENTER(H5FD_flush, FAIL); + assert(file && file->cls); + + if (file->cls->flush && + (file->cls->flush)(file)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver flush request failed"); + } + + FUNC_LEAVE(SUCCEED); +} diff --git a/src/H5FDcore.c b/src/H5FDcore.c new file mode 100644 index 0000000..4be868e --- /dev/null +++ b/src/H5FDcore.c @@ -0,0 +1,491 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Tuesday, August 10, 1999 + * + * Purpose: A driver which stores the HDF5 data in main memory using + * only the HDF5 public API. This driver is useful for fast + * access to small, temporary hdf5 files. + */ +#include <assert.h> +#include <hdf5.h> +#include <stdlib.h> + +#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_CORE_g = 0; + +/* + * The description of a file belonging to this driver. The `eoa' and `eof' + * determine the amount of hdf5 address space in use and the high-water mark + * of the file (the current size of the underlying memory). + */ +typedef struct H5FD_core_t { + H5FD_t pub; /*public stuff, must be first */ + char *name; /*for equivalence testing */ + unsigned char *mem; /*the underlying memory */ + haddr_t eoa; /*end of allocated region */ + haddr_t eof; /*current allocated size */ + size_t increment; /*multiples for mem allocation */ +} H5FD_core_t; + +/* Driver-specific file access properties */ +typedef struct H5FD_core_fapl_t { + size_t increment; /*how much to grow memory */ +} H5FD_core_fapl_t; + +/* Allocate memory in multiples of this size by default */ +#define H5FD_CORE_INCREMENT 8192 + +/* + * These macros check for overflow of various quantities. These macros + * assume that file_offset_t is signed and haddr_t and size_t are unsigned. + * + * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' + * is too large to be represented by the second argument + * of the file seek function. + * + * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too + * large to be represented by the `size_t' type. + * + * REGION_OVERFLOW: Checks whether an address and size pair describe data + * which can be addressed entirely in memory. + */ +#define MAXADDR ((haddr_t)~(size_t)0) +#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ + ((A) & ~(haddr_t)MAXADDR)) +#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) +#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ + HADDR_UNDEF==(A)+(Z) || \ + (size_t)((A)+(Z))<(size_t)(A)) + +/* Prototypes */ +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); +static int H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2); +static haddr_t H5FD_core_get_eoa(H5FD_t *_file); +static herr_t H5FD_core_set_eoa(H5FD_t *_file, haddr_t addr); +static haddr_t H5FD_core_get_eof(H5FD_t *_file); +static herr_t H5FD_core_read(H5FD_t *_file, hid_t fapl_id, haddr_t addr, + hsize_t size, void *buf); +static herr_t H5FD_core_write(H5FD_t *_file, hid_t fapl_id, haddr_t addr, + hsize_t size, const void *buf); + +static const H5FD_class_t H5FD_core_g = { + "core", /*name */ + MAXADDR, /*maxaddr */ + sizeof(H5FD_core_fapl_t), /*fapl_size */ + NULL, /*fapl_copy */ + NULL, /*fapl_free */ + 0, /*dxpl_size */ + NULL, /*dxpl_copy */ + NULL, /*dxpl_free */ + H5FD_core_open, /*open */ + H5FD_core_close, /*close */ + H5FD_core_cmp, /*cmp */ + NULL, /*alloc */ + NULL, /*free */ + H5FD_core_get_eoa, /*get_eoa */ + H5FD_core_set_eoa, /*set_eoa */ + H5FD_core_get_eof, /*get_eof */ + H5FD_core_read, /*read */ + H5FD_core_write, /*write */ + NULL, /*flush */ + H5FD_FLMAP_SINGLE, /*fl_map */ +}; + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_init + * + * Purpose: Initialize this driver by registering the driver with the + * library. + * + * Return: Success: The driver ID for the core driver. + * + * Failure: Negative. + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5FD_core_init(void) +{ + if (!H5FD_CORE_g) { + H5FD_CORE_g = H5FDregister(&H5FD_core_g); + } + return H5FD_CORE_g; +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_core + * + * Purpose: Modify the file access property list to use the H5FD_CORE + * driver defined in this source file. The INCREMENT specifies + * how much to grow the memory each time we need more. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, February 19, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_core(hid_t fapl_id, size_t increment) +{ + H5FD_core_fapl_t fa; + + /*NO TRACE*/ + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; + fa.increment = increment; + return H5Pset_driver(fapl_id, H5FD_CORE, &fa); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_fapl_core + * + * Purpose: Queries properties set by the H5Pset_fapl_core() function. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Tuesday, August 10, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_fapl_core(hid_t fapl_id, size_t *increment/*out*/) +{ + H5FD_core_fapl_t *fa; + + /*NO TRACE*/ + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; + if (H5FD_CORE!=H5Pget_driver(fapl_id)) return -1; + if (NULL==(fa=H5Pget_driver_info(fapl_id))) return -1; + if (increment) *increment = fa->increment; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_open + * + * Purpose: Create memory as an 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 + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5FD_t * +H5FD_core_open(const char *name, unsigned flags/*unused*/, hid_t fapl_id, + haddr_t maxaddr) +{ + H5FD_core_t *file=NULL; + H5FD_core_fapl_t *fa=NULL; + + /* Check arguments */ + if (0==maxaddr || HADDR_UNDEF==maxaddr) return NULL; + if (ADDR_OVERFLOW(maxaddr)) return NULL; + if (H5P_DEFAULT!=fapl_id) fa = H5Pget_driver_info(fapl_id); + + /* Create the new file struct */ + file = calloc(1, sizeof(H5FD_core_t)); + if (name && *name) { + file->name = malloc(strlen(name)+1); + strcpy(file->name, name); + } + + /* + * The increment comes from either the file access property list or the + * default value. But if the file access property list was zero then use + * the default value instead. + */ + file->increment = (fa && fa->increment>0) ? + fa->increment : H5FD_CORE_INCREMENT; + + return (H5FD_t*)file; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_close + * + * Purpose: Closes the file. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_core_close(H5FD_t *_file) +{ + H5FD_core_t *file = (H5FD_core_t*)_file; + + if (file->name) free(file->name); + if (file->mem) free(file->mem); + memset(file, 0, sizeof(H5FD_core_t)); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_cmp + * + * Purpose: Compares two files belonging to this driver by name. If one + * file doesn't have a name then it is less than the other file. + * If neither file has a name then the comparison is by file + * address. + * + * Return: Success: A value like strcmp() + * + * Failure: never fails (arguments were checked by the + * caller). + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5FD_core_cmp(const H5FD_t *_f1, const H5FD_t *_f2) +{ + const H5FD_core_t *f1 = (const H5FD_core_t*)_f1; + const H5FD_core_t *f2 = (const H5FD_core_t*)_f2; + + if (NULL==f1->name && NULL==f2->name) { + if (f1<f2) return -1; + if (f1>f2) return 1; + return 0; + } + + if (NULL==f1->name) return -1; + if (NULL==f2->name) return 1; + + return strcmp(f1->name, f2->name); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_get_eoa + * + * Purpose: Gets 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 + * Monday, August 2, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_core_get_eoa(H5FD_t *_file) +{ + H5FD_core_t *file = (H5FD_core_t*)_file; + return file->eoa; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_set_eoa + * + * Purpose: Set the end-of-address marker for the file. This function is + * called shortly after an existing HDF5 file is opened in order + * to tell the driver where the end of the HDF5 data is located. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_core_set_eoa(H5FD_t *_file, haddr_t addr) +{ + H5FD_core_t *file = (H5FD_core_t*)_file; + if (ADDR_OVERFLOW(addr)) return -1; + file->eoa = addr; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_get_eof + * + * Purpose: Returns the end-of-file marker, which is the greater of + * either the size of the underlying memory or the HDF5 + * end-of-address markers. + * + * Return: Success: End of file address, the first address past + * the end of the "file", either the memory + * or the HDF5 file. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_core_get_eof(H5FD_t *_file) +{ + H5FD_core_t *file = (H5FD_core_t*)_file; + return MAX(file->eof, file->eoa); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_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 + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_core_read(H5FD_t *_file, hid_t dxpl_id/*unused*/, haddr_t addr, + hsize_t size, void *buf/*out*/) +{ + H5FD_core_t *file = (H5FD_core_t*)_file; + ssize_t nbytes; + + assert(file && file->pub.cls); + assert(buf); + + /* Check for overflow conditions */ + if (HADDR_UNDEF==addr) return -1; + if (REGION_OVERFLOW(addr, size)) return -1; + if (addr+size>file->eoa) return -1; + + /* Read the part which is before the EOF marker */ + if (addr<file->eof) { + nbytes = MIN(size, file->eof-addr); + memcpy(buf, file->mem+addr, nbytes); + size -= nbytes; + addr += nbytes; + (char*)buf += nbytes; + } + + /* Read zeros for the part which is after the EOF markers */ + if (size>0) { + memset(buf, 0, size); + } + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_core_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 + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_core_write(H5FD_t *_file, hid_t dxpl_id/*unused*/, haddr_t addr, + hsize_t size, const void *buf) +{ + H5FD_core_t *file = (H5FD_core_t*)_file; + + assert(file && file->pub.cls); + assert(buf); + + /* Check for overflow conditions */ + if (REGION_OVERFLOW(addr, size)) return -1; + if (addr+size>file->eoa) return -1; + + /* + * Allocate more memory if necessary, careful of overflow. Also, if the + * allocation fails then the file should remain in a usable state. Be + * careful of non-Posix realloc() that doesn't understand what to do when + * the first argument is null. + */ + if (addr+size>file->eof) { + unsigned char *x; + size_t new_eof = file->increment * ((addr+size)/file->increment); + if ((addr+size) % file->increment) new_eof += file->increment; + if (NULL==file->mem) x = malloc(new_eof); + else x = realloc(file->mem, new_eof); + if (!x) return -1; + file->mem = x; + file->eof = new_eof; + } + + /* Write from BUF to memory */ + memcpy(file->mem+addr, buf, size); + return 0; +} diff --git a/src/H5FDcore.h b/src/H5FDcore.h new file mode 100644 index 0000000..fa3cb140 --- /dev/null +++ b/src/H5FDcore.h @@ -0,0 +1,21 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, August 2, 1999 + * + * Purpose: The public header file for the sec2 driver. + */ +#ifndef H5FDcore_H +#define H5FDcore_H + +#include <H5Ipublic.h> + +#define H5FD_CORE (H5FD_core_init()) + +hid_t H5FD_core_init(void); +herr_t H5Pset_fapl_core(hid_t fapl_id, size_t increment); +herr_t H5Pget_fapl_core(hid_t fapl_id, size_t *increment/*out*/); + +#endif diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c new file mode 100644 index 0000000..bf46efc --- /dev/null +++ b/src/H5FDfamily.c @@ -0,0 +1,777 @@ +/* + * Copyright (C) 1997 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, November 10, 1997 + * + * Purpose: Implements a family of files that acts as a single hdf5 + * file. The purpose is to be able to split a huge file on a + * 64-bit platform, transfer all the <2GB members to a 32-bit + * platform, and then access the entire huge file on the 32-bit + * platform. + * + * All family members are logically the same size although their + * physical sizes may vary. The logical member size is + * determined by looking at the physical size of the first member + * when the file is opened. When creating a file family, the + * first member is created with a predefined physical size + * (actually, this happens when the file family is flushed, and + * can be quite time consuming on file systems that don't + * implement holes, like nfs). + * + */ +#include <assert.h> +#include <hdf5.h> +#include <stdlib.h> + +#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_FAMILY_g = 0; + +/* The description of a file belonging to this driver. */ +typedef struct H5FD_family_t { + H5FD_t pub; /*public stuff, must be first */ + hid_t memb_fapl_id; /*file access property list for members */ + hsize_t memb_size; /*maximum size of each member file */ + int nmembs; /*number of family members */ + int amembs; /*number of member slots allocated */ + H5FD_t **memb; /*dynamic array of member pointers */ + haddr_t eoa; /*end of allocated addresses */ + char *name; /*name generator printf format */ + unsigned flags; /*flags for opening additional members */ +} H5FD_family_t; + +/* Driver-specific file access properties */ +typedef struct H5FD_family_fapl_t { + hsize_t memb_size; /*size of each member */ + hid_t memb_fapl_id; /*file access property list of each memb*/ +} H5FD_family_fapl_t; + +/* Driver specific data transfer properties */ +typedef struct H5FD_family_dxpl_t { + hid_t memb_dxpl_id; /*data xfer property list of each memb */ +} H5FD_family_dxpl_t; + +/* Callback prototypes */ +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); +static herr_t H5FD_family_dxpl_free(void *_dx); +static H5FD_t *H5FD_family_open(const char *name, unsigned flags, + hid_t fapl_id, haddr_t maxaddr); +static herr_t H5FD_family_close(H5FD_t *_file); +static int H5FD_family_cmp(const H5FD_t *_f1, const H5FD_t *_f2); +static haddr_t H5FD_family_get_eoa(H5FD_t *_file); +static herr_t H5FD_family_set_eoa(H5FD_t *_file, haddr_t eoa); +static haddr_t H5FD_family_get_eof(H5FD_t *_file); +static herr_t H5FD_family_read(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, + hsize_t size, void *_buf/*out*/); +static herr_t H5FD_family_write(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, + hsize_t size, const void *_buf); +static herr_t H5FD_family_flush(H5FD_t *_file); + +/* The class struct */ +static const H5FD_class_t H5FD_family_g = { + "family", /*name */ + HADDR_MAX, /*maxaddr */ + sizeof(H5FD_family_fapl_t), /*fapl_size */ + H5FD_family_fapl_copy, /*fapl_copy */ + H5FD_family_fapl_free, /*fapl_free */ + sizeof(H5FD_family_dxpl_t), /*dxpl_size */ + H5FD_family_dxpl_copy, /*dxpl_copy */ + H5FD_family_dxpl_free, /*dxpl_free */ + H5FD_family_open, /*open */ + H5FD_family_close, /*close */ + H5FD_family_cmp, /*cmp */ + NULL, /*alloc */ + NULL, /*free */ + H5FD_family_get_eoa, /*get_eoa */ + H5FD_family_set_eoa, /*set_eoa */ + H5FD_family_get_eof, /*get_eof */ + H5FD_family_read, /*read */ + H5FD_family_write, /*write */ + H5FD_family_flush, /*flush */ + H5FD_FLMAP_SINGLE, /*fl_map */ +}; + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_init + * + * Purpose: Initialize this driver by registering the driver with the + * library. + * + * Return: Success: The driver ID for the family driver. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5FD_family_init(void) +{ + if (!H5FD_FAMILY_g) { + H5FD_FAMILY_g = H5FDregister(&H5FD_family_g); + } + return H5FD_FAMILY_g; +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_family + * + * Purpose: Sets the file access property list FAPL_ID to use the family + * driver. The MEMB_SIZE is the size in bytes of each file + * member (used only when creating a new file) and the + * MEMB_FAPL_ID is a file access property list to be used for + * each family member. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_family(hid_t fapl_id, hsize_t memb_size, hid_t memb_fapl_id) +{ + H5FD_family_fapl_t fa; + + /*NO TRACE*/ + + /* Check arguments */ + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; + if (H5P_DEFAULT!=memb_fapl_id && + H5P_FILE_ACCESS!=H5Pget_class(memb_fapl_id)) return -1; + + /* Initialize driver specific information */ + fa.memb_size = memb_size; + fa.memb_fapl_id = memb_fapl_id; + return H5Pset_driver(fapl_id, H5FD_FAMILY, &fa); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_fapl_family + * + * Purpose: Returns information about the family file access property + * list though the function arguments. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_fapl_family(hid_t fapl_id, hsize_t *memb_size/*out*/, + hid_t *memb_fapl_id/*out*/) +{ + H5FD_family_fapl_t *fa; + + /*NO TRACE*/ + + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; + if (H5FD_FAMILY!=H5Pget_driver(fapl_id)) return -1; + if (NULL==(fa=H5Pget_driver_info(fapl_id))) return -1; + if (memb_size) *memb_size = fa->memb_size; + if (memb_fapl_id) *memb_fapl_id = H5Pcopy(fa->memb_fapl_id); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_fapl_copy + * + * Purpose: Copies the family-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_family_fapl_copy(const void *_old_fa) +{ + const H5FD_family_fapl_t *old_fa = (const H5FD_family_fapl_t*)_old_fa; + H5FD_family_fapl_t *new_fa = malloc(sizeof(H5FD_family_fapl_t)); + assert(new_fa); + + memcpy(new_fa, old_fa, sizeof(H5FD_family_fapl_t)); + new_fa->memb_fapl_id = H5Pcopy(old_fa->memb_fapl_id); + return new_fa; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_fapl_free + * + * Purpose: Frees the family-specific file access properties. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_family_fapl_free(void *_fa) +{ + H5FD_family_fapl_t *fa = (H5FD_family_fapl_t*)_fa; + H5Pclose(fa->memb_fapl_id); + free(fa); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_dxpl_copy + * + * Purpose: Copes the family-specific data transfer properties. + * + * Return: Success: Ptr to new property list + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_family_dxpl_copy(const void *_old_dx) +{ + const H5FD_family_dxpl_t *old_dx = (const H5FD_family_dxpl_t*)_old_dx; + H5FD_family_dxpl_t *new_dx = malloc(sizeof(H5FD_family_dxpl_t)); + assert(new_dx); + + memcpy(new_dx, old_dx, sizeof(H5FD_family_dxpl_t)); + new_dx->memb_dxpl_id = H5Pcopy(old_dx->memb_dxpl_id); + return new_dx; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_dxpl_free + * + * Purpose: Frees the family-specific data transfer properties. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_family_dxpl_free(void *_dx) +{ + H5FD_family_dxpl_t *dx = (H5FD_family_dxpl_t*)_dx; + H5Pclose(dx->memb_dxpl_id); + free(dx); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_open + * + * Purpose: Creates and/or opens a family of files as an HDF5 file. + * + * Return: Success: A pointer to a new file dat 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_family_open(const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr) +{ + H5FD_family_t *file=NULL; + char memb_name[4096], temp[4096]; + hsize_t eof; + unsigned t_flags = flags & ~H5F_ACC_CREAT; + + /* Check arguments */ + if (!name || !*name) return NULL; + if (0==maxaddr || HADDR_UNDEF==maxaddr) return NULL; + + /* Initialize file from file access properties */ + if (NULL==(file=calloc(1, sizeof(H5FD_family_t)))) return NULL; + if (H5P_DEFAULT==fapl_id) { + file->memb_fapl_id = H5P_DEFAULT; + 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_size = fa->memb_size; + } + file->name = malloc(strlen(name)+1); + strcpy(file->name, name); + file->flags = flags; + + /* Check that names are unique */ + sprintf(memb_name, name, 0); + sprintf(temp, name, 1); + if (!strcmp(memb_name, temp)) return NULL; + + /* Open all the family members */ + while (1) { + sprintf(memb_name, name, file->nmembs); + + /* Enlarge member array */ + if (file->nmembs>=file->amembs) { + int n = MAX(64, 2*file->amembs); + H5FD_t **x = realloc(file->memb, n*sizeof(H5FD_t*)); + if (!x) goto error; + file->amembs = n; + file->memb = x; + } + + /* + * Attempt to open file. If the first file cannot be opened then fail; + * otherwise an open failure means that we've reached the last member. + * Allow H5F_ACC_CREAT only on the first family member. + */ + H5E_BEGIN_TRY { + file->memb[file->nmembs] = H5FDopen(memb_name, + 0==file->nmembs?flags:t_flags, + file->memb_fapl_id, + HADDR_UNDEF); + } H5E_END_TRY; + if (!file->memb[file->nmembs]) { + if (0==file->nmembs) goto error; + H5Eclear(); + break; + } + file->nmembs++; + } + + /* + * The size of the first member determines the size of all the members, + * but if the size of the first member is zero then use the member size + * from the file access property list. + */ + if ((eof=H5FDget_eof(file->memb[0]))) file->memb_size = eof; + + return (H5FD_t*)file; + + error: + /* Cleanup and fail */ + if (file) { + int i; + for (i=0; i<file->nmembs; i++) { + if (file->memb[i]) H5FDclose(file->memb[i]); + } + free(file); + } + return NULL; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_close + * + * Purpose: Closes a family of files. + * + * 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_family_close(H5FD_t *_file) +{ + H5FD_family_t *file = (H5FD_family_t*)_file; + int i, nerrors=0; + + /* Close as many members as possible */ + for (i=0; i<file->nmembs; i++) { + if (file->memb[i]) { + if (H5FDclose(file->memb[i])<0) { + nerrors++; + } else { + file->memb[i] = NULL; + } + } + } + if (nerrors) return -1; + + /* Clean up other stuff */ + H5Pclose(file->memb_fapl_id); + free(file->memb); + free(file->name); + free(file); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_cmp + * + * Purpose: Compares two file families to see if they are the same. It + * does this by comparing the first member of the two families. + * + * Return: Success: like strcmp() + * + * Failure: never fails (arguments were checked by the + * caller). + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5FD_family_cmp(const H5FD_t *_f1, const H5FD_t *_f2) +{ + const H5FD_family_t *f1 = (const H5FD_family_t*)_f1; + const H5FD_family_t *f2 = (const H5FD_family_t*)_f2; + + assert(f1->nmembs>=1 && f1->memb[0]); + assert(f2->nmembs>=1 && f2->memb[0]); + + + return H5FDcmp(f1->memb[0], f2->memb[0]); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_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_family_get_eoa(H5FD_t *_file) +{ + H5FD_family_t *file = (H5FD_family_t*)_file; + return file->eoa; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_set_eoa + * + * Purpose: Set the end-of-address marker for the file. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_family_set_eoa(H5FD_t *_file, haddr_t eoa) +{ + H5FD_family_t *file = (H5FD_family_t*)_file; + haddr_t addr=eoa; + int i; + char memb_name[4096]; + + for (i=0; addr || i<file->nmembs; i++) { + + /* Enlarge member array */ + if (i>=file->amembs) { + int n = MAX(64, 2*file->amembs); + H5FD_t **x = realloc(file->memb, n*sizeof(H5FD_t*)); + if (!x) return -1; + file->amembs = n; + file->memb = x; + file->nmembs = i; + } + + /* Create another file if necessary */ + if (i>=file->nmembs || !file->memb[i]) { + file->nmembs = MAX(file->nmembs, i+1); + sprintf(memb_name, file->name, i); + H5E_BEGIN_TRY { + file->memb[i] = H5FDopen(memb_name, file->flags|H5F_ACC_CREAT, + file->memb_fapl_id, file->memb_size); + } H5E_END_TRY; + if (NULL==file->memb[i]) return -1; + } + + /* Set the EOA marker for the member */ + if (addr>file->memb_size) { + H5FDset_eoa(file->memb[i], file->memb_size); + addr -= file->memb_size; + } else { + H5FDset_eoa(file->memb[i], addr); + addr = 0; + } + } + + file->eoa = eoa; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_get_eof + * + * Purpose: Returns the end-of-file marker, which is the greater of + * either the total family size or the current EOA marker. + * + * Return: Success: End of file address, the first address past + * the end of the family of files or the current + * EOA, whichever is larger. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_family_get_eof(H5FD_t *_file) +{ + H5FD_family_t *file = (H5FD_family_t*)_file; + haddr_t eof; + int i; + + /* + * Find the last member that has a non-zero EOF and break out of the loop + * with `i' equal to that member. If all members have zero EOF then exit + * loop with i==0. + */ + for (i=file->nmembs-1; i>=0; --i) { + if ((eof=H5FDget_eof(file->memb[i]))) break; + if (0==i) break; + } + + /* + * The file size is the number of members before the i'th member plus the + * size of the i'th member. + */ + eof += i*file->memb_size; + return MAX(eof, file->eoa); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_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_family_read(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, hsize_t size, + void *_buf/*out*/) +{ + H5FD_family_t *file = (H5FD_family_t*)_file; + unsigned char *buf = (unsigned char*)_buf; + hid_t memb_dxpl_id = H5P_DEFAULT; + int i; + haddr_t sub; + hsize_t req; + + /* + * Get the member data transfer property list. If the transfer property + * list does not belong to this driver then assume defaults + */ + if (H5P_DEFAULT!=dxpl_id && H5FD_FAMILY==H5Pget_driver(dxpl_id)) { + H5FD_family_dxpl_t *dx = H5Pget_driver_info(dxpl_id); + assert(H5P_DATA_XFER==H5Pget_class(dxpl_id)); + assert(dx); + memb_dxpl_id = dx->memb_dxpl_id; + } + + /* Read from each member */ + while (size>0) { + i = addr / file->memb_size; + sub = addr % file->memb_size; + req = MIN(size, file->memb_size-sub); + assert(i<file->nmembs); + + if (H5FDread(file->memb[i], memb_dxpl_id, sub, req, buf)<0) { + return -1; + } + + addr += req; + buf += req; + size -= req; + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_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_family_write(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, hsize_t size, + const void *_buf) +{ + H5FD_family_t *file = (H5FD_family_t*)_file; + const unsigned char *buf = (const unsigned char*)_buf; + hid_t memb_dxpl_id = H5P_DEFAULT; + int i; + haddr_t sub; + hsize_t req; + + /* + * Get the member data transfer property list. If the transfer property + * list does not belong to this driver then assume defaults. + */ + if (H5P_DEFAULT!=dxpl_id && H5FD_FAMILY==H5Pget_driver(dxpl_id)) { + H5FD_family_dxpl_t *dx = H5Pget_driver_info(dxpl_id); + assert(H5P_DATA_XFER==H5Pget_class(dxpl_id)); + assert(dx); + memb_dxpl_id = dx->memb_dxpl_id; + } + + /* Write to each member */ + while (size>0) { + i = addr / file->memb_size; + sub = addr % file->memb_size; + req = MIN(size, file->memb_size-sub); + assert(i<file->nmembs); + + if (H5FDwrite(file->memb[i], memb_dxpl_id, sub, req, buf)<0) { + return -1; + } + + addr += req; + buf += req; + size -= req; + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_family_flush + * + * Purpose: Flushes all family members. + * + * Return: Success: 0 + * + * Failure: -1, as many files flushed as possible. + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_family_flush(H5FD_t *_file) +{ + H5FD_family_t *file = (H5FD_family_t*)_file; + int i, nerrors=0; + + for (i=0; i<file->nmembs; i++) { + if (file->memb[i] && H5FDflush(file->memb[i])<0) { + nerrors++; + } + } + + return nerrors?-1:0; +} diff --git a/src/H5FDfamily.h b/src/H5FDfamily.h new file mode 100644 index 0000000..a02230e --- /dev/null +++ b/src/H5FDfamily.h @@ -0,0 +1,23 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, August 4, 1999 + * + * Purpose: The public header file for the family driver. + */ +#ifndef H5FDfamily_H +#define H5FDfamily_H + +#include <H5Ipublic.h> + +#define H5FD_FAMILY (H5FD_family_init()) + +hid_t H5FD_family_init(void); +herr_t H5Pset_fapl_family(hid_t fapl_id, hsize_t memb_size, + hid_t memb_fapl_id); +herr_t H5Pget_fapl_family(hid_t fapl_id, hsize_t *memb_size/*out*/, + hid_t *memb_fapl_id/*out*/); + +#endif diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c new file mode 100644 index 0000000..ca9ce12 --- /dev/null +++ b/src/H5FDmpio.c @@ -0,0 +1,1367 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Thursday, July 29, 1999 + * + * Purpose: This is the MPI-2 I/O driver. + * + * Limitations: + * H5FD_mpio_read & H5FD_mpio_write + * Eventually these should choose collective or independent i/o + * based on a parameter that is passed down to it from H5Dwrite, + * rather than the access_parms (which are fixed at the open). + * + * H5FD_mpio_read + * One implementation of MPI/MPI-IO causes MPI_Get_count + * to return (incorrectly) a negative count. I (who?) added code + * to detect this, and a kludge to pretend that the number of + * bytes read is always equal to the number requested. This + * kluge is activated by #ifdef MPI_KLUGE0202. + */ +#include <assert.h> +#include <hdf5.h> +#include <stdlib.h> + +/* + * The driver identification number, initialized at runtime if HAVE_PARALLEL + * is defined. This allows applications to still have the H5FD_MPIO + * "constants" in their source code (it also makes this file strictly ANSI + * compliant when HAVE_PARALLEL isn't defined) + */ +static hid_t H5FD_MPIO_g = 0; + +#ifdef HAVE_PARALLEL + +#define FALSE 0 +#define TRUE 1 + +/* + * The description of a file belonging to this driver. If the ALLSAME + * argument is set during a write operation then only p0 will do the actual + * write (this assumes all procs would write the same data). The EOF value + * is only used just after the file is opened in order for the library to + * determine whether the file is empty, truncated, or okay. The MPIO driver + * doesn't bother to keep it updated since it's an expensive operation. + */ +typedef struct H5FD_mpio_t { + H5FD_t pub; /*public stuff, must be first */ + MPI_File f; /*MPIO file handle */ + MPI_Comm comm; /*communicator */ + MPI_Info info; /*file information */ + hbool_t allsame; /*same data for all procs? */ + haddr_t eof; /*end-of-file marker */ + haddr_t eoa; /*end-of-address marker */ + MPI_Datatype btype; /*buffer type for xfers */ + MPI_Datatype ftype; /*file type for xfers */ + haddr_t disp; /*displacement for set_view in xfers */ + int use_types; /*if !0, use btype, ftype, disp.else do + * simple byteblk xfer + */ + int old_use_types; /*remember value of use_types */ +} H5FD_mpio_t; + +/* Prototypes */ +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 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); +static haddr_t H5FD_mpio_get_eoa(H5FD_t *_file); +static herr_t H5FD_mpio_set_eoa(H5FD_t *_file, haddr_t addr); +static haddr_t H5FD_mpio_get_eof(H5FD_t *_file); +static herr_t H5FD_mpio_read(H5FD_t *_file, hid_t fapl_id, haddr_t addr, + hsize_t size, void *buf); +static herr_t H5FD_mpio_write(H5FD_t *_file, hid_t fapl_id, haddr_t addr, + hsize_t size, const void *buf); +static herr_t H5FD_mpio_flush(H5FD_t *_file); + +/* MPIO-specific file access properties */ +typedef struct H5FD_mpio_fapl_t { + MPI_Comm comm; /*communicator */ + MPI_Info info; /*file information */ +} H5FD_mpio_fapl_t; + +/* The MPIO file driver information */ +static const H5FD_class_t H5FD_mpio_g = { + "mpio", /*name */ + HADDR_MAX, /*maxaddr */ + sizeof(H5FD_mpio_fapl_t), /*fapl_size */ + NULL, /*fapl_copy */ + NULL, /*fapl_free */ + sizeof(H5FD_mpio_dxpl_t), /*dxpl_size */ + NULL, /*dxpl_copy */ + NULL, /*dxpl_free */ + H5FD_mpio_open, /*open */ + H5FD_mpio_close, /*close */ + NULL, /*cmp */ + NULL, /*alloc */ + NULL, /*free */ + H5FD_mpio_get_eoa, /*get_eoa */ + H5FD_mpio_set_eoa, /*set_eoa */ + H5FD_mpio_get_eof, /*get_eof */ + H5FD_mpio_read, /*read */ + H5FD_mpio_write, /*write */ + H5FD_mpio_flush, /*flush */ + H5FD_FLMAP_SINGLE, /*fl_map */ +}; + +#ifdef H5FDmpio_DEBUG +/* Flags to control debug actions in H5Fmpio. + * Meant to be indexed by characters. + * + * 'c' show result of MPI_Get_count after read + * 'r' show read offset and size + * 't' trace function entry and exit + * 'w' show write offset and size + */ +static int H5FD_mpio_Debug[256] = + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; +#endif + +/* Global var to allow elimination of redundant metadata writes + * to be controlled by the value of an environment variable. */ +/* Use the elimination by default unless this is the Intel Red machine */ +#ifndef __PUMAGON__ +hbool_t H5_mpi_1_metawrite_g = TRUE; +#else +hbool_t H5_mpi_1_metawrite_g = FALSE; +#endif + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_init + * + * Purpose: Initialize this driver by registering the driver with the + * library. + * + * Return: Success: The driver ID for the mpio driver. + * + * Failure: Negative. + * + * Programmer: Robb Matzke + * Thursday, August 5, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5FD_mpio_init(void) +{ + if (!H5FD_MPIO_g) { + H5FD_MPIO_g = H5FDregister(&H5FD_mpio_g); + +#if 1 + /* + * To be removed after Albert proof reads this driver. + * --rpm 1999-08-06 + */ + fprintf(stderr, "\ +H5FD_MPIO: this driver is currently under construction and may\n\ + not work as advertised. Please use hdf5-1.3.? if you need a\n\ + more stable development version (or use the hdf5-1.2.x release\n\ + version).\n"); +#endif + } + return H5FD_MPIO_g; +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_mpio + * + * Purpose: Store the user supplied MPIO communicator COMM and INFO in + * the file access property list FAPL_ID which can then be used + * to create and/or open the file. This function is available + * only in the parallel HDF5 library and is not a collective + * function. + * + * COMM is the MPI communicator to be used for file open as + * defined in MPI_FILE_OPEN of MPI-2. This function does not + * make a duplicated communicator. Any modification to COMM + * after this function call returns may have undetermined effect + * on the access property list. Users should not modify the + * communicator while it is defined in a property list. + * + * INFO is the MPI info object to be used for file open as + * defined in MPI_FILE_OPEN of MPI-2. This function does not + * make a duplicated info. Any modification to info after this + * function call returns may have undetermined effect on the + * access property list. Users should not modify the info while + * it is defined in a property list. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Albert Cheng + * Feb 3, 1998 + * + * Modifications: + * Robb Matzke, 1998-02-18 + * Check all arguments before the property list is updated so we + * don't leave the property list in a bad state if something + * goes wrong. Also, the property list data type changed to + * allow more generality so all the mpi-related stuff is in the + * `u.mpi' member. The `access_mode' will contain only + * mpi-related flags defined in H5Fpublic.h. + * + * Albert Cheng, 1998-04-16 + * Removed the ACCESS_MODE argument. The access mode is changed + * to be controlled by data transfer property list during data + * read/write calls. + * + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info) +{ + H5FD_mpio_fapl_t fa; + + /*NO TRACE*/ + + /* Check arguments */ + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; +#ifdef LATER +#warning "We need to verify that COMM and INFO contain sensible information." +#endif + + /* Initialize driver specific properties */ + fa.comm = comm; + fa.info = info; + return H5Pset_driver(fapl_id, H5FD_MPIO, &fa); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_fapl_mpio + * + * Purpose: If the file access property list is set to the H5FD_MPIO + * driver then this function returns the MPI communicator and + * information through the COMM and INFO pointers. + * + * Return: Success: Non-negative with the communicator and + * information returned through the COMM and + * INFO arguments if non-null. Neither piece of + * information is copied and they are therefore + * valid only until the file access property + * list is modified or closed. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Thursday, February 26, 1998 + * + * Modifications: + * + * Albert Cheng, Apr 16, 1998 + * Removed the access_mode argument. The access_mode is changed + * to be controlled by data transfer property list during data + * read/write calls. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_fapl_mpio(hid_t fapl_id, MPI_Comm *comm/*out*/, MPI_Info *info/*out*/) +{ + H5FD_mpio_fapl_t *fa; + + /*NO TRACE*/ + + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; + if (H5FD_MPIO!=H5Pget_driver(fapl_id)) return -1; + if (NULL==(fa=H5Pget_driver_info(fapl_id))) return -1; + + if (comm) *comm = fa->comm; + if (info) *info = fa->info; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_dxpl_mpio + * + * Purpose: Set the data transfer property list DXPL_ID to use transfer + * mode XFER_MODE. The property list can then be used to control + * the I/O transfer mode during data I/O operations. The valid + * transfer modes are: + * + * H5FD_MPIO_INDEPENDENT: + * Use independent I/O access (the default). + * + * H5FD_MPIO_COLLECTIVE: + * Use collective I/O access. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Albert Cheng + * April 2, 1998 + * + * Modifications: + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t xfer_mode) +{ + H5FD_mpio_dxpl_t dx; + + /*NO TRACE*/ + + /* Check arguments */ + if (H5P_DATA_XFER!=H5Pget_class(dxpl_id)) return -1; + if (H5FD_MPIO_INDEPENDENT!=xfer_mode && + H5FD_MPIO_COLLECTIVE!=xfer_mode) return -1; + + /* Initialize driver-specific properties */ + dx.xfer_mode = xfer_mode; + return H5Pset_driver(dxpl_id, H5FD_MPIO, &dx); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_dxpl_mpio + * + * Purpose: Queries the transfer mode current set in the data transfer + * property list DXPL_ID. This is not a collective function. + * + * Return: Success: Non-negative, with the transfer mode returned + * through the XFER_MODE argument if it is + * non-null. + * + * Failure: Negative + * + * Programmer: Albert Cheng + * April 2, 1998 + * + * Modifications: + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t *xfer_mode/*out*/) +{ + H5FD_mpio_dxpl_t *dx; + + /*NO TRACE*/ + + if (H5P_DATA_XFER!=H5Pget_class(dxpl_id)) return -1; + if (H5FD_MPIO!=H5Pget_driver(dxpl_id)) return -1; + if (NULL==(dx=H5Pget_driver_info(dxpl_id))) return -1; + + if (xfer_mode) *xfer_mode = dx->xfer_mode; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_tas_allsame + * + * Purpose: Test and set the allsame parameter. + * + * Return: Success: the old value of the allsame flag + * + * Failure: assert fails if access_parms is NULL. + * + * Programmer: rky 980828 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5FD_mpio_tas_allsame(H5FD_t *_file, hbool_t newval) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + hbool_t oldval; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Entering H5FD_mpio_tas_allsame, newval=%d\n", newval); +#endif + + assert(file); + oldval = file->allsame; + file->allsame = newval; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Leaving H5FD_mpio_tas_allsame, oldval=%d\n", oldval); +#endif + + return oldval; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_communicator + * + * Purpose: Returns the MPI communicator for the file. + * + * Return: Success: The communicator + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Monday, August 9, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +MPI_Comm +H5FD_mpio_communicator(H5FD_t *_file) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + return file->comm; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_setup + * + * Purpose: Set the buffer type BTYPE, file type FTYPE, and absolute base + * address DISP (i.e., the file view displacement) for a data + * transfer. Also request a dataspace transfer or an elementary + * byteblock transfer depending on whether USE_TYPES is non-zero + * or zero, respectively. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Monday, August 9, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_mpio_setup(H5FD_t *_file, MPI_Datatype btype, MPI_Datatype ftype, + haddr_t disp, hbool_t use_types) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + + file->btype = btype; + file->ftype = ftype; + file->disp = disp; + file->use_types = use_types; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_wait_for_left_neighbor + * + * Purpose: Blocks until (empty) msg is received from immediately + * lower-rank neighbor. In conjunction with + * H5FD_mpio_signal_right_neighbor, useful for enforcing + * 1-process-at-at-time access to critical regions to avoid race + * conditions (though it is overkill to require that the + * processes be allowed to proceed strictly in order of their + * rank). + * + * Note: This routine doesn't read or write any file, just performs + * interprocess coordination. It really should reside in a + * separate package of such routines. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: rky + * 19981207 + * + * Modifications: + * Robb Matzke, 1999-08-09 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +herr_t +H5FD_mpio_wait_for_left_neighbor(H5FD_t *_file) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + MPI_Comm comm = file->comm; + char msgbuf[1]; + int myid, mpi_err; + MPI_Status rcvstat; + + mpi_err = MPI_Comm_rank(comm, &myid); + if (MPI_SUCCESS!=mpi_err) return -1; + + /* p0 has no left neighbor; all other procs wait for msg */ + if (myid != 0) { + mpi_err = MPI_Recv( &msgbuf, 1, MPI_CHAR, myid-1, MPI_ANY_TAG, comm, + &rcvstat ); + if (MPI_SUCCESS!=mpi_err) return -1; + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_signal_right_neighbor + * + * Purpose: Blocks until (empty) msg is received from immediately + * lower-rank neighbor. In conjunction with + * H5FD_mpio_wait_for_left_neighbor, useful for enforcing + * 1-process-at-at-time access to critical regions to avoid race + * conditions (though it is overkill to require that the + * processes be allowed to proceed strictly in order of their + * rank). + * + * Note: This routine doesn't read or write any file, just performs + * interprocess coordination. It really should reside in a + * separate package of such routines. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: rky + * 19981207 + * + * Modifications: + * Robb Matzke, 1999-08-09 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +herr_t +H5FD_mpio_signal_right_neighbor(H5FD_t *_file) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + MPI_Comm comm = file->comm; + char msgbuf[1]; + int myid, numprocs, mpi_err; + + mpi_err = MPI_Comm_size( comm, &numprocs ); + if (MPI_SUCCESS!=mpi_err) return -1; + mpi_err = MPI_Comm_rank( comm, &myid ); + if (MPI_SUCCESS!=mpi_err) return -1; + if (myid != (numprocs-1)) { + mpi_err = MPI_Send(&msgbuf, 0/*empty msg*/, MPI_CHAR, myid+1, 0, comm); + if (MPI_SUCCESS!=mpi_err) return -1; + } + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_open + * + * Purpose: Opens a file with name NAME. The FLAGS are a bit field with + * purpose similar to the second argument of open(2) and which + * are defined in H5Fpublic.h. The file access property list + * FAPL_ID contains the properties driver properties and MAXADDR + * is the largest address which this file will be expected to + * access. + * + * Return: Success: A new file pointer. + * + * Failure: NULL + * + * Programmer: + * January 30, 1998 + * + * Modifications: + * Robb Matzke, 1998-02-18 + * Added the ACCESS_PARMS argument. Moved some error checking + * here from elsewhere. + * + * rky, 1998-01-11 + * Added H5FD_mpio_Debug debug flags controlled by MPI_Info. + * + * rky, 1998-08-28 + * Init flag controlling redundant metadata writes to disk. + * + * rky, 1998-12-07 + * Added barrier after MPI_File_set_size to prevent race + * condition -- subsequent writes were being truncated, causing + * holes in file. + * + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +static H5FD_t * +H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr/*unused*/) +{ + H5FD_mpio_t *file=NULL; + MPI_File fh; + int mpi_amode; + int mpierr; + MPI_Offset size; + const H5FD_mpio_fapl_t *fa=NULL; + H5FD_mpio_fapl_t _fa; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) { + fprintf(stdout, "Entering H5FD_mpio_open(name=\"%s\", flags=0x%x, " + "fapl_id=%lu, maxaddr=%lu)\n", name, flags, fapl_id, maxaddr); + } +#endif + + /* Obtain a pointer to mpio-specific file access properties */ + if (H5P_DEFAULT==fapl_id || H5FD_MPIO!=H5Pget_driver(fapl_id)) { + _fa.comm = MPI_COMM_SELF; /*default*/ + _fa.info = MPI_INFO_NULL; /*default*/ + fa = &_fa; + } else { + fa = H5Pget_driver_info(fapl_id); + assert(fa); + } + + /* convert HDF5 flags to MPI-IO flags */ + /* some combinations are illegal; let MPI-IO figure it out */ + mpi_amode = (flags&H5F_ACC_RDWR) ? MPI_MODE_RDWR : MPI_MODE_RDONLY; + if (flags&H5F_ACC_CREAT) mpi_amode |= MPI_MODE_CREATE; + if (flags&H5F_ACC_EXCL) mpi_amode |= MPI_MODE_EXCL; + +#ifdef H5FDmpio_DEBUG + { + /* set debug mask */ + /* Should this be done in H5F global initialization instead of here? */ + const char *s = HDgetenv ("H5FD_mpio_Debug"); + if (s) { + while (*s){ + H5FD_mpio_Debug[(int)*s]++; + s++; + } + } + } + + /* Check for debug commands in the info parameter */ + { + char debug_str[128]; + int infoerr, flag, i; + if (fa->info) { + infoerr = MPI_Info_get(fa->info, H5FD_MPIO_DEBUG_KEY, 127, + debug_str, &flag); + if (flag) { + fprintf(stdout, "H5FD_mpio debug flags=%s\n", debug_str ); + for (i=0; + debug_str[i]/*end of string*/ && i<128/*just in case*/; + ++i) { + H5FD_mpio_Debug[(int)debug_str[i]] = 1; + } + } + } + } +#endif + + /*OKAY: CAST DISCARDS CONST*/ + mpierr = MPI_File_open(fa->comm, (char*)name, mpi_amode, fa->info, &fh); + if (MPI_SUCCESS != mpierr) return NULL; + + /* truncate the file, if requested */ + if (flags & H5F_ACC_TRUNC) { + mpierr = MPI_File_set_size(fh, (MPI_Offset)0); + if (MPI_SUCCESS != mpierr) { + MPI_File_close(&fh); + return NULL; + } + + /* Don't let any proc return until all have truncated the file. */ + mpierr = MPI_Barrier(fa->comm); + if (MPI_SUCCESS!=mpierr) { + MPI_File_close(&fh); + return NULL; + } + } + + /* Build the return value and initialize it */ + if (NULL==(file=calloc(1, sizeof(H5FD_mpio_t)))) return NULL; + file->f = fh; + file->comm = fa->comm; + file->info = fa->info; + file->btype = MPI_DATATYPE_NULL; + file->ftype = MPI_DATATYPE_NULL; + + /* Get current file size */ + mpierr = MPI_File_get_size(fh, &size); + if (MPI_SUCCESS != mpierr) { + free(file); + MPI_File_close(&fh); + return NULL; + } + file->eof = MPIOff_to_haddr(size); + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) { + fprintf(stdout, "Leaving H5FD_mpio_open\n" ); + } +#endif + + return (H5FD_t*)file; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_close + * + * Purpose: Closes a file. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Unknown + * January 30, 1998 + * + * Modifications: + * Robb Matzke, 1998-02-18 + * Added the ACCESS_PARMS argument. + * + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_mpio_close(H5FD_t *_file) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + int mpierr; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Entering H5FD_mpio_close\n"); +#endif + + /* MPI_File_close sets argument to MPI_FILE_NULL */ + mpierr = MPI_File_close(&(file->f)/*in,out*/); + if (MPI_SUCCESS != mpierr) return -1; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Leaving H5FD_mpio_close\n"); +#endif + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_get_eoa + * + * Purpose: Gets 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 + * Friday, August 6, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_mpio_get_eoa(H5FD_t *_file) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + return file->eoa; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_set_eoa + * + * Purpose: Set the end-of-address marker for the file. This function is + * called shortly after an existing HDF5 file is opened in order + * to tell the driver where the end of the HDF5 data is located. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Friday, August 6, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_mpio_set_eoa(H5FD_t *_file, haddr_t addr) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + file->eoa = addr; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_get_eof + * + * Purpose: Gets the end-of-file marker for the file. The EOF marker + * is the real size of the file. + * + * The MPIO driver doesn't bother keeping this field updated + * since that's a relatively expensive operation. Fortunately + * the library only needs the EOF just after the file is opened + * in order to determine whether the file is empty, truncated, + * or okay. Therefore, any MPIO I/O function will set its value + * to HADDR_UNDEF which is the error return value of this + * function. + * + * Return: Success: The end-of-address marker. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Friday, August 6, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_mpio_get_eof(H5FD_t *_file) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + return file->eof; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_read + * + * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF according to data transfer properties in + * DXPL_ID using potentially complex file and buffer types to + * effect the transfer. + * + * Reading past the end of the MPI file returns zeros instead of + * failing. MPI is able to coalesce requests from different + * processes (collective or independent). + * + * Return: Success: Zero. Result is stored in caller-supplied + * buffer BUF. + * + * Failure: -1, Contents of buffer BUF are undefined. + * + * Programmer: rky, 1998-01-30 + * + * Modifications: + * Robb Matzke, 1998-02-18 + * Added the ACCESS_PARMS argument. + * + * rky, 1998-04-10 + * Call independent or collective MPI read, based on + * ACCESS_PARMS. + * + * Albert Cheng, 1998-06-01 + * Added XFER_MODE to control independent or collective MPI + * read. + * + * rky, 1998-08-16 + * Use BTYPE, FTYPE, and DISP from access parms. The guts of + * H5FD_mpio_read and H5FD_mpio_write should be replaced by a + * single dual-purpose routine. + * + * Robb Matzke, 1999-04-21 + * Changed XFER_MODE to XFER_PARMS for all H5F_*_read() + * callbacks. + * + * Robb Matzke, 1999-07-28 + * The ADDR argument is passed by value. + * + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_mpio_read(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, hsize_t size, + void *buf/*out*/) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + const H5FD_mpio_dxpl_t *dx=NULL; + H5FD_mpio_dxpl_t _dx; + MPI_Offset mpi_off, mpi_disp; + MPI_Status mpi_stat; + MPI_Datatype buf_type, file_type; + int mpierr, size_i, bytes_read, n; + int use_types_this_time, used_types_last_time; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Entering H5FD_mpio_read\n" ); +#endif + + /* some numeric conversions */ + if (haddr_to_MPIOff(addr, &mpi_off/*out*/)<0) return -1; + size_i = (int)size; + if ((size_t)size_i != size) return -1; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'r']) + fprintf(stdout, "in H5FD_mpio_read mpi_off=%ld size_i=%d\n", + (long)mpi_off, size_i ); +#endif + + /* Obtain the data transfer properties */ + if (H5P_DEFAULT==dxpl_id || H5FD_MPIO!=H5Pget_driver(dxpl_id)) { + _dx.xfer_mode = H5FD_MPIO_INDEPENDENT; /*the default*/ + dx = &_dx; + } else { + dx = H5Pget_driver_info(dxpl_id); + assert(dx); + } + + /* + * Set up for a fancy xfer using complex types, or single byte block. We + * wouldn't need to rely on the use_types field if MPI semantics allowed + * us to test that btype=ftype=MPI_BYTE (or even MPI_TYPE_NULL, which + * could mean "use MPI_BYTE" by convention). + */ + use_types_this_time = file->use_types; + if (use_types_this_time) { + /* prepare for a full-blown xfer using btype, ftype, and disp */ + buf_type = file->btype; + file_type = file->ftype; + if (haddr_to_MPIOff(file->disp, &mpi_disp)<0) return -1; + } else { + /* + * Prepare for a simple xfer of a contiguous block of bytes. The + * btype, ftype, and disp fields are not used. + */ + buf_type = MPI_BYTE; + file_type = MPI_BYTE; + mpi_disp = 0; /* mpi_off is sufficient */ + } + + /* + * Don't bother to reset the view if we're not using the types this time, + * and did we didn't use them last time either. + */ + used_types_last_time = file->old_use_types; + if (used_types_last_time || /* change to new ftype or MPI_BYTE */ + use_types_this_time) { /* almost certainly a different ftype */ + /*OKAY: CAST DISCARDS CONST QUALIFIER*/ + mpierr = MPI_File_set_view(file->f, mpi_disp, MPI_BYTE, file_type, + (char*)"native", file->info); + if (MPI_SUCCESS != mpierr) return -1; + } + + /* + * We always set the use_types flag to 0 because the default is not to + * use types next time, unless someone explicitly requests it by setting + * this flag to !=0. + */ + file->old_use_types = use_types_this_time; + file->use_types = 0; + + /* Read the data. */ + assert(H5FD_MPIO_INDEPENDENT==dx->xfer_mode || + H5FD_MPIO_COLLECTIVE==dx->xfer_mode); + if (H5FD_MPIO_INDEPENDENT==dx->xfer_mode) { + mpierr = MPI_File_read_at(file->f, mpi_off, buf, size_i, buf_type, + &mpi_stat); + if (MPI_SUCCESS!=mpierr) return -1; + } else { +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "H5FD_mpio_read: using MPIO collective mode\n"); +#endif + mpierr = MPI_File_read_at_all(file->f, mpi_off, buf, size_i, buf_type, + &mpi_stat ); + if (MPI_SUCCESS!=mpierr) return -1; + } + + /* How many bytes were actually read? */ + mpierr = MPI_Get_count(&mpi_stat, MPI_BYTE, &bytes_read); + if (MPI_SUCCESS != mpierr) return -1; +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'c']) + fprintf(stdout, + "In H5FD_mpio_read after Get_count size_i=%d bytes_read=%d\n", + size_i, bytes_read ); +#endif +#if 1 + /* + * KLUGE rky 1998-02-02 + * MPI_Get_count incorrectly returns negative count; fake a complete + * read. + */ + bytes_read = size_i; +#endif + if (bytes_read<0 || bytes_read>size_i) return -1; + + /* + * This gives us zeroes beyond end of physical MPI file. What about + * reading past logical end of HDF5 file??? + */ + if ((n=(size_i-bytes_read)) > 0) { + if (use_types_this_time) { + /* + * INCOMPLETE rky 1998-09-18 + * Haven't implemented reading zeros beyond EOF. What to do??? + */ + return -1; + } else { + memset((char*)buf+bytes_read, 0, (size_t)n); + } + } + + /* Forget the EOF value (see H5FD_mpio_get_eof()) --rpm 1999-08-06 */ + file->eof = HADDR_UNDEF; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Leaving H5FD_mpio_read\n" ); +#endif + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_write + * + * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR + * from buffer BUF according to data transfer properties in + * DXPL_ID using potentially complex file and buffer types to + * effect the transfer. + * + * MPI is able to coalesce requests from different processes + * (collective and independent). + * + * Return: Success: Zero. USE_TYPES and OLD_USE_TYPES in the + * access params are altered. + * + * Failure: -1, USE_TYPES and OLD_USE_TYPES in the + * access params may be altered. + * + * Programmer: Unknown + * January 30, 1998 + * + * Modifications: + * rky, 1998-08-28 + * If the file->allsame flag is set, we assume that all the + * procs in the relevant MPI communicator will write identical + * data at identical offsets in the file, so only proc 0 will + * write, and all other procs will wait for p0 to finish. This + * is useful for writing metadata, for example. Note that we + * don't _check_ that the data is identical. Also, the mechanism + * we use to eliminate the redundant writes is by requiring a + * call to H5FD_mpio_tas_allsame before the write, which is + * rather klugey. Would it be better to pass a parameter to + * low-level writes like H5F_block_write and H5F_low_write, + * instead? Or...??? Also, when I created this mechanism I + * wanted to minimize the difference in behavior between the old + * way of doing things (i.e., all procs write) and the new way, + * so the writes are eliminated at the very lowest level, here + * in H5FD_mpio_write. It may be better to rethink that, and + * short-circuit the writes at a higher level (e.g., at the + * points in the code where H5FD_mpio_tas_allsame is called). + * + * + * Robb Matzke, 1998-02-18 + * Added the ACCESS_PARMS argument. + * + * rky, 1998-04-10 + * Call independent or collective MPI write, based on + * ACCESS_PARMS. + * + * rky, 1998-04-24 + * Removed redundant write from H5FD_mpio_write. + * + * Albert Cheng, 1998-06-01 + * Added XFER_MODE to control independent or collective MPI + * write. + * + * rky, 1998-08-16 + * Use BTYPE, FTYPE, and DISP from access parms. The guts of + * H5FD_mpio_read and H5FD_mpio_write should be replaced by a + * single dual-purpose routine. + * + * rky, 1998-08-28 + * Added ALLSAME parameter to make all but proc 0 skip the + * actual write. + * + * Robb Matzke, 1999-04-21 + * Changed XFER_MODE to XFER_PARMS for all H5FD_*_write() + * callbacks. + * + * Robb Matzke, 1999-07-28 + * The ADDR argument is passed by value. + * + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_mpio_write(H5FD_t *_file, hid_t dxpl_id/*unused*/, haddr_t addr, + hsize_t size, const void *buf) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + const H5FD_mpio_dxpl_t *dx=NULL; + H5FD_mpio_dxpl_t _dx; + MPI_Offset mpi_off, mpi_disp; + MPI_Status mpi_stat; + MPI_Datatype buf_type, file_type; + int mpierr, size_i, bytes_written; + int mpi_rank; + int use_types_this_time, used_types_last_time; + hbool_t allsame; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Entering H5FD_mpio_write\n" ); +#endif + + /* some numeric conversions */ + if (haddr_to_MPIOff(addr, &mpi_off)<0) return -1; + if (haddr_to_MPIOff(file->disp, &mpi_disp)<0) return -1; + size_i = (int)size; + if ((size_t)size_i != size) return -1; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'w']) + fprintf(stdout, "in H5FD_mpio_write mpi_off=%ld size_i=%d\n", + (long)mpi_off, size_i); +#endif + + /* Only p0 will do the actual write if all procs in comm write same data */ + allsame = H5FD_mpio_tas_allsame(_file, FALSE); + if (allsame && H5_mpi_1_metawrite_g) { + mpierr = MPI_Comm_rank(file->comm, &mpi_rank); + if (mpierr != MPI_SUCCESS) return -1; + if (mpi_rank != 0) { +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'w']) { + fprintf(stdout, " in H5FD_mpio_write (write omitted)\n" ); + } +#endif + goto done; /* skip the actual write */ + } + } + + /* Obtain the data transfer properties */ + if (H5P_DEFAULT==dxpl_id || H5FD_MPIO!=H5Pget_driver(dxpl_id)) { + _dx.xfer_mode = H5FD_MPIO_INDEPENDENT; /*the default*/ + dx = &_dx; + } else { + dx = H5Pget_driver_info(dxpl_id); + assert(dx); + } + + /* + * Set up for a fancy xfer using complex types, or single byte block. We + * wouldn't need to rely on the use_types field if MPI semantics allowed + * us to test that btype=ftype=MPI_BYTE (or even MPI_TYPE_NULL, which + * could mean "use MPI_BYTE" by convention). + */ + use_types_this_time = file->use_types; + if (use_types_this_time) { + /* prepare for a full-blown xfer using btype, ftype, and disp */ + buf_type = file->btype; + file_type = file->ftype; + if (haddr_to_MPIOff(file->disp, &mpi_disp)<0) return -1; + } else { + /* + * Prepare for a simple xfer of a contiguous block of bytes. + * The btype, ftype, and disp fields are not used. + */ + buf_type = MPI_BYTE; + file_type = MPI_BYTE; + mpi_disp = 0; /* mpi_off is sufficient */ + } + + /* + * Don't bother to reset the view if we're not using the types this time, + * and did we didn't use them last time either. + */ + used_types_last_time = file->old_use_types; + if (used_types_last_time || /* change to new ftype or MPI_BYTE */ + use_types_this_time) { /* almost certainly a different ftype */ + /*OKAY: CAST DISCARDS CONST QUALIFIER*/ + mpierr = MPI_File_set_view(file->f, mpi_disp, MPI_BYTE, file_type, + (char*)"native", file->info); + if (MPI_SUCCESS != mpierr) return -1; + } + + /* + * We always set the use_types flag to 0 because the default is not to + * use types next time, unless someone explicitly requests it by setting + * this flag to !=0. + */ + file->old_use_types = use_types_this_time; + file->use_types = 0; + + /* Write the data. */ + assert(H5FD_MPIO_INDEPENDENT==dx->xfer_mode || + H5FD_MPIO_COLLECTIVE==dx->xfer_mode); + if (H5FD_MPIO_INDEPENDENT==dx->xfer_mode) { + /*OKAY: CAST DISCARDS CONST QUALIFIER*/ + mpierr = MPI_File_write_at(file->f, mpi_off, (void*)buf, size_i, + buf_type, &mpi_stat); + } else { +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "H5FD_mpio_write: using MPIO collective mode\n"); +#endif + /*OKAY: CAST DISCARDS CONST QUALIFIER*/ + mpierr = MPI_File_write_at_all(file->f, mpi_off, (void*)buf, size_i, + buf_type, &mpi_stat); + } + if (MPI_SUCCESS != mpierr) return -1; + + /* How many bytes were actually written? */ + mpierr = MPI_Get_count(&mpi_stat, MPI_BYTE, &bytes_written); + if (MPI_SUCCESS!=mpierr) return -1; +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'c']) + fprintf(stdout, + "In H5FD_mpio_write after Get_count size_i=%d bytes_written=%d\n", + size_i, bytes_written ); +#endif +#if 1 + /* + * KLUGE rky, 1998-02-02 + * MPI_Get_count incorrectly returns negative count; fake a complete + * write. + */ + bytes_written = size_i; +#endif + if (bytes_written<0 || bytes_written>size_i) return -1; + + /* Forget the EOF value (see H5FD_mpio_get_eof()) --rpm 1999-08-06 */ + file->eof = HADDR_UNDEF; + + done: +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Leaving H5FD_mpio_write\n" ); +#endif + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_mpio_flush + * + * Purpose: Makes sure that all data is on disk. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Unknown + * January 30, 1998 + * + * Modifications: + * Robb Matzke, 1998-02-18 + * Added the ACCESS_PARMS argument. + * + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_mpio_flush(H5FD_t *_file) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + int mpierr; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Entering H5FD_mpio_flush\n" ); +#endif + + mpierr = MPI_File_sync(file->f); + if (MPI_SUCCESS != mpierr) return -1; + +#ifdef H5FDmpio_DEBUG + if (H5FD_mpio_Debug[(int)'t']) + fprintf(stdout, "Leaving H5FD_mpio_flush\n" ); +#endif + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: MPIOff_to_haddr + * + * Purpose: Convert an MPI_Offset value to haddr_t. + * + * Return: Success: The haddr_t equivalent of the MPI_OFF + * argument. + * + * Failure: HADDR_UNDEF + * + * Programmer: Unknown + * January 30, 1998 + * + * Modifications: + * Robb Matzke, 1999-04-23 + * An error is reported for address overflows. The ADDR output + * argument is optional. + * + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +static haddr_t +MPIOff_to_haddr(MPI_Offset mpi_off) +{ + if (mpi_off != (MPI_Offset)(haddr_t)mpi_off) return HADDR_UNDEF; + return (haddr_t)mpi_off; +} + + +/*------------------------------------------------------------------------- + * Function: haddr_to_MPIOff + * + * Purpose: Convert an haddr_t value to MPI_Offset. + * + * Return: Success: Non-negative, the MPI_OFF argument contains + * the converted value. + * + * Failure: Negative, MPI_OFF is undefined. + * + * Programmer: Unknown + * January 30, 1998 + * + * Modifications: + * Robb Matzke, 1999-04-23 + * An error is reported for address overflows. The ADDR output + * argument is optional. + * + * Robb Matzke, 1999-07-28 + * The ADDR argument is passed by value. + * + * Robb Matzke, 1999-08-06 + * Modified to work with the virtual file layer. + *------------------------------------------------------------------------- + */ +static herr_t +haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off/*out*/) +{ + if (mpi_off) *mpi_off = (MPI_Offset)addr; + if (addr != (haddr_t)(MPI_Offset)addr) return -1; + return 0; +} +#endif /*HAVE_PARALLEL*/ diff --git a/src/H5FDmpio.h b/src/H5FDmpio.h new file mode 100644 index 0000000..fa27918 --- /dev/null +++ b/src/H5FDmpio.h @@ -0,0 +1,50 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, August 2, 1999 + * + * Purpose: The public header file for the mpio driver. + */ +#ifndef H5FDmpio_H +#define H5FDmpio_H + +#include <H5FDpublic.h> +#include <H5Ipublic.h> + +#ifdef HAVE_PARALLEL +# define H5FD_MPIO (H5FD_mpio_init()) +#else +# define H5FD_MPIO (-1) +#endif + +/* Type of I/O for data transfer properties */ +typedef enum H5FD_mpio_xfer_t { + H5FD_MPIO_INDEPENDENT = 0, /*zero is the default*/ + H5FD_MPIO_COLLECTIVE +} H5FD_mpio_xfer_t; + +/* MPIO-specific data transfer properties */ +typedef struct H5FD_mpio_dxpl_t { + H5FD_mpio_xfer_t xfer_mode; /*collective or independent I/O */ +} H5FD_mpio_dxpl_t; + +/* Function prototypes */ +#ifdef HAVE_PARALLEL +hid_t H5FD_mpio_init(void); +herr_t H5Pset_fapl_mpio(hid_t fapl_id, MPI_Comm comm, MPI_Info info); +herr_t H5Pget_fapl_mpio(hid_t fapl_id, MPI_Comm *comm/*out*/, + MPI_Info *info/*out*/); +herr_t H5Pset_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t xfer_mode); +herr_t H5Pget_dxpl_mpio(hid_t dxpl_id, H5FD_mpio_xfer_t *xfer_mode/*out*/); +htri_t H5FD_mpio_tas_allsame(H5FD_t *_file, hbool_t newval); +MPI_Comm H5FD_mpio_communicator(H5FD_t *_file); +herr_t H5FD_mpio_setup(H5FD_t *_file, MPI_Datatype btype, MPI_Datatype ftype, + haddr_t disp, hbool_t use_types); +herr_t H5FD_mpio_wait_for_left_neighbor(H5FD_t *file); +herr_t H5FD_mpio_signal_right_neighbor(H5FD_t *file); + +#endif /*HAVE_PARALLEL*/ + +#endif diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h new file mode 100644 index 0000000..a987b60 --- /dev/null +++ b/src/H5FDprivate.h @@ -0,0 +1,35 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, July 26, 1999 + */ +#ifndef _H5FDprivate_H +#define _H5FDprivate_H + +#include <H5FDpublic.h> + +intn H5FD_term_interface(void); +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); +herr_t H5FD_dxpl_free(hid_t driver_id, void *dxpl); +H5FD_t *H5FD_open(const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr); +herr_t H5FD_close(H5FD_t *file); +int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2); +haddr_t H5FD_alloc(H5FD_t *file, H5FD_mem_t type, hsize_t size); +herr_t H5FD_free(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size); +haddr_t H5FD_realloc(H5FD_t *file, H5FD_mem_t type, haddr_t old_addr, + hsize_t old_size, hsize_t new_size); +haddr_t H5FD_get_eoa(H5FD_t *file); +herr_t H5FD_set_eoa(H5FD_t *file, haddr_t addr); +haddr_t H5FD_get_eof(H5FD_t *file); +herr_t H5FD_read(H5FD_t *file, hid_t dxpl_id, haddr_t addr, hsize_t size, + void *buf/*out*/); +herr_t H5FD_write(H5FD_t *file, hid_t dxpl_id, haddr_t addr, hsize_t size, + const void *buf); +herr_t H5FD_flush(H5FD_t *file); + +#endif /* !_H5FDprivate_H */ diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h new file mode 100644 index 0000000..8af79d2 --- /dev/null +++ b/src/H5FDpublic.h @@ -0,0 +1,154 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, July 26, 1999 + */ +#ifndef _H5FDpublic_H +#define _H5FDpublic_H + +/* Types of allocation requests */ +typedef enum H5FD_mem_t { + H5FD_MEM_NOLIST = -1, /*must be negative*/ + H5FD_MEM_DEFAULT = 0, /*must be zero*/ + H5FD_MEM_SUPER, + H5FD_MEM_BTREE, + H5FD_MEM_DRAW, + H5FD_MEM_META, + H5FD_MEM_GROUP, + H5FD_MEM_GHEAP, + H5FD_MEM_LHEAP, + H5FD_MEM_OHDR, + + H5FD_MEM_NTYPES /*must be last*/ +} H5FD_mem_t; +/* + * A free-list map which maps all types of allocation requests to a single + * free list. This is useful for drivers that don't really care about + * keeping different requests segregated in the underlying file and which + * want to make most efficient reuse of freed memory. The use of the + * H5FD_MEM_SUPER free list is arbitrary. + */ +#define H5FD_FLMAP_SINGLE { \ + H5FD_MEM_SUPER, /*default*/ \ + 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*/ \ +} + +/* + * A free-list map which segregates requests into `raw' or `meta' data + * pools. + */ +#define H5FD_FLMAP_DICHOTOMY { \ + H5FD_MEM_META, /*default*/ \ + H5FD_MEM_META, /*super*/ \ + H5FD_MEM_META, /*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*/ \ +} + +/* + * The default free list map which causes each request type to use it's own + * free-list. + */ +#define H5FD_FLMAP_DEFAULT { \ + H5FD_MEM_DEFAULT, /*default*/ \ + 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*/ \ +} + + + +/* Forward declaration */ +typedef struct H5FD_t H5FD_t; + +/* Class information for each file driver */ +typedef struct H5FD_class_t { + const char *name; + haddr_t maxaddr; + size_t fapl_size; + void *(*fapl_copy)(const void *fapl); + herr_t (*fapl_free)(void *fapl); + size_t dxpl_size; + void *(*dxpl_copy)(const void *dxpl); + herr_t (*dxpl_free)(void *dxpl); + H5FD_t *(*open)(const char *name, unsigned flags, hid_t fapl, + haddr_t maxaddr); + herr_t (*close)(H5FD_t *file); + int (*cmp)(const H5FD_t *f1, const H5FD_t *f2); + haddr_t (*alloc)(H5FD_t *file, H5FD_mem_t type, hsize_t size); + herr_t (*free)(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size); + haddr_t (*get_eoa)(H5FD_t *file); + herr_t (*set_eoa)(H5FD_t *file, haddr_t addr); + haddr_t (*get_eof)(H5FD_t *file); + herr_t (*read)(H5FD_t *file, hid_t dxpl, haddr_t addr, hsize_t size, + void *buffer); + herr_t (*write)(H5FD_t *file, hid_t dxpl, haddr_t addr, hsize_t size, + const void *buffer); + herr_t (*flush)(H5FD_t *file); + H5FD_mem_t fl_map[H5FD_MEM_NTYPES]; +} H5FD_class_t; + +/* A free list is a singly-linked list of address/size pairs. */ +typedef struct H5FD_free_t { + haddr_t addr; + hsize_t size; + struct H5FD_free_t *next; +} H5FD_free_t; + +/* + * The main datatype for each driver. Public fields common to all drivers are + * declared here and the driver appends private fields in memory. + */ +struct H5FD_t { + hid_t driver_id; /*driver ID for this file */ + const H5FD_class_t *cls; /*constant class info */ + haddr_t maxaddr; /*for this file, overrides class*/ + H5FD_free_t *fl[H5FD_MEM_NTYPES];/*freelist per allocation type*/ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* Function prototypes */ +hid_t H5FDregister(const H5FD_class_t *cls); +herr_t H5FDunregister(hid_t driver_id); +H5FD_t *H5FDopen(const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr); +herr_t H5FDclose(H5FD_t *file); +int H5FDcmp(const H5FD_t *f1, const H5FD_t *f2); +haddr_t H5FDalloc(H5FD_t *file, H5FD_mem_t type, hsize_t size); +herr_t H5FDfree(H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size); +haddr_t H5FDrealloc(H5FD_t *file, H5FD_mem_t type, haddr_t addr, + hsize_t old_size, hsize_t new_size); +haddr_t H5FDget_eoa(H5FD_t *file); +herr_t H5FDset_eoa(H5FD_t *file, haddr_t eof); +haddr_t H5FDget_eof(H5FD_t *file); +herr_t H5FDread(H5FD_t *file, hid_t dxpl_id, haddr_t addr, hsize_t size, + void *buf/*out*/); +herr_t H5FDwrite(H5FD_t *file, hid_t dxpl_id, haddr_t addr, hsize_t size, + const void *buf); +herr_t H5FDflush(H5FD_t *file); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c new file mode 100644 index 0000000..b383b92 --- /dev/null +++ b/src/H5FDsec2.c @@ -0,0 +1,585 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Thursday, July 29, 1999 + * + * Purpose: The POSIX unbuffered file driver using only the HDF5 public + * API and with a few optimizations: the lseek() call is made + * only when the current file position is unknown or needs to be + * changed based on previous I/O through this driver (don't mix + * I/O from this driver with I/O from other parts of the + * application to the same file). + */ +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <hdf5.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <unistd.h> + + +#undef MAX +#define MAX(X,Y) ((X)>(Y)?(X):(Y)) + +/* The driver identification number, initialized at runtime */ +static hid_t H5FD_SEC2_g = 0; + +/* File operations */ +#define OP_UNKNOWN 0 +#define OP_READ 1 +#define OP_WRITE 2 + +/* + * The description of a file belonging to this driver. The `eoa' and `eof' + * determine the amount of hdf5 address space in use and the high-water mark + * of the file (the current size of the underlying Unix file). The `pos' + * value is used to eliminate file position updates when they would be a + * no-op. Unfortunately we've found systems that use separate file position + * indicators for reading and writing so the lseek can only be eliminated if + * the current operation is the same as the previous operation. When opening + * a file the `eof' will be set to the current file size, `eoa' will be set + * to zero, `pos' will be set to H5F_ADDR_UNDEF (as it is when an error + * occurs), and `op' will be set to H5F_OP_UNKNOWN. + */ +typedef struct H5FD_sec2_t { + H5FD_t pub; /*public stuff, must be first */ + int fd; /*the unix file */ + haddr_t eoa; /*end of allocated region */ + haddr_t eof; /*end of file; current file size*/ + haddr_t pos; /*current file I/O position */ + int op; /*last operation */ +#ifndef WIN32 + /* + * On most systems the combination of device and i-node number uniquely + * identify a file. + */ + dev_t device; /*file device number */ + ino_t inode; /*file i-node number */ +#else + /* + * On WIN32 the low-order word of a unique identifier associated with the + * file and the volume serial number uniquely identify a file. This number + * (which, both? -rpm) may change when the system is restarted or when the + * file is opened. After a process opens a file, the identifier is + * constant until the file is closed. An application can use this + * identifier and the volume serial number to determine whether two + * handles refer to the same file. + */ + int fileindexlo; + int fileindexhi; +#endif +} H5FD_sec2_t; + +/* + * This driver supports systems that have the lseek64() function by defining + * some macros here so we don't have to have conditional compilations later + * throughout the code. + * + * file_offset_t: The datatype for file offsets, the second argument of + * the lseek() or lseek64() call. + * + * file_seek: The function which adjusts the current file position, + * either lseek() or lseek64(). + */ +#ifdef HAVE_LSEEK64 +# define file_offset_t off64_t +# define file_seek lseek64 +#else +# define file_offset_t off_t +# define file_seek lseek +#endif + +/* + * These macros check for overflow of various quantities. These macros + * assume that file_offset_t is signed and haddr_t and size_t are unsigned. + * + * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' + * is too large to be represented by the second argument + * of the file seek function. + * + * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too + * large to be represented by the `size_t' type. + * + * REGION_OVERFLOW: Checks whether an address and size pair describe data + * which can be addressed entirely by the second + * argument of the file seek function. + */ +#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1) +#define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ + ((A) & ~(haddr_t)MAXADDR)) +#define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) +#define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ + sizeof(file_offset_t)<sizeof(size_t) || \ + HADDR_UNDEF==(A)+(Z) || \ + (file_offset_t)((A)+(Z))<(file_offset_t)(A)) + +/* Prototypes */ +static H5FD_t *H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr); +static herr_t H5FD_sec2_close(H5FD_t *_file); +static int H5FD_sec2_cmp(const H5FD_t *_f1, const H5FD_t *_f2); +static haddr_t H5FD_sec2_get_eoa(H5FD_t *_file); +static herr_t H5FD_sec2_set_eoa(H5FD_t *_file, haddr_t addr); +static haddr_t H5FD_sec2_get_eof(H5FD_t *_file); +static herr_t H5FD_sec2_read(H5FD_t *_file, hid_t fapl_id, haddr_t addr, + hsize_t size, void *buf); +static herr_t H5FD_sec2_write(H5FD_t *_file, hid_t fapl_id, haddr_t addr, + hsize_t size, const void *buf); +static herr_t H5FD_sec2_flush(H5FD_t *_file); + +static const H5FD_class_t H5FD_sec2_g = { + "sec2", /*name */ + MAXADDR, /*maxaddr */ + 0, /*fapl_size */ + NULL, /*fapl_copy */ + NULL, /*fapl_free */ + 0, /*dxpl_size */ + NULL, /*dxpl_copy */ + NULL, /*dxpl_free */ + H5FD_sec2_open, /*open */ + H5FD_sec2_close, /*close */ + H5FD_sec2_cmp, /*cmp */ + NULL, /*alloc */ + NULL, /*free */ + H5FD_sec2_get_eoa, /*get_eoa */ + H5FD_sec2_set_eoa, /*set_eoa */ + H5FD_sec2_get_eof, /*get_eof */ + H5FD_sec2_read, /*read */ + H5FD_sec2_write, /*write */ + H5FD_sec2_flush, /*flush */ + H5FD_FLMAP_SINGLE, /*fl_map */ +}; + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_init + * + * Purpose: Initialize this driver by registering the driver with the + * library. + * + * Return: Success: The driver ID for the sec2 driver. + * + * Failure: Negative. + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5FD_sec2_init(void) +{ + if (!H5FD_SEC2_g) { + H5FD_SEC2_g = H5FDregister(&H5FD_sec2_g); + } + return H5FD_SEC2_g; +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_sec2 + * + * Purpose: Modify the file access property list to use the H5FD_SEC2 + * driver defined in this source file. There are no driver + * specific properties. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, February 19, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_sec2(hid_t fapl_id) +{ + /*NO TRACE*/ + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; + return H5Pset_driver(fapl_id, H5FD_SEC2, NULL); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_open + * + * Purpose: Create and/or opens a Unix file as an 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 + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5FD_t * +H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id/*unused*/, + haddr_t maxaddr) +{ + unsigned o_flags; + int fd; + struct stat sb; + H5FD_sec2_t *file=NULL; + + /* Check arguments */ + if (!name || !*name) return NULL; + if (0==maxaddr || HADDR_UNDEF==maxaddr) return NULL; + if (ADDR_OVERFLOW(maxaddr)) return NULL; + + /* Build the open flags */ + o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; + if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC; + if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT; + if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL; + + /* Open the file */ + if ((fd=open(name, o_flags, 0666))<0) return NULL; + if (fstat(fd, &sb)<0) { + close(fd); + return NULL; + } + + /* Create the new file struct */ + file = calloc(1, sizeof(H5FD_sec2_t)); + file->fd = fd; + file->eof = sb.st_size; + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + file->device = sb.st_dev; + file->inode = sb.st_ino; + + return (H5FD_t*)file; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_close + * + * Purpose: Closes a Unix file. + * + * Return: Success: 0 + * + * Failure: -1, file not closed. + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_sec2_close(H5FD_t *_file) +{ + H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + + if (H5FD_sec2_flush(_file)<0) return -1; + if (close(file->fd)<0) return -1; + free(file); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_cmp + * + * Purpose: Compares two files belonging to this driver using an + * arbitrary (but consistent) ordering. + * + * Return: Success: A value like strcmp() + * + * Failure: never fails (arguments were checked by the + * caller). + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5FD_sec2_cmp(const H5FD_t *_f1, const H5FD_t *_f2) +{ + const H5FD_sec2_t *f1 = (const H5FD_sec2_t*)_f1; + const H5FD_sec2_t *f2 = (const H5FD_sec2_t*)_f2; + + if (f1->device < f2->device) return -1; + if (f1->device > f2->device) return 1; + + if (f1->inode < f2->inode) return -1; + if (f1->inode > f2->inode) return 1; + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_get_eoa + * + * Purpose: Gets 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 + * Monday, August 2, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_sec2_get_eoa(H5FD_t *_file) +{ + H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + return file->eoa; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_set_eoa + * + * Purpose: Set the end-of-address marker for the file. This function is + * called shortly after an existing HDF5 file is opened in order + * to tell the driver where the end of the HDF5 data is located. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_sec2_set_eoa(H5FD_t *_file, haddr_t addr) +{ + H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + file->eoa = addr; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_get_eof + * + * Purpose: Returns the end-of-file marker, which is the greater of + * either the Unix end-of-file or the HDF5 end-of-address + * markers. + * + * Return: Success: End of file address, the first address past + * the end of the "file", either the Unix file + * or the HDF5 file. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_sec2_get_eof(H5FD_t *_file) +{ + H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + return MAX(file->eof, file->eoa); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_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 + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_sec2_read(H5FD_t *_file, hid_t dxpl_id/*unused*/, haddr_t addr, + hsize_t size, void *buf/*out*/) +{ + H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + ssize_t nbytes; + + assert(file && file->pub.cls); + assert(buf); + + /* Check for overflow conditions */ + if (HADDR_UNDEF==addr) return -1; + if (REGION_OVERFLOW(addr, size)) return -1; + if (addr+size>file->eoa) return -1; + + /* Seek to the correct location */ + if ((addr!=file->pos || OP_READ!=file->op) && + file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) { + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + return -1; + } + + /* + * Read data, being careful of interrupted system calls, partial results, + * and the end of the file. + */ + while (size>0) { + do nbytes = read(file->fd, buf, size); + while (-1==nbytes && EINTR==errno); + if (-1==nbytes) { + /* error */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + return -1; + } + if (0==nbytes) { + /* end of file but not end of format address space */ + memset(buf, 0, size); + size = 0; + } + assert(nbytes>=0); + assert((hsize_t)nbytes<=size); + size -= (hsize_t)nbytes; + addr += (haddr_t)nbytes; + buf = (char*)buf + nbytes; + } + + /* Update current position */ + file->pos = addr; + file->op = OP_READ; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_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 + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_sec2_write(H5FD_t *_file, hid_t dxpl_id/*unused*/, haddr_t addr, + hsize_t size, const void *buf) +{ + H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + ssize_t nbytes; + + assert(file && file->pub.cls); + assert(buf); + + /* Check for overflow conditions */ + if (HADDR_UNDEF==addr) return -1; + if (REGION_OVERFLOW(addr, size)) return -1; + if (addr+size>file->eoa) return -1; + + /* Seek to the correct location */ + if ((addr!=file->pos || OP_WRITE!=file->op) && + file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) { + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + return -1; + } + + /* + * Write the data, being careful of interrupted system calls and partial + * results + */ + while (size>0) { + do nbytes = write(file->fd, buf, size); + while (-1==nbytes && EINTR==errno); + if (-1==nbytes) { + /* error */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + return -1; + } + assert(nbytes>0); + assert((hsize_t)nbytes<=size); + size -= (hsize_t)nbytes; + addr += (haddr_t)nbytes; + buf = (const char*)buf + nbytes; + } + + /* Update current position and eof */ + file->pos = addr; + file->op = OP_WRITE; + if (file->pos>file->eof) file->eof = file->pos; + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sec2_flush + * + * Purpose: Makes sure that the true file size is the same (or larger) + * than the end-of-address. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_sec2_flush(H5FD_t *_file) +{ + H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + + if (file->eoa>file->eof) { + if (-1==file_seek(file->fd, file->eoa-1, SEEK_SET)) return -1; + if (write(file->fd, "", 1)!=1) return -1; + file->eof = file->eoa; + file->pos = file->eoa; + file->op = OP_WRITE; + } + + return 0; +} diff --git a/src/H5FDsec2.h b/src/H5FDsec2.h new file mode 100644 index 0000000..4310f9e --- /dev/null +++ b/src/H5FDsec2.h @@ -0,0 +1,20 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, August 2, 1999 + * + * Purpose: The public header file for the sec2 driver. + */ +#ifndef H5FDsec2_H +#define H5FDsec2_H + +#include <H5Ipublic.h> + +#define H5FD_SEC2 (H5FD_sec2_init()) + +hid_t H5FD_sec2_init(void); +herr_t H5Pset_fapl_sec2(hid_t fapl_id); + +#endif diff --git a/src/H5Farray.c b/src/H5Farray.c index 67c0446..6019f1e 100644 --- a/src/H5Farray.c +++ b/src/H5Farray.c @@ -15,10 +15,15 @@ #include <H5Dprivate.h> #include <H5Eprivate.h> #include <H5Fprivate.h> +#include <H5Iprivate.h> #include <H5MFprivate.h> #include <H5Oprivate.h> +#include <H5Pprivate.h> #include <H5Vprivate.h> +/* MPIO driver functions are needed for some special checks */ +#include <H5FDmpio.h> + /* Interface initialization */ #define PABLO_MASK H5Farray_mask #define INTERFACE_INIT NULL @@ -51,14 +56,14 @@ H5F_arr_create (H5F_t *f, struct H5O_layout_t *layout/*in,out*/) /* check args */ assert (f); assert (layout); - layout->addr = H5F_ADDR_UNDEF; /*just in case we fail*/ + layout->addr = HADDR_UNDEF; /*just in case we fail*/ switch (layout->type) { case H5D_CONTIGUOUS: /* Reserve space in the file for the entire array */ for (i=0, nbytes=1; i<layout->ndims; i++) nbytes *= layout->dim[i]; assert (nbytes>0); - if (H5MF_alloc (f, H5MF_RAW, nbytes, &(layout->addr)/*out*/)<0) { + if (HADDR_UNDEF==(layout->addr=H5MF_alloc(f, H5FD_MEM_DRAW, nbytes))) { HRETURN_ERROR (H5E_IO, H5E_NOSPACE, FAIL, "unable to reserve file space"); } @@ -103,22 +108,24 @@ H5F_arr_create (H5F_t *f, struct H5O_layout_t *layout/*in,out*/) * Friday, January 16, 1998 * * Modifications: - * June 2, 1998 Albert Cheng + * Albert Cheng, 1998-06-02 * Added xfer_mode argument * - * Sep 28, 1998 Robb Matzke + * Robb Matzke, 1998-09-28 * Added the `xfer' argument and removed the `xfer_mode' * argument since it's a field of `xfer'. * + * Robb Matzke, 1999-08-02 + * Data transfer properties are passed by ID since that's how + * the virtual file layer wants them. *------------------------------------------------------------------------- */ herr_t -H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, - const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, const H5O_fill_t *fill, - const struct H5O_efl_t *efl, const hsize_t _hslab_size[], - const hsize_t mem_size[], const hssize_t mem_offset[], - const hssize_t file_offset[], void *_buf/*out*/) +H5F_arr_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, + const struct H5O_pline_t *pline, const H5O_fill_t *fill, + const struct H5O_efl_t *efl, const hsize_t _hslab_size[], + const hsize_t mem_size[], const hssize_t mem_offset[], + const hssize_t file_offset[], void *_buf/*out*/) { uint8_t *buf = (uint8_t*)_buf; /*cast for arithmetic */ hssize_t file_stride[H5O_LAYOUT_NDIMS]; /*strides through file */ @@ -133,27 +140,43 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, haddr_t addr; /*address in file */ intn i, j; /*counters */ hbool_t carray; /*carry for subtraction */ +#ifdef HAVE_PARALLEL + H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; +#endif - FUNC_ENTER (H5F_arr_read, FAIL); + FUNC_ENTER(H5F_arr_read, FAIL); /* Check args */ - assert (f); - assert (layout); - assert (_hslab_size); - assert (file_offset); - assert (mem_offset); - assert (mem_size); - assert (buf); + assert(f); + assert(layout); + assert(_hslab_size); + assert(file_offset); + assert(mem_offset); + assert(mem_size); + assert(buf); /* Make a local copy of size so we can modify it */ - H5V_vector_cpy (layout->ndims, hslab_size, _hslab_size); + H5V_vector_cpy(layout->ndims, hslab_size, _hslab_size); #ifdef HAVE_PARALLEL - if (xfer->xfer_mode==H5D_XFER_COLLECTIVE){ - if (layout->type != H5D_CONTIGUOUS) - HRETURN_ERROR (H5E_DATASET, H5E_READERROR, FAIL, - "collective access on non-contiguous datasets not " - "supported yet"); + { + /* Get the transfer mode */ + H5F_xfer_t *dxpl; + H5FD_mpio_dxpl_t *dx; + if (H5P_DEFAULT!=dxpl_id && (dxpl=H5I_object(dxpl_id)) && + H5FD_MPIO==dxpl->driver_id && (dx=dxpl->driver_info) && + H5FD_MPIO_INDEPENDENT!=dx->xfer_mode) { + xfer_mode = dx->xfer_mode; + } + } +#endif + +#ifdef HAVE_PARALLEL + /* Collective MPIO access is unsupported for non-contiguous datasets */ + if (H5D_CONTIGUOUS!=layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode) { + HRETURN_ERROR (H5E_DATASET, H5E_READERROR, FAIL, + "collective access on non-contiguous datasets not " + "supported yet"); } #endif #ifdef QAK @@ -177,8 +200,8 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, */ for (i=0; i<ndims; i++) { if (mem_offset[i]<0 || file_offset[i]<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "negative offsets are not valid"); + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "negative offsets are not valid"); } } @@ -186,8 +209,8 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, * Filters cannot be used for contiguous data. */ if (pline && pline->nfilters>0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "filters are not allowed for contiguous data"); + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "filters are not allowed for contiguous data"); } /* @@ -195,12 +218,12 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, * and memory. Optimize the strides to result in the fewest number of * I/O requests. */ - mem_start = H5V_hyper_stride (ndims, hslab_size, mem_size, - mem_offset, mem_stride/*out*/); - file_start = H5V_hyper_stride (ndims, hslab_size, layout->dim, - file_offset, file_stride/*out*/); - H5V_stride_optimize2 (&ndims, &elmt_size, hslab_size, - mem_stride, file_stride); + mem_start = H5V_hyper_stride(ndims, hslab_size, mem_size, + mem_offset, mem_stride/*out*/); + file_start = H5V_hyper_stride(ndims, hslab_size, layout->dim, + file_offset, file_stride/*out*/); + H5V_stride_optimize2(&ndims, &elmt_size, hslab_size, + mem_stride, file_stride); /* * Initialize loop variables. The loop is a multi-dimensional loop @@ -208,8 +231,8 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, * element of IDX is treated as a digit with IDX[0] being the least * significant digit. */ - H5V_vector_cpy (ndims, idx, hslab_size); - nelmts = H5V_vector_reduce_product (ndims, hslab_size); + H5V_vector_cpy(ndims, idx, hslab_size); + nelmts = H5V_vector_reduce_product(ndims, hslab_size); if (efl && efl->nused>0) { addr = 0; } else { @@ -223,19 +246,20 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, * memory. */ #ifdef HAVE_PARALLEL - if (xfer->xfer_mode==H5D_XFER_COLLECTIVE){ - /* Currently supports same number of collective access. - * Need to be changed LATER to combine all reads into one - * collective MPIO call. + if (H5FD_MPIO_COLLECTIVE==xfer_mode){ + /* + * Currently supports same number of collective access. Need to + * be changed LATER to combine all reads into one collective MPIO + * call. */ unsigned long max, min, temp; temp = nelmts; assert(temp==nelmts); /* verify no overflow */ MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX, - f->shared->access_parms->u.mpio.comm); + H5FD_mpio_communicator(f->shared->lf)); MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN, - f->shared->access_parms->u.mpio.comm); + H5FD_mpio_communicator(f->shared->lf)); #ifdef AKC printf("nelmts=%lu, min=%lu, max=%lu\n", temp, min, max); #endif @@ -250,18 +274,17 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, /* Read from file */ if (efl && efl->nused>0) { - if (H5O_efl_read (f, efl, addr, elmt_size, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "external data read failed"); + if (H5O_efl_read(f, efl, addr, elmt_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "external data read failed"); } - } else if (H5F_block_read (f, addr, elmt_size, xfer, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "block read failed"); + } else if (H5F_block_read(f, addr, elmt_size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "block read failed"); } /* Decrement indices and advance pointers */ for (j=ndims-1, carray=TRUE; j>=0 && carray; --j) { - addr += file_stride[j]; buf += mem_stride[j]; @@ -277,29 +300,29 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, * into a proper hyperslab. */ if (efl && efl->nused>0) { - HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, - "chunking and external files are mutually " - "exclusive"); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "chunking and external files are mutually " + "exclusive"); } for (i=0; i<layout->ndims; i++) { if (0!=mem_offset[i] || hslab_size[i]!=mem_size[i]) { - HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, - "unable to copy into a proper hyperslab"); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "unable to copy into a proper hyperslab"); } } - if (H5F_istore_read (f, xfer, layout, pline, fill, file_offset, + if (H5F_istore_read(f, dxpl_id, layout, pline, fill, file_offset, hslab_size, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed"); } break; default: - assert ("not implemented yet" && 0); - HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, - "unsupported storage layout"); + assert("not implemented yet" && 0); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "unsupported storage layout"); } - FUNC_LEAVE (SUCCEED); + FUNC_LEAVE(SUCCEED); } @@ -324,23 +347,25 @@ H5F_arr_read (H5F_t *f, const H5F_xfer_t *xfer, * Friday, January 16, 1998 * * Modifications: - * June 2, 1998 Albert Cheng + * Albert Cheng, 1998-06-02 * Added xfer_mode argument * - * Sep 28, 1998 Robb Matzke + * Robb Matzke, 1998-09-28 * Added `xfer' argument, removed `xfer_mode' argument since it * is a member of H5F_xfer_t. * + * Robb Matzke, 1999-08-02 + * Data transfer properties are passed by ID since that's how + * the virtual file layer wants them. *------------------------------------------------------------------------- */ herr_t -H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, - const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, - const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, - const hsize_t _hslab_size[], const hsize_t mem_size[], - const hssize_t mem_offset[], const hssize_t file_offset[], - const void *_buf) +H5F_arr_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, + const struct H5O_pline_t *pline, + const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, + const hsize_t _hslab_size[], const hsize_t mem_size[], + const hssize_t mem_offset[], const hssize_t file_offset[], + const void *_buf) { const uint8_t *buf = (const uint8_t *)_buf; /*cast for arithmetic */ hssize_t file_stride[H5O_LAYOUT_NDIMS]; /*strides through file */ @@ -355,8 +380,11 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, haddr_t addr; /*address in file */ intn i, j; /*counters */ hbool_t carray; /*carry for subtraction */ +#ifdef HAVE_PARALLEL + H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; +#endif - FUNC_ENTER (H5F_arr_write, FAIL); + FUNC_ENTER(H5F_arr_write, FAIL); /* Check args */ assert(f); @@ -368,17 +396,29 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, assert(buf); /* Make a local copy of _size so we can modify it */ - H5V_vector_cpy (layout->ndims, hslab_size, _hslab_size); + H5V_vector_cpy(layout->ndims, hslab_size, _hslab_size); #ifdef HAVE_PARALLEL - if (xfer->xfer_mode==H5D_XFER_COLLECTIVE) { - if (layout->type != H5D_CONTIGUOUS) { - HRETURN_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, - "collective access on non-contiguous datasets not " - "supported yet"); + { + /* Get the transfer mode */ + H5F_xfer_t *dxpl; + H5FD_mpio_dxpl_t *dx; + if (H5P_DEFAULT!=dxpl_id && (dxpl=H5I_object(dxpl_id)) && + H5FD_MPIO==dxpl->driver_id && (dx=dxpl->driver_info) && + H5FD_MPIO_INDEPENDENT!=dx->xfer_mode) { + xfer_mode = dx->xfer_mode; } } #endif + +#ifdef HAVE_PARALLEL + if (H5D_CONTIGUOUS!=layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode) { + HRETURN_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, + "collective access on non-contiguous datasets not " + "supported yet"); + } +#endif + #ifdef QAK { extern int qak_debug; @@ -403,8 +443,8 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, */ for (i=0; i<ndims; i++) { if (mem_offset[i]<0 || file_offset[i]<0) { - HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, - "negative offsets are not valid"); + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "negative offsets are not valid"); } } @@ -412,8 +452,8 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, * Filters cannot be used for contiguous data */ if (pline && pline->nfilters>0) { - HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, - "filters are not allowed for contiguous data"); + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "filters are not allowed for contiguous data"); } /* @@ -421,12 +461,12 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, * Optimize the strides to result in the fewest number of I/O * requests. */ - mem_start = H5V_hyper_stride (ndims, hslab_size, mem_size, - mem_offset, mem_stride/*out*/); - file_start = H5V_hyper_stride (ndims, hslab_size, layout->dim, - file_offset, file_stride/*out*/); - H5V_stride_optimize2 (&ndims, &elmt_size, hslab_size, - mem_stride, file_stride); + mem_start = H5V_hyper_stride(ndims, hslab_size, mem_size, + mem_offset, mem_stride/*out*/); + file_start = H5V_hyper_stride(ndims, hslab_size, layout->dim, + file_offset, file_stride/*out*/); + H5V_stride_optimize2(&ndims, &elmt_size, hslab_size, + mem_stride, file_stride); /* * Initialize loop variables. The loop is a multi-dimensional loop @@ -434,8 +474,8 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, * element of IDX is treated as a digit with IDX[0] being the least * significant digit. */ - H5V_vector_cpy (ndims, idx, hslab_size); - nelmts = H5V_vector_reduce_product (ndims, hslab_size); + H5V_vector_cpy(ndims, idx, hslab_size); + nelmts = H5V_vector_reduce_product(ndims, hslab_size); if (efl && efl->nused>0) { addr = 0; } else { @@ -449,19 +489,20 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, * disk. */ #ifdef HAVE_PARALLEL - if (xfer->xfer_mode==H5D_XFER_COLLECTIVE){ - /* Currently supports same number of collective access. - * Need to be changed LATER to combine all writes into one - * collective MPIO call. + if (H5FD_MPIO_COLLECTIVE==xfer_mode){ + /* + * Currently supports same number of collective access. Need to + * be changed LATER to combine all writes into one collective + * MPIO call. */ unsigned long max, min, temp; temp = nelmts; assert(temp==nelmts); /* verify no overflow */ MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX, - f->shared->access_parms->u.mpio.comm); + H5FD_mpio_communicator(f->shared->lf)); MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN, - f->shared->access_parms->u.mpio.comm); + H5FD_mpio_communicator(f->shared->lf)); #ifdef AKC printf("nelmts=%lu, min=%lu, max=%lu\n", temp, min, max); #endif @@ -477,18 +518,17 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, /* Write to file */ if (efl && efl->nused>0) { - if (H5O_efl_write (f, efl, addr, elmt_size, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "external data write failed"); + if (H5O_efl_write(f, efl, addr, elmt_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "external data write failed"); } - } else if (H5F_block_write(f, addr, elmt_size, xfer, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, - "block write failed"); + } else if (H5F_block_write(f, addr, elmt_size, dxpl_id, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "block write failed"); } /* Decrement indices and advance pointers */ for (j=ndims-1, carray=TRUE; j>=0 && carray; --j) { - addr += file_stride[j]; buf += mem_stride[j]; @@ -505,27 +545,27 @@ H5F_arr_write (H5F_t *f, const H5F_xfer_t *xfer, * from a proper hyperslab. */ if (efl && efl->nused>0) { - HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, - "chunking and external files are mutually " - "exclusive"); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "chunking and external files are mutually " + "exclusive"); } for (i=0; i<layout->ndims; i++) { if (0!=mem_offset[i] || hslab_size[i]!=mem_size[i]) { - HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, - "unable to copy from a proper hyperslab"); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "unable to copy from a proper hyperslab"); } } - if (H5F_istore_write (f, xfer, layout, pline, fill, file_offset, - hslab_size, buf)<0) { - HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, - "chunked write failed"); + if (H5F_istore_write(f, dxpl_id, layout, pline, fill, file_offset, + hslab_size, buf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "chunked write failed"); } break; default: - assert ("not implemented yet" && 0); - HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, - "unsupported storage layout"); + assert("not implemented yet" && 0); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, + "unsupported storage layout"); } FUNC_LEAVE (SUCCEED); diff --git a/src/H5Fcore.c b/src/H5Fcore.c deleted file mode 100644 index 882648c..0000000 --- a/src/H5Fcore.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (C) 1997 NCSA - * All rights reserved. - * - * Programmer: Robb Matzke <matzke@llnl.gov> - * Wednesday, October 22, 1997 - * - * Purpose: This file implements an in-core temporary file. It's intended - * for storing small temporary files such as wrappers generated - * on the fly. - * - * Note: This is mostly an exercise to help clean up parts of the H5F - * package since this driver is quite different than the other - * low level drivers we have so far. - * - */ -#include <H5private.h> -#include <H5Eprivate.h> -#include <H5Fprivate.h> -#include <H5MMprivate.h> - -#define H5F_CORE_DEV 0xffff /*pseudo dev for core until we fix things */ - -#define PABLO_MASK H5Fcore_mask -static intn interface_initialize_g = 0; -#define INTERFACE_INIT NULL - -static htri_t H5F_core_access(const char *name, - const H5F_access_t *access_parms, int mode, - H5F_search_t *key/*out*/); -static H5F_low_t *H5F_core_open(const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/); -static herr_t H5F_core_close(H5F_low_t *lf, const H5F_access_t *access_parms); -static herr_t H5F_core_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf); -static herr_t H5F_core_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf); - -const H5F_low_class_t H5F_LOW_CORE_g[1] = {{ - H5F_core_access, /*access method */ - H5F_core_open, /*open method */ - H5F_core_close, /*close method */ - H5F_core_read, /*read method */ - H5F_core_write, /*write method */ - NULL, /*flush method */ - NULL, /*extend method */ - NULL, /*alloc method */ -}}; - - -/*------------------------------------------------------------------------- - * Function: H5F_core_access - * - * Purpose: Determines if the specified file already exists. This driver - * doesn't use names, so every call to H5F_core_open() would - * create a new file. Therefore, this function always returns - * false and KEY is never initialized. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, October 24, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static htri_t -H5F_core_access(const char UNUSED*name, - const H5F_access_t UNUSED *access_parms, - int UNUSED mode, H5F_search_t UNUSED *key/*out*/) -{ - FUNC_ENTER(H5F_core_access, FAIL); - FUNC_LEAVE(FALSE); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_core_open - * - * Purpose: Opens a temporary file which will exist only in memory. The - * NAME argument is unused. The FLAGS are a bit field with - * the possible values defined in H5F_low_open(). - * - * Errors: - * IO CANTOPENFILE Must creat file with write access. - * - * Return: Success: Low-level file pointer - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static H5F_low_t * -H5F_core_open(const char UNUSED *name, - const H5F_access_t UNUSED *access_parms, - uintn flags, H5F_search_t *key/*out*/) -{ - H5F_low_t *lf = NULL; - static ino_t ino = 0; - - FUNC_ENTER(H5F_core_open, NULL); - - if (0 == (flags & H5F_ACC_RDWR) || 0 == (flags & H5F_ACC_CREAT)) { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, - "must creat file with write access"); - } - - if (NULL==(lf = H5MM_calloc(sizeof(H5F_low_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - lf->u.core.mem = NULL; - lf->u.core.alloc = 0; - lf->u.core.size = 0; - lf->eof = 0; - - if (key) { - key->dev = H5F_CORE_DEV; - key->ino = ino++; - } - - FUNC_LEAVE(lf); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_core_close - * - * Purpose: Closes a file. - * - * Errors: - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_core_close(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms) -{ - FUNC_ENTER(H5F_core_close, FAIL); - - lf->u.core.mem = H5MM_xfree(lf->u.core.mem); - lf->u.core.size = 0; - lf->u.core.alloc = 0; - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_core_read - * - * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and - * places them in buffer BUF. Reading past the logical or - * physical end of the file returns zeros instead of failing. - * - * Errors: - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_core_read(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms, - const H5F_xfer_t UNUSED *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf) -{ - size_t n; - size_t eof; - - FUNC_ENTER(H5F_core_read, FAIL); - - assert(lf); - assert(H5F_addr_defined(addr)); - assert(buf); - - eof = MIN(lf->eof, lf->u.core.size); - - if (addr >= eof) { - HDmemset(buf, 0, size); - } else { - n = MIN(size, eof-addr); - HDmemcpy(buf, lf->u.core.mem + addr, n); - HDmemset(buf+n, 0, size-n); - } - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_core_write - * - * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at - * file address ADDR. The file is extended as necessary to - * accommodate the new data. - * - * Errors: - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_core_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t UNUSED *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf) -{ - size_t need_more, na; - size_t increment = 1; - uint8_t *x = NULL; - - FUNC_ENTER(H5F_core_write, FAIL); - - assert(lf); - assert(H5F_addr_defined(addr)); - assert(buf); - assert (!access_parms || H5F_LOW_CORE==access_parms->driver); - - /* - * Allocate more space. We always allocate a multiple of the increment - * size, which is either defined in the file access property list or - * which defaults to one. - */ - if (addr + size > lf->u.core.alloc) { - if (access_parms) increment = access_parms->u.core.increment; - need_more = addr+size - lf->u.core.alloc; - need_more = increment*((need_more+increment-1)/increment); - - na = lf->u.core.alloc + need_more; - if (NULL==(x = H5MM_realloc (lf->u.core.mem, na))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - lf->u.core.alloc = na; - lf->u.core.mem = x; - } - - /* Move the physical EOF marker */ - if (addr + size > lf->u.core.size) { - lf->u.core.size = addr + size; - } - - /* Copy data */ - HDmemcpy(lf->u.core.mem+addr, buf, size); - - FUNC_LEAVE(SUCCEED); -} diff --git a/src/H5Ffamily.c b/src/H5Ffamily.c deleted file mode 100644 index ac50541..0000000 --- a/src/H5Ffamily.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (C) 1997 Spizella Software - * All rights reserved. - * - * Programmer: Robb Matzke <matzke@llnl.gov> - * Monday, November 10, 1997 - * - * Purpose: Implements a family of files that acts as a single hdf5 - * file. The purpose is to be able to split a huge file on a - * 64-bit platform, transfer all the <2GB members to a 32-bit - * platform, and then access the entire huge file on the 32-bit - * platform. - * - * All family members are logically the same size although their - * physical sizes may vary. The logical member size is - * determined by looking at the physical size of the first - * member and rounding that up to the next power of two. When - * creating a file family, the first member is created with a - * predefined physical size (actually, this happens when the - * file family is flushed, and can be quite time consuming on - * file systems that don't implement holes, like nfs). - * - */ -#include <H5private.h> -#include <H5Eprivate.h> -#include <H5Fprivate.h> -#include <H5MMprivate.h> - -#define PABLO_MASK H5Ffamily_mask -static intn interface_initialize_g = 0; -#define INTERFACE_INIT NULL - -#define H5F_FAM_OFFSET(LF,ADDR) ((off_t)((ADDR) % (LF)->u.fam.memb_size)) -#define H5F_FAM_MEMBNO(LF,ADDR) ((intn)((ADDR) / (LF)->u.fam.memb_size)) - -static htri_t H5F_fam_access(const char *name, - const H5F_access_t *access_parms, int mode, - H5F_search_t *key/*out*/); -static H5F_low_t *H5F_fam_open(const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/); -static herr_t H5F_fam_close(H5F_low_t *lf, const H5F_access_t *access_parms); -static herr_t H5F_fam_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf); -static herr_t H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf); -static herr_t H5F_fam_flush(H5F_low_t *lf, const H5F_access_t *access_parms); - -const H5F_low_class_t H5F_LOW_FAMILY_g[1] = {{ - H5F_fam_access, /*access method */ - H5F_fam_open, /*open method */ - H5F_fam_close, /*close method */ - H5F_fam_read, /*read method */ - H5F_fam_write, /*write method */ - H5F_fam_flush, /*flush method */ - NULL, /*extend method */ - NULL, /*alloc method */ -}}; - - -/*------------------------------------------------------------------------- - * Function: H5F_fam_open - * - * Purpose: Opens a file family with the specified base name. The name - * should contain a printf-style "%d" field which will be - * expanded with a zero-origin family member number. - * - * Bugs: We don't check for overflow on the name, so keep it under - * 4kb, please. Also, we don't actually check for the `%d' - * field because we assume that the caller already did. Who - * knows what happens when all the family member names are the - * same! - * - * Return: Success: Low-level file pointer - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Monday, November 10, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static H5F_low_t * -H5F_fam_open(const char *name, const H5F_access_t *access_parms, - uintn flags, H5F_search_t *key/*out*/) -{ - H5F_low_t *ret_value = NULL; - H5F_low_t *lf = NULL; - H5F_low_t *member = NULL; /*a family member */ - char member_name[4096]; /*name of family member */ - intn membno; /*member number (zero-origin) */ - haddr_t tmp_addr; /*temporary address */ - const H5F_low_class_t *memb_type; /*type of family member */ - - FUNC_ENTER(H5F_fam_open, NULL); - - assert (access_parms); - assert (H5F_LOW_FAMILY==access_parms->driver); - assert (access_parms->u.fam.memb_access); - memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver); - - /* - * If we're truncating the file then delete all but the first family - * member. - */ - if ((flags & H5F_ACC_RDWR) && (flags & H5F_ACC_TRUNC)) { - for (membno=1; /*void*/; membno++) { - sprintf(member_name, name, membno); - if (!H5F_low_access(memb_type, member_name, - access_parms->u.fam.memb_access, - F_OK, NULL)) { - break; - } else if (HDunlink(member_name) < 0) { - HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "can't delete member"); - } - } - } - - /* Create the file descriptor */ - if (NULL==(lf = H5MM_calloc(sizeof(H5F_low_t))) || - NULL==(lf->u.fam.name = H5MM_strdup(name))) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - lf->u.fam.flags = (flags & ~H5F_ACC_CREAT); - - /* Open all existing members */ - for (membno = 0; /*void*/; membno++) { - sprintf(member_name, name, membno); - - /* - * Open the family member. After the first member is opened or - * created, turn off the creation flag so we don't create a zillion - * family members. - */ - member = H5F_low_open(memb_type, member_name, - access_parms->u.fam.memb_access, flags, - 0 == membno ? key : NULL); - if (!member) { - if (0 == membno) { - HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, - "can't open first family member"); - } - break; - } - flags &= ~H5F_ACC_CREAT; - - /* Add the member to the family */ - if (lf->u.fam.nmemb >= lf->u.fam.nalloc) { - size_t na = MAX (100, 2*lf->u.fam.nalloc); - H5F_low_t **x = H5MM_realloc (lf->u.fam.memb, - na*sizeof(H5F_low_t*)); - if (NULL==x) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - lf->u.fam.nalloc = (intn)na; - lf->u.fam.memb = x; - } - lf->u.fam.memb[lf->u.fam.nmemb++] = member; - member = NULL; - } - - H5F_low_size (lf->u.fam.memb[0], &tmp_addr/*out*/); - if (1==lf->u.fam.nmemb && - H5F_addr_gt (tmp_addr, access_parms->u.fam.memb_size)) { - /* - * If there's only one member and the member is larger than the - * specified member size, then adjust the specified member size to be - * the same as the actual member size, but at least 1kB - */ -#ifdef H5F_DEBUG - if (H5DEBUG(F)) { - HDfprintf (H5DEBUG(F), "H5F: family member size has been " - "increased from %a to %a\n", - access_parms->u.fam.memb_size, tmp_addr); - } -#endif - if (tmp_addr<1024) tmp_addr = 1024; - lf->u.fam.memb_size = tmp_addr; - - } else if (1==lf->u.fam.nmemb) { - /* - * If there's just one member then use the specified size for the - * family members. - */ - lf->u.fam.memb_size = access_parms->u.fam.memb_size; - - } else if (lf->u.fam.nmemb>1 && - H5F_addr_ne(tmp_addr, access_parms->u.fam.memb_size)) { - /* - * If there are more than one member then use the size of the first - * member as the member size. - */ -#ifdef H5F_DEBUG - if (H5DEBUG(F)) { - HDfprintf (H5DEBUG(F), "H5F: family member size adjusted from " - "%a to %a\n", access_parms->u.fam.memb_size, tmp_addr); - } -#endif - lf->u.fam.memb_size = tmp_addr; - for (membno=1; membno<lf->u.fam.nmemb; membno++) { - H5F_low_size(lf->u.fam.memb[membno], &tmp_addr/*out*/); - if (H5F_addr_gt(tmp_addr, lf->u.fam.memb_size)) { - HGOTO_ERROR (H5E_IO, H5E_CANTINIT, NULL, "family contains " - "member(s) larger than first member"); - } - } - - } else { - /* The family member size is the size of the first family member */ - lf->u.fam.memb_size = tmp_addr; - } - -#ifdef H5F_DEBUG - /* - * Check for funny member sizes. One common mistake is to use 2^32 as the - * member size but on a 32-bit machine this isn't possible. The largest - * file on a 32-bit machine is 2^32-1. - */ - if (H5DEBUG(F) && - lf->u.fam.memb_size == ((size_t)1<<(sizeof(off_t)-1))) { - HDfprintf(H5DEBUG(F), "H5F: family member size may be too large: %a\n", - lf->u.fam.memb_size); - } -#endif - - /* - * Get the total family size and store it in the max_addr field. - */ - assert(lf->u.fam.nmemb >= 1); - lf->eof = lf->u.fam.memb_size; - lf->eof *= (lf->u.fam.nmemb-1); - lf->eof += lf->u.fam.memb[lf->u.fam.nmemb-1]->eof; - - HRETURN(lf); - - done: - if (!ret_value) { - if (lf) { - H5F_fam_close(lf, access_parms); - H5MM_xfree(lf); - } - } - FUNC_LEAVE(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_fam_close - * - * Purpose: Closes all members of a file family and releases resources - * used by the file descriptor. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 10, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_fam_close(H5F_low_t *lf, const H5F_access_t *access_parms) -{ - intn membno; - - FUNC_ENTER(H5F_fam_close, FAIL); - - assert(lf); - - for (membno = 0; membno < lf->u.fam.nmemb; membno++) { - lf->u.fam.memb[membno] = H5F_low_close(lf->u.fam.memb[membno], - access_parms->u.fam.memb_access); - } - H5MM_xfree(lf->u.fam.memb); - H5MM_xfree(lf->u.fam.name); - - FUNC_LEAVE(SUCCEED); -} - -/*------------------------------------------------------------------------- - * Function: H5F_fam_read - * - * Purpose: Reads a chunk of contiguous data from the file family. - * Reading past the physical end of a file returns zeros instead - * of failing. We must insure that if the logical end of file is - * before the physical end of file that we will read zeros there - * also (the only time this can happen is if we create a family - * and then close it before the first member is filled, since - * flushing the file causes the first member to be physically - * extended to it's maximum size). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 10, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_fam_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - uint8_t *buf) -{ - size_t nbytes; - haddr_t cur_addr; - haddr_t offset, member_size; - intn membno; - - FUNC_ENTER(H5F_fam_read, FAIL); - - assert(lf); - assert(H5F_addr_defined(addr)); - assert(buf); - - member_size = lf->u.fam.memb_size; - membno = H5F_FAM_MEMBNO(lf, addr); - offset = H5F_FAM_OFFSET(lf, addr); - cur_addr = addr; - - while (size > 0) { - if (membno >= lf->u.fam.nmemb) { - HDmemset(buf, 0, size); - break; - } else { - nbytes = MIN(size, member_size-offset); - cur_addr = offset; - if (H5F_low_read(lf->u.fam.memb[membno], - access_parms->u.fam.memb_access, xfer_parms, - cur_addr, nbytes, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "can't read from family member"); - } - buf += nbytes; - size -= nbytes; - membno++; - offset = 0; - } - } - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_fam_write - * - * Purpose: Writes BUF to the family of files. The superclass has - * already insured that we aren't writing past the logical end - * of file, so this function will extend the physical file to - * accommodate the new data if necessary. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 10, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - const uint8_t *buf) -{ - size_t nbytes; - haddr_t cur_addr, max_addr; - intn membno; - haddr_t offset, member_size; - H5F_low_t *member = NULL; - char member_name[4096]; - intn i; - const H5F_low_class_t *memb_type = NULL; - - FUNC_ENTER(H5F_fam_write, FAIL); - - /* Check args */ - assert(lf); - assert(H5F_addr_defined(addr)); - assert(buf); - assert (access_parms); - assert (H5F_LOW_FAMILY==access_parms->driver); - assert (access_parms->u.fam.memb_access); - - /* Get the member driver */ - memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver); - member_size = lf->u.fam.memb_size; - membno = H5F_FAM_MEMBNO(lf, addr); - offset = H5F_FAM_OFFSET(lf, addr); - cur_addr = addr; - - while (size > 0) { - nbytes = MIN(size, member_size-offset); - cur_addr = offset; - - if (membno >= lf->u.fam.nmemb) { - /* - * We're writing past the end of the last family member--create the - * new family member(s) - */ - if (membno >= lf->u.fam.nalloc) { - size_t na = (membno+1)*2; - H5F_low_t **x = H5MM_realloc (lf->u.fam.memb, - na*sizeof(H5F_low_t*)); - if (NULL==x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - lf->u.fam.nalloc = (intn)na; - lf->u.fam.memb = x; - } - for (i = lf->u.fam.nmemb; i <= membno; i++) { - sprintf(member_name, lf->u.fam.name, i); - member = H5F_low_open(memb_type, member_name, - access_parms->u.fam.memb_access, - lf->u.fam.flags | H5F_ACC_CREAT, - NULL); - if (!member) { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL, - "can't create a new member"); - } - - /* - * For members in the middle, set their logical eof to the - * maximum possible value. - */ - if (i < membno) { - max_addr = member_size; - H5F_low_seteof(member, max_addr); - } - lf->u.fam.memb[lf->u.fam.nmemb++] = member; - } - } - - /* - * Make sure the logical eof is large enough to handle the request. - * Do not decrease the EOF - */ - max_addr = cur_addr + (hsize_t)nbytes; - if (H5F_addr_gt(max_addr, lf->u.fam.memb[membno]->eof)) { - H5F_low_seteof(lf->u.fam.memb[membno], max_addr); - } - - /* Write the data to the member */ - if (H5F_low_write(lf->u.fam.memb[membno], - access_parms->u.fam.memb_access, xfer_parms, - cur_addr, nbytes, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "can't write to family member"); - } - buf += nbytes; - size -= nbytes; - membno++; - offset = 0; - } - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_fam_flush - * - * Purpose: Flushes all data to disk and makes sure that the first member - * is as large as a member can be so we can accurately detect - * the member size if we open this file for read access at a - * later date. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 10, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_fam_flush(H5F_low_t *lf, const H5F_access_t *access_parms) -{ - int membno, nerrors = 0; - uint8_t buf[1]; - haddr_t addr1, addr2, addr3; - hsize_t max_offset; - - FUNC_ENTER(H5F_fam_flush, FAIL); - - /* - * Make sure that the first family member is the maximum size because - * H5F_fam_open() looks at the size of the first member to determine the - * size of each family member. We do this by reading the last possible - * byte from the member (which defaults to zero if we're reading past the - * end of the member) and then writing it back. - */ - max_offset = lf->u.fam.memb_size - 1; - addr1 = max_offset; - H5F_low_size(lf->u.fam.memb[0], &addr2/*out*/);/*remember logical eof */ - addr3 = addr1 + 1; - H5F_low_seteof(lf->u.fam.memb[0], addr3); /*prevent a warning */ - if (H5F_low_read(lf->u.fam.memb[0], access_parms->u.fam.memb_access, - &H5F_xfer_dflt, addr1, 1, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "can't read from first family member"); - } - if (H5F_low_write(lf->u.fam.memb[0], access_parms->u.fam.memb_access, - &H5F_xfer_dflt, addr1, 1, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "can't write to first family member"); - } - H5F_low_seteof(lf->u.fam.memb[0], addr2); /*reset old eof */ - - /* - * Flush each member file. Don't return an error status until we've - * flushed as much as possible. - */ - for (membno = 0; membno < lf->u.fam.nmemb; membno++) { - if (H5F_low_flush(lf->u.fam.memb[membno], - access_parms->u.fam.memb_access) < 0) { - nerrors++; - } - } - if (nerrors) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "can't flush family member"); - } - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_fam_access - * - * Purpose: Determines if all members of the file family can be accessed - * and returns the key for the first member of the family. - * - * Return: Success: TRUE or FALSE - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Monday, November 10, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static htri_t -H5F_fam_access(const char *name, const H5F_access_t *access_parms, - int mode, H5F_search_t *key/*out*/) -{ - intn membno; - char member_name[4096]; - htri_t status; - htri_t ret_value = FALSE; - const H5F_low_class_t *memb_type = NULL; - - FUNC_ENTER(H5F_fam_access, FAIL); - - /* Check args */ - assert (name && *name); - assert (access_parms); - assert (H5F_LOW_FAMILY==access_parms->driver); - assert (access_parms->u.fam.memb_access); - - /* Get the driver for the family members */ - memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver); - - /* Access the members */ - for (membno=0; /*void*/; membno++) { - sprintf(member_name, name, membno); - status = H5F_low_access(memb_type, member_name, NULL, mode, - 0 == membno ? key : NULL); - - if (!status) { - if (F_OK == mode) { - /* - * If we didn't find a member then we must have gotten to the - * end of the family. As long as we found the first - * member(s) the family exists. - */ - ret_value = membno > 0 ? TRUE : FALSE; - break; - - } else if (H5F_low_access(memb_type, member_name, - access_parms->u.fam.memb_access, - F_OK, NULL)) { - /* - * The file exists but didn't have the write access permissions. - */ - ret_value = FALSE; - break; - - } else { - /* - * The file doesn't exist because we got to the end of the - * family. - */ - ret_value = TRUE; - break; - } - } - if (status < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL, - "access method failed for a member file"); - } - } - - FUNC_LEAVE(ret_value); -} diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 6052b31..4849e98 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -33,11 +33,16 @@ #include <H5Dprivate.h> #include <H5Eprivate.h> #include <H5Fprivate.h> +#include <H5Iprivate.h> #include <H5MFprivate.h> #include <H5MMprivate.h> #include <H5Oprivate.h> +#include <H5Pprivate.h> #include <H5Vprivate.h> +/* MPIO driver needed for special checks */ +#include <H5FDmpio.h> + /* * Feature: If this constant is defined then every cache preemption and load * causes a character to be printed on the standard error stream: @@ -487,7 +492,8 @@ H5F_istore_new_node(H5F_t *f, H5B_ins_t op, #ifdef AKC printf("calling H5MF_alloc for new chunk\n"); #endif - if (H5MF_alloc(f, H5MF_RAW, udata->key.nbytes, addr_p/*out*/) < 0) { + if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, + udata->key.nbytes))) { HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "couldn't allocate new file storage"); } @@ -669,8 +675,9 @@ H5F_istore_insert(H5F_t *f, haddr_t addr, void *_lt_key, #ifdef AKC printf("calling H5MF_realloc for new chunk\n"); #endif - if (H5MF_realloc (f, H5MF_RAW, lt_key->nbytes, addr, - udata->key.nbytes, new_node_p/*out*/)<0) { + if (HADDR_UNDEF==(*new_node_p=H5MF_realloc(f, H5FD_MEM_BTREE, addr, + lt_key->nbytes, + udata->key.nbytes))) { HRETURN_ERROR (H5E_STORAGE, H5E_WRITEERROR, H5B_INS_ERROR, "unable to reallocate chunk storage"); } @@ -707,7 +714,8 @@ H5F_istore_insert(H5F_t *f, haddr_t addr, void *_lt_key, #ifdef AKC printf("calling H5MF_alloc for new chunk\n"); #endif - if (H5MF_alloc(f, H5MF_RAW, udata->key.nbytes, new_node_p/*out*/)<0) { + if (HADDR_UNDEF==(*new_node_p=H5MF_alloc(f, H5FD_MEM_BTREE, + udata->key.nbytes))) { HRETURN_ERROR(H5E_IO, H5E_CANTINIT, H5B_INS_ERROR, "file allocation failed"); } @@ -798,9 +806,9 @@ H5F_istore_init (H5F_t *f) FUNC_ENTER (H5F_istore_init, FAIL); HDmemset (rdcc, 0, sizeof(H5F_rdcc_t)); - if (f->shared->access_parms->rdcc_nbytes>0 && - f->shared->access_parms->rdcc_nelmts>0) { - rdcc->nslots = f->shared->access_parms->rdcc_nelmts; + if (f->shared->fapl->rdcc_nbytes>0 && + f->shared->fapl->rdcc_nelmts>0) { + rdcc->nslots = f->shared->fapl->rdcc_nelmts; rdcc->slot = H5MM_calloc (rdcc->nslots*sizeof(H5F_rdcc_ent_t*)); if (NULL==rdcc->slot) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, @@ -830,7 +838,7 @@ H5F_istore_init (H5F_t *f) *------------------------------------------------------------------------- */ static herr_t -H5F_istore_flush_entry (H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) +H5F_istore_flush_entry(H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) { herr_t ret_value=FAIL; /*return value */ H5F_istore_ud1_t udata; /*pass through B-tree */ @@ -839,16 +847,16 @@ H5F_istore_flush_entry (H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) size_t alloc; /*bytes allocated for BUF */ hbool_t point_of_no_return = FALSE; - FUNC_ENTER (H5F_istore_flush_entry, FAIL); + FUNC_ENTER(H5F_istore_flush_entry, FAIL); assert(f); assert(ent); - assert (!ent->locked); + assert(!ent->locked); buf = ent->chunk; if (ent->dirty) { udata.mesg = *(ent->layout); udata.key.filter_mask = 0; - udata.addr = H5F_ADDR_UNDEF; + udata.addr = HADDR_UNDEF; udata.key.nbytes = ent->chunk_size; for (i=0; i<ent->layout->ndims; i++) { udata.key.offset[i] = ent->offset[i]; @@ -893,13 +901,13 @@ H5F_istore_flush_entry (H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) */ if (H5B_insert(f, H5B_ISTORE, ent->layout->addr, ent->split_ratios, &udata)<0) { - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, - "unable to allocate chunk"); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "unable to allocate chunk"); } - if (H5F_block_write (f, udata.addr, udata.key.nbytes, - &H5F_xfer_dflt, buf)<0) { - HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, - "unable to write raw data to file"); + if (H5F_block_write(f, udata.addr, udata.key.nbytes, H5P_DEFAULT, + buf)<0) { + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "unable to write raw data to file"); } /* Mark cache entry as clean */ @@ -933,7 +941,7 @@ H5F_istore_flush_entry (H5F_t *f, H5F_rdcc_ent_t *ent, hbool_t reset) ent->pline = H5O_free(H5O_PLINE, ent->pline); ent->chunk = H5MM_xfree(ent->chunk); } - FUNC_LEAVE (ret_value); + FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- @@ -1103,7 +1111,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->access_parms->rdcc_nbytes; + size_t total = f->shared->fapl->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 */ @@ -1121,7 +1129,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->access_parms->rdcc_w0; + w[0] = rdcc->nused * f->shared->fapl->rdcc_w0; p[0] = rdcc->head; p[1] = NULL; @@ -1214,14 +1222,16 @@ H5F_istore_prune (H5F_t *f, size_t size) * Thursday, May 21, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * The split ratios are passed in as part of the data transfer + * property list. *------------------------------------------------------------------------- */ static void * -H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, - const double split_ratios[], const H5O_pline_t *pline, - const H5O_fill_t *fill, const hssize_t offset[], - hbool_t relax, intn *idx_hint/*in,out*/) +H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, + const H5O_pline_t *pline, const H5O_fill_t *fill, + const hssize_t offset[], hbool_t relax, + intn *idx_hint/*in,out*/) { uintn idx=0; /*hash index number */ hbool_t found = FALSE; /*already in cache? */ @@ -1236,7 +1246,6 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, void *ret_value=NULL; /*return value */ FUNC_ENTER (H5F_istore_lock, NULL); - assert(split_ratios); if (rdcc->nslots>0) { /* We don't care about loss of precision in the following statement. */ @@ -1299,7 +1308,7 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, } chunk_alloc = chunk_size; udata.mesg = *layout; - udata.addr = H5F_ADDR_UNDEF; + udata.addr = HADDR_UNDEF; status = H5B_find (f, H5B_ISTORE, layout->addr, &udata); H5E_clear (); if (NULL==(chunk = H5MM_malloc (chunk_alloc))) { @@ -1310,8 +1319,8 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, /* * The chunk exists on disk. */ - if (H5F_block_read(f, udata.addr, udata.key.nbytes, - &H5F_xfer_dflt, chunk)<0) { + if (H5F_block_read(f, udata.addr, udata.key.nbytes, H5P_DEFAULT, + chunk)<0) { HGOTO_ERROR (H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk"); } @@ -1345,7 +1354,7 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, assert (found || chunk_size>0); if (!found && rdcc->nslots>0 && - chunk_size<=f->shared->access_parms->rdcc_nbytes && + chunk_size<=f->shared->fapl->rdcc_nbytes && (!ent || !ent->locked)) { /* * Add the chunk to the cache only if the slot is not already locked. @@ -1392,10 +1401,15 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, ent->rd_count = chunk_size; ent->wr_count = chunk_size; ent->chunk = chunk; - ent->split_ratios[0] = split_ratios[0]; - ent->split_ratios[1] = split_ratios[1]; - ent->split_ratios[2] = split_ratios[2]; - + + { + H5F_xfer_t *dxpl; + dxpl = (H5P_DEFAULT==dxpl_id)?&H5F_xfer_dflt:H5I_object(dxpl_id); + ent->split_ratios[0] = dxpl->split_ratios[0]; + ent->split_ratios[1] = dxpl->split_ratios[1]; + ent->split_ratios[2] = dxpl->split_ratios[2]; + } + /* Add it to the cache */ assert(NULL==rdcc->slot[idx]); rdcc->slot[idx] = ent; @@ -1485,15 +1499,16 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, * Thursday, May 21, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * The split_ratios are passed as part of the data transfer + * property list. *------------------------------------------------------------------------- */ static herr_t -H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout, - const double split_ratios[], - const H5O_pline_t *pline, hbool_t dirty, - const hssize_t offset[], intn *idx_hint, - uint8_t *chunk, size_t naccessed) +H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, + const H5O_pline_t *pline, hbool_t dirty, + const hssize_t offset[], intn *idx_hint, + uint8_t *chunk, size_t naccessed) { H5F_rdcc_t *rdcc = &(f->shared->rdcc); H5F_rdcc_ent_t *ent = NULL; @@ -1529,9 +1544,14 @@ H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout, } x.alloc_size = x.chunk_size; x.chunk = chunk; - x.split_ratios[0] = split_ratios[0]; - x.split_ratios[1] = split_ratios[1]; - x.split_ratios[2] = split_ratios[2]; + { + H5F_xfer_t *dxpl; + dxpl = (H5P_DEFAULT==dxpl_id)?&H5F_xfer_dflt:H5I_object(dxpl_id); + x.split_ratios[0] = dxpl->split_ratios[0]; + x.split_ratios[1] = dxpl->split_ratios[1]; + x.split_ratios[2] = dxpl->split_ratios[2]; + } + H5F_istore_flush_entry (f, &x, TRUE); } else { H5MM_xfree (chunk); @@ -1567,11 +1587,13 @@ H5F_istore_unlock (H5F_t *f, const H5O_layout_t *layout, * Wednesday, October 15, 1997 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * The data transfer property list is passed as an object ID + * since that's how the virtual file layer wants it. *------------------------------------------------------------------------- */ herr_t -H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, +H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, const hssize_t offset_f[], const hsize_t size[], void *buf) { @@ -1592,13 +1614,13 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, FUNC_ENTER(H5F_istore_read, FAIL); /* Check args */ - assert (f); - assert (layout && H5D_CHUNKED==layout->type); - assert (layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS); - assert (H5F_addr_defined(layout->addr)); - assert (offset_f); - assert (size); - assert (buf); + assert(f); + assert(layout && H5D_CHUNKED==layout->type); + assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS); + assert(H5F_addr_defined(layout->addr)); + assert(offset_f); + assert(size); + assert(buf); /* * For now, a hyperslab of the file must be read into an array in @@ -1611,9 +1633,9 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, #ifndef NDEBUG for (i=0; i<layout->ndims; i++) { - assert (offset_f[i]>=0); /*negative offsets not supported*/ - assert (offset_m[i]>=0); /*negative offsets not supported*/ - assert (size[i]<SIZET_MAX); + assert(offset_f[i]>=0); /*negative offsets not supported*/ + assert(offset_m[i]>=0); /*negative offsets not supported*/ + assert(size[i]<SIZET_MAX); assert(offset_m[i]+(hssize_t)size[i]<=(hssize_t)size_m[i]); assert(layout->dim[i]>0); } @@ -1634,7 +1656,7 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, while (1) { for (i=0, naccessed=1; i<layout->ndims; i++) { /* The location and size of the chunk being accessed */ - assert (layout->dim[i] < HSSIZET_MAX); + assert(layout->dim[i] < HSSIZET_MAX); chunk_offset[i] = idx_cur[i] * (hssize_t)(layout->dim[i]); /* The offset and size wrt the chunk */ @@ -1651,32 +1673,29 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, } #ifdef HAVE_PARALLEL /* - * If MPIO is used, must bypass the chunk-cache scheme - * because other MPI processes could be writing to other - * elements in the same chunk. + * If MPIO is used, must bypass the chunk-cache scheme because other + * MPI processes could be writing to other elements in the same chunk. * Do a direct write-through of only the elements requested. */ - if (f->shared->access_parms->driver==H5F_LOW_MPIO){ + if (H5FD_MPIO==f->shared->fapl->driver_id) { H5F_istore_ud1_t udata; H5O_layout_t l; /* temporary layout */ - H5F_xfer_t tmp_xfer = *xfer; + if (H5F_istore_get_addr(f, layout, chunk_offset, &udata)<0){ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk"); }; + /* * use default transfer mode as we do not support collective * transfer mode since each data write could decompose into - * multiple chunk writes and we are not doing the calculation - * yet. + * multiple chunk writes and we are not doing the calculation yet. */ l.type = H5D_CONTIGUOUS; l.ndims = layout->ndims; - for (i=l.ndims; i-- > 0;) - l.dim[i] = layout->dim[i]; + for (i=l.ndims; i-- > 0; /*void*/) l.dim[i] = layout->dim[i]; l.addr = udata.addr; - tmp_xfer.xfer_mode = H5D_XFER_DFLT; - if (H5F_arr_read(f, &tmp_xfer, &l, pline, fill, NULL/*no efl*/, + if (H5F_arr_read(f, H5P_DEFAULT, &l, pline, fill, NULL/*no efl*/, sub_size, size_m, sub_offset_m, offset_wrt_chunk, buf)<0){ HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, @@ -1696,19 +1715,19 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, * Lock the chunk, transfer data to the application, then unlock * the chunk. */ - if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios, - pline, fill, chunk_offset, - FALSE, &idx_hint))) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "unable to read raw data chunk"); + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, pline, fill, + chunk_offset, FALSE, + &idx_hint))) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "unable to read raw data chunk"); } H5V_hyper_copy(layout->ndims, sub_size, size_m, sub_offset_m, (void*)buf, layout->dim, offset_wrt_chunk, chunk); - if (H5F_istore_unlock (f, layout, xfer->split_ratios, pline, - FALSE, chunk_offset, &idx_hint, chunk, - naccessed)<0) { - HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL, - "unable to unlock raw data chunk"); + if (H5F_istore_unlock(f, dxpl_id, layout, pline, FALSE, + chunk_offset, &idx_hint, chunk, + naccessed)<0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "unable to unlock raw data chunk"); } #ifdef HAVE_PARALLEL } @@ -1737,11 +1756,13 @@ H5F_istore_read(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, * Wednesday, October 15, 1997 * * Modifications: - * + * Robb Matzke, 1999-08-02 + * The data transfer property list is passed as an object ID + * since that's how the virtual file layer wants it. *------------------------------------------------------------------------- */ herr_t -H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, +H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_fill_t *fill, const hssize_t offset_f[], const hsize_t size[], const void *buf) @@ -1783,8 +1804,8 @@ H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, #ifndef NDEBUG for (i=0; i<layout->ndims; i++) { - assert (offset_f[i]>=0); /*negative offsets not supported*/ - assert (offset_m[i]>=0); /*negative offsets not supported*/ + assert(offset_f[i]>=0); /*negative offsets not supported*/ + assert(offset_m[i]>=0); /*negative offsets not supported*/ assert(size[i]<SIZET_MAX); assert(offset_m[i]+(hssize_t)size[i]<=(hssize_t)size_m[i]); assert(layout->dim[i]>0); @@ -1808,7 +1829,7 @@ H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, for (i=0, naccessed=1; i<layout->ndims; i++) { /* The location and size of the chunk being accessed */ - assert (layout->dim[i] < HSSIZET_MAX); + assert(layout->dim[i] < HSSIZET_MAX); chunk_offset[i] = idx_cur[i] * (hssize_t)(layout->dim[i]); /* The offset and size wrt the chunk */ @@ -1826,32 +1847,28 @@ H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, #ifdef HAVE_PARALLEL /* - * If MPIO is used, must bypass the chunk-cache scheme - * because other MPI processes could be writing to other - * elements in the same chunk. + * If MPIO is used, must bypass the chunk-cache scheme because other + * MPI processes could be writing to other elements in the same chunk. * Do a direct write-through of only the elements requested. */ - if (f->shared->access_parms->driver==H5F_LOW_MPIO){ + if (H5FD_MPIO==f->shared->fapl->driver_id) { H5F_istore_ud1_t udata; H5O_layout_t l; /* temporary layout */ - H5F_xfer_t tmp_xfer = *xfer; if (H5F_istore_get_addr(f, layout, chunk_offset, &udata)<0){ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk"); }; + /* * use default transfer mode as we do not support collective * transfer mode since each data write could decompose into - * multiple chunk writes and we are not doing the calculation - * yet. + * multiple chunk writes and we are not doing the calculation yet. */ l.type = H5D_CONTIGUOUS; l.ndims = layout->ndims; - for (i=l.ndims; i-- > 0;) - l.dim[i] = layout->dim[i]; + for (i=l.ndims; i-- > 0; /*void*/) l.dim[i] = layout->dim[i]; l.addr = udata.addr; - tmp_xfer.xfer_mode = H5D_XFER_DFLT; - if (H5F_arr_write(f, &tmp_xfer, &l, pline, fill, NULL/*no efl*/, + if (H5F_arr_write(f, H5P_DEFAULT, &l, pline, fill, NULL/*no efl*/, sub_size, size_m, sub_offset_m, offset_wrt_chunk, buf)<0){ HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, @@ -1871,19 +1888,19 @@ H5F_istore_write(H5F_t *f, const H5F_xfer_t *xfer, const H5O_layout_t *layout, * Lock the chunk, copy from application to chunk, then unlock the * chunk. */ - if (NULL==(chunk=H5F_istore_lock (f, layout, xfer->split_ratios, - pline, fill, chunk_offset, - naccessed==chunk_size, - &idx_hint))) { + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, pline, fill, + chunk_offset, + naccessed==chunk_size, + &idx_hint))) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk"); } H5V_hyper_copy(layout->ndims, sub_size, layout->dim, offset_wrt_chunk, chunk, size_m, sub_offset_m, buf); - if (H5F_istore_unlock (f, layout, xfer->split_ratios, pline, TRUE, - chunk_offset, &idx_hint, chunk, - naccessed)<0) { + if (H5F_istore_unlock(f, dxpl_id, layout, pline, TRUE, + chunk_offset, &idx_hint, chunk, + naccessed)<0) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk"); } @@ -2151,7 +2168,7 @@ H5F_istore_get_addr(H5F_t *f, const H5O_layout_t *layout, udata->key.offset[i] = offset[i]; } udata->mesg = *layout; - udata->addr = H5F_ADDR_UNDEF; + udata->addr = HADDR_UNDEF; status = H5B_find (f, H5B_ISTORE, layout->addr, udata); H5E_clear (); if (status>=0 && H5F_addr_defined(udata->addr)) @@ -2180,20 +2197,23 @@ H5F_istore_get_addr(H5F_t *f, const H5O_layout_t *layout, * June 26, 1998 * * Modifications: + * rky, 1998-09-23 + * Added barrier to preclude racing with data writes. * - * rky 980923 - * Added barrier to preclude racing with data writes. - * - * rky 19981207 - * Added Wait-Signal wrapper around unlock-lock critical region - * to prevent race condition (unlock reads, lock writes the chunk). + * rky, 1998-12-07 + * Added Wait-Signal wrapper around unlock-lock critical region + * to prevent race condition (unlock reads, lock writes the + * chunk). * + * Robb Matzke, 1999-08-02 + * The split_ratios are passed in as part of the data transfer + * property list. *------------------------------------------------------------------------- */ herr_t -H5F_istore_allocate (H5F_t *f, const H5O_layout_t *layout, - const hsize_t *space_dim, const double split_ratios[], - const H5O_pline_t *pline, const H5O_fill_t *fill) +H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, + const hsize_t *space_dim, const H5O_pline_t *pline, + const H5O_fill_t *fill) { intn i, carry; @@ -2256,28 +2276,26 @@ H5F_istore_allocate (H5F_t *f, const H5O_layout_t *layout, #ifdef HAVE_PARALLEL /* rky 981207 Serialize access to this critical region. */ if (SUCCEED!= - H5PC_Wait_for_left_neighbor(f->shared->access_parms->u.mpio.comm)) - { + H5FD_mpio_wait_for_left_neighbor(f->shared->lf)) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to lock the data chunk"); } #endif - if (NULL==(chunk=H5F_istore_lock (f, layout, split_ratios, pline, + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, pline, fill, chunk_offset, FALSE, &idx_hint))) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk"); } - if (H5F_istore_unlock (f, layout, split_ratios, pline, TRUE, - chunk_offset, &idx_hint, chunk, - chunk_size)<0) { + if (H5F_istore_unlock(f, dxpl_id, layout, pline, TRUE, + chunk_offset, &idx_hint, chunk, + chunk_size)<0) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk"); } #ifdef HAVE_PARALLEL if (SUCCEED!= - H5PC_Signal_right_neighbor(f->shared->access_parms->u.mpio.comm)) - { + H5FD_mpio_signal_right_neighbor(f->shared->lf)) { HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to unlock the data chunk"); } @@ -2314,7 +2332,7 @@ H5F_istore_allocate (H5F_t *f, const H5O_layout_t *layout, * removed, when H5D_init_storage is changed to call H5MF_alloc directly * to allocate space, instead of calling H5F_istore_unlock. */ - if (MPI_Barrier( f->shared->access_parms->u.mpio.comm )) { + if (MPI_Barrier(H5FD_mpio_communicator(f->shared->lf))) { HRETURN_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "MPI_Barrier failed"); } #endif diff --git a/src/H5Flow.c b/src/H5Flow.c deleted file mode 100644 index 4764388..0000000 --- a/src/H5Flow.c +++ /dev/null @@ -1,778 +0,0 @@ -/* - * Copyright (C) 1997 NCSA - * All rights reserved. - * - * Programmer: Robb Matzke <matzke@viper.llnl.gov> - * Wednesday, October 22, 1997 - * - * Purpose: This file contains virtual functions for the H5F_low - * class. These are functions that operate on various kinds - * of files at a level where the file is just a one-dimensional - * array of bytes. - */ -#include <H5private.h> -#include <H5Eprivate.h> -#include <H5Fprivate.h> -#include <H5MMprivate.h> - -#define PABLO_MASK H5Flow_mask -static intn interface_initialize_g = 0; -#define INTERFACE_INIT NULL - - -/*------------------------------------------------------------------------- - * Function: H5F_low_class - * - * Purpose: Given a driver identifier return the class pointer for that - * low-level driver. - * - * Return: Success: A low-level driver class pointer. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, February 18, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -const H5F_low_class_t * -H5F_low_class (H5F_driver_t driver) -{ - const H5F_low_class_t *type = NULL; - - FUNC_ENTER (H5F_low_class, NULL); - - switch (driver) { - case H5F_LOW_STDIO: - type = H5F_LOW_STDIO_g; - break; - - case H5F_LOW_SEC2: - type = H5F_LOW_SEC2_g; - break; - - case H5F_LOW_CORE: - type = H5F_LOW_CORE_g; - break; - -#ifdef HAVE_PARALLEL - case H5F_LOW_MPIO: - type = H5F_LOW_MPIO_g; - break; -#endif - - case H5F_LOW_SPLIT: - type = H5F_LOW_SPLIT_g; - break; - - case H5F_LOW_FAMILY: - type = H5F_LOW_FAMILY_g; - break; - - default: - HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, NULL, - "unknown low-level driver"); - } - - FUNC_LEAVE (type); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_low_open - * - * Purpose: Opens a file of type TYPE with name NAME according to the - * field of bit flags FLAGS which are: - * - * H5F_ACC_WRITE: The file is open for read/write access. - * Without this bit set, the file would be open - * for read-only access. - * - * H5F_ACC_CREAT: The file is created if it doesn't already - * exist. On unix, the file permissions are set - * to 0666 modified by the umask. - * - * H5F_ACC_EXCL: This function will fail if the file already - * exists. - * - * H5F_ACC_TRUNC: Truncate the file to a zero-length file as it - * is opened. This allows existing files to be - * overwritten. - * - * The KEY argument is initialized with data which is unique to - * this file. Opening the same file (even by a different name) - * should return the same key. - * - * This is a virtual function only; the actual open operation is - * performed by the subclass. This function will fail if the - * subclass hasn't defined an open method. - * - * Errors: - * IO CANTOPENFILE Open failed. - * - * Return: Success: Pointer to the new file descriptor. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5F_low_t * -H5F_low_open(const H5F_low_class_t *type, const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/) -{ - H5F_low_t *lf = NULL; - - FUNC_ENTER(H5F_low_open, NULL); - - assert(type && type->open); - assert(name && *name); - - if (NULL == (lf = (type->open) (name, access_parms, flags, key))) { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "open failed"); - } - lf->type = type; - - FUNC_LEAVE(lf); -} - -/*------------------------------------------------------------------------- - * Function: H5F_low_close - * - * Purpose: Closes a low-level file. The subclass should free all - * resources used by the file descriptor but should not free the - * file descriptor itself. The close method in the subclass is - * optional; lack of a close method results in only the file - * descriptor being freed. - * - * It is safe to call this function with a null pointer for the - * file descriptor. This function returns a null pointer that - * the caller can assign to the file descriptor pointer as it's - * closed like `desc=H5F_low_close(desc)'. - * - * Errors: - * IO CLOSEERROR Close failed. - * - * Return: Success: NULL - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5F_low_t * -H5F_low_close(H5F_low_t *lf, const H5F_access_t *access_parms) -{ - FUNC_ENTER(H5F_low_close, NULL); - - if (lf) { - if ((lf->type->close) (lf, access_parms) < 0) { - H5MM_xfree(lf); - HRETURN_ERROR(H5E_IO, H5E_CLOSEERROR, NULL, "close failed"); - } - H5MM_xfree(lf); - } - FUNC_LEAVE(NULL); -} - -/*------------------------------------------------------------------------- - * Function: H5F_low_read - * - * Purpose: Reads SIZE bytes of data beginning at address ADDR of the - * file LF and puts the result in BUF. Behavior when reading - * past the logical or physical end of file is to return zeros - * for that part of the request. - * - * This is only a virtual function; the subclass must define a - * read method or this function will fail. - * - * Errors: - * IO READERROR Read failed. - * IO UNSUPPORTED No read method. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -herr_t -H5F_low_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - uint8_t *buf/*out*/) -{ - herr_t ret_value = FAIL; - - FUNC_ENTER(H5F_low_read, FAIL); - - assert(lf && lf->type); - assert(H5F_addr_defined(addr)); - assert(buf); - - if (lf->type->read) { - if ((ret_value = (lf->type->read) (lf, access_parms, xfer_parms, - addr, size, buf)) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, ret_value, "read failed"); - } - } else { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "no read method"); - } - - FUNC_LEAVE(ret_value); -} - -/*------------------------------------------------------------------------- - * Function: H5F_low_write - * - * Purpose: Writes SIZE bytes of data from BUF into the file LF beginning - * at address ADDR of the file. Writing past the logical or - * physical end of file causes the file to be extended. - * - * This is a virtual function only; if the subclass doesn't - * define a write method then this function will fail. - * - * Errors: - * IO UNSUPPORTED No write method. - * IO WRITEERROR Write failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * rky, 1998-08-16 - * Accommodate fancy MPI derived datatype writes. - * - * rky, 1998-09-02 - * For non-block parallel writes, don't change value of lf->eof. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -herr_t -H5F_low_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - const uint8_t *buf) -{ - herr_t ret_value = FAIL; - haddr_t tmp_addr; - - FUNC_ENTER(H5F_low_write, FAIL); - - assert(lf && lf->type); - assert(H5F_addr_defined(addr)); - assert(buf); - - /* check for writing past the end of file marker */ - tmp_addr = addr + (hsize_t)size; - if (H5F_addr_gt(tmp_addr, lf->eof)) - HRETURN_ERROR(H5E_IO, H5E_OVERFLOW, ret_value, "write past end of logical file"); - - /* Check if the last byte of the logical file has been written */ - if (!lf->eof_written && H5F_addr_eq(tmp_addr, lf->eof)) - lf->eof_written=1; - - /* Write the data */ - if (lf->type->write) { - if ((ret_value = (lf->type->write) (lf, access_parms, xfer_parms, - addr, size, buf)) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, ret_value, "write failed"); - } - } else { - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "no write method"); - } - - FUNC_LEAVE(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_low_flush - * - * Purpose: Flushes file buffers to disk. For instance, the stdio.h - * driver would call fflush(). Flushing also insures that the - * file exists to the current logical EOF (the library maintains - * a notion of EOF which is independent of the physical EOF) by - * reading and writing the last byte. On some systems, this - * allocates a single block at the end of the file while on - * other systems it allocates all blocks up to the end of the - * file. Extending the physical file is necessary because - * H5F_open() checks for truncated files. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 10, 1997 - * - * Modifications: - * rky 980828 Only p0 writes metadata to disk. - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_low_flush(H5F_low_t *lf, const H5F_access_t *access_parms) -{ - haddr_t last_byte; - uint8_t buf[1]; - - FUNC_ENTER(H5F_low_flush, FAIL); - - assert(lf && lf->type); - - /* Make sure the last block of the file has been allocated on disk */ - last_byte = 0; - if (!lf->eof_written && H5F_addr_defined(lf->eof) && - H5F_addr_gt(lf->eof, last_byte)) { - last_byte = lf->eof; - last_byte -= 1; - if (H5F_low_read(lf, access_parms, &H5F_xfer_dflt, last_byte, - 1, buf) >= 0) { -#ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame( lf, TRUE ); /* only p0 will write */ -#endif /* HAVE_PARALLEL */ - H5F_low_write(lf, access_parms, &H5F_xfer_dflt, last_byte, - 1, buf); - } - else - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "low level flush failed"); - } - /* Invoke the subclass the flush method */ - if (lf->type->flush) { - if ((lf->type->flush) (lf, access_parms) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "low level flush failed"); - } - } - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_low_size - * - * Purpose: Returns the current logical size of the file in bytes. This - * may differ from the physical size of the file (most - * subclasses extend the physical file size during the write - * operation instead of the alloc operation). - * - * The next absolute file address is returned through the - * EOF argument. This is the address of the logical end of - * file (that is, the address of the first byte past the last - * byte which is logically in the file). - * - * Warning: The return value type may not be large enough to represent - * the true size of the file. In such cases, the maximum - * possible size is returned. It is better to look at the EOF - * output argument to determine the total size. - * - * Errors: - * IO UNSUPPORTED No size method. - * - * Return: Success: Current size of file - * - * Failure: 0 - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hsize_t -H5F_low_size(H5F_low_t *lf, haddr_t *eof_p/*out*/) -{ - hsize_t size = (hsize_t)(-1); /*max possible size */ - - FUNC_ENTER(H5F_low_size, 0); - - assert(lf && lf->type); - assert(eof_p); - - *eof_p = lf->eof; - if (*eof_p < size) size = *eof_p; - - FUNC_LEAVE(size); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_low_access - * - * Purpose: Determines if a file can be accessed in a particular way by a - * particular subclass. The access modes for a file are the - * same as those of access(2), namely - * - * F_OK: determines if the file (or all parts of a multi-part - * file) exists. - * - * R_OK: determines if the file (or all parts of a multi-part - * file) are readable. - * - * W_OK: determines if the file (or all parts of a multi-part - * file) are writable. - * - * If a subclass doesn't define an access method, then we treat - * the name as if it were a local Unix file and test - * accessibility with the access(2) function. The KEY is - * returned as a device number and i-node pair. - * - * Return: Success: TRUE or FALSE. If TRUE, then KEY is - * initialized with data that makes this file - * unique (same value as H5F_low_open). - * - * Failure: FAIL, KEY is undefined. - * - * Programmer: Robb Matzke - * Friday, October 24, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -htri_t -H5F_low_access(const H5F_low_class_t *type, const char *name, - const H5F_access_t *access_parms, int mode, - H5F_search_t *key/*out*/) -{ - htri_t ret_value; - struct stat sb; - - FUNC_ENTER(H5F_low_size, FAIL); - assert(type); - - if (type->access) { - ret_value = (type->access) (name, access_parms, mode, key /*out*/); - } else { - ret_value = (0 == HDaccess(name, mode) ? TRUE : FALSE); - if (key) { - -#ifdef WIN32 - - int fd; - HFILE filehandle; - struct _BY_HANDLE_FILE_INFORMATION fileinfo; - int results; - - - fd = HDopen(name,_O_RDONLY,0); - filehandle = _get_osfhandle(fd); - results = GetFileInformationByHandle(filehandle, &fileinfo); - - /*returns a 0 on failure*/ - - if (!results) { - ret_value = FALSE; - } - - else { - HDstat(name,&sb); - key->dev = sb.st_dev; - key->ino = 0; - key->fileindexhi = fileinfo.nFileIndexHigh; - key->fileindexlo = fileinfo.nFileIndexLow; - } - - HDclose(fd); - - -#else - HDstat(name, &sb); - key->dev = sb.st_dev; - key->ino = sb.st_ino; -#endif - } - } - - FUNC_LEAVE(ret_value); -} - -/*------------------------------------------------------------------------- - * Function: H5F_low_extend - * - * Purpose: Increases the logical size of a file by moving the logical - * end of file marker. A subclass can override this function by - * providing its own allocation method. - * - * Return: Success: Non-negative. The address of the old - * end-of-file is returned through the ADDR_P - * argument and the logical size of the file has - * been extended by SIZE bytes. - * - * Failure: Negative. - * - * Programmer: Robb Matzke - * Thursday, November 13, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_low_extend(H5F_low_t *lf, const H5F_access_t *access_parms, intn op, - hsize_t size, haddr_t *addr_p/*out*/) -{ - FUNC_ENTER(H5F_low_alloc, FAIL); - - assert(lf); - assert(size > 0); - assert(addr_p); - - /* Reset the EOF written flag */ - lf->eof_written=0; - - if (lf->type->extend) { - if ((lf->type->extend) (lf, access_parms, op, size, addr_p/*out*/)<0) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "unable to extend file"); - } - } else { - *addr_p = lf->eof; - lf->eof += size; - } - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_low_alloc - * - * Purpose: Determines if a free block BLK can satisfy a request for SIZE - * bytes of memory from file F. If SIZE >= THRESH then the - * memory must be aligned on an ALIGN-byte boundary. Alignment - * is wrt the relative file addresses (that is, the size of the - * user-defined block at the beginning of the file is subtracted - * from the addresses before aligning them). - * - * Return: Success: Positive if the free block exactly satisfies - * the request; zero if the free block - * over-satisfies the request. In either case, - * ADDR will be the address within the free - * block where the request can be satisfied. - * - * Failure: Negative with the output value of ADDR_P - * undefined. - * - * Programmer: Robb Matzke - * Tuesday, June 9, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -intn -H5F_low_alloc (H5F_low_t *lf, intn op, hsize_t alignment, hsize_t threshold, - hsize_t size, H5MF_free_t *blk, haddr_t *addr_p/*out*/) -{ - intn ret_value = FAIL; - hsize_t wasted; - - FUNC_ENTER (H5F_low_alloc, FAIL); - assert (lf); - assert (alignment>0); - assert (size>0); - assert (blk); - assert (addr_p); - - if (lf->type->alloc) { - ret_value = (lf->type->alloc)(lf, op, alignment, threshold, size, blk, - addr_p/*out*/); - } else { - if (size>=threshold) { - wasted = blk->addr % alignment; - } else { - wasted = 0; - } - if (0==wasted && size==blk->size) { - /* exact match */ - *addr_p = blk->addr; - ret_value = 1; - } else if (blk->size>wasted && blk->size-wasted>=size) { - /* over-satisfied */ - *addr_p = blk->addr + wasted; - ret_value = 0; - } - } - - FUNC_LEAVE (ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_low_seteof - * - * Purpose: Sets the logical end-of-file to the specified address. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, November 13, 1997 - * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -herr_t -H5F_low_seteof(H5F_low_t *lf, haddr_t addr) -{ - FUNC_ENTER(H5F_low_seteof, FAIL); - - assert(lf); - assert(H5F_addr_defined(addr)); - - lf->eof = addr; - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_addr_encode - * - * Purpose: Encodes an address into the buffer pointed to by *PP and - * then increments the pointer to the first byte after the - * address. An undefined value is stored as all 1's. - * - * Return: void - * - * Programmer: Robb Matzke - * Friday, November 7, 1997 - * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -void -H5F_addr_encode(H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) -{ - uintn i; - haddr_t tmp; - - assert(f); - assert(pp && *pp); - - if (H5F_addr_defined(addr)) { - tmp = addr; - for (i=0; i<H5F_SIZEOF_ADDR(f); i++) { - *(*pp)++ = (uint8_t)(tmp & 0xff); - tmp >>= 8; - } - assert("overflow" && 0 == tmp); - - } else { - for (i=0; i<H5F_SIZEOF_ADDR(f); i++) { - *(*pp)++ = 0xff; - } - } -} - - -/*------------------------------------------------------------------------- - * Function: H5F_addr_decode - * - * Purpose: Decodes an address from the buffer pointed to by *PP and - * updates the pointer to point to the next byte after the - * address. - * - * If the value read is all 1's then the address is returned - * with an undefined value. - * - * Return: void - * - * Programmer: Robb Matzke - * Friday, November 7, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -void -H5F_addr_decode(H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) -{ - uintn i; - haddr_t tmp; - uint8_t c; - hbool_t all_zero = TRUE; - - assert(f); - assert(pp && *pp); - assert(addr_p); - - *addr_p = 0; - - for (i=0; i<H5F_SIZEOF_ADDR(f); i++) { - c = *(*pp)++; - if (c != 0xff) all_zero = FALSE; - - if (i<sizeof(*addr_p)) { - tmp = c; - tmp <<= i * 8; /*use tmp to get casting right */ - *addr_p |= tmp; - } else if (!all_zero) { - assert(0 == **pp); /*overflow */ - } - } - if (all_zero) *addr_p = H5F_ADDR_UNDEF; -} - - -/*------------------------------------------------------------------------- - * Function: H5F_addr_pack - * - * Purpose: Converts a long[2] array (usually returned from H5G_get_objinfo) - * back into a haddr_t - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, October 23, 1998 - * - * Modifications: - * Albert Cheng, Feb 18, 1999 - * Changed objno to unsigned long type to be consistent with - * addr->offset and how it is being called. - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_addr_pack(H5F_t UNUSED *f, haddr_t *addr_p/*out*/, - const unsigned long objno[2]) -{ - assert(f); - assert(objno); - assert(addr_p); - - *addr_p = objno[0]; -#if SIZEOF_LONG<SIZEOF_UINT64_T - *addr_p |= ((uint64_t)objno[1]) << (8*sizeof(long)); -#endif - - return(SUCCEED); -} diff --git a/src/H5Fmpio.c b/src/H5Fmpio.c deleted file mode 100644 index 88f9877..0000000 --- a/src/H5Fmpio.c +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * Copyright (C) 1998 NCSA - * All rights reserved. - * - * Programmer: - * January 30, 1998 - * - * Purpose: This is the MPI2 I/O subclass of H5Flow. - * - * Problems and limitations: - * - * H5F_mpio_access - * - Since there is no "access" function for MPI-IO files - * we open (i.e., MPI_File_open) the file to see if it exists - * and to infer the access flags. If the file is opened, - * we close it without reading or writing it. - * - It is not possible within MPI-IO to determine whether or not - * the names "file1" and "file2" refer to the same physical file - * (at least not without writing one and reading the other). - * So we do what H5F_core_open() does: return a bogus device - * number and a unique inode number. - * This has the side effect that calling H5Fopen() twice - * with the same name really does open the file twice - * and the two handles don't communicate with each other, - * resulting in trashing the file. It also runs the (very - * small) risk of having two unrelated names be seen as the - * same file. - * - * H5F_mpio_open - * - "unique" key treated same as in H5F_mpio_access - * - * H5F_mpio_read & H5F_mpio_write - * - Eventually these should choose collective or independent i/o - * based on a parameter that is passed down to it from H5Dwrite, - * rather than the access_parms (which are fixed at the open). - * - * H5F_mpio_read - * - One implementation of MPI/MPI-IO causes MPI_Get_count - * to return (incorrectly) a negative count. - * I added code to detect this, and a kludge to pretend - * that the number of bytes read is always equal to the number - * requested. This kluge is activated by #ifdef MPI_KLUGE0202. - * - */ -#include <H5private.h> -#include <H5Eprivate.h> -#include <H5Dprivate.h> -#include <H5MMprivate.h> - -#ifndef HAVE_PARALLEL -/* - * The H5F_mpio_xxxx functions are for parallel I/O only and are - * valid only when HAVE_PARALLEL is #defined. This empty #ifndef - * body is used to allow this source file be included in the serial - * distribution. - * Some compilers/linkers may complain about "empty" object file. - * If that happens, uncomment the following statement to pacify - * them. - */ -/* const hbool_t H5F_mpio_avail = FALSE; */ -#else /* HAVE_PARALLEL */ - -#define PABLO_MASK H5Fmpio_mask -static intn interface_initialize_g = 0; -#define INTERFACE_INIT NULL - -/* Global var to allow elimination of redundant metadata writes - * to be controlled by the value of an environment variable. */ -/* Use the elimination by default unless this is the Intel Red machine */ -#ifndef __PUMAGON__ -hbool_t H5_mpi_1_metawrite_g = TRUE; -#else -hbool_t H5_mpi_1_metawrite_g = FALSE; -#endif - -#define H5F_MPIO_DEV 0xfffe /*pseudo dev for MPI-IO until we fix things */ - /* Make sure this differs from H5F_CORE_DEV */ - -#ifdef H5Fmpio_DEBUG -/* Flags to control debug actions in H5Fmpio. - * Meant to be indexed by characters. - * - * 'c' show result of MPI_Get_count after read - * 'r' show read offset and size - * 't' trace function entry and exit - * 'w' show write offset and size - */ -static int H5F_mpio_Debug[256] = - { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; -#endif - -static htri_t H5F_mpio_access(const char *name, - const H5F_access_t *access_parms, int mode, - H5F_search_t *key/*out*/); -static H5F_low_t *H5F_mpio_open(const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/); -static herr_t H5F_mpio_close(H5F_low_t *lf, const H5F_access_t *access_parms); -static herr_t H5F_mpio_read(H5F_low_t *lf, H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf/*out*/); -htri_t H5F_mpio_tas_allsame(H5F_low_t *lf, hbool_t newval ); -static herr_t H5F_mpio_write(H5F_low_t *lf, H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf); -static herr_t H5F_mpio_flush(H5F_low_t *lf, const H5F_access_t *access_parms); -static herr_t H5F_MPIOff_to_haddr(MPI_Offset mpi_off, haddr_t *addr_p/*out*/); -static herr_t H5F_haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off/*out*/); - -const H5F_low_class_t H5F_LOW_MPIO_g[1] = {{ - H5F_mpio_access, /*access method */ - H5F_mpio_open, /*open method */ - H5F_mpio_close, /*close method */ - - /* rky 980816 - * this is ugly, but removing the const modifier from access_parms - * in the parameter list of the write function in H5F_low_class_t - * would propagate to a lot of functions that don't change that param */ - (int(*)(struct H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - uint8_t *buf)) - H5F_mpio_read, /*read method */ - - /* rky 980816 - * this is ugly, but removing the const modifier from access_parms - * in the parameter list of the write function in H5F_low_class_t - * would propagate to a lot of functions that don't change that param */ - (int(*)(struct H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - const uint8_t *buf)) - H5F_mpio_write, /*write method */ - - H5F_mpio_flush, /*flush method */ - NULL, /*extend method */ - NULL, /*alloc method */ -}}; - -ino_t mpio_inode_num = 0; /* fake "inode" number */ - - -/*------------------------------------------------------------------------- - * Function: H5F_mpio_access - * - * Purpose: Determines if an MPI-IO file can be accessed in a particular - * way. The access modes for a file are the same as those of - * access(2), namely - * - * F_OK: determines if the MPI-IO file exists - * (in fact, we can only determine that the file can be - * opened for reading or writing, or neither) - * - * R_OK: determines if the MPI-IO file is readable - * - * W_OK: determines if the MPI-IO file is writable. - * - * Warning: It is not possible within MPI-IO to determine whether or not - * the names "file1" and "file2" refer to the same physical fileC - * (at least not without writing one and reading the other). - * So we do what H5F_core_open() does: return a bogus device number - * and a unique inode number. - * This has the side effect that calling H5Fopen() twice - * with the same name really does open the file twice - * and the two handles don't communicate with each other, - * resulting in trashing the file. It also runs the (very small) - * risk of having two unrelated names be seen as the same file. - * - * Must call this routine collectively since it collectively - * calls MPI_File_open with the communicator in access_parms. - * - * Return: Success: TRUE or FALSE. If TRUE, then KEY is - * initialized with data that makes this file - * unique (same value as H5F_low_open). - * - * Failure: FAIL, KEY is undefined. - * - * Programmer: - * January 30, 1998 - * - * Modifications: - * - * Robb Matzke, 18 Feb 1998 - * Added the ACCESS_PARMS argument. - * - * June 9, 1998 Albert Cheng - * Instead of opening the file with COMM_SELF (which results in - * racing condition in routine that calls it), open it with the - * communicator in access_parms. (This assumes this access call - * must be called collectively.) - * - *------------------------------------------------------------------------- - */ -static htri_t -H5F_mpio_access(const char *name, const H5F_access_t *access_parms, int mode, - H5F_search_t *key/*out*/) -{ - htri_t ret_val = FALSE; - MPI_File fh; - int mpierr; - int mpi_mode; - - FUNC_ENTER(H5F_mpio_access, FAIL); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Entering H5F_mpio_access name=%s mode=0x%x\n", name, mode ); -#endif - assert(access_parms->driver == H5F_LOW_MPIO); - - /* The only way to get this info in MPI-IO is to try to open the file */ - /* (though particular implementations of MPI-IO may allow other ways) */ - switch (mode) { - case F_OK: mpi_mode = MPI_MODE_RDONLY; - /* to see if it exists, first try to open for read */ - break; - case R_OK: mpi_mode = MPI_MODE_RDONLY; - break; - case W_OK: mpi_mode = MPI_MODE_WRONLY; - break; - default: HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "invalid mode parameter"); - } - - /* (char*) name is okay since MPI_File_open will not change it. */ - mpierr = MPI_File_open(access_parms->u.mpio.comm, (char*) name, - mpi_mode, access_parms->u.mpio.info, &fh ); - if (MPI_SUCCESS == mpierr) { - mpierr = MPI_File_close( &fh ); - if (MPI_SUCCESS != mpierr) - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, "MPI_File_close failed"); - ret_val = TRUE; - } else if (mode == F_OK) { - /* to see if it exists, this time try to open for write */ - mpierr = MPI_File_open(access_parms->u.mpio.comm, (char*)name, - MPI_MODE_WRONLY, access_parms->u.mpio.info, - &fh ); - if (MPI_SUCCESS == mpierr) { - mpierr = MPI_File_close( &fh ); - if (MPI_SUCCESS != mpierr) - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, "MPI_File_close failed"); - ret_val = TRUE; - } - } - - /* if the file exists, provide its (not really) unique key */ - if ((ret_val==TRUE) && key) { - key->dev = H5F_MPIO_DEV; - key->ino = mpio_inode_num++; - } - -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) { - if (key && (ret_val==TRUE)) - fprintf(stdout, - "Leaving H5F_mpio_access ret_val=%d key->dev=0x%x key->ino=%d\n", - ret_val, key->dev, key->ino ); - else - fprintf(stdout, "Leaving H5F_mpio_access ret_val=%d\n", ret_val ); - } -#endif - - FUNC_LEAVE(ret_val); -} - -/*------------------------------------------------------------------------- - * Function: H5F_mpio_open - * - * Purpose: Opens a file with name NAME. The FLAGS are a bit field with - * the possible values defined in H5F_low_open(). - * - * Errors: - * IO CANTOPENFILE MPI_File_open failed. - * IO CANTOPENFILE MPI_File_get_size failed. - * IO CANTOPENFILE MPI_File_set_size failed (for truncate). - * - * Return: Success: Low-level file pointer - * - * Failure: NULL - * - * Programmer: - * January 30, 1998 - * - * Modifications: - * - * Robb Matzke, 18 Feb 1998 - * Added the ACCESS_PARMS argument. Moved some error checking here from - * elsewhere. - * - * rky, 11 Jun 1998 - * Added H5F_mpio_Debug debug flags controlled by MPI_Info. - * - * rky 980828 Init flag controlling redundant metadata writes to disk. - * - * rky 19981207 Added barrier after MPI_File_set_size to prevent - * race condition: subsequent writes were being truncated, - * causing holes in file. - *------------------------------------------------------------------------- - */ -static H5F_low_t * -H5F_mpio_open(const char *name, const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/) -{ - H5F_low_t *lf = NULL; - MPI_File fh; - int mpi_amode; - char mpierrmsg[MPI_MAX_ERROR_STRING]; - int mpierr, msglen; - MPI_Offset size; - - FUNC_ENTER(H5F_mpio_open, NULL); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Entering H5F_mpio_open name=%s flags=0x%x\n", name, flags ); -#endif - - /* convert HDF5 flags to MPI-IO flags */ - /* some combinations are illegal; let MPI-IO figure it out */ - mpi_amode = (flags&H5F_ACC_RDWR) ? MPI_MODE_RDWR : MPI_MODE_RDONLY; - if (flags&H5F_ACC_CREAT) mpi_amode |= MPI_MODE_CREATE; - if (flags&H5F_ACC_EXCL) mpi_amode |= MPI_MODE_EXCL; - -#ifdef H5Fmpio_DEBUG - { - /* set debug mask */ - /* Should this be done in H5F global initialization instead of here? */ - const char *s = HDgetenv ("H5F_mpio_Debug"); - if (s) { - while (*s){ - H5F_mpio_Debug[(int)*s]++; - s++; - } - } - } - /* Check for debug commands in the info parameter */ - { char debug_str[128]; - int infoerr, flag, i; - if (access_parms->u.mpio.info) { - infoerr = MPI_Info_get( access_parms->u.mpio.info, - H5F_MPIO_DEBUG_KEY, 127, debug_str, &flag ); - if (flag) { - fprintf(stdout, "H5Fmpio debug flags=%s\n", debug_str ); - for (i=0; - debug_str[i]/*end of string*/ && i<128/*just in case*/; - ++i) { - H5F_mpio_Debug[(int)debug_str[i]] = 1; - } - } - } - } -#endif - - mpierr = MPI_File_open(access_parms->u.mpio.comm, (char*)name, mpi_amode, - access_parms->u.mpio.info, &fh); - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, mpierrmsg ); - } - - /* truncate the file, if requested */ - if (flags&H5F_ACC_TRUNC) { - mpierr = MPI_File_set_size( fh, (MPI_Offset)0 ); - if (MPI_SUCCESS != mpierr) { - MPI_File_close( &fh ); - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, - "MPI_File_set_size failed trying to truncate file" ); - } - /* Don't let any proc return until all have truncated the file. */ - mpierr = MPI_Barrier( access_parms->u.mpio.comm ); - if (MPI_SUCCESS!=mpierr) { - MPI_File_close( &fh ); - HRETURN_ERROR( H5E_IO, H5E_MPI, NULL, "MPI_Barrier failed" ); - } - } - - /* Build the return value */ - if (NULL==(lf = H5MM_calloc(sizeof(H5F_low_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - lf->u.mpio.f = fh; - H5F_mpio_tas_allsame( lf, FALSE ); /* initialize */ - lf->eof = 0; - mpierr = MPI_File_get_size( fh, &size ); - if (MPI_SUCCESS != mpierr) { - MPI_File_close( &(lf->u.mpio.f) ); - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, mpierrmsg ); - } else { - haddr_t new_eof; - if (SUCCEED != H5F_MPIOff_to_haddr( size, &new_eof )) { - MPI_File_close( &(lf->u.mpio.f) ); - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, - "couldn't convert size to haddr_t" ); - } - H5F_low_seteof(lf, new_eof); - } - - /* The unique key */ - if (key) { - key->dev = H5F_MPIO_DEV; - key->ino = mpio_inode_num++; - } - -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) { - if (key) - fprintf(stdout, "Leaving H5F_mpio_open key->dev=0x%x key->ino=%d\n", - key->dev, key->ino ); - else - fprintf(stdout, "Leaving H5F_mpio_open\n" ); - } -#endif - - FUNC_LEAVE(lf); -} - -/*------------------------------------------------------------------------- - * Function: H5F_mpio_close - * - * Purpose: Closes a file. - * - * Errors: - * IO CLOSEERROR Fclose failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: - * January 30, 1998 - * - * Modifications: - * - * Robb Matzke, 18 Feb 1998 - * Added the ACCESS_PARMS argument. - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_mpio_close(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms) -{ - int mpierr; - char mpierrmsg[MPI_MAX_ERROR_STRING]; - int msglen; - - FUNC_ENTER(H5F_mpio_close, FAIL); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Entering H5F_mpio_close\n" ); -#endif - - mpierr = MPI_File_close( &(lf->u.mpio.f) ); - /* MPI_File_close sets lf->u.mpio.f to MPI_FILE_NULL */ - - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, mpierrmsg ); - } - -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Leaving H5F_mpio_close\n" ); -#endif - FUNC_LEAVE(SUCCEED); -} - -/*------------------------------------------------------------------------- - * Function: H5F_mpio_read - * - * Purpose: Depending on a field in access params, either: - * - Writes SIZE bytes from the beginning of BUF into file LF - * at file address ADDR. - * - Reads SIZE bytes beginning at address ADDR in file LF - * and places them in buffer BUF. - * - Uses the (potentially complex) file and buffer types - * to effect the transfer. - * This can allow MPI to coalesce requests from - * different processes (collective or independent). - * - * Reading past the end of the MPI file - * returns zeros instead of failing. - * - * Errors: - * IO READERROR MPI_File_read_at failed. - * IO READERROR MPI_Get_count failed - * - * Return: Non-negative on success/Negative on failure - * (use_types and old_use_types in the access params are altered) - * - * Programmer: rky 980130 - * - * Modifications: - * - * Robb Matzke, 18 Feb 1998 - * Added the ACCESS_PARMS argument. - * - * rky, 10 Apr 1998 - * Call independent or collective MPI read, based on ACCESS_PARMS. - * - * Albert Cheng, June 1, 1998 - * Added xfer_mode to control independent or collective MPI read. - * - * rky 980816 - * Use btype, ftype, and disp from access parms. - * The guts of H5F_mpio_read and H5F_mpio_write - * should be replaced by a single dual-purpose routine. - * - * Robb Matzke, 1999-04-21 - * Changed xfer_mode to xfer_parms for all H5F_*_read() callbacks. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_mpio_read(H5F_low_t *lf, H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - uint8_t *buf/*out*/) -{ - MPI_Offset mpi_off, mpi_disp; - MPI_Status mpi_stat; - MPI_Datatype buf_type, file_type; - int mpierr, msglen, size_i, bytes_read, n; - int use_types_this_time, used_types_last_time; - char mpierrmsg[MPI_MAX_ERROR_STRING]; - - FUNC_ENTER(H5F_mpio_read, FAIL); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Entering H5F_mpio_read\n" ); -#endif - - /* some numeric conversions */ - if (SUCCEED != H5F_haddr_to_MPIOff(addr, &mpi_off)) { - HRETURN_ERROR(H5E_IO, H5E_BADTYPE, FAIL, - "couldn't convert addr to MPIOffset" ); - } - size_i = (int)size; - if ((size_t)size_i != size) { /* check type conversion */ - HRETURN_ERROR(H5E_IO, H5E_BADTYPE, FAIL, - "couldn't convert size to int" ); - } - -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'r']) - HDfprintf(stdout, "in H5F_mpio_read mpi_off=%Hd size_i=%d\n", - (hssize_t)mpi_off, size_i ); -#endif - - /* Set up for a fancy xfer using complex types, or single byte block. - * We wouldn't need to rely on the use_types field - * if MPI semantics allowed us to test that btype=ftype=MPI_BYTE - * (or even MPI_TYPE_NULL, which could mean "use MPI_BYTE" by convention). - */ - use_types_this_time = access_parms->u.mpio.use_types; - if (use_types_this_time) { - /* prepare for a full-blown xfer using btype, ftype, and disp */ - buf_type = access_parms->u.mpio.btype; - file_type = access_parms->u.mpio.ftype; - if (SUCCEED != - H5F_haddr_to_MPIOff(access_parms->u.mpio.disp, &mpi_disp)) { - HRETURN_ERROR(H5E_IO, H5E_BADTYPE, FAIL, - "couldn't convert addr to MPIOffset" ); - } - } else { - /* Prepare for a simple xfer of a contiguous block of bytes. - * The btype, ftype, and disp fields are not used. */ - buf_type = MPI_BYTE; - file_type = MPI_BYTE; - mpi_disp = 0; /* mpi_off is sufficient */ - } - - /* Don't bother to reset the view if we're not using the types this time, - * and did we didn't use them last time either. */ - used_types_last_time = access_parms->u.mpio.old_use_types; - if (used_types_last_time /* change to new ftype or MPI_BYTE */ - || use_types_this_time) /* almost certainly a different ftype */ { - mpierr = MPI_File_set_view( lf->u.mpio.f, mpi_disp, - MPI_BYTE, file_type, - "native", access_parms->u.mpio.info ); - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, mpierrmsg ); - } - } - /* We always set the use_types flag to 0 because the - * default is not to use types next time, - * unless someone explicitly requests it by setting this flag to !=0. */ - access_parms->u.mpio.old_use_types = use_types_this_time; - access_parms->u.mpio.use_types = 0; - - /* Read the data. */ - switch (xfer_parms->xfer_mode){ - case H5D_XFER_INDEPENDENT: - case H5D_XFER_DFLT: - mpierr = MPI_File_read_at ( lf->u.mpio.f, mpi_off, (void*) buf, - size_i, buf_type, &mpi_stat ); - break; - - case H5D_XFER_COLLECTIVE: -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "%s: using MPIO collective mode\n", FUNC); -#endif - mpierr = MPI_File_read_at_all ( lf->u.mpio.f, mpi_off, (void*) buf, - size_i, buf_type, &mpi_stat ); - break; - - default: - HRETURN_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "invalid file access mode"); - } - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, mpierrmsg ); - } - - /* How many bytes were actually read? */ - mpierr = MPI_Get_count( &mpi_stat, MPI_BYTE, &bytes_read ); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'c']) - fprintf(stdout, - "In H5F_mpio_read after Get_count size_i=%d bytes_read=%d\n", - size_i, bytes_read ); -#endif - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, mpierrmsg ); - } - -#define MPI_KLUGE0202 -#ifdef MPI_KLUGE0202 - /* KLUGE rky 980202 MPI_Get_count incorrectly returns negative count; - fake a complete read */ - bytes_read = size_i; /* KLUGE rky 980202 */ -#endif - - if ((bytes_read<0) || (bytes_read > size_i)) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "MPI_Get_count returned invalid count" ); - } - - /* This gives us zeroes beyond end of physical MPI file. - * What about reading past logical end of HDF5 file??? */ - if ((n=(size_i-bytes_read)) > 0) { - if (use_types_this_time) { - /* INCOMPLETE rky 980918 Not implemented yet. What to do??? */ - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, - "haven't implemented reading zeroes beyond end of file" ); - } else { - HDmemset( buf+bytes_read, 0, (size_t)n ); - } - } - -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Leaving H5F_mpio_read\n" ); -#endif - FUNC_LEAVE(SUCCEED); -} /* H5F_mpio_read */ - -/*------------------------------------------------------------------------- - * Function: H5F_mpio_tas_allsame - * - * Purpose: Test and set the allsame parameter. - * - * Errors: - * - * Return: Success: the old value of the allsame flag - * - * Failure: assert fails if access_parms is NULL. - * - * Programmer: rky 980828 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -htri_t -H5F_mpio_tas_allsame(H5F_low_t *lf, hbool_t newval ) -{ - hbool_t oldval; - - FUNC_ENTER(H5F_mpio_tas_allsame, FALSE); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Entering H5F_mpio_tas_allsame, newval=%d\n", newval ); -#endif - - assert(lf); - oldval = lf->u.mpio.allsame; - lf->u.mpio.allsame = newval; - -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Leaving H5F_mpio_tas_allsame, oldval=%d\n", oldval ); -#endif - FUNC_LEAVE(oldval); -} - -/*------------------------------------------------------------------------- - * Function: H5F_mpio_write - * - * Purpose: Depending on a field in access params, either: - * - Writes SIZE bytes from the beginning of BUF into file LF - * at file address ADDR. - * - Uses the (potentially complex) file and buffer types - * to effect the transfer. - * This can allow MPI to coalesce requests from - * different processes (collective or independent). - * - * rky 980828 - * If the allsame flag is set, we assume that all the procs - * in the relevant MPI communicator will write identical data - * at identical offsets in the file, so only proc 0 will write, - * and all other procs will wait for p0 to finish. - * This is useful for writing metadata, for example. - * Note that we don't _check_ that the data is identical. - * ALso, the mechanism we use to eliminate the redundant writes - * is by requiring a call to H5F_mpio_tas_allsame before the write, - * which is rather klugey. - * Would it be better to pass a parameter to low-level writes - * like H5F_block_write and H5F_low_write, instead? Or...??? - * Also, when I created this mechanism I wanted to minimize - * the difference in behavior between the old way of doing things - * (i.e., all procs write) and the new way, so the writes are - * eliminated at the very lowest level, here in H5F_mpio_write. - * It may be better to rethink that, and short-circuit the writes - * at a higher level (e.g., at the points in the code where - * H5F_mpio_tas_allsame is called). - * - * Errors: - * IO WRITEERROR MPI_File_write_at failed. - * - * Return: Non-negative on success/Negative on failure - * (use_types and old_use_types in the access params are altered) - * - * Programmer: - * January 30, 1998 - * - * Modifications: - * - * Robb Matzke, 18 Feb 1998 - * Added the ACCESS_PARMS argument. - * - * rky, 10 Apr 1998 - * Call independent or collective MPI write, based on ACCESS_PARMS. - * - * rky, 24 April - * Removed redundant write from H5F_Mpio_write. - * - * Albert Cheng, June 1, 1998 - * Added xfer_mode to control independent or collective MPI write. - * - * rky 980816 - * Use btype, ftype, and disp from access parms. - * The guts of H5F_mpio_read and H5F_mpio_write - * should be replaced by a single dual-purpose routine. - * - * rky, 980828 - * Added allsame parameter to make all but proc 0 skip the actual write. - * - * Robb Matzke, 1999-04-21 - * Changed XFER_MODE to XFER_PARMS for all H5F_*_write() callbacks. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_mpio_write(H5F_low_t *lf, H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - const uint8_t *buf) -{ - MPI_Offset mpi_off, mpi_disp; - MPI_Status mpi_stat; - MPI_Datatype buf_type, file_type; - int mpierr, msglen, size_i, bytes_written, mpi_rank; - int use_types_this_time, used_types_last_time; - char mpierrmsg[MPI_MAX_ERROR_STRING]; - hbool_t allsame; - - FUNC_ENTER(H5F_mpio_write, FAIL); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Entering H5F_mpio_write\n" ); -#endif - - /* some numeric conversions */ - if (SUCCEED != H5F_haddr_to_MPIOff(addr, &mpi_off)) { - HRETURN_ERROR(H5E_IO, H5E_BADTYPE, FAIL, - "couldn't convert addr to MPIOffset" ); - } - if (SUCCEED!=H5F_haddr_to_MPIOff(access_parms->u.mpio.disp, &mpi_disp)) { - HRETURN_ERROR(H5E_IO, H5E_BADTYPE, FAIL, - "couldn't convert addr to MPIOffset" ); - } - size_i = (int)size; - if ((size_t)size_i != size) { /* check type conversion */ - HRETURN_ERROR(H5E_IO, H5E_BADTYPE, FAIL, - "couldn't convert size to int" ); - } - -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'w']) - HDfprintf(stdout, "in H5F_mpio_write mpi_off=%Hd size_i=%d\n", - (hssize_t)mpi_off, size_i ); -#endif - - /* Only p0 will do the actual write if all procs in comm write same data */ - allsame = H5F_mpio_tas_allsame( lf, FALSE ); - if (allsame && H5_mpi_1_metawrite_g) { - mpierr = MPI_Comm_rank( access_parms->u.mpio.comm, &mpi_rank ); - if (mpierr != MPI_SUCCESS) - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, "MPI_Comm_rank failed" ); - if (mpi_rank != 0) { -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'w']) { - fprintf(stdout, " in H5F_mpio_write (write omitted)\n" ); - } -#endif - goto done; /* skip the actual write */ - } - } - - /* Set up for a fancy xfer using complex types, or single byte block. - * We wouldn't need to rely on the use_types field - * if MPI semantics allowed us to test that btype=ftype=MPI_BYTE - * (or even MPI_TYPE_NULL, which could mean "use MPI_BYTE" by convention). - */ - use_types_this_time = access_parms->u.mpio.use_types; - if (use_types_this_time) { - /* prepare for a full-blown xfer using btype, ftype, and disp */ - buf_type = access_parms->u.mpio.btype; - file_type = access_parms->u.mpio.ftype; - if (SUCCEED != - H5F_haddr_to_MPIOff(access_parms->u.mpio.disp, &mpi_disp)) { - HRETURN_ERROR(H5E_IO, H5E_BADTYPE, FAIL, - "couldn't convert addr to MPIOffset" ); - } - } else { - /* Prepare for a simple xfer of a contiguous block of bytes. - * The btype, ftype, and disp fields are not used. */ - buf_type = MPI_BYTE; - file_type = MPI_BYTE; - mpi_disp = 0; /* mpi_off is sufficient */ - } - - /* Don't bother to reset the view if we're not using the types this time, - * and did we didn't use them last time either. */ - used_types_last_time = access_parms->u.mpio.old_use_types; - if (used_types_last_time /* change to new ftype or MPI_BYTE */ - || use_types_this_time) /* almost certainly a different ftype */ { - mpierr = MPI_File_set_view( lf->u.mpio.f, mpi_disp, - MPI_BYTE, file_type, - "native", access_parms->u.mpio.info ); - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, mpierrmsg ); - } - } - /* We always set the use_types flag to 0 because the - * default is not to use types next time, - * unless someone explicitly requests it by setting this flag to !=0. */ - access_parms->u.mpio.old_use_types = use_types_this_time; - access_parms->u.mpio.use_types = 0; - - /* Write the data. */ - switch (xfer_parms->xfer_mode){ - case H5D_XFER_INDEPENDENT: - case H5D_XFER_DFLT: - mpierr = MPI_File_write_at ( lf->u.mpio.f, mpi_off, (void*) buf, - size_i, buf_type, &mpi_stat ); - break; - - case H5D_XFER_COLLECTIVE: -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "%s: using MPIO collective mode\n", FUNC); -#endif - mpierr = MPI_File_write_at_all( lf->u.mpio.f, mpi_off, (void*) buf, - size_i, buf_type, &mpi_stat ); - break; - - default: - HRETURN_ERROR(H5E_IO, H5E_BADVALUE, FAIL, "invalid file access mode"); - } - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, mpierrmsg ); - } - - /* How many bytes were actually written? */ - mpierr = MPI_Get_count( &mpi_stat, MPI_BYTE, &bytes_written ); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'c']) - fprintf(stdout, - "In H5F_mpio_write after Get_count size_i=%d bytes_written=%d\n", - size_i, bytes_written ); -#endif - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, mpierrmsg ); - } - -#define MPI_KLUGE0202 -#ifdef MPI_KLUGE0202 - /* KLUGE rky 980202 MPI_Get_count incorrectly returns negative count; - fake a complete write */ - bytes_written = size_i; /* KLUGE rky 980202 */ -#endif - - if ((bytes_written<0) || (bytes_written > size_i)) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "MPI_Get_count returned invalid count" ); - } - - done: -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Leaving H5F_mpio_write\n" ); -#endif - FUNC_LEAVE(SUCCEED); -} /* H5F_mpio_write */ - -/*------------------------------------------------------------------------- - * Function: H5F_mpio_flush - * - * Purpose: Makes sure that all data is on disk. - * - * Errors: - * IO WRITEERROR MPI_File_sync failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: - * January 30, 1998 - * - * Modifications: - * - * Robb Matzke, 18 Feb 1998 - * Added the ACCESS_PARMS argument. - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_mpio_flush(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms) -{ - int mpierr; - char mpierrmsg[MPI_MAX_ERROR_STRING]; - int msglen; - - FUNC_ENTER(H5F_mpio_flush, FAIL); -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Entering H5F_mpio_flush\n" ); -#endif - - mpierr = MPI_File_sync( lf->u.mpio.f ); - if (MPI_SUCCESS != mpierr) { - MPI_Error_string( mpierr, mpierrmsg, &msglen ); - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, mpierrmsg ); - } -#ifdef H5Fmpio_DEBUG - if (H5F_mpio_Debug[(int)'t']) - fprintf(stdout, "Leaving H5F_mpio_flush\n" ); -#endif - FUNC_LEAVE(SUCCEED); -} - -/*------------------------------------------------------------------------- - * Function: H5F_MPIOff_to_haddr - * - * Purpose: Convert an MPI_Offset value to haddr_t. - * - * Problems and limitations: - * - * Return: Non-negative on success (the haddr_t contains the converted - * value). Negative on failure (the haddr_t is undefined). - * - * Programmer: - * January 30, 1998 - * - * Modifications: - * Robb Matzke, 1999-04-23 - * An error is reported for address overflows. The ADDR output - * argument is optional. - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_MPIOff_to_haddr(MPI_Offset mpi_off, haddr_t *addr_p/*out*/) -{ - FUNC_ENTER(H5F_MPIOff_to_haddr, FAIL); - - if (addr_p) *addr_p = (uint64_t) mpi_off; - if (mpi_off != (MPI_Offset)(uint64_t)mpi_off) { - HRETURN_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, "bad MPI address"); - } - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_haddr_to_MPIOff - * - * Purpose: Convert an haddr_t value to MPI_Offset. - * - * Problems and limitations: - * - * Return: Non-negative on success (the MPIOffset contains the converted - * value). Negative on failure (the MPIOffset is undefined). - * - * Programmer: - * January 30, 1998 - * - * Modifications: - * Robb Matzke, 1999-04-23 - * An error is reported for address overflows. The ADDR output - * argument is optional. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off/*out*/) -{ - FUNC_ENTER(H5F_haddr_to_MPIOff, FAIL); - - if (mpi_off) *mpi_off = (MPI_Offset)addr; - if (addr != (uint64_t)(MPI_Offset)(addr)) { - HRETURN_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, - "hdf5 address overflows MPI address"); - } - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5PC_Wait_for_left_neighbor - * - * Purpose: Blocks until (empty) msg is received - * from immediately lower-rank neighbor. - * In conjunction with Signal_right_neighbor, - * useful for enforcing 1-process-at-at-time access - * to critical regions to avoid race conditions - * (though it is overkill to require that the processes - * be allowed to proceed strictly in order of their rank). - * - * NOTE: This routine doesn't read or write any file, - * just performs interprocess coordination. - * It really should reside in a separate package of such routines. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: rky - * 19981207 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5PC_Wait_for_left_neighbor( MPI_Comm comm ) -{ - char msgbuf[1]; - int myid, mpi_err; - MPI_Status rcvstat; - - FUNC_ENTER (H5PC_Wait_for_left_neighbor, FAIL); - - mpi_err = MPI_Comm_rank( comm, &myid ); - if (MPI_SUCCESS!=mpi_err) - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, "MPI_Comm_rank failed"); - /* p0 has no left neighbor; all other procs wait for msg */ - if (myid != 0) { - mpi_err = MPI_Recv( &msgbuf, 1, MPI_CHAR, myid-1, MPI_ANY_TAG, comm, - &rcvstat ); - if (MPI_SUCCESS!=mpi_err) - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, "MPI_Recv failed"); - } - FUNC_LEAVE (SUCCEED); -} /* H5PC_Wait_for_left_neighbor */ - -/*------------------------------------------------------------------------- - * Function: H5PC_Signal_right_neighbor - * - * Purpose: Blocks until (empty) msg is received - * from immediately lower-rank neighbor. - * In conjunction with Wait_for_left_neighbor, - * useful for enforcing 1-process-at-at-time access - * to critical regions to avoid race conditions - * (though it is overkill to require that the processes - * be allowed to proceed strictly in order of their rank). - * - * NOTE: This routine doesn't read or write any file, - * just performs interprocess coordination. - * It really should reside in a separate package of such routines. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: rky - * 19981207 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5PC_Signal_right_neighbor( MPI_Comm comm ) -{ - char msgbuf[1]; - int myid, numprocs, mpi_err; - - FUNC_ENTER (H5PC_Signal_right_neighbor, FAIL); - - mpi_err = MPI_Comm_size( comm, &numprocs ); - if (MPI_SUCCESS!=mpi_err) - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, "MPI_Comm_rank failed"); - mpi_err = MPI_Comm_rank( comm, &myid ); - if (MPI_SUCCESS!=mpi_err) - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, "MPI_Comm_rank failed"); - if (myid != (numprocs-1)) { - mpi_err = MPI_Send( &msgbuf, 0/*empty msg*/, MPI_CHAR, myid+1, 0, comm); - if (MPI_SUCCESS!=mpi_err) - HRETURN_ERROR(H5E_IO, H5E_MPI, FAIL, "MPI_Send failed"); - } - FUNC_LEAVE (SUCCEED); -} /* H5PC_Signal_right_neighbor */ - -#endif /* HAVE_PARALLEL */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 85aa03b..efe8bd9 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -22,8 +22,8 @@ /* This is a near top-level header! Try not to include much! */ #include <H5private.h> -#include <H5Dpublic.h> /*for the H5D_transfer_t type */ -#include <H5MMpublic.h> /*for the H5MM_allocate_t and H5MM_free_t types */ +#include <H5FDpublic.h> /*file drivers */ +#include <H5MMpublic.h> /*for H5MM_allocate_t and H5MM_free_t types */ /* * Feature: Define this constant to be non-zero if you want to enable code @@ -51,16 +51,14 @@ #define H5F_SIGNATURE_LEN 8 /* size of size_t and off_t as they exist on disk */ -#define H5F_SIZEOF_ADDR(F) ((F)->shared->create_parms->sizeof_addr) -#define H5F_SIZEOF_SIZE(F) ((F)->shared->create_parms->sizeof_size) +#define H5F_SIZEOF_ADDR(F) ((F)->shared->fcpl->sizeof_addr) +#define H5F_SIZEOF_SIZE(F) ((F)->shared->fcpl->sizeof_size) /* * Private file open flags. */ #define H5F_ACC_PUBLIC_FLAGS 0x00ffu -#define H5F_ACC_CREAT 0x0100u /* Create non-existing files */ - /* * Encode and decode macros for file meta-data. * Currently, all file meta-data is little-endian. @@ -256,84 +254,12 @@ typedef struct H5F_access_t { 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? */ - H5F_driver_t driver; /* Low level file driver */ - union { - - /* Properties for in-core files */ - struct { - size_t increment; /*amount by which to increment size*/ - } core; - - /* Properties for file families */ - struct { - struct H5F_access_t *memb_access; /*plist for the members */ - haddr_t memb_size; /*number of bits in offset */ - } fam; - - /* Properties for the split driver */ - struct { - char *meta_ext; /*name extension for meta file */ - char *raw_ext; /*name extension for raw file */ - struct H5F_access_t *meta_access; /*plist for meta file */ - struct H5F_access_t *raw_access; /*plist for raw data file */ - } split; - -#ifdef HAVE_PARALLEL - /* Properties for parallel I/O */ - struct { - MPI_Comm comm; /* communicator for file access */ - MPI_Info info; /* optional info for MPI-IO */ - MPI_Datatype btype; /* buffer type for xfers */ - MPI_Datatype ftype; /* file type for xfers */ - haddr_t disp; /* displacement for set_view in xfers */ - int use_types; /* if !0, use btype, ftype, disp. */ - /* otherwise do simple byteblk xfer */ - int old_use_types; /* remember value of use_types */ - /* from last xfer */ - } mpio; -#endif - - } u; + uintn gc_ref; /* Garbage-collect references? */ + hid_t driver_id; /* File driver ID */ + void *driver_info; /* File driver specific information */ } H5F_access_t; -/* - * These things make a file unique. - */ -typedef struct H5F_search_t { - dev_t dev; /* Device number containing file */ - ino_t ino; /* Unique file number on device */ -#if WIN32 - /* - * Specifies the low-order word of a unique identifier associated with the - * file. This identifier and the volume serial number uniquely identify a - * file. This number may change when the system is restarted or when the - * file is opened. After a process opens a file, the identifier is - * constant until the file is closed. An application can use this - * identifier and the volume serial number to determine whether two - * handles refer to the same file. - */ - int fileindexlo; - int fileindexhi; -#endif -} H5F_search_t; - -/* For determining what the last file operation was */ -typedef enum { - H5F_OP_UNKNOWN, /* Don't know what the last operation was*/ - H5F_OP_SEEK, /* Last operation was a seek */ - H5F_OP_WRITE, /* Last operation was a write */ - H5F_OP_READ /* Last operation was a read */ -} H5F_fileop_t; - -/* A free-list entry */ -#define H5MF_NFREE 32 /*size of free block array */ -typedef struct H5MF_free_t { - haddr_t addr; /*file address */ - hsize_t size; /*size of free area */ -} H5MF_free_t; - -/* Dataset transfer property list */ +/* Data transfer property list */ typedef struct H5F_xfer_t { size_t buf_size; /*max temp buffer size */ void *tconv_buf; /*type conversion buffer or null */ @@ -342,125 +268,14 @@ typedef struct H5F_xfer_t { double split_ratios[3];/*B-tree node splitting ratios */ uintn cache_hyper; /*cache hyperslab blocks during I/O? */ uintn block_limit; /*largest hyperslab block to cache */ - H5D_transfer_t xfer_mode; /*independent or collective transfer */ - H5MM_allocate_t vlen_alloc; /* VL datatype allocation function */ - void * alloc_info; /* VL datatype allocation information */ - H5MM_free_t vlen_free; /* VL datatype free function */ - void * free_info; /* VL datatype free information */ + H5MM_allocate_t vlen_alloc; /*VL datatype allocation function */ + void *alloc_info; /*VL datatype allocation information */ + H5MM_free_t vlen_free; /*VL datatype free function */ + void *free_info; /*VL datatype free information */ + hid_t driver_id; /*File driver ID */ + void *driver_info; /*File driver specific information */ } H5F_xfer_t; -/* - * Define the low-level file interface. - */ -typedef struct H5F_low_class_t { - htri_t (*access)(const char *name, const H5F_access_t *access_parms, - int mode, H5F_search_t *key/*out*/); - struct H5F_low_t *(*open)(const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/); - herr_t (*close)(struct H5F_low_t *lf, - const H5F_access_t *access_parms); - herr_t (*read)(struct H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf); - herr_t (*write)(struct H5F_low_t *lf, - const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf); - herr_t (*flush)(struct H5F_low_t *lf, - const H5F_access_t *access_parms); - herr_t (*extend)(struct H5F_low_t *lf, - const H5F_access_t *access_parms, - intn op, hsize_t size, haddr_t *addr/*out*/); - intn (*alloc)(struct H5F_low_t *lf, intn op, hsize_t alignment, - hsize_t threshold, hsize_t size, H5MF_free_t *blk, - haddr_t *addr/*out*/); -} H5F_low_class_t; - -/* - * One of these H5F_low_t structs is allocated for each H5F_file_t struct. - * This struct describes how to access the storage for the hdf5 address space, - * whether that storage is file, local memory, shared memory, network - * distributed global memory, etc. - */ -typedef struct H5F_low_t { - const H5F_low_class_t *type;/* What type of file is this? */ - haddr_t eof; /* Address of logical end-of-file */ - uintn eof_written; /* whether the last byte is written */ - union { - - /* File families */ - struct { - char *name; /* Family name */ - uintn flags; /* Flags for opening member files */ - intn nmemb; /* Number of family members */ - intn nalloc; /* Size of member table in elements */ - struct H5F_low_t **memb; /* An array of family members */ - haddr_t memb_size; /*Size of each family member */ - } fam; - - /* Split meta/raw data */ - struct { - char *name; /* Base name w/o extension */ - uint64_t mask; /* Bit that determines which file to use*/ - struct H5F_low_t *meta; /* Meta data file */ - struct H5F_low_t *raw; /* Raw data file */ - } split; - - /* Posix section 2 I/O */ - struct { - int fd; /* The unix file descriptor */ - H5F_fileop_t op; /* Previous file operation */ -#ifdef HAVE_LSEEK64 - off64_t cur; /* Current file position */ -#else - off_t cur; /* Current file position */ -#endif - } sec2; - - /* Posix stdio */ - struct { - FILE *f; /* Posix stdio file */ - H5F_fileop_t op; /* Previous file operation */ -#ifdef HAVE_FSEEK64 - int64_t cur; /* Current file position */ -#else - long cur; /* Current file position */ -#endif - } stdio; - - /* In-core temp file */ - struct { - uint8_t *mem; /* Mem image of the file */ - size_t size; /* Current file size */ - size_t alloc; /* Current size of MEM buffer */ - } core; - -#ifdef HAVE_PARALLEL - /* MPI-IO */ - struct { - MPI_File f; /* MPI-IO file handle */ - hbool_t allsame;/* all procs should write same data, * - * so only p0 will do the actual write */ - } mpio; -#endif - - } u; -} H5F_low_t; - -/* What types of low-level files are there? */ -#ifndef H5F_LOW_DFLT -# define H5F_LOW_DFLT H5F_LOW_SEC2 /* The default type */ -#endif -__DLLVAR__ const H5F_low_class_t H5F_LOW_SEC2_g[]; /*Posix section 2 */ -__DLLVAR__ const H5F_low_class_t H5F_LOW_STDIO_g[]; /*Posix stdio */ -__DLLVAR__ const H5F_low_class_t H5F_LOW_CORE_g[]; /*In-core temp file */ -__DLLVAR__ const H5F_low_class_t H5F_LOW_FAMILY_g[];/*File family */ -__DLLVAR__ const H5F_low_class_t H5F_LOW_SPLIT_g[]; /*Split meta/raw data*/ -#ifdef HAVE_PARALLEL -__DLLVAR__ const H5F_low_class_t H5F_LOW_MPIO_g[]; /*MPI-IO */ -#endif - /* The raw data chunk cache */ typedef struct H5F_rdcc_t { uintn ninits; /* Number of chunk creations */ @@ -483,24 +298,20 @@ typedef struct H5F_rdcc_t { * pointing to this struct. */ typedef struct H5F_file_t { - H5F_search_t key; /* The key for looking up files */ uintn flags; /* Access Permissions for file */ - H5F_low_t *lf; /* Lower level file handle for I/O */ + H5FD_t *lf; /* Lower level file handle for I/O */ uintn nrefs; /* Ref count for times file is opened */ uint32_t consist_flags; /* File Consistency Flags */ 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 hdf5_eof; /* Relative addr of end of all hdf5 data*/ struct H5AC_t *cache; /* The object cache */ - H5F_create_t *create_parms; /* File-creation property list */ - H5F_access_t *access_parms; /* File-access property list */ + H5F_create_t *fcpl; /* File-creation property list */ + H5F_access_t *fapl; /* File-access property list */ struct H5G_t *root_grp; /* Open root group */ intn ncwfs; /* Num entries on cwfs list */ struct H5HG_heap_t **cwfs; /* Global heap cache */ H5F_rdcc_t rdcc; /* Raw data chunk cache */ - intn fl_nfree; /*number of free blocks in array */ - H5MF_free_t fl_free[H5MF_NFREE]; /*free block array */ } H5F_file_t; /* Mount property list */ @@ -605,9 +416,8 @@ __DLLVAR__ hbool_t H5_mpi_1_metawrite_g; __DLL__ herr_t H5F_init(void); __DLL__ void H5F_encode_length_unusual(const H5F_t *f, uint8_t **p, uint8_t *l); -__DLL__ H5F_t *H5F_open(const char *name, uintn flags, - const H5F_create_t *create_parms, - const H5F_access_t *access_parms); +__DLL__ H5F_t *H5F_open(const char *name, uintn flags, hid_t fcpl_id, + hid_t fapl_id); __DLL__ herr_t H5F_close(H5F_t *f); __DLL__ herr_t H5F_close_all(void); __DLL__ herr_t H5F_flush_all(hbool_t invalidate); @@ -620,7 +430,7 @@ __DLL__ herr_t H5F_mountpoint(struct H5G_entry_t *find/*in,out*/); /* Functions that operate on array storage */ __DLL__ herr_t H5F_arr_create(H5F_t *f, struct H5O_layout_t *layout /*in,out*/); -__DLL__ herr_t H5F_arr_read (H5F_t *f, const struct H5F_xfer_t *xfer, +__DLL__ herr_t H5F_arr_read (H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, @@ -629,7 +439,7 @@ __DLL__ herr_t H5F_arr_read (H5F_t *f, const struct H5F_xfer_t *xfer, const hsize_t mem_size[], const hssize_t mem_offset[], const hssize_t file_offset[], void *_buf/*out*/); -__DLL__ herr_t H5F_arr_write (H5F_t *f, const struct H5F_xfer_t *xfer, +__DLL__ herr_t H5F_arr_write (H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, @@ -647,22 +457,21 @@ __DLL__ hsize_t H5F_istore_allocated(H5F_t *f, int ndims, haddr_t addr); __DLL__ herr_t H5F_istore_stats (H5F_t *f, hbool_t headers); __DLL__ herr_t H5F_istore_create(H5F_t *f, struct H5O_layout_t *layout/*in,out*/); -__DLL__ herr_t H5F_istore_read(H5F_t *f, const struct H5F_xfer_t *xfer, +__DLL__ herr_t H5F_istore_read(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const hssize_t offset[], const hsize_t size[], void *buf/*out*/); -__DLL__ herr_t H5F_istore_write(H5F_t *f, const struct H5F_xfer_t *xfer, +__DLL__ herr_t H5F_istore_write(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const hssize_t offset[], const hsize_t size[], const void *buf); -__DLL__ herr_t H5F_istore_allocate (H5F_t *f, +__DLL__ herr_t H5F_istore_allocate (H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout, const hsize_t *space_dim, - const double split_ratios[], const struct H5O_pline_t *pline, const struct H5O_fill_t *fill); __DLL__ herr_t H5F_istore_dump_btree(H5F_t *f, FILE *stream, int ndims, @@ -670,54 +479,31 @@ __DLL__ herr_t H5F_istore_dump_btree(H5F_t *f, FILE *stream, int ndims, /* Functions that operate on contiguous storage wrt boot block */ __DLL__ herr_t H5F_block_read(H5F_t *f, haddr_t addr, hsize_t size, - const H5F_xfer_t *xfer_parms, void *buf); + hid_t dxpl_id, void *buf/*out*/); __DLL__ herr_t H5F_block_write(H5F_t *f, haddr_t addr, hsize_t size, - const H5F_xfer_t *xfer_parms, const void *buf); - -/* Functions that operate directly on low-level files */ -__DLL__ const H5F_low_class_t *H5F_low_class (H5F_driver_t driver); -__DLL__ herr_t H5F_low_extend(H5F_low_t *lf, const H5F_access_t *access_parms, - intn op, hsize_t size, haddr_t *addr/*out*/); -__DLL__ herr_t H5F_low_seteof(H5F_low_t *lf, haddr_t addr); -__DLL__ intn H5F_low_alloc (H5F_low_t *lf, intn op, hsize_t alignment, - hsize_t threshold, hsize_t size, H5MF_free_t *blk, - haddr_t *addr/*out*/); -__DLL__ htri_t H5F_low_access(const H5F_low_class_t *type, const char *name, - const H5F_access_t *access_parms, int mode, - H5F_search_t *key); -__DLL__ H5F_low_t *H5F_low_open(const H5F_low_class_t *type, const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key); -__DLL__ H5F_low_t *H5F_low_close(H5F_low_t *lf, - const H5F_access_t *access_parms); -__DLL__ hsize_t H5F_low_size(H5F_low_t *lf, haddr_t *addr); -__DLL__ herr_t H5F_low_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf); -__DLL__ herr_t H5F_low_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf); -__DLL__ herr_t H5F_low_flush(H5F_low_t *lf, const H5F_access_t *access_parms); + hid_t dxpl_id, const void *buf); /* Address-related macros and functions */ -#define H5F_ADDR_UNDEF ((uint64_t)(-1L)) +#define H5F_addr_overflow(X,Z) (HADDR_UNDEF==(X) || \ + HADDR_UNDEF==(X)+(haddr_t)(Z) || \ + (X)+(haddr_t)(Z)<(X)) #define H5F_addr_hash(X,M) ((unsigned)((X)%(M))) -#define H5F_addr_defined(X) (X!=H5F_ADDR_UNDEF) -#define H5F_addr_eq(X,Y) ((X)!=H5F_ADDR_UNDEF && \ - (Y)!=H5F_ADDR_UNDEF && \ +#define H5F_addr_defined(X) (X!=HADDR_UNDEF) +#define H5F_addr_eq(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ (X)==(Y)) #define H5F_addr_ne(X,Y) (!H5F_addr_eq((X),(Y))) -#define H5F_addr_lt(X,Y) ((X)!=H5F_ADDR_UNDEF && \ - (Y)!=H5F_ADDR_UNDEF && \ +#define H5F_addr_lt(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ (X)<(Y)) -#define H5F_addr_le(X,Y) ((X)!=H5F_ADDR_UNDEF && \ - (Y)!=H5F_ADDR_UNDEF && \ +#define H5F_addr_le(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ (X)<=(Y)) -#define H5F_addr_gt(X,Y) ((X)!=H5F_ADDR_UNDEF && \ - (Y)!=H5F_ADDR_UNDEF && \ +#define H5F_addr_gt(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ (X)>(Y)) -#define H5F_addr_ge(X,Y) ((X)!=H5F_ADDR_UNDEF && \ - (Y)!=H5F_ADDR_UNDEF && \ +#define H5F_addr_ge(X,Y) ((X)!=HADDR_UNDEF && \ + (Y)!=HADDR_UNDEF && \ (X)>=(Y)) #define H5F_addr_cmp(X,Y) (H5F_addr_eq(X,Y)?0: \ (H5F_addr_lt(X, Y)?-1:1)) @@ -729,11 +515,4 @@ __DLL__ void H5F_addr_decode(H5F_t *, const uint8_t**/*in,out*/, __DLL__ herr_t H5F_addr_pack(H5F_t UNUSED *f, haddr_t *addr_p/*out*/, const unsigned long objno[2]); -/* Functions for MPI-IO */ -#ifdef HAVE_PARALLEL -__DLL__ htri_t H5F_mpio_tas_allsame(H5F_low_t *lf, hbool_t newval); -__DLL__ herr_t H5PC_Wait_for_left_neighbor(MPI_Comm comm); -__DLL__ herr_t H5PC_Signal_right_neighbor(MPI_Comm comm); -#endif /* HAVE_PARALLEL */ - #endif diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 69a4fa5..3dc536d 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -34,30 +34,20 @@ #define H5F_ACC_TRUNC (H5check(),0x0002u) /*overwrite existing files */ #define H5F_ACC_EXCL (H5check(),0x0004u) /*fail if file already exists*/ #define H5F_ACC_DEBUG (H5check(),0x0008u) /*print debug info */ +#define H5F_ACC_CREAT (H5check(),0x0010u) /*create non-existing files */ -#ifdef HAVE_PARALLEL -/* Use this constant string as the MPI_Info key to set H5Fmpio debug flags. - * To turn on H5Fmpio debug flags, - * set the MPI_Info value with this key to have the value of a string - * consisting of the characters that turn on the desired flags. */ -#define H5F_MPIO_DEBUG_KEY "H5F_mpio_debug_key" -#endif +#ifdef HAVE_PARALLEL /* - * Low-level file drivers. These values are returned by H5Pget_file_driver() - * and are set by the various H5Pset_...() functions that set file driver - * properties. + * Use this constant string as the MPI_Info key to set H5Fmpio debug flags. + * To turn on H5Fmpio debug flags, set the MPI_Info value with this key to + * have the value of a string consisting of the characters that turn on the + * desired flags. */ -typedef enum H5F_driver_t { - H5F_LOW_ERROR = -1, /*error return value */ - H5F_LOW_STDIO = 0, /*use functions declared in stdio.h */ - H5F_LOW_SEC2 = 1, /*use functions declared in unistd.h */ - H5F_LOW_MPIO = 2, /*use indep or collective MPI-IO */ - H5F_LOW_CORE = 3, /*use malloc() and free() */ - H5F_LOW_SPLIT = 4, /*separate meta data from raw data */ - H5F_LOW_FAMILY = 5 /*split addr space over many files */ -} H5F_driver_t; +#define H5F_MPIO_DEBUG_KEY "H5F_mpio_debug_key" +#endif +/* The difference between a single file and a set of mounted files */ typedef enum H5F_scope_t { H5F_SCOPE_LOCAL = 0, /*specified file handle only */ H5F_SCOPE_GLOBAL = 1, /*entire virtual file */ diff --git a/src/H5Fsec2.c b/src/H5Fsec2.c deleted file mode 100644 index cacbff2..0000000 --- a/src/H5Fsec2.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 1997 NCSA - * All rights reserved. - * - * Programmer: Robb Matzke <matzke@llnl.gov> - * Wednesday, October 22, 1997 - * - * Purpose: This is the Posix section-2 I/O subclass of H5Flow. - * - * Notes: This driver keeps track of its own file position in order to - * minimize the number of calls to lseek(). We assume that - * opening a file sets the current file position to the beginning - * and that read() and write() modify the file position as - * expected when they return successfully (unsuccessful return - * leaves the file position undefined). - */ -#include <H5private.h> -#include <H5Eprivate.h> -#include <H5Fprivate.h> -#include <H5MMprivate.h> - -#define PABLO_MASK H5Fsec2_mask -static intn interface_initialize_g = 0; -#define INTERFACE_INIT NULL - -static H5F_low_t *H5F_sec2_open(const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/); -static herr_t H5F_sec2_close(H5F_low_t *lf, const H5F_access_t *access_parms); -static herr_t H5F_sec2_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf/*out*/); -static herr_t H5F_sec2_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf); - -const H5F_low_class_t H5F_LOW_SEC2_g[1] = {{ - NULL, /* access method */ - H5F_sec2_open, /* open method */ - H5F_sec2_close, /* close method */ - H5F_sec2_read, /* read method */ - H5F_sec2_write, /* write method */ - NULL, /* flush method */ - NULL, /* extend method */ - NULL, /* alloc method */ -}}; - - -/*------------------------------------------------------------------------- - * Function: H5F_sec2_open - * - * Purpose: Opens a file with name NAME. The FLAGS are a bit field with - * the possible values defined in H5F_low_open(). - * - * Errors: - * IO CANTOPENFILE Open failed. - * - * Return: Success: Low-level file pointer - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static H5F_low_t * -H5F_sec2_open(const char *name, const H5F_access_t UNUSED *access_parms, - uintn flags, H5F_search_t *key/*out*/) -{ - intn oflags; - H5F_low_t *lf = NULL; - int fd; - struct stat sb; - - FUNC_ENTER(H5F_sec2_open, NULL); - - oflags = (flags & H5F_ACC_RDWR) ? O_RDWR : O_RDONLY; - oflags |= (flags & H5F_ACC_CREAT) ? O_CREAT : 0; - oflags |= (flags & H5F_ACC_EXCL) ? O_EXCL : 0; - oflags |= (flags & H5F_ACC_TRUNC) ? O_TRUNC : 0; - - if ((fd = HDopen(name, oflags, 0666)) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "open failed"); - } - if (NULL==(lf = H5MM_calloc(sizeof(H5F_low_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - lf->u.sec2.fd = fd; - lf->u.sec2.op = H5F_OP_SEEK; - lf->u.sec2.cur = 0; - HDfstat(fd, &sb); - lf->eof = sb.st_size; - - if (key) { -#if WIN32 - - int fd; - HFILE filehandle; - struct _BY_HANDLE_FILE_INFORMATION fileinfo; - int results; - - - fd = HDopen(name,_O_RDONLY,0); - filehandle = _get_osfhandle(fd); - results = GetFileInformationByHandle(filehandle, &fileinfo); - - /*returns a 0 on failure*/ - - if (!results) { - lf = NULL; - } - - else { - HDstat(name,&sb); - key->dev = sb.st_dev; - key->ino = 0; - key->fileindexhi = fileinfo.nFileIndexHigh; - key->fileindexlo = fileinfo.nFileIndexLow; - } - - HDclose(fd); - -#else - key->dev = sb.st_dev; - key->ino = sb.st_ino; -#endif - } - FUNC_LEAVE(lf); -} - -/*------------------------------------------------------------------------- - * Function: H5F_sec2_close - * - * Purpose: Closes a file. - * - * Errors: - * IO CLOSEERROR Close failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_sec2_close(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms) -{ - FUNC_ENTER(H5F_sec2_close, FAIL); - - if (HDclose(lf->u.sec2.fd) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "close failed"); - } - lf->u.sec2.fd = -1; - - FUNC_LEAVE(SUCCEED); -} - -/*------------------------------------------------------------------------- - * Function: H5F_sec2_read - * - * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and - * places them in buffer BUF. Reading past the logical or - * physical end of file returns zeros instead of failing. - * - * Errors: - * IO READERROR Read failed. - * IO SEEKERROR Lseek failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_sec2_read(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms, - const H5F_xfer_t UNUSED *xfer_parms, haddr_t addr, size_t size, - uint8_t *buf) -{ - ssize_t n; - uint64_t mask; -#ifdef HAVE_LSEEK64 - off64_t offset; -#else - off_t offset; -#endif - - FUNC_ENTER(H5F_sec2_read, FAIL); - - /* Check for overflow */ - mask = (uint64_t)1 << (8*sizeof(offset)-1); - if (addr >= mask || - addr+size < addr || - addr+size >= mask) { - HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed"); - } -#ifdef HAVE_LSEEK64 - offset = (off64_t)(addr); /*checked for overflow above*/ -#else - offset = (off_t)(addr); /*checked for overflow above*/ -#endif - - /* Check easy cases */ - if (0 == size) HRETURN(SUCCEED); - if ((uint64_t)offset >= lf->eof) { - HDmemset(buf, 0, size); - HRETURN(SUCCEED); - } - - /* - * Optimize seeking. If that optimization is disabled then always call - * lseek(). - */ - if (!H5F_OPT_SEEK || - lf->u.sec2.op == H5F_OP_UNKNOWN || - lf->u.sec2.cur != offset) { -#ifdef HAVE_LSEEK64 - if (lseek64 (lf->u.sec2.fd, offset, SEEK_SET)<0) { - HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL, "lseek64 failed"); - } -#else - if (HDlseek(lf->u.sec2.fd, offset, SEEK_SET) < 0) { - HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "lseek failed"); - } -#endif - lf->u.sec2.cur = offset; - } - - /* - * Read zeros past the logical end of file (physical is handled below) - */ - if ((size_t) offset + size > lf->eof) { - size_t nbytes = (size_t)offset + size - lf->eof; - HDmemset(buf + size - nbytes, 0, nbytes); - size -= nbytes; - } - - /* - * Read the data. If a read error occurs then set the last file operation - * to UNKNOWN because the file position isn't guaranteed by Posix. - */ - if ((n = HDread(lf->u.sec2.fd, buf, size)) < 0) { - lf->u.sec2.op = H5F_OP_UNKNOWN; - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "read failed"); - } else if ((size_t)n < size) { - HDmemset(buf + n, 0, size - n); - } - - /* - * Update the file position with the number of bytes actually read. This - * might be different than the number requested. - */ - lf->u.sec2.op = H5F_OP_READ; - lf->u.sec2.cur = offset + n; - - FUNC_LEAVE(SUCCEED); -} - -/*------------------------------------------------------------------------- - * Function: H5F_sec2_write - * - * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at - * file address ADDR. - * - * Errors: - * IO SEEKERROR Lseek failed. - * IO WRITEERROR Write failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_sec2_write(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms, - const H5F_xfer_t UNUSED *xfer_parms, haddr_t addr, size_t size, - const uint8_t *buf) -{ - uint64_t mask; - ssize_t n; -#ifdef HAVE_LSEEK64 - off64_t offset; -#else - off_t offset; -#endif - - FUNC_ENTER(H5F_sec2_write, FAIL); - - /* Check for overflow */ - mask = (uint64_t)1 << (8*sizeof(offset)-1); - if (addr >= mask || - addr+size < addr || - addr+size >= mask) { - HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed"); - } -#ifdef HAVE_LSEEK64 - offset = (off64_t)(addr); /*checked for overflow*/ - n = (off64_t)size; /*checked for overflow*/ -#else - offset = (off_t)(addr); /*checked for overflow*/ - n = (off_t)size; /*checked for overflow*/ -#endif - - /* - * Optimize seeking. If that optimization is disabled then always call - * lseek(). - */ - if (!H5F_OPT_SEEK || - lf->u.sec2.op == H5F_OP_UNKNOWN || - lf->u.sec2.cur != offset) { - if (HDlseek(lf->u.sec2.fd, offset, SEEK_SET) < 0) { - HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "lseek failed"); - } - lf->u.sec2.cur = offset; - } - - /* - * Write the data to the file. If the write failed then set the - * operation back to UNKNOWN since Posix doesn't gurantee its value. - */ - if (n != HDwrite(lf->u.sec2.fd, buf, size)) { - lf->u.sec2.op = H5F_OP_UNKNOWN; - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write failed"); - } - - /* - * Update the file position. - */ - lf->u.sec2.op = H5F_OP_WRITE; - lf->u.sec2.cur = offset + n; - - FUNC_LEAVE(SUCCEED); -} diff --git a/src/H5Fsplit.c b/src/H5Fsplit.c deleted file mode 100644 index d18b113..0000000 --- a/src/H5Fsplit.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (C) 1997 NCSA - * All rights reserved. - * - * Programmer: Robb Matzke <matzke@llnl.gov> - * Thursday, November 13, 1997 - * - * Purpose: A driver that splits the meta data and raw data into two - * separate files. The high-order bit of the file address - * determines whether the address refers to the meta data file - * (high order bit is clear) or the raw data file (high order bit - * is set). - */ -#include <H5private.h> -#include <H5Eprivate.h> -#include <H5Fprivate.h> -#include <H5MFprivate.h> -#include <H5MMprivate.h> - -/* Default file name extensions */ -#define H5F_SPLIT_META_EXT ".meta" -#define H5F_SPLIT_RAW_EXT ".raw" - -#define PABLO_MASK H5Fsplit_mask -static intn interface_initialize_g = 0; -#define INTERFACE_INIT NULL - -static htri_t H5F_split_access(const char *name, - const H5F_access_t *access_parms, int mode, - H5F_search_t *key/*out*/); -static H5F_low_t *H5F_split_open(const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/); -static herr_t H5F_split_close(H5F_low_t *lf, const H5F_access_t *access_parms); -static herr_t H5F_split_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf/*out*/); -static herr_t H5F_split_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, - haddr_t addr, size_t size, const uint8_t *buf); -static herr_t H5F_split_flush(H5F_low_t *lf, const H5F_access_t *access_parms); -static herr_t H5F_split_extend(H5F_low_t *lf, const H5F_access_t *access_parms, - intn op, hsize_t size, haddr_t *addr/*out*/); -static intn H5F_split_alloc (H5F_low_t *lf, intn op, hsize_t alignment, - hsize_t threshold, hsize_t size, H5MF_free_t *blk, - haddr_t *addr/*out*/); - -const H5F_low_class_t H5F_LOW_SPLIT_g[1] = {{ - H5F_split_access, /*access method */ - H5F_split_open, /*open method */ - H5F_split_close, /*close method */ - H5F_split_read, /*read method */ - H5F_split_write, /*write method */ - H5F_split_flush, /*flush method */ - H5F_split_extend, /*extend method */ - H5F_split_alloc, /*alloc method */ -}}; - -/* - * This is the bit that determines whether the address is part of the meta - * data file or part of the raw data file. Eventually we'll want to pass - * this kind of thing down to this function from above... - */ -#define H5F_SPLIT_MASK 0x80000000 - - -/*------------------------------------------------------------------------- - * Function: H5F_split_open - * - * Purpose: Opens a split meta data/raw data family with the specified - * base name. The name of the meta data file will be created by - * appending `.h5' while the name of the raw data file will be - * created by appending `.raw'. - * - * Return: Success: Low-level file pointer - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Monday, November 13, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static H5F_low_t * -H5F_split_open(const char *name, const H5F_access_t *access_parms, - uintn flags, H5F_search_t *key/*out*/) -{ - H5F_low_t *lf = NULL, *ret_value = NULL; - char fullname[4096]; - const char *ext; /*file name extension*/ - const H5F_low_class_t *meta_type = NULL; - const H5F_low_class_t *raw_type = NULL; - - FUNC_ENTER(H5F_split_open, NULL); - - assert(name && *name); - assert (access_parms); - assert (H5F_LOW_SPLIT==access_parms->driver); - assert (access_parms->u.split.meta_access); - assert (access_parms->u.split.raw_access); - - /* Get member types */ - meta_type = H5F_low_class (access_parms->u.split.meta_access->driver); - raw_type = H5F_low_class (access_parms->u.split.raw_access->driver); - - /* Create the file descriptor */ - if (NULL==(lf = H5MM_calloc(sizeof(H5F_low_t)))) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - lf->u.split.name = H5MM_xstrdup(name); - lf->u.split.mask = H5F_SPLIT_MASK; - - /* Open the meta data file */ - ext = access_parms->u.split.meta_ext ? - access_parms->u.split.meta_ext : H5F_SPLIT_META_EXT; - if (HDstrlen(name)+HDstrlen(ext) >= sizeof fullname) { - HGOTO_ERROR (H5E_IO, H5E_CANTINIT, NULL, "file name is too long"); - } - HDstrcpy(fullname, name); - HDstrcat(fullname, ext); - - lf->u.split.meta = H5F_low_open(meta_type, fullname, - access_parms->u.split.meta_access, - flags, key/*out*/); - if (NULL == lf->u.split.meta) { - HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "can't open meta file"); - } - - /* Open the raw data file */ - ext = access_parms->u.split.raw_ext ? - access_parms->u.split.raw_ext : H5F_SPLIT_RAW_EXT; - if (HDstrlen(name)+HDstrlen(ext) >= sizeof fullname) { - HGOTO_ERROR (H5E_IO, H5E_CANTINIT, NULL, "file name is too long"); - } - HDstrcpy(fullname, name); - HDstrcat(fullname, ext); - - lf->u.split.raw = H5F_low_open(raw_type, fullname, - access_parms->u.split.raw_access, - flags, NULL); - if (NULL == lf->u.split.raw) { - HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "can't open raw file"); - } - - /* Initialize the file size */ - H5F_low_size(lf->u.split.raw, &(lf->eof)); - lf->eof |= lf->u.split.mask; - - HRETURN(lf); - - done: - if (!ret_value) { - if (lf) { - H5F_split_close(lf, access_parms); - H5MM_xfree(lf); - } - } - FUNC_LEAVE(ret_value); -} - -/*------------------------------------------------------------------------- - * Function: H5F_split_close - * - * Purpose: Closes a split file. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 13, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_split_close(H5F_low_t *lf, const H5F_access_t *access_parms) -{ - FUNC_ENTER(H5F_split_close, FAIL); - - assert(lf); - - H5F_low_close(lf->u.split.meta, access_parms->u.split.meta_access); - H5F_low_close(lf->u.split.raw, access_parms->u.split.raw_access); - H5MM_xfree(lf->u.split.name); - - FUNC_LEAVE(SUCCEED); -} - -/*------------------------------------------------------------------------- - * Function: H5F_split_read - * - * Purpose: Reads a chunk of contiguous data from a split file. We - * assume that the data being read never crosses the meta - * data/raw data boundary. Reading past the end of a file - * returns zeros instead of failing. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 13, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_split_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - uint8_t *buf/*out*/) -{ - haddr_t tmp_addr; - H5F_low_t *sub = NULL; - herr_t status; - const H5F_access_t *sub_parms = NULL; - - FUNC_ENTER(H5F_split_read, FAIL); - - assert(lf); - assert(H5F_addr_defined(addr)); - assert(buf); - /* no collective support */ - assert(xfer_parms->xfer_mode != H5D_XFER_COLLECTIVE); - - /* Which file to we actually read from? */ - if (addr & lf->u.split.mask) { - sub = lf->u.split.raw; - sub_parms = access_parms->u.split.raw_access; - tmp_addr = addr & (lf->u.split.mask - 1); - } else { - sub = lf->u.split.meta; - sub_parms = access_parms->u.split.meta_access; - tmp_addr = addr; - } - - /* Read the data */ - status = H5F_low_read(sub, sub_parms, xfer_parms, tmp_addr, size, - buf/*out*/); - FUNC_LEAVE(status); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_split_write - * - * Purpose: Writes BUF to either the meta data file or the raw data file. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 13, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_split_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, size_t size, - const uint8_t *buf) -{ - haddr_t tmp_addr; - H5F_low_t *sub = NULL; - herr_t status; - const H5F_access_t *sub_parms = NULL; - - FUNC_ENTER(H5F_split_write, FAIL); - - assert(lf); - assert(H5F_addr_defined(addr)); - assert(buf); - /* no collective support */ - assert(xfer_parms->xfer_mode != H5D_XFER_COLLECTIVE); - - /* Which file to we actually write to? */ - if (addr & lf->u.split.mask) { - sub = lf->u.split.raw; - sub_parms = access_parms->u.split.raw_access; - tmp_addr = addr & (lf->u.split.mask - 1); - } else { - sub = lf->u.split.meta; - sub_parms = access_parms->u.split.meta_access; - tmp_addr = addr; - } - - /* Write the data */ - status = H5F_low_write(sub, sub_parms, xfer_parms, tmp_addr, size, buf); - FUNC_LEAVE(status); -} - -/*------------------------------------------------------------------------- - * Function: H5F_split_flush - * - * Purpose: Flushes all data to disk. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, November 13, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_split_flush(H5F_low_t *lf, const H5F_access_t *access_parms) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER(H5F_split_flush, FAIL); - - assert(lf); - - ret_value = (H5F_low_flush(lf->u.split.meta, - access_parms->u.split.meta_access) >= 0 && - H5F_low_flush(lf->u.split.raw, - access_parms->u.split.raw_access) >= 0); - - FUNC_LEAVE(ret_value); -} - -/*------------------------------------------------------------------------- - * Function: H5F_split_access - * - * Purpose: Determines if both members of the split data file family can - * be accessed and returns the key for the first member of the - * family. - * - * Return: Success: TRUE or FALSE - * - * Failure: FAIL - * - * Programmer: Robb Matzke - * Monday, November 13, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static htri_t -H5F_split_access(const char *name, const H5F_access_t *access_parms, - int mode, H5F_search_t *key/*out*/) -{ - char fullname[4096]; - htri_t status; - const char *ext; /*file extension*/ - const H5F_low_class_t *meta_type = NULL; - const H5F_low_class_t *raw_type = NULL; - - FUNC_ENTER(H5F_split_access, FAIL); - - assert(name && *name); - assert (access_parms); - assert (H5F_LOW_SPLIT==access_parms->driver); - assert (access_parms->u.split.meta_access); - assert (access_parms->u.split.raw_access); - - /* The meta data member */ - meta_type = H5F_low_class (access_parms->u.split.meta_access->driver); - ext = access_parms->u.split.meta_ext ? - access_parms->u.split.meta_ext : H5F_SPLIT_META_EXT; - if (HDstrlen(name)+HDstrlen(ext) >= sizeof fullname) { - HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL, "file name is too long"); - } - HDstrcpy(fullname, name); - HDstrcat(fullname, ext); - - status = H5F_low_access(meta_type, fullname, - access_parms->u.split.meta_access, - mode, key/*out*/); - if (status < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "access call failed for meta data member"); - } - if (!status) HRETURN(FALSE); - - /* The raw data member */ - raw_type = H5F_low_class (access_parms->u.split.raw_access->driver); - ext = access_parms->u.split.raw_ext ? - access_parms->u.split.raw_ext : H5F_SPLIT_RAW_EXT; - if (HDstrlen(name)+HDstrlen(ext) >= sizeof fullname) { - HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL, "file name is too long"); - } - HDstrcpy(fullname, name); - HDstrcat(fullname, ext); - - status = H5F_low_access(raw_type, fullname, - access_parms->u.split.raw_access, - mode, NULL/*out*/); - if (status < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "access call failed for raw data member"); - } - FUNC_LEAVE(status); -} - -/*------------------------------------------------------------------------- - * Function: H5F_split_extend - * - * Purpose: Allocates memory from the end of the meta data file or raw - * data file. - * - * Return: Non-negative on success (with the address of the allocated - * memory returned through the ADDR_P argument.) /Negative - * on failure - * - * Programmer: Robb Matzke - * Thursday, November 13, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_split_extend(H5F_low_t *lf, const H5F_access_t *access_parms, intn op, - hsize_t size, haddr_t *addr_p/*out*/) -{ - FUNC_ENTER(H5F_split_extend, FAIL); - - assert(lf); - assert(H5MF_META == op || H5MF_RAW == op); - assert(size > 0); - assert(addr_p); - - if (H5MF_META == op) { - if (H5F_low_extend(lf->u.split.meta, access_parms->u.split.meta_access, - op, size, addr_p/*out*/)<0) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "meta data allocation failed"); - } - if (*addr_p + size > lf->eof) { - lf->eof = *addr_p + size; - } - } else { - if (H5F_low_extend(lf->u.split.raw, access_parms->u.split.raw_access, - op, size, addr_p/*out*/)<0) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "raw data allocation failed"); - } - *addr_p |= lf->u.split.mask; - lf->eof = lf->u.split.raw->eof; - lf->eof |= lf->u.split.mask; - } - - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_split_alloc - * - * Purpose: Determines if free block BLK in file LF can be used to - * satisfy the request for SIZE bytes. This function is - * actually the same as H5F_low_alloc() except it returns - * failure if the OP is not compatible with the block address, - * insuring that meta data is allocated from one half of the - * address space and raw data from the other half. - * - * Return: Success: Positive if the free block satisfies the - * request exactly, zero if the free block - * over-satisfies the request. The ADDR_P will - * contain the address within the free block - * where the request starts. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Tuesday, June 9, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static intn -H5F_split_alloc (H5F_low_t *lf, intn op, hsize_t alignment, hsize_t threshold, - hsize_t size, H5MF_free_t *blk, haddr_t *addr_p/*out*/) -{ - intn ret_value = FAIL; - hsize_t wasted; - - FUNC_ENTER (H5F_split_alloc, FAIL); - assert (lf); - assert (alignment>0); - assert (size>0); - assert (blk); - assert (addr_p); - - switch (op) { - case H5MF_META: - if (blk->addr & lf->u.split.mask) HRETURN(FAIL); - break; - case H5MF_RAW: - if (0==(blk->addr & lf->u.split.mask)) HRETURN(FAIL); - break; - } - - if (size>=threshold) { - wasted = blk->addr % alignment; - } else { - wasted = 0; - } - if (0==wasted && size==blk->size) { - /* exact match */ - *addr_p = blk->addr; - ret_value = 1; - } else if (blk->size>wasted && blk->size-wasted>=size) { - /* over-satisfied */ - *addr_p = blk->addr + wasted; - ret_value = 0; - } - - FUNC_LEAVE (ret_value); -} diff --git a/src/H5Fstdio.c b/src/H5Fstdio.c deleted file mode 100644 index 94ab0d1..0000000 --- a/src/H5Fstdio.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (C) 1997 NCSA - * All rights reserved. - * - * Programmer: Robb Matzke <matzke@llnl.gov> - * Wednesday, October 22, 1997 - * - * Purpose: This is the Posix stdio.h I/O subclass of H5Flow. - */ -#include <H5private.h> -#include <H5private.h> -#include <H5Eprivate.h> -#include <H5Fprivate.h> -#include <H5MMprivate.h> - -#define PABLO_MASK H5Fstdio_mask -static intn interface_initialize_g = 0; -#define INTERFACE_INIT NULL - -static H5F_low_t *H5F_stdio_open(const char *name, - const H5F_access_t *access_parms, uintn flags, - H5F_search_t *key/*out*/); -static herr_t H5F_stdio_close(H5F_low_t *lf, const H5F_access_t *access_parms); -static herr_t H5F_stdio_read(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf/*out*/); -static herr_t H5F_stdio_write(H5F_low_t *lf, const H5F_access_t *access_parms, - const H5F_xfer_t *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf); -static herr_t H5F_stdio_flush(H5F_low_t *lf, const H5F_access_t *access_parms); - -const H5F_low_class_t H5F_LOW_STDIO_g[1] = {{ - NULL, /* use default access(2) func */ - H5F_stdio_open, /* open method */ - H5F_stdio_close, /* close method */ - H5F_stdio_read, /* read method */ - H5F_stdio_write, /* write method */ - H5F_stdio_flush, /* flush method */ - NULL, /* extend method */ - NULL, /* alloc method */ -}}; - - -/*------------------------------------------------------------------------- - * Function: H5F_stdio_open - * - * Purpose: Opens a file with name NAME. The FLAGS are a bit field with - * the possible values defined in H5F_low_open(). - * - * Bugs: H5F_ACC_EXCL has a race condition. - * - * Errors: - * IO CANTOPENFILE File doesn't exist and CREAT wasn't - * specified. - * IO CANTOPENFILE Fopen failed. - * IO FILEEXISTS File exists but CREAT and EXCL were - * specified. - * - * Return: Success: Low-level file pointer - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static H5F_low_t * -H5F_stdio_open(const char *name, const H5F_access_t UNUSED *access_parms, - uintn flags, H5F_search_t *key/*out*/) -{ - H5F_low_t *lf = NULL; - FILE *f = NULL; - struct stat sb; - - FUNC_ENTER(H5F_stdio_open, NULL); - - if (HDaccess(name, F_OK) < 0) { - if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_RDWR)) { - f = HDfopen(name, "wb+"); - } else { - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, - "file doesn't exist and CREAT wasn't specified"); - } - - } else if ((flags & H5F_ACC_CREAT) && (flags & H5F_ACC_EXCL)) { - HRETURN_ERROR(H5E_IO, H5E_FILEEXISTS, NULL, - "file exists but CREAT and EXCL were specified"); - - } else if (flags & H5F_ACC_RDWR) { - if (flags & H5F_ACC_TRUNC) - f = HDfopen(name, "wb+"); - else - f = HDfopen(name, "rb+"); - - } else { - f = HDfopen(name, "rb"); - } - if (!f) - HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL, "fopen failed"); - - /* Build the return value */ - if (NULL==(lf = H5MM_calloc(sizeof(H5F_low_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - lf->u.stdio.f = f; - lf->u.stdio.op = H5F_OP_SEEK; - lf->u.stdio.cur = 0; - lf->eof = 0; - if (HDfseek(lf->u.stdio.f, 0, SEEK_END) < 0) { - lf->u.stdio.op = H5F_OP_UNKNOWN; - } else { - hssize_t x = HDftell (lf->u.stdio.f); - assert (x>=0); - lf->eof += (hsize_t)x; - } - - /* The unique key */ - if (key) { - HDfstat(fileno(f), &sb); - key->dev = sb.st_dev; - key->ino = sb.st_ino; - } - FUNC_LEAVE(lf); -} - -/*------------------------------------------------------------------------- - * Function: H5F_stdio_close - * - * Purpose: Closes a file. - * - * Errors: - * IO CLOSEERROR Fclose failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_stdio_close(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms) -{ - FUNC_ENTER(H5F_stdio_close, FAIL); - - if (HDfclose(lf->u.stdio.f) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "fclose failed"); - } - lf->u.stdio.f = NULL; - - FUNC_LEAVE(SUCCEED); -} - -/*------------------------------------------------------------------------- - * Function: H5F_stdio_read - * - * Purpose: Reads SIZE bytes beginning at address ADDR in file LF and - * places them in buffer BUF. Reading past the logical or - * physical end of file returns zeros instead of failing. - * - * Errors: - * IO READERROR Fread failed. - * IO SEEKERROR Fseek failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_stdio_read(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms, - const H5F_xfer_t UNUSED *xfer_parms, haddr_t addr, - size_t size, uint8_t *buf/*out*/) -{ - size_t n; - uint64_t mask; -#ifdef HAVE_FSEEK64 - int64_t offset; -#else - long offset; -#endif - - FUNC_ENTER(H5F_stdio_read, FAIL); - - /* Check for overflow */ - mask = (uint64_t)1 << (8*sizeof(offset)-1); - if (addr >= mask || - addr + size < addr || - addr+size >= mask) { - HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed"); - } -#ifdef HAVE_FSEEK64 - offset = (int64_t)(addr); /*checked for overflow*/ -#else - offset = (long)(addr); /*checked for overflow*/ -#endif - - /* Check easy cases */ - if (0 == size) HRETURN(SUCCEED); - if ((uint64_t)offset >= lf->eof) { - HDmemset(buf, 0, size); - HRETURN(SUCCEED); - } - - /* - * Seek to the correct file position. - */ - if (!H5F_OPT_SEEK || - lf->u.stdio.op != H5F_OP_READ || - lf->u.stdio.cur != offset) { -#ifdef HAVE_FSEEK64 - if (fseek64 (lf->u.stdio.f, offset, SEEK_SET)<0) { - HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL, "fseek64 failed"); - } -#else - if (HDfseek(lf->u.stdio.f, offset, SEEK_SET) < 0) { - HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "fseek failed"); - } -#endif - lf->u.stdio.cur = offset; - } - - /* - * Read zeros past the logical end of file (physical is handled below) - */ - if ((size_t) offset + size > lf->eof) { - size_t nbytes = (size_t) offset + size - lf->eof; - HDmemset(buf + size - nbytes, 0, nbytes); - size -= nbytes; - } - - /* - * Read the data. Since we're reading single-byte values, a partial read - * will advance the file position by N. If N is negative or an error - * occurs then the file position is undefined. - */ - n = HDfread(buf, 1, size, lf->u.stdio.f); - if (n <= 0 && HDferror(lf->u.stdio.f)) { - lf->u.stdio.op = H5F_OP_UNKNOWN; - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "fread failed"); - } else if (n < size) { - HDmemset(buf + n, 0, size - n); - } - - /* - * Update the file position data. - */ - lf->u.stdio.op = H5F_OP_READ; -#ifdef HAVE_FSEEK64 - lf->u.stdio.cur = (int64_t)(offset+n); /*checked for overflow above*/ -#else - lf->u.stdio.cur = (off_t)(offset+n); /*checked for overflow above*/ -#endif - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_stdio_write - * - * Purpose: Writes SIZE bytes from the beginning of BUF into file LF at - * file address ADDR. - * - * Errors: - * IO SEEKERROR Fseek failed. - * IO WRITEERROR Fwrite failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * Albert Cheng, 1998-06-02 - * Added XFER_MODE argument. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - *------------------------------------------------------------------------- - */ -static herr_t -H5F_stdio_write(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms, - const H5F_xfer_t UNUSED *xfer_parms, haddr_t addr, - size_t size, const uint8_t *buf) -{ - uint64_t mask; -#ifdef HAVE_FSEEK64 - int64_t offset; - uint64_t n; -#else - long offset; - size_t n; -#endif - - FUNC_ENTER(H5F_stdio_write, FAIL); - - /* Check for overflow */ - mask = (uint64_t)1 << (8*sizeof(offset)-1); - if (addr >= mask || - addr+size < addr || - addr+size >= mask) { - HRETURN_ERROR (H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed"); - } -#ifdef HAVE_FSEEK64 - offset = (int64_t)(addr); /*checked for overflow*/ - n = size; /*checked for overflow*/ -#else - offset = (long)(addr); /*checked for overflow*/ - n = size; /*checked for overflow*/ -#endif - - /* - * Seek to the correct file position. - */ - if (!H5F_OPT_SEEK || - lf->u.stdio.op != H5F_OP_WRITE || - lf->u.stdio.cur != offset) { -#ifdef HAVE_FSEEK64 - if (fseek64 (lf->u.stdio.f, offset, SEEK_SET)<0) { - HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL, "fseek64 failed"); - } -#else - if (HDfseek(lf->u.stdio.f, offset, SEEK_SET) < 0) { - HRETURN_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "fseek failed"); - } -#endif - lf->u.stdio.cur = offset; - } - - /* - * Write the buffer. On successful return, the file position will be - * advanced by the number of bytes read. Otherwise nobody knows where it - * is. - */ - if (n != HDfwrite(buf, 1, size, lf->u.stdio.f)) { - lf->u.stdio.op = H5F_OP_UNKNOWN; - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fwrite failed"); - } - - /* - * Update seek optimizing data. - */ - lf->u.stdio.op = H5F_OP_WRITE; - lf->u.stdio.cur = offset + (int64_t)n; - FUNC_LEAVE(SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5F_stdio_flush - * - * Purpose: Makes sure that all data is on disk. - * - * Errors: - * IO WRITEERROR Fflush failed. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Wednesday, October 22, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_stdio_flush(H5F_low_t *lf, const H5F_access_t UNUSED *access_parms) -{ - FUNC_ENTER(H5F_stdio_flush, FAIL); - - /* - * What happens to the file position? Is it guaranteed to be the same - * after the fflush() as it was before? - */ - lf->u.stdio.op = H5F_OP_UNKNOWN; - - /* - * Flush - */ - if (HDfflush(lf->u.stdio.f) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "fflush failed"); - } - FUNC_LEAVE(SUCCEED); -} @@ -1010,7 +1010,7 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/, *obj_ent = *loc_ent; } HDmemset(grp_ent, 0, sizeof(H5G_entry_t)); - grp_ent->header = H5F_ADDR_UNDEF; + grp_ent->header = HADDR_UNDEF; /* traverse the name */ while ((name = H5G_component(name, &nchars)) && *name) { @@ -1040,7 +1040,7 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/, */ *grp_ent = *obj_ent; HDmemset(obj_ent, 0, sizeof(H5G_entry_t)); - obj_ent->header = H5F_ADDR_UNDEF; + obj_ent->header = HADDR_UNDEF; if (H5G_stab_find(grp_ent, comp, obj_ent/*out*/)<0) { /* @@ -1832,6 +1832,7 @@ H5G_loc (hid_t loc_id) case H5I_BADID: case H5I_FILE_CLOSING: case H5I_REFERENCE: + case H5I_VFL: HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object ID"); } @@ -1926,7 +1927,7 @@ H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name, * undefined and the cache contains the link-value offset. */ HDmemset (&cur_obj, 0, sizeof cur_obj); - cur_obj.header = H5F_ADDR_UNDEF; + cur_obj.header = HADDR_UNDEF; cur_obj.file = grp_ent.file; cur_obj.type = H5G_CACHED_SLINK; cur_obj.cache.slink.lval_offset = offset; diff --git a/src/H5Gent.c b/src/H5Gent.c index 06ebe24..f62e89e 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -298,7 +298,7 @@ H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent) } } else { H5F_encode_length(f, *pp, 0); - H5F_addr_encode(f, pp, H5F_ADDR_UNDEF); + H5F_addr_encode(f, pp, HADDR_UNDEF); UINT32ENCODE(*pp, H5G_NOTHING_CACHED); UINT32ENCODE(*pp, 0); /*reserved*/ } diff --git a/src/H5Gnode.c b/src/H5Gnode.c index e28ecb3..5935b8a 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -30,6 +30,9 @@ #include <H5MFprivate.h> /*file memory management */ #include <H5MMprivate.h> /*core memory management */ #include <H5Oprivate.h> /*header messages */ +#include <H5Pprivate.h> /*property lists */ + +#include <H5FDmpio.h> /*the MPIO file driver */ #define PABLO_MASK H5G_node_mask @@ -252,7 +255,7 @@ H5G_node_create(H5F_t *f, H5B_ins_t UNUSED op, void *_lt_key, "memory allocation failed"); } size = H5G_node_size(f); - if (H5MF_alloc(f, H5MF_META, size, addr_p/*out*/) < 0) { + if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, size))) { H5MM_xfree(sym); HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to allocate file space"); @@ -354,9 +357,9 @@ H5G_node_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym) HDmemset(p, 0, size - (p - buf)); #ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame(f->shared->lf, TRUE); /* only p0 will write */ + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/ #endif /* HAVE_PARALLEL */ - status = H5F_block_write(f, addr, (hsize_t)size, &H5F_xfer_dflt, buf); + status = H5F_block_write(f, addr, (hsize_t)size, H5P_DEFAULT, buf); buf = H5MM_xfree(buf); if (status < 0) HRETURN_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, @@ -425,7 +428,7 @@ H5G_node_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - if (H5F_block_read(f, addr, (hsize_t)size, &H5F_xfer_dflt, buf) < 0) { + if (H5F_block_read(f, addr, (hsize_t)size, H5P_DEFAULT, buf) < 0) { HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unabel to read symbol table node"); } @@ -971,7 +974,7 @@ H5G_node_remove(H5F_t *f, haddr_t addr, void *_lt_key/*in,out*/, sn->dirty = TRUE; if (H5AC_unprotect(f, H5AC_SNODE, addr, sn)<0 || H5AC_flush(f, H5AC_SNODE, addr, TRUE)<0 || - H5MF_xfree(f, addr, H5G_node_size(f))<0) { + H5MF_xfree(f, H5FD_MEM_BTREE, addr, H5G_node_size(f))<0) { sn = NULL; HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node"); diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 4071227..e2b657c 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -21,7 +21,7 @@ #define H5G_NODE_VERS 1 /*symbol table node version number */ #define H5G_SIZE_HINT 1024 /*default root grp size hint */ -#define H5G_NODE_K(F) ((unsigned)((F)->shared->create_parms->sym_leaf_k)) +#define H5G_NODE_K(F) ((unsigned)((F)->shared->fcpl->sym_leaf_k)) #define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4) #define H5G_DEFAULT_ROOT_SIZE 32 @@ -29,7 +29,8 @@ #include <H5Eprivate.h> /*error handling */ #include <H5HGprivate.h> /*global heaps */ #include <H5MFprivate.h> /*file memory management */ -#include <H5MMprivate.h> /*memory management */ +#include <H5MMprivate.h> /*core memory management */ +#include <H5Pprivate.h> /*property lists */ #define PABLO_MASK H5HG_mask @@ -106,7 +107,7 @@ H5HG_create (H5F_t *f, size_t size) size = H5HG_ALIGN(size); /* Create it */ - if (H5MF_alloc (f, H5MF_META, (hsize_t)size, &addr/*out*/)<0) { + if (HADDR_UNDEF==(addr=H5MF_alloc(f, H5FD_MEM_GHEAP, (hsize_t)size))) { HGOTO_ERROR (H5E_HEAP, H5E_CANTINIT, NULL, "unable to allocate file space for global heap"); } @@ -234,8 +235,8 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - if (H5F_block_read (f, addr, (hsize_t)H5HG_MINSIZE, &H5F_xfer_dflt, - heap->chunk)<0) { + if (H5F_block_read(f, addr, (hsize_t)H5HG_MINSIZE, H5P_DEFAULT, + heap->chunk)<0) { HGOTO_ERROR (H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection"); } @@ -271,7 +272,7 @@ H5HG_load (H5F_t *f, haddr_t addr, const void UNUSED *udata1, "memory allocation failed"); } if (H5F_block_read (f, next_addr, (hsize_t)(heap->size-H5HG_MINSIZE), - &H5F_xfer_dflt, heap->chunk+H5HG_MINSIZE)<0) { + H5P_DEFAULT, heap->chunk+H5HG_MINSIZE)<0) { HGOTO_ERROR (H5E_HEAP, H5E_READERROR, NULL, "unable to read global heap collection"); } @@ -396,7 +397,7 @@ H5HG_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5HG_heap_t *heap) if (heap->dirty) { if (H5F_block_write (f, addr, (hsize_t)(heap->size), - &H5F_xfer_dflt, heap->chunk)<0) { + H5P_DEFAULT, heap->chunk)<0) { HRETURN_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write global heap collection to file"); } @@ -869,7 +870,7 @@ H5HG_remove (H5F_t *f, H5HG_t *hobj) * to the file free list. */ heap->dirty = FALSE; - H5MF_xfree (f, heap->addr, (hsize_t)(heap->size)); + H5MF_xfree(f, H5FD_MEM_GHEAP, heap->addr, heap->size); H5AC_flush (f, H5AC_GHEAP, heap->addr, TRUE); heap = NULL; } else { @@ -23,8 +23,11 @@ #include <H5Eprivate.h> /*error handling */ #include <H5Fprivate.h> /*file access */ #include <H5HLprivate.h> /*self */ -#include <H5MFprivate.h> /*file memory management */ +#include <H5MFprivate.h> /*file memory management */ #include <H5MMprivate.h> /*core memory management */ +#include <H5Pprivate.h> /*property lists */ + +#include <H5FDmpio.h> /*for H5FD_mpio_tas_allsame() */ #define H5HL_FREE_NULL 1 /*end of free list on disk */ #define PABLO_MASK H5HL_mask @@ -111,8 +114,7 @@ H5HL_create(H5F_t *f, size_t size_hint, haddr_t *addr_p/*out*/) /* allocate file version */ total_size = H5HL_SIZEOF_HDR(f) + size_hint; - if (H5MF_alloc(f, H5MF_META, (hsize_t)total_size, addr_p/*out*/) < 0) { - *addr_p = H5F_ADDR_UNDEF; + if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_LHEAP, total_size))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file memory"); } @@ -154,7 +156,7 @@ H5HL_create(H5F_t *f, size_t size_hint, haddr_t *addr_p/*out*/) done: if (ret_value<0) { if (H5F_addr_defined(*addr_p)) { - H5MF_xfree (f, *addr_p, total_size); + H5MF_xfree(f, H5FD_MEM_LHEAP, *addr_p, total_size); } if (heap) { H5MM_xfree (heap->chunk); @@ -203,8 +205,8 @@ H5HL_load(H5F_t *f, haddr_t addr, const void UNUSED *udata1, assert(!udata1); assert(!udata2); - if (H5F_block_read(f, addr, (hsize_t)H5HL_SIZEOF_HDR(f), - &H5F_xfer_dflt, hdr) < 0) { + if (H5F_block_read(f, addr, (hsize_t)H5HL_SIZEOF_HDR(f), H5P_DEFAULT, + hdr) < 0) { HRETURN_ERROR(H5E_HEAP, H5E_READERROR, NULL, "unable to read heap header"); } @@ -244,7 +246,7 @@ H5HL_load(H5F_t *f, haddr_t addr, const void UNUSED *udata1, } if (heap->disk_alloc && H5F_block_read(f, heap->addr, (hsize_t)(heap->disk_alloc), - &H5F_xfer_dflt, heap->chunk + H5HL_SIZEOF_HDR(f)) < 0) { + H5P_DEFAULT, heap->chunk + H5HL_SIZEOF_HDR(f)) < 0) { HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data"); } @@ -332,13 +334,13 @@ H5HL_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5HL_t *heap) */ if (heap->mem_alloc > heap->disk_alloc) { haddr_t old_addr = heap->addr, new_addr; - if (H5MF_alloc(f, H5MF_META, (hsize_t)(heap->mem_alloc), - &new_addr/*out*/)<0) { + if (HADDR_UNDEF==(new_addr=H5MF_alloc(f, H5FD_MEM_LHEAP, + heap->mem_alloc))) { HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file space for heap"); } heap->addr = new_addr; - H5MF_xfree(f, old_addr, (hsize_t)(heap->disk_alloc)); + H5MF_xfree(f, H5FD_MEM_LHEAP, old_addr, heap->disk_alloc); H5E_clear(); /*don't really care if the free failed */ heap->disk_alloc = heap->mem_alloc; } @@ -378,28 +380,28 @@ H5HL_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5HL_t *heap) if (H5F_addr_eq(heap->addr, hdr_end_addr)) { /* The header and data are contiguous */ #ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ + H5FD_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ #endif /* HAVE_PARALLEL */ if (H5F_block_write(f, addr, (hsize_t)(H5HL_SIZEOF_HDR(f)+heap->disk_alloc), - &H5F_xfer_dflt, heap->chunk) < 0) { + H5P_DEFAULT, heap->chunk) < 0) { HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file"); } } else { #ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ + H5FD_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ #endif /* HAVE_PARALLEL */ if (H5F_block_write(f, addr, (hsize_t)H5HL_SIZEOF_HDR(f), - &H5F_xfer_dflt, heap->chunk)<0) { + H5P_DEFAULT, heap->chunk)<0) { HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file"); } #ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ + H5FD_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 writes */ #endif /* HAVE_PARALLEL */ if (H5F_block_write(f, heap->addr, (hsize_t)(heap->disk_alloc), - &H5F_xfer_dflt, + H5P_DEFAULT, heap->chunk + H5HL_SIZEOF_HDR(f)) < 0) { HRETURN_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap data to file"); @@ -878,6 +878,44 @@ H5I_dec_ref(hid_t id) /*------------------------------------------------------------------------- + * Function: H5I_inc_ref + * + * Purpose: Increment the reference count for an object. + * + * Return: Success: The new reference count. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Thursday, July 29, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +intn +H5I_inc_ref(hid_t id) +{ + H5I_type_t grp = H5I_GROUP(id); /*group the object is in*/ + H5I_id_group_t *grp_ptr = NULL; /*ptr to the group */ + H5I_id_info_t *id_ptr = NULL; /*ptr to the ID */ + + FUNC_ENTER(H5I_inc_ref, FAIL); + + /* Check arguments */ + if (id<0) HRETURN(FAIL); + grp_ptr = H5I_id_group_list_g[grp]; + if (!grp_ptr || grp_ptr->count<=0) HRETURN(FAIL); + + /* General lookup of the ID */ + if (NULL==(id_ptr=H5I_find_id(id))) HRETURN(FAIL); + id_ptr->count++; + + FUNC_LEAVE(id_ptr->count); +} + + +/*------------------------------------------------------------------------- * Function: H5I_search * * Purpose: Apply function FUNC to each member of group GRP and return a diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index 0ac2a8d..a142a9e 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -37,6 +37,7 @@ #define H5I_TEMPBUFID_HASHSIZE 64 #define H5I_RAGGED_HASHSIZE 64 #define H5I_REFID_HASHSIZE 64 +#define H5I_VFL_HASHSIZE 64 /* * Function for freeing objects. This function will be called with an object @@ -82,5 +83,6 @@ __DLL__ H5I_type_t H5I_get_type(hid_t id); __DLL__ void *H5I_remove(hid_t id); __DLL__ void *H5I_search(H5I_type_t grp, H5I_search_func_t func, const void *key); +__DLL__ intn H5I_inc_ref(hid_t id); __DLL__ intn H5I_dec_ref(hid_t id); #endif diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index 2ae5640..8eebf53 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -49,6 +49,7 @@ typedef enum { H5I_TEMPBUF, /*group ID for Temporary buffer objects */ H5I_RAGGED, /*group ID for Ragged array objects */ H5I_REFERENCE, /*group ID for Reference objects */ + H5I_VFL, /*group ID for virtual file layer */ H5I_NGROUPS /*number of valid groups, MUST BE LAST! */ } H5I_type_t; @@ -23,6 +23,7 @@ #include <H5private.h> #include <H5Eprivate.h> #include <H5Fprivate.h> +#include <H5FDprivate.h> #include <H5MFprivate.h> #define PABLO_MASK H5MF_mask @@ -35,147 +36,53 @@ static intn interface_initialize_g = 0; /*------------------------------------------------------------------------- * Function: H5MF_alloc * - * Purpose: Allocate at least SIZE bytes of file memory and return - * the address where that contiguous chunk of file memory - * exists. The allocation operation should be either H5MF_META or - * H5MF_RAW depending on the purpose for which the storage is - * being requested. + * Purpose: Allocate SIZE bytes of file memory and return the relative + * address where that contiguous chunk of file memory exists. + * The TYPE argument describes the purpose for which the storage + * is being requested. * - * Return: Success: Non-negative. The file address of new chunk is - * returned through the ADDR argument. + * Return: Success: The file address of new chunk. * - * Failure: Negative + * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * matzke@llnl.gov * Jul 11 1997 * * Modifications: - * + * Robb Matzke, 1999-08-04 + * Modified to work with the virtual file layer. *------------------------------------------------------------------------- */ -herr_t -H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr_p/*out*/) +haddr_t +H5MF_alloc(H5F_t *f, H5FD_mem_t type, hsize_t size) { - haddr_t tmp_addr; - intn i, found, status=-1; - hsize_t n; - H5MF_free_t blk; - hsize_t thresh = f->shared->access_parms->threshold; - hsize_t align = f->shared->access_parms->alignment; - - FUNC_ENTER(H5MF_alloc, FAIL); + haddr_t ret_value=HADDR_UNDEF; + + FUNC_ENTER(H5MF_alloc, HADDR_UNDEF); /* check arguments */ assert(f); - assert(H5MF_META == op || H5MF_RAW == op); assert(size > 0); - assert(addr_p); /* Fail if we don't have write access */ if (0==(f->intent & H5F_ACC_RDWR)) { - HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, "file is read-only"); + HRETURN_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "file is read-only"); } - /* - * Try to satisfy the request from the free list. We prefer exact matches - * to partial matches, so if we find an exact match then we break out of - * the loop immediately, otherwise we keep looking for an exact match. - */ - for (i=0, found=-1; i<f->shared->fl_nfree; i++) { - if ((status=H5F_low_alloc(f->shared->lf, op, align, thresh, size, - f->shared->fl_free+i, addr_p/*out*/))>0) { - /* Exact match found */ - found = i; - break; - } else if (0==status) { - /* Partial match */ - found = i; - } + /* Allocate space from the virtual file layer */ + if (HADDR_UNDEF==(ret_value=H5FD_alloc(f->shared->lf, type, size))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "file allocation failed"); } - if (found>=0 && - (status=H5F_low_alloc (f->shared->lf, op, align, thresh, size, - f->shared->fl_free+found, addr_p/*out*/))>0) { - /* - * We found an exact match. Remove that block from the free list and - * use it to satisfy the request. - */ - --(f->shared->fl_nfree); - HDmemmove (f->shared->fl_free+found, f->shared->fl_free+found+1, - (f->shared->fl_nfree-found) * sizeof(H5MF_free_t)); - - } else if (found>=0 && status==0) { - /* - * We found a free block which is larger than the requested size. - * Return the unused parts of the free block to the free list. - */ - blk = f->shared->fl_free[found]; - --f->shared->fl_nfree; - HDmemmove (f->shared->fl_free+found, f->shared->fl_free+found+1, - (f->shared->fl_nfree-found) * sizeof(H5MF_free_t)); - if (H5F_addr_gt (*addr_p, blk.addr)) { - /* Free the first part of the free block */ - n = *addr_p - blk.addr; - H5MF_xfree (f, blk.addr, n); - blk.addr = *addr_p; - blk.size -= n; - } - - if (blk.size > size) { - /* Free the second part of the free block */ - blk.addr += size; - blk.size -= size; - H5MF_xfree (f, blk.addr, blk.size); - } - - } else { - /* - * No suitable free block was found. Allocate space from the end of - * the file. We don't know about alignment at this point, so we - * allocate enough space to align the data also. - */ - if (size>=thresh) { - blk.size = size + align - 1; - } else { - blk.size = size; - } - if (H5F_low_extend(f->shared->lf, f->shared->access_parms, op, - blk.size, &(blk.addr)/*out*/) < 0) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "low level mem management failed"); - } - - /* Convert from absolute to relative */ - blk.addr -= f->shared->base_addr; - - /* Did we extend the size of the hdf5 data? */ - tmp_addr = blk.addr + blk.size; - if (H5F_addr_gt(tmp_addr, f->shared->hdf5_eof)) { - f->shared->hdf5_eof = tmp_addr; - } + /* Convert absolute file address to relative file address */ + assert(ret_value>=f->shared->base_addr); + ret_value -= f->shared->base_addr; - if ((status=H5F_low_alloc (f->shared->lf, op, align, thresh, size, - &blk, addr_p/*out*/))>0) { - /* Exact match */ - } else if (0==status) { - /* Partial match */ - if (H5F_addr_gt (*addr_p, blk.addr)) { - n = *addr_p - blk.addr; - H5MF_xfree (f, blk.addr, n); - blk.addr = *addr_p; - blk.size -= n; - } - if (blk.size > size) { - blk.addr += size; - blk.size -= size; - H5MF_xfree (f, blk.addr, blk.size); - } - } - } - - FUNC_LEAVE(SUCCEED); + FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- * Function: H5MF_xfree @@ -183,8 +90,6 @@ H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr_p/*out*/) * Purpose: Frees part of a file, making that part of the file * available for reuse. * - * Note: This version of the function doesn't do anything. - * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke @@ -194,13 +99,14 @@ H5MF_alloc(H5F_t *f, intn op, hsize_t size, haddr_t *addr_p/*out*/) * Modifications: * Robb Matzke, 1999-07-28 * The ADDR argument is passed by value + * + * Robb Matzke, 1999-08-03 + * Modified to use the virtual file layer. *------------------------------------------------------------------------- */ herr_t -H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size) +H5MF_xfree(H5F_t *f, H5FD_mem_t type, haddr_t addr, hsize_t size) { - int i; - FUNC_ENTER(H5MF_xfree, FAIL); /* check arguments */ @@ -210,31 +116,20 @@ H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size) } assert(addr!=0); - /* - * Insert this free block into the free list without attempting to - * combine it with other free blocks. If the list is overfull then - * remove the smallest free block. - */ - if (f->shared->fl_nfree>=H5MF_NFREE) { - for (i=0; i<H5MF_NFREE; i++) { - if (f->shared->fl_free[i].size<size) { + /* Convert relative address to absolute address */ + addr += f->shared->base_addr; + + /* Allow virtual file layer to free block */ + if (H5FD_free(f->shared->lf, type, addr, size)<0) { #ifdef H5MF_DEBUG - if (H5DEBUG(MF)) { - fprintf(H5DEBUG(MF), - "H5MF_free: lost %lu bytes of file storage\n", - (unsigned long) f->shared->fl_free[i].size); - } -#endif - f->shared->fl_free[i].addr = addr; - f->shared->fl_free[i].size = size; - break; - } + if (H5DEBUG(MF)) { + fprintf(H5DEBUG(MF), + "H5MF_free: lost %lu bytes of file storage\n", + (unsigned long)size); } - } else { - i = f->shared->fl_nfree++; - f->shared->fl_free[i].addr = addr; - f->shared->fl_free[i].size = size; +#endif } + FUNC_LEAVE(SUCCEED); } @@ -243,12 +138,12 @@ H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size) * Function: H5MF_realloc * * Purpose: Changes the size of an allocated chunk, possibly moving it to - * a new address. The chunk to change is at address ORIG_ADDR - * and is exactly ORIG_SIZE bytes (if these are zero and undef - * then this function acts like H5MF_alloc). The new size will - * be NEW_SIZE and its address is returned though NEW_ADDR_P (if + * a new address. The chunk to change is at address OLD_ADDR + * and is exactly OLD_SIZE bytes (if these are H5F_ADDR_UNDEF + * and zero then this function acts like H5MF_alloc). The new + * size will be NEW_SIZE and its address is the return value (if * NEW_SIZE is zero then this function acts like H5MF_free and - * an undefined address is returned for NEW_ADDR_P). + * an undefined address is returned). * * If the new size is less than the old size then the new * address will be the same as the old address (except for the @@ -258,7 +153,9 @@ H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size) * new address will be returned. However, under certain * circumstances the library may return the same address. * - * Return: Non-negative on success/Negative on failure + * Return: Success: The relative file address of the new block. + * + * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Thursday, April 16, 1998 @@ -267,59 +164,33 @@ H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size) * Robb Matzke, 1999-07-28 * The ORIG_ADDR is passed by value. The name of NEW_ADDR has * been changed to NEW_ADDR_P + * + * Robb Matzke, 1999-08-04 + * Modified to work with the virtual file layer. *------------------------------------------------------------------------- */ -herr_t -H5MF_realloc (H5F_t *f, intn op, hsize_t orig_size, haddr_t orig_addr, - hsize_t new_size, haddr_t *new_addr_p/*out*/) +haddr_t +H5MF_realloc(H5F_t *f, H5FD_mem_t type, haddr_t old_addr, hsize_t old_size, + hsize_t new_size) { - FUNC_ENTER (H5MF_realloc, FAIL); + haddr_t ret_value=HADDR_UNDEF; + + FUNC_ENTER (H5MF_realloc, HADDR_UNDEF); - if (0==orig_size) { - /* Degenerate to H5MF_alloc() */ - assert (!H5F_addr_defined (orig_addr)); - if (new_size>0) { - if (H5MF_alloc (f, op, new_size, new_addr_p/*out*/)<0) { - HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, - "unable to allocate new file memory"); - } - } else { - *new_addr_p = H5F_ADDR_UNDEF; - } - - } else if (0==new_size) { - /* Degenerate to H5MF_free() */ - assert (H5F_addr_defined (orig_addr)); - if (H5MF_xfree (f, orig_addr, orig_size)<0) { - HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, - "unable to free old file memory"); - } - *new_addr_p = H5F_ADDR_UNDEF; - - } else if (new_size > orig_size) { - /* Size is getting larger */ - if (H5MF_alloc (f, op, new_size, new_addr_p/*out*/)<0) { - HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, - "unable to allocate new file memory"); - } - if (H5MF_xfree (f, orig_addr, orig_size)<0) { - HRETURN_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, - "unable to free old file memory"); - } + /* Convert old relative address to absolute address */ + old_addr += f->shared->base_addr; - } else { - /* New size is not larger */ -#ifdef H5MF_DEBUG - if (H5DEBUG(MF) && new_size<orig_size) { - HDfprintf (H5DEBUG(MF), "H5MF: realloc lost %Hd bytes\n", - orig_size-new_size); - } -#endif - *new_addr_p = orig_addr; + /* Reallocate memory from the virtual file layer */ + ret_value = H5FD_realloc(f->shared->lf, type, old_addr, old_size, + new_size); + if (HADDR_UNDEF==ret_value) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate new file memory"); } - FUNC_LEAVE (SUCCEED); -} + /* Convert return value to relative address */ + assert(ret_value>=f->shared->base_addr); + ret_value -= f->shared->base_addr; - - + FUNC_LEAVE(ret_value); +} diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 1030dcd..4040b88 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -17,8 +17,6 @@ #ifndef _H5MFprivate_H #define _H5MFprivate_H -#include <H5MFpublic.h> - /* Private headers needed by this file */ #include <H5private.h> #include <H5Fprivate.h> @@ -31,16 +29,13 @@ # undef H5MF_DEBUG #endif -#define H5MF_META 0 /*request storage for meta data */ -#define H5MF_RAW 1 /*request storage for raw data */ - /* * Library prototypes... */ -__DLL__ herr_t H5MF_alloc(H5F_t *f, intn, hsize_t size, haddr_t *addr/*out*/); -__DLL__ herr_t H5MF_xfree(H5F_t *f, haddr_t addr, hsize_t size); -__DLL__ herr_t H5MF_realloc(H5F_t *f, intn op, hsize_t orig_size, - haddr_t orig_addr, hsize_t new_size, - haddr_t *new_addr/*out*/); +__DLL__ haddr_t H5MF_alloc(H5F_t *f, H5FD_mem_t type, hsize_t size); +__DLL__ herr_t H5MF_xfree(H5F_t *f, H5FD_mem_t type, haddr_t addr, + hsize_t size); +__DLL__ haddr_t H5MF_realloc(H5F_t *f, H5FD_mem_t type, haddr_t old_addr, + hsize_t old_size, hsize_t new_size); #endif diff --git a/src/H5MFpublic.h b/src/H5MFpublic.h deleted file mode 100644 index cb3d51f..0000000 --- a/src/H5MFpublic.h +++ /dev/null @@ -1,31 +0,0 @@ -/*------------------------------------------------------------------------- - * Copyright (C) 1997 National Center for Supercomputing Applications. - * All rights reserved. - * - *------------------------------------------------------------------------- - * - * Created: H5MFproto.h - * Jul 11 1997 - * Robb Matzke <matzke@llnl.gov> - * - * Purpose: Public declarations for the H5MF (file memory - * management) package. - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -#ifndef _H5MFpublic_H -#define _H5MFpublic_H - -/* Public headers needed by this file */ -#include <H5public.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __cplusplus -} -#endif -#endif @@ -22,6 +22,11 @@ #include <H5MFprivate.h> #include <H5MMprivate.h> #include <H5Oprivate.h> +#include <H5Pprivate.h> + +/* The MPIO driver for H5FD_mpio_tas_allsame() */ +#include <H5FDmpio.h> + #define PABLO_MASK H5O_mask @@ -148,7 +153,7 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/) /* allocate disk space for header and first chunk */ size = H5O_SIZEOF_HDR(f) + size_hint; ent->file = f; - if (H5MF_alloc(f, H5MF_META, (hsize_t)size, &(ent->header)/*out*/) < 0) { + if (HADDR_UNDEF==(ent->header=H5MF_alloc(f, H5FD_MEM_OHDR, size))) { HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header header"); } @@ -352,7 +357,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, /* read fixed-lenth part of object header */ hdr_size = H5O_SIZEOF_HDR(f); - if (H5F_block_read(f, addr, (hsize_t)hdr_size, &H5F_xfer_dflt, buf) < 0) { + if (H5F_block_read(f, addr, hdr_size, H5P_DEFAULT, buf) < 0) { HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header"); } @@ -409,7 +414,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - if (H5F_block_read(f, chunk_addr, (hsize_t)chunk_size, &H5F_xfer_dflt, + if (H5F_block_read(f, chunk_addr, chunk_size, H5P_DEFAULT, oh->chunk[chunkno].image) < 0) { HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data"); @@ -458,7 +463,7 @@ H5O_load(H5F_t *f, haddr_t addr, const void UNUSED *_udata1, assert(p == oh->chunk[chunkno].image + chunk_size); /* decode next object header continuation message */ - for (chunk_addr=H5F_ADDR_UNDEF; + for (chunk_addr=HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; curmesg++) { if (H5O_CONT_ID == oh->mesg[curmesg].type->id) { @@ -552,10 +557,10 @@ H5O_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh) /* write the object header header */ #ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 will write */ + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/ #endif /* HAVE_PARALLEL */ if (H5F_block_write(f, addr, (hsize_t)H5O_SIZEOF_HDR(f), - &H5F_xfer_dflt, buf) < 0) { + H5P_DEFAULT, buf) < 0) { HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk"); } @@ -586,11 +591,12 @@ H5O_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh) assert(cont->chunkno < oh->nchunks); assert(!H5F_addr_defined(oh->chunk[cont->chunkno].addr)); cont->size = oh->chunk[cont->chunkno].size; - if (H5MF_alloc(f, H5MF_META, (hsize_t)(cont->size), - &(cont->addr)/*out*/) < 0) { + if (HADDR_UNDEF==(cont->addr=H5MF_alloc(f, + H5FD_MEM_OHDR, + cont->size))) { HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "unable to allocate space for object " - "header data"); + "unable to allocate space for " + "object header data"); } oh->chunk[cont->chunkno].addr = cont->addr; } @@ -627,11 +633,11 @@ H5O_flush(H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh) if (oh->chunk[i].dirty) { assert(H5F_addr_defined(oh->chunk[i].addr)); #ifdef HAVE_PARALLEL - H5F_mpio_tas_allsame( f->shared->lf, TRUE ); /* only p0 write */ + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 write*/ #endif /* HAVE_PARALLEL */ if (H5F_block_write(f, oh->chunk[i].addr, (hsize_t)(oh->chunk[i].size), - &H5F_xfer_dflt, oh->chunk[i].image) < 0) { + H5P_DEFAULT, oh->chunk[i].image) < 0) { HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk"); } @@ -1788,7 +1794,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) } chunkno = oh->nchunks++; oh->chunk[chunkno].dirty = TRUE; - oh->chunk[chunkno].addr = H5F_ADDR_UNDEF; + oh->chunk[chunkno].addr = HADDR_UNDEF; oh->chunk[chunkno].size = size; if (NULL==(oh->chunk[chunkno].image = p = H5MM_calloc(size))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, @@ -1871,7 +1877,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - cont->addr = H5F_ADDR_UNDEF; + cont->addr = HADDR_UNDEF; cont->size = 0; cont->chunkno = chunkno; oh->mesg[found_null].native = cont; diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 52bc29f..b5a99d6 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -416,7 +416,7 @@ H5O_attr_debug(H5F_t *f, const void *_mesg, FILE * stream, intn indent, (unsigned int)mesg->ent_opened); fprintf(stream, "%*sSymbol table entry...\n", indent, ""); H5G_ent_debug(f, &(mesg->ent), stream, indent+3, MAX(0, fwidth-3), - H5F_ADDR_UNDEF); + HADDR_UNDEF); fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, "Data type size:", diff --git a/src/H5Odtype.c b/src/H5Odtype.c index b98e24d..214782c 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -228,7 +228,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - dt->u.compnd.memb[i].type->ent.header = H5F_ADDR_UNDEF; + dt->u.compnd.memb[i].type->ent.header = HADDR_UNDEF; if (H5O_dtype_decode_helper(f, pp, dt->u.compnd.memb[i].type)<0) { for (j=0; j<=i; j++) H5MM_xfree(dt->u.compnd.memb[j].name); H5MM_xfree(dt->u.compnd.memb); @@ -261,7 +261,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - dt->parent->ent.header = H5F_ADDR_UNDEF; + dt->parent->ent.header = HADDR_UNDEF; if (H5O_dtype_decode_helper(f, pp, dt->parent)<0) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode parent data type"); @@ -297,7 +297,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt) case H5T_VLEN: /* Variable length datatypes... */ /* Decode base type of VL information */ - dt->parent->ent.header = H5F_ADDR_UNDEF; + dt->parent->ent.header = HADDR_UNDEF; if (H5O_dtype_decode_helper(f, pp, dt->parent)<0) { HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "unable to decode VL parent type"); } @@ -685,7 +685,7 @@ H5O_dtype_decode(H5F_t *f, const uint8_t *p, HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); } - dt->ent.header = H5F_ADDR_UNDEF; + dt->ent.header = HADDR_UNDEF; if (H5O_dtype_decode_helper(f, &p, dt) < 0) { H5MM_xfree(dt); diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 063e655..c14203b 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -337,7 +337,7 @@ H5O_efl_reset(void *_mesg) for (i=0; i<mesg->nused; i++) { mesg->slot[i].name = H5MM_xfree (mesg->slot[i].name); } - mesg->heap_addr = H5F_ADDR_UNDEF; + mesg->heap_addr = HADDR_UNDEF; mesg->nused = mesg->nalloc = 0; mesg->slot = H5MM_xfree(mesg->slot); diff --git a/src/H5Oshared.c b/src/H5Oshared.c index da526dc..9c70385 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -235,7 +235,7 @@ H5O_shared_debug (H5F_t UNUSED *f, const void *_mesg, "Sharing method", "Obj Hdr"); H5G_ent_debug (f, &(mesg->u.ent), stream, indent, fwidth, - H5F_ADDR_UNDEF); + HADDR_UNDEF); } FUNC_LEAVE (SUCCEED); @@ -18,13 +18,17 @@ static char RcsId[] = "@(#)$Revision$"; /* Private header files */ #include <H5private.h> /* Generic Functions */ -#include <H5Iprivate.h> /* IDs */ +#include <H5Iprivate.h> /* IDs */ #include <H5Bprivate.h> /* B-tree subclass names */ #include <H5Dprivate.h> /* Datasets */ #include <H5Eprivate.h> /* Error handling */ +#include <H5FDprivate.h> /* File drivers */ #include <H5MMprivate.h> /* Memory management */ #include <H5Pprivate.h> /* Property lists */ +/* Default file driver - see H5Pget_driver() */ +#include <H5FDsec2.h> /* Posix unbuffered I/O file driver */ + #define PABLO_MASK H5P_mask /* Is the interface initialized? */ @@ -181,7 +185,7 @@ H5Pcreate(H5P_class_t type) HDmemcpy(plist, &H5D_create_dflt, sizeof(H5D_create_t)); break; - case H5P_DATASET_XFER: + case H5P_DATA_XFER: if (NULL==(plist = H5MM_malloc(sizeof(H5F_xfer_t)))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); @@ -249,19 +253,24 @@ H5P_create(H5P_class_t type, void *plist) FUNC_LEAVE(ret_value); } -/*-------------------------------------------------------------------------- - NAME - H5Pclose - PURPOSE - Release access to a property list object. - USAGE - herr_t H5Pclose(oid) - hid_t oid; IN: property list object to release access to - RETURNS - Non-negative on success/Negative on failure - DESCRIPTION - This function releases access to a property list object ---------------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function: H5Pclose + * + * Purpose: Release access to a property list object, PLIST_ID. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Unknown + * + * Modifications: + * Robb Matzke, 1999-08-03 + * Attempting to close H5P_DEFAULT is no longer an error, but + * rather a no-op. + *------------------------------------------------------------------------- + */ herr_t H5Pclose(hid_t plist_id) { @@ -272,10 +281,9 @@ H5Pclose(hid_t plist_id) H5TRACE1("e","i",plist_id); /* Check arguments */ - if (plist_id==H5P_DEFAULT) - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "unable to close predefined object"); - if ((type=H5P_get_class (plist_id))<0 || NULL==(plist=H5I_object (plist_id))) { + if (plist_id==H5P_DEFAULT) HRETURN(SUCCEED); + if ((type=H5P_get_class (plist_id))<0 || + NULL==(plist=H5I_object (plist_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list"); } @@ -303,13 +311,15 @@ H5Pclose(hid_t plist_id) * Wednesday, February 18, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-03 + * Modified to work with the virtual file layer. *------------------------------------------------------------------------- */ herr_t H5P_close(H5P_class_t type, void *plist) { H5F_access_t *fa_list = (H5F_access_t*)plist; + H5F_xfer_t *dx_list = (H5F_xfer_t*)plist; H5D_create_t *dc_list = (H5D_create_t*)plist; FUNC_ENTER (H5P_close, FAIL); @@ -320,33 +330,11 @@ H5P_close(H5P_class_t type, void *plist) /* Some property lists may need to do special things */ switch (type) { case H5P_FILE_ACCESS: - switch (fa_list->driver) { - case H5F_LOW_ERROR: - case H5F_LOW_SEC2: - case H5F_LOW_STDIO: - case H5F_LOW_CORE: - /* Nothing to do */ - break; - - case H5F_LOW_MPIO: -#ifdef LATER - /* Need to free the COMM and INFO objects too. */ -#endif - break; - - case H5F_LOW_SPLIT: - /* Free member info */ - fa_list->driver = H5F_LOW_ERROR; /*prevent cycles*/ - H5P_close (H5P_FILE_ACCESS, fa_list->u.split.meta_access); - H5P_close (H5P_FILE_ACCESS, fa_list->u.split.raw_access); - H5MM_xfree (fa_list->u.split.meta_ext); - H5MM_xfree (fa_list->u.split.raw_ext); - break; - - case H5F_LOW_FAMILY: - /* Free member info */ - H5P_close (H5P_FILE_ACCESS, fa_list->u.fam.memb_access); - break; + if (fa_list->driver_id>=0) { + H5FD_fapl_free(fa_list->driver_id, fa_list->driver_info); + H5I_dec_ref(fa_list->driver_id); + fa_list->driver_info = NULL; + fa_list->driver_id = -1; } break; @@ -360,8 +348,13 @@ H5P_close(H5P_class_t type, void *plist) H5O_reset(H5O_PLINE, &(dc_list->pline)); break; - case H5P_DATASET_XFER: - /*nothing to do*/ + case H5P_DATA_XFER: + if (dx_list->driver_id>=0) { + H5FD_dxpl_free(dx_list->driver_id, dx_list->driver_info); + H5I_dec_ref(dx_list->driver_id); + dx_list->driver_info = NULL; + dx_list->driver_id = -1; + } break; case H5P_MOUNT: @@ -1309,539 +1302,177 @@ H5Pget_external(hid_t plist_id, int idx, size_t name_size, char *name/*out*/, /*------------------------------------------------------------------------- - * Function: H5Pget_driver + * Function: H5Pset_driver * - * Purpose: Return the ID of the low-level file driver. PLIST_ID should - * be a file access property list. + * Purpose: Set the file driver (DRIVER_ID) for a file access or data + * transfer property list (PLIST_ID) and supply an optional + * struct containing the driver-specific properites + * (DRIVER_INFO). The driver properties will be copied into the + * property list and the reference count on the driver will be + * incremented, allowing the caller to close the driver ID but + * still use the property list. * - * Return: Success: A low-level driver ID + * Return: Success: Non-negative * - * Failure: H5F_LOW_ERROR (a negative value) - * - * Programmer: Robb Matzke - * Thursday, February 26, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5F_driver_t -H5Pget_driver(hid_t plist_id) -{ - H5F_access_t *plist = NULL; - - FUNC_ENTER (H5Pget_driver, H5F_LOW_ERROR); - H5TRACE1("Fd","i",plist_id); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, H5F_LOW_ERROR, - "not a file access property list"); - } - - FUNC_LEAVE (plist->driver); -} - - -/*------------------------------------------------------------------------- - * Function: H5Pset_stdio - * - * Purpose: Set the low level file driver to use the functions declared - * in the stdio.h file: fopen(), fseek() or fseek64(), fread(), - * fwrite(), and fclose(). - * - * Return: Non-negative on success/Negative on failure + * Failure: Negative * * Programmer: Robb Matzke - * Thursday, February 19, 1998 + * Tuesday, August 3, 1999 * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5Pset_stdio(hid_t plist_id) +H5Pset_driver(hid_t plist_id, hid_t driver_id, const void *driver_info) { - H5F_access_t *plist = NULL; + H5F_access_t *fapl=NULL; + H5F_xfer_t *dxpl=NULL; - FUNC_ENTER (H5Pset_stdio, FAIL); - H5TRACE1("e","i",plist_id); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } + FUNC_ENTER(H5Pset_driver, FAIL); + H5TRACE3("e","iix",plist_id,driver_id,driver_info); - /* Set driver */ - plist->driver = H5F_LOW_STDIO; - - FUNC_LEAVE (SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5Pget_stdio - * - * Purpose: If the file access property list is set to the stdio driver - * then this function returns zero; otherwise it returns a - * negative value. In the future, additional arguments may be - * added to this function to match those added to H5Pset_stdio(). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, February 26, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_stdio(hid_t plist_id) -{ - H5F_access_t *plist = NULL; - - FUNC_ENTER (H5Pget_stdio, FAIL); - H5TRACE1("e","i",plist_id); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (H5F_LOW_STDIO != plist->driver) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "the stdio driver is not set"); + if (H5I_VFL!=H5I_get_type(driver_id) || + NULL==H5I_object(driver_id)) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver ID"); } - FUNC_LEAVE (SUCCEED); -} + if (H5P_FILE_ACCESS==H5P_get_class(plist_id)) { + if (NULL==(fapl=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + + /* Remove old driver */ + assert(fapl->driver_id>=0); + H5FD_fapl_free(fapl->driver_id, fapl->driver_info); + + /* Add new driver */ + H5I_inc_ref(driver_id); + fapl->driver_id = driver_id; + fapl->driver_info = H5FD_fapl_copy(driver_id, driver_info); + + } else if (H5P_DATA_XFER==H5P_get_class(plist_id)) { + if (NULL==(dxpl=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } - -/*------------------------------------------------------------------------- - * Function: H5Pset_sec2 - * - * Purpose: Set the low-level file driver to use the functions declared - * in the unistd.h file: open(), lseek() or lseek64(), read(), - * write(), and close(). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, February 19, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_sec2(hid_t plist_id) -{ - H5F_access_t *plist = NULL; - - FUNC_ENTER (H5Pset_sec2, FAIL); - H5TRACE1("e","i",plist_id); + /* Remove old driver */ + assert(dxpl->driver_id>=0); + H5FD_dxpl_free(dxpl->driver_id, dxpl->driver_info); - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { + /* Add new driver */ + H5I_inc_ref(driver_id); + dxpl->driver_id = driver_id; + dxpl->driver_info = H5FD_fapl_copy(driver_id, driver_info); + + } else { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); + "not a file access or data transfer property list"); } - /* Set driver */ - plist->driver = H5F_LOW_SEC2; - - FUNC_LEAVE (SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5Pget_sec2 - * - * Purpose: If the file access property list is set to the sec2 driver - * then this function returns zero; otherwise it returns a - * negative value. In the future, additional arguments may be - * added to this function to match those added to H5Pset_sec2(). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, February 26, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_sec2(hid_t plist_id) -{ - H5F_access_t *plist = NULL; - - FUNC_ENTER (H5Pget_sec2, FAIL); - H5TRACE1("e","i",plist_id); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (H5F_LOW_SEC2 != plist->driver) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "the sec2 driver is not set"); - } - - FUNC_LEAVE (SUCCEED); + FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5Pset_core - * - * Purpose: Set the low-level file driver to use malloc() and free(). - * This driver is restricted to temporary files which are not - * larger than the amount of virtual memory available. The - * INCREMENT argument determines the file block size and memory - * will be allocated in multiples of INCREMENT bytes. A liberal - * INCREMENT results in fewer calls to realloc() and probably - * less memory fragmentation. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, February 19, 1998 - * - * Modifications: + * Function: H5Pget_driver * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_core(hid_t plist_id, size_t increment) -{ - H5F_access_t *plist = NULL; - - FUNC_ENTER (H5Pset_core, FAIL); - H5TRACE2("e","iz",plist_id,increment); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (increment<1) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "increment must be positive"); - } - - /* Set driver */ - plist->driver = H5F_LOW_CORE; - plist->u.core.increment = increment; - - FUNC_LEAVE (SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5Pget_core + * Purpose: Return the ID of the low-level file driver. PLIST_ID should + * be a file access property list or data transfer propert list. * - * Purpose: If the file access property list is set to the core driver - * then this function returns zero; otherwise it returns a - * negative value. On success, the block size is returned - * through the INCREMENT argument if it isn't the null pointer. - * In the future, additional arguments may be added to this - * function to match those added to H5Pset_core(). + * Return: Success: A low-level driver ID which is the same ID + * used when the driver was set for the property + * list. The driver ID is only valid as long as + * the file driver remains registered. * - * Return: Non-negative on success/Negative on failure + * Failure: Negative * * Programmer: Robb Matzke * Thursday, February 26, 1998 * * Modifications: + * Robb Matzke, 1999-08-03 + * Rewritten to use the virtual file layer. * + * Robb Matzke, 1999-08-05 + * If the driver ID is -2 then substitute the current value of + * H5FD_SEC2. *------------------------------------------------------------------------- */ -herr_t -H5Pget_core(hid_t plist_id, size_t *increment/*out*/) +hid_t +H5Pget_driver(hid_t plist_id) { - H5F_access_t *plist = NULL; - - FUNC_ENTER (H5Pget_core, FAIL); - H5TRACE2("e","ix",plist_id,increment); + H5F_access_t *fapl=NULL; + H5F_xfer_t *dxpl=NULL; + hid_t ret_value=-1; - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (H5F_LOW_CORE != plist->driver) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "the core driver is not set"); - } - - /* Return values */ - if (increment) { - *increment = plist->u.core.increment; - } - - FUNC_LEAVE (SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5Pset_split - * - * Purpose: Set the low-level driver to split meta data from raw data, - * storing meta data in one file and raw data in another file. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, February 19, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_split(hid_t plist_id, const char *meta_ext, hid_t meta_plist_id, - const char *raw_ext, hid_t raw_plist_id) -{ - H5F_access_t *plist = NULL; - H5F_access_t *meta_plist = &H5F_access_dflt; - H5F_access_t *raw_plist = &H5F_access_dflt; - - FUNC_ENTER (H5Pset_split, FAIL); - H5TRACE5("e","isisi",plist_id,meta_ext,meta_plist_id,raw_ext,raw_plist_id); + FUNC_ENTER (H5Pget_driver, FAIL); + H5TRACE1("i","i",plist_id); - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (H5P_DEFAULT!=meta_plist_id && - (H5P_FILE_ACCESS != H5P_get_class(meta_plist_id) || - NULL == (meta_plist = H5I_object(meta_plist_id)))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (H5P_DEFAULT!=raw_plist_id && - (H5P_FILE_ACCESS != H5P_get_class(raw_plist_id) || - NULL == (raw_plist = H5I_object(raw_plist_id)))) { + if (H5P_FILE_ACCESS==H5P_get_class(plist_id) && + (fapl=H5I_object(plist_id))) { + ret_value = fapl->driver_id; + + } else if (H5P_DATA_XFER==H5P_get_class(plist_id) && + (dxpl=H5I_object(plist_id))) { + ret_value = dxpl->driver_id; + + } else { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); + "not a file access or data transfer property list"); } - /* Set driver */ - plist->driver = H5F_LOW_SPLIT; - plist->u.split.meta_access = H5P_copy (H5P_FILE_ACCESS, meta_plist); - plist->u.split.raw_access = H5P_copy (H5P_FILE_ACCESS, raw_plist); - plist->u.split.meta_ext = H5MM_xstrdup (meta_ext); - plist->u.split.raw_ext = H5MM_xstrdup (raw_ext); - - FUNC_LEAVE (SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5Pget_split - * - * Purpose: If the file access property list is set to the sec2 driver - * then this function returns zero; otherwise it returns a - * negative value. On success, at most META_EXT_SIZE characters - * are copied to the META_EXT buffer if non-null and at most - * RAW_EXT_SIZE characters are copied to the RAW_EXT buffer if - * non-null. If the actual extension is larger than the number - * of characters requested then the buffer will not be null - * terminated (that is, behavior like strncpy()). In addition, - * if META_PROPERTIES and/or RAW_PROPERTIES are non-null then - * the file access property list of the meta file and/or raw - * file is copied and its OID returned through these arguments. - * In the future, additional arguments may be added to this - * function to match those added to H5Pset_sec2(). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, February 26, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_split(hid_t plist_id, size_t meta_ext_size, char *meta_ext/*out*/, - hid_t *meta_properties/*out*/, size_t raw_ext_size, - char *raw_ext/*out*/, hid_t *raw_properties/*out*/) -{ - H5F_access_t *plist = NULL; - - FUNC_ENTER (H5Pget_split, FAIL); - H5TRACE7("e","izxxzxx",plist_id,meta_ext_size,meta_ext,meta_properties, - raw_ext_size,raw_ext,raw_properties); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (H5F_LOW_SPLIT != plist->driver) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "the split driver is not set"); - } - - /* Reset output args for error handling */ - if (meta_ext && meta_ext_size>0) *meta_ext = '\0'; - if (raw_ext && raw_ext_size>0) *raw_ext = '\0'; - if (meta_properties) *meta_properties = FAIL; - if (raw_properties) *raw_properties = FAIL; - - /* Output arguments */ - if (meta_ext && meta_ext_size>0) { - if (plist->u.split.meta_ext) { - HDstrncpy (meta_ext, plist->u.split.meta_ext, meta_ext_size); - } else { - HDstrncpy (meta_ext, ".meta", meta_ext_size); - } - } - if (raw_ext && raw_ext_size>0) { - if (plist->u.split.raw_ext) { - HDstrncpy (raw_ext, plist->u.split.raw_ext, raw_ext_size); - } else { - HDstrncpy (raw_ext, ".raw", raw_ext_size); - } - } - if (meta_properties) { - assert (plist->u.split.meta_access); - *meta_properties = H5P_create (H5P_FILE_ACCESS, - H5P_copy (H5P_FILE_ACCESS, - plist->u.split.meta_access)); - } - if (raw_properties) { - assert (plist->u.split.raw_access); - *raw_properties = H5P_create (H5P_FILE_ACCESS, - H5P_copy (H5P_FILE_ACCESS, - plist->u.split.raw_access)); - } - - FUNC_LEAVE (SUCCEED); + if (-2==ret_value) ret_value = H5FD_SEC2; + FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5Pset_family + * Function: H5Pget_driver_info * - * Purpose: Sets the low-level driver to stripe the hdf5 address space - * across a family of files. The MEMB_SIZE argument indicates - * the size in bytes of each family member and is only - * meaningful when creating new files or opening families that - * have only one member. + * Purpose: Returns a pointer directly to the file driver-specific + * information of a file access or data transfer property list. * - * Return: Non-negative on success/Negative on failure + * Return: Success: Ptr to *uncopied* driver specific data + * structure if any. * - * Programmer: Robb Matzke - * Thursday, February 19, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_family(hid_t plist_id, hsize_t memb_size, hid_t memb_plist_id) -{ - - H5F_access_t *plist = NULL; - H5F_access_t *memb_plist = &H5F_access_dflt; - - FUNC_ENTER (H5Pset_family, FAIL); - H5TRACE3("e","ihi",plist_id,memb_size,memb_plist_id); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (memb_size && memb_size<1024) { - HRETURN_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL, - "family member size is too small"); - } - if (H5P_DEFAULT!=memb_plist_id && - (H5P_FILE_ACCESS != H5P_get_class(memb_plist_id) || - NULL == (plist = H5I_object(memb_plist_id)))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - - /* Set driver */ - plist->driver = H5F_LOW_FAMILY; - plist->u.fam.memb_size = memb_size; - plist->u.fam.memb_access = H5P_copy (H5P_FILE_ACCESS, memb_plist); - - FUNC_LEAVE (SUCCEED); -} - - -/*------------------------------------------------------------------------- - * Function: H5Pget_family - * - * Purpose: If the file access property list is set to the family driver - * then this function returns zero; otherwise it returns a - * negative value. On success, if MEMB_PLIST_ID is a non-null - * pointer it will be initialized with the id of an open - * property list: the file access property list for the family - * members. In the future, additional arguments may be added to - * this function to match those added to H5Pset_family(). - * - * Return: Non-negative on success/Negative on failure + * Failure: NULL. Null is also returned if the driver has + * not registered any driver-specific properties + * although no error is pushed on the stack in + * this case. * * Programmer: Robb Matzke - * Thursday, February 26, 1998 + * Wednesday, August 4, 1999 * * Modifications: * *------------------------------------------------------------------------- */ -herr_t -H5Pget_family(hid_t plist_id, hsize_t *memb_size/*out*/, - hid_t *memb_plist_id/*out*/) +void * +H5Pget_driver_info(hid_t plist_id) { - H5F_access_t *plist = NULL; + H5F_access_t *fapl=NULL; + H5F_xfer_t *dxpl=NULL; + void *ret_value=NULL; - FUNC_ENTER (H5Pget_family, FAIL); - H5TRACE3("e","ixx",plist_id,memb_size,memb_plist_id); + FUNC_ENTER(H5Pget_driver_info, NULL); - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (H5F_LOW_FAMILY != plist->driver) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "the family driver is not set"); - } - - /* Output args */ - if (memb_size) { - *memb_size = plist->u.fam.memb_size; - } - if (memb_plist_id) { - assert (plist->u.fam.memb_access); - *memb_plist_id = H5P_create (H5P_FILE_ACCESS, - H5P_copy (H5P_FILE_ACCESS, - plist->u.fam.memb_access)); - } + if (H5P_FILE_ACCESS==H5P_get_class(plist_id) && + (fapl=H5I_object(plist_id))) { + ret_value = fapl->driver_info; - FUNC_LEAVE (SUCCEED); + } else if (H5P_DATA_XFER==H5P_get_class(plist_id) && + (dxpl=H5I_object(plist_id))) { + ret_value = dxpl->driver_info; + + } else { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, + "not a file access or data transfer property list"); + } + + FUNC_LEAVE(ret_value); } @@ -1986,7 +1617,7 @@ H5Pset_buffer(hid_t plist_id, size_t size, void *tconv, void *bkg) H5TRACE4("e","izxx",plist_id,size,tconv,bkg); /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + if (H5P_DATA_XFER != H5P_get_class (plist_id) || NULL == (plist = H5I_object (plist_id))) { HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); @@ -2030,7 +1661,7 @@ H5Pget_buffer(hid_t plist_id, void **tconv/*out*/, void **bkg/*out*/) H5TRACE3("z","ixx",plist_id,tconv,bkg); /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + if (H5P_DATA_XFER != H5P_get_class (plist_id) || NULL == (plist = H5I_object (plist_id))) { HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not a dataset transfer property list"); @@ -2076,7 +1707,7 @@ H5Pset_hyper_cache(hid_t plist_id, unsigned cache, unsigned limit) H5TRACE3("e","iIuIu",plist_id,cache,limit); /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + if (H5P_DATA_XFER != H5P_get_class (plist_id) || NULL == (plist = H5I_object (plist_id))) { HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); @@ -2087,7 +1718,7 @@ H5Pset_hyper_cache(hid_t plist_id, unsigned cache, unsigned limit) plist->block_limit = limit; FUNC_LEAVE (SUCCEED); -} /* end H5P_set_hyper_cache() */ +} /*------------------------------------------------------------------------- @@ -2114,7 +1745,7 @@ H5Pget_hyper_cache(hid_t plist_id, unsigned *cache/*out*/, H5TRACE3("e","ixx",plist_id,cache,limit); /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + if (H5P_DATA_XFER != H5P_get_class (plist_id) || NULL == (plist = H5I_object (plist_id))) { HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, "not a dataset transfer property list"); @@ -2125,7 +1756,7 @@ H5Pget_hyper_cache(hid_t plist_id, unsigned *cache/*out*/, if (limit) *limit = plist->block_limit; FUNC_LEAVE (SUCCEED); -} /* end H5Pget_hyper_cache() */ +} /*------------------------------------------------------------------------- @@ -2155,7 +1786,7 @@ H5Pset_preserve(hid_t plist_id, hbool_t status) H5TRACE2("e","ib",plist_id,status); /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + if (H5P_DATA_XFER != H5P_get_class (plist_id) || NULL == (plist = H5I_object (plist_id))) { HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); @@ -2193,7 +1824,7 @@ H5Pget_preserve(hid_t plist_id) H5TRACE1("Is","i",plist_id); /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + if (H5P_DATA_XFER != H5P_get_class (plist_id) || NULL == (plist = H5I_object (plist_id))) { HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); @@ -2249,7 +1880,7 @@ H5Pset_filter(hid_t plist_id, H5Z_filter_t filter, unsigned int flags, H5TRACE5("e","iZfIuz*[a3]Iu",plist_id,filter,flags,cd_nelmts,cd_values); /* Check arguments */ - if (H5P_DATASET_XFER==H5P_get_class(plist_id)) { + if (H5P_DATA_XFER==H5P_get_class(plist_id)) { HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, "transient pipelines are not supported yet"); } @@ -2313,7 +1944,7 @@ H5Pget_nfilters(hid_t plist_id) FUNC_ENTER(H5Pget_nfilters, FAIL); H5TRACE1("Is","i",plist_id); - if (H5P_DATASET_XFER==H5P_get_class(plist_id)) { + if (H5P_DATA_XFER==H5P_get_class(plist_id)) { HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, "transient pipelines are not supported yet"); } @@ -2365,7 +1996,7 @@ H5Pget_filter(hid_t plist_id, int idx, unsigned int *flags/*out*/, name); /* Check arguments */ - if (H5P_DATASET_XFER==H5P_get_class(plist_id)) { + if (H5P_DATA_XFER==H5P_get_class(plist_id)) { HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, "transient filters are not supported yet"); } @@ -2452,7 +2083,7 @@ H5Pset_deflate(hid_t plist_id, unsigned level) H5TRACE2("e","iIu",plist_id,level); /* Check arguments */ - if (H5P_DATASET_XFER==H5P_get_class(plist_id)) { + if (H5P_DATA_XFER==H5P_get_class(plist_id)) { HRETURN_ERROR(H5E_PLINE, H5E_UNSUPPORTED, FAIL, "transient filter pipelines are not supported yet"); } @@ -2504,7 +2135,7 @@ H5Pget_btree_ratios(hid_t plist_id, double *left/*out*/, double *middle/*out*/, H5TRACE4("e","ixxx",plist_id,left,middle,right); /* Check arguments */ - if (H5P_DATASET_XFER!=H5P_get_class(plist_id) || + if (H5P_DATA_XFER!=H5P_get_class(plist_id) || NULL==(plist=H5I_object(plist_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); @@ -2551,7 +2182,7 @@ H5Pset_btree_ratios(hid_t plist_id, double left, double middle, H5TRACE4("e","iddd",plist_id,left,middle,right); /* Check arguments */ - if (H5P_DATASET_XFER!=H5P_get_class(plist_id) || + if (H5P_DATA_XFER!=H5P_get_class(plist_id) || NULL==(plist=H5I_object(plist_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); @@ -2736,261 +2367,27 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) } -#ifdef HAVE_PARALLEL -/*------------------------------------------------------------------------- - * Function: H5Pset_mpi - * - * Signature: herr_t H5Pset_mpi(hid_t plist_id, MPI_Comm comm, MPI_Info info) - * - * Purpose: Store the access mode for MPIO call and the user supplied - * communicator and info in the access property list which can - * then be used to open file. This function is available only - * in the parallel HDF5 library and is not a collective - * function. - * - * Parameters: - * hid_t plist_id - * ID of property list to modify - * MPI_Comm comm - * MPI communicator to be used for file open as defined in - * MPI_FILE_OPEN of MPI-2. This function does not make a - * duplicated communicator. Any modification to comm after - * this function call returns may have undetermined effect - * to the access property list. Users should call this - * function again to setup the property list. - * MPI_Info info - * MPI info object to be used for file open as defined in - * MPI_FILE_OPEN of MPI-2. This function does not make a - * duplicated info. Any modification to info after - * this function call returns may have undetermined effect - * to the access property list. Users should call this - * function again to setup the property list. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Albert Cheng - * Feb 3, 1998 - * - * Modifications: - * - * Robb Matzke, 18 Feb 1998 - * Check all arguments before the property list is updated so we don't - * leave the property list in a bad state if something goes wrong. Also, - * the property list data type changed to allow more generality so all - * the mpi-related stuff is in the `u.mpi' member. The `access_mode' - * will contain only mpi-related flags defined in H5Fpublic.h. - * - * Albert Cheng, Apr 16, 1998 - * Removed the access_mode argument. The access_mode is changed - * to be controlled by data transfer property list during data - * read/write calls. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_mpi(hid_t plist_id, MPI_Comm comm, MPI_Info info) -{ - H5F_access_t *plist = NULL; - - FUNC_ENTER(H5Pset_mpi, FAIL); - H5TRACE3("e","iMcMi",plist_id,comm,info); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - -#ifdef LATER - /* - * Need to verify comm and info contain sensible information. - */ -#endif - - plist->driver = H5F_LOW_MPIO; - plist->u.mpio.comm = comm; - plist->u.mpio.info = info; - - FUNC_LEAVE(SUCCEED); -} -#endif /*HAVE_PARALLEL*/ - - -#ifdef HAVE_PARALLEL -/*------------------------------------------------------------------------- - * Function: H5Pget_mpi - * - * Purpose: If the file access property list is set to the mpi driver - * then this function returns zero; otherwise it returns a - * negative value. In the future, additional arguments may be - * added to this function to match those added to H5Pset_mpi(). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, February 26, 1998 - * - * Modifications: - * - * Albert Cheng, Apr 16, 1998 - * Removed the access_mode argument. The access_mode is changed - * to be controlled by data transfer property list during data - * read/write calls. - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_mpi(hid_t plist_id, MPI_Comm *comm, MPI_Info *info) -{ - H5F_access_t *plist = NULL; - - FUNC_ENTER (H5Pget_mpi, FAIL); - H5TRACE3("e","i*Mc*Mi",plist_id,comm,info); - - /* Check arguments */ - if (H5P_FILE_ACCESS != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, - "not a file access property list"); - } - if (H5F_LOW_MPIO != plist->driver) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "the mpi driver is not set"); - } - *comm = plist->u.mpio.comm; - *info = plist->u.mpio.info; - - FUNC_LEAVE (SUCCEED); -} -#endif /*HAVE_PARALLEL*/ - - -#ifdef HAVE_PARALLEL -/*------------------------------------------------------------------------- - * Function: H5Pset_xfer - * - * Signature: herr_t H5Pset_xfer(hid_t plist_id, - * H5D_transfer_t data_xfer_mode) - * - * Purpose: Set the transfer mode of the dataset transfer property list. - * The list can then be used to control the I/O transfer mode - * during dataset accesses. This function is available only - * in the parallel HDF5 library and is not a collective function. - * - * Parameters: - * hid_t plist_id - * ID of a dataset transfer property list - * H5D_transfer_t data_xfer_mode - * Data transfer modes: - * H5D_XFER_INDEPENDENT - * Use independent I/O access. - * H5D_XFER_COLLECTIVE - * Use MPI collective I/O access. - * H5D_XFER_DFLT - * Use default I/O access. Currently, - * independent is the default mode. - * - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Albert Cheng - * April 2, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_xfer(hid_t plist_id, H5D_transfer_t data_xfer_mode) -{ - H5F_xfer_t *plist = NULL; - - FUNC_ENTER(H5Pset_xfer, FAIL); - H5TRACE2("e","iDt",plist_id,data_xfer_mode); - - /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a dataset transfer property list"); - } - - switch (data_xfer_mode){ - case H5D_XFER_INDEPENDENT: - case H5D_XFER_COLLECTIVE: - case H5D_XFER_DFLT: - plist->xfer_mode = data_xfer_mode; - break; - default: - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "invalid dataset transfer mode"); - } - - FUNC_LEAVE(SUCCEED); -} -#endif /*HAVE_PARALLEL*/ - - -#ifdef HAVE_PARALLEL -/*------------------------------------------------------------------------- - * Function: H5Pget_xfer - * - * Purpose: Reads the transfer mode current set in the property list. - * This function is available only in the parallel HDF5 library - * and is not a collective function. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Albert Cheng - * April 2, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_xfer(hid_t plist_id, H5D_transfer_t *data_xfer_mode) -{ - H5F_xfer_t *plist = NULL; - - FUNC_ENTER (H5Pget_xfer, FAIL); - H5TRACE2("e","i*Dt",plist_id,data_xfer_mode); - - /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class(plist_id) || - NULL == (plist = H5I_object(plist_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, - "not a dataset transfer property list"); - } - - *data_xfer_mode = plist->xfer_mode; - - FUNC_LEAVE (SUCCEED); -} -#endif /*HAVE_PARALLEL*/ - - /*------------------------------------------------------------------------- * Function: H5Pset_gc_references * * Purpose: Sets the flag for garbage collecting references for the file. - * Dataset region references (and other reference types probably) use - * space in the file heap. If garbage collection is on and the user - * passes in an uninitialized value in a reference structure, the heap - * might get corrupted. When garbage collection is off however and the - * user re-uses a reference, the previous heap block will be orphaned and - * not returned to the free heap space. When garbage collection is on, - * the user must initialize the reference structures to 0 or risk heap - * corruption. - * - * Default value for garbage collecting references is off, just to be - * on the safe side. + * Dataset region references (and other reference types + * probably) use space in the file heap. If garbage collection + * is on and the user passes in an uninitialized value in a + * reference structure, the heap might get corrupted. When + * garbage collection is off however and the user re-uses a + * reference, the previous heap block will be orphaned and not + * returned to the free heap space. When garbage collection is + * on, the user must initialize the reference structures to 0 or + * risk heap corruption. + * + * Default value for garbage collecting references is off, just + * to be on the safe side. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Friday, November 13, 1998 + * June, 1999 * * Modifications: * @@ -3001,12 +2398,14 @@ H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref) { H5F_access_t *fapl = NULL; - FUNC_ENTER (H5Pset_gc_references, FAIL); + FUNC_ENTER(H5Pset_gc_references, FAIL); H5TRACE2("e","iIu",fapl_id,gc_ref); /* Check args */ - if (H5P_FILE_ACCESS != H5P_get_class (fapl_id) || NULL == (fapl = H5I_object (fapl_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + if (H5P_FILE_ACCESS!=H5P_get_class(fapl_id) || + NULL==(fapl=H5I_object(fapl_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); } /* Set values */ @@ -3019,13 +2418,13 @@ H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref) /*------------------------------------------------------------------------- * Function: H5Pget_gc_refernces * - * Purpose: Returns the current setting for the garbage collection refernces - * property from a file access property list. + * Purpose: Returns the current setting for the garbage collection + * refernces property from a file access property list. * * Return: Non-negative on success/Negative on failure * - * Programmer: Robb Matzke - * Tuesday, June 9, 1998 + * Programmer: Quincey Koziol + * June, 1999 * * Modifications: * @@ -3036,12 +2435,14 @@ H5Pget_gc_reference(hid_t fapl_id, unsigned *gc_ref/*out*/) { H5F_access_t *fapl = NULL; - FUNC_ENTER (H5Pget_alignment, FAIL); + FUNC_ENTER(H5Pget_gc_reference, FAIL); H5TRACE2("e","ix",fapl_id,gc_ref); /* Check args */ - if (H5P_FILE_ACCESS != H5P_get_class (fapl_id) || NULL == (fapl = H5I_object (fapl_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + if (H5P_FILE_ACCESS!=H5P_get_class(fapl_id) || + NULL==(fapl=H5I_object(fapl_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); } /* Get values */ @@ -3055,13 +2456,13 @@ H5Pget_gc_reference(hid_t fapl_id, unsigned *gc_ref/*out*/) * Function: H5Pset_vlen_mem_manager * * Purpose: Sets the memory allocate/free pair for VL datatypes. The - * allocation routine is called when data is read into a new array - * and the free routine is called when H5Dvlen_reclaim is called. - * The alloc_info and free_info are user parameters which are passed - * to the allocation and freeing functions respectively. - * To reset the allocate/free functions to the default setting of using - * the system's malloc/free functions, call this routine with alloc_func - * and free_func set to NULL. + * allocation routine is called when data is read into a new + * array and the free routine is called when H5Dvlen_reclaim is + * called. The alloc_info and free_info are user parameters + * which are passed to the allocation and freeing functions + * respectively. To reset the allocate/free functions to the + * default setting of using the system's malloc/free functions, + * call this routine with alloc_func and free_func set to NULL. * * Return: Non-negative on success/Negative on failure * @@ -3078,13 +2479,14 @@ H5Pset_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t alloc_func, { H5F_xfer_t *plist = NULL; - FUNC_ENTER (H5Pset_vlen_mem_manager, FAIL); + FUNC_ENTER(H5Pset_vlen_mem_manager, FAIL); H5TRACE5("e","ixxxx",plist_id,alloc_func,alloc_info,free_func,free_info); /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); + if (H5P_DATA_XFER!=H5P_get_class(plist_id) || + NULL==(plist=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset transfer property list"); } /* Update property list */ @@ -3112,19 +2514,21 @@ H5Pset_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t alloc_func, *------------------------------------------------------------------------- */ herr_t -H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func, - void **alloc_info, H5MM_free_t *free_func, void **free_info) +H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func/*out*/, + void **alloc_info/*out*/, + H5MM_free_t *free_func/*out*/, + void **free_info/*out*/) { H5F_xfer_t *plist = NULL; - FUNC_ENTER (H5Pset_vlen_mem_manager, FAIL); - H5TRACE5("e","i*x*x*x*x",plist_id,alloc_func,alloc_info,free_func, - free_info); + FUNC_ENTER(H5Pget_vlen_mem_manager, FAIL); + H5TRACE5("e","ixxxx",plist_id,alloc_func,alloc_info,free_func,free_info); /* Check arguments */ - if (H5P_DATASET_XFER != H5P_get_class (plist_id) || - NULL == (plist = H5I_object (plist_id))) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list"); + if (H5P_DATA_XFER!=H5P_get_class(plist_id) || + NULL==(plist=H5I_object(plist_id))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset transfer property list"); } if(alloc_func!=NULL) @@ -3139,31 +2543,27 @@ H5Pget_vlen_mem_manager(hid_t plist_id, H5MM_allocate_t *alloc_func, FUNC_LEAVE (SUCCEED); } - -/*-------------------------------------------------------------------------- - NAME - H5Pcopy - PURPOSE - Copy a property list - USAGE - hid_t H5P_copy(plist_id) - hid_t plist_id; IN: property list object to copy - RETURNS - Returns property list ID (atom) on success, Negative on failure - - ERRORS - ARGS BADRANGE Unknown property list class. - ATOM BADATOM Can't unatomize property list. - ATOM CANTREGISTER Register the atom for the new property list. - INTERNAL UNSUPPORTED Dataset transfer properties are not implemented - yet. - INTERNAL UNSUPPORTED File access properties are not implemented yet. - - DESCRIPTION - * This function creates a new copy of a property list with all the same - * parameter settings. ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5Pcopy + * + * Purpose: Deep-copies a property list PLIST_ID. + * + * Return: Success: The ID of the new copy of the property list. + * The ID will be different than the input ID + * since the new ID refers to a completely + * separate copy of the the structure that the + * original ID points to. + * + * Failure: Negative + * + * Programmer: Unknown + * + * Modifications: + * Robb Matzke, 1999-08-03 + * If PLIST_ID is H5P_DEFAULT then we return H5P_DEFAULT. + *------------------------------------------------------------------------- + */ hid_t H5Pcopy(hid_t plist_id) { @@ -3176,6 +2576,8 @@ H5Pcopy(hid_t plist_id) FUNC_ENTER(H5Pcopy, FAIL); H5TRACE1("i","i",plist_id); + if (H5P_DEFAULT==plist_id) return H5P_DEFAULT; + /* Check args */ if (NULL == (plist = H5I_object(plist_id)) || (type = H5P_get_class(plist_id)) < 0 || @@ -3197,6 +2599,7 @@ H5Pcopy(hid_t plist_id) } FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- * Function: H5P_copy @@ -3212,7 +2615,8 @@ H5Pcopy(hid_t plist_id) * Tuesday, February 3, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-03 + * Modified to use the virtual file layer. *------------------------------------------------------------------------- */ void * @@ -3224,6 +2628,8 @@ H5P_copy (H5P_class_t type, const void *src) H5D_create_t *dc_dst = NULL; const H5F_access_t *fa_src = NULL; H5F_access_t *fa_dst = NULL; + const H5F_xfer_t *dx_src = NULL; + H5F_xfer_t *dx_dst = NULL; FUNC_ENTER (H5P_copy, NULL); @@ -3241,7 +2647,7 @@ H5P_copy (H5P_class_t type, const void *src) size = sizeof(H5D_create_t); break; - case H5P_DATASET_XFER: + case H5P_DATA_XFER: size = sizeof(H5F_xfer_t); break; @@ -3269,26 +2675,11 @@ H5P_copy (H5P_class_t type, const void *src) case H5P_FILE_ACCESS: fa_src = (const H5F_access_t*)src; fa_dst = (H5F_access_t*)dst; - switch (fa_src->driver) { - case H5F_LOW_ERROR: - case H5F_LOW_SEC2: - case H5F_LOW_STDIO: - case H5F_LOW_CORE: - case H5F_LOW_MPIO: - /* Nothing to do */ - break; - - case H5F_LOW_FAMILY: - fa_dst->u.fam.memb_access = H5P_copy (H5P_FILE_ACCESS, - fa_src->u.fam.memb_access); - break; - - case H5F_LOW_SPLIT: - fa_dst->u.split.meta_access=H5P_copy (H5P_FILE_ACCESS, - fa_src->u.split.meta_access); - fa_dst->u.split.raw_access = H5P_copy (H5P_FILE_ACCESS, - fa_src->u.split.raw_access); - break; + + if (fa_dst->driver_id>=0) { + H5I_inc_ref(fa_dst->driver_id); + fa_dst->driver_info = H5FD_fapl_copy(fa_dst->driver_id, + fa_dst->driver_info); } break; @@ -3318,8 +2709,15 @@ H5P_copy (H5P_class_t type, const void *src) break; - case H5P_DATASET_XFER: - /* Nothing to do */ + case H5P_DATA_XFER: + dx_src = (const H5F_xfer_t*)src; + dx_dst = (H5F_xfer_t*)dst; + + if (dx_dst->driver_id>=0) { + H5I_inc_ref(dx_dst->driver_id); + dx_dst->driver_info = H5FD_dxpl_copy(dx_dst->driver_id, + dx_dst->driver_info); + } break; case H5P_MOUNT: diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index f19bec7..56770f3 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -33,7 +33,7 @@ typedef enum H5P_class_t { H5P_FILE_CREATE = 0, /*file creation properties */ H5P_FILE_ACCESS = 1, /*file access properties */ H5P_DATASET_CREATE = 2, /*dataset creation properties */ - H5P_DATASET_XFER = 3, /*dataset transfer properties */ + H5P_DATA_XFER = 3, /*data transfer properties */ H5P_MOUNT = 4, /*file mounting properties */ H5P_NCLASSES = 5 /*this must be last! */ @@ -75,26 +75,10 @@ __DLL__ int H5Pget_external_count(hid_t plist_id); __DLL__ herr_t H5Pget_external(hid_t plist_id, int idx, size_t name_size, char *name/*out*/, off_t *offset/*out*/, hsize_t *size/*out*/); -__DLL__ H5F_driver_t H5Pget_driver(hid_t plist_id); -__DLL__ herr_t H5Pset_stdio(hid_t plist_id); -__DLL__ herr_t H5Pget_stdio(hid_t plist_id); -__DLL__ herr_t H5Pset_sec2(hid_t plist_id); -__DLL__ herr_t H5Pget_sec2(hid_t plist_id); -__DLL__ herr_t H5Pset_core(hid_t plist_id, size_t increment); -__DLL__ herr_t H5Pget_core(hid_t plist_id, size_t *increment/*out*/); -__DLL__ herr_t H5Pset_split(hid_t plist_id, const char *meta_ext, - hid_t meta_plist_id, const char *raw_ext, - hid_t raw_plist_id); -__DLL__ herr_t H5Pget_split(hid_t plist_id, size_t meta_ext_size, - char *meta_ext/*out*/, - hid_t *meta_properties/*out*/, - size_t raw_ext_size, char *raw_ext/*out*/, - hid_t *raw_properties/*out*/); - -__DLL__ herr_t H5Pset_family(hid_t plist_id, hsize_t memb_size, - hid_t memb_plist_id); -__DLL__ herr_t H5Pget_family(hid_t plist_id, hsize_t *memb_size/*out*/, - hid_t *memb_plist_id/*out*/); +__DLL__ herr_t H5Pset_driver(hid_t plist_id, hid_t driver_id, + const void *driver_info); +__DLL__ hid_t H5Pget_driver(hid_t plist_id); +__DLL__ void *H5Pget_driver_info(hid_t plist_id); __DLL__ herr_t H5Pset_buffer(hid_t plist_id, size_t size, void *tconv, void *bkg); __DLL__ size_t H5Pget_buffer(hid_t plist_id, void **tconv/*out*/, @@ -129,16 +113,6 @@ __DLL__ herr_t H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value); __DLL__ herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/); - -#ifdef HAVE_PARALLEL -__DLL__ herr_t H5Pset_mpi(hid_t plist_id, MPI_Comm comm, MPI_Info info); -__DLL__ herr_t H5Pget_mpi(hid_t plist_id, MPI_Comm *comm/*out*/, - MPI_Info *info/*out*/); -__DLL__ herr_t H5Pset_xfer(hid_t plist_id, H5D_transfer_t data_xfer_mode); -__DLL__ herr_t H5Pget_xfer(hid_t plist_id, - H5D_transfer_t *data_xfer_mode/*out*/); -#endif - __DLL__ herr_t H5Pset_gc_references(hid_t fapl_id, unsigned gc_ref); __DLL__ herr_t H5Pget_gc_reference(hid_t fapl_id, unsigned *gc_ref/*out*/); __DLL__ herr_t H5Pset_vlen_mem_manager(hid_t plist_id, @@ -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->access_parms->gc_ref) { + if(loc->file->shared->fapl->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/H5Sall.c b/src/H5Sall.c index 711ade5..d956b78 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -29,14 +29,14 @@ static size_t H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, void *buf/*out*/); + hid_t dxpl_id, void *buf/*out*/); static herr_t H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, const void *buf); + hid_t dxpl_id, const void *buf); static size_t H5S_all_mgath (const void *_buf, size_t elmt_size, const H5S_t *mem_space, H5S_sel_iter_t *mem_iter, size_t nelmts, void *_tconv_buf/*out*/); @@ -182,7 +182,9 @@ H5S_all_favail (const H5S_t *space, const H5S_sel_iter_t *sel_iter, size_t max) * Tuesday, June 16, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-03 + * The data transfer properties are passed by ID since that's + * what the virtual file layer needs. *------------------------------------------------------------------------- */ static size_t @@ -190,8 +192,8 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, void *_buf/*out*/) + H5S_sel_iter_t *file_iter, size_t nelmts, hid_t dxpl_id, + void *_buf/*out*/) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -244,9 +246,9 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, /* * Gather from file. */ - if (H5F_arr_read (f, xfer_parms, layout, pline, fill, efl, hsize, hsize, - zero, file_offset, buf/*out*/)<0) { - HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); + if (H5F_arr_read(f, dxpl_id, layout, pline, fill, efl, hsize, hsize, + zero, file_offset, buf/*out*/)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error"); } /* Advance iterator */ @@ -271,7 +273,9 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, * Tuesday, June 16, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-03 + * The data transfer properties are passed by ID since that's + * what the virtual file layer needs. *------------------------------------------------------------------------- */ static herr_t @@ -279,7 +283,7 @@ H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, - size_t nelmts, const H5F_xfer_t *xfer_parms, const void *_buf) + size_t nelmts, hid_t dxpl_id, const void *_buf) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -328,7 +332,7 @@ H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout, /* * Scatter to file. */ - if (H5F_arr_write (f, xfer_parms, layout, pline, fill, efl, hsize, hsize, + if (H5F_arr_write (f, dxpl_id, layout, pline, fill, efl, hsize, hsize, zero, file_offset, buf)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); } @@ -538,15 +542,19 @@ H5S_all_mscat (const void *_tconv_buf, size_t elmt_size, * Thursday, April 22, 1999 * * Modifications: - * Modified to allow contiguous hyperslabs to be written out - QAK - 5/25/99 + * Quincey Koziol, 1999-05-25 + * Modified to allow contiguous hyperslabs to be written out. * + * Robb Matzke, 1999-08-03 + * The data transfer properties are passed by ID since that's + * what the virtual file layer needs. *------------------------------------------------------------------------- */ herr_t H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - const H5S_t *mem_space, const H5F_xfer_t *xfer_parms, - void *buf/*out*/, hbool_t *must_convert/*out*/) + const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/, + hbool_t *must_convert/*out*/) { H5S_hyper_node_t *file_node,*mem_node; /* Hyperslab node */ hsize_t mem_size,file_size; @@ -611,7 +619,7 @@ H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline, mem_offset[i] = 0; /* Read data from the file */ - if (H5F_arr_read(f, xfer_parms, layout, pline, NULL, efl, size, + if (H5F_arr_read(f, dxpl_id, layout, pline, NULL, efl, size, size, mem_offset, file_offset, buf/*out*/)<0) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read data from the file"); @@ -639,16 +647,20 @@ H5S_all_read(H5F_t *f, const H5O_layout_t *layout, const H5O_pline_t *pline, * Wednesday, April 21, 1999 * * Modifications: - * Modified to allow contiguous hyperslabs to be written out - QAK - 5/25/99 + * Quincey Koziol, 1999-05-25 + * Modified to allow contiguous hyperslabs to be written out. * + * Robb Matzke, 1999-08-03 + * The data transfer properties are passed by ID since that's + * what the virtual file layer needs. *------------------------------------------------------------------------- */ herr_t H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, const H5O_pline_t *pline, const H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - const H5S_t *mem_space, const H5F_xfer_t *xfer_parms, - const void *buf, hbool_t *must_convert/*out*/) + const H5S_t *mem_space, hid_t dxpl_id, const void *buf, + hbool_t *must_convert/*out*/) { H5S_hyper_node_t *file_node,*mem_node; /* Hyperslab node */ hsize_t mem_size,file_size; @@ -713,7 +725,7 @@ H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, mem_offset[i] = 0; /* Write data to the file */ - if (H5F_arr_write(f, xfer_parms, layout, pline, NULL, efl, size, + if (H5F_arr_write(f, dxpl_id, layout, pline, NULL, efl, size, size, mem_offset, file_offset, buf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write data to the file"); diff --git a/src/H5Shyper.c b/src/H5Shyper.c index fe3fc76..f56f3fa 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -8,13 +8,14 @@ * Purpose: Hyperslab selection data space I/O functions. */ #include <H5private.h> +#include <H5Dprivate.h> #include <H5Eprivate.h> #include <H5Iprivate.h> -#include <H5Sprivate.h> -#include <H5Vprivate.h> #include <H5MMprivate.h> +#include <H5Pprivate.h> +#include <H5Sprivate.h> #include <H5TBprivate.h> -#include <H5Dprivate.h> +#include <H5Vprivate.h> /* Interface initialization */ #define PABLO_MASK H5Shyper_mask @@ -33,7 +34,7 @@ typedef struct { const H5S_t *space; H5S_sel_iter_t *iter; size_t nelmts; - const H5F_xfer_t *xfer_parms; + hid_t dxpl_id; const void *src; void *dst; hsize_t mem_size[H5O_LAYOUT_NDIMS]; @@ -79,14 +80,14 @@ static size_t H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, void *buf/*out*/); + hid_t dxpl_id, void *buf/*out*/); static herr_t H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, const void *buf); + hid_t dxpl_id, const void *buf); static size_t H5S_hyper_mgath (const void *_buf, size_t elmt_size, const H5S_t *mem_space, H5S_sel_iter_t *mem_iter, size_t nelmts, @@ -474,10 +475,10 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node, hsize[i]=(node->end[i]-node->start[i])+1; hsize[io_info->space->extent.u.simple.rank]=io_info->elmt_size; - if (H5F_arr_read (io_info->f, io_info->xfer_parms, - io_info->layout, io_info->pline, - io_info->fill, io_info->efl, hsize, hsize, - zero, file_offset, node->cinfo.block/*out*/)<0) + if (H5F_arr_read(io_info->f, io_info->dxpl_id, + io_info->layout, io_info->pline, + io_info->fill, io_info->efl, hsize, hsize, + zero, file_offset, node->cinfo.block/*out*/)<0) HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, FAIL, "read error"); } /* end if */ else { @@ -595,10 +596,10 @@ H5S_hyper_block_write (H5S_hyper_node_t *node, hsize[i]=(node->end[i]-node->start[i])+1; hsize[io_info->space->extent.u.simple.rank]=io_info->elmt_size; - if (H5F_arr_write (io_info->f, io_info->xfer_parms, - io_info->layout, io_info->pline, - io_info->fill, io_info->efl, hsize, hsize, - zero, file_offset, node->cinfo.block/*out*/)<0) + if (H5F_arr_write(io_info->f, io_info->dxpl_id, io_info->layout, + io_info->pline, io_info->fill, io_info->efl, hsize, + hsize, zero, file_offset, + node->cinfo.block/*out*/)<0) HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); /* Release the temporary buffer */ @@ -639,10 +640,17 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info) size_t i; /* Counters */ intn j; size_t num_read=0; /* Number of elements read */ + const H5F_xfer_t *xfer_parms;/* Data transfer property list */ FUNC_ENTER (H5S_hyper_fread, 0); assert(io_info); + if (H5P_DEFAULT==io_info->dxpl_id) { + xfer_parms = &H5F_xfer_dflt; + } else { + xfer_parms = H5I_object(io_info->dxpl_id); + assert(xfer_parms); + } #ifdef QAK printf("%s: check 1.0, dim=%d\n",FUNC,dim); @@ -680,9 +688,9 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info) /* Check if this hyperslab block is cached or could be cached */ if(!regions[i].node->cinfo.cached && - (io_info->xfer_parms->cache_hyper && - (io_info->xfer_parms->block_limit==0 || - io_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*io_info->elmt_size)))) { + (xfer_parms->cache_hyper && + (xfer_parms->block_limit==0 || + xfer_parms->block_limit>=(regions[i].node->cinfo.size*io_info->elmt_size)))) { /* if we aren't cached, attempt to cache the block */ H5S_hyper_block_cache(regions[i].node,io_info,1); } /* end if */ @@ -713,11 +721,12 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info) /* * Gather from file. */ - if (H5F_arr_read (io_info->f, io_info->xfer_parms, - io_info->layout, io_info->pline, - io_info->fill, io_info->efl, - io_info->hsize, io_info->hsize, zero, io_info->offset, - io_info->dst/*out*/)<0) { + if (H5F_arr_read(io_info->f, io_info->dxpl_id, + io_info->layout, io_info->pline, + io_info->fill, io_info->efl, + io_info->hsize, io_info->hsize, + zero, io_info->offset, + io_info->dst/*out*/)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } @@ -807,7 +816,9 @@ H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info) * Tuesday, June 16, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-03 + * The data transfer properties are passed by ID since that's + * what the virtual file layer needs. *------------------------------------------------------------------------- */ static size_t @@ -816,8 +827,7 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, - size_t nelmts, const H5F_xfer_t *xfer_parms, - void *_buf/*out*/) + size_t nelmts, hid_t dxpl_id, void *_buf/*out*/) { H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ @@ -864,7 +874,7 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout, io_info.space=file_space; io_info.iter=file_iter; io_info.nelmts=nelmts; - io_info.xfer_parms=xfer_parms; + io_info.dxpl_id = dxpl_id; io_info.src=NULL; io_info.dst=_buf; @@ -921,10 +931,17 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) size_t i; /* Counters */ intn j; size_t num_written=0; /* Number of elements read */ + const H5F_xfer_t *xfer_parms; /* Data transfer properties */ FUNC_ENTER (H5S_hyper_fwrite, 0); assert(io_info); + if (H5P_DEFAULT==io_info->dxpl_id) { + xfer_parms = &H5F_xfer_dflt; + } else { + xfer_parms = H5I_object(io_info->dxpl_id); + assert(xfer_parms); + } #ifdef QAK printf("%s: check 1.0\n", FUNC); @@ -958,7 +975,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) region_size=MIN(io_info->nelmts, (regions[i].end-regions[i].start)+1); /* Check if this hyperslab block is cached or could be cached */ - if(!regions[i].node->cinfo.cached && (io_info->xfer_parms->cache_hyper && (io_info->xfer_parms->block_limit==0 || io_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*io_info->elmt_size)))) { + if(!regions[i].node->cinfo.cached && (xfer_parms->cache_hyper && (xfer_parms->block_limit==0 || xfer_parms->block_limit>=(regions[i].node->cinfo.size*io_info->elmt_size)))) { /* if we aren't cached, attempt to cache the block */ H5S_hyper_block_cache(regions[i].node,io_info,0); } /* end if */ @@ -985,11 +1002,11 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) /* * Scatter to file. */ - if (H5F_arr_write (io_info->f, io_info->xfer_parms, - io_info->layout, io_info->pline, - io_info->fill, io_info->efl, - io_info->hsize, io_info->hsize, zero, io_info->offset, - io_info->src)<0) { + if (H5F_arr_write(io_info->f, io_info->dxpl_id, + io_info->layout, io_info->pline, + io_info->fill, io_info->efl, + io_info->hsize, io_info->hsize, zero, + io_info->offset, io_info->src)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } } /* end else */ @@ -1063,7 +1080,9 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info) * Tuesday, June 16, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-03 + * The data transfer properties are passed by ID since that's + * what the virtual file layer needs. *------------------------------------------------------------------------- */ static herr_t @@ -1072,8 +1091,7 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, - size_t nelmts, const H5F_xfer_t *xfer_parms, - const void *_buf) + size_t nelmts, hid_t dxpl_id, const void *_buf) { H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */ @@ -1121,7 +1139,7 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout, io_info.space=file_space; io_info.iter=file_iter; io_info.nelmts=nelmts; - io_info.xfer_parms=xfer_parms; + io_info.dxpl_id = dxpl_id; io_info.src=_buf; io_info.dst=NULL; diff --git a/src/H5Smpio.c b/src/H5Smpio.c index 91a42ba..e2c1375 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -12,8 +12,11 @@ #include <H5private.h> #include <H5Eprivate.h> +#include <H5FDprivate.h> #include <H5Sprivate.h> +#include <H5FDmpio.h> /*the MPIO file driver */ + #ifndef HAVE_PARALLEL /* * The H5S_mpio_xxxx functions are for parallel I/O only and are @@ -54,7 +57,7 @@ H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t UNUSED *pline, const struct H5O_efl_t UNUSED *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, void *buf/*out*/, + hid_t dxpl_id, void *buf/*out*/, hbool_t *must_convert/*out*/, const hbool_t do_write); /*------------------------------------------------------------------------- @@ -105,7 +108,8 @@ H5S_mpio_all_type( const H5S_t *space, const size_t elmt_size, fprintf(stdout, "Leave %s total_bytes=%Hu\n", FUNC, total_bytes ); #endif FUNC_LEAVE (SUCCEED); -} /* H5S_mpio_all_type() */ +} + /*------------------------------------------------------------------------- * Function: H5S_mpio_hyper_type @@ -140,7 +144,7 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size, hsize_t count; } d[32]; - int i, j, err, new_rank, num_to_collapse, stride_bytes; + int i, err, new_rank, num_to_collapse; int offset[32], max_xtent[32], block_length[2], displacement[2]; H5S_hyper_dim_t *diminfo; /* [rank] */ intn rank; @@ -403,7 +407,7 @@ H5S_mpio_hyper_type( const H5S_t *space, const size_t elmt_size, fprintf(stdout, "Leave %s\n", FUNC ); #endif FUNC_LEAVE (SUCCEED); -} /* H5S_mpio_hyper_type() */ +} /*------------------------------------------------------------------------- @@ -488,7 +492,8 @@ H5S_mpio_space_type( const H5S_t *space, const size_t elmt_size, } FUNC_LEAVE (ret_value); -} /* H5S_mpio_space_type() */ +} + /*------------------------------------------------------------------------- * Function: H5S_mpio_spaces_xfer @@ -508,11 +513,11 @@ H5S_mpio_space_type( const H5S_t *space, const size_t elmt_size, *------------------------------------------------------------------------- */ herr_t -H5S_mpio_spaces_xfer (H5F_t *f, const struct H5O_layout_t *layout, +H5S_mpio_spaces_xfer(H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t UNUSED *pline, const struct H5O_efl_t UNUSED *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, void *buf /*out*/, + hid_t dxpl_id, void *buf /*out*/, hbool_t *must_convert /*out*/, const hbool_t do_write ) { @@ -534,7 +539,7 @@ H5S_mpio_spaces_xfer (H5F_t *f, const struct H5O_layout_t *layout, assert (file_space); assert (mem_space); assert (buf); - assert (f->shared->access_parms->driver == H5F_LOW_MPIO); + assert (H5FD_MPIO==f->shared->fapl->driver_id); /* INCOMPLETE!!! rky 980816 */ /* Currently can only handle H5D_CONTIGUOUS layout */ @@ -556,8 +561,6 @@ H5S_mpio_spaces_xfer (H5F_t *f, const struct H5O_layout_t *layout, &mbt_is_derived ); if (MPI_SUCCESS != err) HRETURN_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI buf type"); - /* pass the buf type to low-level write via access_parms */ - f->shared->access_parms->u.mpio.btype = mpi_buf_type; /* create the MPI file type */ err = H5S_mpio_space_type( file_space, elmt_size, @@ -567,12 +570,9 @@ H5S_mpio_spaces_xfer (H5F_t *f, const struct H5O_layout_t *layout, &mft_is_derived ); if (MPI_SUCCESS != err) HRETURN_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"couldn't create MPI file type"); - /* pass the file type to low-level write via access_parms */ - f->shared->access_parms->u.mpio.ftype = mpi_file_type; /* calculate the absolute base addr (i.e., the file view disp) */ disp = f->shared->base_addr + layout->addr; - f->shared->access_parms->u.mpio.disp = disp; #ifdef H5Smpi_DEBUG fprintf(stdout, "spaces_xfer: disp=%Hu\n", disp.offset ); #endif @@ -580,22 +580,26 @@ H5S_mpio_spaces_xfer (H5F_t *f, const struct H5O_layout_t *layout, /* Effective address determined by base addr and the MPI file type */ addr = 0; - /* request a dataspace xfer (instead of an elementary byteblock xfer) */ - f->shared->access_parms->u.mpio.use_types = 1; + /* + * Pass buf type, file type, and absolute base address (i.e., the file + * view disp) to the file driver. Request a dataspace transfer (instead + * of an elementary byteblock transfer). + */ + H5FD_mpio_setup(f->shared->lf, mpi_buf_type, mpi_file_type, disp, 1); /* transfer the data */ mpi_count = (size_t)mpi_buf_count; - if (mpi_count != mpi_buf_count) - HRETURN_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL,"transfer size overflows size_t"); + if (mpi_count != mpi_buf_count) { + HRETURN_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, + "transfer size overflows size_t"); + } if (do_write) { - err = H5F_low_write( f->shared->lf, f->shared->access_parms, - xfer_parms, addr, mpi_count, buf ); + err = H5FD_write(f->shared->lf, dxpl_id, addr, mpi_count, buf); if (err) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,"MPI write failed"); } } else { - err = H5F_low_read ( f->shared->lf, f->shared->access_parms, - xfer_parms, addr, mpi_count, buf ); + err = H5FD_read (f->shared->lf, dxpl_id, addr, mpi_count, buf); if (err) { HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,"MPI read failed"); } @@ -605,19 +609,22 @@ H5S_mpio_spaces_xfer (H5F_t *f, const struct H5O_layout_t *layout, if (mbt_is_derived) { err = MPI_Type_free( &mpi_buf_type ); if (MPI_SUCCESS != err) { - HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't free MPI file type"); + HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL, + "unable to free MPI file type"); } } if (mft_is_derived) { err = MPI_Type_free( &mpi_file_type ); if (MPI_SUCCESS != err) { - HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL,"couldn't free MPI file type"); + HRETURN_ERROR(H5E_DATASPACE, H5E_MPI, FAIL, + "unable to free MPI file type"); } } done: FUNC_LEAVE (ret_value); -} /* H5S_mpio_spaces_xfer() */ +} + /*------------------------------------------------------------------------- * Function: H5S_mpio_spaces_read @@ -636,11 +643,11 @@ H5S_mpio_spaces_xfer (H5F_t *f, const struct H5O_layout_t *layout, *------------------------------------------------------------------------- */ herr_t -H5S_mpio_spaces_read (H5F_t *f, const struct H5O_layout_t *layout, +H5S_mpio_spaces_read(H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, void *buf/*out*/, + hid_t dxpl_id, void *buf/*out*/, hbool_t *must_convert/*out*/) { herr_t ret_value = FAIL; @@ -648,11 +655,12 @@ H5S_mpio_spaces_read (H5F_t *f, const struct H5O_layout_t *layout, FUNC_ENTER (H5S_mpio_spaces_read, FAIL); ret_value = H5S_mpio_spaces_xfer(f, layout, pline, efl, elmt_size, - file_space, mem_space, xfer_parms, + file_space, mem_space, dxpl_id, buf, must_convert/*out*/, 0/*read*/); FUNC_LEAVE (ret_value); -} /* H5S_mpio_spaces_read() */ +} + /*------------------------------------------------------------------------- * Function: H5S_mpio_spaces_write @@ -672,22 +680,22 @@ H5S_mpio_spaces_read (H5F_t *f, const struct H5O_layout_t *layout, */ herr_t H5S_mpio_spaces_write(H5F_t *f, const struct H5O_layout_t *layout, - const struct H5O_pline_t *pline, - const struct H5O_efl_t *efl, size_t elmt_size, - const H5S_t *file_space, const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, const void *buf, - hbool_t *must_convert/*out*/) + const struct H5O_pline_t *pline, + const struct H5O_efl_t *efl, size_t elmt_size, + const H5S_t *file_space, const H5S_t *mem_space, + hid_t dxpl_id, const void *buf, + hbool_t *must_convert/*out*/) { herr_t ret_value = FAIL; FUNC_ENTER (H5S_mpio_spaces_write, FAIL); ret_value = H5S_mpio_spaces_xfer(f, layout, pline, efl, elmt_size, - file_space, mem_space, xfer_parms, + file_space, mem_space, dxpl_id, (void*)buf, must_convert/*out*/, 1/*write*/); FUNC_LEAVE (ret_value); -} /* H5S_mpio_spaces_write() */ +} #endif /* HAVE_PARALLEL */ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 685b42d..a7062e9 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -30,16 +30,14 @@ static size_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, - void *buf/*out*/); + hid_t dxpl_id, void *buf/*out*/); static herr_t H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, - const void *buf); + hid_t dxpl_id, const void *buf); static size_t H5S_point_mgath (const void *_buf, size_t elmt_size, const H5S_t *mem_space, H5S_sel_iter_t *mem_iter, size_t nelmts, @@ -263,7 +261,9 @@ H5S_point_favail (const H5S_t UNUSED *space, * Tuesday, June 16, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-03 + * The data transfer properties are passed by ID since that's + * what the virtual file layer needs. *------------------------------------------------------------------------- */ static size_t @@ -271,8 +271,8 @@ H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, void *_buf/*out*/) + H5S_sel_iter_t *file_iter, size_t nelmts, hid_t dxpl_id, + void *_buf/*out*/) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -321,9 +321,9 @@ H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, file_offset[i] += file_space->select.offset[i]; /* Go read the point */ - if (H5F_arr_read (f, xfer_parms, layout, pline, fill, efl, hsize, - hsize, zero, file_offset, buf/*out*/)<0) { - HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); + if (H5F_arr_read(f, dxpl_id, layout, pline, fill, efl, hsize, + hsize, zero, file_offset, buf/*out*/)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error"); } #ifdef QAK @@ -370,7 +370,9 @@ H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, * Tuesday, June 16, 1998 * * Modifications: - * + * Robb Matzke, 1999-08-03 + * The data transfer properties are passed by ID since that's + * what the virtual file layer needs. *------------------------------------------------------------------------- */ static herr_t @@ -378,8 +380,8 @@ H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - H5S_sel_iter_t *file_iter, size_t nelmts, - const H5F_xfer_t *xfer_parms, const void *_buf) + H5S_sel_iter_t *file_iter, size_t nelmts, hid_t dxpl_id, + const void *_buf) { hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ @@ -447,9 +449,9 @@ H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout, } #endif /* QAK */ /* Go write the point */ - if (H5F_arr_write (f, xfer_parms, layout, pline, fill, efl, hsize, - hsize, zero, file_offset, buf)<0) { - HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); + if (H5F_arr_write(f, dxpl_id, layout, pline, fill, efl, hsize, + hsize, zero, file_offset, buf)<0) { + HRETURN_ERROR(H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } /* Increment the offset of the buffer */ diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index f87d64b..9e9038f 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -20,6 +20,7 @@ /* Private headers needed by this file */ #include <H5private.h> +#include <H5Dpublic.h> #include <H5Fprivate.h> #include <H5Gprivate.h> /*for H5G_entry_t */ #include <H5Oprivate.h> @@ -196,8 +197,7 @@ typedef struct H5S_fconv_t { const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, - size_t nelmts, const struct H5F_xfer_t *xfer_parms, - void *tconv_buf/*out*/); + size_t nelmts, hid_t dxpl_id, void *tconv_buf/*out*/); /* Scatter elements from type conversion buffer to disk */ herr_t (*scat)(H5F_t *f, const struct H5O_layout_t *layout, @@ -205,8 +205,7 @@ typedef struct H5S_fconv_t { const struct H5O_fill_t *fill, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, H5S_sel_iter_t *file_iter, - size_t nelmts, const struct H5F_xfer_t *xfer_parms, - const void *tconv_buf); + size_t nelmts, hid_t dxpl_id, const void *tconv_buf); } H5S_fconv_t; typedef struct H5S_mconv_t { @@ -255,7 +254,7 @@ typedef struct H5S_conv_t { const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, void *buf/*out*/, + hid_t dxpl_id, void *buf/*out*/, hbool_t *must_convert/*out*/); @@ -264,7 +263,7 @@ typedef struct H5S_conv_t { const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, const void *buf, + hid_t dxpl_id, const void *buf, hbool_t *must_convert/*out*/); #ifdef H5S_DEBUG @@ -343,7 +342,7 @@ __DLL__ herr_t H5S_select_serialize(const H5S_t *space, uint8_t *buf); __DLL__ herr_t H5S_select_deserialize(H5S_t *space, const uint8_t *buf); __DLL__ htri_t H5S_select_contiguous(const H5S_t *space); __DLL__ herr_t H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, - H5D_operator_t op, void *operator_data); + H5D_operator_t op, void *operator_data); /* Point select functions */ __DLL__ herr_t H5S_point_add(H5S_t *space, size_t num_elemn, @@ -358,7 +357,12 @@ __DLL__ herr_t H5S_point_select_deserialize(H5S_t *space, const uint8_t *buf); __DLL__ herr_t H5S_point_bounds(H5S_t *space, hsize_t *start, hsize_t *end); __DLL__ htri_t H5S_point_select_contiguous(const H5S_t *space); __DLL__ herr_t H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, +<<<<<<< H5Sprivate.h + H5D_operator_t operator, + void *operator_data); +======= H5D_operator_t op, void *operator_data); +>>>>>>> 1.53 /* "All" select functions */ __DLL__ herr_t H5S_all_release(H5S_t *space); @@ -370,16 +374,21 @@ __DLL__ herr_t H5S_all_read(H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, void *buf/*out*/, + hid_t dxpl_id, void *buf/*out*/, hbool_t *must_convert/*out*/); __DLL__ herr_t H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout, const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, const void *buf, + hid_t dxpl_id, const void *buf, hbool_t *must_convert/*out*/); __DLL__ herr_t H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space, +<<<<<<< H5Sprivate.h + H5D_operator_t operator, + void *operator_data); +======= H5D_operator_t op, void *operator_data); +>>>>>>> 1.53 /* Hyperslab selection functions */ __DLL__ herr_t H5S_hyper_add(H5S_t *space, const hssize_t *start, @@ -409,7 +418,12 @@ __DLL__ herr_t H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, __DLL__ herr_t H5S_none_select_serialize(const H5S_t *space, uint8_t *buf); __DLL__ herr_t H5S_none_select_deserialize(H5S_t *space, const uint8_t *buf); __DLL__ herr_t H5S_none_select_iterate(void *buf, hid_t type_id, H5S_t *space, +<<<<<<< H5Sprivate.h + H5D_operator_t operator, + void *operator_data); +======= H5D_operator_t op, void *operator_data); +>>>>>>> 1.53 #ifdef HAVE_PARALLEL /* MPI-IO function to read directly from app buffer to file rky980813 */ @@ -418,8 +432,7 @@ __DLL__ herr_t H5S_mpio_spaces_read(H5F_t *f, const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, + const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/, hbool_t *must_convert /*out*/ ); @@ -429,8 +442,7 @@ __DLL__ herr_t H5S_mpio_spaces_write(H5F_t *f, const struct H5O_pline_t *pline, const struct H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space, - const H5S_t *mem_space, - const H5F_xfer_t *xfer_parms, + const H5S_t *mem_space, hid_t dxpl_id, const void *buf, hbool_t *must_convert /*out*/ ); #ifndef _H5S_IN_H5S_C @@ -462,7 +462,7 @@ H5T_init_interface(void) "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; - dt->ent.header = H5F_ADDR_UNDEF; + dt->ent.header = HADDR_UNDEF; dt->type = H5T_OPAQUE; dt->size = 1; dt->u.opaque.tag = H5MM_strdup(""); @@ -837,7 +837,7 @@ H5T_init_interface(void) "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; - dt->ent.header = H5F_ADDR_UNDEF; + dt->ent.header = HADDR_UNDEF; dt->type = H5T_STRING; dt->size = 1; dt->u.atomic.order = H5T_ORDER_NONE; @@ -863,7 +863,7 @@ H5T_init_interface(void) "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; - dt->ent.header = H5F_ADDR_UNDEF; + dt->ent.header = HADDR_UNDEF; dt->type = H5T_STRING; dt->size = 1; dt->u.atomic.order = H5T_ORDER_NONE; @@ -889,7 +889,7 @@ H5T_init_interface(void) "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; - dt->ent.header = H5F_ADDR_UNDEF; + dt->ent.header = HADDR_UNDEF; dt->type = H5T_REFERENCE; dt->size = H5R_OBJ_REF_BUF_SIZE; dt->u.atomic.order = H5T_ORDER_NONE; @@ -909,7 +909,7 @@ H5T_init_interface(void) "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; - dt->ent.header = H5F_ADDR_UNDEF; + dt->ent.header = HADDR_UNDEF; dt->type = H5T_REFERENCE; dt->size = H5R_DSET_REG_REF_BUF_SIZE; dt->u.atomic.order = H5T_ORDER_NONE; @@ -3914,7 +3914,7 @@ H5Tvlen_create(hid_t base_id) HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - dt->ent.header = H5F_ADDR_UNDEF; + dt->ent.header = HADDR_UNDEF; dt->type = H5T_VLEN; /* @@ -4410,7 +4410,7 @@ H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, /* Check args */ if (H5I_DATATYPE!=H5I_get_type(src_id) || NULL==(src=H5I_object(src_id)) || H5I_DATATYPE!=H5I_get_type(dst_id) || NULL==(dst=H5I_object(dst_id)) || - (H5P_DEFAULT != plist_id && H5P_DATASET_XFER != H5P_get_class(plist_id))) { + (H5P_DEFAULT!=plist_id && H5P_DATA_XFER!=H5P_get_class(plist_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } @@ -4580,7 +4580,7 @@ H5T_create(H5T_class_t type, size_t size) "unknown data type class"); } - dt->ent.header = H5F_ADDR_UNDEF; + dt->ent.header = HADDR_UNDEF; dt->size = size; FUNC_LEAVE(dt); } @@ -4770,7 +4770,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) */ new_dt->state = H5T_STATE_TRANSIENT; HDmemset (&(new_dt->ent), 0, sizeof(new_dt->ent)); - new_dt->ent.header = H5F_ADDR_UNDEF; + new_dt->ent.header = HADDR_UNDEF; break; case H5T_COPY_ALL: @@ -4950,7 +4950,7 @@ H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type) if (ret_value<0) { if (H5F_addr_defined(type->ent.header)) { H5O_close(&(type->ent)); - type->ent.header = H5F_ADDR_UNDEF; + type->ent.header = HADDR_UNDEF; } } FUNC_LEAVE (ret_value); @@ -7033,7 +7033,7 @@ H5T_debug(H5T_t *dt, FILE *stream) REVISION LOG --------------------------------------------------------------------------*/ H5R_type_t -H5T_get_ref_type(H5T_t *dt) +H5T_get_ref_type(const H5T_t *dt) { H5R_type_t ret_value = H5R_BADTYPE; diff --git a/src/H5Tconv.c b/src/H5Tconv.c index eaf930d..0973ec4 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -1818,7 +1818,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Get the dataset transfer property list */ if (H5P_DEFAULT == dset_xfer_plist) { xfer_parms = &H5F_xfer_dflt; - } else if (H5P_DATASET_XFER != H5P_get_class(dset_xfer_plist) || + } else if (H5P_DATA_XFER != H5P_get_class(dset_xfer_plist) || NULL == (xfer_parms = H5I_object(dset_xfer_plist))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms"); } diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index bfd59cf..e0bac81 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -545,6 +545,6 @@ __DLL__ herr_t H5T_vlen_disk_read(H5F_t *f, void *vl_addr, void *_buf, size_t le __DLL__ herr_t H5T_vlen_disk_write(const H5F_xfer_t *xfer_parms, H5F_t *f, void *vl_addr, void *_buf, hsize_t seq_len, hsize_t base_size); /* Reference specific functions */ -__DLL__ H5R_type_t H5T_get_ref_type(H5T_t *dt); +__DLL__ H5R_type_t H5T_get_ref_type(const H5T_t *dt); #endif diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 7ce7f67..a870e0b 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -21,6 +21,7 @@ /* Private headers needed by this file */ #include <H5private.h> #include <H5Gprivate.h> /*for H5G_entry_t */ +#include <H5Rprivate.h> /*for H5R_type_t */ #define H5T_RESERVED_ATOMS 8 #define H5T_NAMELEN 32 /*length of debugging name buffer */ @@ -108,5 +109,6 @@ __DLL__ herr_t H5T_enum_valueof(H5T_t *dt, const char *name, void *value/*out*/); __DLL__ herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t UNUSED ndim, hssize_t UNUSED *point, void UNUSED *_op_data); __DLL__ herr_t H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_type_t loc); +__DLL__ H5R_type_t H5T_get_ref_type(const H5T_t *dt); #endif diff --git a/src/H5detect.c b/src/H5detect.c index f5ebc30..d4cb4f0 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -434,7 +434,7 @@ H5TN_init_interface(void)\n\ \"memory allocation failed\");\n\ }\n\ dt->state = H5T_STATE_IMMUTABLE;\n\ - dt->ent.header = H5F_ADDR_UNDEF;\n\ + dt->ent.header = HADDR_UNDEF;\n\ dt->type = H5T_%s;\n\ dt->size = %d;\n\ dt->u.atomic.order = H5T_ORDER_%s;\n\ diff --git a/src/H5private.h b/src/H5private.h index 9117c2e..bd9e348 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -394,11 +394,6 @@ typedef int intn; typedef unsigned uintn; /* - * File addresses. - */ -typedef uint64_t haddr_t; - -/* * Maximum and minimum values. These should be defined in <limits.h> for the * most part. */ diff --git a/src/H5public.h b/src/H5public.h index da67b5c..a63f6cc 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -98,6 +98,26 @@ typedef size_t hsize_t; typedef ssize_t hssize_t; #endif +/* + * File addresses have there own types. + */ +#if SIZEOF_UINT64_T>=8 + typedef uint64_t haddr_t; +# define HADDR_UNDEF ((haddr_t)(int64_t)(-1)) +#elif SIZEOF_INT>=8 + typedef unsigned haddr_t; +# define HADDR_UNDEF ((haddr_t)(-1)) +#elif SIZEOF_LONG>=8 + typedef unsigned long haddr_t; +# define HADDR_UNDEF ((haddr_t)(long)(-1)) +#elif SIZEOF_LONG_LONG>=8 + typedef unsigned long long haddr_t; +# define HADDR_UNDEF ((haddr_t)(long long)(-1)) +#else +# error "nothing appropriate for haddr_t" +#endif +#define HADDR_MAX (HADDR_UNDEF-1) + #ifdef __cplusplus extern "C" { #endif diff --git a/src/Makefile.in b/src/Makefile.in index 15d5172..ec675a1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -21,14 +21,13 @@ LIB=libhdf5.la 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 H5Fcore.c \ - H5Ffamily.c H5Fistore.c H5Flow.c H5Fmpio.c H5Fsec2.c H5Fsplit.c \ - H5Fstdio.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_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 LIB_OBJ=$(LIB_SRC:.c=.lo) @@ -37,17 +36,17 @@ 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 H5Gpublic.h H5HGpublic.h H5HLpublic.h \ - H5Ipublic.h H5MFpublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h \ - H5Rpublic.h H5RApublic.h H5Spublic.h H5Tpublic.h H5Zpublic.h H5config.h \ - hdf5.h H5api_adpt.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 ## Other header files (not to be installed)... PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ - H5Dprivate.h H5Eprivate.h H5Fprivate.h H5Gprivate.h H5Gpkg.h \ - H5HGprivate.h H5HLprivate.h H5Iprivate.h H5MFprivate.h H5MMprivate.h \ - H5Oprivate.h H5Pprivate.h H5Rprivate.h H5RAprivate.h H5Sprivate.h \ - H5Tprivate.h H5TBprivate.h H5Tpkg.h H5Vprivate.h H5Zprivate.h + H5Dprivate.h H5Eprivate.h H5Fprivate.h H5FDprivate.h H5Gprivate.h \ + H5Gpkg.h H5HGprivate.h H5HLprivate.h H5Iprivate.h H5MFprivate.h \ + H5MMprivate.h H5Oprivate.h H5Pprivate.h H5Rprivate.h H5RAprivate.h \ + H5Sprivate.h H5Tprivate.h H5TBprivate.h H5Tpkg.h H5Vprivate.h H5Zprivate.h ## Number format detection H5Tinit.c: H5detect @@ -19,24 +19,30 @@ #define _HDF5_H #include <H5public.h> -#include <H5Ipublic.h> /* IDs (this has to come near the top, to define hid_t) */ -#include <H5Apublic.h> /* Attributes */ -#include <H5ACpublic.h> /* Metadata cache */ -#include <H5Bpublic.h> /* B-trees */ -#include <H5Dpublic.h> /* Datasets */ -#include <H5Epublic.h> /* Errors */ -#include <H5Fpublic.h> /* Files */ -#include <H5Gpublic.h> /* Groups */ -#include <H5HGpublic.h> /* Global heaps */ -#include <H5HLpublic.h> /* Local heaps */ -#include <H5MFpublic.h> /* File memory management */ -#include <H5MMpublic.h> /* Core memory management */ -#include <H5Opublic.h> /* Object headers */ -#include <H5Ppublic.h> /* Property lists */ -#include <H5Rpublic.h> /* References */ -#include <H5RApublic.h> /* Ragged arrays */ -#include <H5Spublic.h> /* Dataspaces */ -#include <H5Tpublic.h> /* Datatypes */ -#include <H5Zpublic.h> /* Data filters */ +#include <H5Ipublic.h> /* Interface abstraction */ +#include <H5Apublic.h> /* Attributes */ +#include <H5ACpublic.h> /* Metadata cache */ +#include <H5Bpublic.h> /* B-trees */ +#include <H5Dpublic.h> /* Datasets */ +#include <H5Epublic.h> /* Errors */ +#include <H5Fpublic.h> /* Files */ +#include <H5FDpublic.h> /* File drivers */ +#include <H5Gpublic.h> /* Groups */ +#include <H5HGpublic.h> /* Global heaps */ +#include <H5HLpublic.h> /* Local heaps */ +#include <H5MMpublic.h> /* Memory management */ +#include <H5Opublic.h> /* Object headers */ +#include <H5Ppublic.h> /* Property lists */ +#include <H5Rpublic.h> /* References */ +#include <H5RApublic.h> /* Ragged arrays */ +#include <H5Spublic.h> /* Dataspaces */ +#include <H5Tpublic.h> /* Datatypes */ +#include <H5Zpublic.h> /* Data filters */ + +/* Predefined file drivers */ +#include <H5FDcore.h> /* Files stored entirely in memory */ +#include <H5FDfamily.h> /* File families */ +#include <H5FDmpio.h> /* Parallel files using MPI-2 I/O */ +#include <H5FDsec2.h> /* POSIX unbuffered file I/O */ #endif |