From affc2a2b7071af91bb9d6b88998107657b738551 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 9 Apr 2009 15:22:11 -0500 Subject: [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) --- src/H5Groot.c | 64 ++++++++++++++++++++++++++++++++++++++++------------------- src/H5Gstab.c | 3 ++- 2 files changed, 46 insertions(+), 21 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() */ diff --git a/src/H5Gstab.c b/src/H5Gstab.c index c2df8e7..52c9d07 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -1011,7 +1011,8 @@ H5G_stab_valid(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5O_stab_t *alt_stab) FUNC_ENTER_NOAPI(H5G_stab_valid, FAIL) /* Read the symbol table message */ - H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id); + if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message"); /* Check if the symbol table message's b-tree address is valid */ if(H5B_valid(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr) < 0) { -- cgit v0.12