[svn-r10734] Purpose:

Bug fix

Description:
    Fix several problems with mounting files on an entry in a group when the
file the group is in has been closed.

Platforms tested:
    FreeBSD 4.11 (sleipnir)
    h5committest
This commit is contained in:
Quincey Koziol 2005-05-07 14:34:25 -05:00
parent 314bfe6f3c
commit c952661afb
3 changed files with 257 additions and 23 deletions

View File

@ -398,7 +398,8 @@ H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5G_ent_copy_depth_t dept
/* If the depth is "very shallow", keep the old entry's user path */
if(depth==H5G_COPY_LIMITED) {
tmp_user_path_r=dst->user_path_r;
H5RS_decr(dst->canon_path_r);
if(dst->canon_path_r)
H5RS_decr(dst->canon_path_r);
} /* end if */
/* Copy the top level information */

View File

@ -289,7 +289,7 @@ H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, had
oh->nchunks = 1;
oh->alloc_nchunks = H5O_NCHUNKS;
if (NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, oh->alloc_nchunks)))
if (NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
tmp_addr = ent->header + (hsize_t)H5O_SIZEOF_HDR(f);
@ -304,7 +304,7 @@ H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, had
oh->nmesgs = 1;
oh->alloc_nmesgs = H5O_NMESGS;
if (NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh->alloc_nmesgs)))
if (NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, (size_t)oh->alloc_nmesgs)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
oh->mesg[0].type = H5O_NULL;
@ -416,14 +416,14 @@ H5O_close(H5G_entry_t *obj_ent)
#endif
/*
* If the file open-lock count has reached zero and the file has a close
* 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 (0==obj_ent->file->nopen_objs && obj_ent->file->closing)
if (obj_ent->file->mtab.nmounts==obj_ent->file->nopen_objs && obj_ent->file->closing)
H5I_dec_ref(obj_ent->file->closing);
/* Free the ID to name buffers */
H5G_free_ent_name(obj_ent);
@ -517,7 +517,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* build the message array */
oh->alloc_nmesgs = MAX(H5O_NMESGS, nmesgs);
if (NULL==(oh->mesg=H5FL_SEQ_CALLOC(H5O_mesg_t,oh->alloc_nmesgs)))
if (NULL==(oh->mesg=H5FL_SEQ_CALLOC(H5O_mesg_t,(size_t)oh->alloc_nmesgs)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* read each chunk from disk */
@ -525,7 +525,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
/* increase chunk array size */
if (oh->nchunks >= oh->alloc_nchunks) {
unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, na);
H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, (size_t)na);
if (!x)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
@ -677,7 +677,7 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
UINT32ENCODE(p, oh->chunk[0].size);
/* zero to alignment */
HDmemset (p, 0, H5O_SIZEOF_HDR(f)-12);
HDmemset (p, 0, (size_t)(H5O_SIZEOF_HDR(f)-12));
/* write the object header prefix */
@ -686,7 +686,7 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
combine=1;
} /* end if */
else {
if (H5F_block_write(f, H5FD_MEM_OHDR, addr, H5O_SIZEOF_HDR(f),
if (H5F_block_write(f, H5FD_MEM_OHDR, addr, (size_t)H5O_SIZEOF_HDR(f),
dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk");
} /* end else */
@ -759,7 +759,7 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Copy in the prefix */
HDmemcpy(p,buf,H5O_SIZEOF_HDR(f));
HDmemcpy(p,buf,(size_t)H5O_SIZEOF_HDR(f));
/* Copy in the first chunk */
HDmemcpy(p+H5O_SIZEOF_HDR(f),oh->chunk[u].image,oh->chunk[u].size);
@ -2698,7 +2698,7 @@ H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh, unsigned chunkno, size_t size)
/* create a new null message */
if (oh->nmesgs >= oh->alloc_nmesgs) {
unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, na);
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, (size_t)na);
if (NULL==x)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
@ -2842,7 +2842,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size)
*/
if (oh->nchunks >= oh->alloc_nchunks) {
unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, na);
H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, (size_t)na);
if (!x)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
@ -2863,7 +2863,7 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size)
if (oh->nmesgs + 3 > oh->alloc_nmesgs) {
int old_alloc=oh->alloc_nmesgs;
unsigned na = oh->alloc_nmesgs + MAX (H5O_NMESGS, 3);
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, na);
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, (size_t)na);
if (!x)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
@ -3029,7 +3029,7 @@ H5O_alloc(H5F_t *f, H5O_t *oh, const H5O_class_t *type, size_t size)
if (oh->nmesgs >= oh->alloc_nmesgs) {
int old_alloc=oh->alloc_nmesgs;
unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, na);
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, (size_t)na);
if (!x)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");

View File

@ -27,6 +27,13 @@ const char *FILENAME[] = {
NULL
};
/* For "mount_after_close" test */
#define RANK 2
#define NX 4
#define NY 5
#define NAME_BUF_SIZE 40
int bm[NX][NY], bm_out[NX][NY]; /* Data buffers */
/*-------------------------------------------------------------------------
* Function: setup
@ -54,10 +61,10 @@ setup(hid_t fapl)
h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
goto error;
if (H5Gclose(H5Gcreate(file, "/mnt1", 0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt1/file1", 0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt_unlink", 0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt_move_a", 0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt1", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt1/file1", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt_unlink", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/mnt_move_a", (size_t)0))<0) goto error;
if (H5Glink(file, H5G_LINK_HARD, "/mnt1/file1", "/file1")<0) goto error;
if (H5Glink(file, H5G_LINK_HARD, "/mnt1", "/mnt1_link")<0) goto error;
if (H5Fclose(file)<0) goto error;
@ -66,10 +73,10 @@ setup(hid_t fapl)
h5_fixname(FILENAME[1], fapl, filename, sizeof filename);
if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
goto error;
if (H5Gclose(H5Gcreate(file, "/file2", 0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/rename_a", 0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/rename_b", 0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/rename_a/x", 0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/file2", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/rename_a", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/rename_b", (size_t)0))<0) goto error;
if (H5Gclose(H5Gcreate(file, "/rename_a/x", (size_t)0))<0) goto error;
if (H5Fclose(file)<0) goto error;
/* file 3 */
@ -1016,6 +1023,231 @@ test_close(hid_t fapl)
return 1;
}
/*-------------------------------------------------------------------------
* Function: test_mount_after_close
*
* Purpose: Test that the library handles mounting a file on a group
* if the group is the only object holding the file open.
*
* Return: Success: 0
*
* Failure: number of errors
*
* Programmer: Quincey Koziol
* Wednesday, May 4, 2005
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
test_mount_after_close(hid_t fapl)
{
hid_t fid1=-1, fid2=-1; /* File IDs */
hid_t gidA=-1, gidAB=-1, gidABM=-1, gidX=-1, gidXY=-1; /* Group identifiers */
hid_t gidABMX=-1, gidABC=-1, gidABT=-1; /* Group IDs for testing */
hid_t didABMXYD=-1; /* Dataset ID for testing */
hid_t did=-1, sid=-1; /* Dataset and dataspace identifiers */
char filename1[1024], filename2[1024]; /* Name of files to mount */
char objname[NAME_BUF_SIZE]; /* Name of object opened */
hsize_t dims[] = {NX,NY}; /* Dataset dimensions */
int i, j; /* Local index variable */
TESTING("mounting on group after file is closed");
h5_fixname(FILENAME[0], fapl, filename1, sizeof filename1);
h5_fixname(FILENAME[1], fapl, filename2, sizeof filename2);
/*
* Initialization of buffer matrix "bm"
*/
for(i =0; i<NX; i++)
for(j = 0; j<NY; j++)
bm[i][j] = i + j;
/* Create first file and a groups in it. */
/* h5ls -r shows: */
/* /A Group
/A/B Group
/A/B/C -> ./M/X/Y
/A/B/M Group
/A/B/T -> /A
*/
if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
TEST_ERROR
if((gidA = H5Gcreate(fid1, "A", (size_t)0)) < 0)
TEST_ERROR
if((gidAB = H5Gcreate(gidA , "B", (size_t)0)) < 0)
TEST_ERROR
if((gidABM = H5Gcreate(gidAB , "M", (size_t)0)) < 0) /* Mount point */
TEST_ERROR
if(H5Glink(gidAB, H5G_LINK_SOFT, "./M/X/Y", "C") < 0) /* Soft link */
TEST_ERROR
if(H5Glink(gidAB, H5G_LINK_SOFT, "/A", "T") < 0) /* Soft link */
TEST_ERROR
/* Close groups and file */
if(H5Gclose(gidABM) < 0)
TEST_ERROR
if(H5Gclose(gidAB) < 0)
TEST_ERROR
if(H5Gclose(gidA) < 0)
TEST_ERROR
if(H5Fclose(fid1) < 0)
TEST_ERROR
/* Create second file and dataset "D" in it. */
/* h5ls shows: */
/* /X Group
/X/T -> ./Y
/X/Y Group
/X/Y/D Dataset {4, 5}
*/
if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
TEST_ERROR
dims[0] = NX;
dims[1] = NY;
if((sid = H5Screate_simple(RANK, dims, NULL)) < 0)
TEST_ERROR
if((gidX = H5Gcreate(fid2, "/X", (size_t)0)) < 0)
TEST_ERROR
if((gidXY = H5Gcreate(gidX, "Y", (size_t)0)) < 0)
TEST_ERROR
if((did = H5Dcreate(gidXY, "D", H5T_NATIVE_INT, sid, H5P_DEFAULT)) < 0)
TEST_ERROR
if(H5Glink(gidX, H5G_LINK_SOFT, "./Y", "T") < 0) /* Soft link */
TEST_ERROR
/* Write data to the dataset. */
if(H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, bm) < 0)
TEST_ERROR
/* Close all identifiers. */
if(H5Sclose(sid) < 0)
TEST_ERROR
if(H5Dclose(did) < 0)
TEST_ERROR
if(H5Gclose(gidXY) < 0)
TEST_ERROR
if(H5Gclose(gidX) < 0)
TEST_ERROR
if(H5Fclose(fid2) < 0)
TEST_ERROR
/* Beginning of the actual test code */
/*
* Reopen both files
*/
if((fid1 = H5Fopen(filename1, H5F_ACC_RDONLY, fapl)) < 0)
TEST_ERROR
if((fid2 = H5Fopen(filename2, H5F_ACC_RDONLY, fapl)) < 0)
TEST_ERROR
/*
* Open /A/B to use as a mount point
*/
if((gidAB = H5Gopen(fid1, "/A/B")) < 0)
TEST_ERROR
/*
* Close the parent file. This keeps the file open because of the other handle on the group within
*/
if(H5Fclose(fid1) < 0) /* We close the file (it should stay open from the group) */
TEST_ERROR
/*
* Mount second file under G in the first file.
*/
if(H5Fmount(gidAB, "M", fid2, H5P_DEFAULT) < 0)
TEST_ERROR
/* Open "normal" group in mounted file */
/* (This shows we successfully mounted) */
if((gidABMX = H5Gopen(gidAB, "M/X")) < 0)
TEST_ERROR
/* Check name */
if(H5Iget_name( gidABMX, objname, (size_t)NAME_BUF_SIZE ) < 0)
TEST_ERROR
if(HDstrcmp(objname, "/A/B/M/X"))
TEST_ERROR
/* Close object in mounted file */
if(H5Gclose(gidABMX) < 0)
TEST_ERROR
/* Open group in mounted file through softlink */
if((gidABC = H5Gopen(gidAB, "C")) < 0)
TEST_ERROR
/* Check name */
if(H5Iget_name( gidABC, objname, (size_t)NAME_BUF_SIZE ) < 0)
TEST_ERROR
if(HDstrcmp(objname, "/A/B/C"))
TEST_ERROR
/* Close object in mounted file */
if(H5Gclose(gidABC) < 0)
TEST_ERROR
/* Open group in original file through softlink */
if((gidABT = H5Gopen(gidAB, "T")) < 0)
TEST_ERROR
/* Check name */
if(H5Iget_name( gidABT, objname, (size_t)NAME_BUF_SIZE ) < 0)
TEST_ERROR
if(HDstrcmp(objname, "/A/B/T"))
TEST_ERROR
/* Close object in original file */
if(H5Gclose(gidABT) < 0)
TEST_ERROR
/* Open "normal" dataset in mounted file */
if((didABMXYD = H5Dopen(gidAB, "M/X/Y/D")) < 0)
TEST_ERROR
/* Check name */
if(H5Iget_name( didABMXYD, objname, (size_t)NAME_BUF_SIZE ) < 0)
TEST_ERROR
if(HDstrcmp(objname, "/A/B/M/X/Y/D"))
TEST_ERROR
/* Close object in mounted file */
if(H5Dclose(didABMXYD) < 0)
TEST_ERROR
if(H5Gclose(gidAB) < 0)
TEST_ERROR
if(H5Fclose(fid2) < 0)
TEST_ERROR
/* Shut down */
PASSED();
return 0;
error:
H5E_BEGIN_TRY {
H5Sclose(sid);
H5Dclose(did);
H5Gclose(didABMXYD);
H5Gclose(gidABT);
H5Gclose(gidABC);
H5Gclose(gidABMX);
H5Gclose(gidXY);
H5Gclose(gidX);
H5Gclose(gidABM);
H5Gclose(gidAB);
H5Gclose(gidA);
H5Fclose(fid1);
H5Fclose(fid2);
} H5E_END_TRY;
return 1;
}
/*-------------------------------------------------------------------------
@ -1057,6 +1289,7 @@ main(void)
nerrors += test_interlink(fapl);
nerrors += test_uniformity(fapl);
nerrors += test_close(fapl);
nerrors += test_mount_after_close(fapl);
if (nerrors) goto error;
puts("All mount tests passed.");