summaryrefslogtreecommitdiffstats
path: root/src/H5F.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1999-08-10 20:21:32 (GMT)
committerRobb Matzke <matzke@llnl.gov>1999-08-10 20:21:32 (GMT)
commitcbf68fc824f69dcdc0fcd38a83a3fee8c7093c28 (patch)
treeb7075c9f11db1b343593b5e0619a285ccc8418af /src/H5F.c
parent7d949c9da91b33955d4e253c1093a4f23fb63523 (diff)
downloadhdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.zip
hdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.tar.gz
hdf5-cbf68fc824f69dcdc0fcd38a83a3fee8c7093c28.tar.bz2
[svn-r1568] Changes since 19990730
---------------------- This extensive change is the virtual file layer implementation. I've ported and tested the sec2, family, and core drivers and only ported the mpio driver (Albert will test it). So if you need MPIO I would recommend sticking with the previous version for a while. You will get a few compile warnings about split and stdio drivers not being implemented and possibly tracing information not inserted in some of the drivers. You can safely ignore them but I plan to fix them. I'm still working on the split driver because I just realized that it needs a part of the VFL that isn't written yet. Documentation is being updated also because there were some minor changes (mostly just name changes). It should be available on my web site later this week. ./MANIFEST ./src/Makefile.in ./src/hdf5.h ./src/H5Flow.c [REMOVED] ./src/H5Fstdio.c [REMOVED] ./src/H5Fsec2.c [REMOVED] ./src/H5Fsplit.c [REMOVED] ./src/H5Fmpio.c [REMOVED] ./src/H5Ffamily.c [REMOVED] ./src/H5Fcore.c [REMOVED] ./src/H5MFpublic.h [REMOVED] ./src/H5FD.c [NEW] ./src/H5FDcore.c [NEW] ./src/H5FDcore.h [NEW] ./src/H5FDfamily.c [NEW] ./src/H5FDfamily.h [NEW] ./src/H5FDmpio.c [NEW] ./src/H5FDmpio.h [NEW] ./src/H5FDprivate.h [NEW] ./src/H5FDpublic.h [NEW] ./src/H5FDsec2.c [NEW] ./src/H5FDsec2.h [NEW] Removed/added files for virtual file layer. ./bin/trace ./src/H5.c Removed unused public datatypes and added new VFL public datatypes. Changed an error message. ./config/BlankForm ./config/dec-flags ./config/gnu-flags ./config/hpux10.20 ./config/hpux9.03 ./config/irix5.x ./config/irix6.x ./config/solaris2.x ./config/unicosmk Removed the H5F_OPT_SEEK and H5F_LOW_DFLT constants from the configuration since they're no longer applicable. The default file driver is always the sec2 driver and it always optimizes calls to lseek() or lseek64(). ./config/depend.in C preprocessor errors generated during automatic dependency building are sent to /dev/null to prevent them from appearing twice in the make output. ./src/H5AC.c ./src/H5B.c ./src/H5D.c ./src/H5F.c ./src/H5G.c ./src/H5Gent.c ./src/H5Gnode.c ./src/H5HG.c ./src/H5HL.c ./src/H5O.c ./src/H5Oattr.c ./src/H5Odtype.c ./src/H5Oefl.c ./src/H5Oshared.c ./src/H5T.c ./src/H5detect.c ./test/ohdr.c Changed H5F_ADDR_UNDEF to HADDR_UNDEF to be more consistent with the `haddr_t' datatype which is now a public type. ./src/H5D.c ./src/H5P.c ./src/H5Ppublic.h ./src/H5Tconv.c ./test/cmpd_dset.c ./test/dsets.c ./test/overhead.c ./test/tselect.c ./test/tvltypes.c The H5P_DATASET_XFER constant was changed to H5P_DATA_XFER because the properties apply to all types of I/O operations, not just datasets. ./src/H5B.c ./src/H5Bprivate.h ./src/H5D.c ./src/H5Dpublic.h ./src/H5F.c ./src/H5Farray.c ./src/H5Fistore.c ./src/H5Fprivate.h ./src/H5Fpublic.h ./src/H5Gnode.c ./src/H5Gpkg.h ./src/H5HG.c ./src/H5HL.c ./src/H5O.c ./src/H5R.c ./src/H5Sall.c ./src/H5Shyper.c ./src/H5Smpio.c ./src/H5Spoint.c ./src/H5Sprivate.h ./test/big.c ./test/h5test.c ./test/istore.c ./testpar/t_dset.c ./testpar/t_file.c ./tools/h5debug.c ./tools/h5ls.c Modified to work with the virtual file layer by calling H5FD_* functions instead of H5F_low_* functions and by passing file access and data transfer properties by object ID instead of pointer. Changed H5D_transfer_t to H5FD_mpio_xfer_t since the COLLECTIVE vs. INDEPENDENT transfer mode is specific to the MPIO file driver. Moved MPIO-specific stuff into the MPIO driver. ./src/H5B.c ./src/H5D.c ./src/H5Fprivate.h The H5F_mpio_* private functions were renamed and placed in the H5FDmpio driver except those which appeared in H5Smpio.c. ./src/H5E.c ./src/H5Epublic.h Added major error number H5E_VFL for virtual file layer related errors. ./src/H5F.c ./src/H5Fprivate.h Changed the logic that controls whether the boot block is written. Instead of assuming that the first call to write the boot block is only to allocate space, I've added a function argument which makes this explicit. Changed the way files are compared so that a driver-defined comparison function can be called. Files which belong to different drivers are always considered different. Removed H5F_driver_t since file drivers are now identified by object ID instead of a special non-user-extendible datatype. Removed all the hard-coded low-level file properties which have been replaced by the various file drivers. ./src/H5I.c ./src/H5Iprivate.h Added the H5I_inc_ref() which was removed a few months ago since we finally have a use for it. ./src/H5Ipublic.h Added the H5I_VFL object ID type to identify file drivers in the virtual file layer. ./src/H5MF.c ./src/H5MFprivate.h Moved all the allocation/deallocation code into the virtual file layer which allows file drivers to override much of it. ./src/H5P.c ./src/H5Ppublic.h Moved file driver-specific code into the various file driver files. The H5Pcopy() and H5Pclose() functions make calls into the virtual file driver to manage the memory for driver-specific file access and data transfer properties. ./src/H5private.h ./src/H5public.h The `haddr_t' type is now public. ./test/tfile.c Added a few more comments.
Diffstat (limited to 'src/H5F.c')
-rw-r--r--src/H5F.c1343
1 files changed, 670 insertions, 673 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 48c0114..0aacbd4 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -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);
}