diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5F.c | 18 | ||||
-rw-r--r-- | src/H5Fmount.c | 146 | ||||
-rw-r--r-- | src/H5Fpkg.h | 37 | ||||
-rw-r--r-- | src/H5G.c | 4 | ||||
-rw-r--r-- | src/H5Gname.c | 12 | ||||
-rw-r--r-- | src/H5Gtraverse.c | 40 | ||||
-rw-r--r-- | src/H5O.c | 2 |
7 files changed, 128 insertions, 131 deletions
@@ -1058,6 +1058,10 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) /* Push error, but keep going*/ HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") + /* Free mount table */ + f->shared->mtab.child = H5MM_xfree(f->shared->mtab.child); + f->shared->mtab.nalloc = 0; + /* Destroy shared file struct */ f->shared = H5FL_FREE(H5F_file_t,f->shared); @@ -1072,8 +1076,6 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) /* Free the non-shared part of the file */ f->name = H5MM_xfree(f->name); f->extpath = H5MM_xfree(f->extpath); - f->mtab.child = H5MM_xfree(f->mtab.child); - f->mtab.nalloc = 0; if(H5FO_top_dest(f) < 0) HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") f->shared = NULL; @@ -1701,14 +1703,14 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags) /* Flush other files, depending on scope */ if(H5F_SCOPE_GLOBAL == scope) { - while(f->mtab.parent) - f = f->mtab.parent; + while(f->parent) + f = f->parent; scope = H5F_SCOPE_DOWN; } /* end while */ if(H5F_SCOPE_DOWN == scope) - for(i = 0; i < f->mtab.nmounts; i++) - if(H5F_flush(f->mtab.child[i].file, dxpl_id, scope, flags) < 0) + for(i = 0; i < f->shared->mtab.nmounts; i++) + if(H5F_flush(f->shared->mtab.child[i].file, dxpl_id, scope, flags) < 0) nerrors++; /* Flush any cached dataset storage raw data */ @@ -1938,8 +1940,8 @@ H5F_try_close(H5F_t *f) /* Check if this is a child file in a mounting hierarchy & proceed up the * hierarchy if so. */ - if(f->mtab.parent) - if(H5F_try_close(f->mtab.parent) < 0) + if(f->parent) + if(H5F_try_close(f->parent) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file") /* Unmount and close each child before closing the current file. */ diff --git a/src/H5Fmount.c b/src/H5Fmount.c index c96c920..b922446 100644 --- a/src/H5Fmount.c +++ b/src/H5Fmount.c @@ -80,19 +80,23 @@ H5F_close_mounts(H5F_t *f) HDassert(f); /* Unmount all child files */ - for (u = 0; u < f->mtab.nmounts; u++) { - /* Detach the child file from the parent file */ - f->mtab.child[u].file->mtab.parent = NULL; - - /* Close the internal group maintaining the mount point */ - if(H5G_close(f->mtab.child[u].group) < 0) + for (u = 0; u < f->shared->mtab.nmounts; u++) { + /* Only unmount children mounted to this top level file structure */ + if(f->shared->mtab.child[u].file->parent == f) { + /* Detach the child file from the parent file */ + f->shared->mtab.child[u].file->parent = NULL; + + /* Close the internal group maintaining the mount point */ + if(H5G_close(f->shared->mtab.child[u].group) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close child group") - /* Close the child file */ - if(H5F_try_close(f->mtab.child[u].file) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close child file") + /* Close the child file */ + if(H5F_try_close(f->shared->mtab.child[u].file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close child file") + } } /* end if */ - f->mtab.nmounts = 0; + f->shared->mtab.nmounts -= f->nmounts; + f->nmounts = 0; done: FUNC_LEAVE_NOAPI(ret_value) @@ -146,7 +150,7 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, * the parent & child files have the same file close degree, and * that the mount wouldn't introduce a cycle in the mount tree. */ - if(child->mtab.parent) + if(child->parent) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "file is already mounted") if(H5G_loc_find(loc, name, &mp_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") @@ -175,8 +179,8 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, HDassert(mp_loc.oloc); mp_loc.path = H5G_nameof(mount_point); HDassert(mp_loc.path); - for(ancestor = parent; ancestor; ancestor = ancestor->mtab.parent) { - if(ancestor == child) + for(ancestor = parent; ancestor; ancestor = ancestor->parent) { + if(ancestor->shared == child->shared) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount would introduce a cycle") } /* end for */ @@ -190,13 +194,13 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, * `md' will be the index where the child should be inserted. */ lt = md = 0; - rt = parent->mtab.nmounts; + rt = parent->shared->mtab.nmounts; cmp = -1; while(lt < rt && cmp) { H5O_loc_t *oloc; /*temporary symbol table entry */ md = (lt + rt) / 2; - oloc = H5G_oloc(parent->mtab.child[md].group); + oloc = H5G_oloc(parent->shared->mtab.child[md].group); cmp = H5F_addr_cmp(mp_loc.oloc->addr, oloc->addr); if(cmp < 0) rt = md; @@ -209,26 +213,27 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount point is already in use") /* Make room in the table */ - if(parent->mtab.nmounts >= parent->mtab.nalloc) { - unsigned n = MAX(16, 2 * parent->mtab.nalloc); - H5F_mount_t *x = H5MM_realloc(parent->mtab.child, - n * sizeof(parent->mtab.child[0])); + if(parent->shared->mtab.nmounts >= parent->shared->mtab.nalloc) { + unsigned n = MAX(16, 2 * parent->shared->mtab.nalloc); + H5F_mount_t *x = H5MM_realloc(parent->shared->mtab.child, + n * sizeof(parent->shared->mtab.child[0])); if(!x) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for mount table") - parent->mtab.child = x; - parent->mtab.nalloc = n; + parent->shared->mtab.child = x; + parent->shared->mtab.nalloc = n; } /* end if */ /* Insert into table */ - HDmemmove(parent->mtab.child + md + 1, parent->mtab.child + md, - (parent->mtab.nmounts-md) * sizeof(parent->mtab.child[0])); - parent->mtab.nmounts++; - parent->mtab.child[md].group = mount_point; - parent->mtab.child[md].file = child; - child->mtab.parent = parent; + HDmemmove(parent->shared->mtab.child + md + 1, parent->shared->mtab.child + md, + (parent->shared->mtab.nmounts-md) * sizeof(parent->shared->mtab.child[0])); + parent->shared->mtab.nmounts++; + parent->nmounts++; + parent->shared->mtab.child[md].group = mount_point; + parent->shared->mtab.child[md].file = child; + child->parent = parent; /* Set the group's mountpoint flag */ - if(H5G_mount(parent->mtab.child[md].group) < 0) + if(H5G_mount(parent->shared->mtab.child[md].group) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to set group mounted flag") /* Get the group location for the root group in the file to unmount */ @@ -315,16 +320,16 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) mnt_oloc = H5G_oloc(child->shared->root_grp); child_idx = -1; - if(child->mtab.parent && H5F_addr_eq(mp_oloc.addr, mnt_oloc->addr)) { + if(child->parent && H5F_addr_eq(mp_oloc.addr, mnt_oloc->addr)) { unsigned u; /*counters */ /* * We've been given the root group of the child. We do a reverse * lookup in the parent's mount table to find the correct entry. */ - parent = child->mtab.parent; - for(u = 0; u < parent->mtab.nmounts; u++) { - if(parent->mtab.child[u].file == child) { + parent = child->parent; + for(u = 0; u < parent->shared->mtab.nmounts; u++) { + if(parent->shared->mtab.child[u].file->shared == child->shared) { /* Found the correct index */ child_idx = u; break; @@ -340,11 +345,11 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) */ parent = child; /*we guessed wrong*/ lt = 0; - rt = parent->mtab.nmounts; + rt = parent->shared->mtab.nmounts; cmp = -1; while(lt < rt && cmp) { md = (lt + rt) / 2; - mnt_oloc = H5G_oloc(parent->mtab.child[md].group); + mnt_oloc = H5G_oloc(parent->shared->mtab.child[md].group); cmp = H5F_addr_cmp(mp_oloc.addr, mnt_oloc->addr); if (cmp<0) rt = md; @@ -359,13 +364,17 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) H5G_loc_free(&mp_loc); mp_loc_setup = FALSE; mp_loc.oloc = mnt_oloc; - mp_loc.path = H5G_nameof(parent->mtab.child[md].group); - child = parent->mtab.child[child_idx].file; + mp_loc.path = H5G_nameof(parent->shared->mtab.child[md].group); + child = parent->shared->mtab.child[child_idx].file; + + /* Set the parent to be the actual parent of the discovered child. + * Could be different due to the shared mount table. */ + parent = child->parent; } /* end else */ HDassert(child_idx >= 0); /* Save the information about the child from the mount table */ - child_group = parent->mtab.child[child_idx].group; + child_group = parent->shared->mtab.child[child_idx].group; /* Get the group location for the root group in the file to unmount */ if(NULL == (root_loc.oloc = H5G_oloc(child->shared->root_grp))) @@ -380,9 +389,10 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name") /* Eliminate the mount point from the table */ - HDmemmove(parent->mtab.child + child_idx, parent->mtab.child + child_idx + 1, - (parent->mtab.nmounts-child_idx) * sizeof(parent->mtab.child[0])); - parent->mtab.nmounts -= 1; + HDmemmove(parent->shared->mtab.child + child_idx, parent->shared->mtab.child + child_idx + 1, + (parent->shared->mtab.nmounts-child_idx) * sizeof(parent->shared->mtab.child[0])); + parent->shared->mtab.nmounts -= 1; + parent->nmounts -= 1; /* Unmount the child file from the parent file */ if(H5G_unmount(child_group) < 0) @@ -391,7 +401,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group") /* Detach child file from parent & see if it should close */ - child->mtab.parent = NULL; + child->parent = NULL; if(H5F_try_close(child) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close unmounted file") @@ -405,37 +415,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_has_mount - * - * Purpose: Check if a file has mounted files within it. - * - * Return: Success: TRUE/FALSE - * Failure: (can't happen) - * - * Programmer: Quincey Koziol - * Thursday, January 2, 2002 - * - *------------------------------------------------------------------------- - */ -hbool_t -H5F_has_mount(const H5F_t *file) -{ - hbool_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_has_mount) - - HDassert(file); - - if(file->mtab.nmounts > 0) - ret_value = TRUE; - else - ret_value = FALSE; - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_has_mount() */ - - -/*------------------------------------------------------------------------- * Function: H5F_is_mount * * Purpose: Check if a file is mounted within another file. @@ -457,7 +436,7 @@ H5F_is_mount(const H5F_t *file) HDassert(file); - if(file->mtab.parent != NULL) + if(file->parent != NULL) ret_value = TRUE; else ret_value = FALSE; @@ -587,15 +566,18 @@ H5F_mount_count_ids_recurse(H5F_t *f, unsigned *nopen_files, unsigned *nopen_obj * (Reduced by number of mounted files, we'll add back in the mount point's * groups later, if they are open) */ - *nopen_objs += (f->nopen_objs - f->mtab.nmounts); + *nopen_objs += (f->nopen_objs - f->nmounts); /* Iterate over files mounted in this file and add in their open ID counts also */ - for(u = 0; u < f->mtab.nmounts; u++) { - /* Increment the open object count if the mount point group has an open ID */ - if(H5G_get_shared_count(f->mtab.child[u].group) > 1) - *nopen_objs += 1; - - H5F_mount_count_ids_recurse(f->mtab.child[u].file, nopen_files, nopen_objs); + for(u = 0; u < f->shared->mtab.nmounts; u++) { + /* Only recurse on children mounted to this top level file structure */ + if(f->shared->mtab.child[u].file->parent == f) { + /* Increment the open object count if the mount point group has an open ID */ + if(H5G_get_shared_count(f->shared->mtab.child[u].group) > 1) + *nopen_objs += 1; + + H5F_mount_count_ids_recurse(f->shared->mtab.child[u].file, nopen_files, nopen_objs); + } } /* end for */ FUNC_LEAVE_NOAPI_VOID @@ -627,8 +609,8 @@ H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs) HDassert(nopen_objs); /* Find the top file in the mounting hierarchy */ - while(f->mtab.parent) - f = f->mtab.parent; + while(f->parent) + f = f->parent; /* Count open IDs in the hierarchy */ H5F_mount_count_ids_recurse(f, nopen_files, nopen_objs); diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 288ef8a..594ed50 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -62,6 +62,22 @@ /* Mask for removing private file access flags */ #define H5F_ACC_PUBLIC_FLAGS 0x00ffu +/* A record of the mount table */ +typedef struct H5F_mount_t { + struct H5G_t *group; /* Mount point group held open */ + struct H5F_t *file; /* File mounted at that point */ +} H5F_mount_t; + +/* + * The mount table describes what files are attached to (mounted on) the file + * to which this table belongs. + */ +typedef struct H5F_mtab_t { + unsigned nmounts;/* Number of children which are mounted */ + unsigned nalloc; /* Number of mount slots allocated */ + H5F_mount_t *child; /* An array of mount records */ +} H5F_mtab_t; + /* * Define the structure to store the file information for HDF5 files. One of * these structures is allocated per file, not per H5Fopen(). That is, set of @@ -74,6 +90,7 @@ typedef struct H5F_file_t { unsigned nrefs; /* Ref count for times file is opened */ uint8_t status_flags; /* File status flags */ unsigned flags; /* Access Permissions for file */ + H5F_mtab_t mtab; /* File mount table */ /* Cached values from FCPL/superblock */ unsigned sym_leaf_k; /* Size of leaves in symbol tables */ @@ -114,23 +131,6 @@ typedef struct H5F_file_t { H5RC_t *grp_btree_shared; /* Ref-counted group B-tree node info */ } H5F_file_t; -/* A record of the mount table */ -typedef struct H5F_mount_t { - struct H5G_t *group; /* Mount point group held open */ - struct H5F_t *file; /* File mounted at that point */ -} H5F_mount_t; - -/* - * The mount table describes what files are attached to (mounted on) the file - * to which this table belongs. - */ -typedef struct H5F_mtab_t { - struct H5F_t *parent;/* Parent file */ - unsigned nmounts;/* Number of children which are mounted */ - unsigned nalloc; /* Number of mount slots allocated */ - H5F_mount_t *child; /* An array of mount records */ -} H5F_mtab_t; - /* * This is the top-level file descriptor. One of these structures is * allocated every time H5Fopen() is called although they may contain pointers @@ -148,7 +148,8 @@ struct H5F_t { H5FO_t *obj_count; /* # of time each object is opened through top file structure */ hid_t file_id; /* ID of this file */ hbool_t closing; /* File is in the process of being closed */ - H5F_mtab_t mtab; /* File mount table */ + struct H5F_t *parent; /* Parent file that this file is mounted to */ + unsigned nmounts; /* Number of children mounted to this file */ }; /*****************************/ @@ -1360,8 +1360,8 @@ H5G_rootof(H5F_t *f) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof) - while(f->mtab.parent) - f = f->mtab.parent; + while(f->parent) + f = f->parent; FUNC_LEAVE_NOAPI(f->shared->root_grp) } /* end H5G_rootof() */ diff --git a/src/H5Gname.c b/src/H5Gname.c index 185da21..c5fc2c1 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -700,19 +700,19 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) HGOTO_DONE(SUCCEED) /* No need to look at object, it's path is already invalid */ /* Find the top file in object's mount hier. */ - if(oloc->file->mtab.parent) { + if(oloc->file->parent) { /* Check if object is in child file (for mount & unmount operations) */ if(names->dst_file && oloc->file->shared == names->dst_file->shared) obj_in_child = TRUE; /* Find the "top" file in the chain of mounted files */ - top_obj_file = oloc->file->mtab.parent; - while(top_obj_file->mtab.parent != NULL) { + top_obj_file = oloc->file->parent; + while(top_obj_file->parent != NULL) { /* Check if object is in child mount hier. (for mount & unmount operations) */ if(names->dst_file && top_obj_file->shared == names->dst_file->shared) obj_in_child = TRUE; - top_obj_file = top_obj_file->mtab.parent; + top_obj_file = top_obj_file->parent; } /* end while */ } /* end if */ else @@ -997,8 +997,8 @@ H5G_name_replace(const H5O_link_t *lnk, H5G_names_op_t op, H5F_t *src_file, H5G_names_t names; /* Structure to hold operation information for callback */ /* Find top file in src location's mount hierarchy */ - while(src_file->mtab.parent) - src_file = src_file->mtab.parent; + while(src_file->parent) + src_file = src_file->parent; /* Set up common information for callback */ names.src_file = src_file; diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 4fc345c..dcc77c2 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -384,7 +384,8 @@ done: static herr_t H5G_traverse_mount(H5G_loc_t *obj_loc/*in,out*/) { - H5F_t *parent = obj_loc->oloc->file; /* File of object */ + H5F_t *parent = obj_loc->oloc->file, /* File of object */ + *child = NULL; /* Child file */ unsigned lt, rt, md = 0; /* Binary search indices */ int cmp; H5O_loc_t *oloc = NULL; /* Object location for mount points */ @@ -405,11 +406,11 @@ H5G_traverse_mount(H5G_loc_t *obj_loc/*in,out*/) * table for the parent */ lt = 0; - rt = parent->mtab.nmounts; + rt = parent->shared->mtab.nmounts; cmp = -1; while(lt < rt && cmp) { md = (lt + rt) / 2; - oloc = H5G_oloc(parent->mtab.child[md].group); + oloc = H5G_oloc(parent->shared->mtab.child[md].group); cmp = H5F_addr_cmp(obj_loc->oloc->addr, oloc->addr); if(cmp < 0) rt = md; @@ -418,17 +419,28 @@ H5G_traverse_mount(H5G_loc_t *obj_loc/*in,out*/) } /* end while */ /* Copy root info over to ENT */ - if(0 == cmp) { - /* Get the location for the root group in the child's file */ - oloc = H5G_oloc(parent->mtab.child[md].file->shared->root_grp); - - /* Copy the entry for the root group */ - if(H5O_loc_copy(obj_loc->oloc, oloc, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location") - - /* Switch to child's file */ - parent = oloc->file; - } /* end if */ + if(0 == cmp) { + /* Get the child file */ + child = parent->shared->mtab.child[md].file; + + /* Get the location for the root group in the child's file */ + oloc = H5G_oloc(child->shared->root_grp); + + /* Release the mount point */ + if(H5O_loc_free(obj_loc->oloc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "unable to free object location") + + /* Copy the entry for the root group */ + if(H5O_loc_copy(obj_loc->oloc, oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location") + + /* In case the shared root group info points to a different file handle + * than the child, modify obj_loc */ + obj_loc->oloc->file = child; + + /* Switch to child's file */ + parent = child; + } /* end if */ } while(!cmp); done: @@ -1375,7 +1375,7 @@ H5O_close(H5O_loc_t *loc) * If the file open object count has reached the number of open mount points * (each of which has a group open in the file) attempt to close the file. */ - if(loc->file->nopen_objs == loc->file->mtab.nmounts) + if(loc->file->nopen_objs == loc->file->nmounts) /* Attempt to close down the file hierarchy */ if(H5F_try_close(loc->file) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close") |