diff options
Diffstat (limited to 'src/H5Fmount.c')
-rw-r--r-- | src/H5Fmount.c | 111 |
1 files changed, 98 insertions, 13 deletions
diff --git a/src/H5Fmount.c b/src/H5Fmount.c index b922446..f70a7c6 100644 --- a/src/H5Fmount.c +++ b/src/H5Fmount.c @@ -79,8 +79,10 @@ H5F_close_mounts(H5F_t *f) HDassert(f); - /* Unmount all child files */ - for (u = 0; u < f->shared->mtab.nmounts; u++) { + /* Unmount all child files. Loop backwards to avoid having to adjust u when + * a file is unmounted. Note that we rely on unsigned u "wrapping around" + * to terminate the loop. */ + for (u = f->shared->mtab.nmounts - 1; 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 */ @@ -93,10 +95,16 @@ H5F_close_mounts(H5F_t *f) /* 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") + + /* Eliminate the mount point from the table */ + HDmemmove(f->shared->mtab.child + u, f->shared->mtab.child + u + 1, + (f->shared->mtab.nmounts - u - 1) * sizeof(f->shared->mtab.child[0])); + f->shared->mtab.nmounts--; + f->nmounts--; } } /* end if */ - f->shared->mtab.nmounts -= f->nmounts; - f->nmounts = 0; + + HDassert(f->nmounts == 0); done: FUNC_LEAVE_NOAPI(ret_value) @@ -159,7 +167,7 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, * user from doing this. */ if(mp_loc.oloc->holding_file != FALSE) - HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount path cannot contain links to external files") + HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount path cannot contain links to external files") /* Open the mount point group */ if(NULL == (mount_point = H5G_open(&mp_loc, dxpl_id))) @@ -215,8 +223,8 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, /* Make room in the table */ 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])); + H5F_mount_t *x = (H5F_mount_t *)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->shared->mtab.child = x; @@ -331,7 +339,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) 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; + child_idx = (int)u; break; } /* end if */ } /* end for */ @@ -360,7 +368,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "not a mount point") /* Found the correct index, set the info about the child */ - child_idx = md; + child_idx = (int)md; H5G_loc_free(&mp_loc); mp_loc_setup = FALSE; mp_loc.oloc = mnt_oloc; @@ -389,8 +397,8 @@ 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->shared->mtab.child + child_idx, parent->shared->mtab.child + child_idx + 1, - (parent->shared->mtab.nmounts-child_idx) * sizeof(parent->shared->mtab.child[0])); + HDmemmove(parent->shared->mtab.child + (unsigned)child_idx, (parent->shared->mtab.child + (unsigned)child_idx) + 1, + ((parent->shared->mtab.nmounts - (unsigned)child_idx) - 1) * sizeof(parent->shared->mtab.child[0])); parent->shared->mtab.nmounts -= 1; parent->nmounts -= 1; @@ -463,7 +471,7 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) { H5G_loc_t loc; H5F_t *child = NULL; - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Fmount, FAIL) H5TRACE4("e", "i*sii", loc_id, name, child_id, plist_id); @@ -473,7 +481,7 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") - if(NULL == (child = H5I_object_verify(child_id,H5I_FILE))) + if(NULL == (child = (H5F_t *)H5I_object_verify(child_id, H5I_FILE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") if(H5P_DEFAULT == plist_id) plist_id = H5P_FILE_MOUNT_DEFAULT; @@ -619,3 +627,80 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_mount_count_ids() */ + +/*------------------------------------------------------------------------- + * Function: H5F_flush_mounts_recurse + * + * Purpose: Flush a mount hierarchy, recursively + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Fri, August 21, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_flush_mounts_recurse(H5F_t *f, hid_t dxpl_id) +{ + unsigned nerrors = 0; /* Errors from recursive flushes */ + unsigned u; /* Index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_flush_mounts_recurse) + + /* Sanity check */ + HDassert(f); + + /* Flush all child files, not stopping for errors */ + for(u = 0; u < f->shared->mtab.nmounts; u++) + if(H5F_flush_mounts_recurse(f->shared->mtab.child[u].file, dxpl_id) < 0) + nerrors++; + + /* Call the "real" flush routine, for this file */ + if(H5F_flush(f, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") + + /* Check flush errors for children - errors are already on the stack */ + if(nerrors) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's child mounts") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_flush_mounts_recurse() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_flush_mounts + * + * Purpose: Flush a mount hierarchy + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Fri, August 21, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_flush_mounts(H5F_t *f, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5F_flush_mounts, FAIL) + + /* Sanity check */ + HDassert(f); + + /* Find the top file in the mount hierarchy */ + while(f->parent) + f = f->parent; + + /* Flush the mounted file hierarchy */ + if(H5F_flush_mounts_recurse(f, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_flush_mounts() */ + |