summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2009-03-26 15:29:23 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2009-03-26 15:29:23 (GMT)
commit9863d5aee2dd6b8a862199671640c209191c8c77 (patch)
tree3e84e5b480cc2c0dccd08923838aebd537edd8e3
parent2def5e4c85b2fa2cdc992f360a90dc2a103e9e17 (diff)
downloadhdf5-9863d5aee2dd6b8a862199671640c209191c8c77.zip
hdf5-9863d5aee2dd6b8a862199671640c209191c8c77.tar.gz
hdf5-9863d5aee2dd6b8a862199671640c209191c8c77.tar.bz2
[svn-r16616] Purpose: Fix bug 1499
Description: Due to a bug in H5F_super_read, every time a file with a user block was opened it would grow by the size of the user block. The bug has been fixed, and comments have been added to clarify when an eoa address should be relative and when it should be absolute. Tested: jam, linew (h5committest)
-rw-r--r--release_docs/RELEASE.txt12
-rw-r--r--src/H5FDint.c21
-rw-r--r--src/H5Fsuper.c3
-rw-r--r--test/tfile.c120
4 files changed, 147 insertions, 9 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index cd4066a..a32a36b 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -129,6 +129,8 @@ Bug Fixes since HDF5-1.8.2
Library
-------
+ - Fixed a bug that caused files with a user block to grow by the size of the
+ user block every time they were opened. NAF - 2009/03/26 - 1499
- Fixed a rare problem that could occur with files using the old (pre 1.4)
array datatype. NAF - 2009/03/23
- Modified library to be able to open files with corrupt root group symbol
@@ -138,20 +140,20 @@ Bug Fixes since HDF5-1.8.2
"long long". This caused problems with third party products. All
currently supported compliers support the type. (ADB - 2009/03/05)
- Fixed various bugs that could prevent the fill value from being written
- in certain rare cases. NAF - 2009/02/26
+ in certain rare cases. NAF - 2009/02/26 - 1469
- Fixed a bug that prevented more than one dataset chunk from being cached
- at a time. NAF - 2009/02/12
+ at a time. NAF - 2009/02/12 - 1015
- Fixed an assertion failure caused by opening an attribute multiple times
- through multiple file handles. NAF - 2009/02/12
+ through multiple file handles. NAF - 2009/02/12 - 1420
- Fixed a problem that could prevent the user from adding attributes (or any
- object header message) in some circumstances. NAF - 2009/02/12
+ object header message) in some circumstances. NAF - 2009/02/12 - 1427
- Fixed a bug that could cause problems when an attribute was added to a
committed datatype using the committed datatype's datatype.
NAF - 2009/02/12
- Fixed a bug that could cause problems when copying an object with a shared
message in its own object header. NAF - 2009/01/29
- Changed H5Tset_order to properly reject H5T_ORDER_NONE for most datatypes.
- NAF - 2009/01/27
+ NAF - 2009/01/27 - 1443
- Fixed a bug where H5Tpack wouldn't remove trailing space from an otherwise
packed compound type. NAF - 2009/01/14
- Fixed up some old v2 btree assertions that get run in debug mode that
diff --git a/src/H5FDint.c b/src/H5FDint.c
index aa375e2..74b3bf6 100644
--- a/src/H5FDint.c
+++ b/src/H5FDint.c
@@ -194,6 +194,11 @@ done:
*
* Purpose: Private version of H5FDset_eoa()
*
+ * This function expects the EOA is a RELATIVE address, i.e.
+ * relative to the base address. This is NOT the same as the
+ * EOA stored in the superblock, which is an absolute
+ * address. Object addresses are relative.
+ *
* Return: Success: Non-negative
* Failure: Negative, no side effect
*
@@ -212,7 +217,7 @@ H5FD_set_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t addr)
HDassert(file && file->cls);
HDassert(H5F_addr_defined(addr) && addr <= file->maxaddr);
- /* Dispatch to driver */
+ /* Dispatch to driver, convert to absolute address */
if((file->cls->set_eoa)(file, type, addr + file->base_addr) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver set_eoa request failed")
@@ -226,6 +231,11 @@ done:
*
* Purpose: Private version of H5FDget_eoa()
*
+ * This function returns the EOA as a RELATIVE address, i.e.
+ * relative to the base address. This is NOT the same as the
+ * EOA stored in the superblock, which is an absolute
+ * address. Object addresses are relative.
+ *
* Return: Success: First byte after allocated memory.
* Failure: HADDR_UNDEF
*
@@ -247,7 +257,7 @@ H5FD_get_eoa(const H5FD_t *file, H5FD_mem_t type)
if(HADDR_UNDEF == (ret_value = (file->cls->get_eoa)(file, type)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "driver get_eoa request failed")
- /* Adjust for base address in file */
+ /* Adjust for base address in file (convert to relative address) */
ret_value -= file->base_addr;
done:
@@ -260,6 +270,11 @@ done:
*
* Purpose: Private version of H5FDget_eof()
*
+ * This function returns the EOF as a RELATIVE address, i.e.
+ * relative to the base address. This will be different
+ * from the end of the physical file if there is a user
+ * block.
+ *
* Return: Success: The EOF address.
*
* Failure: HADDR_UNDEF
@@ -288,7 +303,7 @@ H5FD_get_eof(const H5FD_t *file)
else
ret_value = file->maxaddr;
- /* Adjust for base address in file */
+ /* Adjust for base address in file (convert to relative address) */
ret_value -= file->base_addr;
done:
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index 04abfb2..8040554 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -560,7 +560,8 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
* Tell the file driver how much address space has already been
* allocated so that it knows how to allocate additional memory.
*/
- if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, stored_eoa) < 0)
+ /* (Account for the stored EOA being absolute offset -NAF) */
+ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, stored_eoa - H5F_BASE_ADDR(f)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to set end-of-address marker for file")
/* Read the file's superblock extension, if there is one. */
diff --git a/test/tfile.c b/test/tfile.c
index 2afade3..724ad4a 100644
--- a/test/tfile.c
+++ b/test/tfile.c
@@ -79,6 +79,8 @@
#define TESTA_NX 4
#define TESTA_NY 5
+#define USERBLOCK_SIZE ((hsize_t) 512)
+
static void
create_objects(hid_t, hid_t, hid_t *, hid_t *, hid_t *, hid_t *);
static void
@@ -1855,6 +1857,122 @@ test_file_double_datatype_open(void)
/****************************************************************
**
+** test_userblock_file_size(): low-level file test routine.
+** This test checks that the presence of a userblock
+** affects the file size in the expected manner, and that
+** the filesize is not changed by reopening the file. It
+** creates two files which are identical except that one
+** contains a userblock, and verifies that their file sizes
+** differ exactly by the userblock size.
+**
+*****************************************************************/
+static void
+test_userblock_file_size(void)
+{
+ hid_t file1_id, file2_id;
+ hid_t group1_id, group2_id;
+ hid_t dset1_id, dset2_id;
+ hid_t space_id;
+ hid_t fcpl2_id;
+ hsize_t dims[2] = {3, 4};
+ hsize_t filesize1, filesize2, filesize;
+ herr_t ret; /* Generic return value */
+
+ /* Output message about test being performed */
+ MESSAGE(5, ("Testing file size with user block\n"));
+
+ /* Create property list with userblock size set */
+ fcpl2_id = H5Pcreate(H5P_FILE_CREATE);
+ CHECK(fcpl2_id, FAIL, "H5Pcreate");
+ ret = H5Pset_userblock(fcpl2_id, USERBLOCK_SIZE);
+ CHECK(ret, FAIL, "H5Pset_userblock");
+
+ /* Create files. Onyl file2 with have a userblock. */
+ file1_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(file1_id, FAIL, "H5Fcreate");
+ file2_id = H5Fcreate(FILE2, H5F_ACC_TRUNC, fcpl2_id, H5P_DEFAULT);
+ CHECK(file2_id, FAIL, "H5Fcreate");
+
+ /* Create groups */
+ group1_id = H5Gcreate2(file1_id, GROUP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(group1_id, FAIL, "H5Gcreate2");
+ group2_id = H5Gcreate2(file2_id, GROUP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(group2_id, FAIL, "H5Gcreate2");
+
+ /* Create dataspace */
+ space_id = H5Screate_simple(2, dims, NULL);
+ CHECK(space_id, FAIL, "H5Screate_simple");
+
+ /* Create datasets */
+ dset1_id = H5Dcreate2(file1_id, DSET2, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(dset1_id, FAIL, "H5Dcreate2");
+ dset2_id = H5Dcreate2(file2_id, DSET2, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(dset2_id, FAIL, "H5Dcreate2");
+
+ /* Close IDs */
+ ret = H5Dclose(dset1_id);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Dclose(dset2_id);
+ CHECK(ret, FAIL, "H5Dclose");
+ ret = H5Sclose(space_id);
+ CHECK(ret, FAIL, "H5Sclose");
+ ret = H5Gclose(group1_id);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Gclose(group2_id);
+ CHECK(ret, FAIL, "H5Gclose");
+ ret = H5Pclose(fcpl2_id);
+ CHECK(ret, FAIL, "H5Pclose");
+
+ /* Close files */
+ ret = H5Fclose(file1_id);
+ CHECK(ret, FAIL, "H5Fclose");
+ ret = H5Fclose(file2_id);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Reopen files */
+ file1_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Fopen");
+ file2_id = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Fopen");
+
+ /* Check file sizes */
+ ret = H5Fget_filesize(file1_id, &filesize1);
+ CHECK(ret, FAIL, "H5Fget_filesize");
+ ret = H5Fget_filesize(file2_id, &filesize2);
+ CHECK(ret, FAIL, "H5Fget_filesize");
+
+ /* Verify that the file sizes differ exactly by the userblock size */
+ VERIFY(filesize2, filesize1 + USERBLOCK_SIZE, "H5Fget_filesize");
+
+ /* Close files */
+ ret = H5Fclose(file1_id);
+ CHECK(ret, FAIL, "H5Fclose");
+ ret = H5Fclose(file2_id);
+ CHECK(ret, FAIL, "H5Fclose");
+
+ /* Reopen files */
+ file1_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Fopen");
+ file2_id = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(ret, FAIL, "H5Fopen");
+
+ /* Verify file sizes did not change */
+ ret = H5Fget_filesize(file1_id, &filesize);
+ CHECK(ret, FAIL, "H5Fget_filesize");
+ VERIFY(filesize, filesize1, "H5Fget_filesize");
+ ret = H5Fget_filesize(file2_id, &filesize);
+ CHECK(ret, FAIL, "H5Fget_filesize");
+ VERIFY(filesize, filesize2, "H5Fget_filesize");
+
+ /* Close files */
+ ret = H5Fclose(file1_id);
+ CHECK(ret, FAIL, "H5Fclose");
+ ret = H5Fclose(file2_id);
+ CHECK(ret, FAIL, "H5Fclose");
+} /* end test_userblock_file_size() */
+
+/****************************************************************
+**
** test_file(): Main low-level file I/O test routine.
**
****************************************************************/
@@ -1884,6 +2002,7 @@ test_file(void)
test_file_double_dataset_open(); /* Test opening same dataset from two files works properly */
test_file_double_datatype_open(); /* Test opening same named datatype from two files works properly */
#endif /*H5_CANNOT_OPEN_TWICE*/
+ test_userblock_file_size(); /* Tests that files created with a userblock have the correct size */
} /* test_file() */
@@ -1909,3 +2028,4 @@ cleanup_file(void)
HDremove(FILE3);
HDremove(FILE4);
}
+