From 26fdccf6cd0325756a9365c86fd373d3eb955095 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 29 Mar 2007 20:18:27 -0500 Subject: [svn-r13570] Description: Fix error when eliminating empty chunk from "middle" of list of chunks for an object header. Tested on: Mac OS X/32 10.4.9 (amazon) --- src/H5Oalloc.c | 15 ++++++ src/H5Odbg.c | 24 ++++++++- test/tattr.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 1 deletion(-) diff --git a/src/H5Oalloc.c b/src/H5Oalloc.c index ce20a27..70c627f 100644 --- a/src/H5Oalloc.c +++ b/src/H5Oalloc.c @@ -1525,6 +1525,21 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id) HDassert(curr_msg->chunkno != deleted_chunkno); if(curr_msg->chunkno > deleted_chunkno) curr_msg->chunkno--; + + /* Check for continuation message */ + if(H5O_CONT_ID == curr_msg->type->id) { + /* Decode current continuation message if necessary */ + if(NULL == curr_msg->native) { + HDassert(H5O_MSG_CONT->decode); + curr_msg->native = (H5O_MSG_CONT->decode)(f, dxpl_id, 0, curr_msg->raw); + if(NULL == curr_msg->native) + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message") + } /* end if */ + + /* Check for pointer to chunk after deleted chunk */ + if(((H5O_cont_t *)(curr_msg->native))->chunkno > deleted_chunkno) + ((H5O_cont_t *)(curr_msg->native))->chunkno--; + } /* end if */ } /* end for */ /* Found chunk to delete */ diff --git a/src/H5Odbg.c b/src/H5Odbg.c index b4d642b..108ac81 100644 --- a/src/H5Odbg.c +++ b/src/H5Odbg.c @@ -94,6 +94,7 @@ H5O_assert(const H5O_t *oh) { H5O_mesg_t *curr_msg; /* Pointer to current message to examine */ H5O_mesg_t *tmp_msg; /* Pointer to temporary message to examine */ + unsigned cont_msgs_found = 0; /* # of continuation messages for object */ size_t meta_space; /* Size of header metadata */ size_t mesg_space; /* Size of message raw data */ size_t free_space; /* Size of free space in header */ @@ -155,8 +156,26 @@ H5O_assert(const H5O_t *oh) /* Accumulate information, based on the type of message */ if(H5O_NULL_ID == curr_msg->type->id) free_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; - else if(H5O_CONT_ID == curr_msg->type->id) + else if(H5O_CONT_ID == curr_msg->type->id) { + H5O_cont_t *cont = (H5O_cont_t *)curr_msg->native; + hbool_t found_chunk = FALSE; /* Found a chunk that matches */ + + /* Increment # of continuation messages found */ + cont_msgs_found++; + + /* Sanity check that every continuation message has a matching chunk */ + /* (and only one) */ + for(v = 0; v < oh->nchunks; v++) { + if(H5F_addr_eq(cont->addr, oh->chunk[v].addr) && cont->size == oh->chunk[v].size) { + HDassert(cont->chunkno == v); + HDassert(!found_chunk); + found_chunk = TRUE; + } /* end if */ + } /* end for */ + HDassert(found_chunk); + meta_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + } /* end if */ else { meta_space += H5O_SIZEOF_MSGHDR_OH(oh); mesg_space += curr_msg->raw_size; @@ -184,6 +203,9 @@ H5O_assert(const H5O_t *oh) } /* end for */ } /* end for */ + /* Sanity check that the # of cont. messages is correct for the # of chunks */ + HDassert(oh->nchunks == (cont_msgs_found + 1)); + /* Sanity check that all the bytes are accounted for */ HDassert(hdr_size == (free_space + meta_space + mesg_space + oh->skipped_mesg_size)); diff --git a/test/tattr.c b/test/tattr.c index c5d5e7a..0b47ed8 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -71,6 +71,8 @@ /* Group Information */ #define GROUP1_NAME "/Group1" +#define GROUP2_NAME "/Group2" +#define GROUP3_NAME "/Group3" /* Named Datatype Information */ #define TYPE1_NAME "/Type" @@ -124,6 +126,9 @@ float attr_data5=(float)-5.123; /* Test data for 5th attribute */ #define ATTR6_DIM2 100 #define ATTR6_DIM3 100 +#define ATTR7_NAME "attr 1 - 000000" +#define ATTR8_NAME "attr 2" + /* Attribute iteration struct */ typedef struct { H5_iter_order_t order; /* Direction of iteration */ @@ -7653,6 +7658,151 @@ test_attr_shared_unlink(hid_t fcpl, hid_t fapl) /**************************************************************** ** +** test_attr_bug1(): Test basic H5A (attribute) code. +** Tests odd sequence of allocating and deallocating space in the file. +** The series of actions below constructs a file with an attribute +** in each object header chunk, except the first. Then, the attributes +** are removed and re-created in a way that makes the object header +** allocation code remove an object header chunk "in the middle" of +** the sequence of the chunks. +** +****************************************************************/ +static void +test_attr_bug1(hid_t fcpl, hid_t fapl) +{ + hid_t fid; /* File ID */ + hid_t gid; /* Group ID */ + hid_t aid; /* Attribute ID */ + hid_t sid; /* Dataspace ID */ + herr_t ret; /* Generic return status */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing Allocating and De-allocating Attributes in Unusual Way\n")); + + /* Create dataspace ID for attributes */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create main group to operate on */ + fid = H5Fcreate(FILENAME, H5F_ACC_TRUNC, fcpl, fapl); + CHECK(fid, FAIL, "H5Fcreate"); + + gid = H5Gcreate(fid, GROUP1_NAME, (size_t)0); + CHECK(gid, FAIL, "H5Gcreate"); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file and create another group, then attribute on first group */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Create second group */ + gid = H5Gcreate(fid, GROUP2_NAME, (size_t)0); + CHECK(gid, FAIL, "H5Gcreate"); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Re-open first group */ + gid = H5Gopen(fid, GROUP1_NAME); + CHECK(gid, FAIL, "H5Gopen"); + + /* Create attribute on first group */ + aid = H5Acreate(gid, ATTR7_NAME, H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate"); + + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file and create another group, then another attribute on first group */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Create third group */ + gid = H5Gcreate(fid, GROUP3_NAME, (size_t)0); + CHECK(gid, FAIL, "H5Gcreate"); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Unlink second group */ + ret = H5Gunlink(fid, GROUP2_NAME); + CHECK(ret, FAIL, "H5Gunlink"); + + /* Re-open first group */ + gid = H5Gopen(fid, GROUP1_NAME); + CHECK(gid, FAIL, "H5Gopen"); + + /* Create another attribute on first group */ + aid = H5Acreate(gid, ATTR8_NAME, H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate"); + + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file and re-create attributes on first group */ + fid = H5Fopen(FILENAME, H5F_ACC_RDWR, fapl); + CHECK(fid, FAIL, "H5Fopen"); + + /* Re-open first group */ + gid = H5Gopen(fid, GROUP1_NAME); + CHECK(gid, FAIL, "H5Gopen"); + + /* Delete first attribute */ + ret = H5Adelete(gid, ATTR7_NAME); + CHECK(ret, FAIL, "H5Adelete"); + + /* Re-create first attribute */ + aid = H5Acreate(gid, ATTR7_NAME, H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate"); + + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + /* Delete second attribute */ + ret = H5Adelete(gid, ATTR8_NAME); + CHECK(ret, FAIL, "H5Adelete"); + + /* Re-create second attribute */ + aid = H5Acreate(gid, ATTR8_NAME, H5T_NATIVE_DOUBLE, sid, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Acreate"); + + ret = H5Aclose(aid); + CHECK(ret, FAIL, "H5Aclose"); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Close dataspace ID */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Gclose"); +} /* test_attr_bug1() */ + +/**************************************************************** +** ** test_attr(): Main H5A (attribute) testing routine. ** ****************************************************************/ @@ -7779,6 +7929,9 @@ test_attr(void) test_attr_shared_delete(my_fcpl, my_fapl); /* Test deleting shared attributes in compact & dense storage */ test_attr_shared_unlink(my_fcpl, my_fapl); /* Test unlinking object with shared attributes in compact & dense storage */ } /* end if */ + + /* Tests that address specific bugs */ + test_attr_bug1(my_fcpl, my_fapl); /* Test odd allocation operations */ } /* end for */ } /* end if */ else { @@ -7789,6 +7942,9 @@ test_attr(void) test_attr_open_by_idx(new_format, fcpl, my_fapl); /* Test opening attributes by index */ test_attr_open(new_format, fcpl, my_fapl); /* Test opening attributes by name */ test_attr_big(fcpl, my_fapl); /* Test storing big attribute */ + + /* Tests that address specific bugs */ + test_attr_bug1(fcpl, my_fapl); /* Test odd allocation operations */ } /* end else */ } /* end for */ -- cgit v0.12