diff options
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 |