From f29e3e10975ee2164ca1ad1c0964108f3dc117d0 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 14 Aug 2003 07:18:34 -0500 Subject: [svn-r7362] Purpose: Bug fix Description: Allow a user block to be "inserted" in front of a file (probably by writing a validly-sized userblock to a new file and then appending another HDF5 file to the new file). Platforms tested: FreeBSD 4.8 (sleipnir) h5committested --- release_docs/RELEASE.txt | 3 + src/H5Distore.c | 2 +- src/H5F.c | 15 +- src/H5Fistore.c | 2 +- test/Makefile.in | 2 +- test/tmisc.c | 382 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 402 insertions(+), 4 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index e291c1a..400b4ec 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -73,6 +73,9 @@ Bug Fixes since HDF5-1.6.0 release Library ------- + - Corrected bug with user blocks that didn't allow a user block to + be inserted in front of a file after the file was created. + QAK - 2003/08/13 - Corrected errors with using point selections to access data in chunked datasets. QAK - 2003/07/23 - Corrected error with variable-length datatypes and chunked datasets diff --git a/src/H5Distore.c b/src/H5Distore.c index fa969f0..929a3e0 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -2666,7 +2666,7 @@ H5F_istore_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key /*in,out HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, H5B_INS_ERROR, "unable to clear sieve buffer"); /* Remove raw data chunk from file */ - H5FD_free(f->shared->lf, H5FD_MEM_DRAW, dxpl_id, addr, (hsize_t)lt_key->nbytes); + H5MF_xfree(f, H5FD_MEM_DRAW, dxpl_id, addr, (hsize_t)lt_key->nbytes); /* Mark keys as unchanged */ *lt_key_changed = FALSE; diff --git a/src/H5F.c b/src/H5F.c index 6600196..097093d 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -2124,6 +2124,19 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d if (H5G_ent_decode(file, &p, &root_ent/*out*/)<0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root symbol entry"); + /* Check if superblock address is different from base address and + * adjust base address and "end of address" address if so. + */ + if(!H5F_addr_eq(shared->super_addr,shared->base_addr)) { + /* Check if the superblock moved earlier in the file */ + if(H5F_addr_lt(shared->super_addr,shared->base_addr)) + stored_eoa -= (shared->base_addr-shared->super_addr); + /* The superblock moved later in the file */ + else + stored_eoa += (shared->super_addr-shared->base_addr); + shared->base_addr = shared->super_addr; + } /* end if */ + /* Compute super block checksum */ assert(sizeof(chksum)==sizeof(shared->super_chksum)); for(q=(uint8_t *)&chksum, chksum=0, i=0; i<(fixed_size+variable_size); i++) @@ -2196,7 +2209,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d /* * Tell the file driver how much address space has already been - * allocated so that it knows how to allocated additional memory. + * allocated so that it knows how to allocate additional memory. */ if (H5FD_set_eoa(lf, stored_eoa)<0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to set end-of-address marker for file"); diff --git a/src/H5Fistore.c b/src/H5Fistore.c index fa969f0..929a3e0 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -2666,7 +2666,7 @@ H5F_istore_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key /*in,out HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, H5B_INS_ERROR, "unable to clear sieve buffer"); /* Remove raw data chunk from file */ - H5FD_free(f->shared->lf, H5FD_MEM_DRAW, dxpl_id, addr, (hsize_t)lt_key->nbytes); + H5MF_xfree(f, H5FD_MEM_DRAW, dxpl_id, addr, (hsize_t)lt_key->nbytes); /* Mark keys as unchanged */ *lt_key_changed = FALSE; diff --git a/test/Makefile.in b/test/Makefile.in index fc03b62..5504940 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -58,7 +58,7 @@ MOSTLYCLEAN=cmpd_dset.h5 compact_dataset.h5 dataset.h5 extend.h5 istore.h5 \ tvlstr.h5 flush.h5 enum1.h5 titerate.h5 ttsafe.h5 tarray1.h5 \ tgenprop.h5 tmisc.h5 tmisc2a.h5 tmisc2b.h5 tmisc3.h5 tmisc4a.h5 \ tmisc4b.h5 tmisc5.h5 tmisc6.h5 tmisc7.h5 tmisc8.h5 tmisc9.h5 \ - tmisc10.h5 tmisc11.h5 tmisc12.h5 \ + tmisc10.h5 tmisc11.h5 tmisc12.h5 tmisc13a.h5 tmisc13b.h5 \ set_extent_read.h5 set_extent_create.h5 getname.h5 getname1.h5 \ getname2.h5 getname3.h5 sec2_file.h5 family_file000[0-3][0-9].h5 \ multi_file-[rs].h5 core_file new_move_[ab].h5 ntypes.h5 dangle.h5 \ diff --git a/test/tmisc.c b/test/tmisc.c index 3e545c1..c3ede54 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -164,6 +164,26 @@ typedef struct #define MISC12_CHUNK_SIZE 2 #define MISC12_APPEND_SIZE 5 +/* Definitions for misc. test #13 */ +#define MISC13_FILE_1 "tmisc13a.h5" +#define MISC13_FILE_2 "tmisc13b.h5" +#define MISC13_DSET1_NAME "Dataset1" +#define MISC13_DSET2_NAME "Dataset2" +#define MISC13_DSET3_NAME "Dataset3" +#define MISC13_GROUP1_NAME "Group1" +#define MISC13_GROUP2_NAME "Group2" +#define MISC13_DTYPE_NAME "Datatype" +#define MISC13_RANK 2 +#define MISC13_DIM1 20 +#define MISC13_DIM2 30 +#define MISC13_CHUNK_DIM1 10 +#define MISC13_CHUNK_DIM2 15 +#define MISC13_USERBLOCK_SIZE 512 +#define MISC13_COPY_BUF_SIZE 4096 + +unsigned m13_data[MISC13_DIM1][MISC13_DIM2]; /* Data to write to dataset */ +unsigned m13_rdata[MISC13_DIM1][MISC13_DIM2]; /* Data read from dataset */ + /**************************************************************** ** ** test_misc1(): test unlinking a dataset from a group and immediately @@ -1949,6 +1969,365 @@ test_misc12(void) CHECK(ret, FAIL, "H5Fclose"); } /* end test_misc12() */ +/* Various routines for misc. 13 test */ +static void +init_data(void) +{ + unsigned u,v; /* Local index variables */ + + for(u=0; u=0); + CHECK(ret, FAIL, "H5Fclose"); +} + +static void +insert_user_block(const char *old_name, const char *new_name,const char *str,size_t size) +{ + FILE *new_fp, *old_fp; /* Pointers to new & old files */ + void *user_block; /* Pointer to user block to write to file */ + void *copy_buf; /* Pointer to buffer for copying data */ + size_t written; /* Amount of data written to new file */ + size_t read_in; /* Amount of data read in from old file */ + int ret; /* Generic status value */ + + /* Allocate space for the user block */ + user_block=HDcalloc(size,1); + CHECK(user_block, NULL, "HDcalloc"); + + /* Copy in the user block data */ + HDmemcpy(user_block,str,strlen(str)); + + /* Open the new file */ + new_fp=HDfopen(new_name,"wb"); + CHECK(new_fp, NULL, "HDfopen"); + + /* Write the user block to the new file */ + written=HDfwrite(user_block,1,size,new_fp); + VERIFY(written, size, "HDfwrite"); + + /* Open the old file */ + old_fp=fopen(old_name,"rb"); + CHECK(old_fp, NULL, "HDfopen"); + + /* Allocate space for the copy buffer */ + copy_buf=malloc(MISC13_COPY_BUF_SIZE); + CHECK(copy_buf, NULL, "HDmalloc"); + + /* Copy data from the old file to the new file */ + while((read_in=fread(copy_buf,1,MISC13_COPY_BUF_SIZE,old_fp))>0) { + /* Write the data to the new file */ + written=fwrite(copy_buf,1,read_in,new_fp); + VERIFY(written, read_in, "HDfwrite"); + } /* end while */ + + /* Close the old file */ + ret=HDfclose(old_fp); + VERIFY(ret, 0, "HDfclose"); + + /* Close the new file */ + ret=fclose(new_fp); + VERIFY(ret, 0, "HDfclose"); + + /* Free the copy buffer */ + free(copy_buf); + + /* Free the user block */ + free(user_block); +} + +static void +verify_file(const char *name, hsize_t blk_size, unsigned check_new_data) +{ + hid_t fid; /* File ID */ + hid_t gid,gid2; /* Group IDs */ + hid_t tid; /* Datatype ID */ + hid_t fcpl; /* File creation property list ID */ + hsize_t userblock; /* Userblock size retrieved from FCPL */ + herr_t ret; /* Generic return value */ + + /* Open the file */ + fid=H5Fopen(name, H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* Get the file's FCPL */ + fcpl=H5Fget_create_plist(fid); + CHECK(fcpl, FAIL, "H5Fget_create_plist"); + + /* Get the user block size for the file */ + ret=H5Pget_userblock(fcpl,&userblock); + CHECK(ret, FAIL, "H5Pget_userblock"); + + /* Check the userblock size */ + VERIFY(userblock, blk_size, "H5Pget_userblock"); + + /* Close the FCPL */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Verify the contiguous dataset in the root group */ + verify_dataset(fid,MISC13_DSET1_NAME); + + /* Verify the chunked dataset in the root group */ + verify_dataset(fid,MISC13_DSET2_NAME); + + /* Verify the "new" contiguous dataset in the root group, if asked */ + if(check_new_data) + verify_dataset(fid,MISC13_DSET3_NAME); + + /* Open the named datatype in the root group */ + tid = H5Topen(fid, MISC13_DTYPE_NAME); + CHECK(tid, FAIL, "H5Topen"); + + /* Verify the type is correct */ + VERIFY(H5Tequal(tid,H5T_NATIVE_INT), TRUE, "H5Tequal"); + + /* Close named datatype */ + ret=H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Open the first group */ + gid = H5Gopen(fid, MISC13_GROUP1_NAME); + CHECK(gid, FAIL, "H5Gopen"); + + /* Verify the contiguous dataset in the first group */ + verify_dataset(gid,MISC13_DSET1_NAME); + + /* Verify the chunked dataset in the first group */ + verify_dataset(gid,MISC13_DSET2_NAME); + + /* Open the named datatype in the first group */ + tid = H5Topen(gid,MISC13_DTYPE_NAME); + CHECK(tid, FAIL, "H5Topen"); + + /* Verify the type is correct */ + VERIFY(H5Tequal(tid,H5T_NATIVE_INT), TRUE, "H5Tequal"); + + /* Close named datatype */ + ret=H5Tclose(tid); + CHECK(ret, FAIL, "H5Tclose"); + + /* Open the second group */ + gid2 = H5Gopen(gid, MISC13_GROUP2_NAME); + CHECK(gid2, FAIL, "H5Gopen"); + + /* Close the second group */ + ret = H5Gclose(gid2); + CHECK(ret, FAIL, "H5Gclose"); + + /* Close the first group */ + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} + +static void +add_to_new_file(const char *name) +{ + hid_t fid; /* File ID */ + herr_t ret; /* Generic return value */ + + /* Open the file */ + fid=H5Fopen(name, H5F_ACC_RDWR, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* Create new contiguous dataset in root group */ + create_dataset(fid, MISC13_DSET3_NAME, H5P_DEFAULT); + + /* Close the file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} + +/**************************************************************** +** +** test_misc13(): Test that file contents can be "slid down" by +** inserting a user block in front of an existing file. +** +****************************************************************/ +static void +test_misc13(void) +{ + /* Initialize data to write */ + init_data(); + + /* Create first file, with no user block */ + create_hdf_file(MISC13_FILE_1); + + /* Verify file contents are correct */ + verify_file(MISC13_FILE_1,(hsize_t)0,0); + + /* Create a new file by inserting a user block in front of the first file */ + insert_user_block(MISC13_FILE_1,MISC13_FILE_2,"Test String",MISC13_USERBLOCK_SIZE); + + /* Verify file contents are still correct */ + verify_file(MISC13_FILE_2,(hsize_t)MISC13_USERBLOCK_SIZE,0); + + /* Make certain we can modify the new file */ + add_to_new_file(MISC13_FILE_2); + + /* Verify file contents are still correct */ + verify_file(MISC13_FILE_2,(hsize_t)MISC13_USERBLOCK_SIZE,1); +} + /**************************************************************** ** ** test_misc(): Main misc. test routine. @@ -1972,6 +2351,7 @@ test_misc(void) test_misc10(); /* Test for using dataset creation property lists from old files */ test_misc11(); /* Test for all properties of a file creation property list being stored */ test_misc12(); /* Test VL-strings in chunked datasets operating correctly */ + test_misc13(); /* Test that a user block can be insert in front of file contents */ } /* test_misc() */ @@ -2007,4 +2387,6 @@ cleanup_misc(void) HDremove(MISC10_FILE_NEW); HDremove(MISC11_FILE); HDremove(MISC12_FILE); + HDremove(MISC13_FILE_1); + HDremove(MISC13_FILE_2); } -- cgit v0.12