summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--release_docs/RELEASE.txt3
-rw-r--r--src/H5A.c4
-rw-r--r--src/H5Adense.c2
-rw-r--r--src/H5Aint.c186
-rw-r--r--src/H5Apkg.h2
-rw-r--r--src/H5Oainfo.c15
-rw-r--r--src/H5Oattribute.c2
-rw-r--r--src/H5Ocopy.c24
-rw-r--r--src/H5Odtype.c2
-rw-r--r--src/H5Ofill.c4
-rw-r--r--src/H5Omessage.c8
-rw-r--r--src/H5Opline.c2
-rw-r--r--src/H5Osdspace.c2
-rw-r--r--src/H5Oshared.c24
-rw-r--r--src/H5Oshared.h9
-rw-r--r--src/H5Ounknown.c2
-rwxr-xr-xsrc/H5SM.c266
-rwxr-xr-xsrc/H5SMprivate.h2
-rwxr-xr-xtest/objcopy.c150
19 files changed, 416 insertions, 293 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index 43555d6..6b70b27 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -300,6 +300,9 @@ Bug Fixes since HDF5-1.8.0 release
Library
-------
+ - Fixed a bug that occurred when using H5Ocopy on a committed datatype
+ containing an attribute using that committed datatype.
+ (NAF - 2011/10/13 - Issue 5854)
- #ifdef _WIN32 instances changed to #ifdef H5_HAVE_WIN32_API and added
H5_HAVE_VISUAL_STUDIO checks where necessary. CMake only as configure
never set _WIN32.
diff --git a/src/H5A.c b/src/H5A.c
index 29cfbe8..a1833a3 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -451,9 +451,9 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
/* Check if any of the pieces should be (or are already) shared in the
* SOHM table
*/
- if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0)
+ if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, FALSE, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed")
- if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0)
+ if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, FALSE, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed")
/* Check whether datatype is committed & increment ref count
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 889889e..6724736 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -470,7 +470,7 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
mesg_flags |= H5O_MSG_FLAG_SHARED;
else {
/* Should this attribute be written as a SOHM? */
- if(H5SM_try_share(f, dxpl_id, NULL, H5O_ATTR_ID, attr, &mesg_flags) < 0)
+ if(H5SM_try_share(f, dxpl_id, NULL, FALSE, H5O_ATTR_ID, attr, &mesg_flags) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "error determining if message should be shared")
/* Attributes can't be "unique be shareable" yet */
diff --git a/src/H5Aint.c b/src/H5Aint.c
index db9508e..b66c9b3 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -859,37 +859,14 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
if(H5T_set_loc(attr_dst->shared->dt, file_dst, H5T_LOC_DISK) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "cannot mark datatype on disk")
- /* Check for named datatype being copied */
- if(H5T_committed(attr_src->shared->dt)) {
- H5O_loc_t *src_oloc; /* Pointer to source datatype's object location */
- H5O_loc_t *dst_oloc; /* Pointer to dest. datatype's object location */
-
- /* Get group entries for source & destination */
- src_oloc = H5T_oloc(attr_src->shared->dt);
- HDassert(src_oloc);
- dst_oloc = H5T_oloc(attr_dst->shared->dt);
- HDassert(dst_oloc);
-
- /* Reset object location for new object */
- H5O_loc_reset(dst_oloc);
- dst_oloc->file = file_dst;
-
- /* Copy the shared object from source to destination */
- if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE,
- NULL, NULL) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
-
- /* Update shared message info from named datatype info */
- H5T_update_shared(attr_dst->shared->dt);
- } /* end if */
- else {
+ if(!H5T_committed(attr_src->shared->dt)) {
/* If the datatype is not named, it may have been shared in the
* source file's heap. Un-share it for now. We'll try to shared
* it in the destination file below.
*/
if(H5O_msg_reset_share(H5O_DTYPE_ID, attr_dst->shared->dt) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
- } /* end else */
+ } /* end if */
/* Copy the dataspace for the attribute. Make sure the maximal dimension is also copied.
* Otherwise the comparison in the test may complain about it. SLU 2011/4/12 */
@@ -902,13 +879,13 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
if(H5O_msg_reset_share(H5O_SDSPACE_ID, attr_dst->shared->ds) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset dataspace sharing")
-
/* Try to share both the datatype and dataset. This does nothing if the
* datatype is committed or sharing is disabled.
*/
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_DTYPE_ID, attr_dst->shared->dt, NULL) < 0)
+ /* Use try_share_virtual and move try_share to post copy? -NAF */
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, FALSE, H5O_DTYPE_ID, attr_dst->shared->dt, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute datatype")
- if(H5SM_try_share(file_dst, dxpl_id, NULL, H5O_SDSPACE_ID, attr_dst->shared->ds, NULL) < 0)
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, FALSE, H5O_SDSPACE_ID, attr_dst->shared->ds, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "can't share attribute dataspace")
/* Compute the sizes of the datatype and dataspace. This is their raw
@@ -1077,20 +1054,47 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t UNUSED *attr_src,
+H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *attr_src,
H5O_loc_t *dst_oloc, const H5A_t *attr_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
{
- H5F_t *file_src = src_oloc->file;
- H5F_t *file_dst = dst_oloc->file;
+ H5F_t *file_src, *file_dst;
herr_t ret_value = SUCCEED; /* Return value */
-
FUNC_ENTER_NOAPI_NOINIT(H5A_attr_post_copy_file)
/* check args */
+ HDassert(src_oloc);
+ HDassert(dst_oloc);
HDassert(attr_dst);
+ HDassert(attr_src);
+
+ file_src = src_oloc->file;
+ file_dst = dst_oloc->file;
+
+ HDassert(file_src);
HDassert(file_dst);
+ if(H5T_committed(attr_src->shared->dt)) {
+ H5O_loc_t *src_oloc_dt; /* Pointer to source datatype's object location */
+ H5O_loc_t *dst_oloc_dt; /* Pointer to dest. datatype's object location */
+
+ /* Get group entries for source & destination */
+ src_oloc_dt = H5T_oloc(attr_src->shared->dt);
+ HDassert(src_oloc_dt);
+ dst_oloc_dt = H5T_oloc(attr_dst->shared->dt);
+ HDassert(dst_oloc_dt);
+
+ /* Reset object location for new object */
+ H5O_loc_reset(dst_oloc_dt);
+ dst_oloc_dt->file = file_dst;
+
+ /* Copy the shared object from source to destination */
+ if(H5O_copy_header_map(src_oloc_dt, dst_oloc_dt, dxpl_id, cpy_info, FALSE, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+ /* Update shared message info from named datatype info */
+ H5T_update_shared(attr_dst->shared->dt);
+ } /* end if */
/* Only need to fix reference attribute with real data being copied to
* another file.
@@ -1124,7 +1128,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5A_dense_copy_file_cb
+ * Function: H5A_dense_post_copy_file_cb
*
* Purpose: Callback routine for copying a dense attribute from SRC to DST.
*
@@ -1138,13 +1142,13 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_dense_copy_file_cb(const H5A_t *attr_src, void *_udata)
+H5A_dense_post_copy_file_cb(const H5A_t *attr_src, void *_udata)
{
H5A_dense_file_cp_ud_t *udata = (H5A_dense_file_cp_ud_t *)_udata;
H5A_t *attr_dst = NULL;
herr_t ret_value = H5_ITER_CONT; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5A_dense_copy_file_cb)
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_post_copy_file_cb)
/* check arguments */
HDassert(attr_src);
@@ -1157,6 +1161,10 @@ H5A_dense_copy_file_cb(const H5A_t *attr_src, void *_udata)
udata->recompute_size, udata->cpy_info, udata->dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+ if(H5A_attr_post_copy_file(udata->oloc_src, attr_src, udata->oloc_dst, attr_dst,
+ udata->dxpl_id, udata->cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
+
/* Reset shared location information */
if(H5O_msg_reset_share(H5O_ATTR_ID, attr_dst) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to reset attribute sharing")
@@ -1176,105 +1184,20 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close destination attribute")
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5A_dense_copy_file_cb() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5A_dense_copy_file_all
- *
- * Purpose: Copy all dense attributes from SRC to DST.
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Peter Cao
- * xcao@hdfgroup.org
- * July 20, 2007
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst,
- const H5O_ainfo_t *ainfo_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, hid_t dxpl_id)
-{
- H5A_dense_file_cp_ud_t udata; /* User data for iteration callback */
- H5A_attr_iter_op_t attr_op; /* Attribute operator */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5A_dense_copy_file_all)
-
- /* check arguments */
- HDassert(ainfo_src);
- HDassert(ainfo_dst);
-
- udata.ainfo = ainfo_dst; /* Destination dense information */
- udata.file = file_dst; /* Destination file */
- udata.recompute_size = recompute_size; /* Flag to indicate if size changed */
- udata.cpy_info = cpy_info; /* Information on copying options */
- udata.dxpl_id = dxpl_id; /* DXPL for operation */
-
- attr_op.op_type = H5A_ATTR_OP_LIB;
- attr_op.u.lib_op = H5A_dense_copy_file_cb;
-
- if(H5A_dense_iterate(file_src, dxpl_id, (hid_t)0, ainfo_src, H5_INDEX_NAME,
- H5_ITER_NATIVE, (hsize_t)0, NULL, &attr_op, &udata) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5A_dense_copy_file_all */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5A_dense_post_copy_file_cb
- *
- * Purpose: Callback routine to perfom post copy for a dense attribute.
- *
- * Return: Success: Non-negative
- * Failure: Negative
- *
- * Programmer: Peter Cao
- * xcao@hdfgroup.org
- * July 25, 2007
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5A_dense_post_copy_file_cb(const H5A_t *attr_dst, void *_udata)
-{
- H5A_dense_file_cp_ud_t *udata = (H5A_dense_file_cp_ud_t *)_udata;
- herr_t ret_value = H5_ITER_CONT; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5A_dense_post_copy_file_cb)
-
- /* check arguments */
- HDassert(attr_dst);
- HDassert(udata);
- HDassert(udata->ainfo);
- HDassert(udata->file);
- HDassert(udata->cpy_info);
-
- if ( H5A_attr_post_copy_file(udata->oloc_src, NULL,
- udata->oloc_dst, attr_dst, udata->dxpl_id, udata->cpy_info) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute")
-
-done:
-
- FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_post_copy_file_cb() */
/*-------------------------------------------------------------------------
* Function: H5A_dense_post_copy_file_all
*
- * Purpose: Do post copy for all dense attributes.
+ * Purpose: Copy all dense attributes from SRC to DST.
*
* Return: Success: Non-negative
* Failure: Negative
*
* Programmer: Peter Cao
* xcao@hdfgroup.org
- * July 25, 2007
+ * July 20, 2007
*
*-------------------------------------------------------------------------
*/
@@ -1283,21 +1206,19 @@ H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t *ainfo
H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst, hid_t dxpl_id, H5O_copy_t *cpy_info)
{
H5A_dense_file_cp_ud_t udata; /* User data for iteration callback */
- H5A_attr_iter_op_t attr_op; /* Attribute operator */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5A_attr_iter_op_t attr_op; /* Attribute operator */
+ hbool_t recompute_size = FALSE; /* recompute the size */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_post_copy_file_all)
/* check arguments */
HDassert(ainfo_src);
HDassert(ainfo_dst);
- HDassert(src_oloc);
- HDassert(dst_oloc);
- HDassert(src_oloc->file);
- HDassert(dst_oloc->file);
- udata.ainfo = ainfo_src;
- udata.file = src_oloc->file;
+ udata.ainfo = ainfo_dst; /* Destination dense information */
+ udata.file = dst_oloc->file; /* Destination file */
+ udata.recompute_size = &recompute_size; /* Flag to indicate if size changed */
udata.cpy_info = cpy_info; /* Information on copying options */
udata.dxpl_id = dxpl_id; /* DXPL for operation */
udata.oloc_src = src_oloc;
@@ -1306,11 +1227,12 @@ H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t *ainfo
attr_op.op_type = H5A_ATTR_OP_LIB;
attr_op.u.lib_op = H5A_dense_post_copy_file_cb;
- if(H5A_dense_iterate(dst_oloc->file, dxpl_id, (hid_t)0, ainfo_dst, H5_INDEX_NAME,
+
+ if(H5A_dense_iterate(src_oloc->file, dxpl_id, (hid_t)0, ainfo_src, H5_INDEX_NAME,
H5_ITER_NATIVE, (hsize_t)0, NULL, &attr_op, &udata) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5A_dense_post_copy_file_all */
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 27f500e..20aa5b9 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -283,8 +283,6 @@ H5_DLL H5A_t *H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t
H5O_copy_t *cpy_info, hid_t dxpl_id);
H5_DLL herr_t H5A_attr_post_copy_file(const H5O_loc_t *src_oloc, const H5A_t *mesg_src,
H5O_loc_t *dst_oloc, const H5A_t *mesg_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
-H5_DLL herr_t H5A_dense_copy_file_all(H5F_t *file_src, H5O_ainfo_t *ainfo_src, H5F_t *file_dst,
- const H5O_ainfo_t *ainfo_dst, hbool_t *recompute_size, H5O_copy_t *cpy_info, hid_t dxpl_id);
H5_DLL herr_t H5A_dense_post_copy_file_all(const H5O_loc_t *src_oloc, const H5O_ainfo_t * ainfo_src,
H5O_loc_t *dst_oloc, H5O_ainfo_t *ainfo_dst, hid_t dxpl_id, H5O_copy_t *cpy_info);
diff --git a/src/H5Oainfo.c b/src/H5Oainfo.c
index 8ff9cf6..d4d3b2a 100644
--- a/src/H5Oainfo.c
+++ b/src/H5Oainfo.c
@@ -403,7 +403,7 @@ H5O_ainfo_pre_copy_file(H5F_t UNUSED *file_src, const void UNUSED *native_src,
*/
static void *
H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
- hbool_t *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
+ hbool_t UNUSED *recompute_size, H5O_copy_t *cpy_info, void UNUSED *udata, hid_t dxpl_id)
{
H5O_ainfo_t *ainfo_src = (H5O_ainfo_t *)mesg_src;
H5O_ainfo_t *ainfo_dst = NULL;
@@ -436,9 +436,6 @@ H5O_ainfo_copy_file(H5F_t *file_src, void *mesg_src, H5F_t *file_dst,
/* Reset metadata tag */
H5_END_TAG(NULL);
-
- if((H5A_dense_copy_file_all(file_src, ainfo_src, file_dst, ainfo_dst, recompute_size, cpy_info, dxpl_id)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to create dense storage for attributes")
} /* end if */
/* Set return value */
@@ -458,7 +455,7 @@ done:
*
* Purpose: Finish copying a message from between files.
* We have to copy the values of a reference attribute in the
- * post copy because H5O_post_copy_file() fails at the case that
+ * post copy because H5O_post_copy_file() fails in the case that
* an object may have a reference attribute that points to the
* object itself.
*
@@ -481,10 +478,10 @@ H5O_ainfo_post_copy_file(const H5O_loc_t *src_oloc, const void *mesg_src,
HDassert(ainfo_src);
if(H5F_addr_defined(ainfo_src->fheap_addr)) {
- if ( H5A_dense_post_copy_file_all(src_oloc, ainfo_src, dst_oloc,
- (H5O_ainfo_t *)mesg_dst, dxpl_id, cpy_info) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute")
- }
+ if(H5A_dense_post_copy_file_all(src_oloc, ainfo_src, dst_oloc,
+ (H5O_ainfo_t *)mesg_dst, dxpl_id, cpy_info) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "can't copy attribute")
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 82d832b..bb9553f 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -788,7 +788,7 @@ H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5A_t *attr,
/* Store new version of message as a SOHM */
/* (should always work, since we're not changing the size of the attribute) */
- if((shared_mesg = H5SM_try_share(f, dxpl_id, oh, H5O_ATTR_ID, attr, NULL)) == 0)
+ if((shared_mesg = H5SM_try_share(f, dxpl_id, oh, FALSE, H5O_ATTR_ID, attr, NULL)) == 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "attribute changed sharing status")
else if(shared_mesg < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't share attribute")
diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c
index 1ecd16f..7f121d9 100644
--- a/src/H5Ocopy.c
+++ b/src/H5Ocopy.c
@@ -688,6 +688,18 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
if(H5SL_insert(cpy_info->map_list, addr_map, &(addr_map->src_obj_pos)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+ /* Set metadata tag for destination object's object header */
+ H5_BEGIN_TAG(dxpl_id, oloc_dst->addr, FAIL);
+
+ /* Insert destination object header in cache. Insert before post copy loop
+ * so anything that references this object header can find it. Insert
+ * 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")
+
+ /* Reset metadata tag */
+ H5_END_TAG(FAIL);
+
/* "post copy" loop over messages, to fix up any messages which require a complete
* object header for destination object
*/
@@ -738,17 +750,11 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
oh_dst->nlink += (unsigned)addr_map->inc_ref_count;
} /* end if */
- /* Set metadata tag for destination object's object header */
- H5_BEGIN_TAG(dxpl_id, oloc_dst->addr, FAIL);
-
- /* Insert destination object header in cache */
- if(H5AC_insert_entry(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
+ /* Unpin oh_dst */
+ if(H5AC_unpin_entry(oh_dst) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPIN, FAIL, "can't unpin object header")
oh_dst = NULL;
- /* Reset metadat tag */
- H5_END_TAG(FAIL);
-
/* Retag all copied metadata to apply the destination object's tag */
if(H5AC_retag_copied_metadata(oloc_dst->file, oloc_dst->addr) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "unable to re-tag metadata entries")
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index f419e44..39c97cb 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -104,7 +104,7 @@ const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{
H5O_dtype_can_share, /* can share method */
H5O_dtype_pre_copy_file, /* pre copy native value to file */
H5O_dtype_shared_copy_file, /* copy native value to file */
- NULL, /* post copy native value to file */
+ H5O_dtype_shared_post_copy_file, /* post copy native value to file */
NULL, /* get creation index */
NULL, /* set creation index */
H5O_dtype_shared_debug /* debug the message */
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index c7c743a..f333410 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -120,7 +120,7 @@ const H5O_msg_class_t H5O_MSG_FILL[1] = {{
NULL, /*can share method */
NULL, /* pre copy native value to file */
H5O_fill_shared_copy_file, /* copy native value to file */
- NULL, /* post copy native value to file */
+ H5O_fill_shared_post_copy_file, /* post copy native value to file */
NULL, /* get creation index */
NULL, /* set creation index */
H5O_fill_shared_debug /*debug the message */
@@ -144,7 +144,7 @@ const H5O_msg_class_t H5O_MSG_FILL_NEW[1] = {{
NULL, /*can share method */
NULL, /* pre copy native value to file */
H5O_fill_new_shared_copy_file, /* copy native value to file */
- NULL, /* post copy native value to file */
+ H5O_fill_new_shared_post_copy_file, /* post copy native value to file */
NULL, /* get creation index */
NULL, /* set creation index */
H5O_fill_new_shared_debug /*debug the message */
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index c03bf0a..f655211 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -419,7 +419,7 @@ H5O_msg_write_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *ty
* XXX: This doesn't handle freeing extra space in object header from
* a message shrinking.
*/
- if((status = H5SM_try_share(f, dxpl_id, ((mesg_flags & H5O_MSG_FLAG_SHARED) ? NULL : oh), idx_msg->type->id, mesg, &mesg_flags)) < 0)
+ if((status = H5SM_try_share(f, dxpl_id, ((mesg_flags & H5O_MSG_FLAG_SHARED) ? NULL : oh), FALSE, idx_msg->type->id, mesg, &mesg_flags)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "error while trying to share message")
if(status == FALSE && (mesg_flags & H5O_MSG_FLAG_SHARED))
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "message changed sharing status")
@@ -1536,6 +1536,10 @@ H5O_msg_can_share(unsigned type_id, const void *mesg)
ret_value = (type->share_flags & H5O_SHARE_IS_SHARABLE) ? TRUE : FALSE;
} /* end else */
+ /* If the message is shareable, both copy_file and post_copy_file must be
+ * defined */
+ HDassert((type->post_copy_file && type->copy_file) || ret_value == FALSE);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_msg_can_share() */
@@ -1918,7 +1922,7 @@ H5O_msg_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type,
} /* end if */
else {
/* Attempt to share message */
- if(H5SM_try_share(f, dxpl_id, oh, type->id, native, mesg_flags) < 0)
+ if(H5SM_try_share(f, dxpl_id, oh, FALSE, type->id, native, mesg_flags) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "error determining if message should be shared")
} /* end else */
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 89bdd36..518bcdf 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -83,7 +83,7 @@ const H5O_msg_class_t H5O_MSG_PLINE[1] = {{
NULL, /*can share method */
H5O_pline_pre_copy_file, /* pre copy native value to file */
H5O_pline_shared_copy_file, /* copy native value to file */
- NULL, /* post copy native value to file */
+ H5O_pline_shared_post_copy_file, /* post copy native value to file */
NULL, /* get creation index */
NULL, /* set creation index */
H5O_pline_shared_debug /* debug the message */
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index 323bec9..62d5b63 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -77,7 +77,7 @@ const H5O_msg_class_t H5O_MSG_SDSPACE[1] = {{
NULL, /*can share method */
H5O_sdspace_pre_copy_file, /* pre copy native value to file */
H5O_sdspace_shared_copy_file,/* copy native value to file */
- NULL, /* post copy native value to file */
+ H5O_sdspace_shared_post_copy_file,/* post copy native value to file */
NULL, /* get creation index */
NULL, /* set creation index */
H5O_sdspace_shared_debug /* debug the message */
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 4ba01ac..4c5408d 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -285,7 +285,7 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
} /* end if */
/* Check for incrementing reference count on message */
else if(adjust > 0) {
- if(H5SM_try_share(f, dxpl_id, open_oh, type->id, shared, NULL) < 0)
+ if(H5SM_try_share(f, dxpl_id, open_oh, FALSE, type->id, shared, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "error trying to share message")
} /* end if */
} /* end else */
@@ -610,7 +610,11 @@ H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
/* Committed shared messages create a shared message at the destination
* and also copy the committed object that they point to.
*
- * SOHMs try to share the destination message.
+ * Other messages simulate sharing the destination message to determine how
+ * it will eventually be shared (if at all), but do not actually share the
+ * message until "post copy". The "H5O_shared_t" part of the message will
+ * be updated (to allow calculation of the final size) but the message is
+ * not actually shared.
*/
if(shared_src->type == H5O_SHARE_TYPE_COMMITTED) {
H5O_loc_t dst_oloc;
@@ -628,20 +632,15 @@ H5O_shared_copy_file(H5F_t *file_src, H5F_t *file_dst,
H5O_UPDATE_SHARED(shared_dst, H5O_SHARE_TYPE_COMMITTED, file_dst, mesg_type->id, 0, dst_oloc.addr)
} /* end if */
else {
- /* Try to share new message in the destination file. */
- /* Message is always shared in heap in dest. file because the dest.
- * object header doesn't quite exist yet - JML
- */
-
+ /* Simulate trying to share new message in the destination file. */
/* Set copied metadata tag */
H5_BEGIN_TAG(dxpl_id, H5AC__COPIED_TAG, FAIL);
- if(H5SM_try_share(file_dst, dxpl_id, NULL, mesg_type->id, _native_dst, NULL) < 0)
+ if(H5SM_try_share(file_dst, dxpl_id, NULL, TRUE, mesg_type->id, _native_dst, NULL) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to determine if message should be shared")
/* Reset metadata tag */
H5_END_TAG(FAIL);
-
} /* end else */
done:
@@ -687,12 +686,8 @@ H5O_shared_post_copy_file(H5F_t *f, hid_t dxpl_id, H5O_t *oh, void *mesg)
/* save the type id for later use */
msg_type_id = old_sh_mesg->msg_type_id;
- /* Remove the old message from the SOHM storage */
- if(H5SM_delete(f, dxpl_id, oh, old_sh_mesg) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to find attribute information for object")
-
/* Add the new message */
- if((shared_mesg = H5SM_try_share(f, dxpl_id, oh, msg_type_id, mesg, NULL)) == 0)
+ if((shared_mesg = H5SM_try_share(f, dxpl_id, oh, FALSE, msg_type_id, mesg, NULL)) == 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "message changed sharing status")
else if(shared_mesg < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't share message")
@@ -701,7 +696,6 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_shared_post_copy_file() */
-
/*-------------------------------------------------------------------------
* Function: H5O_shared_debug
diff --git a/src/H5Oshared.h b/src/H5Oshared.h
index c0f5cd6..569889d 100644
--- a/src/H5Oshared.h
+++ b/src/H5Oshared.h
@@ -408,11 +408,14 @@ H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy native message to another file")
#endif /* H5O_SHARED_POST_COPY_FILE_REAL */
- /* update only shared message after the post copy */
- if(H5O_msg_is_shared(shared_dst->msg_type_id, mesg_dst)) {
+ /* Update only shared message after the post copy. Do not update committed
+ * messages as they have already been dealt with in the copy pass.
+ * (Move copy of target of committed messages to post copy? -NAF) */
+ if(shared_dst->type == H5O_SHARE_TYPE_SOHM
+ || shared_dst->type == H5O_SHARE_TYPE_HERE) {
if(H5O_shared_post_copy_file(oloc_dst->file, dxpl_id, cpy_info->oh_dst, mesg_dst) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to fix shared message in post copy")
- }
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Ounknown.c b/src/H5Ounknown.c
index d4a3801..68bb64b 100644
--- a/src/H5Ounknown.c
+++ b/src/H5Ounknown.c
@@ -40,7 +40,7 @@ const H5O_msg_class_t H5O_MSG_UNKNOWN[1] = {{
H5O_UNKNOWN_ID, /*message id number */
"unknown", /*message name for debugging */
0, /*native message size */
- FALSE, /* messages are sharable? */
+ 0, /* messages are sharable? */
NULL, /*decode message */
NULL, /*encode message */
NULL, /*copy the native value */
diff --git a/src/H5SM.c b/src/H5SM.c
index 3928ab5..a3bc2f9 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -65,7 +65,7 @@ static herr_t H5SM_convert_list_to_btree(H5F_t * f, H5SM_index_header_t * header
static herr_t H5SM_convert_btree_to_list(H5F_t * f, H5SM_index_header_t * header, hid_t dxpl_id);
static herr_t H5SM_incr_ref(void *record, void *_op_data, hbool_t *changed);
static herr_t H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
- H5SM_index_header_t *header, unsigned type_id, void *mesg,
+ H5SM_index_header_t *header, hbool_t defer, unsigned type_id, void *mesg,
unsigned *cache_flags_ptr);
static herr_t H5SM_decr_ref(void *record, void *op_data, hbool_t *changed);
static herr_t H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
@@ -988,6 +988,10 @@ done:
* header it needs (which can cause an error if that OH is
* already protected!).
*
+ * The DEFER flag indicates whether the sharing operation
+ * should actually occur, or whether this is just a set up call
+ * for a future sharing operation.
+ *
* MESG_FLAGS will have the H5O_MSG_FLAG_SHAREABLE or
* H5O_MSG_FLAG_SHARED flag set if one is appropriate. This is
* the only way to tell the difference between a message that
@@ -1025,8 +1029,8 @@ done:
*-------------------------------------------------------------------------
*/
htri_t
-H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id,
- void *mesg, unsigned *mesg_flags)
+H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, hbool_t defer,
+ unsigned type_id, void *mesg, unsigned *mesg_flags)
{
H5SM_master_table_t *table = NULL;
H5SM_table_cache_ud_t cache_udata; /* User-data for callback */
@@ -1071,13 +1075,13 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id,
* message to become shared (if it is unique, it will not be shared).
*/
if(H5SM_write_mesg(f, dxpl_id, open_oh, &(table->indexes[index_num]),
- type_id, mesg, &cache_flags) < 0)
+ defer, type_id, mesg, &cache_flags) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "can't write shared message")
- /* Set flags if this message was "written" without error; it is now
- * either fully shared or "shareable".
+ /* Set flags if this message was "written" without error and wasn't a
+ * 'defer' attempt; it is now either fully shared or "shareable".
*/
- if(mesg_flags) {
+ if(mesg_flags && !defer) {
if(((H5O_shared_t *)mesg)->type == H5O_SHARE_TYPE_HERE)
*mesg_flags |= H5O_MSG_FLAG_SHAREABLE;
else
@@ -1157,19 +1161,28 @@ done:
/*-------------------------------------------------------------------------
* Function: H5SM_write_mesg
*
- * Purpose: Adds a shareable message to an index. If this is the first
- * such message and we have an object header location for this
- * message, we record it in the index but don't modify the
- * message passed in.
- *
- * If the message is already in the index or we don't have an
- * object header location for it, it is shared in the heap
- * and this function sets its sharing struct to reflect this.
+ * Purpose: This routine adds a shareable message to an index.
+ * The behavior is controlled by the DEFER parameter:
+ *
+ * If DEFER is TRUE, this routine Simulates adding a shareable
+ * message to an index. It determines what the outcome would
+ * be with DEFER set the FALSE and updates the shared message
+ * info, but does not actually add the message to a heap, list,
+ * or b-tree. Assumes that an open object header will be
+ * available when H5SM_write_mesg is called with DEFER set to
+ * FALSE.
+ *
+ * If DEFER is FALSE, this routine adds a shareable message to
+ * an index. If this is the first such message and we have an
+ * object header location for this message, we record it in the
+ * index but don't modify the message passed in. If the message
+ * is already in the index or we don't have an object header
+ * location for it, it is shared in the heap and this function
+ * sets its sharing struct to reflect this.
*
* The index could be a list or a B-tree.
*
- * Return: TRUE if message is now shared
- * FALSE if message is in index but is not shared
+ * Return: Non-negative on success
* Negative on failure
*
* Programmer: James Laird
@@ -1179,7 +1192,7 @@ done:
*/
static herr_t
H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
- H5SM_index_header_t *header, unsigned type_id, void *mesg,
+ H5SM_index_header_t *header, hbool_t defer, unsigned type_id, void *mesg,
unsigned *cache_flags_ptr)
{
H5SM_list_t *list = NULL; /* List index */
@@ -1234,7 +1247,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
cache_udata.header = header;
/* The index is a list; get it from the cache */
- if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, &cache_udata, H5AC_WRITE)))
+ if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, &cache_udata, defer ? H5AC_READ : H5AC_WRITE)))
HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index")
/* See if the message is already in the index and get its location.
@@ -1242,55 +1255,75 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
* later.
*/
list_pos = H5SM_find_in_list(list, &key, &empty_pos);
- if(list_pos != UFAIL) {
- /* If the message was previously shared in an object header, share
- * it in the heap now.
- */
- if(list->messages[list_pos].location == H5SM_IN_OH) {
- /* Put the message in the heap and record its new heap ID */
- if(H5HF_insert(fheap, dxpl_id, key.encoding_size, key.encoding, &shared.u.heap_id) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap")
-
- list->messages[list_pos].location = H5SM_IN_HEAP;
- list->messages[list_pos].u.heap_loc.fheap_id = shared.u.heap_id;
- list->messages[list_pos].u.heap_loc.ref_count = 2;
- } /* end if */
- else {
- /* If the message was already in the heap, increase its ref count */
- HDassert(list->messages[list_pos].location == H5SM_IN_HEAP);
- ++(list->messages[list_pos].u.heap_loc.ref_count);
- } /* end else */
-
- /* Set up the shared location to point to the shared location */
- shared.u.heap_id = list->messages[list_pos].u.heap_loc.fheap_id;
- found = TRUE;
+ if(defer) {
+ if(list_pos != UFAIL)
+ found = TRUE;
} /* end if */
+ else {
+ if(list_pos != UFAIL) {
+ /* If the message was previously shared in an object header, share
+ * it in the heap now.
+ */
+ if(list->messages[list_pos].location == H5SM_IN_OH) {
+ /* Put the message in the heap and record its new heap ID */
+ if(H5HF_insert(fheap, dxpl_id, key.encoding_size, key.encoding, &shared.u.heap_id) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap")
+
+ list->messages[list_pos].location = H5SM_IN_HEAP;
+ list->messages[list_pos].u.heap_loc.fheap_id = shared.u.heap_id;
+ list->messages[list_pos].u.heap_loc.ref_count = 2;
+ } /* end if */
+ else {
+ /* If the message was already in the heap, increase its ref count */
+ HDassert(list->messages[list_pos].location == H5SM_IN_HEAP);
+ ++(list->messages[list_pos].u.heap_loc.ref_count);
+ } /* end else */
+
+ /* Set up the shared location to point to the shared location */
+ shared.u.heap_id = list->messages[list_pos].u.heap_loc.fheap_id;
+ found = TRUE;
+ } /* end if */
+ } /* end else */
} /* end if */
/* Index is a B-tree */
else {
- H5SM_incr_ref_opdata op_data;
-
HDassert(header->index_type == H5SM_BTREE);
/* Open the index v2 B-tree */
if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f)))
HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
- /* Set up callback info */
- op_data.key = &key;
- op_data.dxpl_id = dxpl_id;
+ if(defer) {
+ htri_t bt2_find; /* Result from searching in the v2 B-tree */
- /* If this returns failure, it means that the message wasn't found. */
- /* If it succeeds, set the heap_id in the shared struct. It will
- * return a heap ID, since a message with a reference count greater
- * than 1 is always shared in the heap.
- */
- if(H5B2_modify(bt2, dxpl_id, &key, H5SM_incr_ref, &op_data) >= 0) {
- shared.u.heap_id = op_data.fheap_id;
- found = TRUE;
+ /* If this returns 0, it means that the message wasn't found. */
+ /* If it return 1, set the heap_id in the shared struct. It will
+ * return a heap ID, since a message with a reference count greater
+ * than 1 is always shared in the heap.
+ */
+ if((bt2_find = H5B2_find(bt2, dxpl_id, &key, NULL, NULL)) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "can't search for message in index")
+ found = (hbool_t)bt2_find;
} /* end if */
- else
- H5E_clear_stack(NULL); /*ignore error*/
+ else {
+ H5SM_incr_ref_opdata op_data;
+
+ /* Set up callback info */
+ op_data.key = &key;
+ op_data.dxpl_id = dxpl_id;
+
+ /* If this returns failure, it means that the message wasn't found. */
+ /* If it succeeds, set the heap_id in the shared struct. It will
+ * return a heap ID, since a message with a reference count greater
+ * than 1 is always shared in the heap.
+ */
+ if(H5B2_modify(bt2, dxpl_id, &key, H5SM_incr_ref, &op_data) >= 0) {
+ shared.u.heap_id = op_data.fheap_id;
+ found = TRUE;
+ } /* end if */
+ else
+ H5E_clear_stack(NULL); /*ignore error*/
+ } /* end else */
} /* end else */
if(found)
@@ -1308,75 +1341,94 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
HGOTO_ERROR(H5E_SOHM, H5E_BADTYPE, FAIL, "'share in ohdr' check returned error")
/* If this message can be shared in an object header location, it is
- * "shareable" but not shared in the heap. Insert it in the index
- * but don't modify the original message.
+ * "shareable" but not shared in the heap.
+ *
+ * If 'defer' flag is set:
+ * We will insert it in the index but not modify the original
+ * message.
+ * If it can't be shared in an object header location, we will
+ * insert it in the heap. Note that we assume there will
+ * be an "open_oh" available when it is time to call
+ * H5SM_write_mesg with defer flag disabled.
*
- * If it can't be shared in an object header location or there's no
- * object header location available, insert it in the heap.
+ * If 'defer' flag is not set:
+ * Insert it in the index but don't modify the original message.
+ * If it can't be shared in an object header location or there's
+ * no object header location available, insert it in the
+ * heap.
*/
- if(share_in_ohdr && open_oh) {
+ if(share_in_ohdr && (defer || open_oh)) {
/* Set up shared component info */
shared.type = H5O_SHARE_TYPE_HERE;
/* Retrieve any creation index from the native message */
if(H5O_msg_get_crt_index(type_id, mesg, &shared.u.loc.index) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, FAIL, "unable to retrieve creation index")
- shared.u.loc.oh_addr = H5O_OH_GET_ADDR(open_oh);
- /* Copy shared component info into key for inserting into index */
- key.message.location = H5SM_IN_OH;
- key.message.u.mesg_loc = shared.u.loc;
+ if(defer)
+ shared.u.loc.oh_addr = HADDR_UNDEF;
+ else {
+ shared.u.loc.oh_addr = H5O_OH_GET_ADDR(open_oh);
+
+ /* Copy shared component info into key for inserting into index */
+ key.message.location = H5SM_IN_OH;
+ key.message.u.mesg_loc = shared.u.loc;
+ } /* end else */
} /* end if */
else {
- /* Put the message in the heap and record its new heap ID */
- if(H5HF_insert(fheap, dxpl_id, key.encoding_size, key.encoding, &shared.u.heap_id) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap")
-
/* Set up shared component info */
- /* (heap ID set above) */
+ /* (heap ID set below, if not deferred) */
shared.type = H5O_SHARE_TYPE_SOHM;
- key.message.location = H5SM_IN_HEAP;
- key.message.u.heap_loc.fheap_id = shared.u.heap_id;
- key.message.u.heap_loc.ref_count = 1;
- } /* end else */
-
- /* Set common information */
- key.message.msg_type_id = type_id;
+ if(!defer) {
+ /* Put the message in the heap and record its new heap ID */
+ if(H5HF_insert(fheap, dxpl_id, key.encoding_size, key.encoding, &shared.u.heap_id) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to insert message into fractal heap")
- /* Check whether the list has grown enough that it needs to become a B-tree */
- if(header->index_type == H5SM_LIST && header->num_messages >= header->list_max)
- if(H5SM_convert_list_to_btree(f, header, &list, fheap, open_oh, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to convert list to B-tree")
-
- /* Insert the new message into the SOHM index */
- if(header->index_type == H5SM_LIST) {
- /* Index is a list. Find an empty spot if we haven't already */
- if(empty_pos == UFAIL)
- if((H5SM_find_in_list(list, NULL, &empty_pos) == UFAIL) || empty_pos == UFAIL)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to find empty entry in list")
-
- /* Insert message into list */
- HDassert(list->messages[empty_pos].location == H5SM_NO_LOC);
- HDassert(key.message.location != H5SM_NO_LOC);
- list->messages[empty_pos] = key.message;
- } /* end if */
- /* Index is a B-tree */
- else {
- HDassert(header->index_type == H5SM_BTREE);
+ key.message.location = H5SM_IN_HEAP;
+ key.message.u.heap_loc.fheap_id = shared.u.heap_id;
+ key.message.u.heap_loc.ref_count = 1;
+ } /* end if */
+ } /* end else */
- /* Open the index v2 B-tree, if it isn't already */
- if(NULL == bt2) {
- if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f)))
- HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
+ if(!defer) {
+ /* Set common information */
+ key.message.msg_type_id = type_id;
+
+ /* Check whether the list has grown enough that it needs to become a B-tree */
+ if(header->index_type == H5SM_LIST && header->num_messages >= header->list_max)
+ if(H5SM_convert_list_to_btree(f, header, &list, fheap, open_oh, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTDELETE, FAIL, "unable to convert list to B-tree")
+
+ /* Insert the new message into the SOHM index */
+ if(header->index_type == H5SM_LIST) {
+ /* Index is a list. Find an empty spot if we haven't already */
+ if(empty_pos == UFAIL)
+ if((H5SM_find_in_list(list, NULL, &empty_pos) == UFAIL) || empty_pos == UFAIL)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "unable to find empty entry in list")
+
+ /* Insert message into list */
+ HDassert(list->messages[empty_pos].location == H5SM_NO_LOC);
+ HDassert(key.message.location != H5SM_NO_LOC);
+ list->messages[empty_pos] = key.message;
} /* end if */
+ /* Index is a B-tree */
+ else {
+ HDassert(header->index_type == H5SM_BTREE);
- if(H5B2_insert(bt2, dxpl_id, &key) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree")
- } /* end else */
+ /* Open the index v2 B-tree, if it isn't already */
+ if(NULL == bt2) {
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, header->index_addr, f)))
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for SOHM index")
+ } /* end if */
+
+ if(H5B2_insert(bt2, dxpl_id, &key) < 0)
+ HGOTO_ERROR(H5E_SOHM, H5E_CANTINSERT, FAIL, "couldn't add SOHM to B-tree")
+ } /* end else */
- ++(header->num_messages);
- (*cache_flags_ptr) |= H5AC__DIRTIED_FLAG;
+ ++(header->num_messages);
+ (*cache_flags_ptr) |= H5AC__DIRTIED_FLAG;
+ } /* end if */
} /* end else */
/* Set the file pointer & message type for the shared component */
@@ -1395,7 +1447,7 @@ done:
HDONE_ERROR(H5E_SOHM, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for SOHM index")
/* If we got a list out of the cache, release it (it is always dirty after writing a message) */
- if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__DIRTIED_FLAG) < 0)
+ if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, defer ? H5AC__NO_FLAGS_SET : H5AC__DIRTIED_FLAG) < 0)
HDONE_ERROR(H5E_SOHM, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index")
if(encoding_buf)
diff --git a/src/H5SMprivate.h b/src/H5SMprivate.h
index 46a43ad..aa964a7 100755
--- a/src/H5SMprivate.h
+++ b/src/H5SMprivate.h
@@ -44,7 +44,7 @@ H5_DLL herr_t H5SM_init(H5F_t *f, H5P_genplist_t *fc_plist,
H5_DLL htri_t H5SM_can_share(H5F_t *f, hid_t dxpl_id, H5SM_master_table_t *table,
ssize_t *sohm_index_num, unsigned type_id, const void *mesg);
H5_DLL htri_t H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
- unsigned type_id, void *mesg, unsigned *mesg_flags);
+ hbool_t defer, unsigned type_id, void *mesg, unsigned *mesg_flags);
H5_DLL herr_t H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5O_shared_t *sh_mesg);
H5_DLL herr_t H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist,
diff --git a/test/objcopy.c b/test/objcopy.c
index 508666d..8d60498 100755
--- a/test/objcopy.c
+++ b/test/objcopy.c
@@ -1748,7 +1748,150 @@ error:
H5Fclose(fid_src);
} H5E_END_TRY;
return 1;
-} /* end test_copy_named_datatype_vl */
+} /* end test_copy_named_datatype_vl_vl */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_copy_named_datatype_attr_self
+ *
+ * Purpose: Create name datatype in SRC file, with an attribute that
+ * uses that named datatype as its datatype, and copy it to
+ * DST file
+ *
+ * Return: Success: 0
+ * Failure: number of errors
+ *
+ * Programmer: Neil
+ * Friday, March 11, 2011
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_copy_named_datatype_attr_self(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl)
+{
+ hid_t fid_src = -1, fid_dst = -1; /* File IDs */
+ hid_t tid = -1, tid2 = -1; /* Datatype IDs */
+ hid_t aid = -1; /* Attribute ID */
+ hid_t sid = -1; /* Dataspace ID */
+ hsize_t dims[2] = {3, 4}; /* Dataspace dimensions */
+ H5O_info_t oinfo, oinfo2; /* Object info */
+ H5G_info_t ginfo; /* Group info */
+ char src_filename[NAME_BUF_SIZE];
+ char dst_filename[NAME_BUF_SIZE];
+
+ TESTING("H5Ocopy(): named datatype with self-referential attribute");
+
+ /* Initialize the filenames */
+ h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename);
+ h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename);
+
+ /* Reset file address checking info */
+ addr_reset();
+
+ /* create source file */
+ if((fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, fcpl_src, fapl)) < 0) TEST_ERROR
+
+ /* create datatype */
+ if((tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR
+
+ /* create named datatype */
+ if((H5Tcommit2(fid_src, NAME_DATATYPE_SIMPLE, tid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* create dataspace */
+ if((sid = H5Screate_simple(2, dims, NULL)) < 0) TEST_ERROR
+
+ /* create attribute */
+ if((aid = H5Acreate2(tid, "attr_self", tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* attach other attributes to the dataset */
+ if(test_copy_attach_attributes(tid, tid) < 0) TEST_ERROR
+
+ /* close the attribute */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the dataspace */
+ if(H5Sclose(sid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+
+ /* open the source file with read-only */
+ if((fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR
+
+ /* create destination file */
+ if((fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, fcpl_dst, fapl)) < 0) TEST_ERROR
+
+ /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */
+ if(H5Gclose(H5Gcreate2(fid_dst, NAME_GROUP_UNCOPIED, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* copy the datatype from SRC to DST */
+ if(H5Ocopy(fid_src, NAME_DATATYPE_SIMPLE, fid_dst, NAME_DATATYPE_SIMPLE, H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
+
+ /* open the source datatype */
+ if((tid = H5Topen2(fid_src, NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+
+ /* open the copied datatype */
+ if((tid2 = H5Topen2(fid_dst, NAME_DATATYPE_SIMPLE, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
+
+ /* Compare the datatypes */
+ if(H5Tequal(tid, tid2) != TRUE) TEST_ERROR
+
+ /* close the source datatype */
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* open the destination attribute */
+ if((aid = H5Aopen(tid2, "attr_self", H5P_DEFAULT)) < 0) TEST_ERROR
+
+ /* open the destination attribute's datatype */
+ if((tid = H5Aget_type(aid)) < 0) TEST_ERROR
+
+ /* verify that the attribute's datatype is committed */
+ if(H5Tcommitted(tid) != TRUE) TEST_ERROR
+
+ /* verify that the addresses of the datatypes are the same */
+ if(H5Oget_info(tid, &oinfo) < 0) TEST_ERROR
+ if(H5Oget_info(tid2, &oinfo2) < 0) TEST_ERROR
+ if(oinfo.fileno != oinfo2.fileno || oinfo.addr != oinfo2.addr)
+ FAIL_PUTS_ERROR("destination attribute does not use the same committed datatype")
+
+ /* Verify that there are only 2 links int he destination root group */
+ if(H5Gget_info(fid_dst, &ginfo) < 0)
+ if(ginfo.nlinks != 2)
+ FAIL_PUTS_ERROR("unexpected number of links in destination root group")
+
+ /* close the attribute */
+ if(H5Aclose(aid) < 0) TEST_ERROR
+
+ /* close the datatypes */
+ if(H5Tclose(tid2) < 0) TEST_ERROR
+ if(H5Tclose(tid) < 0) TEST_ERROR
+
+ /* close the SRC file */
+ if(H5Fclose(fid_src) < 0) TEST_ERROR
+
+ /* close the DST file */
+ if(H5Fclose(fid_dst) < 0) TEST_ERROR
+
+ PASSED();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Tclose(tid2);
+ H5Tclose(tid);
+ H5Sclose(sid);
+ H5Aclose(aid);
+ H5Fclose(fid_dst);
+ H5Fclose(fid_src);
+ } H5E_END_TRY;
+ return 1;
+} /* end test_copy_named_datatype_attr_self */
/*-------------------------------------------------------------------------
@@ -7803,7 +7946,7 @@ error:
* Failure: number of errors
*
* Programmer: Neil Fortner
- * Wednesday, March 31, 2005
+ * Wednesday, March 31, 2010
*
*-------------------------------------------------------------------------
*/
@@ -8333,7 +8476,7 @@ main(void)
}
else {
puts("Testing without dense attributes:");
- num_attributes_g = MAX(min_dense, 2) - 1;
+ num_attributes_g = MAX(min_dense, 2) - 2;
}
} /* end if */
else {
@@ -8343,6 +8486,7 @@ main(void)
} /* end else */
/* The tests... */
+ nerrors += test_copy_named_datatype_attr_self(fcpl_src, fcpl_dst, my_fapl);
nerrors += test_copy_dataset_simple(fcpl_src, fcpl_dst, my_fapl);
nerrors += test_copy_dataset_simple_samefile(fcpl_src, my_fapl);
nerrors += test_copy_dataset_simple_empty(fcpl_src, fcpl_dst, my_fapl);