diff options
-rw-r--r-- | src/H5FDint.c | 21 | ||||
-rw-r--r-- | src/H5Fsuper.c | 3 | ||||
-rw-r--r-- | test/tfile.c | 120 |
3 files changed, 140 insertions, 4 deletions
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); } + |