summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST1
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5B.c2
-rw-r--r--src/H5Bprivate.h2
-rw-r--r--src/H5F.c16
-rw-r--r--src/H5Fpkg.h6
-rw-r--r--src/H5Fsuper.c20
-rw-r--r--src/H5Ftest.c40
-rw-r--r--src/H5G.c165
-rw-r--r--src/H5Gobj.c109
-rw-r--r--src/H5Gpkg.h7
-rw-r--r--src/H5Gprivate.h8
-rw-r--r--src/H5Groot.c344
-rw-r--r--src/H5Gtest.c56
-rwxr-xr-xsrc/Makefile.am2
-rw-r--r--src/Makefile.in9
-rw-r--r--test/family_v16_00000.h5bin5120 -> 5120 bytes
-rwxr-xr-xtest/objcopy.c25
-rw-r--r--test/tfile.c65
19 files changed, 552 insertions, 328 deletions
diff --git a/MANIFEST b/MANIFEST
index 051c034..f475808 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -582,6 +582,7 @@
./src/H5Gpkg.h
./src/H5Gprivate.h
./src/H5Gpublic.h
+./src/H5Groot.c
./src/H5Gstab.c
./src/H5Gtest.c
./src/H5Gtraverse.c
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 2a6d4e6..77f0ae3 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -142,6 +142,9 @@ Bug Fixes since HDF5-1.8.0 release
Library
-------
+ - Modified library to write cached symbol table information to the
+ superblock, to allow library versions 1.3.0 to 1.6.3 to read files
+ created by this version. (NAF - 2009/04/08)
- Changed skip lists to use a deterministic algorithm. The library should
now never call rand() or srand(). (NAF - 2009/04/08 - 503)
- Fixed a bug where H5Lcopy and H5Lmove wouldn't create intermediate
diff --git a/src/H5B.c b/src/H5B.c
index c504507..aba62b0 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -2057,7 +2057,6 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_get_info() */
-#ifndef H5_STRICT_FORMAT_CHECKS
/*-------------------------------------------------------------------------
* Function: H5B_valid
@@ -2099,5 +2098,4 @@ H5B_valid(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr)
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B_valid() */
-#endif /* H5_STRICT_FORMAT_CHECKS */
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 2ec2c22..716b608 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -168,9 +168,7 @@ H5_DLL H5B_shared_t *H5B_shared_new(const H5F_t *f, const H5B_class_t *type,
H5_DLL herr_t H5B_shared_free(void *_shared);
H5_DLL herr_t H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, const H5B_class_t *type, void *udata);
-#ifndef H5_STRICT_FORMAT_CHECKS
H5_DLL htri_t H5B_valid(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type,
haddr_t addr);
-#endif /* H5_STRICT_FORMAT_CHECKS */
#endif /* _H5Bprivate_H */
diff --git a/src/H5F.c b/src/H5F.c
index 921fe27..fc85688 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -893,6 +893,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
f->shared->driver_addr = HADDR_UNDEF;
f->shared->accum.loc = HADDR_UNDEF;
f->shared->lf = lf;
+ f->shared->root_addr = HADDR_UNDEF;
/*
* Copy the file creation and file access property lists into the
@@ -1369,7 +1370,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
/* (This must be after the space for the superblock is allocated in
* the file, since the superblock must be at offset 0)
*/
- if(H5G_mkroot(file, dxpl_id, NULL) < 0)
+ if(H5G_mkroot(file, dxpl_id, TRUE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group")
/* Write the superblock to the file */
@@ -1379,21 +1380,12 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
if(H5F_super_write(file, dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to write file superblock")
} else if (1 == shared->nrefs) {
- H5G_loc_t root_loc; /*root location */
- H5O_loc_t root_oloc; /*root object location */
- H5G_name_t root_path; /*root group hier. path */
-
- /* Set up root location to fill in */
- root_loc.oloc = &root_oloc;
- root_loc.path = &root_path;
- H5G_loc_reset(&root_loc);
-
/* Read the superblock if it hasn't been read before. */
- if(H5F_super_read(file, dxpl_id, &root_loc) < 0)
+ if(H5F_super_read(file, dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")
/* Open the root group */
- if(H5G_mkroot(file, dxpl_id, &root_loc) < 0)
+ if(H5G_mkroot(file, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group")
} /* end if */
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 4080705..49af73e 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -158,7 +158,8 @@ typedef struct H5F_file_t {
int ncwfs; /* Num entries on cwfs list */
struct H5HG_heap_t **cwfs; /* Global heap cache */
struct H5G_t *root_grp; /* Open root group */
- H5G_entry_t *root_ent; /* Root group symbol table entry */
+ H5G_entry_t *root_ent; /* Root group symbol table entry */
+ haddr_t root_addr; /* Root group address */
H5FO_t *open_objs; /* Open objects in file */
H5RC_t *grp_btree_shared; /* Ref-counted group B-tree node info */
@@ -225,7 +226,7 @@ H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nop
/* Superblock related routines */
H5_DLL herr_t H5F_super_init(H5F_t *f, hid_t dxpl_id);
H5_DLL herr_t H5F_super_write(H5F_t *f, hid_t dxpl_id);
-H5_DLL herr_t H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc);
+H5_DLL herr_t H5F_super_read(H5F_t *f, hid_t dxpl_id);
H5_DLL herr_t H5F_super_ext_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_ext_info);
/* Metadata accumulator routines */
@@ -247,6 +248,7 @@ H5_DLL herr_t H5F_sfile_remove(H5F_file_t *shared);
#ifdef H5F_TESTING
H5_DLL herr_t H5F_get_sohm_mesg_count_test(hid_t fid, unsigned type_id,
size_t *mesg_count);
+H5_DLL herr_t H5F_check_cached_stab_test(hid_t file_id);
#endif /* H5F_TESTING */
#endif /* _H5Fpkg_H */
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index 8040554..32541ae 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -32,6 +32,7 @@
#include "H5FDprivate.h" /* File drivers */
#include "H5Iprivate.h" /* IDs */
#include "H5MFprivate.h" /* File memory management */
+#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
#include "H5SMprivate.h" /* Shared Object Header Messages */
@@ -230,7 +231,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
+H5F_super_read(H5F_t *f, hid_t dxpl_id)
{
uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* Buffer for superblock */
H5P_genplist_t *c_plist; /* File creation property list */
@@ -383,8 +384,9 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
H5F_addr_decode(f, (const uint8_t **)&p, &shared->extension_addr/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &shared->driver_addr/*out*/);
- if(H5G_obj_ent_decode(f, (const uint8_t **)&p, root_loc->oloc/*out*/,
- &shared->root_ent/*out*/) < 0)
+
+ /* Decode the symbol table entry */
+ if(H5G_root_ent_decode(f, (const uint8_t **)&p) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root symbol entry")
/*
@@ -468,7 +470,6 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
} /* end if */
} /* end if */
else {
- haddr_t root_addr; /* Address of root group */
uint32_t computed_chksum; /* Computed checksum */
uint32_t read_chksum; /* Checksum read from file */
@@ -499,7 +500,7 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &shared->extension_addr/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
- H5F_addr_decode(f, (const uint8_t **)&p, &root_addr/*out*/);
+ H5F_addr_decode(f, (const uint8_t **)&p, &shared->root_addr/*out*/);
/* Compute checksum for superblock */
computed_chksum = H5_checksum_metadata(sbuf, (size_t)(p - sbuf), 0);
@@ -511,11 +512,6 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
if(read_chksum != computed_chksum)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad checksum on driver information block")
- /* Create root group object location */
- H5O_loc_reset(root_loc->oloc);
- root_loc->oloc->file = f;
- root_loc->oloc->addr = root_addr;
-
/*
* Check if superblock address is different from base address and
* adjust base address and "end of address" address if so.
@@ -930,7 +926,9 @@ H5F_super_write(H5F_t *f, hid_t dxpl_id)
rel_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER);
H5F_addr_encode(f, &p, (rel_eoa + f->shared->base_addr));
H5F_addr_encode(f, &p, f->shared->driver_addr);
- if(H5G_obj_ent_encode(f, &p, H5G_oloc(f->shared->root_grp)) < 0)
+
+ /* Encode the root group object entry, including the cached stab info */
+ if(H5G_root_ent_encode(f, &p) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode root group information")
/* Encode the driver information block. */
diff --git a/src/H5Ftest.c b/src/H5Ftest.c
index 1d7e514..8cbc133 100644
--- a/src/H5Ftest.c
+++ b/src/H5Ftest.c
@@ -32,6 +32,8 @@
#define H5F_TESTING /*suppress warning about H5F testing funcs*/
#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
#define H5SM_TESTING /*suppress warning about H5SM testing funcs*/
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+#define H5G_TESTING /*suppress warning about H5G testing funcs*/
/***********/
@@ -40,6 +42,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
+#include "H5Gpkg.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
#include "H5SMpkg.h" /* Shared object header messages */
@@ -113,3 +116,40 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_get_sohm_mesg_count_test() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_check_cached_stab_test
+ *
+ * Purpose: Check that a file's superblock contains a cached symbol
+ * table entry, that the entry matches that in the root
+ * group's object header, and check that the addresses are
+ * valid.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Mar 31, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_check_cached_stab_test(hid_t file_id)
+{
+ H5F_t *file; /* File info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5F_check_cached_stab_test)
+
+ /* Check arguments */
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+
+ /* Verify the cached stab info */
+ if(H5G_verify_cached_stab_test(H5G_oloc(file->shared->root_grp), file->shared->root_ent) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to verify cached symbol table info")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_check_cached_stab_test() */
+
diff --git a/src/H5G.c b/src/H5G.c
index 56e6c6a..2afd837 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -817,141 +817,6 @@ H5G_term_interface(void)
/*-------------------------------------------------------------------------
- * Function: H5G_mkroot
- *
- * Purpose: Creates a root group in an empty file and opens it. If a
- * root group is already open then this function immediately
- * returns. If ENT is non-null then it's the symbol table
- * entry for an existing group which will be opened as the root
- * group. Otherwise a new root group is created and then
- * opened.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 11 1997
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc)
-{
- H5O_loc_t new_root_oloc; /* New root object location */
- H5G_name_t new_root_path; /* New root path */
- H5G_loc_t new_root_loc; /* New root location information */
- H5G_loc_t root_loc; /* Root location information */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_mkroot, FAIL)
-
- /* check args */
- HDassert(f);
-
- /* Check if the root group is already initialized */
- if(f->shared->root_grp)
- HGOTO_DONE(SUCCEED)
-
- /* Create information needed for group nodes */
- if(H5G_node_init(f) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info")
-
- /*
- * If there is no root object then create one. The root group always starts
- * with a hard link count of one since it's pointed to by the superblock.
- */
- if(loc == NULL) {
- H5P_genplist_t *fc_plist; /* File creation property list */
- H5O_ginfo_t ginfo; /* Group info parameters */
- H5O_linfo_t linfo; /* Link info parameters */
-
- /* Get the file creation property list */
- /* (Which is a sub-class of the group creation property class) */
- if(NULL == (fc_plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
-
- /* Get the group info property */
- if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info")
-
- /* Get the link info property */
- if(H5P_get(fc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info")
-
- /* Set up group location for root group */
- new_root_loc.oloc = &new_root_oloc;
- new_root_loc.path = &new_root_path;
- H5G_loc_reset(&new_root_loc);
- loc = &new_root_loc;
-
- /* Create root group */
- if(H5G_obj_create(f, dxpl_id, &ginfo, &linfo, f->shared->fcpl_id, loc->oloc/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
- if(1 != H5O_link(loc->oloc, 1, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)")
- } /* end if */
- else {
- /*
- * Open the root object as a group.
- */
- if(H5O_open(loc->oloc) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group")
-
-#ifndef H5_STRICT_FORMAT_CHECKS
- /* If symbol table information is cached, check if we should replace the
- * symbol table message with the cached symbol table information */
- if((H5F_INTENT(f) & H5F_ACC_RDWR) && f->shared->root_ent
- && (f->shared->root_ent->type == H5G_CACHED_STAB)) {
- H5O_stab_t cached_stab;
-
- /* Retrieve the cached symbol table information */
- cached_stab.btree_addr = f->shared->root_ent->cache.stab.btree_addr;
- cached_stab.heap_addr = f->shared->root_ent->cache.stab.heap_addr;
-
- /* Check if the symbol table message is valid, and replace with the
- * cached symbol table if necessary */
- if(H5G_stab_valid(loc->oloc, dxpl_id, &cached_stab) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to verify symbol table")
- } /* end if */
-#endif /* H5_STRICT_FORMAT_CHECKS */
- } /* end else */
-
- /* Create the path names for the root group's entry */
- H5G_name_init(loc->path, "/");
-
- /*
- * Create the group pointer. Also decrement the open object count so we
- * don't count the root group as an open object. The root group will
- * never be closed.
- */
- if(NULL == (f->shared->root_grp = H5FL_CALLOC(H5G_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- if(NULL == (f->shared->root_grp->shared = H5FL_CALLOC(H5G_shared_t))) {
- (void)H5FL_FREE(H5G_t, f->shared->root_grp);
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- } /* end if */
-
- /* Shallow copy (take ownership) of the group object info */
- root_loc.oloc = &(f->shared->root_grp->oloc);
- root_loc.path = &(f->shared->root_grp->path);
- if(H5G_loc_copy(&root_loc, loc, H5_COPY_SHALLOW) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy group object location")
-
- f->shared->root_grp->shared->fo_count = 1;
- /* The only other open object should be the superblock extension, if it
- * exists. Don't count either the superblock extension or the root group
- * in the number of open objects in the file.
- */
- HDassert((1 == f->nopen_objs) ||
- (2 == f->nopen_objs && HADDR_UNDEF != f->shared->extension_addr));
- f->nopen_objs--;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_mkroot() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_create
*
* Purpose: Creates a new empty group with the specified name. The name
@@ -1351,36 +1216,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_rootof
- *
- * Purpose: Return a pointer to the root group of the file. If the file
- * is part of a virtual file then the root group of the virtual
- * file is returned.
- *
- * Return: Success: Ptr to the root group of the file. Do not
- * free the pointer -- it points directly into
- * the file struct.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Tuesday, October 13, 1998
- *
- *-------------------------------------------------------------------------
- */
-H5G_t *
-H5G_rootof(H5F_t *f)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof)
-
- while(f->parent)
- f = f->parent;
-
- FUNC_LEAVE_NOAPI(f->shared->root_grp)
-} /* end H5G_rootof() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_oloc
*
* Purpose: Returns a pointer to the object location for a group.
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index 2eb1924..08a9268 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -221,115 +221,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_obj_ent_decode
- *
- * Purpose: Decodes a symbol table entry into a object location
- *
- * Return: Success: Non-negative with *pp pointing to the first byte
- * following the symbol table entry.
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Sep 26 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp, H5O_loc_t *oloc, H5G_entry_t **entp)
-{
- const uint8_t *p_ret = *pp;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_obj_ent_decode, FAIL)
-
- /* check arguments */
- HDassert(f);
- HDassert(pp);
- HDassert(oloc);
-
- if(entp) {
- /* If entp is not NULL we allocate space for the symbol table entry and
- * decode the entire entry. */
- if(!(*entp)) /* Only allocate space if *entp is NULL */
- if(NULL == (*entp = (H5G_entry_t *) H5MM_calloc(sizeof(H5G_entry_t))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry")
- if(H5G_ent_decode_vec(f, pp, *entp, 1) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode symbol table entry")
-
- /* Set oloc to the correct values */
- oloc->file = (*entp)->file;
- oloc->addr = (*entp)->header;
- } else {
- /* Set file pointer for root object location */
- oloc->file = f;
-
- /* decode header */
- *pp += H5F_SIZEOF_SIZE(f); /* Skip over local heap address */
- H5F_addr_decode(f, pp, &(oloc->addr));
- *pp += 4; /* Skip over "cache type" */
- *pp += 4; /* Reserved */
- }
-
- /* Common oloc settings */
- oloc->holding_file = FALSE;
-
- /* Set decode pointer */
- *pp = p_ret + H5G_SIZEOF_ENTRY(f);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_obj_ent_decode() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_obj_ent_encode
- *
- * Purpose: Encodes the specified object location into a symbol table
- * entry in the buffer pointed to by *pp.
- *
- * Return: Success: Non-negative, with *pp pointing to the first byte
- * after the symbol table entry.
- *
- * Failure: Negative
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Sep 26 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp, const H5O_loc_t *oloc)
-{
- uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
-
- FUNC_ENTER_NOAPI_NOFUNC(H5G_obj_ent_encode)
-
- /* check arguments */
- HDassert(f);
- HDassert(pp);
-
- /* encode header */
- H5F_ENCODE_LENGTH(f, *pp, 0); /* No name for root group */
- if(oloc)
- H5F_addr_encode(f, pp, oloc->addr);
- else
- H5F_addr_encode(f, pp, HADDR_UNDEF);
- UINT32ENCODE(*pp, H5G_NOTHING_CACHED);
- UINT32ENCODE(*pp, 0); /*reserved*/
-
- /* fill with zero */
- while(*pp < p_ret)
- *(*pp)++ = 0;
- *pp = p_ret;
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5G_obj_ent_encode() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_obj_get_linfo
*
* Purpose: Retrieves the "link info" message for an object. Also
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index 38c7628..0840ee7 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -340,6 +340,12 @@ H5_DLLVAR const H5B2_class_t H5G_BT2_NAME[1];
/* The v2 B-tree class for indexing 'creation order' field on links */
H5_DLLVAR const H5B2_class_t H5G_BT2_CORDER[1];
+/* Free list for managing H5G_t structs */
+H5FL_EXTERN(H5G_t);
+
+/* Free list for managing H5G_shared_t structs */
+H5FL_EXTERN(H5G_shared_t);
+
/******************************/
/* Package Private Prototypes */
/******************************/
@@ -565,6 +571,7 @@ H5_DLL htri_t H5G_is_new_dense_test(hid_t gid);
H5_DLL herr_t H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count);
H5_DLL herr_t H5G_lheap_size_test(hid_t gid, size_t *lheap_size);
H5_DLL herr_t H5G_user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsigned *user_path_hidden);
+H5_DLL herr_t H5G_verify_cached_stab_test(H5O_loc_t *grp_oloc, H5G_entry_t *ent);
#endif /* H5G_TESTING */
#endif /* _H5Gpkg_H */
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index b1db96f..7f001e0 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -151,7 +151,7 @@ typedef struct H5G_entry_t H5G_entry_t;
* Library prototypes... These are the ones that other packages routinely
* call.
*/
-H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc);
+H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root);
H5_DLL struct H5O_loc_t *H5G_oloc(H5G_t *grp);
H5_DLL H5G_t *H5G_rootof(H5F_t *f);
H5_DLL H5G_name_t * H5G_nameof(H5G_t *grp);
@@ -181,10 +181,8 @@ H5_DLL herr_t H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream
/*
* These functions operate on group object locations.
*/
-H5_DLL herr_t H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp,
- struct H5O_loc_t *oloc, H5G_entry_t **entp);
-H5_DLL herr_t H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp,
- const struct H5O_loc_t *oloc);
+H5_DLL herr_t H5G_root_ent_decode(H5F_t *f, const uint8_t **pp);
+H5_DLL herr_t H5G_root_ent_encode(H5F_t *f, uint8_t **pp);
/*
* These functions operate on group hierarchy names.
diff --git a/src/H5Groot.c b/src/H5Groot.c
new file mode 100644
index 0000000..4c7c357
--- /dev/null
+++ b/src/H5Groot.c
@@ -0,0 +1,344 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+ /*-------------------------------------------------------------------------
+ *
+ * Created: H5Gobj.c
+ * Apr 8 2009
+ * Neil Fortner <nfortne2@hdfgroup.org>
+ *
+ * Purpose: Functions for operating on the root group.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5Gpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property Lists */
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_rootof
+ *
+ * Purpose: Return a pointer to the root group of the file. If the file
+ * is part of a virtual file then the root group of the virtual
+ * file is returned.
+ *
+ * Return: Success: Ptr to the root group of the file. Do not
+ * free the pointer -- it points directly into
+ * the file struct.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 13, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_t *
+H5G_rootof(H5F_t *f)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof)
+
+ while(f->parent)
+ f = f->parent;
+
+ FUNC_LEAVE_NOAPI(f->shared->root_grp)
+} /* end H5G_rootof() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_root_ent_decode
+ *
+ * Purpose: Decodes the root group symbol table entry into the file
+ * structure, and updates the root group address in the file
+ * structure.
+ *
+ * Return: Success: Non-negative with *pp pointing to the first byte
+ * following the symbol table entry.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_root_ent_decode(H5F_t *f, const uint8_t **pp)
+{
+ const uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_root_ent_decode, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(pp);
+
+ /* Allocate space for the root group symbol table entry */
+ HDassert(!f->shared->root_ent);
+ if(NULL == (f->shared->root_ent = (H5G_entry_t *) H5MM_calloc(sizeof(H5G_entry_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry")
+
+ /* decode the root group symbol table entry */
+ if(H5G_ent_decode_vec(f, pp, f->shared->root_ent, 1) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode symbol table entry")
+
+ /* Set the root group address to the correct value */
+ f->shared->root_addr = f->shared->root_ent->header;
+
+ /* Set decode pointer */
+ *pp = p_ret;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_root_ent_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_root_ent_encode
+ *
+ * Purpose: Encodes the root group symbol table entry into the buffer
+ * pointed to by *pp.
+ *
+ * Return: Success: Non-negative, with *pp pointing to the first byte
+ * after the symbol table entry.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_root_ent_encode(H5F_t *f, uint8_t **pp)
+{
+ uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_root_ent_encode, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(f->shared);
+ HDassert(f->shared->root_ent);
+ HDassert(pp);
+
+ /* Encode entry */
+ if(H5G_ent_encode_vec(f, pp, f->shared->root_ent, 1) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't encode symbol table entry")
+
+ /* Set encode pointer */
+ *pp = p_ret;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_root_ent_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_mkroot
+ *
+ * Purpose: Creates a root group in an empty file and opens it. If a
+ * root group is already open then this function immediately
+ * returns. If ENT is non-null then it's the symbol table
+ * entry for an existing group which will be opened as the root
+ * group. Otherwise a new root group is created and then
+ * opened.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 11 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root)
+{
+ H5G_loc_t root_loc; /* Root location information */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_mkroot, FAIL)
+
+ /* check args */
+ HDassert(f);
+
+ /* Check if the root group is already initialized */
+ if(f->shared->root_grp)
+ HGOTO_DONE(SUCCEED)
+
+ /* Create information needed for group nodes */
+ if(H5G_node_init(f) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info")
+
+ /*
+ * Create the group pointer
+ */
+ if(NULL == (f->shared->root_grp = H5FL_CALLOC(H5G_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (f->shared->root_grp->shared = H5FL_CALLOC(H5G_shared_t))) {
+ (void)H5FL_FREE(H5G_t, f->shared->root_grp);
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ } /* end if */
+
+ /* Initialize the root_loc structure to point to fields in the newly created
+ * f->shared->root_grp structure */
+ root_loc.oloc = &(f->shared->root_grp->oloc);
+ root_loc.path = &(f->shared->root_grp->path);
+ H5G_loc_reset(&root_loc);
+
+ /*
+ * If there is no root object then create one. The root group always starts
+ * with a hard link count of one since it's pointed to by the superblock.
+ */
+ if(create_root) {
+ H5P_genplist_t *fc_plist; /* File creation property list */
+ H5O_ginfo_t ginfo; /* Group info parameters */
+ H5O_linfo_t linfo; /* Link info parameters */
+ unsigned super_vers; /* Superblock version */
+
+ /* Get the file creation property list */
+ /* (Which is a sub-class of the group creation property class) */
+ if(NULL == (fc_plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+
+ /* Get the group info property */
+ if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info")
+
+ /* Get the link info property */
+ if(H5P_get(fc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info")
+
+ /* Get the superblock version */
+ if(H5P_get(fc_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get superblock version")
+
+ /* Create root group */
+ if(H5G_obj_create(f, dxpl_id, &ginfo, &linfo, f->shared->fcpl_id, root_loc.oloc/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
+ if(1 != H5O_link(root_loc.oloc, 1, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)")
+
+ /* Create the root group symbol table entry */
+ HDassert(!f->shared->root_ent);
+ if(super_vers < HDF5_SUPERBLOCK_VERSION_2) {
+ /* Allocate space for the root group symbol table entry */
+ if(NULL == (f->shared->root_ent = (H5G_entry_t *) H5MM_calloc(sizeof(H5G_entry_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry")
+
+ /* Initialize the root group symbol table entry */
+ f->shared->root_ent->dirty = TRUE;
+ f->shared->root_ent->type = H5G_NOTHING_CACHED; /* We will cache the stab later */
+ f->shared->root_ent->name_off = 0; /* No name (yet) */
+ f->shared->root_ent->header = root_loc.oloc->addr;
+ f->shared->root_ent->file = root_loc.oloc->file;
+ } /* end if */
+ } /* end if */
+ else {
+ /* Create root group object location from f */
+ root_loc.oloc->addr = f->shared->root_addr;
+ root_loc.oloc->file = f;
+
+ /*
+ * Open the root object as a group.
+ */
+ if(H5O_open(root_loc.oloc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group")
+
+#ifndef H5_STRICT_FORMAT_CHECKS
+ /* If symbol table information is cached, check if we should replace the
+ * symbol table message with the cached symbol table information */
+ if((H5F_INTENT(f) & H5F_ACC_RDWR) && f->shared->root_ent
+ && (f->shared->root_ent->type == H5G_CACHED_STAB)) {
+ H5O_stab_t cached_stab;
+
+ /* Retrieve the cached symbol table information */
+ cached_stab.btree_addr = f->shared->root_ent->cache.stab.btree_addr;
+ cached_stab.heap_addr = f->shared->root_ent->cache.stab.heap_addr;
+
+ /* Check if the symbol table message is valid, and replace with the
+ * cached symbol table if necessary */
+ if(H5G_stab_valid(root_loc.oloc, dxpl_id, &cached_stab) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to verify symbol table")
+ } /* end if */
+#endif /* H5_STRICT_FORMAT_CHECKS */
+ } /* end else */
+
+ /* Cache the root group's symbol table information in the root group symbol
+ * table entry. It will have been allocated by now if it needs to be
+ * present, so we don't need to check the superblock version. We do this if
+ * we have write access, the root entry has been allocated (i.e.
+ * super_vers < 2) and the stab info is not already cached. */
+ if((H5F_INTENT(f) & H5F_ACC_RDWR) && f->shared->root_ent
+ && f->shared->root_ent->type != H5G_CACHED_STAB) {
+ htri_t stab_exists; /* Whether the symbol table exists */
+ H5O_stab_t stab; /* Symbol table */
+
+ /* Check if the stab message exists. It's possible for the root group
+ * to use the latest version while the superblock is an old version. */
+ if((stab_exists = H5O_msg_exists(root_loc.oloc, H5O_STAB_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check if symbol table message exists")
+
+ if(stab_exists) {
+ /* Read the root group's symbol table message */
+ if(NULL == H5O_msg_read(root_loc.oloc, H5O_STAB_ID, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message")
+
+ /* Update the root group symbol table entry */
+ f->shared->root_ent->type = H5G_CACHED_STAB;
+ f->shared->root_ent->cache.stab.btree_addr = stab.btree_addr;
+ f->shared->root_ent->cache.stab.heap_addr = stab.heap_addr;
+ } /* end if */
+ } /* end if */
+
+ /* Create the path names for the root group's entry */
+ H5G_name_init(root_loc.path, "/");
+
+ f->shared->root_grp->shared->fo_count = 1;
+ /* The only other open object should be the superblock extension, if it
+ * exists. Don't count either the superblock extension or the root group
+ * in the number of open objects in the file.
+ */
+ HDassert((1 == f->nopen_objs) ||
+ (2 == f->nopen_objs && HADDR_UNDEF != f->shared->extension_addr));
+ f->nopen_objs--;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_mkroot() */
+
diff --git a/src/H5Gtest.c b/src/H5Gtest.c
index 1f09048..f3508eb 100644
--- a/src/H5Gtest.c
+++ b/src/H5Gtest.c
@@ -550,3 +550,59 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5G_user_path_test() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_verify_cached_stab_test
+ *
+ * Purpose: Check that a that the provided group entry contains a
+ * cached symbol table entry, that the entry matches that in
+ * the provided group's object header, and check that the
+ * addresses are valid.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Neil Fortner
+ * Mar 31, 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_verify_cached_stab_test(H5O_loc_t *grp_oloc, H5G_entry_t *ent)
+{
+ H5O_stab_t stab; /* Symbol table */
+ H5HL_t *heap = NULL; /* Pointer to local heap */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_verify_cached_stab_test)
+
+ /* Verify that stab info is cached in ent */
+ if(ent->type != H5G_CACHED_STAB)
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "symbol table information is not cached")
+
+ /* Read the symbol table message from the group */
+ if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, H5AC_ind_dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message")
+
+ /* Verify that the cached symbol table info matches the symbol table message
+ * in the object header */
+ if((ent->cache.stab.btree_addr != stab.btree_addr)
+ || (ent->cache.stab.heap_addr != stab.heap_addr))
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "cached stab info does not match object header")
+
+ /* Verify that the btree address is valid */
+ if(H5B_valid(grp_oloc->file, H5AC_ind_dxpl_id, H5B_SNODE, stab.btree_addr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "b-tree address is invalid")
+
+ /* Verify that the heap address is valid */
+ if(NULL == (heap = H5HL_protect(grp_oloc->file, H5AC_ind_dxpl_id, stab.heap_addr, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "heap address is invalid")
+
+done:
+ /* Release resources */
+ if(heap && H5HL_unprotect(grp_oloc->file, H5AC_ind_dxpl_id, heap, stab.heap_addr) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_verify_cached_stab_test() */
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 9ae2252..99a0e72 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -62,7 +62,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5G.c H5Gbtree2.c H5Gcache.c \
H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
H5Gint.c H5Glink.c \
- H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c \
+ H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Groot.c H5Gstab.c H5Gtest.c \
H5Gtraverse.c \
H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \
H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 9dc8180..ecf06c2 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -97,9 +97,9 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5FScache.lo H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo \
H5G.lo H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \
H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \
- H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo \
- H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo \
- H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \
+ H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Groot.lo H5Gstab.lo \
+ H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo \
+ H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \
H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \
H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \
H5HGcache.lo H5HGdbg.lo H5HL.lo H5HLcache.lo H5HLdbg.lo \
@@ -446,7 +446,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5G.c H5Gbtree2.c H5Gcache.c \
H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \
H5Gint.c H5Glink.c \
- H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c \
+ H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Groot.c H5Gstab.c H5Gtest.c \
H5Gtraverse.c \
H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \
H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \
@@ -711,6 +711,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gnode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gobj.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Goh.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Groot.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gstab.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gtest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gtraverse.Plo@am__quote@
diff --git a/test/family_v16_00000.h5 b/test/family_v16_00000.h5
index bf1a711..5b69c93 100644
--- a/test/family_v16_00000.h5
+++ b/test/family_v16_00000.h5
Binary files differ
diff --git a/test/objcopy.c b/test/objcopy.c
index c2d71c0..4bd4662 100755
--- a/test/objcopy.c
+++ b/test/objcopy.c
@@ -7451,6 +7451,10 @@ main(void)
hid_t fcpl_src;
hid_t fcpl_dst;
+ /* No need to test dense attributes with old format */
+ if(!(configuration & CONFIG_NEW_FORMAT) && (configuration & CONFIG_DENSE))
+ continue;
+
/* Test with and without shared messages */
if(configuration & CONFIG_SHARE_SRC) {
puts("\nTesting with shared src messages:");
@@ -7473,22 +7477,23 @@ main(void)
if(configuration & CONFIG_NEW_FORMAT) {
puts("Testing with new group format:");
my_fapl = fapl2;
+
+ /* Test with and without dense attributes */
+ if(configuration & CONFIG_DENSE) {
+ puts("Testing with dense attributes:");
+ num_attributes_g = max_compact + 1;
+ }
+ else {
+ puts("Testing without dense attributes:");
+ num_attributes_g = MAX(min_dense, 2) - 1;
+ }
} /* end if */
else {
puts("Testing with old group format:");
my_fapl = fapl;
+ num_attributes_g = 4;
} /* end else */
- /* Test with and without dense attributes */
- if(configuration & CONFIG_DENSE) {
- puts("Testing with dense attributes:");
- num_attributes_g = max_compact + 1;
- }
- else {
- puts("Testing without dense attributes:");
- num_attributes_g = MAX(min_dense, 2) - 1;
- }
-
/* The tests... */
nerrors += test_copy_dataset_simple(fcpl_src, fcpl_dst, my_fapl);
nerrors += test_copy_dataset_simple_samefile(fcpl_src, my_fapl);
diff --git a/test/tfile.c b/test/tfile.c
index 724ad4a..68c7f6b 100644
--- a/test/tfile.c
+++ b/test/tfile.c
@@ -27,6 +27,14 @@
#include "H5Bprivate.h"
#include "H5Pprivate.h"
+/*
+ * This file needs to access private information from the H5F package.
+ * This file also needs to access the file testing code.
+ */
+#define H5F_PACKAGE
+#define H5F_TESTING
+#include "H5Fpkg.h" /* File access */
+
#define F1_USERBLOCK_SIZE (hsize_t)0
#define F1_OFFSET_SIZE sizeof(haddr_t)
#define F1_LENGTH_SIZE sizeof(hsize_t)
@@ -1931,9 +1939,9 @@ test_userblock_file_size(void)
/* Reopen files */
file1_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
- CHECK(ret, FAIL, "H5Fopen");
+ CHECK(file1_id, FAIL, "H5Fopen");
file2_id = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT);
- CHECK(ret, FAIL, "H5Fopen");
+ CHECK(file2_id, FAIL, "H5Fopen");
/* Check file sizes */
ret = H5Fget_filesize(file1_id, &filesize1);
@@ -1952,9 +1960,9 @@ test_userblock_file_size(void)
/* Reopen files */
file1_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
- CHECK(ret, FAIL, "H5Fopen");
+ CHECK(file1_id, FAIL, "H5Fopen");
file2_id = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT);
- CHECK(ret, FAIL, "H5Fopen");
+ CHECK(file2_id, FAIL, "H5Fopen");
/* Verify file sizes did not change */
ret = H5Fget_filesize(file1_id, &filesize);
@@ -1973,6 +1981,52 @@ test_userblock_file_size(void)
/****************************************************************
**
+** test_cached_stab_info(): low-level file test routine.
+** This test checks that new files are created with cached
+** symbol table information in the superblock (when using
+** the old format). This is necessary to ensure backwards
+** compatibility with versions from 1.3.0 to 1.6.3.
+**
+*****************************************************************/
+static void
+test_cached_stab_info(void)
+{
+ hid_t file_id;
+ hid_t group_id;
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing cached symbol table information\n"));
+
+ /* Create file */
+ file_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(file_id, FAIL, "H5Fcreate");
+
+ /* Create group */
+ group_id = H5Gcreate2(file_id, GROUP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(group_id, FAIL, "H5Gcreate2");
+
+ /* Close file and group */
+ ret = H5Gclose(group_id);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Fclose(file_id);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Reopen file */
+ file_id = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Fopen");
+
+ /* Verify the cached symbol table information */
+ ret = H5F_check_cached_stab_test(file_id);
+ CHECK(ret, FAIL, "H5F_check_cached_stab_test");
+
+ /* Close file */
+ ret = H5Fclose(file_id);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* end test_cached_stab_info() */
+
+/****************************************************************
+**
** test_file(): Main low-level file I/O test routine.
**
****************************************************************/
@@ -2002,7 +2056,8 @@ test_file(void)
test_file_double_dataset_open(); /* Test opening same dataset from two files works properly */
test_file_double_datatype_open(); /* Test opening same named datatype from two files works properly */
#endif /*H5_CANNOT_OPEN_TWICE*/
- test_userblock_file_size(); /* Tests that files created with a userblock have the correct size */
+ test_userblock_file_size(); /* Tests that files created with a userblock have the correct size */
+ test_cached_stab_info(); /* Tests that files are created with cached stab info in the superblock */
} /* test_file() */