diff options
-rw-r--r-- | MANIFEST | 2 | ||||
-rw-r--r-- | release_docs/RELEASE.txt | 7 | ||||
-rw-r--r-- | src/H5FDmulti.c | 22 | ||||
-rw-r--r-- | src/H5FDsec2.c | 3 | ||||
-rw-r--r-- | test/CMakeLists.txt | 4 | ||||
-rw-r--r-- | test/Makefile.am | 3 | ||||
-rw-r--r-- | test/Makefile.in | 3 | ||||
-rw-r--r-- | test/multi_file_v16-r.h5 | bin | 0 -> 65536 bytes | |||
-rw-r--r-- | test/multi_file_v16-s.h5 | bin | 0 -> 2048 bytes | |||
-rw-r--r-- | test/vfd.c | 174 |
10 files changed, 214 insertions, 4 deletions
@@ -862,6 +862,8 @@ ./test/mf.c ./test/mount.c ./test/mtime.c +./test/multi_file_v16-r.h5 +./test/multi_file_v16-s.h5 ./test/noencoder.h5 ./test/ntypes.c ./test/ohdr.c diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 5ccd579..58bcfe4 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -105,6 +105,13 @@ Bug Fixes since HDF5-1.8.7 Library ------- + - In v1.6 library, there was EOA for the whole MULTI file saved in the + super block. We took it out in v1.8 library because it's meaningless + for the MULTI file. v1.8 library saves the EOA for the metadata file, + instead. But this caused some backward compatibility problem. + v1.8 library couldn't open the file created with v1.6 library. We + fixed the problem by checking the EOA value to detect the file + created with v1.6 library. (SLU - 2011/6/22) - When a dataset had filters and reading data failed, the error message didn't say which filter isn't registered. It's fixed now. (SLU - 2011/6/3) diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index 328b530..0937ec0 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -83,6 +83,7 @@ typedef struct H5FD_multi_fapl_t { hid_t memb_fapl[H5FD_MEM_NTYPES];/*member access properties */ char *memb_name[H5FD_MEM_NTYPES];/*name generators */ haddr_t memb_addr[H5FD_MEM_NTYPES];/*starting addr per member */ + haddr_t memb_eoa[H5FD_MEM_NTYPES]; /*EOA for individual files */ hbool_t relax; /*less stringent error checking */ } H5FD_multi_fapl_t; @@ -505,6 +506,9 @@ H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, memcpy(fa.memb_addr, memb_addr, H5FD_MEM_NTYPES*sizeof(haddr_t)); fa.relax = relax; + /* Initialize all EOAs to zero */ + memset(fa.memb_eoa, 0, H5FD_MEM_NTYPES*sizeof(haddr_t)); + /* Patch up H5P_DEFAULT property lists for members */ for (mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; mt=(H5FD_mem_t)(mt+1)) { if(fa.memb_fapl[mt]==H5P_DEFAULT) @@ -969,6 +973,9 @@ H5FD_multi_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) if (file->memb[mt]) if(H5FDset_eoa(file->memb[mt], mt, memb_eoa[mt])<0) H5Epush_ret(func, H5E_ERR_CLS, H5E_INTERNAL, H5E_CANTSET, "set_eoa() failed", -1) + + /* Save the individual EOAs in one place for later comparison (in H5FD_multi_set_eoa) */ + file->fa.memb_eoa[mt] = memb_eoa[mt]; } END_MEMBERS; return 0; @@ -1563,6 +1570,10 @@ H5FD_multi_get_eoa(const H5FD_t *_file, H5FD_mem_t type) * for MULTI file. This function only sets eoa for individual * file. * + * Raymond Lu + * 21 June 2011 + * Backward compatibility of EOA. Please the comment in the + * code. *------------------------------------------------------------------------- */ static herr_t @@ -1580,6 +1591,17 @@ H5FD_multi_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t eoa) if(H5FD_MEM_DEFAULT == mmt) mmt = type; + /* Handle backward compatibility in a quick and simple way. v1.6 library had EOA for the entire virtual + * file. But it wasn't meaningful. So v1.8 library doesn't have it anymore. It saves the EOA for the + * metadata file, instead. Here we try to figure out whether the EOA is from a v1.6 file by comparing its + * value. If it is a big value, we assume it's from v1.6 and simply discard it. This is the normal case + * when the metadata file has the smallest starting address. If the metadata file has the biggest address, + * the EOAs of v1.6 and v1.8 files are the same. It won't cause any trouble. (Please see Issue 2598 + * in Jira) SLU - 2011/6/21 + */ + if(H5FD_MEM_SUPER == type && file->fa.memb_eoa[H5FD_MEM_SUPER] > 0 && eoa > file->fa.memb_eoa[H5FD_MEM_SUPER]) + return 0; + assert(eoa >= file->fa.memb_addr[mmt]); assert(eoa < file->memb_next[mmt]); diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 1153df7..5b9b22b 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -695,7 +695,8 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, if(REGION_OVERFLOW(addr, size)) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) if((addr + size) > file->eoa) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size=%lu, eoa=%llu", + (unsigned long long)addr, size, (unsigned long long)file->eoa) /* Seek to the correct location */ if(addr != file->pos || OP_READ != file->op) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7685886..ad2547e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -93,6 +93,8 @@ SET (HDF5_REFERENCE_TEST_FILES le_extlink1.h5 le_extlink2.h5 mergemsg.h5 + multi_file_v16-r.h5 + multi_file_v16-s.h5 noencoder.h5 specmetaread.h5 tarrold.h5 @@ -222,6 +224,8 @@ ADD_TEST ( extlinks19B00027.h5 extlinks19B00028.h5 fheap.h5 + new_multi_file_v16-r.h5 + new_multi_file_v16-s.h5 objcopy_ext.h5 sys_file1 tattr.h5 diff --git a/test/Makefile.am b/test/Makefile.am index 65bf872..52283bd 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -124,7 +124,8 @@ CHECK_CLEANFILES+=accum.h5 cmpd_dset.h5 compact_dataset.h5 dataset.h5 dset_offse dtransform.h5 test_filters.h5 get_file_name.h5 tstint[1-2].h5 \ unlink_chunked.h5 btree2.h5 objcopy_src.h5 objcopy_dst.h5 \ objcopy_ext.dat trefer1.h5 trefer2.h5 app_ref.h5 tcheck_version_*.out \ - tcheck_version_*.err efc[0-5].h5 log_vfd_out.log + tcheck_version_*.err efc[0-5].h5 log_vfd_out.log \ + new_multi_file_v16-r.h5 new_multi_file_v16-s.h5 # Sources for testhdf5 executable testhdf5_SOURCES=testhdf5.c tarray.c tattr.c tchecksum.c tconfig.c tfile.c \ diff --git a/test/Makefile.in b/test/Makefile.in index 8b5e327..f3545b0 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -736,7 +736,8 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog accum.h5 cmpd_dset.h5 \ tstint[1-2].h5 unlink_chunked.h5 btree2.h5 objcopy_src.h5 \ objcopy_dst.h5 objcopy_ext.dat trefer1.h5 trefer2.h5 \ app_ref.h5 tcheck_version_*.out tcheck_version_*.err \ - efc[0-5].h5 log_vfd_out.log + efc[0-5].h5 log_vfd_out.log new_multi_file_v16-r.h5 \ + new_multi_file_v16-s.h5 INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src # Test script for error_test and err_compat diff --git a/test/multi_file_v16-r.h5 b/test/multi_file_v16-r.h5 Binary files differnew file mode 100644 index 0000000..36a4c88 --- /dev/null +++ b/test/multi_file_v16-r.h5 diff --git a/test/multi_file_v16-s.h5 b/test/multi_file_v16-s.h5 Binary files differnew file mode 100644 index 0000000..e990e95 --- /dev/null +++ b/test/multi_file_v16-s.h5 @@ -50,13 +50,14 @@ const char *FILENAME[] = { "log_file", /*6*/ "stdio_file", /*7*/ "windows_file", /*8*/ + "new_multi_file_v16",/*9*/ NULL }; #define LOG_FILENAME "log_vfd_out.log" #define COMPAT_BASENAME "family_v16_" - +#define MULTI_COMPAT_BASENAME "multi_file_v16" /*------------------------------------------------------------------------- @@ -1123,6 +1124,176 @@ error: /*------------------------------------------------------------------------- + * Function: test_multi_compat + * + * Purpose: Tests the backward compatibility for MULTI driver. + * See if we can open files created with v1.6 library. + * The source file was created by the test/file_handle.c + * of the v1.6 library. This test verifies the fix for + * Issue 2598. In v1.6 library, there was EOA for the whole + * MULTI file saved in the super block. We took it out in + * v1.8 library because it's meaningless for the MULTI file. + * v1.8 library saves the EOA for the metadata file, instead. + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Raymond Lu + * 21 June 2011 + * + *------------------------------------------------------------------------- + */ +static herr_t +test_multi_compat(void) +{ + hid_t file=(-1), fapl, fapl2=(-1), dset=(-1), space=(-1); + hid_t access_fapl = -1; + char filename[1024], newname[1024], tmp[1024]; + char filename_s[1024], newname_s[1024]; + char filename_r[1024], newname_r[1024]; + int *fhandle2=NULL, *fhandle=NULL; + hsize_t file_size; + H5FD_mem_t mt, memb_map[H5FD_MEM_NTYPES]; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + const char *memb_name[H5FD_MEM_NTYPES]; + char sv[H5FD_MEM_NTYPES][32]; + hsize_t dims[2]={MULTI_SIZE, MULTI_SIZE}; + char dname[]="dataset2"; + int i, j; + int buf[MULTI_SIZE][MULTI_SIZE]; + + TESTING("MULTI file driver backward compatibility"); + + /* Set file access property list for MULTI driver */ + fapl = h5_fileaccess(); + + HDmemset(memb_map, 0, sizeof memb_map); + HDmemset(memb_fapl, 0, sizeof memb_fapl); + HDmemset(memb_name, 0, sizeof memb_name); + HDmemset(memb_addr, 0, sizeof memb_addr); + HDmemset(sv, 0, sizeof sv); + + for(mt=H5FD_MEM_DEFAULT; mt<H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,mt)) + memb_map[mt] = H5FD_MEM_SUPER; + memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + + memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + sprintf(sv[H5FD_MEM_SUPER], "%%s-%c.h5", 's'); + memb_name[H5FD_MEM_SUPER] = sv[H5FD_MEM_SUPER]; + memb_addr[H5FD_MEM_SUPER] = 0; + + memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + sprintf(sv[H5FD_MEM_DRAW], "%%s-%c.h5", 'r'); + memb_name[H5FD_MEM_DRAW] = sv[H5FD_MEM_DRAW]; + memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2; + + if(H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr, TRUE)<0) + TEST_ERROR; + + h5_fixname(FILENAME[9], fapl, newname, sizeof newname); + + /* Make copy for the data file in the build directory, to protect the + * original file in the source directory */ + sprintf(filename_s, "%s-%c.h5", MULTI_COMPAT_BASENAME, 's'); + sprintf(newname_s, "%s-%c.h5", FILENAME[9], 's'); + h5_make_local_copy(filename_s, newname_s); + + sprintf(filename_r, "%s-%c.h5", MULTI_COMPAT_BASENAME, 'r'); + sprintf(newname_r, "%s-%c.h5", FILENAME[9], 'r'); + h5_make_local_copy(filename_r, newname_r); + + /* Reopen the file for read only. Verify 1.8 library can open file + * created with 1.6 library. */ + if((file=H5Fopen(newname, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR; + + if((dset = H5Dopen2(file, DSET1_NAME, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dclose(dset) < 0) + TEST_ERROR; + + if(H5Fclose(file) < 0) + TEST_ERROR; + + /* Make sure we can reopen the file for read and write */ + if((file=H5Fopen(newname, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR; + + if((dset = H5Dopen2(file, DSET1_NAME, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dclose(dset) < 0) + TEST_ERROR; + + if(H5Fclose(file) < 0) + TEST_ERROR; + + /* Reopen the file for adding another dataset. The new EOA for metadata file + * should be written to the file */ + if((file=H5Fopen(newname, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR; + + /* Create and write data set */ + if((space=H5Screate_simple(2, dims, NULL)) < 0) + TEST_ERROR; + + if((dset=H5Dcreate2(file, DSET2_NAME, H5T_NATIVE_INT, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + TEST_ERROR; + + for(i=0; i<MULTI_SIZE; i++) + for(j=0; j<MULTI_SIZE; j++) + buf[i][j] = i*10000+j; + if(H5Dwrite(dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) + TEST_ERROR; + + if(H5Dclose(dset) < 0) + TEST_ERROR; + + if(H5Sclose(space) < 0) + TEST_ERROR; + + if(H5Fclose(file) < 0) + TEST_ERROR; + + /* Reopen the file for read only again. Verify the library can handle + * the EOA correctly */ + if((file=H5Fopen(newname, H5F_ACC_RDONLY, fapl)) < 0) + TEST_ERROR; + + if((dset = H5Dopen2(file, DSET1_NAME, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dclose(dset) < 0) + TEST_ERROR; + + if((dset = H5Dopen2(file, DSET2_NAME, H5P_DEFAULT)) < 0) + TEST_ERROR; + + if(H5Dclose(dset) < 0) + TEST_ERROR; + + if(H5Fclose(file) < 0) + TEST_ERROR; + + h5_cleanup(FILENAME, fapl); + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Sclose(space); + H5Dclose(dset); + H5Pclose(fapl); + H5Fclose(file); + } H5E_END_TRY; + return -1; +} + + +/*------------------------------------------------------------------------- * Function: test_log * * Purpose: Tests the file handle interface for log driver @@ -1401,6 +1572,7 @@ main(void) nerrors += test_family() < 0 ? 1 : 0; nerrors += test_family_compat() < 0 ? 1 : 0; nerrors += test_multi() < 0 ? 1 : 0; + nerrors += test_multi_compat() < 0 ? 1 : 0; nerrors += test_direct() < 0 ? 1 : 0; nerrors += test_log() < 0 ? 1 : 0; nerrors += test_stdio() < 0 ? 1 : 0; |