From c952661afbac41d4bf2622899bf2a4c2c02b07b5 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 7 May 2005 14:34:25 -0500 Subject: [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 --- src/H5Gent.c | 3 +- src/H5O.c | 28 +++---- test/mount.c | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 257 insertions(+), 23 deletions(-) diff --git a/src/H5Gent.c b/src/H5Gent.c index 69a34f8..08b3988 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -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 */ diff --git a/src/H5O.c b/src/H5O.c index 21afecb..edd3424 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -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"); diff --git a/test/mount.c b/test/mount.c index 7c71967..ac8212e 100644 --- a/test/mount.c +++ b/test/mount.c @@ -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 ./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."); -- cgit v0.12