summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5C.c2
-rw-r--r--src/H5D.c14
-rw-r--r--src/H5Dint.c4
-rw-r--r--src/H5Fpkg.h3
-rw-r--r--src/H5Fsuper.c61
-rw-r--r--src/H5Fsuper_cache.c4
-rw-r--r--src/H5G.c16
-rw-r--r--src/H5Gobj.c5
-rw-r--r--src/H5Groot.c4
-rw-r--r--src/H5Gtraverse.c10
-rw-r--r--src/H5L.c22
-rw-r--r--src/H5O.c57
-rw-r--r--src/H5Opkg.h1
-rw-r--r--src/H5Oprivate.h3
-rw-r--r--src/H5Otest.c49
-rw-r--r--src/H5Tcommit.c17
16 files changed, 231 insertions, 41 deletions
diff --git a/src/H5C.c b/src/H5C.c
index 5b7984b..1956edb 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -7792,7 +7792,7 @@ end_of_inner_loop:
*/
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \
- "Pinned entry count not decreasing.")
+ "Pinned entry count not decreasing, cur_pel_len = %d, old_pel_len = %d", (int)cur_pel_len, (int)old_pel_len)
} else if ( ( cur_pel_len == 0 ) && ( old_pel_len == 0 ) ) {
diff --git a/src/H5D.c b/src/H5D.c
index 91a7c3e..667fe1fb 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -256,6 +256,20 @@ H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id,
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
done:
+ /* Release the dataset's object header, if it was created */
+ if(dset) {
+ H5O_loc_t *oloc; /* Object location for dataset */
+
+ /* Get the new dataset's object location */
+ if(NULL == (oloc = H5D_oloc(dset)))
+ HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get object location of dataset")
+
+ /* Decrement refcount on dataset's object header in memory */
+ if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
+ } /* end if */
+
+ /* Cleanup on failure */
if(ret_value < 0)
if(dset && H5D_close(dset) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 4c076f7..8782f58 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -789,7 +789,7 @@ H5D_update_oh_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, hid_t dapl_id)
ohdr_size += layout->storage.u.compact.size;
/* Create an object header for the dataset */
- if(H5O_create(file, dxpl_id, ohdr_size, dset->shared->dcpl_id, oloc/*out*/) < 0)
+ if(H5O_create(file, dxpl_id, ohdr_size, (size_t)1, dset->shared->dcpl_id, oloc/*out*/) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset object header")
HDassert(file == dset->oloc.file);
@@ -1063,6 +1063,8 @@ done:
if(new_dset->shared->type && H5I_dec_ref(new_dset->shared->type_id) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release datatype")
if(H5F_addr_defined(new_dset->oloc.addr)) {
+ if(H5O_dec_rc_by_loc(&(new_dset->oloc), dxpl_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
if(H5O_close(&(new_dset->oloc)) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release object header")
if(file) {
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index d264d04..4a4d49c 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -310,7 +310,8 @@ H5_DLL herr_t H5F_super_free(H5F_super_t *sblock);
H5_DLL herr_t H5F_super_ext_open(H5F_t *f, haddr_t ext_addr, H5O_loc_t *ext_ptr);
H5_DLL herr_t H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create);
H5_DLL herr_t H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id);
-H5_DLL herr_t H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr);
+H5_DLL herr_t H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr, hid_t dxpl_id,
+ hbool_t was_created);
/* Metadata accumulator routines */
H5_DLL htri_t H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type,
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index a259dde..2510487 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -204,7 +204,7 @@ H5F_super_ext_create(H5F_t *f, hid_t dxpl_id, H5O_loc_t *ext_ptr)
* extension.
*/
H5O_loc_reset(ext_ptr);
- if(H5O_create(f, dxpl_id, 0, H5P_GROUP_CREATE_DEFAULT, ext_ptr) < 0)
+ if(H5O_create(f, dxpl_id, 0, (size_t)1, H5P_GROUP_CREATE_DEFAULT, ext_ptr) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "unable to create superblock extension")
/* Record the address of the superblock extension */
@@ -267,7 +267,8 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr)
+H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr, hid_t dxpl_id,
+ hbool_t was_created)
{
herr_t ret_value = SUCCEED; /* Return value */
@@ -277,6 +278,17 @@ H5F_super_ext_close(H5F_t *f, H5O_loc_t *ext_ptr)
HDassert(f);
HDassert(ext_ptr);
+ /* Check if extension was created */
+ if(was_created) {
+ /* Increment link count on superblock extension's object header */
+ if(H5O_link(ext_ptr, 1, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_LINKCOUNT, FAIL, "unable to increment hard link count")
+
+ /* Decrement refcount on superblock extension's object header in memory */
+ if(H5O_dec_rc_by_loc(ext_ptr, dxpl_id) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to decrement refcount on superblock extension")
+ } /* end if */
+
/* Twiddle the number of open objects to avoid closing the file. */
f->nopen_objs++;
if(H5O_close(ext_ptr) < 0)
@@ -384,7 +396,9 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
hsize_t superblock_size; /* Size of superblock, in bytes */
size_t driver_size; /* Size of driver info block (bytes) */
unsigned super_vers = HDF5_SUPERBLOCK_VERSION_DEF; /* Superblock version for file */
+ H5O_loc_t ext_loc; /* Superblock extension object location */
hbool_t need_ext; /* Whether the superblock extension is needed */
+ hbool_t ext_created = FALSE; /* Whether the extension has been created */
herr_t ret_value = SUCCEED; /* Return Value */
FUNC_ENTER_NOAPI_TAG(H5F_super_init, dxpl_id, H5AC__SUPERBLOCK_TAG, FAIL)
@@ -545,8 +559,6 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
/* Create the superblock extension for "extra" superblock data, if necessary. */
if(need_ext) {
- H5O_loc_t ext_loc; /* Superblock extension object location */
-
/* The superblock extension isn't actually a group, but the
* default group creation list should work fine.
* If we don't supply a size for the object header, HDF5 will
@@ -557,6 +569,7 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
*/
if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to create superblock extension")
+ ext_created = TRUE;
/* Create the Shared Object Header Message table and register it with
* the metadata cache, if this file supports shared messages.
@@ -615,13 +628,13 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
if(H5O_msg_create(&ext_loc, H5O_FSINFO_ID, H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &fsinfo, dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update free-space info header message")
} /* end if */
-
- /* Close superblock extension */
- if(H5F_super_ext_close(f, &ext_loc) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
} /* end if */
done:
+ /* Close superblock extension, if it was created */
+ if(ext_created && H5F_super_ext_close(f, &ext_loc, dxpl_id, ext_created) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
+
/* Cleanup on failure */
if(ret_value < 0) {
/* Check if the superblock has been allocated yet */
@@ -786,7 +799,8 @@ done:
herr_t
H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_t may_create)
{
- hbool_t sblock_dirty = FALSE; /* Whether superblock was dirtied */
+ hbool_t ext_created = FALSE; /* Whether superblock extension was created */
+ hbool_t ext_opened = FALSE; /* Whether superblock extension was opened */
H5O_loc_t ext_loc; /* "Object location" for superblock extension */
htri_t status; /* Indicate whether the message exists or not */
herr_t ret_value = SUCCEED; /* Return value */
@@ -807,9 +821,10 @@ H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_
HDassert(may_create);
if(H5F_super_ext_create(f, dxpl_id, &ext_loc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "unable to create file's superblock extension")
- sblock_dirty = TRUE;
+ ext_created = TRUE;
} /* end else */
HDassert(H5F_addr_defined(ext_loc.addr));
+ ext_opened = TRUE;
/* Check if message with ID does not exist in the object header */
if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0)
@@ -833,15 +848,14 @@ H5F_super_ext_write_msg(H5F_t *f, hid_t dxpl_id, void *mesg, unsigned id, hbool_
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to write the message in object header")
} /* end else */
- /* Close the superblock extension object header */
- if(H5F_super_ext_close(f, &ext_loc) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
-
done:
- /* Mark superblock dirty in cache, if necessary */
- if(sblock_dirty)
- if(H5AC_mark_entry_dirty(f->shared->sblock) < 0)
- HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
+ /* Close the superblock extension, if it was opened */
+ if(ext_opened && H5F_super_ext_close(f, &ext_loc, dxpl_id, ext_created) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
+
+ /* Mark superblock dirty in cache, if superblock extension was created */
+ if(ext_created && H5AC_mark_entry_dirty(f->shared->sblock) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_super_ext_write_msg() */
@@ -861,9 +875,10 @@ done:
herr_t
H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id)
{
- htri_t status; /* Indicate whether the message exists or not */
H5O_loc_t ext_loc; /* "Object location" for superblock extension */
+ hbool_t ext_opened = FALSE; /* Whether the superblock extension was opened */
int null_count = 0; /* # of null messages */
+ htri_t status; /* Indicate whether the message exists or not */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_super_ext_remove_msg, FAIL)
@@ -874,6 +889,7 @@ H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id)
/* Open superblock extension object header */
if(H5F_super_ext_open(f, f->shared->sblock->ext_addr, &ext_loc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "error in starting file's superblock extension")
+ ext_opened = TRUE;
/* Check if message with ID exists in the object header */
if((status = H5O_msg_exists(&ext_loc, id, dxpl_id)) < 0)
@@ -902,10 +918,11 @@ H5F_super_ext_remove_msg(H5F_t *f, hid_t dxpl_id, unsigned id)
} /* end if */
} /* end if */
- /* Close superblock extension object header */
- if(H5F_super_ext_close(f, &ext_loc) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
done:
+ /* Close superblock extension object header, if opened */
+ if(ext_opened && H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "unable to close file's superblock extension")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F_super_ext_remove_msg() */
diff --git a/src/H5Fsuper_cache.c b/src/H5Fsuper_cache.c
index f9a29e8..56f9219 100644
--- a/src/H5Fsuper_cache.c
+++ b/src/H5Fsuper_cache.c
@@ -595,7 +595,7 @@ H5F_sblock_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata)
} /* end if */
/* Close superblock extension */
- if(H5F_super_ext_close(f, &ext_loc) < 0)
+ if(H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, NULL, "unable to close file's superblock extension")
} /* end if */
@@ -794,7 +794,7 @@ H5F_sblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t UNUSED addr,
HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "unable to update driver info header message")
/* Close the superblock extension object header */
- if(H5F_super_ext_close(f, &ext_loc) < 0)
+ if(H5F_super_ext_close(f, &ext_loc, dxpl_id, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close file's superblock extension")
} /* end if */
} /* end if */
diff --git a/src/H5G.c b/src/H5G.c
index 18e6403..6da8ec6 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -353,6 +353,20 @@ H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
+ /* Release the group's object header, if it was created */
+ if(grp) {
+ H5O_loc_t *oloc; /* Object location for group */
+
+ /* Get the new group's object location */
+ if(NULL == (oloc = H5G_oloc(grp)))
+ HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object location of group")
+
+ /* Decrement refcount on group's object header in memory */
+ if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
+ } /* end if */
+
+ /* Cleanup on failure */
if(ret_value < 0)
if(grp && H5G_close(grp) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
@@ -901,6 +915,8 @@ done:
if(ret_value == NULL) {
/* Check if we need to release the file-oriented symbol table info */
if(oloc_init) {
+ if(H5O_dec_rc_by_loc(&(grp->oloc), dxpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object")
if(H5O_close(&(grp->oloc)) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "unable to release object header")
if(H5O_delete(file, dxpl_id, grp->oloc.addr) < 0)
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
index ce11990..b0add06 100644
--- a/src/H5Gobj.c
+++ b/src/H5Gobj.c
@@ -160,8 +160,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, H5G_obj_create_t *gcrt_info,
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get group info")
/* Call the "real" group creation routine now */
- if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcrt_info, oloc)
- < 0)
+ if(H5G_obj_create_real(f, dxpl_id, &ginfo, &linfo, &pline, gcrt_info, oloc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "unable to create group")
done:
@@ -264,7 +263,7 @@ H5G_obj_create_real(H5F_t *f, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
* since nothing refers to it yet. The link count will be
* incremented if the object is added to the group directed graph.
*/
- if(H5O_create(f, dxpl_id, hdr_size, gcpl_id, oloc/*out*/) < 0)
+ if(H5O_create(f, dxpl_id, hdr_size, (size_t)1, gcpl_id, oloc/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header")
/* Check for format of group to create */
diff --git a/src/H5Groot.c b/src/H5Groot.c
index a79a5dd..b8ba0fd 100644
--- a/src/H5Groot.c
+++ b/src/H5Groot.c
@@ -148,6 +148,10 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root)
if(1 != H5O_link(root_loc.oloc, 1, dxpl_id))
HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)")
+ /* Decrement refcount on root group's object header in memory */
+ if(H5O_dec_rc_by_loc(root_loc.oloc, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on root group's object header")
+
/* Mark superblock dirty, so root group info is flushed */
sblock_dirty = TRUE;
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index 4016068..bb8e590 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -792,15 +792,17 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
gcrt_info.gcpl_id = H5P_GROUP_CREATE_DEFAULT;
gcrt_info.cache_type = H5G_NOTHING_CACHED;
HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache));
- if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo,
- pline, &gcrt_info, obj_loc.oloc/*out*/) < 0)
+ if(H5G_obj_create_real(grp_oloc.file, dxpl_id, ginfo, linfo, pline, &gcrt_info, obj_loc.oloc/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
/* Insert new group into current group's symbol table */
- if(H5G_loc_insert(&grp_loc, H5G_comp_g, &obj_loc,
- H5O_TYPE_GROUP, &gcrt_info, dxpl_id) < 0)
+ if(H5G_loc_insert(&grp_loc, H5G_comp_g, &obj_loc, H5O_TYPE_GROUP, &gcrt_info, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert intermediate group")
+ /* Decrement refcount on intermediate group's object header in memory */
+ if(H5O_dec_rc_by_loc(obj_loc.oloc, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
+
/* Close new group */
if(H5O_close(obj_loc.oloc) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close")
diff --git a/src/H5L.c b/src/H5L.c
index 64e194a..9319e2c 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -1664,8 +1664,9 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED
H5G_t *grp = NULL; /* H5G_t for this group, opened to pass to user callback */
hid_t grp_id = FAIL; /* Id for this group (passed to user callback */
H5G_loc_t temp_loc; /* For UD callback */
- hbool_t temp_loc_init = FALSE;
- herr_t ret_value = SUCCEED; /* Return value */
+ hbool_t temp_loc_init = FALSE; /* Temporary location for UD callback (temp_loc) has been initialized */
+ hbool_t obj_created = FALSE; /* Whether an object was created (through a hard link) */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5L_link_cb)
@@ -1690,6 +1691,9 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED
/* Set object path to use for setting object name (below) */
udata->path = new_loc.path;
+
+ /* Indicate that an object was created */
+ obj_created = TRUE;
} /* end if */
else {
/* Check that both objects are in same file */
@@ -1763,6 +1767,20 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED
} /* end if */
done:
+ /* Check if an object was created */
+ if(obj_created) {
+ H5O_loc_t oloc; /* Object location for created object */
+
+ /* Set up object location */
+ HDmemset(&oloc, 0, sizeof(oloc));
+ oloc.file = grp_loc->oloc->file;
+ oloc.addr = udata->lnk->u.hard.addr;
+
+ /* Decrement refcount on superblock extension's object header in memory */
+ if(H5O_dec_rc_by_loc(&oloc, udata->dxpl_id) < 0)
+ HDONE_ERROR(H5E_LINK, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
+ } /* end if */
+
/* Close the location given to the user callback if it was created */
if(grp_id >= 0) {
if(H5I_dec_app_ref(grp_id) < 0)
diff --git a/src/H5O.c b/src/H5O.c
index eae83df..c160d3e 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -1106,14 +1106,15 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
- H5O_loc_t *loc/*out*/)
+H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, size_t initial_rc,
+ hid_t ocpl_id, H5O_loc_t *loc/*out*/)
{
H5P_genplist_t *oc_plist; /* Object creation property list */
H5O_t *oh = NULL; /* Object header created */
haddr_t oh_addr; /* Address of initial object header */
size_t oh_size; /* Size of initial object header */
uint8_t oh_flags; /* Object header's initial status flags */
+ unsigned insert_flags = H5AC__NO_FLAGS_SET; /* Flags for inserting object header into cache */
hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */
herr_t ret_value = SUCCEED; /* return value */
@@ -1243,11 +1244,18 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id,
oh->mesg[0].raw_size = size_hint - (size_t)H5O_SIZEOF_MSGHDR_OH(oh);
oh->mesg[0].chunkno = 0;
+ /* Check for non-zero initial refcount on the object header */
+ if(initial_rc > 0) {
+ /* Set the initial refcount & pin the header when its inserted */
+ oh->rc = initial_rc;
+ insert_flags |= H5AC__PIN_ENTRY_FLAG;
+ } /* end if */
+
/* Set metadata tag in dxpl_id */
H5_BEGIN_TAG(dxpl_id, oh_addr, FAIL);
/* Cache object header */
- if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR, oh_addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR, oh_addr, oh, insert_flags) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
oh = NULL;
@@ -3422,6 +3430,49 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_dec_rc_by_loc
+ *
+ * Purpose: Decrement the refcount of an object header, using its
+ * object location information.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 08 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_dec_rc_by_loc(const H5O_loc_t *loc, hid_t dxpl_id)
+{
+ H5O_t *oh = NULL; /* Object header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_dec_rc_by_loc, FAIL)
+
+ /* check args */
+ HDassert(loc);
+
+ /* Get header */
+ if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
+
+ /* Decrement the reference count on the object header */
+ /* (which will unpin it, if appropriate) */
+ if(H5O_dec_rc(oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement reference count on object header")
+
+done:
+ /* Release the object header from the cache */
+ if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_dec_rc_by_loc() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_free
*
* Purpose: Destroys an object header.
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index a14d471..54e7233 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -610,6 +610,7 @@ H5_DLL herr_t H5O_num_attrs_test(hid_t oid, hsize_t *nattrs);
H5_DLL herr_t H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count);
H5_DLL herr_t H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val);
H5_DLL herr_t H5O_expunge_chunks_test(const H5O_loc_t *oloc, hid_t dxpl_id);
+H5_DLL herr_t H5O_get_rc(const H5O_loc_t *oloc, hid_t dxpl_id, unsigned *rc);
#endif /* H5O_TESTING */
/* Object header debugging routines */
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 63264d8..c0bff03 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -623,13 +623,14 @@ struct H5P_genplist_t;
/* Object header routines */
H5_DLL herr_t H5O_init(void);
H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint,
- hid_t ocpl_id, H5O_loc_t *loc/*out*/);
+ size_t initial_rc, hid_t ocpl_id, H5O_loc_t *loc/*out*/);
H5_DLL herr_t H5O_open(H5O_loc_t *loc);
H5_DLL herr_t H5O_close(H5O_loc_t *loc);
H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id);
H5_DLL H5O_t *H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, H5AC_protect_t prot);
H5_DLL H5O_t *H5O_pin(const H5O_loc_t *loc, hid_t dxpl_id);
H5_DLL herr_t H5O_unpin(H5O_t *oh);
+H5_DLL herr_t H5O_dec_rc_by_loc(const H5O_loc_t *loc, hid_t dxpl_id);
H5_DLL herr_t H5O_unprotect(const H5O_loc_t *loc, hid_t dxpl_id, H5O_t *oh,
unsigned oh_flags);
H5_DLL herr_t H5O_touch(const H5O_loc_t *loc, hbool_t force, hid_t dxpl_id);
diff --git a/src/H5Otest.c b/src/H5Otest.c
index 557ac9e..883bfcd 100644
--- a/src/H5Otest.c
+++ b/src/H5Otest.c
@@ -536,3 +536,52 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_expunge_chunks_test() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5O_get_rc
+ PURPOSE
+ Retrieve the refcount for the object header
+ USAGE
+ herr_t H5O_expunge_chunks_test(loc, dxpl_id, rc)
+ const H5O_loc_t *loc; IN: Object location for object header to query
+ hid_t dxpl_id; IN: DXPL to use for operation
+ unsigned *rc; OUT: Pointer to refcount for object header
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Protects object header, retrieves the object header's refcount, and
+ unprotects object header.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5O_get_rc(const H5O_loc_t *loc, hid_t dxpl_id, unsigned *rc)
+{
+ H5O_t *oh = NULL; /* Object header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_get_rc, FAIL)
+
+ /* Sanity check */
+ HDassert(loc);
+ HDassert(rc);
+
+ /* Get the object header */
+ if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
+
+ /* Save the refcount for the object header */
+ *rc = oh->nlink;
+
+done:
+ /* Release the object header */
+ if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_expunge_chunks_test() */
+
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index b924b61..e109f95 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -302,6 +302,19 @@ H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id)
if(H5T_commit(loc.oloc->file, type, tcpl_id, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype")
+ /* Release the datatype's object header */
+ {
+ H5O_loc_t *oloc; /* Object location for datatype */
+
+ /* Get the new committed datatype's object location */
+ if(NULL == (oloc = H5T_oloc(type)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get object location of committed datatype")
+
+ /* Decrement refcount on committed datatype's object header in memory */
+ if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
+ } /* end if */
+
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Tcommit_anon() */
@@ -379,7 +392,7 @@ H5T_commit(H5F_t *file, H5T_t *type, hid_t tcpl_id, hid_t dxpl_id)
* Create the object header and open it for write access. Insert the data
* type message and then give the object header a name.
*/
- if(H5O_create(file, dxpl_id, dtype_size, tcpl_id, &temp_oloc) < 0)
+ if(H5O_create(file, dxpl_id, dtype_size, (size_t)1, tcpl_id, &temp_oloc) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create datatype object header")
if(H5O_msg_create(&temp_oloc, H5O_DTYPE_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, type, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message")
@@ -415,6 +428,8 @@ done:
H5G_name_free(&temp_path);
} /* end if */
if((type->shared->state == H5T_STATE_TRANSIENT || type->shared->state == H5T_STATE_RDONLY) && (type->sh_loc.type == H5O_SHARE_TYPE_COMMITTED)) {
+ if(H5O_dec_rc_by_loc(&(type->oloc), dxpl_id) < 0)
+ HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
if(H5O_close(&(type->oloc)) < 0)
HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release object header")
if(H5O_delete(file, dxpl_id, type->sh_loc.u.loc.oh_addr) < 0)