diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2008-08-07 21:32:36 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2008-08-07 21:32:36 (GMT) |
commit | 2df9af6ae8fd7bf4658e702b3e5046382dc5a852 (patch) | |
tree | 8192f956e40224566862d7d4ff640e61bba6ae45 /src | |
parent | c827f0450cf1324cb972b90d70b2d8d4faecdb9e (diff) | |
download | hdf5-2df9af6ae8fd7bf4658e702b3e5046382dc5a852.zip hdf5-2df9af6ae8fd7bf4658e702b3e5046382dc5a852.tar.gz hdf5-2df9af6ae8fd7bf4658e702b3e5046382dc5a852.tar.bz2 |
[svn-r15450] Purpose: Fix various problems that were occurring when using mounted files.
Description:
Moved mount table from top file structure to shared file structure. Moved
parent out of mount table and back into top file structure. mounted files can
now be accessed from any handle of the parent file. Changes to how files are
closed. Stricter cycle checking on mounted files. Removed unused function
H5F_has_mount().
Tested:
kagiso, smirom, linew (h5committest)
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 1efb91e..072673a 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") |