diff options
-rw-r--r-- | src/H5Gcompact.c | 71 | ||||
-rw-r--r-- | src/H5Gdense.c | 41 | ||||
-rw-r--r-- | src/H5Glink.c | 66 | ||||
-rw-r--r-- | src/H5Gpkg.h | 2 | ||||
-rw-r--r-- | src/H5L.c | 48 | ||||
-rw-r--r-- | src/H5Lpublic.h | 2 | ||||
-rw-r--r-- | src/H5O.c | 13 | ||||
-rw-r--r-- | src/H5Olayout.c | 22 | ||||
-rw-r--r-- | src/H5Olink.c | 62 | ||||
-rw-r--r-- | src/H5Oprivate.h | 6 | ||||
-rw-r--r-- | src/H5Oshared.c | 18 | ||||
-rw-r--r-- | test/links.c | 20 |
12 files changed, 180 insertions, 191 deletions
diff --git a/src/H5Gcompact.c b/src/H5Gcompact.c index 50e661b..9dd9275 100644 --- a/src/H5Gcompact.c +++ b/src/H5Gcompact.c @@ -38,7 +38,7 @@ typedef struct { H5G_link_table_t *ltable; /* Pointer to link table to build */ size_t curr_lnk; /* Current link to operate on */ -} H5G_compact_ud1_t; +} H5G_iter_bt_t; /* User data for deleting a link in the link messages */ typedef struct { @@ -49,20 +49,9 @@ typedef struct { /* upward */ H5G_obj_t *obj_type; /* Type of object deleted */ -} H5G_compact_ud2_t; +} H5G_iter_rm_t; -/* User data for link message iteration when querying object info */ -typedef struct { - /* downward */ - const char *name; /* Name to search for */ - H5F_t *file; /* File that object header is located within */ - hid_t dxpl_id; /* DXPL during insertion */ - - /* upward */ - H5G_stat_t *statbuf; /* Stat buffer for info */ -} H5G_compact_ud3_t; - -/* User data for link message iteration when querying object location */ +/* User data for link message iteration when querying link info */ typedef struct { /* downward */ const char *name; /* Name to search for */ @@ -70,17 +59,7 @@ typedef struct { /* upward */ H5O_link_t *lnk; /* Link struct to fill in */ hbool_t found; /* Flag to indicate that the object was found */ -} H5G_compact_ud4_t; - -/* User data for link message iteration when querying soft link value */ -typedef struct { - /* downward */ - const char *name; /* Name to search for */ - size_t size; /* Buffer size for link value */ - - /* upward */ - char *buf; /* Buffer to fill with link value */ -} H5G_compact_ud5_t; +} H5G_iter_lkp_t; /* Private macros */ @@ -109,7 +88,7 @@ static herr_t H5G_compact_build_table_cb(const void *_mesg, unsigned UNUSED idx, void *_udata) { const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */ - H5G_compact_ud1_t *udata = (H5G_compact_ud1_t *)_udata; /* 'User data' passed in */ + H5G_iter_bt_t *udata = (H5G_iter_bt_t *)_udata; /* 'User data' passed in */ herr_t ret_value=H5O_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_compact_build_table_cb) @@ -164,7 +143,7 @@ H5G_compact_build_table(H5O_loc_t *oloc, hid_t dxpl_id, const H5O_linfo_t *linfo /* Allocate space for the table entries */ if(ltable->nlinks > 0) { - H5G_compact_ud1_t udata; /* User data for iteration callback */ + H5G_iter_bt_t udata; /* User data for iteration callback */ if((ltable->lnks = H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") @@ -376,7 +355,7 @@ static herr_t H5G_compact_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata) { const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */ - H5G_compact_ud2_t *udata = (H5G_compact_ud2_t *)_udata; /* 'User data' passed in */ + H5G_iter_rm_t *udata = (H5G_iter_rm_t *)_udata; /* 'User data' passed in */ herr_t ret_value = H5O_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_compact_remove_cb) @@ -387,32 +366,10 @@ H5G_compact_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata) /* If we've found the right link, get the object type */ if(HDstrcmp(lnk->name, udata->name) == 0) { - switch(lnk->type) - { - case H5L_TYPE_HARD: - { - H5O_loc_t tmp_oloc; /* Temporary object location */ - - /* Build temporary object location */ - tmp_oloc.file = udata->file; - tmp_oloc.addr = lnk->u.hard.addr; - - /* Get the type of the object */ - /* Note: no way to check for error :-( */ - *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id); - } - break; - - case H5L_TYPE_SOFT: - *(udata->obj_type) = H5G_LINK; - break; - - default: /* User-defined link */ - if(lnk->type < H5L_TYPE_UD_MIN) - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unknown link type") - - *(udata->obj_type) = H5G_UDLINK; - } + /* Determine the object's type */ + if(H5G_link_obj_type(udata->file, udata->dxpl_id, lnk, udata->obj_type) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5O_ITER_ERROR, "unable to get object type") + /* Stop the iteration, we found the correct link */ HGOTO_DONE(H5O_ITER_STOP) } /* end if */ @@ -438,7 +395,7 @@ herr_t H5G_compact_remove(const H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id) { - H5G_compact_ud2_t udata; /* Data to pass through OH iteration */ + H5G_iter_rm_t udata; /* Data to pass through OH iteration */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_compact_remove, FAIL) @@ -543,7 +500,7 @@ static herr_t H5G_compact_lookup_cb(const void *_mesg, unsigned UNUSED idx, void *_udata) { const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */ - H5G_compact_ud4_t *udata = (H5G_compact_ud4_t *)_udata; /* 'User data' passed in */ + H5G_iter_lkp_t *udata = (H5G_iter_lkp_t *)_udata; /* 'User data' passed in */ herr_t ret_value = H5O_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_compact_lookup_cb) @@ -589,7 +546,7 @@ herr_t H5G_compact_lookup(H5O_loc_t *oloc, const char *name, H5O_link_t *lnk, hid_t dxpl_id) { - H5G_compact_ud4_t udata; /* User data for iteration callback */ + H5G_iter_lkp_t udata; /* User data for iteration callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_compact_lookup, FAIL) diff --git a/src/H5Gdense.c b/src/H5Gdense.c index 3b8be2f..4213076 100644 --- a/src/H5Gdense.c +++ b/src/H5Gdense.c @@ -1352,39 +1352,14 @@ H5G_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata) HGOTO_ERROR(H5E_SYM, H5E_CANTREMOVE, H5B2_ITER_ERROR, "unable to remove link from creation order index v2 B-tree") } /* end if */ - /* Retrieve the link's object type & decr. the ref. count on hard links, if requested */ - switch(lnk->type) { - case H5L_TYPE_HARD: - { - H5O_loc_t tmp_oloc; /* Temporary object location */ - - /* Build temporary object location */ - tmp_oloc.file = udata->f; - tmp_oloc.addr = lnk->u.hard.addr; - - /* Get the type of the object */ - /* Note: no way to check for error :-( */ - if(udata->obj_type) - *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id); - - /* Decrement the ref count for the object, if requested */ - if(udata->adj_link) - if(H5O_link(&tmp_oloc, -1, udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to decrement object link count") - } - break; - - case H5L_TYPE_SOFT: - if(udata->obj_type) - *(udata->obj_type) = H5G_LINK; - break; - - default: /* User-defined link */ - if(lnk->type < H5L_TYPE_UD_MIN) - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unknown link type") - if(udata->obj_type) - *(udata->obj_type) = H5G_UDLINK; - } /* end switch */ + /* Determine the object's type */ + if(H5G_link_obj_type(udata->f, udata->dxpl_id, lnk, udata->obj_type) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object type") + + /* Perform the deletion action on the link */ + /* (call link message "delete" callback directly: *ick* - QAK) */ + if(H5O_link_delete(udata->f, udata->dxpl_id, lnk, udata->adj_link) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link") /* Release the space allocated for the link */ H5O_free(H5O_LINK_ID, lnk); diff --git a/src/H5Glink.c b/src/H5Glink.c index 0600e97..9144096 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -37,6 +37,9 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ +#include "H5MMprivate.h" /* Memory management */ /****************/ @@ -418,3 +421,66 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_link_release_table() */ + +/*------------------------------------------------------------------------- + * Function: H5G_link_obj_type + * + * Purpose: Determine the type of object referred to (for hard links) or + * the link type (for soft links and user-defined links). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Nov 13 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_link_obj_type(H5F_t *file, hid_t dxpl_id, const H5O_link_t *lnk, + H5G_obj_t *obj_type) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_link_obj_type, FAIL) + + /* check arguments */ + HDassert(file); + HDassert(lnk); + + /* Check if we are able to retrieve the object's type */ + if(obj_type) { + /* Look up the object type for each type of link */ + switch(lnk->type) { + case H5L_TYPE_HARD: + { + H5O_loc_t tmp_oloc; /* Temporary object location */ + + /* Build temporary object location */ + tmp_oloc.file = file; + tmp_oloc.addr = lnk->u.hard.addr; + + /* Get the type of the object */ + /* Note: no way to check for error :-( */ + *obj_type = H5O_obj_type(&tmp_oloc, dxpl_id); + } + break; + + case H5L_TYPE_SOFT: + /* Get the object's type */ + *obj_type = H5G_LINK; + break; + + default: /* User-defined link */ + if(lnk->type < H5L_TYPE_UD_MIN) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unknown link type") + + /* Get the object's type */ + *obj_type = H5G_UDLINK; + } /* end switch */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_link_obj_type() */ + diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index b3dc299..47342dd 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -423,6 +423,8 @@ H5_DLL herr_t H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk, const H5O_loc_t *src_oloc, H5O_link_t *dst_lnk, H5O_copy_t *cpy_info); H5_DLL herr_t H5G_link_release_table(H5G_link_table_t *ltable); +H5_DLL herr_t H5G_link_obj_type(H5F_t *file, hid_t dxpl_id, const H5O_link_t *lnk, + H5G_obj_t *obj_type); /* Functions that understand "compact" link storage */ H5_DLL herr_t H5G_compact_insert(H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk, @@ -1958,10 +1958,6 @@ H5L_delete_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSE H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { H5L_trav_rm_t *udata = (H5L_trav_rm_t *)_udata; /* User data passed in */ - 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; /* Temporary location has been initialized? */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5L_delete_cb) @@ -1974,55 +1970,11 @@ H5L_delete_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSE if(lnk == NULL) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "can't delete self") - /* If there is a user-defined callback, call it before deleting the link */ - if(lnk->type >= H5L_TYPE_UD_MIN) - { - const H5L_class_t *link_class; /* User-defined link class */ - - /* Get the link class for this type of link. */ - if(NULL == (link_class = H5L_find_class(lnk->type))) - HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class not registered") - - if(link_class->del_func != NULL) - { - H5O_loc_t temp_oloc; - H5G_name_t temp_path; - - H5G_name_reset(&temp_path); - - /* Get object location for link's parent group */ - if(H5O_loc_copy(&temp_oloc, grp_loc->oloc, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location") - - temp_loc.oloc = &temp_oloc; - temp_loc.path = &temp_path; - temp_loc_init = TRUE; - - /* Set up group for user-defined callback */ - if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group") - if((grp_id = H5I_register(H5I_GROUP, grp)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") - - /* Call user-defined link's 'delete' callback */ - if((link_class->del_func)(name, grp_id, lnk->u.ud.udata, lnk->u.ud.size) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "link deletion callback returned failure") - } /* end if */ - } /* end if */ - /* Remove the link from the group */ if(H5G_loc_remove(grp_loc, name, obj_loc, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to remove link from group") done: - /* Close the location given to the user callback if it was created */ - if(grp_id >= 0) - H5I_dec_ref(grp_id); - else if(grp != NULL) - H5G_close(grp); - else if(temp_loc_init) - H5G_loc_free(&temp_loc); - /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h index d8744ca..f003173 100644 --- a/src/H5Lpublic.h +++ b/src/H5Lpublic.h @@ -101,7 +101,7 @@ typedef herr_t (*H5L_copy_func_t)(const char * new_name, hid_t new_loc, void * u typedef herr_t (*H5L_traverse_func_t)(const char * link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id); /* Callback for when the link is deleted */ -typedef herr_t (*H5L_delete_func_t)(const char * link_name, hid_t loc_group, void * udata, size_t udata_size); +typedef herr_t (*H5L_delete_func_t)(const char * link_name, hid_t file, void * udata, size_t udata_size); /* Callback for querying the link */ /* Returns the size of the buffer needed */ @@ -4350,8 +4350,8 @@ done: static herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link) { - const H5O_msg_class_t *type; /* Type of object to free */ - herr_t ret_value=SUCCEED; /* Return value */ + const H5O_msg_class_t *type; /* Type of object to free */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_delete_mesg) @@ -4369,13 +4369,10 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link) /* Check if there is a file space deletion callback for this type of message */ if(type->del) { - /* - * Decode the message if necessary. - */ + /* Decode the message if necessary. */ if(NULL == mesg->native) { HDassert(type->decode); - mesg->native = (type->decode) (f, dxpl_id, mesg->raw); - if(NULL == mesg->native) + if(NULL == (mesg->native = (type->decode)(f, dxpl_id, mesg->raw))) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message") } /* end if */ @@ -4955,7 +4952,7 @@ H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5_copy_depth_t depth) /* Deep copy the names */ if(depth == H5_COPY_DEEP) { - /* If the original entry has holding open the file, this one should + /* If the original entry was holding open the file, this one should * hold it open, too. */ if(src->holding_file) diff --git a/src/H5Olayout.c b/src/H5Olayout.c index a420301..3b4d7e5 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -38,7 +38,8 @@ static void *H5O_layout_copy(const void *_mesg, void *_dest, unsigned update_fla static size_t H5O_layout_size(const H5F_t *f, const void *_mesg); static herr_t H5O_layout_reset(void *_mesg); static herr_t H5O_layout_free(void *_mesg); -static herr_t H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); +static herr_t H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, + hbool_t adj_link); static void *H5O_layout_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type, void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_layout_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, @@ -567,16 +568,17 @@ H5O_layout_free (void *_mesg) *------------------------------------------------------------------------- */ static herr_t -H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t UNUSED adj_link) +H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, + hbool_t UNUSED adj_link) { - const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; - herr_t ret_value=SUCCEED; /* Return value */ + const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_layout_delete); + FUNC_ENTER_NOAPI_NOINIT(H5O_layout_delete) /* check args */ - assert(f); - assert(mesg); + HDassert(f); + HDassert(mesg); /* Perform different actions, depending on the type of storage */ switch(mesg->type) { @@ -586,13 +588,13 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t UNUSED adj case H5D_CONTIGUOUS: /* Contiguous block on disk */ /* Free the file space for the raw data */ - if (H5D_contig_delete(f, dxpl_id, mesg)<0) + if(H5D_contig_delete(f, dxpl_id, mesg) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") break; case H5D_CHUNKED: /* Chunked blocks on disk */ /* Free the file space for the raw data */ - if (H5D_istore_delete(f, dxpl_id, mesg)<0) + if(H5D_istore_delete(f, dxpl_id, mesg) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free raw data") break; @@ -601,7 +603,7 @@ H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t UNUSED adj } /* end switch */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_layout_delete() */ diff --git a/src/H5Olink.c b/src/H5Olink.c index 9331019..8b7afbb 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -30,6 +30,8 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free lists */ #include "H5Gpkg.h" /* Groups */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ @@ -41,7 +43,7 @@ static void *H5O_link_copy(const void *_mesg, void *_dest, unsigned update_flags static size_t H5O_link_size(const H5F_t *f, const void *_mesg); static herr_t H5O_link_reset(void *_mesg); static herr_t H5O_link_free(void *_mesg); -static herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); +/* static herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); */ static herr_t H5O_link_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata); static void *H5O_link_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type, @@ -489,31 +491,61 @@ H5O_link_free(void *_mesg) * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link) { const H5O_link_t *lnk = (const H5O_link_t *)_mesg; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_link_delete) + FUNC_ENTER_NOAPI(H5O_link_delete, FAIL) /* check args */ HDassert(f); HDassert(lnk); - /* Decrement reference count to the object (if requested), for hard links */ - if(lnk->type == H5L_TYPE_HARD && adj_link) { - H5O_loc_t oloc; - - /* Construct object location for object, in order to decrement it's ref count */ - H5O_loc_reset(&oloc); - oloc.file = f; - HDassert(H5F_addr_defined(lnk->u.hard.addr)); - oloc.addr = lnk->u.hard.addr; + /* Check for adjusting the link count when the link is removed */ + if(adj_link) { + /* Adjust the reference count of the object when a hard link is removed */ + if(lnk->type == H5L_TYPE_HARD) { + H5O_loc_t oloc; + + /* Construct object location for object, in order to decrement it's ref count */ + H5O_loc_reset(&oloc); + oloc.file = f; + HDassert(H5F_addr_defined(lnk->u.hard.addr)); + oloc.addr = lnk->u.hard.addr; + + /* Decrement the ref count for the object */ + if(H5O_link(&oloc, -1, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to decrement object link count") + } /* end if */ + /* Perform the "delete" callback when a user-defined link is removed */ + else if(lnk->type >= H5L_TYPE_UD_MIN) { + const H5L_class_t *link_class; /* User-defined link class */ + + /* Get the link class for this type of link. */ + if(NULL == (link_class = H5L_find_class(lnk->type))) + HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class not registered") + + /* Check for delete callback */ + if(link_class->del_func) { + hid_t file_id; /* ID for the file the link is located in (passed to user callback) */ + + /* Get a file ID for the file the link is in */ + if((file_id = H5F_get_id(f)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get file ID") + + /* Call user-defined link's 'delete' callback */ + if((link_class->del_func)(lnk->name, file_id, lnk->u.ud.udata, lnk->u.ud.size) < 0) { + H5I_dec_ref(file_id); + HGOTO_ERROR(H5E_OHDR, H5E_CALLBACK, FAIL, "link deletion callback returned failure") + } /* end if */ - /* Decrement the ref count for the object */ - if(H5O_link(&oloc, -1, dxpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to decrement object link count") + /* Release the file ID */ + if(H5I_dec_ref(file_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "can't close file") + } /* end if */ + } /* end if */ } /* end if */ done: diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 5aa7c87..30ea804 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -450,4 +450,8 @@ H5_DLL hsize_t H5O_efl_total_size(H5O_efl_t *efl); /* Fill value operators */ H5_DLL herr_t H5O_fill_convert(void *_fill, H5T_t *type, hid_t dxpl_id); -#endif +/* Link operators */ +H5_DLL herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); + +#endif /* _H5Oprivate_H */ + diff --git a/src/H5Oshared.c b/src/H5Oshared.c index 7c69ab9..e90031d 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -42,7 +42,8 @@ static void *H5O_shared_decode (H5F_t*, hid_t dxpl_id, const uint8_t*); static herr_t H5O_shared_encode (H5F_t*, uint8_t*, const void*); static void *H5O_shared_copy(const void *_mesg, void *_dest, unsigned update_flags); static size_t H5O_shared_size (const H5F_t*, const void *_mesg); -static herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link); +static herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, + hbool_t adj_link); static herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg); static herr_t H5O_shared_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type, void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *_udata); @@ -512,16 +513,17 @@ H5O_shared_size (const H5F_t *f, const void *_mesg) *------------------------------------------------------------------------- */ static herr_t -H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link) +H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, + hbool_t adj_link) { const H5O_shared_t *shared = (const H5O_shared_t *) _mesg; - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_shared_delete); + FUNC_ENTER_NOAPI_NOINIT(H5O_shared_delete) /* check args */ - assert(f); - assert(shared); + HDassert(f); + HDassert(shared); /* * Committed datatypes increment the OH of the original message when they @@ -534,7 +536,7 @@ H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link) /* Decrement the reference count on the shared object, if requested */ if(adj_link) - if(H5O_shared_link_adj(f, dxpl_id, shared, -1)<0) + if(H5O_shared_link_adj(f, dxpl_id, shared, -1) < 0) HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count") /* JAMES */ @@ -542,7 +544,7 @@ H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link) H5O_loc_free(&(shared->oloc)); */ done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_shared_delete() */ diff --git a/test/links.c b/test/links.c index 7a3a4c0..0c1cae2 100644 --- a/test/links.c +++ b/test/links.c @@ -3679,7 +3679,7 @@ done: /* UD_hard_delete decrements the object's reference count */ static herr_t -UD_hard_delete(const char UNUSED * link_name, hid_t loc_group, void * udata, size_t udata_size) +UD_hard_delete(const char UNUSED * link_name, hid_t file, void * udata, size_t udata_size) { haddr_t addr; hid_t target_obj = -1; @@ -3694,7 +3694,7 @@ UD_hard_delete(const char UNUSED * link_name, hid_t loc_group, void * udata, siz addr = *((haddr_t *) udata); /* Open the object this link points to */ - target_obj= H5Oopen_by_addr(loc_group, addr); + target_obj= H5Oopen_by_addr(file, addr); if(target_obj < 0) { ret_value = -1; @@ -4134,8 +4134,8 @@ UD_cb_move(const char * new_name, hid_t new_loc, void * udata, size_t udata_size if(new_loc < 0) TEST_ERROR if(udata_size > 0 && !udata) TEST_ERROR - if(strcmp(new_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR - if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR + if(HDstrcmp(new_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR + if(HDstrcmp(udata, UD_CB_TARGET)) TEST_ERROR if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR return 0; @@ -4146,14 +4146,14 @@ error: /* Callback for when the link is deleted. Also called during move */ static herr_t -UD_cb_delete(const char * link_name, hid_t loc_group, void * udata, size_t udata_size) +UD_cb_delete(const char * link_name, hid_t file, void * udata, size_t udata_size) { if(!link_name) TEST_ERROR - if(loc_group < 0) TEST_ERROR + if(file < 0) TEST_ERROR if(udata_size > 0 && !udata) TEST_ERROR - if(strcmp(link_name, UD_CB_LINK_NAME) && strcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR - if(strcmp(udata, UD_CB_TARGET)) TEST_ERROR + if(HDstrcmp(link_name, UD_CB_LINK_NAME) && HDstrcmp(link_name, NEW_UD_CB_LINK_NAME)) TEST_ERROR + if(HDstrcmp(udata, UD_CB_TARGET)) TEST_ERROR if(udata_size != UD_CB_TARGET_LEN) TEST_ERROR return 0; @@ -4528,7 +4528,7 @@ UD_cbsucc_move(const char UNUSED * new_name, hid_t UNUSED new_loc, /* Callback for when the link is deleted. Also called during move */ static herr_t -UD_cbsucc_delete(const char UNUSED * link_name, hid_t UNUSED loc_group, +UD_cbsucc_delete(const char UNUSED * link_name, hid_t UNUSED file, void UNUSED * udata, size_t UNUSED udata_size) { /* This callback will always succeed */ @@ -4537,7 +4537,7 @@ UD_cbsucc_delete(const char UNUSED * link_name, hid_t UNUSED loc_group, /* Callback for when the link is deleted. Also called during move */ static herr_t -UD_cbfail_delete(const char UNUSED * link_name, hid_t UNUSED loc_group, +UD_cbfail_delete(const char UNUSED * link_name, hid_t UNUSED file, void UNUSED * udata, size_t UNUSED udata_size) { /* This traversal function will always fail. */ |