From eaf4ee3eb992809394f74e607b932482126a5b57 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 8 Sep 2009 15:15:37 -0500 Subject: [svn-r17459] Description: Correct bad interaction between non-zero userblocks with non-zero alignments. Also add some additional range checking and tests for invalid userblock sizes. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.8 (amazon) in debug mode Mac OS X/32 10.5.8 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode --- src/H5FDspace.c | 8 ++- src/H5Fsuper.c | 8 +++ src/H5Pfcpl.c | 37 +++++----- test/tfile.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 248 insertions(+), 24 deletions(-) diff --git a/src/H5FDspace.c b/src/H5FDspace.c index 5526b03..19f9281 100644 --- a/src/H5FDspace.c +++ b/src/H5FDspace.c @@ -149,9 +149,11 @@ H5FD_extend(H5FD_t *file, H5FD_mem_t type, hbool_t new_block, hsize_t size, hadd /* Check for EOA already aligned */ if((mis_align = (eoa % file->alignment)) > 0) { extra = file->alignment - mis_align; - if (frag_addr) *frag_addr = eoa; - if (frag_size) *frag_size = extra; - } + if(frag_addr) + *frag_addr = eoa - file->base_addr; /* adjust for file's base address */ + if(frag_size) + *frag_size = extra; + } /* end if */ } /* end if */ /* Add in extra allocation amount */ diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 3be8069..f26d93f 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -419,6 +419,14 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id) if(H5P_get(plist, H5F_CRT_USER_BLOCK_NAME, &userblock_size) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get userblock size") + /* Sanity check the userblock size vs. the file's allocation alignment */ + if(userblock_size > 0) { + if(userblock_size < f->shared->alignment) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "userblock size must be > file object alignment") + if(0 != (userblock_size % f->shared->alignment)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "userblock size must be an integral multiple of file object alignment") + } /* end if */ + sblock->base_addr = userblock_size; sblock->status_flags = 0; diff --git a/src/H5Pfcpl.c b/src/H5Pfcpl.c index 4d576c6..406dbe1 100644 --- a/src/H5Pfcpl.c +++ b/src/H5Pfcpl.c @@ -261,44 +261,39 @@ done: * Programmer: Robb Matzke * Tuesday, January 6, 1998 * - * Modifications: - * - * Raymond Lu, Oct 14, 2001 - * Changed to the new generic property list. - * *------------------------------------------------------------------------- */ herr_t H5Pset_userblock(hid_t plist_id, hsize_t size) { - unsigned i; H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ + herr_t ret_value = SUCCEED; /* return value */ - FUNC_ENTER_API(H5Pset_userblock, FAIL); + FUNC_ENTER_API(H5Pset_userblock, FAIL) H5TRACE2("e", "ih", plist_id, size); - /* Check that the userblock size is a power of two */ - for (i=8; i<8*sizeof(hsize_t); i++) { - hsize_t p2 = 8==i ? 0 : ((hsize_t)1< 0) { + /* Check that the userblock size is >=512 */ + if(size < 512) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "userblock size is non-zero and less than 512") - if (size == p2) - break; - } - if (i>=8*sizeof(hsize_t)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "userblock size is not valid"); + /* Check that the userblock size is a power of two */ + if(!POWER_OF_TWO(size)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "userblock size is non-zero and not a power of two") + } /* end if */ /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); + if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Set value */ if(H5P_set(plist, H5F_CRT_USER_BLOCK_NAME, &size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set user block"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set user block") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_userblock() */ /*------------------------------------------------------------------------- diff --git a/test/tfile.c b/test/tfile.c index 07ccfb2..84dcb73 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -35,6 +35,14 @@ #define H5F_TESTING #include "H5Fpkg.h" /* File access */ +#define BAD_USERBLOCK_SIZE1 (hsize_t)1 +#define BAD_USERBLOCK_SIZE2 (hsize_t)2 +#define BAD_USERBLOCK_SIZE3 (hsize_t)3 +#define BAD_USERBLOCK_SIZE4 (hsize_t)64 +#define BAD_USERBLOCK_SIZE5 (hsize_t)511 +#define BAD_USERBLOCK_SIZE6 (hsize_t)513 +#define BAD_USERBLOCK_SIZE7 (hsize_t)6144 + #define F1_USERBLOCK_SIZE (hsize_t)0 #define F1_OFFSET_SIZE sizeof(haddr_t) #define F1_LENGTH_SIZE sizeof(hsize_t) @@ -208,6 +216,36 @@ test_file_create(void) tmpl1 = H5Pcreate(H5P_FILE_CREATE); CHECK(tmpl1, FAIL, "H5Pcreate"); + /* Try setting some bad userblock sizes */ + H5E_BEGIN_TRY { + ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE1); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pset_userblock"); + H5E_BEGIN_TRY { + ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE2); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pset_userblock"); + H5E_BEGIN_TRY { + ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE3); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pset_userblock"); + H5E_BEGIN_TRY { + ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE4); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pset_userblock"); + H5E_BEGIN_TRY { + ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE5); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pset_userblock"); + H5E_BEGIN_TRY { + ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE6); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pset_userblock"); + H5E_BEGIN_TRY { + ret = H5Pset_userblock(tmpl1, BAD_USERBLOCK_SIZE7); + } H5E_END_TRY; + VERIFY(ret, FAIL, "H5Pset_userblock"); + /* Set the new file-creation parameters */ ret = H5Pset_userblock(tmpl1, F2_USERBLOCK_SIZE); CHECK(ret, FAIL, "H5Pset_userblock"); @@ -2079,6 +2117,186 @@ test_rw_noupdate(void) /**************************************************************** ** +** test_userblock_alignment(): low-level file test routine. +** This test checks to ensure that files with both a userblock and a +** object [allocation] alignment size set interact properly. +** +** Programmer: Quincey Koziol +** koziol@hdfgroup.org +** Septmber 8, 2009 +** +*****************************************************************/ +static void +test_userblock_alignment(void) +{ + hid_t fid; /* File ID */ + hid_t fcpl; /* File creation property list ID */ + hid_t fapl; /* File access property list ID */ + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing that non-zero userblocks and object alignment interact correctly.\n")); + + /* Case 1: + * Userblock size = 0, alignment != 0 + * Outcome: + * Should succeed + */ + /* Create file creation property list with user block */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + ret = H5Pset_userblock(fcpl, (hsize_t)0); + CHECK(ret, FAIL, "H5Pset_userblock"); + + /* Create file access property list with alignment */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3); + CHECK(ret, FAIL, "H5Pset_alignment"); + + /* Create a file with FAPL & FCPL */ + fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Release property lists */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Case 2: + * Userblock size = 512, alignment = 16 + * (userblock is integral mult. of alignment) + * Outcome: + * Should succeed + */ + /* Create file creation property list with user block */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + ret = H5Pset_userblock(fcpl, (hsize_t)512); + CHECK(ret, FAIL, "H5Pset_userblock"); + + /* Create file access property list with alignment */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)16); + CHECK(ret, FAIL, "H5Pset_alignment"); + + /* Create a file with FAPL & FCPL */ + fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Release property lists */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Case 3: + * Userblock size = 512, alignment = 512 + * (userblock is equal to alignment) + * Outcome: + * Should succeed + */ + /* Create file creation property list with user block */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + ret = H5Pset_userblock(fcpl, (hsize_t)512); + CHECK(ret, FAIL, "H5Pset_userblock"); + + /* Create file access property list with alignment */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)512); + CHECK(ret, FAIL, "H5Pset_alignment"); + + /* Create a file with FAPL & FCPL */ + fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Release property lists */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Close file */ + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + /* Case 4: + * Userblock size = 512, alignment = 3 + * (userblock & alignment each individually valid, but userblock is + * non-integral multiple of alignment) + * Outcome: + * Should fail at file creation + */ + /* Create file creation property list with user block */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + ret = H5Pset_userblock(fcpl, (hsize_t)512); + CHECK(ret, FAIL, "H5Pset_userblock"); + + /* Create file access property list with alignment */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)3); + CHECK(ret, FAIL, "H5Pset_alignment"); + + /* Create a file with FAPL & FCPL */ + H5E_BEGIN_TRY { + fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl); + } H5E_END_TRY; + VERIFY(fid, FAIL, "H5Fcreate"); + + /* Release property lists */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); + + /* Case 5: + * Userblock size = 512, alignment = 1024 + * (userblock & alignment each individually valid, but userblock is + * less than alignment) + * Outcome: + * Should fail at file creation + */ + /* Create file creation property list with user block */ + fcpl = H5Pcreate(H5P_FILE_CREATE); + CHECK(fcpl, FAIL, "H5Pcreate"); + ret = H5Pset_userblock(fcpl, (hsize_t)512); + CHECK(ret, FAIL, "H5Pset_userblock"); + + /* Create file access property list with alignment */ + fapl = H5Pcreate(H5P_FILE_ACCESS); + CHECK(fapl, FAIL, "H5Pcreate"); + ret = H5Pset_alignment(fapl, (hsize_t)1, (hsize_t)1024); + CHECK(ret, FAIL, "H5Pset_alignment"); + + /* Create a file with FAPL & FCPL */ + H5E_BEGIN_TRY { + fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, fcpl, fapl); + } H5E_END_TRY; + VERIFY(fid, FAIL, "H5Fcreate"); + + /* Release property lists */ + ret = H5Pclose(fcpl); + CHECK(ret, FAIL, "H5Pclose"); + ret = H5Pclose(fapl); + CHECK(ret, FAIL, "H5Pclose"); +} /* end test_userblock_alignment() */ + +/**************************************************************** +** ** test_file(): Main low-level file I/O test routine. ** ****************************************************************/ @@ -2111,6 +2329,7 @@ test_file(void) test_userblock_file_size(); /* Tests that files created with a userblock have the correct size */ test_cached_stab_info(); /* Tests that files are created with cached stab info in the superblock */ test_rw_noupdate(); /* Test to ensure that RW permissions don't write the file unless dirtied */ + test_userblock_alignment(); /* Tests that files created with a userblock and alignment interact properly */ } /* test_file() */ -- cgit v0.12