From bb31e94a924a1b3f6f1da6c10ffe95029c87d5c5 Mon Sep 17 00:00:00 2001
From: Quincey Koziol <koziol@hdfgroup.org>
Date: Thu, 21 Jul 2005 09:48:26 -0500
Subject: [svn-r11093] Purpose:     Bug fix

Description:
    Rewrite code for mounting files to clean up layers of kludges and implement
a much cleaner and more maintainable design.

Platforms tested:
    FreeBSD 4.11 (sleipnir)
    Linux 2.4
---
 MANIFEST         |   1 -
 src/H5.c         | 108 ++++-----
 src/H5D.c        |  17 +-
 src/H5F.c        | 723 ++++++++++++++++++++++++++++++++-----------------------
 src/H5Fmount.c   | 186 ++++++--------
 src/H5Fpkg.h     |   9 +-
 src/H5Fprivate.h |   4 +-
 src/H5G.c        |  88 ++++++-
 src/H5Gpkg.h     |   3 +-
 src/H5Gprivate.h |   2 +
 src/H5I.c        |  51 ++--
 src/H5Iprivate.h |   1 +
 src/H5Ipublic.h  |   1 -
 src/H5O.c        |  34 +--
 test/Makefile.am |   2 +-
 test/Makefile.in |  34 +--
 test/filename.c  | 154 ------------
 test/mount.c     | 719 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 test/testhdf5.h  |  13 +
 test/tfile.c     | 155 ++++++++++--
 20 files changed, 1527 insertions(+), 778 deletions(-)
 delete mode 100644 test/filename.c

diff --git a/MANIFEST b/MANIFEST
index 1e48d0e..71ea466 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -622,7 +622,6 @@ a------------------------------------------------------------------------------
 ./test/family_v1.6_00001.h5
 ./test/family_v1.6_00002.h5
 ./test/family_v1.6_00003.h5
-./test/filename.c
 ./test/fill_old.h5
 ./test/fillval.c
 ./test/flush1.c
diff --git a/src/H5.c b/src/H5.c
index 5956c9e..cb86136 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -2098,9 +2098,6 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
                         case H5I_FILE:
                             fprintf(out, "%ld (file)", (long)obj);
                             break;
-                        case H5I_FILE_CLOSING:
-                            fprintf(out, "%ld (file closing)", (long)obj);
-                            break;
                         case H5I_GROUP:
                             fprintf(out, "%ld (group)", (long)obj);
                             break;
@@ -2300,60 +2297,57 @@ H5_trace (const double *returning, const char *func, const char *type, ...)
 		} else {
 		    H5I_type_t id_type = va_arg (ap, H5I_type_t); /*lint !e64 Type mismatch not really occuring */
 		    switch (id_type) {
-		    case H5I_UNINIT:
-			fprintf (out, "H5I_UNINIT");
-			break;
-		    case H5I_BADID:
-			fprintf (out, "H5I_BADID");
-			break;
-		    case H5I_FILE:
-			fprintf (out, "H5I_FILE");
-			break;
-		    case H5I_FILE_CLOSING:
-			fprintf (out, "H5I_FILE_CLOSING");
-			break;
-		    case H5I_GROUP:
-			fprintf (out, "H5I_GROUP");
-			break;
-		    case H5I_DATATYPE:
-			fprintf (out, "H5I_DATATYPE");
-			break;
-		    case H5I_DATASPACE:
-			fprintf (out, "H5I_DATASPACE");
-			break;
-		    case H5I_DATASET:
-			fprintf (out, "H5I_DATASET");
-			break;
-		    case H5I_ATTR:
-			fprintf (out, "H5I_ATTR");
-			break;
-		    case H5I_REFERENCE:
-			fprintf (out, "H5I_REFERENCE");
-			break;
-		    case H5I_VFL:
-			fprintf (out, "H5I_VFL");
-			break;
-		    case H5I_GENPROP_CLS:
-			fprintf (out, "H5I_GENPROP_CLS");
-			break;
-		    case H5I_GENPROP_LST:
-			fprintf (out, "H5I_GENPROP_LST");
-			break;
-		    case H5I_ERROR_CLASS:
-			fprintf (out, "H5I_ERROR_CLASS");
-			break;
-		    case H5I_ERROR_MSG:
-			fprintf (out, "H5I_ERROR_MSG");
-			break;
-		    case H5I_ERROR_STACK:
-			fprintf (out, "H5I_ERROR_STACK");
-			break;
-		    case H5I_NTYPES:
-			fprintf (out, "H5I_NTYPES");
-			break;
-		    default:
-			fprintf (out, "%ld", (long)id_type);
-			break;
+                        case H5I_UNINIT:
+                            fprintf (out, "H5I_UNINIT");
+                            break;
+                        case H5I_BADID:
+                            fprintf (out, "H5I_BADID");
+                            break;
+                        case H5I_FILE:
+                            fprintf (out, "H5I_FILE");
+                            break;
+                        case H5I_GROUP:
+                            fprintf (out, "H5I_GROUP");
+                            break;
+                        case H5I_DATATYPE:
+                            fprintf (out, "H5I_DATATYPE");
+                            break;
+                        case H5I_DATASPACE:
+                            fprintf (out, "H5I_DATASPACE");
+                            break;
+                        case H5I_DATASET:
+                            fprintf (out, "H5I_DATASET");
+                            break;
+                        case H5I_ATTR:
+                            fprintf (out, "H5I_ATTR");
+                            break;
+                        case H5I_REFERENCE:
+                            fprintf (out, "H5I_REFERENCE");
+                            break;
+                        case H5I_VFL:
+                            fprintf (out, "H5I_VFL");
+                            break;
+                        case H5I_GENPROP_CLS:
+                            fprintf (out, "H5I_GENPROP_CLS");
+                            break;
+                        case H5I_GENPROP_LST:
+                            fprintf (out, "H5I_GENPROP_LST");
+                            break;
+                        case H5I_ERROR_CLASS:
+                            fprintf (out, "H5I_ERROR_CLASS");
+                            break;
+                        case H5I_ERROR_MSG:
+                            fprintf (out, "H5I_ERROR_MSG");
+                            break;
+                        case H5I_ERROR_STACK:
+                            fprintf (out, "H5I_ERROR_STACK");
+                            break;
+                        case H5I_NTYPES:
+                            fprintf (out, "H5I_NTYPES");
+                            break;
+                        default:
+                            fprintf (out, "%ld", (long)id_type);
+                            break;
 		    }
 		}
 		break;
diff --git a/src/H5D.c b/src/H5D.c
index 41376a9..5f9658d 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -4101,8 +4101,6 @@ done:
  *
  * Date:        August 14, 2002
  *
- * Comments:    Just flushing the compact data information currently.
- *
  * Modifications:
  *
  *-------------------------------------------------------------------------
@@ -4110,11 +4108,11 @@ done:
 herr_t
 H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags)
 {
-    int         num_dsets;      /* Number of datasets in file   */
+    unsigned    num_dsets;      /* Number of datasets in file   */
     hid_t       *id_list=NULL;  /* list of dataset IDs          */
     H5D_t       *dataset=NULL;  /* Dataset pointer              */
+    unsigned	u;              /* Index variable */
     herr_t      ret_value = SUCCEED;        /* Return value     */
-    int		j;              /* Index variable */
 
     FUNC_ENTER_NOAPI(H5D_flush, FAIL)
 
@@ -4122,18 +4120,17 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags)
     assert(f);
 
     /* Update layout message for compact dataset */
-    if((num_dsets=H5F_get_obj_count(f, H5F_OBJ_DATASET))<0)
-        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset count")
+    num_dsets=H5F_get_obj_count(f, H5F_OBJ_DATASET);
 
     /* Check for something to do */
     if(num_dsets>0) {
-        H5_CHECK_OVERFLOW(num_dsets,int,size_t);
+        H5_CHECK_OVERFLOW(num_dsets,unsigned,size_t);
         if(NULL==(id_list=H5MM_malloc((size_t)num_dsets*sizeof(hid_t))))
             HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate memory for ID list")
-        if(H5F_get_obj_ids(f, H5F_OBJ_DATASET, -1, id_list)<0)
+        if(H5F_get_obj_ids(f, H5F_OBJ_DATASET, -1, id_list) != num_dsets)
             HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset ID list")
-        for(j=0; j<num_dsets; j++) {
-            if(NULL==(dataset=H5I_object_verify(id_list[j], H5I_DATASET)))
+        for(u = 0; u < num_dsets; u++) {
+            if(NULL==(dataset=H5I_object_verify(id_list[u], H5I_DATASET)))
                 HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to get dataset object")
 
             /* Flush the raw data buffer, if we have a dirty one */
diff --git a/src/H5F.c b/src/H5F.c
index 6ff52d0..ba7a983 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -60,6 +60,12 @@ typedef struct H5F_olist_t {
     int   max_index;            /* Maximum # of IDs to put into array */
 } H5F_olist_t;    
 
+/* Struct for tracking "shared" file structs */
+typedef struct H5F_sfile_node_t {
+    H5F_file_t *shared;         /* Pointer to "shared" struct */
+    struct H5F_sfile_node_t *next;   /* Pointer to next node */
+} H5F_sfile_node_t;
+
 /* PRIVATE PROTOTYPES */
 
 #ifdef NOT_YET
@@ -67,19 +73,31 @@ static herr_t H5F_flush_all(hbool_t invalidate);
 static int H5F_flush_all_cb(void *f, hid_t fid, void *_invalidate);
 #endif /* NOT_YET */
 
+static herr_t H5F_close(H5F_t *f);
 static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id);
 static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id);
 static herr_t H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags);
-static int H5F_get_objects(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
+static unsigned H5F_get_objects(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
 static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
 static herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void** file_handle);
 
+/* Routines to operate on the shared file list */
+static herr_t H5F_shared_add(H5F_file_t *shared);
+static H5F_file_t * H5F_shared_search(H5FD_t *lf);
+static herr_t H5F_shared_remove(H5F_file_t *shared);
+
 /* Declare a free list to manage the H5F_t struct */
 H5FL_DEFINE_STATIC(H5F_t);
 
 /* Declare a free list to manage the H5F_file_t struct */
 H5FL_DEFINE_STATIC(H5F_file_t);
 
+/* Declare a free list to manage the H5F_sfile_node_t struct */
+H5FL_DEFINE_STATIC(H5F_sfile_node_t);
+
+/* Declare a local variable to track the shared file information */
+H5F_sfile_node_t *H5F_sfile_head_g = NULL;
+
 
 /*-------------------------------------------------------------------------
  * Function:	H5F_init
@@ -220,15 +238,9 @@ H5F_init_interface(void)
     FUNC_ENTER_NOAPI_NOINIT(H5F_init_interface)
 
     /*
-     * Initialize the atom group for the file IDs. There are two groups:
-     * the H5I_FILE group contains all the ID's for files which are currently
-     * open at the public API level while the H5I_FILE_CLOSING group contains
-     * ID's for files for which the application has called H5Fclose() but
-     * which are pending completion because there are object headers still
-     * open within the file.
+     * Initialize the atom group for the file IDs.
      */
-    if (H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE ||
-            H5I_register_type(H5I_FILE_CLOSING, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE)
+    if (H5I_register_type(H5I_FILE, (size_t)H5I_FILEID_HASHSIZE, 0, (H5I_free_t)H5F_close)<H5I_FILE)
         HGOTO_ERROR (H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface")
    
     /* ========== File Creation Property Class Initialization ============*/ 
@@ -438,13 +450,11 @@ H5F_term_interface(void)
     if (H5_interface_initialize_g) {
 	if ((n=H5I_nmembers(H5I_FILE))!=0) {
             H5I_clear_type(H5I_FILE, FALSE);
-	} else if ((n=H5I_nmembers(H5I_FILE_CLOSING))!=0) {
-            /* Attempt to unmount any child files from files that are closing */
-            (void)H5I_search(H5I_FILE_CLOSING, H5F_term_unmount_cb, NULL);
-	}
-        else {
+	} else {
+            /* Make certain we've cleaned up all the shared file objects */
+            HDassert(H5F_sfile_head_g == NULL);
+
 	    H5I_dec_type_ref(H5I_FILE);
-	    H5I_dec_type_ref(H5I_FILE_CLOSING);
 	    H5_interface_initialize_g = 0;
 	    n = 1; /*H5I*/
 	}
@@ -962,17 +972,15 @@ done:
  *
  *-------------------------------------------------------------------------
  */
-int
+unsigned
 H5F_get_obj_count(const H5F_t *f, unsigned types)
 {
-    int   ret_value;            /* Return value */
+    unsigned   ret_value;            /* Return value */
 
-    FUNC_ENTER_NOAPI_NOINIT(H5F_get_obj_count)
+    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_count)
 
-    if((ret_value=H5F_get_objects(f, types, -1, NULL)) < 0)
-        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get counts of opened file IDs and object IDs in the file")
+    ret_value=H5F_get_objects(f, types, -1, NULL);
 
-done:
     FUNC_LEAVE_NOAPI(ret_value)
 }
 
@@ -1014,7 +1022,7 @@ done:
 
 
 /*-------------------------------------------------------------------------
- * Function:    H5F_get_object_ids
+ * Function:    H5F_get_obj_ids
  *
  * Purpose:     Private function to return a list of opened object IDs.
  *
@@ -1027,17 +1035,15 @@ done:
  *      
  *-------------------------------------------------------------------------
  */
-int
+unsigned
 H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *oid_list)
 {
-    int ret_value;              /* Return value */
+    unsigned ret_value;              /* Return value */
  
-    FUNC_ENTER_NOAPI_NOINIT(H5F_get_obj_ids)
+    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_obj_ids)
 
-    if((ret_value=H5F_get_objects(f, types, max_objs, oid_list)) < 0)
-        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get object IDs opened in the file")
+    ret_value = H5F_get_objects(f, types, max_objs, oid_list);
 
-done:
     FUNC_LEAVE_NOAPI(ret_value)
 }
 
@@ -1057,12 +1063,12 @@ done:
  *
  *---------------------------------------------------------------------------
  */
-static int
+static unsigned
 H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_list)
 {
     unsigned obj_id_count=0;    /* Number of open IDs */
     H5F_olist_t olist;          /* Structure to hold search results */
-    int ret_value;              /* Return value */
+    unsigned ret_value;         /* Return value */
 
     FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_objects)
 
@@ -1084,45 +1090,42 @@ H5F_get_objects(const H5F_t *f, unsigned types, int max_index, hid_t *obj_id_lis
 
     /* Search through file IDs to count the number, and put their
      * IDs on the object list */
-    if( (types & H5F_OBJ_FILE) && H5I_nmembers(H5I_FILE) > 0 ) {
+    if(types & H5F_OBJ_FILE) {
         olist.obj_type = H5I_FILE;
         (void)H5I_search(H5I_FILE, H5F_get_objects_cb, &olist);
-    }
+    } /* end if */
 
     /* Search through dataset IDs to count number of datasets, and put their 
      * IDs on the object list */
-    if( (max_index<0 || (int)olist.list_index< max_index) && (types & H5F_OBJ_DATASET) && H5I_nmembers(H5I_DATASET) > 0 ) {
+    if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_DATASET) ) {
         olist.obj_type = H5I_DATASET;
         (void)H5I_search(H5I_DATASET, H5F_get_objects_cb, &olist);
     }
 
     /* Search through group IDs to count number of groups, and put their 
      * IDs on the object list */
-    if( (max_index<0 || (int)olist.list_index< max_index) && (types & H5F_OBJ_GROUP) && H5I_nmembers(H5I_GROUP) > 0 ) {
+    if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_GROUP) ) {
         olist.obj_type = H5I_GROUP;
         (void)H5I_search(H5I_GROUP, H5F_get_objects_cb, &olist);
     }
 
     /* Search through datatype IDs to count number of named datatypes, and put their 
      * IDs on the object list */
-    if( (max_index<0 || (int)olist.list_index< max_index) && (types & H5F_OBJ_DATATYPE) && H5I_nmembers(H5I_DATATYPE) > 0 ) {
+    if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_DATATYPE) ) {
         olist.obj_type = H5I_DATATYPE;
         (void)H5I_search(H5I_DATATYPE, H5F_get_objects_cb, &olist);
     }
 
     /* Search through attribute IDs to count number of attributes, and put their 
      * IDs on the object list */
-    if( (max_index<0 || (int)olist.list_index< max_index) && (types & H5F_OBJ_ATTR) && H5I_nmembers(H5I_ATTR) > 0 ) {
+    if( (max_index < 0 || (int)olist.list_index < max_index) && (types & H5F_OBJ_ATTR) ) {
         olist.obj_type = H5I_ATTR;
         (void)H5I_search(H5I_ATTR, H5F_get_objects_cb, &olist);
     }
 
     /* Set the number of objects currently open */
-    H5_ASSIGN_OVERFLOW(ret_value,obj_id_count,unsigned,int);
+    ret_value = obj_id_count;
 
-#ifdef LATER
-done:
-#endif /* LATER */
     FUNC_LEAVE_NOAPI(ret_value)
 }
 
@@ -1296,39 +1299,6 @@ done:
 
 
 /*-------------------------------------------------------------------------
- * Function:	H5F_equal
- *
- * Purpose:	Compares NEEDLE to a file from the HAYSTACK.
- *
- * Return:	Success:	Returns positive if two files are equal,
- *				zero otherwise.
- *
- *		Failure:	Negative
- *
- * Programmer:	Robb Matzke
- *              Monday, August  2, 1999
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static int
-H5F_equal(void *_haystack, hid_t UNUSED id, void *_needle)
-{
-    H5F_t		*haystack = (H5F_t*)_haystack;
-    const H5FD_t	*needle = (const H5FD_t*)_needle;
-    int		retval;
-    
-    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_equal)
-
-    retval = (0==H5FD_cmp(haystack->shared->lf, needle));
-
-    FUNC_LEAVE_NOAPI(retval)
-}
-
-
-/*-------------------------------------------------------------------------
  * Function:	H5F_locate_signature
  *
  * Purpose:	Finds the HDF5 super block signature in a file.	The signature
@@ -1557,20 +1527,19 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
 	 * The cache might be created with a different number of elements and
 	 * the access property list should be updated to reflect that.
 	 */
-	if ( SUCCEED != H5AC_create(f, &(f->shared->mdc_initCacheCfg)) ) {
-
-	    HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, \
-                        "unable to create meta data cache")
-
-        } 
+	if ( SUCCEED != H5AC_create(f, &(f->shared->mdc_initCacheCfg)) )
+	    HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create meta data cache")
 
         /* Create the file's "open object" information */
         if(H5FO_create(f)<0)
-	    HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object TBBT")
+	    HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure")
+
+        /* Add new "shared" struct to list of open files */
+        if(H5F_shared_add(f->shared) < 0)
+	    HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to append to list of open files")
     } /* end else */
     
     f->shared->nrefs++;
-    f->nrefs = 1;
 
     /* Set return value */
     ret_value = f;
@@ -1627,77 +1596,83 @@ H5F_dest(H5F_t *f, hid_t dxpl_id)
     
     FUNC_ENTER_NOAPI_NOINIT(H5F_dest)
 
-    if (f && 1==f->nrefs) {
-	if (1==f->shared->nrefs) {
-	    /*
-	     * Do not close the root group since we didn't count it, but free
-	     * the memory associated with it.
-	     */
-	    if (f->shared->root_grp) {
-                /* Free the ID to name buffer */
-                if(H5G_free_grp_name(f->shared->root_grp)<0) {
-                    HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
-                    ret_value = FAIL; /*but keep going*/
-                } /* end if */
-
-                /* Free the memory for the root group */
-                if(H5G_free(f->shared->root_grp)<0) {
-                    HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
-                    ret_value = FAIL; /*but keep going*/
-                } /* end if */
-                f->shared->root_grp=NULL;
-            }
-	    if (H5AC_dest(f, dxpl_id)) {
-		HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
-		ret_value = FAIL; /*but keep going*/
-	    }
-	    if (H5FO_dest(f)<0) {
+    /* Sanity check */
+    HDassert(f);
+
+    if (1==f->shared->nrefs) {
+        /* Remove shared file struct from list of open files */
+        if(H5F_shared_remove(f->shared) < 0) {
+            HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
+            ret_value = FAIL; /*but keep going*/
+        } /* end if */
+
+        /*
+         * Do not close the root group since we didn't count it, but free
+         * the memory associated with it.
+         */
+        if (f->shared->root_grp) {
+            /* Free the ID to name buffer */
+            if(H5G_free_grp_name(f->shared->root_grp)<0) {
                 HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
                 ret_value = FAIL; /*but keep going*/
-	    } /* end if */
-	    f->shared->cwfs = H5MM_xfree (f->shared->cwfs);
-	    if (H5G_node_close(f)<0) {
+            } /* end if */
+
+            /* Free the memory for the root group */
+            if(H5G_free(f->shared->root_grp)<0) {
                 HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
                 ret_value = FAIL; /*but keep going*/
-	    } /* end if */
-
-	    /* Destroy file creation properties */
-            if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) 
-                HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list")
-            if((ret_value=H5I_dec_ref(f->shared->fcpl_id)) < 0)
-                HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close property list")
-
-	    /* Destroy shared file struct */
-	    if (H5FD_close(f->shared->lf)<0) {
-		HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file");
-		ret_value = FAIL; /*but keep going*/
-	    }
-	    f->shared = H5FL_FREE(H5F_file_t,f->shared);
-	    
-	} else if (f->shared->nrefs>0) {
-	    /*
-	     * There are other references to the shared part of the file.
-	     * Only decrement the reference count.
-	     */
-	    --f->shared->nrefs;
-	}
+            } /* end if */
+            f->shared->root_grp=NULL;
+        }
+        if (H5AC_dest(f, dxpl_id)) {
+            HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
+            ret_value = FAIL; /*but keep going*/
+        }
+        if (H5FO_dest(f)<0) {
+            HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
+            ret_value = FAIL; /*but keep going*/
+        } /* end if */
+        f->shared->cwfs = H5MM_xfree (f->shared->cwfs);
+        if (H5G_node_close(f)<0) {
+            HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file");
+            ret_value = FAIL; /*but keep going*/
+        } /* end if */
 
-	/* Free the non-shared part of the file */
-	f->name = H5MM_xfree(f->name);
-	f->mtab.child = H5MM_xfree(f->mtab.child);
-	f->mtab.nalloc = 0;
-	H5FL_FREE(H5F_t,f);
-    } else if (f && f->nrefs>0) {
-	/*
-	 * There are other references to this file. Only decrement the
-	 * reference count.
-	 */
-	--f->nrefs;
+        /* Destroy file creation properties */
+        if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) {
+            HERROR(H5E_PLIST, H5E_BADTYPE, "not a property list");
+            ret_value = FAIL; /*but keep going*/
+        } /* end if */
+        if((ret_value=H5I_dec_ref(f->shared->fcpl_id)) < 0) {
+            HERROR(H5E_PLIST, H5E_CANTFREE, "can't close property list");
+            ret_value = FAIL; /*but keep going*/
+        } /* end if */
+
+        /* Close low-level file */
+        if (H5FD_close(f->shared->lf)<0) {
+            HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file");
+            ret_value = FAIL; /*but keep going*/
+        }
+
+        /* Destroy shared file struct */
+        f->shared = H5FL_FREE(H5F_file_t,f->shared);
+        
+    } else if (f->shared->nrefs>0) {
+        /*
+         * There are other references to the shared part of the file.
+         * Only decrement the reference count.
+         */
+        --f->shared->nrefs;
     }
 
-done:
+    /* Free the non-shared part of the file */
+    f->name = H5MM_xfree(f->name);
+    f->mtab.child = H5MM_xfree(f->mtab.child);
+    f->mtab.nalloc = 0;
+    H5FL_FREE(H5F_t,f);
+
     FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_dest() */
 
 
 /*-------------------------------------------------------------------------
@@ -1836,8 +1811,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
     } /* end if */
 
     /* Is the file already open? */
-    if ((file=H5I_search(H5I_FILE, H5F_equal, lf))!=NULL ||
-            (file=H5I_search(H5I_FILE_CLOSING, H5F_equal, lf))!=NULL) {
+    if ((shared = H5F_shared_search(lf)) != NULL) {
 	/*
 	 * The file is already open, so use that one instead of the one we
 	 * just opened. We only one one H5FD_t* per file so one doesn't
@@ -1847,24 +1821,17 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
 	 * exists), or if the new request adds write access (since the
 	 * readers don't expect the file to change under them).
 	 */
-	if(H5FD_close(lf)<0) {
-	    file = NULL; /*to prevent destruction of wrong file*/
+	if(H5FD_close(lf)<0)
 	    HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info")
-        } /* end if */
-	if (flags & H5F_ACC_TRUNC) {
-	    file = NULL; /*to prevent destruction of wrong file*/
+	if (flags & H5F_ACC_TRUNC)
 	    HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open")
-	}
-	if (flags & H5F_ACC_EXCL) {
-	    file = NULL; /*to prevent destruction of wrong file*/
+	if (flags & H5F_ACC_EXCL)
 	    HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists")
-	}
-	if ((flags & H5F_ACC_RDWR) && 0==(file->intent & H5F_ACC_RDWR)) {
-	    file = NULL; /*to prevent destruction of wrong file*/
+	if ((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR))
 	    HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only")
-	}
 
-        if ((file = H5F_new(file->shared, fcpl_id, fapl_id)) == NULL)
+        /* Allocate new "high-level" file struct */
+        if ((file = H5F_new(shared, fcpl_id, fapl_id)) == NULL)
             HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object")
 
 	lf = file->shared->lf;
@@ -2608,26 +2575,58 @@ H5F_close(H5F_t *f)
 
     FUNC_ENTER_NOAPI_NOINIT(H5F_close)
 
-    assert(f->nrefs>0);
+    /* Sanity check */
+    HDassert(f);
+    HDassert(f->file_id > 0);   /* This routine should only be called when a file ID's ref count drops to zero */
 
-    /*
-     * If this file is referenced more than once then just decrement the
-     * count and return.
-     */
-    if (f->nrefs>1) {
-	/* Decrement reference counts */
-        if (H5F_dest(f, H5AC_dxpl_id)<0)
-            HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file")
-	HGOTO_DONE(SUCCEED)
-    } /* end if */
+    /* Reset the file ID for this file */
+    f->file_id = -1;
 
-    /* Double-check that this file should be closed */
-    assert(1==f->nrefs);
-    
-    /* if close degree if "semi" and there are objects left open and we are
-     * holding open the file with this file ID, fail now */
-    if(f->shared->fc_degree==H5F_CLOSE_SEMI && f->nopen_objs>0)
-        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open")
+    /* Attempt to close the file/mount hierarchy */
+    if(H5F_try_close(f) < 0)
+        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file")
+
+done:
+    FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5F_try_close
+ *
+ * Purpose:	Attempts to close a file due to one of several actions:
+ *                      - The reference count on the file ID dropped to zero
+ *                      - The last open object was closed in the file
+ *                      - The file was unmounted
+ *
+ * Return:	Non-negative on success/Negative on failure
+ *
+ * Programmer:	Quincey Koziol
+ *		Tuesday, July 19, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_try_close(H5F_t *f)
+{
+    unsigned            nopen_files = 0;        /* Number of open files in file/mount hierarchy */
+    unsigned            nopen_objs = 0;         /* Number of open objects in file/mount hierarchy */
+    herr_t	        ret_value = SUCCEED;    /* Return value */
+
+    FUNC_ENTER_NOAPI_NOINIT(H5F_try_close)
+
+    /* Sanity check */
+    HDassert(f);
+
+    /* Check if this file is already in the process of closing */
+    if(f->closing)
+        HGOTO_DONE(SUCCEED)
+
+    /* Get the number of open objects and open files on this file/mount hierarchy */
+    if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0)
+        HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy")
 
     /*
      * Close file according to close degree:
@@ -2642,134 +2641,81 @@ H5F_close(H5F_t *f)
     switch(f->shared->fc_degree) {
         case H5F_CLOSE_WEAK:
             /*
-             * If object headers are still open then delay deletion of 
+             * If file or object IDS are still open then delay deletion of 
              * resources until they have all been closed.  Flush all 
-             * caches and update the object eader anyway so that failing toi
-             * close all objects isn't a major problem. If the file is on 
-             * the H5I_FILE list then move it to the H5I_FILE_CLOSING list 
-             * instead.
+             * caches and update the object header anyway so that failing to
+             * close all objects isn't a major problem.
              */ 
-            if (f->nopen_objs>0) {
-#ifdef H5F_DEBUG
-                if (H5DEBUG(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_objs,
-                    1 == f->nopen_objs?" is":"s are",
-                    1 == f->nopen_objs?"that header is":"those headers are");
-                }
-#endif
-                /* If the only open objects are the groups that are mount points, */
-                /* allow the file to close and shut things down */
-                if(f->nopen_objs == f->mtab.nmounts) {
-                    unsigned u;         /* Local index variable */
-                    hbool_t really_close;  /* Whether to delay the file close by going to a "closing" state */
-
-                    /* Check for open groups on mount points */
-                    really_close = TRUE;
-                    for(u = 0; u < f->mtab.nmounts; u++) {
-                        if(H5G_get_shared_count(f->mtab.child[u].group) > 1) {
-                            really_close = FALSE;
-                            break;
-                        } /* end if */
-                    } /* end for */
-
-                    /* If we really want to close this file now */
-                    if(really_close)
-                        break;
-                } /* end if */
-
-                /* Register an ID for closing the file later */
-                if (!f->closing)
-                    f->closing  = H5I_register(H5I_FILE_CLOSING, f);
-
-                /* Invalidate file ID */
-                f->file_id = -1;
-
+            if ((nopen_files + nopen_objs) > 0)
                 HGOTO_DONE(SUCCEED)
-            } else {
-                if (f->closing) {
-
-#ifdef H5F_DEBUG
-                    if (H5DEBUG(F))
-                        fprintf(H5DEBUG(F), "H5F: H5F_close: operation completing\n");
-#endif
-                } /* end if */
-            } /* end else */
             break;
 
         case H5F_CLOSE_SEMI:
+            /* Can leave safely if file IDs are still open on this file */
+            if (nopen_files > 0)
+                HGOTO_DONE(SUCCEED)
+
+            /* Sanity check: If close degree if "semi" and we have gotten this
+             * far and there are objects left open, bail out now */
+            HDassert(nopen_files == 0 && nopen_objs == 0);
+
             /* If we've gotten this far (ie. there are no open objects in the file), fall through to flush & close */
             break;
 
         case H5F_CLOSE_STRONG:
-            /* Force to close all opened objects in file */
-            while(f->nopen_objs > 0) {
-                int obj_count;          /* # of open objects */
-                hid_t objs[128];        /* Array of objects to close */
-                int i;                  /* Local index variable */
-
-                /* Get the list of IDs of open dataset objects */
-                while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) {
-               
-                    /* Try to close all the open objects */
-                    for(i=0; i<obj_count; i++)
-                        if(H5I_dec_ref(objs[i]) < 0)
-                            HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
-                } /* end while */
-
-                /* Get the list of IDs of open group objects */
-                while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_GROUP, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) {
-               
-                    /* Try to close all the open objects */
-                    for(i=0; i<obj_count; i++)
-                        if(H5I_dec_ref(objs[i]) < 0)
-                            HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
-                } /* end while */
-
-                /* Get the list of IDs of open named datatype objects */
-                while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATATYPE, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) {
-               
-                    /* Try to close all the open objects */
-                    for(i=0; i<obj_count; i++)
-                        if(H5I_dec_ref(objs[i]) < 0)
-                            HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
-                } /* end while */
-
-                /* Get the list of IDs of open attribute objects */
-                while((obj_count=H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs))!=0) {
-               
-                    /* Try to close all the open objects */
-                    for(i=0; i<obj_count; i++)
-                        if(H5I_dec_ref(objs[i]) < 0)
-                            HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
-                } /* end while */
-            } /* end while */
+            /* If there are other open files in the hierarchy, we can leave now */
+            if(nopen_files > 0)
+                HGOTO_DONE(SUCCEED)
+
+            /* If we've gotten this far (ie. there are no open file IDs in the file/mount hierarchy), fall through to flush & close */
             break;
 
         default:
             HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, unknown file close degree")
     } /* end switch */
 
-    /*
-     * Unmount and close each child before closing the current file.
-     */
-    assert(NULL==f->mtab.parent);
-    if(H5F_close_mounts(f) < 0)
-        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child file")
+    /* Mark this file as closing (prevents re-entering file shutdown code below) */
+    f->closing = TRUE;
 
-    /* Invalidate file ID */
-    f->file_id = -1;
+    /* If the file close degree is "strong", close all the open objects in this file */
+    if(f->shared->fc_degree == H5F_CLOSE_STRONG) {
+        HDassert(nopen_files ==  0);
 
-    /* Flush at this point since the file will be closed */
+        /* Forced close of all opened objects in this file */
+        if(f->nopen_objs > 0) {
+            unsigned obj_count;     /* # of open objects */
+            hid_t objs[128];        /* Array of objects to close */
+            unsigned u;             /* Local index variable */
+
+            /* Get the list of IDs of open dataset, group, named datatype & attribute objects */
+            while((obj_count = H5F_get_obj_ids(f, H5F_OBJ_LOCAL|H5F_OBJ_DATASET|H5F_OBJ_GROUP|H5F_OBJ_DATATYPE|H5F_OBJ_ATTR, (int)(sizeof(objs)/sizeof(objs[0])), objs)) != 0) {
+           
+                /* Try to close all the open objects in this file */
+                for(u = 0; u < obj_count; u++)
+                    if(H5I_dec_ref(objs[u]) < 0)
+                        HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object")
+            } /* end while */
+        } /* end if */
+    } /* end if */
+
+    /* 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)
+            HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file")
+
+    /* Unmount and close each child before closing the current file. */
+    if(H5F_close_mounts(f) < 0)
+        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files")
 
-    /* Dump debugging info */
 #if H5AC_DUMP_STATS_ON_CLOSE
+    /* Dump debugging info */
     H5AC_stats(f);
 #endif /* H5AC_DUMP_STATS_ON_CLOSE */
 
-    /* Only try to flush the file if it was opened with write access */
+    /* Flush at this point since the file will be closed */
+    /* (Only try to flush the file if it was opened with write access) */
     if(f->intent&H5F_ACC_RDWR) {
 #ifdef H5_HAVE_FPHDF5
         /*
@@ -2803,12 +2749,12 @@ H5F_close(H5F_t *f)
      * shared H5F_file_t struct. If the reference count for the H5F_file_t
      * struct reaches zero then destroy it also.
      */
-    if (H5F_dest(f,H5AC_dxpl_id)<0)
-	HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file")
+    if (H5F_dest(f, H5AC_dxpl_id) < 0)
+        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file")
 
 done:
     FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_close() */
+} /* end H5F_try_close() */
 
 
 /*-------------------------------------------------------------------------
@@ -2835,14 +2781,42 @@ done:
 herr_t
 H5Fclose(hid_t file_id)
 {
+    H5F_t	*f;
     herr_t	ret_value = SUCCEED;
 
     FUNC_ENTER_API(H5Fclose, FAIL)
     H5TRACE1("e","i",file_id);
 
     /* Check/fix arguments. */
-    if (NULL==H5I_object_verify(file_id,H5I_FILE))
-	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file atom")
+    if (NULL == (f = H5I_object_verify(file_id,H5I_FILE)))
+	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID")
+
+    /* Perform checks for "semi" file close degree here, since closing the
+     * file ID will mess things up if we need to return FAIL */
+    if(f->shared->fc_degree == H5F_CLOSE_SEMI) {
+        int ref_count;                  /* Reference count for file's ID */
+
+        /* Get the reference count for this ID */
+        if((ref_count = H5I_get_ref(file_id)) < 0)
+            HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count")
+
+        /* If we will be decrementing the reference count to zero, check for objects open */
+        if(ref_count == 1) {
+            unsigned nopen_files = 0;       /* Number of open files in file/mount hierarchy */
+            unsigned nopen_objs = 0;        /* Number of open objects in file/mount hierarchy */
+
+            /* Get the number of open objects and open files on this file/mount hierarchy */
+            if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0)
+                HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy")
+
+            /* If there are no other file IDs open on this file/mount hier., but
+             * there are still open objects, issue an error and bail out now,
+             * before decrementing the file ID's reference count and triggering
+             * a "real" attempt at closing the file */
+            if(nopen_files == 1 && nopen_objs > 0)
+                HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open")
+        } /* end if */
+    } /* end if */
 
     /*
      * Decrement reference count on atom.  When it reaches zero the file will
@@ -2898,6 +2872,9 @@ H5Freopen(hid_t file_id)
     /* Keep old file's read/write intent in new file */
     new_file->intent=old_file->intent;
 
+    /* Duplicate old file's name */
+    new_file->name = H5MM_xstrdup(old_file->name);
+
     if ((ret_value=H5I_register(H5I_FILE, new_file))<0)
 	HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle")
 
@@ -2906,7 +2883,7 @@ H5Freopen(hid_t file_id)
 
 done:
     if (ret_value<0 && new_file)
-	if(H5F_close(new_file)<0)
+	if(H5F_dest(new_file, H5AC_dxpl_id)<0)
 	    HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file")
     FUNC_LEAVE_API(ret_value)
 }
@@ -3292,15 +3269,9 @@ H5F_get_id(H5F_t *file)
     assert(file);
 
     if(file->file_id == -1) {
-        if(H5I_remove(file->closing)==NULL)
-	    HGOTO_ERROR(H5E_ATOM, H5E_READERROR, FAIL, "unable to remove from closing list")
-                
         /* Get an atom for the file */
         if ((file->file_id = H5I_register(H5I_FILE, file))<0)
 	    HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file")
-           
-        /* Indicate file is not closing */     
-        file->closing = 0;
     } else {
         /* Increment reference count on atom. */
         if (H5I_inc_ref(file->file_id)<0)
@@ -4154,21 +4125,33 @@ done:
 ssize_t
 H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
 {
-    H5G_entry_t   *ent;       /*symbol table entry */
+    H5G_entry_t   *ent;         /*symbol table entry */
+    H5F_t   *f;               /* Top file in mount hierarchy */
     size_t        len=0;
     ssize_t       ret_value;
 
     FUNC_ENTER_API (H5Fget_name, FAIL)
     H5TRACE3("Zs","ixz",obj_id,name,size);
 
-    /* get symbol table entry */
-    if((ent = H5G_loc(obj_id))==NULL)
-         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID")
+    /* For file IDs, get the file object directly */
+    /* (This prevents the H5G_loc() call from returning the file pointer for
+     * the top file in a mount hierarchy)
+     */
+    if(H5I_get_type(obj_id) == H5I_FILE ) {
+        if (NULL==(f=H5I_object(obj_id)))
+            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+    } /* end if */
+    else {
+        /* Get symbol table entry */
+        if((ent = H5G_loc(obj_id))==NULL)
+             HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID")
+        f = ent->file;
+    } /* end else */
 
-    len = HDstrlen(ent->file->name);
+    len = HDstrlen(f->name);
 
     if(name) {
-        HDstrncpy(name, ent->file->name, MIN(len+1,size));
+        HDstrncpy(name, f->name, MIN(len+1,size));
         if(len >= size)
             name[size-1]='\0';
     } /* end if */
@@ -4179,3 +4162,143 @@ H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
 done:
     FUNC_LEAVE_API(ret_value)
 } /* end H5Fget_name() */
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5F_shared_add
+ *
+ * Purpose:	Add a "shared" file struct to the list of open files
+ *
+ * Return:	SUCCEED/FAIL
+ *
+ * Programmer:	Quincey Koziol
+ *              Monday, July 18, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_shared_add(H5F_file_t *shared)
+{
+    H5F_sfile_node_t *new;              /* New shared file node */
+    herr_t ret_value = SUCCEED;         /* Return value */
+    
+    FUNC_ENTER_NOAPI_NOINIT(H5F_shared_add)
+
+    /* Sanity check */
+    HDassert(shared);
+
+    /* Allocate new shared file node */
+    if (NULL == (new = H5FL_CALLOC(H5F_sfile_node_t)))
+	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+    /* Set shared file value */
+    new->shared = shared;
+
+    /* Prepend to list of shared files open */
+    new->next = H5F_sfile_head_g;
+    H5F_sfile_head_g = new;
+
+done:
+    FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_shared_add() */
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5F_shared_search
+ *
+ * Purpose:	Search for a "shared" file with low-level file info that
+ *              matches
+ *
+ * Return:	Non-NULL on success / NULL on failure
+ *
+ * Programmer:	Quincey Koziol
+ *              Monday, July 18, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5F_file_t *
+H5F_shared_search(H5FD_t *lf)
+{
+    H5F_sfile_node_t *curr;             /* Current shared file node */
+    H5F_file_t *ret_value = NULL;       /* Return value */
+    
+    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_shared_search)
+
+    /* Sanity check */
+    HDassert(lf);
+
+    /* Iterate through low-level files for matching low-level file info */
+    curr = H5F_sfile_head_g;
+    while(curr) {
+        /* Check for match */
+        if(0==H5FD_cmp(curr->shared->lf, lf))
+            HGOTO_DONE(curr->shared)
+
+        /* Advance to next shared file node */
+        curr = curr->next;
+    } /* end while */
+
+done:
+    FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_shared_search() */
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5F_shared_remove
+ *
+ * Purpose:	Remove a "shared" file struct from the list of open files
+ *
+ * Return:	SUCCEED/FAIL
+ *
+ * Programmer:	Quincey Koziol
+ *              Monday, July 18, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F_shared_remove(H5F_file_t *shared)
+{
+    H5F_sfile_node_t *curr;             /* Current shared file node */
+    H5F_sfile_node_t *last;             /* Last shared file node */
+    herr_t ret_value = SUCCEED;         /* Return value */
+    
+    FUNC_ENTER_NOAPI_NOINIT(H5F_shared_remove)
+
+    /* Sanity check */
+    HDassert(shared);
+
+    /* Locate shared file node with correct shared file */
+    last = NULL;
+    curr = H5F_sfile_head_g;
+    while(curr && curr->shared != shared) {
+        /* Advance to next node */
+        last = curr;
+        curr = curr->next;
+    } /* end while */
+
+    /* Indicate error if the node wasn't found */
+    if(curr == NULL)
+	HGOTO_ERROR(H5E_FILE, H5E_NOTFOUND, FAIL, "can't find shared file info")
+
+    /* Remove node found from list */
+    if(last != NULL)
+        /* Removing middle or tail node in list */
+        last->next = curr->next;
+    else
+        /* Removing head node in list */
+        H5F_sfile_head_g = curr->next;
+
+    /* Release the shared file node struct */
+    /* (the shared file info itself is freed elsewhere) */
+    H5FL_FREE(H5F_sfile_node_t, curr);
+
+done:
+    FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F_shared_remove() */
+
diff --git a/src/H5Fmount.c b/src/H5Fmount.c
index c67f40d..7e234a5 100644
--- a/src/H5Fmount.c
+++ b/src/H5Fmount.c
@@ -86,7 +86,7 @@ H5F_close_mounts(H5F_t *f)
             HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close child group")
 
         /* Close the child file */
-        if(H5F_close(f->mtab.child[u].file) < 0)
+        if(H5F_try_close(f->mtab.child[u].file) < 0)
             HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close child file")
     } /* end if */
     f->mtab.nmounts = 0;
@@ -97,46 +97,6 @@ done:
 
 
 /*-------------------------------------------------------------------------
- * Function:	H5F_term_unmount_cb 
- *
- * Purpose:	H5F_term_interface' callback function.  This routine
- *              unmounts child files from files that are in the "closing"
- *              state.
- *
- * Programmer:  Quincey Koziol
- *              Thursday, Jun 30, 2005
- *
- * Modification:
- *
- *-------------------------------------------------------------------------
- */
-int
-H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void UNUSED *key)
-{
-    H5F_t *f = (H5F_t *)obj_ptr;    /* Alias for search info */
-    int      ret_value = FALSE;     /* Return value */
- 
-    FUNC_ENTER_NOAPI_NOINIT(H5F_term_unmount_cb)
-
-    assert(f);
-
-    if(f->mtab.nmounts) {
-        /* Unmount all child files */
-        if(H5F_close_mounts(f) < 0)
-            HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child file")
-
-        /* Decrement reference count for file */
-        H5I_dec_ref(obj_id);
-    } /* end if */
-    else
-        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "no files to unmount")
-
-done:
-    FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_term_unmount_cb() */
-
-
-/*-------------------------------------------------------------------------
  * Function:	H5F_mount
  *
  * Purpose:	Mount file CHILD onto the group specified by LOC and NAME,
@@ -181,7 +141,8 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
     assert(TRUE==H5P_isa_class(plist_id,H5P_MOUNT));
 
     /*
-     * Check that the child isn't mounted, that the mount point exists, and
+     * Check that the child isn't mounted, that the mount point exists, that
+     * 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)
@@ -197,6 +158,9 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
 	if (ancestor==child)
 	    HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount would introduce a cycle")
     }
+
+    if(parent->shared->fc_degree != child->shared->fc_degree)
+        HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mounted file has different file close degree than parent")
     
     /*
      * Use a binary search to locate the position that the child should be
@@ -239,7 +203,10 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
     parent->mtab.child[md].group = mount_point;
     parent->mtab.child[md].file = child;
     child->mtab.parent = parent;
-    child->nrefs++;
+
+    /* Set the group's mountpoint flag */
+    if(H5G_mount(parent->mtab.child[md].group)<0)
+        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to set group mounted flag")
 
     /* Search the open IDs and replace names for mount operation */
     /* We pass H5G_UNKNOWN as object type; search all IDs */
@@ -317,8 +284,7 @@ H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
     mnt_ent = H5G_entof(mounted);
     ent = H5G_entof(child->shared->root_grp);
 
-    if (child->mtab.parent &&
-	H5F_addr_eq(mnt_ent->header, ent->header)) {
+    if (child->mtab.parent && H5F_addr_eq(mnt_ent->header, ent->header)) {
 	/*
 	 * 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.
@@ -332,18 +298,21 @@ H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
 
 		/* Unmount the child */
 		parent->mtab.nmounts -= 1;
+                if(H5G_unmount(parent->mtab.child[md].group)<0)
+                    HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to reset group mounted flag")
 		if(H5G_close(parent->mtab.child[i].group)<0)
                     HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group")
 		child->mtab.parent = NULL;
-		if(H5F_close(child)<0)
+		if(H5F_try_close(child)<0)
                     HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close unmounted file")
+
+                /* Eliminate the mount point from the table */
 		HDmemmove(parent->mtab.child+i, parent->mtab.child+i+1,
                     (parent->mtab.nmounts-i)* sizeof(parent->mtab.child[0]));
 		ret_value = SUCCEED;
 	    }
 	}
-	assert(ret_value>=0);
-	
+	HDassert(ret_value>=0);
     } else {
 	/*
 	 * We've been given the mount point in the parent.  We use a binary
@@ -368,11 +337,15 @@ H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
 
 	/* Unmount the child */
 	parent->mtab.nmounts -= 1;
+	if(H5G_unmount(parent->mtab.child[md].group)<0)
+            HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to reset group mounted flag")
 	if(H5G_close(parent->mtab.child[md].group)<0)
             HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group")
 	parent->mtab.child[md].file->mtab.parent = NULL;
-	if(H5F_close(parent->mtab.child[md].file)<0)
+	if(H5F_try_close(parent->mtab.child[md].file)<0)
             HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close unmounted file")
+
+        /* Eliminate the mount point from the table */
 	HDmemmove(parent->mtab.child+md, parent->mtab.child+md+1,
             (parent->mtab.nmounts-md)*sizeof(parent->mtab.child[0]));
 	ret_value = SUCCEED;
@@ -621,100 +594,89 @@ done:
 
 
 /*-------------------------------------------------------------------------
- * Function:	H5F_check_mounts_recurse
+ * Function:	H5F_mount_count_ids_recurse
  *
- * Purpose:	Helper routine for checking for file mounting hierarchies to
- *              close.
+ * Purpose:	Helper routine for counting number of open IDs in mount
+ *              hierarchy.
  *
- * Return:	TRUE if entire hierarchy can be closed / FALSE otherwise
+ * Return:	<none>
  *
  * Programmer:	Quincey Koziol
- *              Saturday, July  2, 2005
+ *              Tuesday, July 19, 2005
  *
  * Modifications:
  *
  *-------------------------------------------------------------------------
  */
-static hbool_t
-H5F_check_mounts_recurse(H5F_t *f)
+static void
+H5F_mount_count_ids_recurse(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs)
 {
-    hbool_t ret_value = FALSE;          /* Return value */
+    unsigned u;                         /* Local index value */
 
-    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_check_mounts_recurse)
+    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_mount_count_ids_recurse)
 
-    /* Check if this file is closing and if the only objects left open are
-     * the mount points */
-    if((f->closing || (f->nrefs == 1 && f->mtab.parent)) && f->nopen_objs == f->mtab.nmounts) {
-        unsigned u;
+    /* Sanity check */
+    HDassert(f);
+    HDassert(nopen_files);
+    HDassert(nopen_objs);
 
-        /* Iterate over files mounted in this file and check if all can be closed */
-        for(u = 0; u < f->mtab.nmounts; u++) {
-            if(H5G_get_shared_count(f->mtab.child[u].group) > 1
-                    || !H5F_check_mounts_recurse(f->mtab.child[u].file))
-                HGOTO_DONE(FALSE)
-        } /* end for */
+    /* If this file is still open, increment number of file IDs open */
+    if(f->file_id > 0)
+        *nopen_files += 1;
 
-        /* Set return value */
-        ret_value = TRUE;
-    } /* end if */
+    /* Increment number of open objects in file 
+     * (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);
 
-done:
-    FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_check_mounts_recurse() */
+    /* 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);
+    } /* end for */
+
+    FUNC_LEAVE_NOAPI_VOID
+} /* end H5F_mount_count_ids_recurse() */
 
 
 /*-------------------------------------------------------------------------
- * Function:	H5F_check_mounts
+ * Function:	H5F_mount_count_ids
  *
- * Purpose:	Check for file mounting hierarchies that have been created
- *              and that now are composed completely of files that are closing
- *              and have no more open objects in them.
+ * Purpose:	Count the number of open file & object IDs in a mount hierarchy
  *
- *              When such a mounting hierarchy is detected, unmount and close
- *              all the files involved.
- *
- * Return:	Non-negative on success/Negative on failure
+ * Return:	SUCCEED/FAIL
  *
  * Programmer:	Quincey Koziol
- *              Saturday, July  2, 2005
+ *              Tues, July 19, 2005
  *
  * Modifications:
  *
  *-------------------------------------------------------------------------
  */
 herr_t
-H5F_check_mounts(H5F_t *f)
+H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs)
 {
-    herr_t      ret_value=SUCCEED;       /* Return value */
+    herr_t      ret_value = SUCCEED;       /* Return value */
     
-    FUNC_ENTER_NOAPI(H5F_check_mounts, FAIL)
-
-    /* Only try to close files for files involved in a mounting hierarchy */
-    if(f->mtab.parent || f->mtab.nmounts) {
-        H5F_t *top = f;         /* Pointer to the top file in the hierarchy */
-
-        /* Find the top file in the mounting hierarchy */
-        while(top->mtab.parent) {
-            /* Get out early if we detect that this hierarchy won't close */
-            if(top->nopen_objs != top->mtab.nmounts || !top->closing)
-                HGOTO_DONE(SUCCEED)
-
-            /* Advance toward the top of the hierarchy */
-            top = top->mtab.parent;
-        } /* end while */
-
-        /* Check for closing the hierarchy */
-        if(H5F_check_mounts_recurse(top)) {
-            /* Unmount all child files */
-            if(H5F_close_mounts(top) < 0)
-                HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child file")
-
-            if(H5I_dec_ref(top->closing) < 0)
-                HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't decrement file closing ID")
-        } /* end if */
-    } /* end if */
+    FUNC_ENTER_NOAPI(H5F_mount_count_ids, FAIL)
+
+    /* Sanity check */
+    HDassert(f);
+    HDassert(nopen_files);
+    HDassert(nopen_objs);
+
+    /* Find the top file in the mounting hierarchy */
+    while(f->mtab.parent)
+        f = f->mtab.parent;
+
+    /* Count open IDs in the hierarchy */
+    H5F_mount_count_ids_recurse(f, nopen_files, nopen_objs);
 
 done:
     FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5F_check_mounts() */
+} /* end H5F_mount_count_ids() */
 
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 363c1e6..596103e 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -93,7 +93,7 @@ typedef struct H5F_file_t {
     haddr_t	freespace_addr;	/* Relative address of free-space info	*/
     haddr_t	driver_addr;	/* File driver information block address*/
     hbool_t     fam_to_sec2;    /* Is h5repart changing driver from family to sec2 */
-                                   
+
     unsigned	super_chksum;	/* Superblock checksum                  */
     unsigned	drvr_chksum;	/* Driver info block checksum           */
     H5AC_t      *cache;		/* The object cache			*/
@@ -144,13 +144,12 @@ typedef struct H5F_mtab_t {
  * indicate that the file is mounted on some other file).
  */
 struct H5F_t {
-    unsigned		nrefs;		/* Reference count		*/
     unsigned		intent;		/* The flags passed to H5F_open()*/
     char		*name;		/* Name used to open file	*/
     H5F_file_t		*shared;	/* The shared file info		*/
     unsigned		nopen_objs;	/* Number of open object headers*/
     hid_t               file_id;        /* ID of this file              */
-    hid_t		closing;	/* H5I_FILE_CLOSING ID or zero	*/
+    hbool_t             closing;        /* File is in the process of being closed */
     H5F_mtab_t		mtab;		/* File mount table		*/
 };
 
@@ -165,14 +164,14 @@ H5_DLL void H5F_encode_length_unusual(const H5F_t *f, uint8_t **p, uint8_t *l);
 #endif /* NOT_YET */
 
 /* General routines */
-H5_DLL herr_t H5F_close(H5F_t *f);
+H5_DLL herr_t H5F_try_close(H5F_t *f);
 H5_DLL haddr_t H5F_locate_signature(H5FD_t *file, hid_t dxpl_id);
 
 /* File mount related routines */
 H5_DLL herr_t H5F_mountpoint(struct H5G_entry_t *find/*in,out*/);
 H5_DLL herr_t H5F_close_mounts(H5F_t *f);
 H5_DLL int H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void *key);
-H5_DLL herr_t H5F_check_mounts(H5F_t *f);
+H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs);
 
 /* Superblock related routines */
 H5_DLL hsize_t H5F_init_superblock(const H5F_t *f, hid_t dxpl_id);
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 8466bf2..52b92dc 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -438,8 +438,8 @@ H5_DLL hid_t H5F_get_access_plist(H5F_t *f);
 H5_DLL unsigned H5F_get_intent(const H5F_t *f);
 H5_DLL herr_t H5F_get_fileno(const H5F_t *f, unsigned long *filenum);
 H5_DLL hid_t H5F_get_id(H5F_t *file);
-H5_DLL int H5F_get_obj_count(const H5F_t *f, unsigned types);
-H5_DLL int H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
+H5_DLL unsigned H5F_get_obj_count(const H5F_t *f, unsigned types);
+H5_DLL unsigned H5F_get_obj_ids(const H5F_t *f, unsigned types, int max_objs, hid_t *obj_id_list);
 H5_DLL haddr_t H5F_get_base_addr(const H5F_t *f);
 H5_DLL haddr_t H5F_get_eoa(const H5F_t *f);
 #ifdef H5_HAVE_PARALLEL
diff --git a/src/H5G.c b/src/H5G.c
index ec17d28..c2305c5 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -2091,7 +2091,8 @@ H5G_open(H5G_entry_t *ent, hid_t dxpl_id)
             HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects")
         }
 
-        grp->shared->fo_count =1;
+        /* Set open object count */
+        grp->shared->fo_count = 1;
     }
     else {
         if(NULL == (grp = H5FL_CALLOC(H5G_t)))
@@ -2101,7 +2102,10 @@ H5G_open(H5G_entry_t *ent, hid_t dxpl_id)
         if(H5G_ent_copy(&(grp->ent), ent, H5G_COPY_SHALLOW)<0)
             HGOTO_ERROR (H5E_SYM, H5E_CANTCOPY, NULL, "can't copy group entry")
 
-        grp->shared=shared_fo;
+        /* Point to shared group info */
+        grp->shared = shared_fo;
+
+        /* Increment shared reference count */
         shared_fo->fo_count++;
     }
 
@@ -2254,11 +2258,14 @@ H5G_close(H5G_t *grp)
             HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close");
         H5FL_FREE (H5G_shared_t, grp->shared);
     } else {
-        /* Check if this group was the last object holding open a mounted file
-         * hierarchy and close down the file hierarchy if so */
-        if(grp->shared->fo_count == 1)
-            if(H5F_check_mounts(grp->ent.file) < 0)
-                HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy"); 
+        /* If this group is a mount point and the mount point is the last open
+         * reference to the group, then attempt to close down the file hierarchy
+         */
+        if(grp->shared->mounted && grp->shared->fo_count == 1) {
+            /* Attempt to close down the file hierarchy */
+            if(H5F_try_close(grp->ent.file) < 0)
+                HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
+        } /* end if */
 
         if(H5G_free_ent_name(&(grp->ent))<0)
         {
@@ -2271,7 +2278,7 @@ H5G_close(H5G_t *grp)
 
 done:
     FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* end H5G_close() */
 
 
 /*-------------------------------------------------------------------------
@@ -2547,6 +2554,9 @@ H5G_loc (hid_t loc_id)
                 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry for root group");
 
             /* Patch up root group's symbol table entry to reflect this file */
+            /* (Since the root group info is only stored once for files which
+             *  share an underlying low-level file)
+             */
             /* (but only for non-mounted files) */
             if(!f->mtab.parent)
                 ret_value->file = f;
@@ -4121,8 +4131,68 @@ H5G_get_shared_count(H5G_t *grp)
     FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_get_shared_count);
 
     /* Check args */
-    assert(grp && grp->shared);
+    HDassert(grp && grp->shared);
 
     FUNC_LEAVE_NOAPI(grp->shared->fo_count);
 } /* end H5G_get_shared_count() */
 
+
+/*-------------------------------------------------------------------------
+ * Function:	H5G_mount
+ *
+ * Purpose:	Sets the 'mounted' flag for a group
+ *
+ * Return:	Non-negative on success/Negative on failure
+ *
+ * Programmer:	Quincey Koziol
+ *		Tuesday, July 19, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_mount(H5G_t *grp)
+{
+    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_mount);
+
+    /* Check args */
+    HDassert(grp && grp->shared);
+    HDassert(grp->shared->mounted == FALSE);
+
+    /* Set the 'mounted' flag */
+    grp->shared->mounted = TRUE;
+
+    FUNC_LEAVE_NOAPI(SUCCEED);
+} /* end H5G_mount() */
+
+
+/*-------------------------------------------------------------------------
+ * Function:	H5G_unmount
+ *
+ * Purpose:	Resets the 'mounted' flag for a group
+ *
+ * Return:	Non-negative on success/Negative on failure
+ *
+ * Programmer:	Quincey Koziol
+ *		Tuesday, July 19, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_unmount(H5G_t *grp)
+{
+    FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_unmount);
+
+    /* Check args */
+    HDassert(grp && grp->shared);
+    HDassert(grp->shared->mounted == TRUE);
+
+    /* Reset the 'mounted' flag */
+    grp->shared->mounted = FALSE;
+
+    FUNC_LEAVE_NOAPI(SUCCEED);
+} /* end H5G_unmount() */
+
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index e190ba0..36a18f9 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -47,10 +47,11 @@ typedef struct H5G_node_t {
 } H5G_node_t;
 
 /*
- * Reference count shared between all instances of an open group
+ * Shared information for all open group objects
  */
 struct H5G_shared_t {
     int fo_count;                   /* open file object count */
+    hbool_t mounted;                /* Group is mount point */
 };
 
 /*
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 34d6797..08ec9af 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -167,6 +167,8 @@ H5_DLL  herr_t H5G_replace_name(H5G_obj_t type, H5G_entry_t *loc,
         H5RS_str_t *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op);
 H5_DLL  herr_t H5G_free_grp_name(H5G_t *grp);
 H5_DLL herr_t H5G_get_shared_count(H5G_t *grp);
+H5_DLL herr_t H5G_mount(H5G_t *grp);
+H5_DLL herr_t H5G_unmount(H5G_t *grp);
 
 /*
  * These functions operate on symbol table nodes.
diff --git a/src/H5I.c b/src/H5I.c
index 98b3c86..6ae8ca8 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -125,7 +125,6 @@ H5FL_DEFINE_STATIC(H5I_id_info_t);
 /*--------------------- Local function prototypes ---------------------------*/
 static H5I_id_info_t *H5I_find_id(hid_t id);
 static hid_t H5I_get_file_id(hid_t obj_id);
-static int H5I_get_ref(hid_t id);
 #ifdef H5I_DEBUG_OUTPUT
 static herr_t H5I_debug(H5I_type_t type);
 #endif /* H5I_DEBUG_OUTPUT */
@@ -483,9 +482,6 @@ int
 H5I_nmembers(H5I_type_t type)
 {
     H5I_id_type_t	*type_ptr = NULL;
-    H5I_id_info_t	*cur=NULL;
-    int		n=0;
-    unsigned		i;
     int		ret_value;
 
     FUNC_ENTER_NOAPI(H5I_nmembers, FAIL);
@@ -495,12 +491,8 @@ H5I_nmembers(H5I_type_t type)
     if (NULL==(type_ptr=H5I_id_type_list_g[type]) || type_ptr->count<=0)
 	HGOTO_DONE(0);
 
-    for (i=0; i<type_ptr->hash_size; i++)
-	for (cur=type_ptr->id_list[i]; cur; cur=cur->next)
-	    n++;
-
     /* Set return value */
-    ret_value=n;
+    H5_ASSIGN_OVERFLOW(ret_value, type_ptr->ids, unsigned, int);
 
 done:
     FUNC_LEAVE_NOAPI(ret_value);
@@ -971,18 +963,14 @@ void *H5Iobject_verify(hid_t id, H5I_type_t id_type)
   FUNC_ENTER_API(H5Iobject_verify, NULL);
 
   if( H5I_IS_LIB_TYPE( id_type ) )
-  {
-    HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
-  }
+    HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
 
   if(id_type < 1 || id_type >= H5I_next_type)
-  {
-    HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "identifier has invalid type");
-  }
+    HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "identifier has invalid type")
 
   ret_value = H5I_object_verify(id, id_type);
 
-  done:
+done:
     FUNC_LEAVE_API(ret_value);
 }
 
@@ -1127,9 +1115,7 @@ void *H5Iremove_verify(hid_t id, H5I_type_t id_type)
     FUNC_ENTER_API(H5Iremove_verify, NULL);
 
 	if( H5I_IS_LIB_TYPE( id_type ) )
-	{
-		HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type");
-	}
+		HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type")
 
 	/* Remove the id */
 	ret_value = H5I_remove_verify(id, id_type);
@@ -1516,7 +1502,7 @@ done:
  *
  *-------------------------------------------------------------------------
  */
-static int
+int
 H5I_get_ref(hid_t id)
 {
     H5I_type_t		type;		/*type the object is in*/
@@ -1906,20 +1892,23 @@ H5I_search(H5I_type_t type, H5I_search_func_t func, void *key)
     if (type_ptr == NULL || type_ptr->count <= 0)
 	HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "invalid type");
 
-    /* Start at the beginning of the array */
-    for (i=0; i<type_ptr->hash_size; i++) {
-	id_ptr = type_ptr->id_list[i];
-	while (id_ptr) {
-            next_id= id_ptr->next;      /* Protect against ID being deleted in callback */
-	    if ((*func)(id_ptr->obj_ptr, id_ptr->id, key))
-		HGOTO_DONE(id_ptr->obj_ptr);	/*found the item*/
-	    id_ptr = next_id;
-	}
-    }
+    /* Only iterate through hash table if there are IDs in group */
+    if(type_ptr->ids > 0) {
+        /* Start at the beginning of the array */
+        for (i=0; i<type_ptr->hash_size; i++) {
+            id_ptr = type_ptr->id_list[i];
+            while (id_ptr) {
+                next_id= id_ptr->next;      /* Protect against ID being deleted in callback */
+                if ((*func)(id_ptr->obj_ptr, id_ptr->id, key))
+                    HGOTO_DONE(id_ptr->obj_ptr);	/*found the item*/
+                id_ptr = next_id;
+            } /* end while */
+        } /* end for */
+    } /* end if */
 
 done:
     FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* end H5I_search() */
 
 
 /*-------------------------------------------------------------------------
diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h
index 667af3d1..c91240a 100644
--- a/src/H5Iprivate.h
+++ b/src/H5Iprivate.h
@@ -60,6 +60,7 @@ H5_DLL H5I_type_t H5I_get_type(hid_t id);
 H5_DLL void *H5I_remove(hid_t id);
 H5_DLL void *H5I_remove_verify(hid_t id, H5I_type_t id_type);
 H5_DLL void *H5I_search(H5I_type_t type, H5I_search_func_t func, void *key);
+H5_DLL int H5I_get_ref(hid_t id);
 H5_DLL int H5I_inc_ref(hid_t id);
 H5_DLL int H5I_dec_ref(hid_t id);
 H5_DLL int H5I_inc_type_ref(H5I_type_t type);
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 78915a6..bda034c 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -36,7 +36,6 @@ typedef enum H5I_type_t {
     H5I_UNINIT		= (-2), /*uninitialized type			    */
     H5I_BADID		= (-1),	/*invalid Type				    */
     H5I_FILE		= 1,	/*type ID for File objects		    */
-    H5I_FILE_CLOSING,		/*files pending close due to open objhdrs   */
     H5I_GROUP,		        /*type ID for Group objects		    */
     H5I_DATATYPE,	        /*type ID for Datatype objects		    */
     H5I_DATASPACE,	        /*type ID for Dataspace objects		    */
diff --git a/src/H5O.c b/src/H5O.c
index 7abc16e..a15d9ac 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -412,7 +412,7 @@ H5O_close(H5G_entry_t *obj_ent)
 
 #ifdef H5O_DEBUG
     if (H5DEBUG(O)) {
-	if (obj_ent->file->closing && 1==obj_ent->file->shared->nrefs) {
+	if (obj_ent->file->file_id < 0 && 1==obj_ent->file->shared->nrefs) {
 	    HDfprintf(H5DEBUG(O), "< %a auto %lu remaining\n",
 		      obj_ent->header,
 		      (unsigned long)(obj_ent->file->nopen_objs));
@@ -423,28 +423,13 @@ H5O_close(H5G_entry_t *obj_ent)
 #endif
     
     /*
-     * If the file open-lock count has reached the number of open mount points
-     * (each of which has a group open in the file) and the file has a close
-     * pending then close the file and remove it from the H5I_FILE_CLOSING ID
-     * group.
+     * 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.
      */
-    /* Check for just mount points holding file open */
-    if(obj_ent->file->mtab.nmounts == obj_ent->file->nopen_objs && obj_ent->file->closing) {
-        unsigned u;             /* Local index variable */
-        hbool_t really_close;  /* Whether to delay the file close by going to a "closing" state */
-
-        /* Check for open groups on mount points */
-        really_close = TRUE;
-        for(u = 0; u < obj_ent->file->mtab.nmounts; u++) {
-            if(H5G_get_shared_count(obj_ent->file->mtab.child[u].group) > 1) {
-                really_close = FALSE;
-                break;
-            } /* end if */
-        } /* end for */
-
-        /* If we really want to close this file now */
-        if(really_close)
-            H5I_dec_ref(obj_ent->file->closing);
+    if(obj_ent->file->nopen_objs == obj_ent->file->mtab.nmounts) {
+        /* Attempt to close down the file hierarchy */
+        if(H5F_try_close(obj_ent->file) < 0)
+            HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
     } /* end if */
 
     /* Free the ID to name buffers */
@@ -452,7 +437,7 @@ H5O_close(H5G_entry_t *obj_ent)
 
 done:
     FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* end H5O_close() */
 
 
 /*-------------------------------------------------------------------------
@@ -1920,7 +1905,7 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
 	    HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found");
     } /* end if */
 
-    /* Check for creating new message */ 
+    /* Check for creating new message */
     if (overwrite < 0) {
         /* Create a new message */
         if((idx=H5O_new_mesg(ent->file,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id,&oh_flags))==UFAIL)
@@ -2265,7 +2250,6 @@ H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
     unsigned * oh_flags_ptr)
 {
     H5O_mesg_t         *idx_msg;        /* Pointer to message to modify */
-    
     herr_t      ret_value=SUCCEED;      /* Return value */
 
     FUNC_ENTER_NOAPI_NOINIT(H5O_write_mesg);
diff --git a/test/Makefile.am b/test/Makefile.am
index eb53695..6247d1a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -34,7 +34,7 @@ TEST_PROG=testhdf5 lheap ohdr stab gheap cache b+tree btree2 blocktrack sheap \
            dtypes dsets cmpd_dset extend external links unlink big mtime     \
            fillval mount flush1 flush2 enum \
            set_extent ttsafe stream_test \
-           getname vfd ntypes dangle dtransform filename reserved 
+           getname vfd ntypes dangle dtransform reserved 
 
 # List programs to be built when testing here. error_test and err_compat are
 # built at the same time as the other tests, but executed by testerror.sh.
diff --git a/test/Makefile.in b/test/Makefile.in
index 54ec422..ce95a9b 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -29,7 +29,7 @@
 #
 # HDF5 Library Test Makefile(.in)
 #
-SOURCES = $(libh5test_la_SOURCES) b+tree.c big.c bittests.c blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c filename.c fillval.c flush1.c flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+SOURCES = $(libh5test_la_SOURCES) b+tree.c big.c bittests.c blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c dt_arith.c dtransform.c dtypes.c enum.c err_compat.c error_test.c extend.c external.c fillval.c flush1.c flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -81,7 +81,7 @@ am__EXEEXT_1 = testhdf5$(EXEEXT) lheap$(EXEEXT) ohdr$(EXEEXT) \
 	flush2$(EXEEXT) enum$(EXEEXT) set_extent$(EXEEXT) \
 	ttsafe$(EXEEXT) stream_test$(EXEEXT) getname$(EXEEXT) \
 	vfd$(EXEEXT) ntypes$(EXEEXT) dangle$(EXEEXT) \
-	dtransform$(EXEEXT) filename$(EXEEXT) reserved$(EXEEXT)
+	dtransform$(EXEEXT) reserved$(EXEEXT)
 b_tree_SOURCES = b+tree.c
 b_tree_OBJECTS = b+tree.$(OBJEXT)
 b_tree_LDADD = $(LDADD)
@@ -150,10 +150,6 @@ external_SOURCES = external.c
 external_OBJECTS = external.$(OBJEXT)
 external_LDADD = $(LDADD)
 external_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
-filename_SOURCES = filename.c
-filename_OBJECTS = filename.$(OBJEXT)
-filename_LDADD = $(LDADD)
-filename_DEPENDENCIES = libh5test.la $(am__DEPENDENCIES_1)
 fillval_SOURCES = fillval.c
 fillval_OBJECTS = fillval.$(OBJEXT)
 fillval_LDADD = $(LDADD)
@@ -273,19 +269,19 @@ LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 SOURCES = $(libh5test_la_SOURCES) b+tree.c big.c bittests.c \
 	blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c \
 	dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
-	error_test.c extend.c external.c filename.c fillval.c flush1.c \
-	flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c \
-	links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c \
-	set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) \
-	testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+	error_test.c extend.c external.c fillval.c flush1.c flush2.c \
+	getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
+	mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c \
+	stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c \
+	$(ttsafe_SOURCES) unlink.c vfd.c
 DIST_SOURCES = $(libh5test_la_SOURCES) b+tree.c big.c bittests.c \
 	blocktrack.c btree2.c cache.c cmpd_dset.c dangle.c dsets.c \
 	dt_arith.c dtransform.c dtypes.c enum.c err_compat.c \
-	error_test.c extend.c external.c filename.c fillval.c flush1.c \
-	flush2.c getname.c gheap.c hyperslab.c istore.c lheap.c \
-	links.c mount.c mtime.c ntypes.c ohdr.c pool.c reserved.c \
-	set_extent.c sheap.c stab.c stream_test.c $(testhdf5_SOURCES) \
-	testmeta.c $(ttsafe_SOURCES) unlink.c vfd.c
+	error_test.c extend.c external.c fillval.c flush1.c flush2.c \
+	getname.c gheap.c hyperslab.c istore.c lheap.c links.c mount.c \
+	mtime.c ntypes.c ohdr.c pool.c reserved.c set_extent.c sheap.c \
+	stab.c stream_test.c $(testhdf5_SOURCES) testmeta.c \
+	$(ttsafe_SOURCES) unlink.c vfd.c
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -532,7 +528,7 @@ TEST_PROG = testhdf5 lheap ohdr stab gheap cache b+tree btree2 blocktrack sheap
            dtypes dsets cmpd_dset extend external links unlink big mtime     \
            fillval mount flush1 flush2 enum \
            set_extent ttsafe stream_test \
-           getname vfd ntypes dangle dtransform filename reserved 
+           getname vfd ntypes dangle dtransform reserved 
 
 
 # The libh5test.a library provides common support code for the tests.
@@ -677,9 +673,6 @@ extend$(EXEEXT): $(extend_OBJECTS) $(extend_DEPENDENCIES)
 external$(EXEEXT): $(external_OBJECTS) $(external_DEPENDENCIES) 
 	@rm -f external$(EXEEXT)
 	$(LINK) $(external_LDFLAGS) $(external_OBJECTS) $(external_LDADD) $(LIBS)
-filename$(EXEEXT): $(filename_OBJECTS) $(filename_DEPENDENCIES) 
-	@rm -f filename$(EXEEXT)
-	$(LINK) $(filename_LDFLAGS) $(filename_OBJECTS) $(filename_LDADD) $(LIBS)
 fillval$(EXEEXT): $(fillval_OBJECTS) $(fillval_DEPENDENCIES) 
 	@rm -f fillval$(EXEEXT)
 	$(LINK) $(fillval_LDFLAGS) $(fillval_OBJECTS) $(fillval_LDADD) $(LIBS)
@@ -776,7 +769,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error_test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extend.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/external.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filename.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fillval.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flush2.Po@am__quote@
diff --git a/test/filename.c b/test/filename.c
deleted file mode 100644
index b11e6c7..0000000
--- a/test/filename.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by the Board of Trustees of the University of Illinois.         *
- * All rights reserved.                                                      *
- *                                                                           *
- * This file is part of HDF5.  The full HDF5 copyright notice, including     *
- * terms governing use, modification, and redistribution, is contained in    *
- * the files COPYING and Copyright.html.  COPYING can be found at the root   *
- * of the source code distribution tree; Copyright.html can be found at the  *
- * root level of an installed copy of the electronic HDF5 document set and   *
- * is linked from the top-level documents page.  It can also be found at     *
- * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html.  If you do not have     *
- * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/*
- * Programmer:  Raymond Lu <slu@ncsa.uiuc.edu>
- *              June 29, 2004
- *
- * Purpose:     Tests the "H5Fget_name" functionality
- */
-
-#include "testhdf5.h"
-
-#define FILENAME "get_file_name"
-#define GROUPNAME "group"
-#define DSETNAME "dataset"
-#define ATTRNAME "attribute"
-#define DTYPENAME "compound"
-#define NAME_BUF_SIZE   64
-
-#define RANK 2
-#define NX 4
-#define NY 5
-
-/* Compound datatype */
-typedef struct s1_t {
-    unsigned int a;
-    float        b;
-} s1_t;
-
-/* Used to make certain a return name _is_ the file name */
-#define VERIFY_NAME(x, val, where) do {					      \
-    if (GetTestVerbosity()>=VERBO_HI) {				              \
-	print_func("   Call to routine: %15s at line %4d in %s had value "    \
-		   "%ld \n", (where), (int)__LINE__, __FILE__, (long)(x));    \
-    }									      \
-    if (strcmp(x, val)) {					              \
-	TestErrPrintf("*** UNEXPECTED VALUE from %s should be %s, but is %s at line %4d " \
-		   "in %s\n", where, val, x, (int)__LINE__, __FILE__);        \
-	H5Eprint_stack(H5E_DEFAULT, stdout);				      \
-    }									      \
-} while(0)
-
-int main( void )
-{
-    char    filename[NAME_BUF_SIZE];
-    hid_t   fapl;
-    hid_t   file_id;
-    hid_t   group_id;
-    hid_t   dataset_id;
-    hid_t   space_id;  
-    hid_t   type_id;
-    hid_t   attr_id;
-    hsize_t dims[RANK] = {NX, NY};
-    char    name[NAME_BUF_SIZE];
-    ssize_t name_len;
-    herr_t  ret;
-
-    TESTING("H5Fget_name");
-         
-    /* Reset the library and get the file access property list */
-    h5_reset();
-    fapl = h5_fileaccess();
-
-    /* Initialize the file names */
-    h5_fixname(FILENAME, fapl, filename, sizeof filename);
-     
-    /* Create a new file_id using default properties. */
-    file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl );
-    CHECK(file_id, FAIL, "H5Fcreate"); 
-
-    /* Get and verify file name */
-    name_len = H5Fget_name(file_id, name, NAME_BUF_SIZE);
-    CHECK(name_len, FAIL, "H5Fget_name");
-    VERIFY_NAME(name, filename, "H5Fget_name");
-
-    /* Create a group in the root group */
-    group_id = H5Gcreate(file_id, GROUPNAME, 0);
-    CHECK(group_id, FAIL, "H5Gcreate"); 
-
-    /* Get and verify file name */
-    name_len = H5Fget_name(group_id, name, NAME_BUF_SIZE);
-    CHECK(name_len, FAIL, "H5Fget_name");
-    VERIFY_NAME(name, filename, "H5Fget_name");
-
-    /* Create the data space  */
-    space_id = H5Screate_simple(RANK, dims, NULL);
-    CHECK(space_id, FAIL, "H5Screate_simple"); 
-
-    /* Try get file name from data space.  Supposed to fail because 
-     * it's illegal operation. */
-    H5E_BEGIN_TRY {
-        name_len = H5Fget_name(space_id, name, NAME_BUF_SIZE);
-    } H5E_END_TRY;
-    VERIFY(name_len, FAIL, "H5Fget_name");
-
-    /* Create a new dataset */
-    dataset_id = H5Dcreate(file_id, DSETNAME, H5T_NATIVE_INT, space_id, H5P_DEFAULT);
-    CHECK(dataset_id, FAIL, "H5Dcreate"); 
-
-    /* Get and verify file name */
-    name_len = H5Fget_name(dataset_id, name, NAME_BUF_SIZE);
-    CHECK(name_len, FAIL, "H5Fget_name");
-    VERIFY_NAME(name, filename, "H5Fget_name");
-
-    /* Create an attribute for the dataset */
-    attr_id = H5Acreate(dataset_id,ATTRNAME,H5T_NATIVE_INT,space_id,H5P_DEFAULT);
-    CHECK(attr_id, FAIL, "H5Acreate");
-
-    /* Get and verify file name */
-    name_len = H5Fget_name(attr_id, name, NAME_BUF_SIZE);
-    CHECK(name_len, FAIL, "H5Fget_name");
-    VERIFY_NAME(name, filename, "H5Fget_name");
-
-    /* Create a compound datatype */
-    type_id = H5Tcreate(H5T_COMPOUND, sizeof(s1_t));
-    CHECK(type_id, FAIL, "H5Tcreate"); 
-
-    /* Insert fields */
-    ret = H5Tinsert (type_id, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT);
-    CHECK(ret, FAIL, "H5Tinsert"); 
-
-    ret = H5Tinsert (type_id, "b", HOFFSET(s1_t,b), H5T_NATIVE_FLOAT);
-    CHECK(ret, FAIL, "H5Tinsert"); 
-  
-    /* Save it on file */
-    ret = H5Tcommit(file_id, DTYPENAME, type_id);
-    CHECK(ret, FAIL, "H5Tcommit"); 
-
-    /* Get and verify file name */
-    name_len = H5Fget_name(type_id, name, NAME_BUF_SIZE);
-    CHECK(name_len, FAIL, "H5Fget_name");
-    VERIFY_NAME(name, filename, "H5Fget_name");
-
-    H5Tclose(type_id);
-    H5Aclose(attr_id);
-    H5Dclose(dataset_id);
-    H5Sclose(space_id);
-    H5Gclose(group_id);
-    H5Fclose(file_id);
-
-    PASSED();
-    return 0;
-}
diff --git a/test/mount.c b/test/mount.c
index dd798a6..4813fa0 100644
--- a/test/mount.c
+++ b/test/mount.c
@@ -124,15 +124,21 @@ test_basic(hid_t fapl)
     h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
     h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
 
-    if ((file1=H5Fopen(filename1, H5F_ACC_RDONLY, fapl))<0 ||
-	(file2=H5Fopen(filename2, H5F_ACC_RDONLY, fapl))<0)
-	goto error;
-    if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error;
-    if ((grp=H5Gopen(file1, "/mnt1/file2"))<0) goto error;
-    if (H5Gclose(grp)<0) goto error;
-    if (H5Funmount(file1, "/mnt1")<0) goto error;
-    if (H5Fclose(file1)<0) goto error;
-    if (H5Fclose(file2)<0) goto error;
+    if ((file1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0 ||
+            (file2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0)
+        TEST_ERROR
+    if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT) < 0)
+        TEST_ERROR
+    if ((grp = H5Gopen(file1, "/mnt1/file2")) < 0)
+        TEST_ERROR
+    if (H5Gclose(grp) < 0)
+        TEST_ERROR
+    if (H5Funmount(file1, "/mnt1") < 0)
+        TEST_ERROR
+    if (H5Fclose(file1) < 0)
+        TEST_ERROR
+    if (H5Fclose(file2) < 0)
+        TEST_ERROR
 
     PASSED();
     return 0;
@@ -972,7 +978,6 @@ test_close(hid_t fapl)
 {
     hid_t	file1=-1, file2=-1;
     char	filename1[1024], filename2[1024];
-    herr_t	status;
     
     TESTING("file handle close");
     h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
@@ -985,21 +990,21 @@ test_close(hid_t fapl)
     if (H5Fmount(file1, "/mnt1", file2, H5P_DEFAULT)<0) goto error;
 
     /*
-     * Close file1 unmounting it from the virtual file.  Objects in file2 are
-     * still accessible through the file2 handle, but nothing in file1 is
-     * accessible.
+     * Close file1 unmounting it from the virtual file.  Objects in file1 are
+     * still accessible through the file2 handle.
      */
     if (H5Fclose(file1)<0) goto error;
-    H5E_BEGIN_TRY {
-	status = H5Gget_objinfo(file2, "/mnt1", TRUE, NULL);
-    } H5E_END_TRY;
-    if (status>=0) {
+    if(H5Gget_objinfo(file2, "/mnt1", TRUE, NULL) < 0) {
 	H5_FAILED();
-	puts("    File1 contents are still accessible!");
+	puts("    File1 contents are not accessible!");
 	goto error;
     }
     if (H5Fclose(file2)<0) goto error;
 
+    /* Check that all file IDs have been closed */
+    if(H5I_nmembers(H5I_FILE) != 0)
+        TEST_ERROR
+
     /* Build the virtual file again */
     if ((file1=H5Fopen(filename1, H5F_ACC_RDWR, fapl))<0 ||
 	(file2=H5Fopen(filename2, H5F_ACC_RDWR, fapl))<0)
@@ -1013,6 +1018,10 @@ test_close(hid_t fapl)
     if (H5Gget_objinfo(file1, "/mnt1/file2", TRUE, NULL)<0) goto error;
     if (H5Fclose(file1)<0) goto error;
     
+    /* Check that all file IDs have been closed */
+    if(H5I_nmembers(H5I_FILE) != 0)
+        TEST_ERROR
+
     /* Shut down */
     PASSED();
     return 0;
@@ -1657,10 +1666,6 @@ test_missing_unmount(hid_t fapl)
     if(H5I_nmembers(H5I_FILE) != 0)
         TEST_ERROR
 
-    /* Check that all "file closing" IDs have been closed */
-    if(H5I_nmembers(H5I_FILE_CLOSING) != 0)
-        TEST_ERROR
-
     PASSED();
     return 0;
 
@@ -1795,10 +1800,6 @@ test_hold_open_file(hid_t fapl)
     if(H5I_nmembers(H5I_FILE) != 0)
         TEST_ERROR
 
-    /* Check that all "file closing" IDs have been closed */
-    if(H5I_nmembers(H5I_FILE_CLOSING) != 0)
-        TEST_ERROR
-
     PASSED();
     return 0;
 
@@ -1835,7 +1836,7 @@ static int
 test_hold_open_group(hid_t fapl)
 {
     hid_t fid1 = -1, fid2 = -1;           	/* File IDs */
-    hid_t gidA = -1, gidM = -1, gidAM = -1, gidAM2 = -1;    	/* Group IDs */
+    hid_t gid = -1, gidA = -1, gidM = -1, gidAM = -1, gidAM2 = -1;    	/* Group IDs */
     char	filename1[1024],
 		filename2[1024]; 	/* Name of files to mount */
     
@@ -1916,21 +1917,42 @@ test_hold_open_group(hid_t fapl)
     if((gidAM2 = H5Gopen(fid1, "/A/M")) < 0)
         TEST_ERROR
 
+    /* Close file #1 */
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+    /* Get ID of file #2 */
+    if((fid2 = H5Iget_file_id(gidAM2)) < 0)
+        TEST_ERROR
+
     /* Close group in mounted file */
     if(H5Gclose(gidAM2) < 0)
         TEST_ERROR
 
-    /* Close file #1 */
-    /* (should unmount file #2 also) */
-    if(H5Fclose(fid1) < 0)
+    /* Attempt to open group in mounted file */
+    /* (Should work because file is still mounted) */
+    if((gidAM2 = H5Gopen(fid2, "/A/M")) < 0)
         TEST_ERROR
 
-    /* Check that all file IDs have been closed */
-    if(H5I_nmembers(H5I_FILE) != 0)
+    /* Close file #2 */
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+    /* Attempt to open group in parent file */
+    /* (Should work because files should be mounted together) */
+    if((gid = H5Gopen(gidAM2, "/")) < 0)
         TEST_ERROR
 
-    /* Check that all "file closing" IDs have been closed */
-    if(H5I_nmembers(H5I_FILE_CLOSING) != 0)
+    /* Close group in mounted file */
+    if(H5Gclose(gidAM2) < 0)
+        TEST_ERROR
+
+    /* Close group in parent file */
+    if(H5Gclose(gid) < 0)
+        TEST_ERROR
+
+    /* Check that all file IDs have been closed */
+    if(H5I_nmembers(H5I_FILE) != 0)
         TEST_ERROR
 
     PASSED();
@@ -1942,6 +1964,7 @@ error:
 	H5Gclose(gidAM);
 	H5Gclose(gidAM2);
 	H5Gclose(gidA);
+	H5Gclose(gid);
         H5Fclose(fid2);
 	H5Fclose(fid1);
     } H5E_END_TRY;
@@ -1950,6 +1973,630 @@ error:
     
 
 /*-------------------------------------------------------------------------
+ * Function:	test_fcdegree_same
+ *
+ * Purpose:	Test that the library will only allow files with same file
+ *              close degree to be mounted together.
+ *
+ * Return:	Success:	0
+ *
+ *		Failure:	number of errors
+ *
+ * Programmer:	Quincey Koziol
+ *              Tuesday, July 19, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_fcdegree_same(hid_t fapl)
+{
+    hid_t fid1 = -1, fid2 = -1;           	/* File IDs */
+    hid_t gidA = -1, gidM = -1, gidAM = -1;    	/* Group IDs */
+    hid_t fapl_id = -1;                         /* FAPL IDs */
+    herr_t ret;                                 /* Generic return value */
+    char	filename1[1024],
+		filename2[1024]; 	/* Name of files to mount */
+    
+    TESTING("file close degrees must be same");
+
+    h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
+    h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
+    
+    /* Create file #1 */
+    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
+        TEST_ERROR
+
+    if(H5Gclose(gidA) < 0)
+        TEST_ERROR
+
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+
+    /* Create file #2 */
+    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidM = H5Gcreate(fid2, "M", (size_t)0)) < 0)
+        TEST_ERROR
+
+    if(H5Gclose(gidM) < 0)
+        TEST_ERROR
+
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+
+    /* Re-open files and mount file #2 in file #1 */
+    if((fid1 = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidA = H5Gopen(fid1, "A")) < 0)
+        TEST_ERROR
+
+    /* Create FAPL & set file close degree for file #2 to be different */
+    if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+        TEST_ERROR
+
+    /* Set file close mode to H5F_CLOSE_STRONG */
+    if(H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG) < 0)
+        TEST_ERROR
+
+    if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl_id)) < 0)
+        TEST_ERROR
+
+    /* Try mounting file with different file close degree (should fail) */
+    H5E_BEGIN_TRY {
+        ret = H5Fmount(gidA, ".", fid2, H5P_DEFAULT);
+    } H5E_END_TRY;
+    if(ret >= 0)
+        TEST_ERROR
+
+    /* Set file close mode to H5F_CLOSE_WEAK */
+    if(H5Pset_fclose_degree(fapl_id, H5F_CLOSE_WEAK) < 0)
+        TEST_ERROR
+
+    /* Close file #2 & re-open with same file close degree as file #1 */
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+    if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl_id)) < 0)
+        TEST_ERROR
+
+    /* Try mounting files again (should work now) */
+    if(H5Fmount(gidA, ".", fid2, H5P_DEFAULT) < 0)
+        TEST_ERROR
+
+    /* Verify opening group in mounted file */
+    if((gidAM = H5Gopen(fid1, "A/M")) < 0)
+        TEST_ERROR
+
+    /* Close group in mounted file */
+    if(H5Gclose(gidAM) < 0)
+        TEST_ERROR
+
+    /* Close group in parent file */
+    if(H5Gclose(gidA) < 0)
+        TEST_ERROR
+
+    /* Close file #2 */
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+    /* Close file #1 */
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+    /* Close FAPL ID */
+    if(H5Pclose(fapl_id) < 0)
+        TEST_ERROR
+
+    /* Check that all file IDs have been closed */
+    if(H5I_nmembers(H5I_FILE) != 0)
+        TEST_ERROR
+
+    PASSED();
+    return 0;
+
+error:
+    H5E_BEGIN_TRY {
+        H5Pclose(fapl_id);
+	H5Gclose(gidM);
+	H5Gclose(gidAM);
+	H5Gclose(gidA);
+        H5Fclose(fid2);
+	H5Fclose(fid1);
+    } H5E_END_TRY;
+    return 1;
+} /* end test_fcdegree_same() */
+    
+
+/*-------------------------------------------------------------------------
+ * Function:	test_fcdegree_semi
+ *
+ * Purpose:	Test that the library perform correct actions when using
+ *              "semi" file close degree on mounted files
+ *
+ * Return:	Success:	0
+ *
+ *		Failure:	number of errors
+ *
+ * Programmer:	Quincey Koziol
+ *              Tuesday, July 19, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_fcdegree_semi(hid_t fapl)
+{
+    hid_t fid1 = -1, fid2 = -1;           	/* File IDs */
+    hid_t gidA = -1, gidM = -1, gidAM = -1;    	/* Group IDs */
+    hid_t fapl_id = -1;                         /* FAPL IDs */
+    herr_t ret;                                 /* Generic return value */
+    char	filename1[1024],
+		filename2[1024]; 	/* Name of files to mount */
+    
+    TESTING("'semi' file close degree");
+
+    h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
+    h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
+    
+    /* Create file #1 */
+    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
+        TEST_ERROR
+
+    if(H5Gclose(gidA) < 0)
+        TEST_ERROR
+
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+
+    /* Create file #2 */
+    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidM = H5Gcreate(fid2, "M", (size_t)0)) < 0)
+        TEST_ERROR
+
+    if(H5Gclose(gidM) < 0)
+        TEST_ERROR
+
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+
+    /* Create FAPL & set file close degree to be "semi" */
+    if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+        TEST_ERROR
+
+    /* Set file close mode to H5F_CLOSE_SEMI */
+    if(H5Pset_fclose_degree(fapl_id, H5F_CLOSE_SEMI) < 0)
+        TEST_ERROR
+
+    /* Re-open files and mount file #2 in file #1 */
+    if((fid1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl_id)) < 0)
+        TEST_ERROR
+
+    if((gidA = H5Gopen(fid1, "A")) < 0)
+        TEST_ERROR
+
+    if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl_id)) < 0)
+        TEST_ERROR
+
+    /* Mount files together */
+    if(H5Fmount(gidA, ".", fid2, H5P_DEFAULT) < 0)
+        TEST_ERROR
+
+    /* Verify opening group in mounted file */
+    if((gidAM = H5Gopen(fid1, "A/M")) < 0)
+        TEST_ERROR
+
+    /* Close file #1 (should succeed, since file #2 is open still) */
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+    /* Try closing file #2 (should fail, since there are still objects open) */
+    H5E_BEGIN_TRY {
+        ret = H5Fclose(fid2);
+    } H5E_END_TRY;
+    if(ret >= 0)
+        TEST_ERROR
+
+    /* Close group in parent file */
+    if(H5Gclose(gidA) < 0)
+        TEST_ERROR
+
+    /* Try closing file #2 (should still fail, since there are still objects open in child file) */
+    H5E_BEGIN_TRY {
+        ret = H5Fclose(fid2);
+    } H5E_END_TRY;
+    if(ret >= 0)
+        TEST_ERROR
+
+    /* Close group in mounted file */
+    if(H5Gclose(gidAM) < 0)
+        TEST_ERROR
+
+    /* Close file #2 (should succeed now) */
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+    /* Close FAPL ID */
+    if(H5Pclose(fapl_id) < 0)
+        TEST_ERROR
+
+    /* Check that all file IDs have been closed */
+    if(H5I_nmembers(H5I_FILE) != 0)
+        TEST_ERROR
+
+    PASSED();
+    return 0;
+
+error:
+    H5E_BEGIN_TRY {
+        H5Pclose(fapl_id);
+	H5Gclose(gidM);
+	H5Gclose(gidAM);
+	H5Gclose(gidA);
+        H5Fclose(fid2);
+	H5Fclose(fid1);
+    } H5E_END_TRY;
+    return 1;
+} /* end test_fcdegree_semi() */
+    
+
+/*-------------------------------------------------------------------------
+ * Function:	test_fcdegree_strong
+ *
+ * Purpose:	Test that the library perform correct actions when using
+ *              "strong" file close degree on mounted files
+ *
+ * Return:	Success:	0
+ *
+ *		Failure:	number of errors
+ *
+ * Programmer:	Quincey Koziol
+ *              Tuesday, July 19, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_fcdegree_strong(hid_t fapl)
+{
+    hid_t fid1 = -1, fid2 = -1;           	/* File IDs */
+    hid_t gidA = -1, gidM = -1, gidAM = -1;    	/* Group IDs */
+    hid_t fapl_id = -1;                         /* FAPL IDs */
+    herr_t ret;                                 /* Generic return value */
+    char	filename1[1024],
+		filename2[1024]; 	/* Name of files to mount */
+    
+    TESTING("'strong' file close degree");
+
+    h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
+    h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
+    
+    /* Create file #1 */
+    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
+        TEST_ERROR
+
+    if(H5Gclose(gidA) < 0)
+        TEST_ERROR
+
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+
+    /* Create file #2 */
+    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidM = H5Gcreate(fid2, "M", (size_t)0)) < 0)
+        TEST_ERROR
+
+    if(H5Gclose(gidM) < 0)
+        TEST_ERROR
+
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+
+    /* Create FAPL & set file close degree to be "strong" */
+    if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+        TEST_ERROR
+
+    /* Set file close mode to H5F_CLOSE_STRONG */
+    if(H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG) < 0)
+        TEST_ERROR
+
+    /* Re-open files and mount file #2 in file #1 */
+    if((fid1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl_id)) < 0)
+        TEST_ERROR
+
+    if((gidA = H5Gopen(fid1, "A")) < 0)
+        TEST_ERROR
+
+    if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl_id)) < 0)
+        TEST_ERROR
+
+    /* Mount files together */
+    if(H5Fmount(gidA, ".", fid2, H5P_DEFAULT) < 0)
+        TEST_ERROR
+
+    /* Open group in mounted file */
+    if((gidAM = H5Gopen(fid1, "A/M")) < 0)
+        TEST_ERROR
+
+    /* Close file #1 */
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+    /* Check that objects are still open */
+    if (H5Gget_objinfo(gidA, ".", TRUE, NULL) < 0)
+        TEST_ERROR
+    if (H5Gget_objinfo(gidAM, ".", TRUE, NULL) < 0)
+        TEST_ERROR
+
+    /* Close file #2 (should close open objects also) */
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+    /* Check that objects are closed */
+    H5E_BEGIN_TRY {
+        ret = H5Gget_objinfo(gidA, ".", TRUE, NULL);
+    } H5E_END_TRY;
+    if(ret >= 0)
+        TEST_ERROR
+    H5E_BEGIN_TRY {
+        ret = H5Gget_objinfo(gidAM, ".", TRUE, NULL);
+    } H5E_END_TRY;
+    if(ret >= 0)
+        TEST_ERROR
+
+    /* Close FAPL ID */
+    if(H5Pclose(fapl_id) < 0)
+        TEST_ERROR
+
+    /* Check that all file IDs have been closed */
+    if(H5I_nmembers(H5I_FILE) != 0)
+        TEST_ERROR
+
+    PASSED();
+    return 0;
+
+error:
+    H5E_BEGIN_TRY {
+        H5Pclose(fapl_id);
+	H5Gclose(gidM);
+	H5Gclose(gidAM);
+	H5Gclose(gidA);
+        H5Fclose(fid2);
+	H5Fclose(fid1);
+    } H5E_END_TRY;
+    return 1;
+} /* end test_fcdegree_strong() */
+    
+
+/*-------------------------------------------------------------------------
+ * Function:	test_acc_perm
+ *
+ * Purpose:	Test that the library correctly segregates operations in
+ *              parts of mounted file hierarchy with files that have different
+ *              R/W access permissions.
+ *
+ *
+ * Return:	Success:	0
+ *
+ *		Failure:	number of errors
+ *
+ * Programmer:	Quincey Koziol
+ *              Tuesday, July 19, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_acc_perm(hid_t fapl)
+{
+    hid_t fid1 = -1, fid2 = -1, fid3 = -1;           	/* File IDs */
+    hid_t gidA = -1, gidB = -1, gidC = -1, gidM = -1, gidAM = -1, gidAMZ = -1;    	/* Group IDs */
+    hid_t bad_id = -1;                          /* Bad ID from object create */
+    char    name[NAME_BUF_SIZE];        /* Buffer for filename retrieved */
+    ssize_t name_len;                   /* Filename length */
+    char	filename1[1024],
+		filename2[1024],
+		filename3[1024]; 	/* Name of files to mount */
+    
+    TESTING("access permissions");
+
+    h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
+    h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
+    h5_fixname(FILENAME[2], fapl, filename3, sizeof filename3);
+    
+    /* Create file #1 */
+    if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
+        TEST_ERROR
+
+    if(H5Gclose(gidA) < 0)
+        TEST_ERROR
+
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+
+    /* Create file #2 */
+    if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidM = H5Gcreate(fid2, "M", (size_t)0)) < 0)
+        TEST_ERROR
+
+    if(H5Gclose(gidM) < 0)
+        TEST_ERROR
+
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+
+    /* Re-open files and mount file #2 in file #1 */
+    if((fid1 = H5Fopen(filename1, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    if((gidA = H5Gopen(fid1, "A")) < 0)
+        TEST_ERROR
+
+    /* Get and verify file name */
+    if((name_len = H5Fget_name(gidA, name, NAME_BUF_SIZE)) < 0)
+        TEST_ERROR
+    if(HDstrcmp(name, filename1) != 0)
+        TEST_ERROR
+
+    if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    /* Get and verify file name */
+    if((name_len = H5Fget_name(fid2, name, NAME_BUF_SIZE)) < 0)
+        TEST_ERROR
+    if(HDstrcmp(name, filename2) != 0)
+        TEST_ERROR
+
+    /* Mount files together */
+    if(H5Fmount(gidA, ".", fid2, H5P_DEFAULT) < 0)
+        TEST_ERROR
+
+    /* Get and verify file name */
+    if((name_len = H5Fget_name(fid2, name, NAME_BUF_SIZE)) < 0)
+        TEST_ERROR
+    if(HDstrcmp(name, filename2) != 0)
+        TEST_ERROR
+
+    /* Open group in mounted file */
+    if((gidAM = H5Gopen(fid1, "A/M")) < 0)
+        TEST_ERROR
+
+    /* Get and verify file name */
+    if((name_len = H5Fget_name(gidAM, name, NAME_BUF_SIZE)) < 0)
+        TEST_ERROR
+    if(HDstrcmp(name, filename2) != 0)
+        TEST_ERROR
+
+    /* Attempt to create objects in read only file (should fail) */
+    H5E_BEGIN_TRY {
+        bad_id = H5Gcreate(gidAM, "Z", (size_t)0);
+    } H5E_END_TRY;
+    if(bad_id >= 0)
+        TEST_ERROR
+    H5E_BEGIN_TRY {
+        bad_id = H5Gcreate(fid1, "/A/L", (size_t)0);
+    } H5E_END_TRY;
+    if(bad_id >= 0)
+        TEST_ERROR
+
+    /* Attempt to create objects in read/write file (should succeed) */
+    if((gidB = H5Gcreate(fid2, "/B", (size_t)0)) < 0)
+        TEST_ERROR
+    if(H5Gclose(gidB) < 0)
+        TEST_ERROR
+
+    /* (Note that this object should get created in the "hidden" group for "A" in parent file) */
+    if((gidC = H5Gcreate(gidA, "C", (size_t)0)) < 0)
+        TEST_ERROR
+    if(H5Gclose(gidC) < 0)
+        TEST_ERROR
+
+    /* Create file #3 (it will have R/W permissions) */
+    if((fid3 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+        TEST_ERROR
+
+    /* Mount file #3 on file #2 */
+    if(H5Fmount(gidAM, ".", fid3, H5P_DEFAULT) < 0)
+        TEST_ERROR
+
+    /* Attempt to create objects in read/write file (should succeed) */
+    if((gidAMZ = H5Gcreate(fid1, "/A/M/Z", (size_t)0)) < 0)
+        TEST_ERROR
+
+    /* Get and verify file name */
+    if((name_len = H5Fget_name(gidAMZ, name, NAME_BUF_SIZE)) < 0)
+        TEST_ERROR
+    if(HDstrcmp(name, filename3) != 0)
+        TEST_ERROR
+
+    /* Close object in file #3 */
+    if(H5Gclose(gidAMZ) < 0)
+        TEST_ERROR
+
+
+    /* Attempt to create objects in read only file again (should fail) */
+    H5E_BEGIN_TRY {
+        bad_id = H5Gcreate(fid1, "/A/L", (size_t)0);
+    } H5E_END_TRY;
+    if(bad_id >= 0)
+        TEST_ERROR
+
+    /* Close group in mounted file */
+    if(H5Gclose(gidAM) < 0)
+        TEST_ERROR
+
+    /* Close group in parent file */
+    if(H5Gclose(gidA) < 0)
+        TEST_ERROR
+
+    /* Close file #3 */
+    if(H5Fclose(fid3) < 0)
+        TEST_ERROR
+
+    /* Close file #2 */
+    if(H5Fclose(fid2) < 0)
+        TEST_ERROR
+
+    /* Close file #1 */
+    if(H5Fclose(fid1) < 0)
+        TEST_ERROR
+
+
+    /* Check that all file IDs have been closed */
+    if(H5I_nmembers(H5I_FILE) != 0)
+        TEST_ERROR
+
+    PASSED();
+    return 0;
+
+error:
+    H5E_BEGIN_TRY {
+	H5Gclose(gidM);
+	H5Gclose(gidAMZ);
+	H5Gclose(gidAM);
+	H5Gclose(gidC);
+	H5Gclose(gidB);
+	H5Gclose(gidA);
+        H5Fclose(fid3);
+        H5Fclose(fid2);
+	H5Fclose(fid1);
+    } H5E_END_TRY;
+    return 1;
+} /* end test_acc_perm() */
+    
+
+/*-------------------------------------------------------------------------
  * Function:	main
  *
  * Purpose:	Test file mounting
@@ -1993,6 +2640,10 @@ main(void)
     nerrors += test_missing_unmount(fapl);
     nerrors += test_hold_open_file(fapl);
     nerrors += test_hold_open_group(fapl);
+    nerrors += test_fcdegree_same(fapl);
+    nerrors += test_fcdegree_semi(fapl);
+    nerrors += test_fcdegree_strong(fapl);
+    nerrors += test_acc_perm(fapl);
     
     if (nerrors) goto error;
     puts("All mount tests passed.");
diff --git a/test/testhdf5.h b/test/testhdf5.h
index 7043950..2274b78 100644
--- a/test/testhdf5.h
+++ b/test/testhdf5.h
@@ -80,6 +80,19 @@
     }									      \
 } while(0)
 
+/* Used to make certain a string return value _is_ a value */
+#define VERIFY_STR(x, val, where) do {					      \
+    if (GetTestVerbosity()>=VERBO_HI) {				              \
+	print_func("   Call to routine: %15s at line %4d in %s had value "    \
+		   "%s \n", (where), (int)__LINE__, __FILE__, x);    \
+    }									      \
+    if (HDstrcmp(x, val)) {					              \
+	TestErrPrintf("*** UNEXPECTED VALUE from %s should be %s, but is %s at line %4d " \
+		   "in %s\n", where, val, x, (int)__LINE__, __FILE__);        \
+	H5Eprint_stack(H5E_DEFAULT, stdout);				      \
+    }									      \
+} while(0)
+
 /* Used to document process through a test and to check for errors */
 #define RESULT(ret,func) do {						      \
     if (GetTestVerbosity()>VERBO_MED) {					      \
diff --git a/test/tfile.c b/test/tfile.c
index 0e1e7ec..05a0765 100644
--- a/test/tfile.c
+++ b/test/tfile.c
@@ -69,6 +69,15 @@
 #define DSET1   "Dataset1"
 #define DSET2   "/Group1/Dataset2"
 
+#define TESTA_GROUPNAME "group"
+#define TESTA_DSETNAME "dataset"
+#define TESTA_ATTRNAME "attribute"
+#define TESTA_DTYPENAME "compound"
+#define TESTA_NAME_BUF_SIZE     64
+#define TESTA_RANK 2
+#define TESTA_NX 4
+#define TESTA_NY 5
+
 static void
 create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *);
 static void
@@ -1447,64 +1456,181 @@ test_file_open_overlap(void)
 
     /* Create file */
     fid1 = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
-    assert(fid1 > 0);
+    CHECK(fid1, FAIL, "H5Fcreate");
 
     /* Open file also */
     fid2 = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
-    assert(fid2 > 0);
+    CHECK(fid2, FAIL, "H5Fopen");
 
     /* Create a group in file */
     gid = H5Gcreate(fid1, GROUP1, (size_t)0);
-    assert(gid > 0);
+    CHECK(gid, FAIL, "H5Gcreate");
 
     /* Create dataspace for dataset */
     sid = H5Screate(H5S_SCALAR);
-    assert(sid > 0);
+    CHECK(sid, FAIL, "H5Screate");
 
     /* Create dataset in group w/first file ID */
     did1 = H5Dcreate(gid, DSET1, H5T_NATIVE_INT, sid, H5P_DEFAULT);
-    assert(did1 > 0);
+    CHECK(did1, FAIL, "H5Dcreate");
 
     /* Check number of objects opened in first file */
     nobjs = H5Fget_obj_count(fid1, H5F_OBJ_LOCAL|H5F_OBJ_ALL);
-    assert(nobjs == 3);         /* 3 == file, dataset & group */
+    VERIFY(nobjs, 3, "H5Fget_obj_count");       /* 3 == file, dataset & group */
 
     /* Close dataset */
     ret = H5Dclose(did1);
-    assert(ret >= 0);
+    CHECK(ret, FAIL, "H5Dclose");
 
     /* Close group */
     ret = H5Gclose(gid);
-    assert(ret >= 0);
+    CHECK(ret, FAIL, "H5Gclose");
 
     /* Close first file ID */
     ret = H5Fclose(fid1);
-    assert(ret >= 0);
+    CHECK(ret, FAIL, "H5Fclose");
 
 
     /* Create dataset with second file ID */
     did2 = H5Dcreate(fid2, DSET2, H5T_NATIVE_INT, sid, H5P_DEFAULT);
-    assert(did2 > 0);
+    CHECK(did2, FAIL, "H5Dcreate");
 
     /* Check number of objects opened in first file */
     nobjs = H5Fget_obj_count(fid2, H5F_OBJ_ALL);
-    assert(nobjs == 2);         /* 2 == file & dataset */
+    VERIFY(nobjs, 2, "H5Fget_obj_count");       /* 3 == file & dataset */
 
     /* Close dataspace */
     ret = H5Sclose(sid);
-    assert(ret >= 0);
+    CHECK(ret, FAIL, "H5Sclose");
 
     /* Close second dataset */
     ret = H5Dclose(did2);
-    assert(ret >= 0);
+    CHECK(ret, FAIL, "H5Dclose");
 
     /* Close second file */
     ret = H5Fclose(fid2);
-    assert(ret >= 0);
+    CHECK(ret, FAIL, "H5Fclose");
 } /* end test_file_open_overlap() */
 
 /****************************************************************
 **
+**  test_file_getname(): low-level file test routine.  
+**      This test checks whether H5Fget_name works correctly.
+**
+*****************************************************************/
+static void 
+test_file_getname(void)
+{
+    /* Compound datatype */
+    typedef struct s1_t {
+        unsigned int a;
+        float        b;
+    } s1_t;
+
+    hid_t   file_id;
+    hid_t   group_id;
+    hid_t   dataset_id;
+    hid_t   space_id;  
+    hid_t   type_id;
+    hid_t   attr_id;
+    hsize_t dims[TESTA_RANK] = {TESTA_NX, TESTA_NY};
+    char    name[TESTA_NAME_BUF_SIZE];
+    ssize_t name_len;
+    herr_t ret;         /* Generic return value */
+ 
+    /* Output message about test being performed */
+    MESSAGE(5, ("Testing H5Fget_name() functionality\n"));
+
+    /* Create a new file_id using default properties. */
+    file_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
+    CHECK(file_id, FAIL, "H5Fcreate"); 
+
+    /* Get and verify file name */
+    name_len = H5Fget_name(file_id, name, TESTA_NAME_BUF_SIZE);
+    CHECK(name_len, FAIL, "H5Fget_name");
+    VERIFY_STR(name, FILE1, "H5Fget_name");
+
+    /* Create a group in the root group */
+    group_id = H5Gcreate(file_id, TESTA_GROUPNAME, 0);
+    CHECK(group_id, FAIL, "H5Gcreate"); 
+
+    /* Get and verify file name */
+    name_len = H5Fget_name(group_id, name, TESTA_NAME_BUF_SIZE);
+    CHECK(name_len, FAIL, "H5Fget_name");
+    VERIFY_STR(name, FILE1, "H5Fget_name");
+
+    /* Create the data space  */
+    space_id = H5Screate_simple(TESTA_RANK, dims, NULL);
+    CHECK(space_id, FAIL, "H5Screate_simple"); 
+
+    /* Try get file name from data space.  Supposed to fail because 
+     * it's illegal operation. */
+    H5E_BEGIN_TRY {
+        name_len = H5Fget_name(space_id, name, TESTA_NAME_BUF_SIZE);
+    } H5E_END_TRY;
+    VERIFY(name_len, FAIL, "H5Fget_name");
+
+    /* Create a new dataset */
+    dataset_id = H5Dcreate(file_id, TESTA_DSETNAME, H5T_NATIVE_INT, space_id, H5P_DEFAULT);
+    CHECK(dataset_id, FAIL, "H5Dcreate"); 
+
+    /* Get and verify file name */
+    name_len = H5Fget_name(dataset_id, name, TESTA_NAME_BUF_SIZE);
+    CHECK(name_len, FAIL, "H5Fget_name");
+    VERIFY_STR(name, FILE1, "H5Fget_name");
+
+    /* Create an attribute for the dataset */
+    attr_id = H5Acreate(dataset_id,TESTA_ATTRNAME,H5T_NATIVE_INT,space_id,H5P_DEFAULT);
+    CHECK(attr_id, FAIL, "H5Acreate");
+
+    /* Get and verify file name */
+    name_len = H5Fget_name(attr_id, name, TESTA_NAME_BUF_SIZE);
+    CHECK(name_len, FAIL, "H5Fget_name");
+    VERIFY_STR(name, FILE1, "H5Fget_name");
+
+    /* Create a compound datatype */
+    type_id = H5Tcreate(H5T_COMPOUND, sizeof(s1_t));
+    CHECK(type_id, FAIL, "H5Tcreate"); 
+
+    /* Insert fields */
+    ret = H5Tinsert (type_id, "a", HOFFSET(s1_t,a), H5T_NATIVE_INT);
+    CHECK(ret, FAIL, "H5Tinsert"); 
+
+    ret = H5Tinsert (type_id, "b", HOFFSET(s1_t,b), H5T_NATIVE_FLOAT);
+    CHECK(ret, FAIL, "H5Tinsert"); 
+  
+    /* Save it on file */
+    ret = H5Tcommit(file_id, TESTA_DTYPENAME, type_id);
+    CHECK(ret, FAIL, "H5Tcommit"); 
+
+    /* Get and verify file name */
+    name_len = H5Fget_name(type_id, name, TESTA_NAME_BUF_SIZE);
+    CHECK(name_len, FAIL, "H5Fget_name");
+    VERIFY_STR(name, FILE1, "H5Fget_name");
+
+    /* Close things down */
+    ret = H5Tclose(type_id);
+    CHECK(ret, FAIL, "H5Tclose");
+
+    ret = H5Aclose(attr_id);
+    CHECK(ret, FAIL, "H5Aclose");
+
+    ret = H5Dclose(dataset_id);
+    CHECK(ret, FAIL, "H5Dclose");
+
+    ret = H5Sclose(space_id);
+    CHECK(ret, FAIL, "H5Sclose");
+
+    ret = H5Gclose(group_id);
+    CHECK(ret, FAIL, "H5Gclose");
+
+    ret = H5Fclose(file_id);
+    CHECK(ret, FAIL, "H5Fclose");
+
+} /* end test_file_getname() */
+
+/****************************************************************
+**
 **  test_file(): Main low-level file I/O test routine.
 ** 
 ****************************************************************/
@@ -1525,6 +1651,7 @@ test_file(void)
     test_file_ishdf5();         /* Test detecting HDF5 files correctly */
     test_file_open_dot();       /* Test opening objects with "." for a name */
     test_file_open_overlap();   /* Test opening files in an overlapping manner */
+    test_file_getname();        /* Test basic H5Fget_name() functionality */
 }				/* test_file() */
 
 
-- 
cgit v0.12