mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-25 17:00:45 +08:00
[svn-r16082] Purpose: Fix a problem in the file unmounting code
Description: Fixes a problem in H5F_close_mounts where it wouldn't correctly reshape the "child" array when unmounting files. Test added for this case. Also fixed a potential bug in H5F_unmount where that routine reshapes the child array. Tested: kagiso linew smirom (h5committest)
This commit is contained in:
parent
2d445f880d
commit
e86e9f49f6
@ -127,6 +127,8 @@ Bug Fixes since HDF5-1.8.0 release
|
||||
|
||||
Library
|
||||
-------
|
||||
- Fixed a bug that could cause problems when "automatically" unmounting
|
||||
multiple files. (NAF - 2008/11/17)
|
||||
- H5Ovisit and H5Ovisit_by_name will now properly terminate when the
|
||||
callback function returns a positive value on the starting object.
|
||||
(NAF - 2008/11/03)
|
||||
|
@ -79,8 +79,10 @@ H5F_close_mounts(H5F_t *f)
|
||||
|
||||
HDassert(f);
|
||||
|
||||
/* Unmount all child files */
|
||||
for (u = 0; u < f->shared->mtab.nmounts; u++) {
|
||||
/* Unmount all child files. Loop backwards to avoid having to adjust u when
|
||||
* a file is unmounted. Note that we rely on unsigned u "wrapping around"
|
||||
* to terminate the loop. */
|
||||
for (u = f->shared->mtab.nmounts - 1; u < f->shared->mtab.nmounts; u--) {
|
||||
/* Only unmount children mounted to this top level file structure */
|
||||
if(f->shared->mtab.child[u].file->parent == f) {
|
||||
/* Detach the child file from the parent file */
|
||||
@ -93,10 +95,16 @@ H5F_close_mounts(H5F_t *f)
|
||||
/* Close the child file */
|
||||
if(H5F_try_close(f->shared->mtab.child[u].file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close child file")
|
||||
|
||||
/* Eliminate the mount point from the table */
|
||||
HDmemmove(f->shared->mtab.child + u, f->shared->mtab.child + u + 1,
|
||||
(f->shared->mtab.nmounts - u - 1) * sizeof(f->shared->mtab.child[0]));
|
||||
f->shared->mtab.nmounts--;
|
||||
f->nmounts--;
|
||||
}
|
||||
} /* end if */
|
||||
f->shared->mtab.nmounts -= f->nmounts;
|
||||
f->nmounts = 0;
|
||||
|
||||
HDassert(f->nmounts == 0);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
@ -390,7 +398,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
|
||||
|
||||
/* Eliminate the mount point from the table */
|
||||
HDmemmove(parent->shared->mtab.child + child_idx, parent->shared->mtab.child + child_idx + 1,
|
||||
(parent->shared->mtab.nmounts-child_idx) * sizeof(parent->shared->mtab.child[0]));
|
||||
(parent->shared->mtab.nmounts - child_idx - 1) * sizeof(parent->shared->mtab.child[0]));
|
||||
parent->shared->mtab.nmounts -= 1;
|
||||
parent->nmounts -= 1;
|
||||
|
||||
|
125
test/mount.c
125
test/mount.c
@ -4200,6 +4200,130 @@ error:
|
||||
return 1;
|
||||
} /* end test_sharedclose() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_multisharedclose
|
||||
*
|
||||
* Purpose: Test that multiple files mounted to a shared mount structure
|
||||
* can be properly closed by closing the groups holding them open.
|
||||
*
|
||||
* Return: Success: 0
|
||||
*
|
||||
* Failure: number of errors
|
||||
*
|
||||
* Programmer: Neil Fortner
|
||||
* Friday, November 14, 2008
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
test_multisharedclose(hid_t fapl)
|
||||
{
|
||||
hid_t fid1 = -1, fid2 = -1; /* File IDs */
|
||||
hid_t gid1 = -1, gid2 = -1, gid3 = -1;
|
||||
char filename1[NAME_BUF_SIZE],
|
||||
filename2[NAME_BUF_SIZE],
|
||||
filename3[NAME_BUF_SIZE],
|
||||
filename4[NAME_BUF_SIZE]; /* Name of files to mount */
|
||||
|
||||
TESTING("closing multiple shared mounts");
|
||||
|
||||
h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
|
||||
h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
|
||||
h5_fixname(FILENAME[2], fapl, filename3, sizeof filename3);
|
||||
h5_fixname(FILENAME[3], fapl, filename4, sizeof filename4);
|
||||
|
||||
/* Create master file with three groups to serve as mount points */
|
||||
if ((fid1 = H5Fcreate(filename4, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Gclose(H5Gcreate(fid1, "mnt1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Gclose(H5Gcreate(fid1, "mnt2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Gclose(H5Gcreate(fid1, "mnt3", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Fclose(fid1) < 0) TEST_ERROR
|
||||
|
||||
/* Create child file with group */
|
||||
if ((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Gclose(H5Gcreate(fid1, "grp", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Fclose(fid1) < 0) TEST_ERROR
|
||||
|
||||
/* Create child file with group */
|
||||
if ((fid1 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Gclose(H5Gcreate(fid1, "grp", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Fclose(fid1) < 0) TEST_ERROR
|
||||
|
||||
/* Create child file with group */
|
||||
if ((fid1 = H5Fcreate(filename3, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Gclose(H5Gcreate(fid1, "grp", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Fclose(fid1) < 0) TEST_ERROR
|
||||
|
||||
|
||||
/* Open master and child 1 and mount child 1 to master */
|
||||
if ((fid1 = H5Fopen(filename4, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if ((fid2 = H5Fopen(filename1, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Fmount(fid1, "mnt1", fid2, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* Open the group in child 1 */
|
||||
if ((gid1 = H5Gopen(fid1, "mnt1/grp", H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
|
||||
/* Close both files. They will be held open by gid1 */
|
||||
if (H5Idec_ref(fid2) < 0) TEST_ERROR
|
||||
if (H5Idec_ref(fid1) < 0) TEST_ERROR
|
||||
|
||||
|
||||
/* Open master and child 2 and mount child 2 to master */
|
||||
if ((fid1 = H5Fopen(filename4, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if ((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Fmount(fid1, "mnt2", fid2, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* Open the group in child 2 */
|
||||
if ((gid2 = H5Gopen(fid1, "mnt2/grp", H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
|
||||
/* Close both files. They will be held open by gid2 */
|
||||
if (H5Idec_ref(fid2) < 0) TEST_ERROR
|
||||
if (H5Idec_ref(fid1) < 0) TEST_ERROR
|
||||
|
||||
|
||||
/* Open master and child 3 and mount child 3 to master */
|
||||
if ((fid1 = H5Fopen(filename4, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if ((fid2 = H5Fopen(filename3, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
if (H5Fmount(fid1, "mnt3", fid2, H5P_DEFAULT) < 0) TEST_ERROR
|
||||
|
||||
/* Open the group in child 3 */
|
||||
if ((gid3 = H5Gopen(fid1, "mnt3/grp", H5P_DEFAULT)) < 0) TEST_ERROR
|
||||
|
||||
/* Close both files. They will be held open by gid3 */
|
||||
if (H5Idec_ref(fid2) < 0) TEST_ERROR
|
||||
if (H5Idec_ref(fid1) < 0) TEST_ERROR
|
||||
|
||||
|
||||
/* Close gid1. This will close child 1. */
|
||||
if (H5Idec_ref(gid1) < 0) TEST_ERROR
|
||||
|
||||
/* Close gid2. This will close child 2. */
|
||||
if (H5Idec_ref(gid2) < 0) TEST_ERROR
|
||||
|
||||
/* Close gid3. This will close child 3 and the master file. */
|
||||
if (H5Idec_ref(gid3) < 0) TEST_ERROR
|
||||
|
||||
/* Check that all file IDs have been closed */
|
||||
if(H5I_nmembers(H5I_FILE) != 0) TEST_ERROR
|
||||
if(H5F_sfile_assert_num(0) < 0) TEST_ERROR
|
||||
|
||||
PASSED();
|
||||
return 0;
|
||||
|
||||
error:
|
||||
H5E_BEGIN_TRY {
|
||||
H5Gclose(gid1);
|
||||
H5Gclose(gid2);
|
||||
H5Gclose(gid3);
|
||||
H5Fclose(fid2);
|
||||
H5Fclose(fid2);
|
||||
} H5E_END_TRY;
|
||||
return 1;
|
||||
} /* end test_multisharedclose() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
@ -4257,6 +4381,7 @@ main(void)
|
||||
nerrors += test_symlink(fapl);
|
||||
nerrors += test_sharedacc(fapl);
|
||||
nerrors += test_sharedclose(fapl);
|
||||
nerrors += test_multisharedclose(fapl);
|
||||
|
||||
if (nerrors) goto error;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user