summaryrefslogtreecommitdiffstats
path: root/src/H5Gent.c
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2010-09-21 17:52:12 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2010-09-21 17:52:12 (GMT)
commit2087c6a9e49daa4d160fdbd79230bb3b36e63c30 (patch)
treea3f6011efa1a9369fd33d1fffa09365edc696ac5 /src/H5Gent.c
parent95bc60ceb48bf6cd508691dd94be071b190fa74a (diff)
downloadhdf5-2087c6a9e49daa4d160fdbd79230bb3b36e63c30.zip
hdf5-2087c6a9e49daa4d160fdbd79230bb3b36e63c30.tar.gz
hdf5-2087c6a9e49daa4d160fdbd79230bb3b36e63c30.tar.bz2
[svn-r19461] Purpose: Fix bug 1864
Description: Library versions 1.6.3 and earlier contain a bug which causes them to be unable to perform certain operations on a group if that group's symbol table information is not cached in the parent group's symbol table. Versions 1.8.0 to 1.8.5 did not cache this information. Modified library to cache this information. Tested: jam, amani, heiwa (h5committest)
Diffstat (limited to 'src/H5Gent.c')
-rw-r--r--src/H5Gent.c85
1 files changed, 82 insertions, 3 deletions
diff --git a/src/H5Gent.c b/src/H5Gent.c
index a2e6159..cec788c 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -352,7 +352,8 @@ H5G_ent_reset(H5G_entry_t *ent)
*/
herr_t
H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, const char *name,
- const H5O_link_t *lnk, H5G_entry_t *ent)
+ const H5O_link_t *lnk, H5O_type_t obj_type, const void *crt_info,
+ H5G_entry_t *ent)
{
size_t name_offset; /* Offset of name in heap */
herr_t ret_value = SUCCEED; /* Return value */
@@ -373,13 +374,91 @@ H5G_ent_convert(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, const char *name,
*/
name_offset = H5HL_insert(f, dxpl_id, heap, HDstrlen(name) + 1, name);
if(0 == name_offset || (size_t)(-1) == name_offset)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert symbol name into heap")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert symbol name into heap")
ent->name_off = name_offset;
/* Build correct information for symbol table entry based on link type */
switch(lnk->type) {
case H5L_TYPE_HARD:
- ent->type = H5G_NOTHING_CACHED;
+ if(obj_type == H5O_TYPE_GROUP) {
+ const H5G_obj_create_t *gcrt_info = (const H5G_obj_create_t *)crt_info;
+
+ ent->type = gcrt_info->cache_type;
+ if(ent->type != H5G_NOTHING_CACHED)
+ ent->cache = gcrt_info->cache;
+#ifndef NDEBUG
+ else {
+ /* Make sure there is no stab message in the target object
+ */
+ H5O_loc_t targ_oloc; /* Location of link target */
+ htri_t stab_exists; /* Whether the target symbol table exists */
+
+ /* Build target object location */
+ if(H5O_loc_reset(&targ_oloc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize target location")
+ targ_oloc.file = f;
+ targ_oloc.addr = lnk->u.hard.addr;
+
+ /* Check if a symbol table message exists */
+ if((stab_exists = H5O_msg_exists(&targ_oloc, H5O_STAB_ID,
+ dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for STAB message")
+
+ HDassert(!stab_exists);
+ } /* end else */
+#endif /* NDEBUG */
+ } /* end if */
+ else if(obj_type == H5O_TYPE_UNKNOWN){
+ /* Try to retrieve symbol table information for caching */
+ H5O_loc_t targ_oloc; /* Location of link target */
+ H5O_t *oh; /* Link target object header */
+ H5O_stab_t stab; /* Link target symbol table */
+ htri_t stab_exists; /* Whether the target symbol table exists */
+
+ /* Build target object location */
+ if(H5O_loc_reset(&targ_oloc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRESET, FAIL, "unable to initialize target location")
+ targ_oloc.file = f;
+ targ_oloc.addr = lnk->u.hard.addr;
+
+ /* Get the object header */
+ if(NULL == (oh = H5O_protect(&targ_oloc, dxpl_id, H5AC_READ)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTPROTECT, FAIL, "unable to protect target object header")
+
+ /* Check if a symbol table message exists */
+ if((stab_exists = H5O_msg_exists_oh(oh, H5O_STAB_ID)) < 0) {
+ if(H5O_unprotect(&targ_oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET)
+ < 0)
+ HERROR(H5E_SYM, H5E_CANTUNPROTECT, "unable to release object header");
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for STAB message")
+ } /* end if */
+
+ if(stab_exists) {
+ /* Read symbol table message */
+ if(NULL == H5O_msg_read_oh(f, dxpl_id, oh, H5O_STAB_ID,
+ &stab)) {
+ if(H5O_unprotect(&targ_oloc, dxpl_id, oh,
+ H5AC__NO_FLAGS_SET) < 0)
+ HERROR(H5E_SYM, H5E_CANTUNPROTECT, "unable to release object header");
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read STAB message")
+ } /* end if */
+
+ /* Cache symbol table message */
+ ent->type = H5G_CACHED_STAB;
+ ent->cache.stab.btree_addr = stab.btree_addr;
+ ent->cache.stab.heap_addr = stab.heap_addr;
+ } /* end if */
+ else
+ /* No symbol table message, don't cache anything */
+ ent->type = H5G_NOTHING_CACHED;
+
+ if(H5O_unprotect(&targ_oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET)
+ < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
+ } /* end else */
+ else
+ ent->type = H5G_NOTHING_CACHED;
+
ent->header = lnk->u.hard.addr;
break;