diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5C.c | 2 | ||||
-rw-r--r-- | src/H5D.c | 14 | ||||
-rw-r--r-- | src/H5Dint.c | 4 | ||||
-rw-r--r-- | src/H5Fpkg.h | 3 | ||||
-rw-r--r-- | src/H5Fsuper.c | 61 | ||||
-rw-r--r-- | src/H5Fsuper_cache.c | 4 | ||||
-rw-r--r-- | src/H5G.c | 16 | ||||
-rw-r--r-- | src/H5Gobj.c | 5 | ||||
-rw-r--r-- | src/H5Groot.c | 4 | ||||
-rw-r--r-- | src/H5Gtraverse.c | 10 | ||||
-rw-r--r-- | src/H5L.c | 22 | ||||
-rw-r--r-- | src/H5O.c | 57 | ||||
-rw-r--r-- | src/H5Opkg.h | 1 | ||||
-rw-r--r-- | src/H5Oprivate.h | 3 | ||||
-rw-r--r-- | src/H5Otest.c | 49 | ||||
-rw-r--r-- | src/H5Tcommit.c | 17 |
16 files changed, 231 insertions, 41 deletions
@@ -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 ) ) { @@ -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 */ @@ -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") @@ -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) @@ -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) |