summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5F.c18
-rw-r--r--src/H5Fmount.c146
-rw-r--r--src/H5Fpkg.h37
-rw-r--r--src/H5G.c4
-rw-r--r--src/H5Gname.c12
-rw-r--r--src/H5Gtraverse.c40
-rw-r--r--src/H5O.c2
7 files changed, 128 insertions, 131 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 80c28bc..a5427db 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -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 */
};
/*****************************/
diff --git a/src/H5G.c b/src/H5G.c
index e04402e..3a57fa7 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -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:
diff --git a/src/H5O.c b/src/H5O.c
index b5c74ff..d090df0 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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")