summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MANIFEST2
-rw-r--r--release_docs/RELEASE.txt10
-rw-r--r--src/H5FDmulti.c22
-rw-r--r--src/H5FDsec2.c3
-rw-r--r--test/multi_file_v16-r.h5bin0 -> 65536 bytes
-rw-r--r--test/multi_file_v16-s.h5bin0 -> 2048 bytes
-rw-r--r--test/vfd.c173
7 files changed, 207 insertions, 3 deletions
diff --git a/MANIFEST b/MANIFEST
index f7893eb..50fb2f9 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -891,6 +891,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 86882fd..264908b 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -286,6 +286,14 @@ Bug Fixes since HDF5-1.8.0 release
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)
@@ -519,7 +527,7 @@ Bug Fixes since HDF5-1.8.0 release
prior to configuration. MAM - 2009/03/09 - BZ #1401.
- Fixed error with 'make check install' failing due to h5dump
needing other tools built first. MAM - 2008/10/24.
- - When using shared szip, it is no longer necessary to specify
+ - Wpen using shared szip, it is no longer necessary to specify
the path to the shared szip libraries in LD_LIBRARY_PATH. MAM -
2008/10/24.
- The file libhdf5_fortran.settings is not installed since its content
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index 9c30104..9f05126 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;
@@ -506,6 +507,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)
@@ -970,6 +974,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;
@@ -1564,6 +1571,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
@@ -1581,6 +1592,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 bb5dc15..7908fd9 100644
--- a/src/H5FDsec2.c
+++ b/src/H5FDsec2.c
@@ -697,7 +697,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/multi_file_v16-r.h5 b/test/multi_file_v16-r.h5
new file mode 100644
index 0000000..36a4c88
--- /dev/null
+++ b/test/multi_file_v16-r.h5
Binary files differ
diff --git a/test/multi_file_v16-s.h5 b/test/multi_file_v16-s.h5
new file mode 100644
index 0000000..e990e95
--- /dev/null
+++ b/test/multi_file_v16-s.h5
Binary files differ
diff --git a/test/vfd.c b/test/vfd.c
index 9fe0e9e..8f88681 100644
--- a/test/vfd.c
+++ b/test/vfd.c
@@ -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,175 @@ 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;
+
+ 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
@@ -1402,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;