summaryrefslogtreecommitdiffstats
path: root/src/H5Gname.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Gname.c')
-rw-r--r--src/H5Gname.c172
1 files changed, 93 insertions, 79 deletions
diff --git a/src/H5Gname.c b/src/H5Gname.c
index 56df3d6..1e1cf16 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -34,6 +34,7 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5Gpkg.h" /* Groups */
#include "H5Iprivate.h" /* IDs */
+#include "H5Lprivate.h" /* Links */
#include "H5MMprivate.h" /* Memory wrappers */
/* Private typedefs */
@@ -81,7 +82,8 @@ static H5RS_str_t *H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r,
static herr_t H5G_name_move_path(H5RS_str_t **path_r_ptr,
const char *full_suffix, const char *src_path, const char *dst_path);
static int H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key);
-static herr_t H5G_refname_iterator(hid_t group, const char *name, void *_iter);
+static herr_t H5G_refname_iterator(hid_t group, const char *name,
+ const H5L_info_t *link_info, void *_udata);
static herr_t H5G_free_ref_path_node(void *item, void *key, void *operator_data/*in,out*/);
@@ -1045,102 +1047,104 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_refname_iterator(hid_t group, const char *name, void *_udata)
+H5G_refname_iterator(hid_t group, const char *name, const H5L_info_t *link_info,
+ void *_udata)
{
H5G_ref_path_iter_t *udata = (H5G_ref_path_iter_t*)_udata;
- H5G_stat_t sb; /* Stat buffer for object */
- H5G_loc_t loc; /* Group location of parent */
- haddr_t objno; /* Address of current object */
- herr_t ret_value = 0; /* Return value */
+ herr_t ret_value = H5_ITER_CONT; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_refname_iterator)
- /* Look up group's location */
- if(H5G_loc(group, &loc) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
-
- /* Get information for object in group */
- if(H5G_get_objinfo(&loc, name, FALSE, &sb, udata->dxpl_id) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object")
-#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG
- objno = (haddr_t)sb.objno[0] | ((haddr_t)sb.objno[1] << (8 * sizeof(long)));
-#else
- objno = (haddr_t)sb.objno[0];
-#endif
-
- /* Check for finding the object */
- /* (checks against the file in the location as well, to make certain that
- * the correct object is found in a mounted file hierarchy)
- */
- if(udata->loc->addr == objno && udata->loc->file == loc.oloc->file) {
- size_t len_needed; /* Length of container string needed */
-
- /* Build the object's full name */
- len_needed = HDstrlen(udata->container) + HDstrlen(name) + 2;
- if(len_needed > udata->max_container_len) {
- if(NULL == (udata->container = H5MM_realloc(udata->container, len_needed)))
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate path string")
- udata->max_container_len = len_needed;
- } /* end if */
- HDstrcat(udata->container, name);
+ /* We only care about hard links */
+ if(link_info->type == H5L_TYPE_HARD) {
+ H5G_loc_t loc; /* Group location of parent */
+
+ /* Look up group's location */
+ if(H5G_loc(group, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "not a location")
+
+ /* Check for finding the object */
+ /* (checks against the file in the location as well, to make certain that
+ * the correct object is found in a mounted file hierarchy)
+ */
+ if(udata->loc->addr == link_info->u.address && udata->loc->file == loc.oloc->file) {
+ size_t len_needed; /* Length of container string needed */
+
+ /* Build the object's full name */
+ len_needed = HDstrlen(udata->container) + HDstrlen(name) + 2;
+ if(len_needed > udata->max_container_len) {
+ if(NULL == (udata->container = H5MM_realloc(udata->container, len_needed)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path string")
+ udata->max_container_len = len_needed;
+ } /* end if */
+ HDstrcat(udata->container, name);
- /* We found a match so we return immediately */
- HGOTO_DONE(1)
- } /* end if */
- else {
- /* See if we've seen this object before */
- if(H5SL_search(udata->ref_path_table, &objno))
- HGOTO_DONE(0)
+ /* We found a match so we return immediately */
+ HGOTO_DONE(H5_ITER_STOP)
+ } /* end if */
else {
- /* If not, we add it to the list of visited objects if it's ref count is > 1 */
- if(sb.nlink > 1) {
+ H5O_info_t oinfo; /* Object information */
+ H5O_loc_t tmp_oloc; /* Temporary object location */
+
+ /* Check if we've seen this object before */
+ if(H5SL_search(udata->ref_path_table, &link_info->u.address))
+ HGOTO_DONE(H5_ITER_CONT)
+
+ /* Go retrieve the object information */
+ tmp_oloc.file = loc.oloc->file;
+ tmp_oloc.addr = link_info->u.address;
+ if(H5O_get_info(&tmp_oloc, &oinfo, udata->dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "unable to get object info")
+
+ /* If its ref count is > 1, we add it to the list of visited objects */
+ if(oinfo.rc > 1) {
haddr_t *new_node; /* New path node for table */
/* Allocate new path node */
if((new_node = H5FL_MALLOC(haddr_t)) == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate path node")
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path node")
/* Set node information */
- *new_node = objno;
+ *new_node = link_info->u.address;
/* Insert into skip list */
if(H5SL_insert(udata->ref_path_table, new_node, new_node) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert path node into table")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5_ITER_ERROR, "can't insert path node into table")
} /* end if */
- } /* end else */
-
- /* If it's a group, we recurse into it */
- if(sb.type == H5G_GROUP) {
- H5G_link_iterate_t lnk_op; /* Link operator */
- hsize_t last_obj;
- size_t len_needed; /* Length of container string needed */
- size_t len;
- /* Build full path name of group to recurse into */
- len = HDstrlen(udata->container);
- len_needed = len + HDstrlen(name) + 2;
- if(len_needed > udata->max_container_len) {
- if(NULL == (udata->container = H5MM_realloc(udata->container, len_needed)))
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate path string")
- udata->max_container_len = len_needed;
- } /* end if */
- if(!udata->is_root_group)
- HDstrcat(udata->container, name);
- else
- udata->is_root_group = FALSE;
- HDstrcat(udata->container, "/");
+ /* If it's a group, we recurse into it */
+ if(oinfo.type == H5G_GROUP) {
+ H5G_link_iterate_t lnk_op; /* Link operator */
+ hsize_t last_obj;
+ size_t len_needed; /* Length of container string needed */
+ size_t len;
+
+ /* Build full path name of group to recurse into */
+ len = HDstrlen(udata->container);
+ len_needed = len + HDstrlen(name) + 2;
+ if(len_needed > udata->max_container_len) {
+ if(NULL == (udata->container = H5MM_realloc(udata->container, len_needed)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path string")
+ udata->max_container_len = len_needed;
+ } /* end if */
+ if(!udata->is_root_group)
+ HDstrcat(udata->container, name);
+ else
+ udata->is_root_group = FALSE;
+ HDstrcat(udata->container, "/");
+
+ /* Build iterator operator */
+ lnk_op.op_type = H5G_LINK_OP_APP;
+ lnk_op.u.app_op = H5G_refname_iterator;
+
+ ret_value = H5G_obj_iterate(udata->file, udata->container, H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, &last_obj, &lnk_op, udata, udata->dxpl_id);
- /* Build iterator operator */
- lnk_op.op_type = H5G_LINK_OP_OLD;
- lnk_op.u.old_op = H5G_refname_iterator;
-
- ret_value = H5G_obj_iterate(udata->file, udata->container, H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, &last_obj, &lnk_op, udata, udata->dxpl_id);
-
- /* If we didn't find the object, truncate the name to not include group name anymore */
- if(!ret_value)
- udata->container[len] = '\0';
- } /* end if */
- } /* end else */
+ /* If we didn't find the object, truncate the name to not include group name anymore */
+ if(!ret_value)
+ udata->container[len] = '\0';
+ } /* end if */
+ } /* end else */
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1199,11 +1203,20 @@ H5G_get_refobj_name(hid_t file, hid_t dxpl_id, const H5O_loc_t *loc,
char *name, size_t size)
{
H5G_ref_path_iter_t udata; /* User data for iteration */
+ H5G_loc_t root_loc; /* Root location */
+ H5L_info_t root_info; /* Link info for root group */
herr_t status; /* Status from iteration */
ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_get_refobj_name, FAIL)
+ /* Construct the link info for the root group */
+ if(H5G_loc(file, &root_loc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get root group's location")
+ HDmemset(&root_info, 0, sizeof(root_info));
+ root_info.type = H5L_TYPE_HARD;
+ root_info.u.address = root_loc.oloc->addr;
+
/* Set up user data for iterator */
udata.file = file;
udata.dxpl_id = dxpl_id;
@@ -1218,7 +1231,7 @@ H5G_get_refobj_name(hid_t file, hid_t dxpl_id, const H5O_loc_t *loc,
HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create skip list for path nodes")
/* Iterate over all the objects in the file */
- if((status = H5G_refname_iterator(file, "/", &udata)) < 0)
+ if((status = H5G_refname_iterator(file, "/", &root_info, &udata)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group iteration failed while looking for object name")
else if(status > 0) {
/* Set the length of the full path */
@@ -1235,6 +1248,7 @@ H5G_get_refobj_name(hid_t file, hid_t dxpl_id, const H5O_loc_t *loc,
ret_value = 0;
done:
+ /* Release resources */
H5MM_xfree(udata.container);
if(udata.ref_path_table)
H5SL_destroy(udata.ref_path_table, H5G_free_ref_path_node, NULL);