diff options
-rw-r--r-- | release_docs/RELEASE.txt | 4 | ||||
-rw-r--r-- | src/H5MFaggr.c | 2 | ||||
-rw-r--r-- | test/mf.c | 201 |
3 files changed, 189 insertions, 18 deletions
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index cc1c157..2c716dd 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -255,6 +255,10 @@ Bug Fixes since HDF5-1.8.16 Library ------- + - Fixed a bug that could occur when using H5Pset_alignment. + + (NAF, 2016/08/11, HDFFV-9948) + - Fixed a memory bug that could occur when a message was improperly marked as sharable on disk. diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c index 02a1720..21d460e 100644 --- a/src/H5MFaggr.c +++ b/src/H5MFaggr.c @@ -201,7 +201,7 @@ HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_siz alignment = 0; /* no alignment */ /* Generate fragment if aggregator is mis-aligned */ - if(alignment && aggr->addr > 0 && aggr->size > 0 && (aggr_mis_align = (aggr->addr + H5FD_get_base_addr(f->shared->lf)) % alignment)) { + if(alignment && aggr->addr > 0 && (aggr_mis_align = (aggr->addr + H5FD_get_base_addr(f->shared->lf)) % alignment)) { aggr_frag_addr = aggr->addr; aggr_frag_size = alignment - aggr_mis_align; } /* end if */ @@ -5974,6 +5974,170 @@ error: return(1); } /* test_mf_align_alloc6() */ + +/* + * Test a bug that occurs when an allocator with zero size left and an unaligned + * endpoint is extended to allocate an aligned object + */ +static unsigned +test_mf_bug1(const char *env_h5_drvr, hid_t fapl) +{ + hid_t file = -1; /* File ID */ + hid_t copied_fapl = -1; /* FAPL to use for this test */ + char filename[FILENAME_LEN]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5FD_mem_t type; + haddr_t addr1, addr2; + hsize_t block_size; + hsize_t align; + hbool_t split = FALSE, multi = FALSE; + + TESTING("H5MF_alloc() bug 1"); + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Copy fapl */ + if((copied_fapl = H5Pcopy(fapl)) < 0) + TEST_ERROR + + /* Get metadata block size */ + if(H5Pget_meta_block_size(copied_fapl, &block_size) < 0) + TEST_ERROR + + /* Set alignment to equal block size / 2 */ + align = block_size / 2; + if(H5Pset_alignment(copied_fapl, 0, align) < 0) + TEST_ERROR + + /* Check for split or multi driver */ + if(!HDstrcmp(env_h5_drvr, "split")) + split = TRUE; + else if(!HDstrcmp(env_h5_drvr, "multi")) + multi = TRUE; + + /* Add alignment to member files for split/multi driver */ + if(split || multi) { + hid_t memb_fapl; + + /* Creat fapl */ + if((memb_fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + TEST_ERROR + + /* Set alignment. Note that it is the block size of the parent FAPL that + * is important here. */ + if(H5Pset_alignment(memb_fapl, 0, align) < 0) + TEST_ERROR + + if(split) { + /* Set split driver with new FAPLs */ + if(H5Pset_fapl_split(copied_fapl, "-m.h5", memb_fapl, "-r.h5", memb_fapl) < 0) + TEST_ERROR + } /* end if */ + else { + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + hid_t memb_fapl_arr[H5FD_MEM_NTYPES]; + char *memb_name[H5FD_MEM_NTYPES]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + hbool_t relax; + H5FD_mem_t mt; + + /* Get current multi settings */ + HDmemset(memb_name, 0, sizeof memb_name); + if(H5Pget_fapl_multi(copied_fapl, memb_map, NULL, memb_name, memb_addr, &relax) < 0) + TEST_ERROR + + /* Populate memb_fapl_arr, patch memb_addr so member file addresses + * are aligned */ + for(mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, mt)) { + memb_fapl_arr[mt] = memb_fapl; + memb_addr[mt] = ((memb_addr[mt] + align - 1) / align) * align; + } /* end for */ + + /* Set multi driver with new FAPLs */ + if(H5Pset_fapl_multi(copied_fapl, memb_map, memb_fapl_arr, (const char * const *)memb_name, memb_addr, relax) < 0) + TEST_ERROR + + /* Free memb_name */ + for(mt = H5FD_MEM_DEFAULT; mt < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, mt)) + free(memb_name[mt]); + } /* end else */ + + /* Close memb_fapl */ + if(H5Pclose(memb_fapl) < 0) + TEST_ERROR + } /* end if */ + + /* Reopen the file with alignment */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, copied_fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = (H5F_t *)H5I_object(file))) + TEST_ERROR + + /* Allocate a block of size align from meta_aggr. This should create an + * aggregator that extends to the end of the file, with + * block_size / 2 bytes remaining, and the end of the file aligned */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, align); + + /* Verify that the allocated block is aligned */ + if(addr1 % align) TEST_ERROR + + /* Allocate a block of size align from meta_aggr. This should force the + * aggregator to extend to the end of the file, with 0 bytes remaining, and + * the end of the file aligned */ + type = H5FD_MEM_SUPER; + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, align); + + /* Verify that the allocated block is aligned */ + if(addr2 % align) TEST_ERROR + + /* Verify that the allocated block is placed align after the previous */ + if((addr2 - addr1) != align) TEST_ERROR + + /* Allocate a block of size block_size + 1 from meta_aggr. This should + * force the aggregator to extend to the end of the file, with 0 bytes + * remaining, and the end of the file unaligned */ + type = H5FD_MEM_SUPER; + addr1 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, block_size + (hsize_t)1); + + /* Verify that the allocated block is aligned */ + if(addr1 % align) TEST_ERROR + + /* Verify that the allocated block is placed block_size / 2 after the + * previous */ + if((addr1 - addr2) != align) TEST_ERROR + + /* Allocate a block of size 1. This should extend the aggregator from + * the previous allocation, and align the new block */ + type = H5FD_MEM_SUPER; + addr2 = H5MF_alloc(f, type, H5P_DATASET_XFER_DEFAULT, (hsize_t)1); + + /* Verify that the allocated block is aligned */ + if(addr2 % align) TEST_ERROR + + /* Verify that the allocated block is placed 3 * (block_size / 2) after + * the previous */ + if((addr2 - addr1) != (3 * align)) TEST_ERROR + + PASSED() + + /* Close file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_mf_bug1() */ + + /* * To verify that file space is allocated from the corresponding free-space manager * because H5FD_FLMAP_DICHOTOMY is used as the default free-list mapping. @@ -6126,32 +6290,35 @@ main(void) /* Tests for alignment */ for(curr_test = TEST_NORMAL; curr_test < TEST_NTESTS; H5_INC_ENUM(test_type_t, curr_test)) { - switch(curr_test) { + switch(curr_test) { case TEST_NORMAL: /* set alignment = 1024 */ - if(H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN1024) < 0) - TEST_ERROR + if(H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN1024) < 0) + TEST_ERROR break; case TEST_AGGR_SMALL: /* set alignment = 4096 */ - if(H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN4096) < 0) - TEST_ERROR + if(H5Pset_alignment(new_fapl, (hsize_t)0, (hsize_t)TEST_ALIGN4096) < 0) + TEST_ERROR break; case TEST_NTESTS: default: TEST_ERROR; - break; - } /* end switch */ - - nerrors += test_mf_align_eoa(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_fs(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc1(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc2(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc3(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc4(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc5(env_h5_drvr, fapl, new_fapl); - nerrors += test_mf_align_alloc6(env_h5_drvr, fapl, new_fapl); - } /* end if */ + break; + } /* end switch */ + + nerrors += test_mf_align_eoa(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_fs(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc1(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc2(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc3(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc4(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc5(env_h5_drvr, fapl, new_fapl); + nerrors += test_mf_align_alloc6(env_h5_drvr, fapl, new_fapl); + } /* end for */ + + /* tests for specific bugs */ + nerrors += test_mf_bug1(env_h5_drvr, fapl); if(H5Pclose(new_fapl) < 0) FAIL_STACK_ERROR |