diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 2 | ||||
-rw-r--r-- | src/H5D.c | 77 | ||||
-rw-r--r-- | src/H5F.c | 25 | ||||
-rw-r--r-- | src/H5Fprivate.h | 2 | ||||
-rw-r--r-- | src/H5G.c | 149 | ||||
-rw-r--r-- | src/H5Gpkg.h | 9 | ||||
-rw-r--r-- | src/H5Gprivate.h | 3 | ||||
-rw-r--r-- | src/H5I.c | 4 | ||||
-rw-r--r-- | src/H5O.c | 16 | ||||
-rw-r--r-- | src/H5R.c | 4 | ||||
-rw-r--r-- | src/H5T.c | 9 |
11 files changed, 215 insertions, 85 deletions
@@ -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) { @@ -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. */ @@ -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; @@ -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*/); @@ -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); } @@ -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"); @@ -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 */ @@ -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"); } |