summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2011-10-19 20:39:55 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2011-10-19 20:39:55 (GMT)
commit8ce6f57fed2b12527d271b9259234b6bb640139d (patch)
tree770456e027cc435438a8fb6616bc78e04a4befda /src
parent395c1c7db532897452716615889ad882c4ee935a (diff)
downloadhdf5-8ce6f57fed2b12527d271b9259234b6bb640139d.zip
hdf5-8ce6f57fed2b12527d271b9259234b6bb640139d.tar.gz
hdf5-8ce6f57fed2b12527d271b9259234b6bb640139d.tar.bz2
[svn-r21610] Purpose: Fix bug 7776
Description: When H5Ocopy failed due to attempting to expand an invalid reference in an attribute (or at any point after the destination object header was inserted into the cache), it failed to clean up correctly. Modified H5O_copy_header_real to keep track of whether the object header was inserted and take appropriate action on failure. Tested: fedora (too minor for full commit test)
Diffstat (limited to 'src')
-rw-r--r--src/H5Ocopy.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index be27167..0774acd 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -293,6 +293,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
unsigned mesgno = 0;
haddr_t addr_new = HADDR_UNDEF;
hbool_t *deleted = NULL; /* Array of flags indicating whether messages should be copied */
+ hbool_t inserted = FALSE; /* Whether the destination object header has been inserted into the cache */
size_t null_msgs; /* Number of NULL messages found in each loop */
size_t orig_dst_msgs; /* Original # of messages in dest. object */
H5O_mesg_t *mesg_src; /* Message in source object header */
@@ -370,9 +371,9 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
/* Allocate memory for "deleted" array. This array marks the message in
* the source that shouldn't be copied to the destination.
*/
- if(NULL == (deleted = (hbool_t *)HDmalloc(sizeof(hbool_t) * oh_src->nmesgs)))
+ if(NULL == (deleted = (hbool_t *)HDmalloc(sizeof(hbool_t) * oh_src->nmesgs)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- HDmemset(deleted, FALSE, sizeof(hbool_t) * oh_src->nmesgs);
+ HDmemset(deleted, FALSE, sizeof(hbool_t) * oh_src->nmesgs);
/* "pre copy" pass over messages, to gather information for actual message copy operation
* (for messages which depend on information from other messages)
@@ -696,6 +697,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
* pinned so we can continue using oh_dst. */
if(H5AC_insert_entry(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__PIN_ENTRY_FLAG) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
+ inserted = TRUE;
/* Reset metadata tag */
H5_END_TAG(FAIL);
@@ -752,7 +754,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
/* Unpin oh_dst */
if(H5AC_unpin_entry(oh_dst) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, FAIL, "can't unpin object header")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "can't unpin object header")
oh_dst = NULL;
/* Retag all copied metadata to apply the destination object's tag */
@@ -775,9 +777,19 @@ done:
if(oh_src && H5O_unprotect(oloc_src, dxpl_id, oh_src, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
- /* Release pointer to destination object header */
- if(ret_value < 0 && oh_dst && H5O_free(oh_dst) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
+ /* Free destination object header on failure */
+ if(ret_value < 0 && oh_dst) {
+ if(inserted) {
+ if(H5AC_unpin_entry(oh_dst) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "can't unpin object header")
+ } /* end if */
+ else {
+ if(H5O_free(oh_dst) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
+ if(H5O_loc_reset(oloc_dst) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
+ } /* end else */
+ } /* end if */
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5O_copy_header_real() */