summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5.c2
-rw-r--r--src/H5D.c77
-rw-r--r--src/H5F.c25
-rw-r--r--src/H5Fprivate.h2
-rw-r--r--src/H5G.c149
-rw-r--r--src/H5Gpkg.h9
-rw-r--r--src/H5Gprivate.h3
-rw-r--r--src/H5I.c4
-rw-r--r--src/H5O.c16
-rw-r--r--src/H5R.c4
-rw-r--r--src/H5T.c9
11 files changed, 215 insertions, 85 deletions
diff --git a/src/H5.c b/src/H5.c
index fa6eba3..3fc25d7 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -1172,7 +1172,7 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...)
}
/* Clear array sizes */
- for (i=0; i<NELMTS(asize); i++) asize[i] = -1;
+ for (i=0; i<(hssize_t)NELMTS(asize); i++) asize[i] = -1;
/* Parse the argument types */
for (argno=0; *type; argno++, type+=HDisupper(*type)?2:1) {
diff --git a/src/H5D.c b/src/H5D.c
index 27b46ca..6f5ca00 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -832,10 +832,12 @@ H5D_new(const H5D_create_t *create_parms)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
"memory allocation failed");
}
- if(create_parms!=NULL)
+ if(create_parms!=NULL) {
ret_value->create_parms = H5P_copy (H5P_DATASET_CREATE, create_parms);
- else
- ret_value->create_parms = H5P_copy (H5P_DATASET_CREATE, &H5D_create_dflt);
+ } else {
+ ret_value->create_parms = H5P_copy (H5P_DATASET_CREATE,
+ &H5D_create_dflt);
+ }
H5F_addr_undef(&(ret_value->ent.header));
/* Success */
@@ -887,17 +889,28 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
intn i, ndims;
hsize_t max_dim[H5O_LAYOUT_NDIMS];
H5O_efl_t *efl = NULL;
- H5F_t *f = loc->file;
+ H5F_t *f = NULL;
FUNC_ENTER(H5D_create, NULL);
/* check args */
- assert (f);
assert (loc);
assert (name && *name);
assert (type);
assert (space);
assert (create_parms);
+ if (create_parms->pline.nfilters>0 &&
+ H5D_CHUNKED!=create_parms->layout) {
+ HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, NULL,
+ "filters can only be used with chunked layout");
+ }
+
+ /* What file is the dataset being added to? */
+ if (NULL==(f=H5G_insertion_file(loc, name))) {
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL,
+ "unable to locate insertion point");
+ }
+
#ifdef HAVE_PARALLEL
/* If MPIO is used, no filter support yet. */
if (f->shared->access_parms->driver == H5F_LOW_MPIO &&
@@ -906,12 +919,7 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
"Parallel IO does not support filters yet");
}
#endif
- if (create_parms->pline.nfilters>0 &&
- H5D_CHUNKED!=create_parms->layout) {
- HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, NULL,
- "filters can only be used with chunked layout");
- }
-
+
/* Initialize the dataset object */
if (NULL==(new_dset = H5D_new(create_parms))) {
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
@@ -1118,8 +1126,9 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
* Modifications:
* Robb Matzke, 9 Jun 1998
* The data space message is no longer cached in the dataset struct.
- * Quincey Koziol, 12 Oct 1998
- * Moved guts of function into H5D_open_oid
+ *
+ * Quincey Koziol, 12 Oct 1998
+ * Moved guts of function into H5D_open_oid
*
*-------------------------------------------------------------------------
*/
@@ -1204,14 +1213,16 @@ H5D_open_oid(H5D_t *dataset, H5G_entry_t *ent)
}
/* Get the optional fill value message */
- if (NULL==H5O_read(&(dataset->ent), H5O_FILL, 0, &(dataset->create_parms->fill))) {
+ if (NULL==H5O_read(&(dataset->ent), H5O_FILL, 0,
+ &(dataset->create_parms->fill))) {
H5E_clear();
HDmemset(&(dataset->create_parms->fill), 0,
sizeof(dataset->create_parms->fill));
}
/* Get the optional filters message */
- if (NULL==H5O_read (&(dataset->ent), H5O_PLINE, 0, &(dataset->create_parms->pline))) {
+ if (NULL==H5O_read (&(dataset->ent), H5O_PLINE, 0,
+ &(dataset->create_parms->pline))) {
H5E_clear ();
HDmemset (&(dataset->create_parms->pline), 0,
sizeof(dataset->create_parms->pline));
@@ -1219,7 +1230,7 @@ H5D_open_oid(H5D_t *dataset, H5G_entry_t *ent)
#ifdef HAVE_PARALLEL
/* If MPIO is used, no filter support yet. */
- if (dataset.ent.file->shared->access_parms->driver == H5F_LOW_MPIO &&
+ if (dataset->ent.file->shared->access_parms->driver == H5F_LOW_MPIO &&
dataset->create_parms->pline.nfilters>0){
HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL,
"Parallel IO does not support filters yet");
@@ -1255,12 +1266,14 @@ H5D_open_oid(H5D_t *dataset, H5G_entry_t *ent)
break;
default:
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "not implemented yet");
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL,
+ "not implemented yet");
}
/* Get the external file list message, which might not exist */
- if (NULL==H5O_read (&(dataset->ent), H5O_EFL, 0, &(dataset->create_parms->efl)) &&
- !H5F_addr_defined (&(dataset->layout.addr))) {
+ if (NULL==H5O_read (&(dataset->ent), H5O_EFL, 0,
+ &(dataset->create_parms->efl)) &&
+ !H5F_addr_defined (&(dataset->layout.addr))) {
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
"storage address is undefined an no external file list");
}
@@ -1270,7 +1283,8 @@ H5D_open_oid(H5D_t *dataset, H5G_entry_t *ent)
* This is especially important for parallel I/O where the B-tree must
* be fully populated before I/O can happen.
*/
- if ((dataset->ent.file->intent & H5F_ACC_RDWR) && H5D_CHUNKED==dataset->layout.type) {
+ if ((dataset->ent.file->intent & H5F_ACC_RDWR) &&
+ H5D_CHUNKED==dataset->layout.type) {
if (H5D_init_storage(dataset, space)<0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
"unable to initialize file storage");
@@ -1831,7 +1845,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
* turns off background preservation.
*/
#ifdef QAK
- printf("%s: check 0.5, nelmts=%d, mem_space->rank=%d\n",FUNC,(int)nelmts,mem_space->extent.u.simple.rank);
+ printf("%s: check 0.5, nelmts=%d, mem_space->rank=%d\n", FUNC,
+ (int)nelmts, mem_space->extent.u.simple.rank);
#endif /* QAK */
if (nelmts!=H5S_get_select_npoints (file_space)) {
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
@@ -2266,8 +2281,7 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space)
intn ndims;
hsize_t dim[H5O_LAYOUT_NDIMS];
hsize_t npoints, ptsperbuf;
- size_t i, size, bufsize=8*1024;
- hbool_t all_zero;
+ size_t size, bufsize=8*1024;
hid_t buf_id = -1;
haddr_t addr;
herr_t ret_value = FAIL;
@@ -2280,18 +2294,13 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space)
switch (dset->layout.type) {
case H5D_CONTIGUOUS:
/*
- * If the fill value is non-zero then write the fill value to the
- * specified selection.
+ * If the fill value is set then write it to the specified selection
+ * even if it is all zero. This allows the application to force
+ * filling when the underlying storage isn't initialized to zero.
*/
- for (i=0, all_zero=TRUE; i<dset->create_parms->fill.size; i++) {
- if (((uint8*)(dset->create_parms->fill.buf))[i]) {
- all_zero = FALSE;
- break;
- }
- }
npoints = H5S_get_simple_extent_npoints(space);
-
- if (!all_zero && npoints==H5S_get_select_npoints(space)) {
+ if (dset->create_parms->fill.buf &&
+ npoints==H5S_get_select_npoints(space)) {
/*
* Fill the entire current extent with the fill value. We can do
* this quite efficiently by making sure we copy the fill value
@@ -2330,7 +2339,7 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space)
npoints -= MIN(ptsperbuf, npoints);
H5F_addr_inc(&addr, size);
}
- } else if (!all_zero) {
+ } else if (dset->create_parms->fill.buf) {
/*
* Fill the specified selection with the fill value.
*/
diff --git a/src/H5F.c b/src/H5F.c
index 9436104..ac5d2fd 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -289,7 +289,7 @@ H5Fget_create_plist(hid_t file_id)
H5TRACE1("i","i",file_id);
/* check args */
- if (H5I_FILE != H5I_get_type(file_id) || NULL==(file=H5I_object(file_id))) {
+ if (H5I_FILE!=H5I_get_type(file_id) || NULL==(file=H5I_object(file_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file");
}
@@ -1535,15 +1535,29 @@ H5F_flush(H5F_t *f, hbool_t invalidate)
herr_t
H5F_close(H5F_t *f)
{
+ uintn i;
+
FUNC_ENTER(H5F_close, FAIL);
/*
+ * Find the root of the virtual file. Then unmount and close each child
+ * before closing the current file.
+ */
+ while (f->mtab.parent) f = f->mtab.parent;
+ for (i=0; i<f->mtab.nmounts; i++) {
+ H5G_close(f->mtab.child[i].group);
+ f->mtab.child[i].file->mtab.parent = NULL;
+ H5F_close(f->mtab.child[i].file);
+ }
+ f->mtab.nmounts = 0;
+
+ /*
* If object headers are still open then delay deletion of resources until
* they have all been closed. Flush all caches and update the object
* header anyway so that failing to close all objects isn't a major
* problem.
*/
- if (f->nopen>0) {
+ if (f->nopen_objs>0) {
if (H5F_flush(f, FALSE)<0) {
HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL,
"unable to flush cache");
@@ -1553,9 +1567,9 @@ H5F_close(H5F_t *f)
fprintf(H5DEBUG(F), "H5F: H5F_close(%s): %u object header%s still "
"open (file close will complete when %s closed)\n",
f->name,
- f->nopen,
- 1 == f->nopen ? " is" : "s are",
- 1 == f->nopen ? "that header is" : "those headers are");
+ f->nopen_objs,
+ 1 == f->nopen_objs?" is":"s are",
+ 1 == f->nopen_objs?"that header is":"those headers are");
}
#endif
f->close_pending = TRUE;
@@ -1942,6 +1956,7 @@ H5F_mountpoint(H5G_entry_t *find/*in,out*/)
if (0==cmp) {
ent = H5G_entof(parent->mtab.child[md].file->shared->root_grp);
*find = *ent;
+ parent = ent->file;
}
} while (!cmp);
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 8ba9613..004c411 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -479,7 +479,7 @@ typedef struct H5F_t {
uintn intent; /* The flags passed to H5F_open()*/
char *name; /* Name used to open file */
H5F_file_t *shared; /* The shared file info */
- uintn nopen; /* Number of open object headers*/
+ uintn nopen_objs; /* Number of open object headers*/
hbool_t close_pending; /* File close is pending */
H5F_mtab_t mtab; /* File mount table */
} H5F_t;
diff --git a/src/H5G.c b/src/H5G.c
index e2d0e39..90dd1a9 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -427,7 +427,7 @@ H5Glink(hid_t loc_id, H5G_link_t type, const char *cur_name,
HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
"no new name specified");
}
- if (H5G_link (loc, type, cur_name, new_name)<0) {
+ if (H5G_link (loc, type, cur_name, new_name, H5G_TARGET_NORMAL)<0) {
HRETURN_ERROR (H5E_SYM, H5E_LINK, FAIL, "unable to create link");
}
@@ -839,15 +839,21 @@ H5G_basename(const char *name, size_t *size_p)
* understood by this function (unless it appears as an entry in
* the symbol table).
*
- * Symbolic links are followed automatically, but if
- * FOLLOW_SLINK is false and the last component of the name is a
- * symbolic link then that link is not followed. At most NLINKS
- * are followed and the next link generates an error.
+ * Symbolic links are followed automatically, but if TARGET
+ * includes the H5G_TARGET_SLINK bit and the last component of
+ * the name is a symbolic link then that link is not followed.
+ * The *NLINKS value is decremented each time a link is followed
+ * and link traversal fails if the value would become negative.
+ * If NLINKS is the null pointer then a default value is used.
*
* Mounted files are handled by calling H5F_mountpoint() after
* each step of the translation. If the input argument to that
* function is a mount point then the argument shall be replaced
* with information about the root group of the mounted file.
+ * But if TARGET includes the H5G_TARGET_MOUNT bit and the last
+ * component of the name is a mount point then H5F_mountpoint()
+ * is not called and information about the mount point itself is
+ * returned.
*
* Errors:
*
@@ -871,7 +877,7 @@ H5G_basename(const char *name, size_t *size_p)
static herr_t
H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/,
- hbool_t follow_slink, intn *nlinks)
+ uintn target, intn *nlinks)
{
H5G_entry_t _grp_ent; /*entry for current group */
H5G_entry_t _obj_ent; /*entry found */
@@ -944,11 +950,12 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
/*
* If we found a symbolic link then we should follow it. But if this
- * is the last component of the name and FOLLOW_SLINK is zero then we
- * don't follow it.
+ * is the last component of the name and the H5G_TARGET_SLINK bit of
+ * TARGET is set then we don't follow it.
*/
if (H5G_CACHED_SLINK==obj_ent->type &&
- (follow_slink || ((s=H5G_component(name+nchars, NULL)) && *s))) {
+ (0==(target & H5G_TARGET_SLINK) ||
+ ((s=H5G_component(name+nchars, NULL)) && *s))) {
if ((*nlinks)-- <= 0) {
HRETURN_ERROR (H5E_SYM, H5E_SLINK, FAIL,
"too many symbolic links");
@@ -959,8 +966,17 @@ H5G_namei(H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
}
}
+ /*
+ * Resolve mount points to the mounted group. Do not do this step if
+ * the H5G_TARGET_MOUNT bit of TARGET is set and this is the last
+ * component of the name.
+ */
+ if (0==(target & H5G_TARGET_MOUNT) ||
+ ((s=H5G_component(name+nchars, NULL)) && *s)) {
+ H5F_mountpoint(obj_ent/*in,out*/);
+ }
+
/* next component */
- H5F_mountpoint(obj_ent/*in,out*/);
name += nchars;
}
if (rest) *rest = name; /*final null */
@@ -1014,7 +1030,8 @@ H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
linkval = H5MM_xstrdup (clv);
/* Traverse the link */
- if (H5G_namei (grp_ent, linkval, NULL, grp_ent, obj_ent, TRUE, nlinks)) {
+ if (H5G_namei (grp_ent, linkval, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL,
+ nlinks)) {
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
"unable to follow symbolic link");
}
@@ -1101,8 +1118,8 @@ H5G_mkroot (H5F_t *f, H5G_entry_t *ent)
}
f->shared->root_grp->ent = *ent;
f->shared->root_grp->nref = 1;
- assert (1==f->nopen);
- f->nopen = 0;
+ assert (1==f->nopen_objs);
+ f->nopen_objs = 0;
FUNC_LEAVE(SUCCEED);
}
@@ -1146,7 +1163,8 @@ H5G_create(H5G_entry_t *loc, const char *name, size_t size_hint)
assert(name && *name);
/* lookup name */
- if (0 == H5G_namei(loc, name, &rest, &grp_ent, NULL, TRUE, NULL)) {
+ if (0 == H5G_namei(loc, name, &rest, &grp_ent, NULL, H5G_TARGET_NORMAL,
+ NULL)) {
HRETURN_ERROR(H5E_SYM, H5E_EXISTS, NULL, "already exists");
}
H5E_clear(); /*it's OK that we didn't find it */
@@ -1320,11 +1338,15 @@ H5G_close(H5G_t *grp)
/*-------------------------------------------------------------------------
* Function: H5G_rootof
*
- * Purpose: Return a pointer to the root group of the file.
+ * Purpose: Return a pointer to the root group of the file. If the file
+ * is part of a virtual file then the root group of the virtual
+ * file is returned.
*
- * Return: Success:
+ * Return: Success: Ptr to the root group of the file. Do not
+ * free the pointer -- it points directly into
+ * the file struct.
*
- * Failure:
+ * Failure: NULL
*
* Programmer: Robb Matzke
* Tuesday, October 13, 1998
@@ -1336,8 +1358,8 @@ H5G_close(H5G_t *grp)
H5G_t *
H5G_rootof(H5F_t *f)
{
-
FUNC_ENTER(H5G_rootof, NULL);
+ while (f->mtab.parent) f = f->mtab.parent;
FUNC_LEAVE(f->shared->root_grp);
}
@@ -1378,7 +1400,7 @@ H5G_insert(H5G_entry_t *loc, const char *name, H5G_entry_t *ent)
/*
* Look up the name -- it shouldn't exist yet.
*/
- if (H5G_namei(loc, name, &rest, &grp, NULL, TRUE, NULL) >= 0) {
+ if (H5G_namei(loc, name, &rest, &grp, NULL, H5G_TARGET_NORMAL, NULL)>=0) {
HRETURN_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "already exists");
}
H5E_clear(); /*it's OK that we didn't find it */
@@ -1409,6 +1431,7 @@ H5G_insert(H5G_entry_t *loc, const char *name, H5G_entry_t *ent)
"unable to increment hard link count");
}
if (H5G_stab_insert(&grp, rest, ent) < 0) {
+ H5O_link(ent, -1);
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to insert name");
}
FUNC_LEAVE(SUCCEED);
@@ -1452,7 +1475,8 @@ H5G_find(H5G_entry_t *loc, const char *name,
assert (loc);
assert (name && *name);
- if (H5G_namei(loc, name, NULL, grp_ent, obj_ent, TRUE, NULL)<0) {
+ if (H5G_namei(loc, name, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL,
+ NULL)<0) {
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
}
FUNC_LEAVE(SUCCEED);
@@ -1650,7 +1674,7 @@ H5G_loc (hid_t loc_id)
*/
herr_t
H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name,
- const char *new_name)
+ const char *new_name, uintn namei_flags)
{
H5G_entry_t cur_obj; /*entry for the link tail */
H5G_entry_t grp_ent; /*ent for grp containing link hd*/
@@ -1673,7 +1697,8 @@ H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name,
* Lookup the the new_name so we can get the group which will contain
* the new entry. The entry shouldn't exist yet.
*/
- if (H5G_namei (loc, new_name, &rest, &grp_ent, NULL, TRUE, NULL)>=0) {
+ if (H5G_namei (loc, new_name, &rest, &grp_ent, NULL, H5G_TARGET_NORMAL,
+ NULL)>=0) {
HRETURN_ERROR (H5E_SYM, H5E_EXISTS, FAIL, "already exists");
}
H5E_clear (); /*it's okay that we didn't find it*/
@@ -1738,9 +1763,10 @@ H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name,
break;
case H5G_LINK_HARD:
- if (H5G_find (loc, cur_name, NULL, &cur_obj)<0) {
- HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
- "source object not found");
+ if (H5G_namei(loc, cur_name, NULL, NULL, &cur_obj, namei_flags,
+ NULL)<0) {
+ HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL,
+ "source object not found");
}
if (H5G_insert (loc, new_name, &cur_obj)<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL,
@@ -1793,7 +1819,7 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link,
/* Find the object's symbol table entry */
if (H5G_namei (loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/,
- follow_link, NULL)<0) {
+ follow_link?H5G_TARGET_NORMAL:H5G_TARGET_SLINK, NULL)<0) {
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to stat object");
}
@@ -1889,8 +1915,8 @@ H5G_linkval (H5G_entry_t *loc, const char *name, size_t size, char *buf/*out*/)
* Get the symbol table entry for the link head and the symbol table
* entry for the group in which the link head appears.
*/
- if (H5G_namei (loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/, FALSE,
- NULL)<0) {
+ if (H5G_namei (loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/,
+ H5G_TARGET_SLINK, NULL)<0) {
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL,
"symbolic link was not found");
}
@@ -1947,7 +1973,8 @@ H5G_set_comment(H5G_entry_t *loc, const char *name, const char *buf)
FUNC_ENTER(H5G_set_comment, FAIL);
/* Get the symbol table entry for the object */
- if (H5G_namei(loc, name, NULL, NULL, &obj_ent/*out*/, TRUE, NULL)<0) {
+ if (H5G_namei(loc, name, NULL, NULL, &obj_ent/*out*/, H5G_TARGET_NORMAL,
+ NULL)<0) {
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
}
@@ -1996,7 +2023,8 @@ H5G_get_comment(H5G_entry_t *loc, const char *name, size_t bufsize, char *buf)
FUNC_ENTER(H5G_get_comment, FAIL);
/* Get the symbol table entry for the object */
- if (H5G_namei(loc, name, NULL, NULL, &obj_ent/*out*/, TRUE, NULL)<0) {
+ if (H5G_namei(loc, name, NULL, NULL, &obj_ent/*out*/, H5G_TARGET_NORMAL,
+ NULL)<0) {
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
}
@@ -2043,7 +2071,8 @@ H5G_unlink(H5G_entry_t *loc, const char *name)
assert(name && *name);
/* Get the entry for the group that contains the object to be unlinked */
- if (H5G_namei(loc, name, NULL, &grp_ent, &obj_ent, FALSE, NULL)<0) {
+ if (H5G_namei(loc, name, NULL, &grp_ent, &obj_ent,
+ H5G_TARGET_SLINK|H5G_TARGET_MOUNT, NULL)<0) {
HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
}
if (!H5F_addr_defined(&(grp_ent.header))) {
@@ -2113,7 +2142,8 @@ H5G_move(H5G_entry_t *loc, const char *src_name, const char *dst_name)
"unable to read symbolic link value");
}
} while (linkval[lv_size-1]);
- if (H5G_link(loc, H5G_LINK_SOFT, linkval, dst_name)<0) {
+ if (H5G_link(loc, H5G_LINK_SOFT, linkval, dst_name,
+ H5G_TARGET_NORMAL)<0) {
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
"unable to rename symbolic link");
}
@@ -2123,7 +2153,8 @@ H5G_move(H5G_entry_t *loc, const char *src_name, const char *dst_name)
/*
* Rename the object.
*/
- if (H5G_link(loc, H5G_LINK_HARD, src_name, dst_name)<0) {
+ if (H5G_link(loc, H5G_LINK_HARD, src_name, dst_name,
+ H5G_TARGET_MOUNT)<0) {
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
"unable to register new name for object");
}
@@ -2137,3 +2168,55 @@ H5G_move(H5G_entry_t *loc, const char *src_name, const char *dst_name)
FUNC_LEAVE(SUCCEED);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_insertion_file
+ *
+ * Purpose: Given a location and name that specifies a not-yet-existing
+ * object return the file into which the object is about to be
+ * inserted.
+ *
+ * Return: Success: File pointer
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, October 14, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5F_t *
+H5G_insertion_file(H5G_entry_t *loc, const char *name)
+{
+ const char *rest;
+ H5G_entry_t grp_ent;
+ size_t size;
+
+ FUNC_ENTER(H5G_insertion_file, NULL);
+ assert(loc);
+ assert(name && *name);
+
+ /*
+ * Look up the name to get the containing group and to make sure the name
+ * doesn't already exist.
+ */
+ if (H5G_namei(loc, name, &rest, &grp_ent, NULL, H5G_TARGET_NORMAL,
+ NULL)>=0) {
+ HRETURN_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists");
+ }
+ H5E_clear();
+
+ /* Make sure only the last component wasn't resolved */
+ rest = H5G_component(rest, &size);
+ assert(*rest && size>0);
+ rest = H5G_component(rest+size, NULL);
+ if (*rest) {
+ HRETURN_ERROR(H5E_SYM, H5E_NOTFOUND, NULL,
+ "insertion point not found");
+ }
+
+ FUNC_LEAVE(grp_ent.file);
+}
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index 74573f3..03a2629 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -56,6 +56,15 @@ struct H5G_t {
};
/*
+ * During name lookups (see H5G_namei()) we sometimes want information about
+ * a symbolic link or a mount point. The normal operation is to follow the
+ * symbolic link or mount point and return information about its target.
+ */
+#define H5G_TARGET_NORMAL 0x0000
+#define H5G_TARGET_SLINK 0x0001
+#define H5G_TARGET_MOUNT 0x0002
+
+/*
* These operations can be passed down from the H5G_stab layer to the
* H5G_node layer through the B-tree layer.
*/
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 417f011..1cf448f 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -109,7 +109,7 @@ H5G_t *H5G_reopen (H5G_t *grp);
herr_t H5G_close (H5G_t *grp);
H5G_t *H5G_rootof(H5F_t *f);
herr_t H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name,
- const char *new_name);
+ const char *new_name, uintn namei_flags);
herr_t H5G_get_objinfo (H5G_entry_t *loc, const char *name,
hbool_t follow_link, H5G_stat_t *statbuf/*out*/);
herr_t H5G_linkval (H5G_entry_t *loc, const char *name, size_t size,
@@ -122,6 +122,7 @@ herr_t H5G_move(H5G_entry_t *loc, const char *src_name, const char *dst_name);
herr_t H5G_unlink(H5G_entry_t *loc, const char *name);
herr_t H5G_find (H5G_entry_t *loc, const char *name,
H5G_entry_t *grp_ent/*out*/, H5G_entry_t *ent/*out*/);
+H5F_t *H5G_insertion_file(H5G_entry_t *loc, const char *name);
herr_t H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
H5G_entry_t *obj_ent/*in,out*/,
intn *nlinks/*in,out*/);
diff --git a/src/H5I.c b/src/H5I.c
index 91c8b1a..6dc7ef3 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -564,8 +564,8 @@ H5I_get_type(hid_t id)
FUNC_ENTER(H5I_get_type, H5I_BADID);
- ret_value = H5I_GROUP(id);
- assert(ret_value>H5I_BADID && ret_value<H5I_MAXID);
+ if (id>0) ret_value = H5I_GROUP(id);
+ assert(ret_value>=H5I_BADID && ret_value<H5I_MAXID);
FUNC_LEAVE(ret_value);
}
diff --git a/src/H5O.c b/src/H5O.c
index 233d7f5..4386962 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -244,7 +244,7 @@ H5O_open(H5G_entry_t *obj_ent)
#endif
/* Increment open-lock counters */
- obj_ent->file->nopen++;
+ obj_ent->file->nopen_objs++;
FUNC_LEAVE(SUCCEED);
}
@@ -273,16 +273,16 @@ H5O_close(H5G_entry_t *obj_ent)
/* Check args */
assert(obj_ent);
assert(obj_ent->file);
- assert(obj_ent->file->nopen > 0);
+ assert(obj_ent->file->nopen_objs > 0);
/* Decrement open-lock counters */
- --obj_ent->file->nopen;
+ --obj_ent->file->nopen_objs;
/*
* If the file open-lock count has reached zero and the file has a close
* pending then close the file.
*/
- if (0 == obj_ent->file->nopen && obj_ent->file->close_pending) {
+ if (0 == obj_ent->file->nopen_objs && obj_ent->file->close_pending) {
H5F_close(obj_ent->file);
}
#ifdef H5O_DEBUG
@@ -1203,8 +1203,14 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
} else {
/*
* The shared message is stored in some other object header.
- * Increment the reference count on that object header.
+ * The other object header must be in the same file as the
+ * new object header. Increment the reference count on that
+ * object header.
*/
+ if (sh_mesg->u.ent.file->shared != ent->file->shared) {
+ HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL,
+ "interfile hard links are not allowed");
+ }
if (H5O_link (&(sh_mesg->u.ent), 1)<0) {
HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL,
"unable to adjust shared object link count");
diff --git a/src/H5R.c b/src/H5R.c
index 88ab707..48051de 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -246,7 +246,7 @@ H5R_dereference(href_t *ref)
*/
/* Allocate the dataset structure */
if (NULL==(dataset = H5D_new(NULL))) {
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed");
}
@@ -258,7 +258,7 @@ H5R_dereference(href_t *ref)
/* Open the dataset object */
if (H5D_open_oid(dataset, &ent) < 0) {
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found");
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
}
/* Create an atom for the dataset */
diff --git a/src/H5T.c b/src/H5T.c
index 0231a0e..cb72c8c 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -3679,6 +3679,7 @@ herr_t
H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type)
{
herr_t ret_value = FAIL;
+ H5F_t *file = NULL;
FUNC_ENTER (H5T_commit, FAIL);
@@ -3699,11 +3700,17 @@ H5T_commit (H5G_entry_t *loc, const char *name, H5T_t *type)
"data type is immutable");
}
+ /* Find the insertion file */
+ if (NULL==(file=H5G_insertion_file(loc, name))) {
+ HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
+ "unable to find insertion point");
+ }
+
/*
* 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 (loc->file, 64, &(type->ent))<0) {
+ if (H5O_create (file, 64, &(type->ent))<0) {
HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to create data type object header");
}