summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2011-06-22 15:47:57 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2011-06-22 15:47:57 (GMT)
commitf8f8bed0c2d9d8c9dd39ce09018e629c6e886037 (patch)
treef1e1aa7b5f13dec3121be487fb377097dbbda03a
parent83b77cb4eb777b8e04ba2bdc71e2c53bc9cfd1b5 (diff)
downloadhdf5-f8f8bed0c2d9d8c9dd39ce09018e629c6e886037.zip
hdf5-f8f8bed0c2d9d8c9dd39ce09018e629c6e886037.tar.gz
hdf5-f8f8bed0c2d9d8c9dd39ce09018e629c6e886037.tar.bz2
[svn-r21015] Bug 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. But this caused some backward compatibility problem. v1.8 library couldn't open the file created with v1.6 library. I fixed the problem by checking the EOA value to detect the file created with v1.6 library. Tested on jam, koala, and heiwa.
-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;