summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Gcompact.c71
-rw-r--r--src/H5Gdense.c41
-rw-r--r--src/H5Glink.c66
-rw-r--r--src/H5Gpkg.h2
-rw-r--r--src/H5L.c48
-rw-r--r--src/H5Lpublic.h2
-rw-r--r--src/H5O.c13
-rw-r--r--src/H5Olayout.c22
-rw-r--r--src/H5Olink.c62
-rw-r--r--src/H5Oprivate.h6
-rw-r--r--src/H5Oshared.c18
-rw-r--r--test/links.c20
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,
diff --git a/src/H5L.c b/src/H5L.c
index 1dff29d..2b2363d 100644
--- a/src/H5L.c
+++ b/src/H5L.c
@@ -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 */
diff --git a/src/H5O.c b/src/H5O.c
index 89194b5..5a7d1f0 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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. */