summaryrefslogtreecommitdiffstats
path: root/src/H5Groot.c
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2009-04-09 20:22:11 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2009-04-09 20:22:11 (GMT)
commitaffc2a2b7071af91bb9d6b88998107657b738551 (patch)
treef293523fb2b9e03c4f4b18d2646e33111ccca6da /src/H5Groot.c
parentc8f6207556a42f2408eb075d5c037699751fef8d (diff)
downloadhdf5-affc2a2b7071af91bb9d6b88998107657b738551.zip
hdf5-affc2a2b7071af91bb9d6b88998107657b738551.tar.gz
hdf5-affc2a2b7071af91bb9d6b88998107657b738551.tar.bz2
[svn-r16721] Purpose: Fix problems with "no strct format checks"
Description: Changed H5G_mkroot to be tolerant of files with symbol table information cached but no symbol table in the root group. Also changed H5G_mkroot to properly clean up in case of an error, and changed H5G_stab_is_valid to properly detect errors in H5O_msg_read. Tested: jam, linew, smirom (h5committest), jam (--disable-strict-format-checks)
Diffstat (limited to 'src/H5Groot.c')
-rw-r--r--src/H5Groot.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/src/H5Groot.c b/src/H5Groot.c
index 4c7c357..b8a1468 100644
--- a/src/H5Groot.c
+++ b/src/H5Groot.c
@@ -189,7 +189,8 @@ done:
herr_t
H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root)
{
- H5G_loc_t root_loc; /* Root location information */
+ H5G_loc_t root_loc; /* Root location information */
+ htri_t stab_exists = -1; /* Whether the symbol table exists */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_mkroot, FAIL)
@@ -280,23 +281,34 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root)
if(H5O_open(root_loc.oloc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group")
+ /* Actions to take if the symbol table information is cached */
+ if(f->shared->root_ent && f->shared->root_ent->type == H5G_CACHED_STAB) {
+ /* Check for the situation where the symbol table is cached but does
+ * not exist. This can happen if, for example, an external link is
+ * added to the root group. */
+ 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")
+
+ /* Remove the cache if the stab does not exist */
+ if(!stab_exists)
+ f->shared->root_ent->type = H5G_NOTHING_CACHED;
#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 */
+ /* If symbol table information is cached, check if we should replace the
+ * symbol table message with the cached symbol table information */
+ else if(H5F_INTENT(f) & H5F_ACC_RDWR) {
+ 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 if */
} /* end else */
/* Cache the root group's symbol table information in the root group symbol
@@ -304,14 +316,14 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root)
* 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
+ if((H5F_INTENT(f) & H5F_ACC_RDWR) && stab_exists != FALSE && 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)
+ * to use the latest version while the superblock is an old version.
+ * If stab_exists is not -1 then we have already checked. */
+ if(stab_exists == -1 && (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) {
@@ -339,6 +351,18 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root)
f->nopen_objs--;
done:
+ /* In case of error, free various memory locations that may have been
+ * allocated */
+ if(ret_value < 0) {
+ if(f->shared->root_grp) {
+ if(f->shared->root_grp->shared)
+ f->shared->root_grp->shared = H5FL_FREE(H5G_shared_t, f->shared->root_grp->shared);
+ f->shared->root_grp = H5FL_FREE(H5G_t, f->shared->root_grp);
+ } /* end if */
+ f->shared->root_ent = (H5G_entry_t *) H5MM_xfree(f->shared->root_ent);
+ H5G_name_free(root_loc.path);
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_mkroot() */