summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-09-08 20:15:37 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-09-08 20:15:37 (GMT)
commiteaf4ee3eb992809394f74e607b932482126a5b57 (patch)
tree1a0b803f84532ddf92543239009c5df1a1a43a4d
parent1cad9f47513a8819c82397371ebe25f83b9917e6 (diff)
downloadhdf5-eaf4ee3eb992809394f74e607b932482126a5b57.zip
hdf5-eaf4ee3eb992809394f74e607b932482126a5b57.tar.gz
hdf5-eaf4ee3eb992809394f74e607b932482126a5b57.tar.bz2
[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
-rw-r--r--src/H5FDspace.c8
-rw-r--r--src/H5Fsuper.c8
-rw-r--r--src/H5Pfcpl.c37
-rw-r--r--test/tfile.c219
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<<i);
+ /* Sanity check non-zero userblock sizes */
+ if(size > 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() */