diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-03-06 15:06:05 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-03-06 15:06:05 (GMT) |
commit | 509b8f645deadb880ea09ca5d89f9a28526d78ec (patch) | |
tree | 6dccced9fa3cb2ab60bb5cdb019fd6faceb831f1 /src | |
parent | a8251f3467bf00e5f1dbe086c96e404ad029a677 (diff) | |
download | hdf5-509b8f645deadb880ea09ca5d89f9a28526d78ec.zip hdf5-509b8f645deadb880ea09ca5d89f9a28526d78ec.tar.gz hdf5-509b8f645deadb880ea09ca5d89f9a28526d78ec.tar.bz2 |
[svn-r13465] Description:
Fix bug in external links when "strong" file close degree is used.
Make external link callbacks use standard error reporting mechanisms.
Other minor code cleanups...
Tested on:
Mac OS X/32 10.4.8 (amazon)
FreeBSD/32 6.2 (duty)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5F.c | 168 | ||||
-rw-r--r-- | src/H5Fpkg.h | 1 | ||||
-rw-r--r-- | src/H5Fprivate.h | 8 | ||||
-rw-r--r-- | src/H5Fsuper.c | 4 | ||||
-rw-r--r-- | src/H5Gloc.c | 70 | ||||
-rw-r--r-- | src/H5Gpkg.h | 1 | ||||
-rw-r--r-- | src/H5I.c | 12 | ||||
-rw-r--r-- | src/H5Lexternal.c | 158 | ||||
-rw-r--r-- | src/H5O.c | 71 | ||||
-rw-r--r-- | src/H5Oprivate.h | 1 |
10 files changed, 311 insertions, 183 deletions
@@ -972,27 +972,6 @@ done: * matzke@llnl.gov * Jul 18 1997 * - * Modifications: - * - * Robb Matzke, 1998-10-14 - * Nothing happens unless the reference count for the H5F_t goes to - * zero. The reference counts are decremented here. - * - * Robb Matzke, 1999-02-19 - * More careful about decrementing reference counts so they don't go - * negative or wrap around to some huge value. Nothing happens if a - * reference count is already zero. - * - * Robb Matzke, 2000-10-31 - * H5FL_FREE() aborts if called with a null pointer (unlike the - * original H5MM_free()). - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * - * James Laird, 2007-1-29 - * H5F_dest now frees superblock extension oloc. - * *------------------------------------------------------------------------- */ static herr_t @@ -1004,6 +983,7 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) /* Sanity check */ HDassert(f); + HDassert(f->shared); if(1 == f->shared->nrefs) { /* Flush at this point since the file will be closed */ @@ -1085,6 +1065,7 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) f->mtab.nalloc = 0; if(H5FO_top_dest(f) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") + f->shared = NULL; H5FL_FREE(H5F_t, f); FUNC_LEAVE_NOAPI(ret_value) @@ -1566,9 +1547,8 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) new_file->file_id = ret_value; done: - if(ret_value < 0 && new_file) - if(H5F_close(new_file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") + if(ret_value < 0 && new_file && H5F_try_close(new_file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") FUNC_LEAVE_API(ret_value) } /* end H5Fopen() */ @@ -1674,50 +1654,6 @@ done: * matzke@llnl.gov * Aug 29 1997 * - * Modifications: - * rky 1998-08-28 - * Only p0 writes metadata to disk. - * - * Robb Matzke, 1998-10-16 - * Added the `scope' argument to indicate what should be - * flushed. If the value is H5F_SCOPE_GLOBAL then the entire - * virtual file is flushed; a value of H5F_SCOPE_LOCAL means - * that only the specified file is flushed. A value of - * H5F_SCOPE_DOWN means flush the specified file and all - * children. - * - * Robb Matzke, 1999-08-02 - * If ALLOC_ONLY is non-zero then all this function does is - * allocate space for the userblock and superblock. Also - * rewritten to use the virtual file layer. - * - * Robb Matzke, 1999-08-16 - * The driver information block is encoded and either allocated - * or written to disk. - * - * Raymond Lu, 2001-10-14 - * Changed to new generic property list. - * - * Quincey Koziol, 2002-05-20 - * Added 'closing' parameter - * - * Quincey Koziol, 2002-06-05 - * Added boot block & driver info block checksumming, to avoid - * writing them out when they haven't changed. - * - * Quincey Koziol, 2002-06-06 - * Return the remainders of the metadata & "small data" blocks to - * the free list of blocks for the file. - * - * Bill Wendling, 2003-03-18 - * Modified the flags being passed in to be one flag instead - * of several. - * - * John Mainzer, 2005-01-07 - * H5AC (and H5C) now have their own system of flags. Hence - * we must now translate between the H5F_FLUSH flags and the - * H5AC flags. Added code to handle this detail. - * *------------------------------------------------------------------------- */ static herr_t @@ -1835,19 +1771,6 @@ done: * Programmer: Robb Matzke * Tuesday, September 23, 1997 * - * Modifications: - * Robb Matzke, 1998-10-14 - * Nothing happens unless the H5F_t reference count is one (the - * file is flushed anyway). The reference count is decremented - * by H5F_dest(). - * - * Robb Matzke, 1999-08-02 - * Modified to use the virtual file layer. - * - * Bill Wendling, 2003-03-18 - * Modified H5F_flush call to take one flag instead of - * several Boolean flags. - * *------------------------------------------------------------------------- */ static herr_t @@ -1919,6 +1842,7 @@ H5F_try_close(H5F_t *f) /* Sanity check */ HDassert(f); + HDassert(f->shared); /* Check if this file is already in the process of closing */ if(f->closing) @@ -2903,6 +2827,88 @@ H5F_use_latest_format(const H5F_t *f) /*------------------------------------------------------------------------- + * Function: H5F_get_fc_degree + * + * Purpose: Retrieve the 'file close degree' for the file. + * + * Return: Success: Non-negative, the 'file close degree' + * + * Failure: (can't happen) + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 5 2007 + * + *------------------------------------------------------------------------- + */ +H5F_close_degree_t +H5F_get_fc_degree(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_fc_degree) + + HDassert(f); + HDassert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->fc_degree) +} /* end H5F_get_fc_degree() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_incr_nopen_objs + * + * Purpose: Increment the number of open objects for a file. + * + * Return: Success: The number of open objects, after the increment + * + * Failure: (can't happen) + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 6 2007 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_incr_nopen_objs(H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_incr_nopen_objs) + + HDassert(f); + + FUNC_LEAVE_NOAPI(++f->nopen_objs) +} /* end H5F_incr_nopen_objs() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_decr_nopen_objs + * + * Purpose: Decrement the number of open objects for a file. + * + * Return: Success: The number of open objects, after the decrement + * + * Failure: (can't happen) + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 6 2007 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_decr_nopen_objs(H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_decr_nopen_objs) + + HDassert(f); + + FUNC_LEAVE_NOAPI(--f->nopen_objs) +} /* end H5F_decr_nopen_objs() */ + + +/*------------------------------------------------------------------------- * Function: H5F_block_read * * Purpose: Reads some data from a file/server/etc into a buffer. diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index e8df026..616bb81 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -162,7 +162,6 @@ H5FL_EXTERN(H5F_file_t); /* General routines */ H5_DLL herr_t H5F_init(void); -H5_DLL herr_t H5F_try_close(H5F_t *f); H5_DLL haddr_t H5F_locate_signature(H5FD_t *file, hid_t dxpl_id); /* File mount related routines */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 1084ab5..264218f 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -255,7 +255,7 @@ typedef struct H5F_t H5F_t; #define H5F_RDCC_NBYTES(F) ((F)->shared->rdcc_nbytes) #define H5F_RDCC_W0(F) ((F)->shared->rdcc_w0) /* Check for file driver feature enabled */ -#define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags&(FL)) +#define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags & (FL)) /* B-tree node raw page */ #define H5F_GRP_BTREE_SHARED(F) ((F)->shared->grp_btree_shared) /* Base address of file */ @@ -265,6 +265,7 @@ typedef struct H5F_t H5F_t; #define H5F_GC_REF(F) ((F)->shared->gc_ref) #define H5F_USE_LATEST_FORMAT(F) ((F)->shared->latest_format) #define H5F_INTENT(F) ((F)->intent) +#define H5F_GET_FC_DEGREE(F) ((F)->shared->fc_degree) #else /* H5F_PACKAGE */ #define H5F_FCPL(F) (H5F_get_fcpl(F)) #define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F)) @@ -281,6 +282,7 @@ typedef struct H5F_t H5F_t; #define H5F_GC_REF(F) (H5F_gc_ref(F)) #define H5F_USE_LATEST_FORMAT(F) (H5F_use_latest_format(F)) #define H5F_INTENT(F) (H5F_get_intent(F)) +#define H5F_GET_FC_DEGREE(F) (H5F_get_fc_degree(F)) #endif /* H5F_PACKAGE */ @@ -405,6 +407,7 @@ struct H5RC_t; /* Private functions */ H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id); +H5_DLL herr_t H5F_try_close(H5F_t *f); /* Functions than retrieve values from the file struct */ H5_DLL hid_t H5F_get_driver_id(const H5F_t *f); @@ -421,6 +424,8 @@ H5_DLL int H5F_mpi_get_rank(const H5F_t *f); H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f); H5_DLL int H5F_mpi_get_size(const H5F_t *f); #endif /* H5_HAVE_PARALLEL */ +H5_DLL unsigned H5F_incr_nopen_objs(H5F_t *f); +H5_DLL unsigned H5F_decr_nopen_objs(H5F_t *f); /* Functions than check file mounting information */ H5_DLL hbool_t H5F_is_mount(const H5F_t *file); @@ -440,6 +445,7 @@ H5_DLL struct H5RC_t *H5F_grp_btree_shared(const H5F_t *f); H5_DLL size_t H5F_sieve_buf_size(const H5F_t *f); H5_DLL unsigned H5F_gc_ref(const H5F_t *f); H5_DLL hbool_t H5F_use_latest_format(const H5F_t *f); +H5_DLL H5F_close_degree_t H5F_get_fc_degree(const H5F_t *f); /* Functions that operate on blocks of bytes wrt super block */ H5_DLL herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 547502d..0df22bb 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -613,8 +613,8 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) H5O_msg_reset(H5O_DRVINFO_ID, &drvinfo); } /* end else */ - /* Close the extension. Bump the version number to avoid closing the - * file (since this will be the only open object). + /* Close the extension. Twiddle the number of open objects to avoid + * closing the file (since this will be the only open object). */ f->nopen_objs++; if(H5O_close(&ext_loc) < 0) diff --git a/src/H5Gloc.c b/src/H5Gloc.c index d447d20..247f185 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -133,23 +133,13 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) { H5F_t *f; + /* Get the file struct */ if(NULL == (f = H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID") - if(NULL == (loc->oloc = H5G_oloc(H5G_rootof(f)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") - if(NULL == (loc->path = H5G_nameof(H5G_rootof(f)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") - - /* Patch up root group's object location to reflect this file */ - /* (Since the root group info is only stored once for files which - * share an underlying low-level file) - */ - /* (but only for non-mounted files) */ - if(!H5F_is_mount(f)) - { - loc->oloc->file = f; - loc->oloc->holding_file = FALSE; - } + + /* Construct a group location for root group of the file */ + if(H5G_loc_root(f, loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file") } /* end case */ break; @@ -230,6 +220,56 @@ done: /*------------------------------------------------------------------------- + * Function: H5G_loc_root + * + * Purpose: Construct a "group location" for the root group of a file + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 5 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_loc_root(H5F_t *f, H5G_loc_t *loc) +{ + H5G_t *root_grp; /* Pointer to root group's info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_loc_root, FAIL) + + HDassert(f); + HDassert(loc); + + /* Retrieve the root group for the file */ + root_grp = H5G_rootof(f); + HDassert(root_grp); + + /* Build the group location for the root group */ + if(NULL == (loc->oloc = H5G_oloc(root_grp))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") + if(NULL == (loc->path = H5G_nameof(root_grp))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") + + /* Patch up root group's object location to reflect this file */ + /* (Since the root group info is only stored once for files which + * share an underlying low-level file) + */ + /* (but only for non-mounted files) */ + if(!H5F_is_mount(f)) { + loc->oloc->file = f; + loc->oloc->holding_file = FALSE; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_root() */ + + +/*------------------------------------------------------------------------- * Function: H5G_loc_copy * * Purpose: Copy over information for a location diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index b02155d..181d5e4 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -533,6 +533,7 @@ H5_DLL H5RS_str_t *H5G_build_fullpath_refstr_str(H5RS_str_t *path_r, const char /* * These functions operate on group "locations" */ +H5_DLL herr_t H5G_loc_root(H5F_t *f, H5G_loc_t *loc); H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, const H5G_loc_t *src, H5_copy_depth_t depth); H5_DLL herr_t H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, hid_t dxpl_id); @@ -2077,15 +2077,11 @@ H5I_get_file_id(hid_t obj_id) if(H5I_inc_ref(ret_value) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") } - else if(type == H5I_DATATYPE) { + else if(type == H5I_DATATYPE || type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) { if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "not a named datatype") - ret_value = H5F_get_id(loc.oloc->file); - } - else if(type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) { - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get symbol table info") - ret_value = H5F_get_id(loc.oloc->file); + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get object location") + if((ret_value = H5F_get_id(loc.oloc->file)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get file ID") } else HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID") diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 5357f6a..074cb47 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -13,19 +13,20 @@ * access to either file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#define H5L_PACKAGE /*suppress error about including H5Lpkg */ #define H5G_PACKAGE /*suppress error about including H5Gpkg */ +#define H5L_PACKAGE /*suppress error about including H5Lpkg */ /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5L_init_extern_interface #include "H5private.h" /* Generic Functions */ -#include "H5Lpkg.h" /* Links */ #include "H5Eprivate.h" /* Error handling */ +#include "H5Gpkg.h" /* Groups */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lpkg.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opublic.h" /* File objects */ -#include "H5Ppublic.h" /* Property lists */ -#include "H5Gpkg.h" /* Groups */ +#include "H5Pprivate.h" /* Property lists */ static hid_t H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, void * udata, size_t UNUSED udata_size, hid_t lapl_id); @@ -92,74 +93,117 @@ static hid_t H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, void * udata, size_t UNUSED udata_size, hid_t lapl_id) { - hid_t fid; - char *file_name; - char *obj_name; - ssize_t prefix_len; /* External link prefix length */ - size_t fname_len; - hbool_t fname_alloc = FALSE; - unsigned intent; - hid_t fapl_id; - hid_t ret_value = -1; - - file_name = (char *) udata; + H5P_genplist_t *plist; /* Property list pointer */ + char *my_prefix; /* Library's copy of the prefix */ + H5G_loc_t root_loc; /* Location of root group in external file */ + H5G_loc_t loc; /* Location of object */ + H5F_t *ext_file = NULL; /* File struct for external file */ + char *file_name = (char *)udata; + char *obj_name; + size_t fname_len; + hbool_t fname_alloc = FALSE; + unsigned intent; + hid_t fapl_id = -1; + hid_t ret_value = -1; + + FUNC_ENTER_NOAPI(H5L_extern_traverse, FAIL) + + /* Sanity checks */ + HDassert(file_name); + + /* Gather some information from the external link's user data */ fname_len = HDstrlen(file_name); - obj_name = ((char *) udata) + fname_len + 1; + obj_name = ((char *)udata) + fname_len + 1; + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get the current prefix */ + if(H5P_get(plist, H5L_ACS_ELINK_PREFIX_NAME, &my_prefix) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external link prefix") - /* See if the external link prefix property is set */ - if((prefix_len = H5Pget_elink_prefix(lapl_id, NULL, (size_t)0)) < 0) - goto error; + /* Check for prefix being set, if so, prepend it to the filename */ + if(my_prefix) { + size_t prefix_len = HDstrlen(my_prefix); - /* If so, prepend it to the filename */ - if(prefix_len > 0) - { /* Allocate a buffer to hold the filename plus prefix */ - file_name = H5MM_malloc(prefix_len + fname_len + 1); + if(NULL == (file_name = H5MM_malloc(prefix_len + fname_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer") fname_alloc = TRUE; /* Copy the prefix into the buffer */ - if(H5Pget_elink_prefix(lapl_id, file_name, (size_t)(prefix_len + 1)) < 0) - goto error; + HDstrcpy(file_name, my_prefix); /* Add the external link's filename to the prefix supplied */ HDstrcat(file_name, udata); - } + } /* end if */ + + /* Get the location for the group holding the external link */ + if(H5G_loc(cur_group, &loc) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get object location") /* Whatever access properties and intent the user used on the old file, * use the same ones to open the new file. If this is a bad default, * users can override this callback using H5Lregister. */ - if((fid = H5Iget_file_id(cur_group)) < 0) - goto error; - if(H5Fget_intent(fid, &intent) < 0) - goto error; - if((fapl_id = H5Fget_access_plist(fid)) < 0) - goto error; - if(H5Fclose(fid) < 0) - goto error; - - if((fid = H5Fopen(file_name, intent, fapl_id)) < 0) - goto error; - - ret_value = H5Oopen(fid, obj_name, lapl_id); /* If this fails, our return value will be negative. */ - if(H5Pclose(fapl_id) < 0) - goto error; - if(H5Fclose(fid) < 0) - goto error; + intent = H5F_INTENT(loc.oloc->file); + if((fapl_id = H5F_get_access_plist(loc.oloc->file)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get file access property list") + + /* Check for non-"weak" file close degree for parent file */ + if(H5F_GET_FC_DEGREE(loc.oloc->file) != H5F_CLOSE_WEAK) { + H5P_genplist_t *fa_plist; /* Property list pointer */ + H5F_close_degree_t fc_degree = H5F_CLOSE_WEAK; /* File close degree */ + + /* Get the plist structure */ + if(NULL == (fa_plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set file close degree for new file to "weak" */ + if(H5P_set(fa_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") + } /* end if */ + + /* Open the external file */ + /* (extra work with file intent to mask off inappropriate flags) */ + if(NULL == (ext_file = H5F_open(file_name, ((intent & H5F_ACC_RDWR) ? H5F_ACC_RDWR : H5F_ACC_RDONLY), H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file") + + /* Increment the number of open objects, to hold the file open */ + H5F_incr_nopen_objs(ext_file); + + /* Retrieve the "group location" for the file's root group */ + if(H5G_loc_root(ext_file, &root_loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file") + + /* Open the object referenced in the external file */ + if((ret_value = H5O_open_name(&root_loc, obj_name, lapl_id)) < 0) { + H5F_decr_nopen_objs(ext_file); + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + } /* end if */ + + /* Decrement the number of open objects, to let the file close */ + H5F_decr_nopen_objs(ext_file); + + /* Close the external file */ + if(H5F_try_close(ext_file) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file") + ext_file = NULL; - /* Free file_name if it's been allocated */ - if(fname_alloc) - H5MM_xfree(file_name); - - return ret_value; +done: + /* Release resources */ + if(fapl_id > 0 && H5I_dec_ref(fapl_id) < 0) + HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list") + if(ext_file && H5F_try_close(ext_file) < 0) + HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file") -error: /* Free file_name if it's been allocated */ if(fname_alloc) H5MM_xfree(file_name); - return -1; -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_extern_traverse() */ /*------------------------------------------------------------------------- @@ -183,18 +227,20 @@ static ssize_t H5L_extern_query(const char UNUSED * link_name, void * udata, size_t udata_size, void * buf /*out*/, size_t buf_size) { + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_extern_query) + /* If the buffer is NULL, skip writing anything in it and just return * the size needed */ if(buf) { if(udata_size < buf_size) buf_size = udata_size; - /* Copy the udata verbatim up to buf_size*/ + /* Copy the udata verbatim up to buf_size */ HDmemcpy(buf, udata, buf_size); - } + } /* end if */ - return udata_size; -} + FUNC_LEAVE_NOAPI(udata_size) +} /* end H5L_extern_query() */ /*------------------------------------------------------------------------- @@ -254,7 +300,7 @@ H5Lcreate_external(const char *file_name, const char *obj_name, done: if(temp_name != NULL) H5MM_free(temp_name); - FUNC_LEAVE_API(ret_value); + FUNC_LEAVE_API(ret_value) } /* end H5Lcreate_external() */ @@ -195,10 +195,6 @@ hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id) { H5G_loc_t loc; - H5G_loc_t obj_loc; /* Location used to open group */ - H5G_name_t obj_path; /* Opened object group hier. path */ - H5O_loc_t obj_oloc; /* Opened object object location */ - hbool_t loc_found = FALSE; /* Entry at 'name' found */ hid_t ret_value = FAIL; FUNC_ENTER_API(H5Oopen, FAIL) @@ -210,25 +206,11 @@ H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id) if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") - /* Set up opened group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object's location */ - if(H5G_loc_find(&loc, name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; - /* Open the object */ - if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0) + if((ret_value = H5O_open_name(&loc, name, lapl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") done: - if(ret_value < 0 && loc_found) - if(H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") - FUNC_LEAVE_API(ret_value) } /* end H5Oopen() */ @@ -817,6 +799,57 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_open_name + * + * Purpose: Opens an object within an HDF5 file. + * + * Return: Success: An open object identifier + * Failure: Negative + * + * Programmer: Quincey Koziol + * March 5 2007 + * + *------------------------------------------------------------------------- + */ +hid_t +H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id) +{ + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + hbool_t loc_found = FALSE; /* Entry at 'name' found */ + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI(H5O_open_name, FAIL) + + /* Check args */ + HDassert(loc); + HDassert(name && *name); + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location */ + if(H5G_loc_find(loc, name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Open the object */ + if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + +done: + if(ret_value < 0 && loc_found) + if(H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_open_name() */ + + +/*------------------------------------------------------------------------- * Function: H5O_open_by_loc * * Purpose: Opens an object and returns an ID given its group loction. diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index c08b97d..3fb2255 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -435,6 +435,7 @@ H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); H5_DLL herr_t H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id); H5_DLL herr_t H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id); H5_DLL herr_t H5O_get_create_plist(const H5O_loc_t *loc, hid_t dxpl_id, struct H5P_genplist_t *oc_plist); +H5_DLL hid_t H5O_open_name(H5G_loc_t *loc, const char *name, hid_t lapl_id); /* Object header message routines */ H5_DLL herr_t H5O_msg_create(const H5O_loc_t *loc, unsigned type_id, unsigned mesg_flags, |