diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2006-08-22 17:13:17 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2006-08-22 17:13:17 (GMT) |
commit | dfd71ce12683526f1fdb6abeb43d4a1a107cfe49 (patch) | |
tree | 609ee7979f4a4e6732c36f41817e071e17a8764e | |
parent | 058eb9921de06d297f80f2f633fb6638fd8d6f68 (diff) | |
download | hdf5-dfd71ce12683526f1fdb6abeb43d4a1a107cfe49.zip hdf5-dfd71ce12683526f1fdb6abeb43d4a1a107cfe49.tar.gz hdf5-dfd71ce12683526f1fdb6abeb43d4a1a107cfe49.tar.bz2 |
[svn-r12610] Description:
Add support for checksumming fractal heaps. This is always enabled for
the heap header and indirect blocks (as they are "pure" metadata) and is
optional for direct blocks, since they may be used for "raw" data.
Also, rearrange direct block routines in H5HFcache.c to be in a more
sensible location in the file. (probably should have been a separate checkin,
since the diffs are mostly useless for this checkin... *sigh*)
Tested on:
Linux/32 2.6 (chicago)
Linux/64 2.6 (chicago2)
-rw-r--r-- | src/H5HFcache.c | 871 | ||||
-rw-r--r-- | src/H5HFhdr.c | 1 | ||||
-rw-r--r-- | src/H5HFpkg.h | 45 | ||||
-rw-r--r-- | src/H5HFprivate.h | 1 | ||||
-rw-r--r-- | test/fheap.c | 20 |
5 files changed, 500 insertions, 438 deletions
diff --git a/src/H5HFcache.c b/src/H5HFcache.c index e0b0c16..2f3a78e 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -62,23 +62,23 @@ /* Local Prototypes */ /********************/ -/* Metadata cache callbacks */ +/* Local encode/decode routines */ +static herr_t H5HF_dtable_encode(H5F_t *f, uint8_t **pp, const H5HF_dtable_t *dtable); +static herr_t H5HF_dtable_decode(H5F_t *f, const uint8_t **pp, H5HF_dtable_t *dtable); + +/* Metadata cache (H5AC) callbacks */ static H5HF_hdr_t *H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_hdr_t *hdr); static herr_t H5HF_cache_hdr_clear(H5F_t *f, H5HF_hdr_t *hdr, hbool_t destroy); static herr_t H5HF_cache_hdr_size(const H5F_t *f, const H5HF_hdr_t *hdr, size_t *size_ptr); -static H5HF_direct_t *H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); -static herr_t H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_direct_t *dblock); -static herr_t H5HF_cache_dblock_clear(H5F_t *f, H5HF_direct_t *dblock, hbool_t destroy); -static herr_t H5HF_cache_dblock_size(const H5F_t *f, const H5HF_direct_t *dblock, size_t *size_ptr); static H5HF_indirect_t *H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5HF_cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_indirect_t *iblock); static herr_t H5HF_cache_iblock_clear(H5F_t *f, H5HF_indirect_t *iblock, hbool_t destroy); static herr_t H5HF_cache_iblock_size(const H5F_t *f, const H5HF_indirect_t *iblock, size_t *size_ptr); - -/* Local encode/decode routines */ -static herr_t H5HF_dtable_encode(H5F_t *f, uint8_t **pp, const H5HF_dtable_t *dtable); -static herr_t H5HF_dtable_decode(H5F_t *f, const uint8_t **pp, H5HF_dtable_t *dtable); +static H5HF_direct_t *H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); +static herr_t H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_direct_t *dblock); +static herr_t H5HF_cache_dblock_clear(H5F_t *f, H5HF_direct_t *dblock, hbool_t destroy); +static herr_t H5HF_cache_dblock_size(const H5F_t *f, const H5HF_direct_t *dblock, size_t *size_ptr); /*********************/ /* Package Variables */ @@ -94,16 +94,6 @@ const H5AC_class_t H5AC_FHEAP_HDR[1] = {{ (H5AC_size_func_t)H5HF_cache_hdr_size, }}; -/* H5HF direct block inherits cache-like properties from H5AC */ -const H5AC_class_t H5AC_FHEAP_DBLOCK[1] = {{ - H5AC_FHEAP_DBLOCK_ID, - (H5AC_load_func_t)H5HF_cache_dblock_load, - (H5AC_flush_func_t)H5HF_cache_dblock_flush, - (H5AC_dest_func_t)H5HF_cache_dblock_dest, - (H5AC_clear_func_t)H5HF_cache_dblock_clear, - (H5AC_size_func_t)H5HF_cache_dblock_size, -}}; - /* H5HF indirect block inherits cache-like properties from H5AC */ const H5AC_class_t H5AC_FHEAP_IBLOCK[1] = {{ H5AC_FHEAP_IBLOCK_ID, @@ -114,6 +104,16 @@ const H5AC_class_t H5AC_FHEAP_IBLOCK[1] = {{ (H5AC_size_func_t)H5HF_cache_iblock_size, }}; +/* H5HF direct block inherits cache-like properties from H5AC */ +const H5AC_class_t H5AC_FHEAP_DBLOCK[1] = {{ + H5AC_FHEAP_DBLOCK_ID, + (H5AC_load_func_t)H5HF_cache_dblock_load, + (H5AC_flush_func_t)H5HF_cache_dblock_flush, + (H5AC_dest_func_t)H5HF_cache_dblock_dest, + (H5AC_clear_func_t)H5HF_cache_dblock_clear, + (H5AC_size_func_t)H5HF_cache_dblock_size, +}}; + /*****************************/ /* Library Private Variables */ @@ -257,7 +257,8 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud size_t size; /* Header size */ uint8_t *buf = NULL; /* Temporary buffer */ const uint8_t *p; /* Pointer into raw data buffer */ - uint32_t metadata_chksum; /* Metadata checksum value */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + uint32_t computed_chksum; /* Computed metadata checksum value */ uint8_t heap_flags; /* Status flags for heap */ H5HF_hdr_t *ret_value; /* Return value */ @@ -277,7 +278,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* Set the heap header's address */ hdr->heap_addr = addr; - /* Compute the size of the fractal heap header on disk */ + /* Compute the 'base' size of the fractal heap header on disk */ size = H5HF_HEADER_SIZE(hdr); /* Allocate temporary buffer */ @@ -304,12 +305,6 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); if(*p++ != 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unknown metadata flag in fractal heap header") - /* Metadata checksum (unused, currently) */ - UINT32DECODE(p, metadata_chksum); -/* XXX: Verify checksum */ - if(metadata_chksum != 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap header") - /* General heap information */ UINT16DECODE(p, hdr->id_len); /* Heap ID length */ UINT16DECODE(p, hdr->filter_len); /* I/O filters' encoded length */ @@ -318,6 +313,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* (bit 0: "huge" object IDs have wrapped) */ heap_flags = *p++; hdr->huge_ids_wrapped = heap_flags & H5HF_HDR_FLAGS_HUGE_ID_WRAPPED; + hdr->checksum_dblocks = heap_flags & H5HF_HDR_FLAGS_CHECKSUM_DBLOCKS; /* "Huge" object information */ UINT32DECODE(p, hdr->max_man_size); /* Max. size of "managed" objects */ @@ -343,29 +339,37 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, NULL, "unable to encode managed obj. doubling table info") /* Sanity check */ - HDassert((size_t)(p - buf) == size); + /* (allow for checksum not decoded yet) */ + HDassert((size_t)(p - buf) == (size - H5HF_SIZEOF_CHKSUM)); /* Check for I/O filter information to decode */ if(hdr->filter_len > 0) { - size_t filter_info_size; /* Size of filter information */ - H5O_pline_t *pline; /* Pipeline information from the header on disk */ + size_t filter_info_off; /* Offset in header of filter information */ + size_t filter_info_size; /* Size of filter information */ + H5O_pline_t *pline; /* Pipeline information from the header on disk */ + + /* Compute the offset of the filter info in the header */ + filter_info_off = p - buf; /* Compute the size of the extra filter information */ filter_info_size = hdr->sizeof_size /* Size of size for filtered root direct block */ + 4 /* Size of filter mask for filtered root direct block */ + hdr->filter_len; /* Size of encoded I/O filter info */ - /* Check if the current buffer can be re-used, or needs to be re-sized */ - if(filter_info_size > size) { - if((buf = H5FL_BLK_REALLOC(header_block, buf, filter_info_size)) == NULL) - HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't allocate space to decode I/O pipeline filters") - } /* end if */ + /* Compute the heap header's size */ + hdr->heap_size = size + filter_info_size; + + /* Re-size current buffer */ + if((buf = H5FL_BLK_REALLOC(header_block, buf, hdr->heap_size)) == NULL) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't allocate space to decode I/O pipeline filters") /* Read in I/O filter information */ - if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, (addr + size), filter_info_size, dxpl_id, buf) < 0) + /* (and the checksum) */ + if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, (addr + filter_info_off), (filter_info_size + H5HF_SIZEOF_CHKSUM), dxpl_id, (buf + filter_info_off)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header's I/O pipeline filter info") - p = buf; + /* Point at correct offset in header for the filter information */ + p = buf + filter_info_off; /* Decode the size of a filtered root direct block */ H5F_DECODE_LENGTH(f, p, hdr->pline_root_direct_size); @@ -376,6 +380,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* Decode I/O filter information */ if(NULL == (pline = H5O_decode(hdr->f, p, H5O_PLINE_ID))) HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't decode I/O pipeline filters") + p += hdr->filter_len; /* Copy the information into the header's I/O pipeline structure */ if(NULL == H5O_copy(H5O_PLINE_ID, pline, &(hdr->pline))) @@ -383,14 +388,25 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* Release the space allocated for the I/O pipeline filters */ H5O_free(H5O_PLINE_ID, pline); - - /* Compute the heap header's size */ - hdr->heap_size = size + filter_info_size; } /* end if */ else /* Set the heap header's size */ hdr->heap_size = size; + /* Metadata checksum */ + UINT32DECODE(p, stored_chksum); + + /* Sanity check */ + HDassert((size_t)(p - buf) == hdr->heap_size); + + /* Compute checksum on entire header */ + /* (including the filter information, if present) */ + computed_chksum = H5_fletcher32(buf, (hdr->heap_size - H5HF_SIZEOF_CHKSUM)); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap header") + /* Finish initialization of heap header */ if(H5HF_hdr_finish_init(hdr) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "can't finish initializing shared fractal heap header") @@ -444,6 +460,7 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a uint8_t *p; /* Pointer into raw data buffer */ size_t size; /* Header size on disk */ uint8_t heap_flags; /* Status flags for heap */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ /* Sanity check */ HDassert(hdr->dirty); @@ -468,11 +485,6 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a /* XXX: Set this? */ *p++ = 0; - /* Metadata checksum */ -/* XXX: Set this! (After all the metadata is in the buffer) */ - HDmemset(p, 0, (size_t)4); - p += 4; - /* General heap information */ UINT16ENCODE(p, hdr->id_len); /* Heap ID length */ UINT16ENCODE(p, hdr->filter_len); /* I/O filters' encoded length */ @@ -481,6 +493,7 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a /* (bit 0: "huge" object IDs have wrapped) */ heap_flags = 0; heap_flags |= (hdr->huge_ids_wrapped ? H5HF_HDR_FLAGS_HUGE_ID_WRAPPED : 0); + heap_flags |= (hdr->checksum_dblocks ? H5HF_HDR_FLAGS_CHECKSUM_DBLOCKS : 0); *p++ = heap_flags; /* "Huge" object information */ @@ -520,6 +533,12 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a p += hdr->filter_len; } /* end if */ + /* Compute metadata checksum */ + metadata_chksum = H5_fletcher32(buf, hdr->heap_size - H5HF_SIZEOF_CHKSUM); + + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); + /* Write the heap header. */ HDassert((size_t)(p - buf) == size); if(H5F_block_write(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0) @@ -649,354 +668,6 @@ H5HF_cache_hdr_size(const H5F_t UNUSED *f, const H5HF_hdr_t *hdr, size_t *size_p /*------------------------------------------------------------------------- - * Function: H5HF_cache_dblock_load - * - * Purpose: Loads a fractal heap direct block from the disk. - * - * Return: Success: Pointer to a new fractal heap direct block - * - * Failure: NULL - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 27 2006 - * - *------------------------------------------------------------------------- - */ -static H5HF_direct_t * -H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, void *_par_info) -{ - const size_t *size = (const size_t *)_size; /* Size of block */ - H5HF_hdr_t *hdr; /* Shared fractal heap information */ - H5HF_parent_t *par_info = (H5HF_parent_t *)_par_info; /* Pointer to parent information */ - H5HF_direct_t *dblock = NULL; /* Direct block info */ - const uint8_t *p; /* Pointer into raw data buffer */ - haddr_t heap_addr; /* Address of heap header in the file */ - uint32_t metadata_chksum; /* Metadata checksum value */ - H5HF_direct_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_load) - - /* Check arguments */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); - HDassert(par_info); - - /* Allocate space for the fractal heap direct block */ - if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t)); - - /* Get the pointer to the shared heap header */ - hdr = par_info->hdr; - - /* Share common heap information */ - dblock->hdr = hdr; - if(H5HF_hdr_incr(hdr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") - -#ifdef LATER - /* Check for I/O filters on this heap */ - if(hdr->filter_len > 0) { -HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC); -HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "I/O filters not supported yet") - } /* end if */ -#endif /* LATER */ - - /* Set block's internal information */ - dblock->size = *size; - dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size); - - /* Allocate block buffer */ -/* XXX: Change to using free-list factories */ - if((dblock->blk = H5FL_BLK_MALLOC(direct_block, (size_t)dblock->size)) == NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - - /* Read direct block from disk */ - if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, (size_t)dblock->size, dxpl_id, dblock->blk) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block") - - p = dblock->blk; - - /* Magic number */ - if(HDmemcmp(p, H5HF_DBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC)) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block signature") - p += H5HF_SIZEOF_MAGIC; - - /* Version */ - if(*p++ != H5HF_DBLOCK_VERSION) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block version") - - /* Metadata flags (unused, currently) */ -/* XXX: Plan out metadata flags (including "read-only duplicate" feature) */ - if(*p++ != 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unknown metadata flag in fractal heap direct block") - - /* Metadata checksum (unused, currently) */ - UINT32DECODE(p, metadata_chksum); -/* XXX: Verify checksum */ - if(metadata_chksum != 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap direct block") - - /* Address of heap that owns this block (skip) */ - H5F_addr_decode(f, &p, &heap_addr); - if(H5F_addr_ne(heap_addr, hdr->heap_addr)) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block") - - /* Address of parent block */ - dblock->parent = par_info->iblock; - dblock->par_entry = par_info->entry; - if(dblock->parent) { - /* Share parent block */ - if(H5HF_iblock_incr(dblock->parent) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block") - } /* end if */ - - /* Offset of heap within the heap's address space */ - UINT64DECODE_VAR(p, dblock->block_off, hdr->heap_off_size); - - /* Set return value */ - ret_value = dblock; - -done: - if(!ret_value && dblock) - (void)H5HF_cache_dblock_dest(f, dblock); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_cache_dblock_load() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_cache_dblock_flush - * - * Purpose: Flushes a dirty fractal heap direct block to disk. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 27 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_direct_t *dblock) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_flush) - - /* check arguments */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); - HDassert(dblock); - - if(dblock->cache_info.is_dirty) { - H5HF_hdr_t *hdr; /* Shared fractal heap information */ - void *write_buf; /* Pointer to buffer to write out */ - size_t write_size; /* Size of buffer to write out */ - uint8_t *p; /* Pointer into raw data buffer */ - - /* Get the pointer to the shared heap header */ - hdr = dblock->hdr; - - HDassert(dblock->blk); - p = dblock->blk; - - /* Magic number */ - HDmemcpy(p, H5HF_DBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC); - p += H5HF_SIZEOF_MAGIC; - - /* Version # */ - *p++ = H5HF_DBLOCK_VERSION; - - /* Metadata status flags */ -/* XXX: Set this? */ - *p++ = 0; - - /* Metadata checksum */ -/* XXX: Set this! (After all the metadata is in the buffer) */ - HDmemset(p, 0, (size_t)4); - p += 4; - - /* Address of heap header for heap which owns this block */ - H5F_addr_encode(f, &p, hdr->heap_addr); - - /* Offset of block in heap */ - UINT64ENCODE_VAR(p, dblock->block_off, hdr->heap_off_size); - - /* Sanity check */ - HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)); - -#ifdef LATER - /* Check for I/O filters on this heap */ - if(hdr->filter_len > 0) { - H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */ - size_t nbytes; /* Number of bytes used */ - unsigned filter_mask; /* Filter mask for block */ - - /* Allocate buffer to perform I/O filtering on */ - write_size = dblock->size; - if(NULL == (write_buf = H5MM_malloc(write_size))) - HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer") - HDmemcpy(write_buf, dblock->blk, write_size); - - /* Push direct block data through I/O filter pipeline */ - nbytes = write_size; - if(H5Z_pipeline(&(hdr->pline), 0, &filter_mask, H5Z_ENABLE_EDC, - filter_cb, &nbytes, &write_size, &write_buf) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "output pipeline failed") -HDfprintf(stderr, "%s: nbytes = %Zu, write_size = %Zu, write_buf = %p\n", FUNC, nbytes, write_size, write_buf); -HDfprintf(stderr, "%s: dblock->size = %Zu, dblock->blk = %p\n", FUNC, dblock->size, dblock->blk); - -HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC); -HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "I/O filters not supported yet") - } /* end if */ - else { -#endif /* LATER */ - write_buf = dblock->blk; - write_size = dblock->size; -#ifdef LATER - } /* end else */ -#endif /* LATER */ - - /* Write the direct block */ - if(H5F_block_write(f, H5FD_MEM_FHEAP_DBLOCK, addr, write_size, dxpl_id, write_buf) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap direct block to disk") - - /* Release the write buffer, if it was allocated */ - if(write_buf != dblock->blk) - H5MM_xfree(write_buf); - - dblock->cache_info.is_dirty = FALSE; - } /* end if */ - - if(destroy) - if(H5HF_cache_dblock_dest(f, dblock) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap direct block") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5HF_cache_dblock_flush() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_cache_dblock_dest - * - * Purpose: Destroys a fractal heap direct block in memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 27 2006 - * - *------------------------------------------------------------------------- - */ -/* ARGSUSED */ -herr_t -H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_dest) - - /* - * Check arguments. - */ - HDassert(dblock); -#ifdef QAK -HDfprintf(stderr, "%s: Destroying direct block, dblock = %p\n", FUNC, dblock); -#endif /* QAK */ - - /* Decrement reference count on shared fractal heap info */ - HDassert(dblock->hdr); - if(H5HF_hdr_decr(dblock->hdr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header") - if(dblock->parent) - if(H5HF_iblock_decr(dblock->parent) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") - - /* Free block's buffer */ - H5FL_BLK_FREE(direct_block, dblock->blk); - - /* Free fractal heap direct block info */ - H5FL_FREE(H5HF_direct_t, dblock); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_cache_dblock_dest() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_cache_dblock_clear - * - * Purpose: Mark a fractal heap direct block in memory as non-dirty. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 27 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HF_cache_dblock_clear(H5F_t *f, H5HF_direct_t *dblock, hbool_t destroy) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_clear) - - /* - * Check arguments. - */ - HDassert(dblock); - - /* Reset the dirty flag. */ - dblock->cache_info.is_dirty = FALSE; - - if(destroy) - if(H5HF_cache_dblock_dest(f, dblock) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap direct block") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_cache_dblock_clear() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_cache_dblock_size - * - * Purpose: Compute the size in bytes of a fractal heap direct block - * on disk, and return it in *size_ptr. On failure, - * the value of *size_ptr is undefined. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 24 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HF_cache_dblock_size(const H5F_t UNUSED *f, const H5HF_direct_t *dblock, size_t *size_ptr) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_dblock_size) - - /* check arguments */ - HDassert(dblock); - HDassert(size_ptr); - - /* Set size value */ - *size_ptr = dblock->size; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_cache_dblock_size() */ - - -/*------------------------------------------------------------------------- * Function: H5HF_cache_iblock_load * * Purpose: Loads a fractal heap indirect block from the disk. @@ -1021,7 +692,8 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows uint8_t *buf = NULL; /* Temporary buffer */ const uint8_t *p; /* Pointer into raw data buffer */ haddr_t heap_addr; /* Address of heap header in the file */ - uint32_t metadata_chksum; /* Metadata checksum value */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + uint32_t computed_chksum; /* Computed metadata checksum value */ size_t u; /* Local index variable */ H5HF_indirect_t *ret_value; /* Return value */ @@ -1082,12 +754,6 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); if(*p++ != 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unknown metadata flag in fractal heap direct block") - /* Metadata checksum (unused, currently) */ - UINT32DECODE(p, metadata_chksum); -/* XXX: Verify checksum */ - if(metadata_chksum != 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap direct block") - /* Address of heap that owns this block */ H5F_addr_decode(f, &p, &heap_addr); if(H5F_addr_ne(heap_addr, hdr->heap_addr)) @@ -1164,6 +830,22 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add #endif /* QAK */ } /* end for */ + /* Sanity check */ + HDassert(iblock->nchildren); /* indirect blocks w/no children should have been deleted */ + + /* Metadata checksum */ + UINT32DECODE(p, stored_chksum); + + /* Sanity check */ + HDassert((size_t)(p - buf) == iblock->size); + + /* Compute checksum on indirect block */ + computed_chksum = H5_fletcher32(buf, (iblock->size - H5HF_SIZEOF_CHKSUM)); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap indirect block") + /* Check if we have any indirect block children */ if(iblock->nrows > hdr->man_dtable.max_direct_rows) { unsigned indir_rows; /* Number of indirect rows in this indirect block */ @@ -1178,10 +860,6 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add else iblock->child_iblocks = NULL; - /* Sanity checks */ - HDassert((size_t)(p - buf) == iblock->size); - HDassert(iblock->nchildren); /* indirect blocks w/no children should have been deleted */ - /* Set return value */ ret_value = iblock; @@ -1233,6 +911,7 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC unsigned nchildren = 0; /* Track # of children */ unsigned max_child = 0; /* Track max. child entry used */ #endif /* NDEBUG */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ size_t u; /* Local index variable */ /* Get the pointer to the shared heap header */ @@ -1262,11 +941,6 @@ HDfprintf(stderr, "%s: hdr->man_dtable.cparam.width = %u\n", FUNC, hdr->man_dtab /* XXX: Set this? */ *p++ = 0; - /* Metadata checksum */ -/* XXX: Set this! (After all the metadata is in the buffer) */ - HDmemset(p, 0, (size_t)4); - p += 4; - /* Address of heap header for heap which owns this block */ H5F_addr_encode(f, &p, hdr->heap_addr); @@ -1316,6 +990,12 @@ HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->f #endif /* NDEBUG */ } /* end for */ + /* Compute checksum */ + metadata_chksum = H5_fletcher32(buf, iblock->size - H5HF_SIZEOF_CHKSUM); + + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); + /* Sanity check */ HDassert((size_t)(p - buf) == iblock->size); #ifndef NDEBUG @@ -1464,3 +1144,376 @@ H5HF_cache_iblock_size(const H5F_t UNUSED *f, const H5HF_indirect_t *iblock, siz FUNC_LEAVE_NOAPI(SUCCEED) } /* H5HF_cache_iblock_size() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_cache_dblock_load + * + * Purpose: Loads a fractal heap direct block from the disk. + * + * Return: Success: Pointer to a new fractal heap direct block + * + * Failure: NULL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 27 2006 + * + *------------------------------------------------------------------------- + */ +static H5HF_direct_t * +H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, void *_par_info) +{ + const size_t *size = (const size_t *)_size; /* Size of block */ + H5HF_hdr_t *hdr; /* Shared fractal heap information */ + H5HF_parent_t *par_info = (H5HF_parent_t *)_par_info; /* Pointer to parent information */ + H5HF_direct_t *dblock = NULL; /* Direct block info */ + const uint8_t *p; /* Pointer into raw data buffer */ + haddr_t heap_addr; /* Address of heap header in the file */ + H5HF_direct_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_load) + + /* Check arguments */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(par_info); + + /* Allocate space for the fractal heap direct block */ + if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t)); + + /* Get the pointer to the shared heap header */ + hdr = par_info->hdr; + + /* Share common heap information */ + dblock->hdr = hdr; + if(H5HF_hdr_incr(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") + +#ifdef LATER + /* Check for I/O filters on this heap */ + if(hdr->filter_len > 0) { +HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC); +HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "I/O filters not supported yet") + } /* end if */ +#endif /* LATER */ + + /* Set block's internal information */ + dblock->size = *size; + dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size); + + /* Allocate block buffer */ +/* XXX: Change to using free-list factories */ + if((dblock->blk = H5FL_BLK_MALLOC(direct_block, (size_t)dblock->size)) == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* Read direct block from disk */ + if(H5F_block_read(f, H5FD_MEM_FHEAP_DBLOCK, addr, (size_t)dblock->size, dxpl_id, dblock->blk) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap direct block") + + p = dblock->blk; + + /* Magic number */ + if(HDmemcmp(p, H5HF_DBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block signature") + p += H5HF_SIZEOF_MAGIC; + + /* Version */ + if(*p++ != H5HF_DBLOCK_VERSION) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block version") + + /* Metadata flags (unused, currently) */ +/* XXX: Plan out metadata flags (including "read-only duplicate" feature) */ + if(*p++ != 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unknown metadata flag in fractal heap direct block") + + /* Address of heap that owns this block (just for file integrity checks) */ + H5F_addr_decode(f, &p, &heap_addr); + if(H5F_addr_ne(heap_addr, hdr->heap_addr)) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block") + + /* Address of parent block */ + dblock->parent = par_info->iblock; + dblock->par_entry = par_info->entry; + if(dblock->parent) { + /* Share parent block */ + if(H5HF_iblock_incr(dblock->parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block") + } /* end if */ + + /* Offset of heap within the heap's address space */ + UINT64DECODE_VAR(p, dblock->block_off, hdr->heap_off_size); + + /* Encode checksum on direct block, if requested */ + if(hdr->checksum_dblocks) { + uint32_t stored_chksum; /* Metadata checksum value */ + uint32_t computed_chksum; /* Computed metadata checksum value */ + + /* Metadata checksum */ + UINT32DECODE(p, stored_chksum); + + /* Reset checksum field, for computing the checksum */ + /* (Casting away const OK - QAK) */ + HDmemset((uint8_t *)p - H5HF_SIZEOF_CHKSUM, 0, (size_t)H5HF_SIZEOF_CHKSUM); + + /* Compute checksum on entire direct block */ + computed_chksum = H5_fletcher32(dblock->blk, dblock->size); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap direct block") + } /* end if */ + + /* Sanity check */ + HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)); + + /* Set return value */ + ret_value = dblock; + +done: + if(!ret_value && dblock) + (void)H5HF_cache_dblock_dest(f, dblock); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_cache_dblock_load() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_cache_dblock_flush + * + * Purpose: Flushes a dirty fractal heap direct block to disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 27 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_direct_t *dblock) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_flush) + + /* check arguments */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(dblock); + + if(dblock->cache_info.is_dirty) { + H5HF_hdr_t *hdr; /* Shared fractal heap information */ + void *write_buf; /* Pointer to buffer to write out */ + size_t write_size; /* Size of buffer to write out */ + uint8_t *p; /* Pointer into raw data buffer */ + + /* Get the pointer to the shared heap header */ + hdr = dblock->hdr; + + HDassert(dblock->blk); + p = dblock->blk; + + /* Magic number */ + HDmemcpy(p, H5HF_DBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC); + p += H5HF_SIZEOF_MAGIC; + + /* Version # */ + *p++ = H5HF_DBLOCK_VERSION; + + /* Metadata status flags */ +/* XXX: Set this? */ + *p++ = 0; + + /* Address of heap header for heap which owns this block */ + H5F_addr_encode(f, &p, hdr->heap_addr); + + /* Offset of block in heap */ + UINT64ENCODE_VAR(p, dblock->block_off, hdr->heap_off_size); + + /* Metadata checksum */ + if(hdr->checksum_dblocks) { + uint32_t metadata_chksum; /* Computed metadata checksum value */ + + /* Clear the checksum field, to compute the checksum */ + HDmemset(p, 0, (size_t)H5HF_SIZEOF_CHKSUM); + + /* Compute checksum on entire direct block */ + metadata_chksum = H5_fletcher32(dblock->blk, dblock->size); + + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); + } /* end if */ + + /* Sanity check */ + HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)); + +#ifdef LATER + /* Check for I/O filters on this heap */ + if(hdr->filter_len > 0) { + H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */ + size_t nbytes; /* Number of bytes used */ + unsigned filter_mask; /* Filter mask for block */ + + /* Allocate buffer to perform I/O filtering on */ + write_size = dblock->size; + if(NULL == (write_buf = H5MM_malloc(write_size))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer") + HDmemcpy(write_buf, dblock->blk, write_size); + + /* Push direct block data through I/O filter pipeline */ + nbytes = write_size; + if(H5Z_pipeline(&(hdr->pline), 0, &filter_mask, H5Z_ENABLE_EDC, + filter_cb, &nbytes, &write_size, &write_buf) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "output pipeline failed") +HDfprintf(stderr, "%s: nbytes = %Zu, write_size = %Zu, write_buf = %p\n", FUNC, nbytes, write_size, write_buf); +HDfprintf(stderr, "%s: dblock->size = %Zu, dblock->blk = %p\n", FUNC, dblock->size, dblock->blk); + +HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC); +HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "I/O filters not supported yet") + } /* end if */ + else { +#endif /* LATER */ + write_buf = dblock->blk; + write_size = dblock->size; +#ifdef LATER + } /* end else */ +#endif /* LATER */ + + /* Write the direct block */ + if(H5F_block_write(f, H5FD_MEM_FHEAP_DBLOCK, addr, write_size, dxpl_id, write_buf) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap direct block to disk") + + /* Release the write buffer, if it was allocated */ + if(write_buf != dblock->blk) + H5MM_xfree(write_buf); + + dblock->cache_info.is_dirty = FALSE; + } /* end if */ + + if(destroy) + if(H5HF_cache_dblock_dest(f, dblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap direct block") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_cache_dblock_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_cache_dblock_dest + * + * Purpose: Destroys a fractal heap direct block in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 27 2006 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +herr_t +H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_dest) + + /* + * Check arguments. + */ + HDassert(dblock); +#ifdef QAK +HDfprintf(stderr, "%s: Destroying direct block, dblock = %p\n", FUNC, dblock); +#endif /* QAK */ + + /* Decrement reference count on shared fractal heap info */ + HDassert(dblock->hdr); + if(H5HF_hdr_decr(dblock->hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header") + if(dblock->parent) + if(H5HF_iblock_decr(dblock->parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + + /* Free block's buffer */ + H5FL_BLK_FREE(direct_block, dblock->blk); + + /* Free fractal heap direct block info */ + H5FL_FREE(H5HF_direct_t, dblock); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_cache_dblock_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_cache_dblock_clear + * + * Purpose: Mark a fractal heap direct block in memory as non-dirty. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 27 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_cache_dblock_clear(H5F_t *f, H5HF_direct_t *dblock, hbool_t destroy) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_clear) + + /* + * Check arguments. + */ + HDassert(dblock); + + /* Reset the dirty flag. */ + dblock->cache_info.is_dirty = FALSE; + + if(destroy) + if(H5HF_cache_dblock_dest(f, dblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap direct block") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_cache_dblock_clear() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_cache_dblock_size + * + * Purpose: Compute the size in bytes of a fractal heap direct block + * on disk, and return it in *size_ptr. On failure, + * the value of *size_ptr is undefined. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 24 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_cache_dblock_size(const H5F_t UNUSED *f, const H5HF_direct_t *dblock, size_t *size_ptr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_dblock_size) + + /* check arguments */ + HDassert(dblock); + HDassert(size_ptr); + + /* Set size value */ + *size_ptr = dblock->size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_cache_dblock_size() */ + diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index e239aeb..5b9022c 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -393,6 +393,7 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) /* Set the creation parameters for the heap */ hdr->max_man_size = cparam->max_man_size; + hdr->checksum_dblocks = cparam->checksum_dblocks; HDmemcpy(&(hdr->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t)); /* Set root table address to indicate that the heap is empty currently */ diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index bc9e23a..14a9baa 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -49,12 +49,15 @@ #define H5HF_DBLOCK_MAGIC "FHDB" /* Direct block */ #define H5HF_IBLOCK_MAGIC "FHIB" /* Indirect block */ +/* Size of checksum information (on disk) */ +#define H5HF_SIZEOF_CHKSUM 4 + /* "Standard" size of prefix information for fractal heap metadata */ -#define H5HF_METADATA_PREFIX_SIZE ( \ +#define H5HF_METADATA_PREFIX_SIZE(c) ( \ 4 /* Signature */ \ + 1 /* Version */ \ + 1 /* Metadata flags */ \ - + 4 /* Metadata checksum */ \ + + ((c) ? H5HF_SIZEOF_CHKSUM : 0) /* Metadata checksum */ \ ) /* Size of doubling-table information */ @@ -70,6 +73,7 @@ /* Flags for status byte */ #define H5HF_HDR_FLAGS_HUGE_ID_WRAPPED 0x01 +#define H5HF_HDR_FLAGS_CHECKSUM_DBLOCKS 0x02 /* Size of the fractal heap header on disk */ /* (this is the fixed-len portion, the variable-len I/O filter information @@ -77,7 +81,7 @@ */ #define H5HF_HEADER_SIZE(h) ( \ /* General metadata fields */ \ - H5HF_METADATA_PREFIX_SIZE \ + H5HF_METADATA_PREFIX_SIZE(TRUE) \ \ /* Fractal Heap Header specific fields */ \ \ @@ -112,7 +116,7 @@ /* Size of overhead for a direct block */ #define H5HF_MAN_ABS_DIRECT_OVERHEAD(h) ( \ /* General metadata fields */ \ - H5HF_METADATA_PREFIX_SIZE \ + H5HF_METADATA_PREFIX_SIZE(h->checksum_dblocks) \ \ /* Fractal heap managed, absolutely mapped direct block specific fields */ \ + (h)->sizeof_addr /* File address of heap owning the block */ \ @@ -129,7 +133,7 @@ /* Size of managed indirect block */ #define H5HF_MAN_INDIRECT_SIZE(h, i) ( \ /* General metadata fields */ \ - H5HF_METADATA_PREFIX_SIZE \ + H5HF_METADATA_PREFIX_SIZE(TRUE) \ \ /* Fractal heap managed, absolutely mapped indirect block specific fields */ \ + (h)->sizeof_addr /* File address of heap owning the block */ \ @@ -308,6 +312,7 @@ typedef struct H5HF_hdr_t { hbool_t debug_objs; /* Is the heap storing objects in 'debug' format */ hbool_t write_once; /* Is heap being written in "write once" mode? */ hbool_t huge_ids_wrapped; /* Have "huge" object IDs wrapped around? */ + hbool_t checksum_dblocks; /* Should the direct blocks in the heap be checksummed? */ /* Doubling table information (partially stored in header) */ /* (Partially set by user, partially derived/updated internally) */ @@ -475,12 +480,12 @@ typedef struct { /* H5HF header inherits cache-like properties from H5AC */ H5_DLLVAR const H5AC_class_t H5AC_FHEAP_HDR[1]; -/* H5HF direct block inherits cache-like properties from H5AC */ -H5_DLLVAR const H5AC_class_t H5AC_FHEAP_DBLOCK[1]; - /* H5HF indirect block inherits cache-like properties from H5AC */ H5_DLLVAR const H5AC_class_t H5AC_FHEAP_IBLOCK[1]; +/* H5HF direct block inherits cache-like properties from H5AC */ +H5_DLLVAR const H5AC_class_t H5AC_FHEAP_DBLOCK[1]; + /* The v2 B-tree class for tracking indirectly accessed 'huge' objects */ H5_DLLVAR const H5B2_class_t H5HF_BT2_INDIR[1]; @@ -508,12 +513,6 @@ H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_INDIRECT[1]; /* Declare a free list to manage the H5HF_hdr_t struct */ H5FL_EXTERN(H5HF_hdr_t); -/* Declare a free list to manage the H5HF_direct_t struct */ -H5FL_EXTERN(H5HF_direct_t); - -/* Declare a free list to manage heap direct block data to/from disk */ -H5FL_BLK_EXTERN(direct_block); - /* Declare a free list to manage the H5HF_indirect_t struct */ H5FL_EXTERN(H5HF_indirect_t); @@ -527,18 +526,17 @@ H5FL_SEQ_EXTERN(H5HF_indirect_filt_ent_t); typedef H5HF_indirect_t *H5HF_indirect_ptr_t; H5FL_SEQ_EXTERN(H5HF_indirect_ptr_t); +/* Declare a free list to manage the H5HF_direct_t struct */ +H5FL_EXTERN(H5HF_direct_t); + +/* Declare a free list to manage heap direct block data to/from disk */ +H5FL_BLK_EXTERN(direct_block); + /******************************/ /* Package Private Prototypes */ /******************************/ -/* Routines for managing shared fractal heap header */ -H5_DLL H5HF_hdr_t * H5HF_hdr_alloc(H5F_t *f); -H5_DLL haddr_t H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam); -H5_DLL herr_t H5HF_hdr_finish_init_phase1(H5HF_hdr_t *hdr); -H5_DLL herr_t H5HF_hdr_finish_init_phase2(H5HF_hdr_t *hdr); -H5_DLL herr_t H5HF_hdr_finish_init(H5HF_hdr_t *hdr); - /* Doubling table routines */ H5_DLL herr_t H5HF_dtable_init(H5HF_dtable_t *dtable); H5_DLL herr_t H5HF_dtable_dest(H5HF_dtable_t *dtable); @@ -550,6 +548,11 @@ H5_DLL hsize_t H5HF_dtable_span_size(const H5HF_dtable_t *dtable, unsigned start unsigned start_col, unsigned num_entries); /* Heap header routines */ +H5_DLL H5HF_hdr_t * H5HF_hdr_alloc(H5F_t *f); +H5_DLL haddr_t H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam); +H5_DLL herr_t H5HF_hdr_finish_init_phase1(H5HF_hdr_t *hdr); +H5_DLL herr_t H5HF_hdr_finish_init_phase2(H5HF_hdr_t *hdr); +H5_DLL herr_t H5HF_hdr_finish_init(H5HF_hdr_t *hdr); H5_DLL herr_t H5HF_hdr_incr(H5HF_hdr_t *hdr); H5_DLL herr_t H5HF_hdr_decr(H5HF_hdr_t *hdr); H5_DLL herr_t H5HF_hdr_dirty(H5HF_hdr_t *hdr); diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h index 20415c1..5e25a58f 100644 --- a/src/H5HFprivate.h +++ b/src/H5HFprivate.h @@ -62,6 +62,7 @@ typedef struct H5HF_dtable_cparam_t { /* Fractal heap creation parameters */ typedef struct H5HF_create_t { H5HF_dtable_cparam_t managed;/* Mapped object doubling-table creation parameters */ + hbool_t checksum_dblocks; /* Whether the direct blocks should be checksummed */ uint32_t max_man_size; /* Max. size of object to manage in doubling table */ /* (i.e. min. size of object to store standalone) */ uint16_t id_len; /* Length of IDs to use for heap objects */ diff --git a/test/fheap.c b/test/fheap.c index 721ad89..209a2a0 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -40,6 +40,7 @@ /* "Small" heap creation parameters */ #define SMALL_DBLOCK_OVERHEAD 22 /* Overhead for direct blocks */ +#define SMALL_CHECKSUM_DBLOCKS TRUE /* Whether to checksum direct blocks */ #define SMALL_MAN_WIDTH 4 /* Managed obj. table width */ #define SMALL_MAN_START_BLOCK_SIZE 512 /* Managed obj. starting block size */ #define SMALL_MAN_MAX_DIRECT_SIZE (64 * 1024) /* Managed obj. max. direct block size */ @@ -49,7 +50,8 @@ #define SMALL_STAND_SIZE (SMALL_MAN_MAX_DIRECT_SIZE - SMALL_DBLOCK_OVERHEAD) /* Standalone obj. min. size */ /* "Large" heap creation parameters */ -#define LARGE_DBLOCK_OVERHEAD 26 /* Overhead for direct blocks */ +#define LARGE_DBLOCK_OVERHEAD 22 /* Overhead for direct blocks */ +#define LARGE_CHECKSUM_DBLOCKS FALSE /* Whether to checksum direct blocks */ #define LARGE_MAN_WIDTH 32 /* Managed obj. table width */ #define LARGE_MAN_START_BLOCK_SIZE 4096 /* Managed obj. starting block size */ #define LARGE_MAN_MAX_DIRECT_SIZE (1024 * 1024) /* Managed obj. max. direct block size */ @@ -113,7 +115,7 @@ typedef struct fheap_test_param_t { fheap_test_del_dir_t del_dir; /* Whether to delete objects forward or reverse */ fheap_test_del_drain_t drain_half; /* Whether to drain half of the objects & refill, when deleting objects */ fheap_test_fill_t fill; /* How to "bulk" fill heap blocks */ - unsigned actual_id_len; /* The actual length of heap IDs for a test */ + size_t actual_id_len; /* The actual length of heap IDs for a test */ } fheap_test_param_t; /* Heap state information */ @@ -178,6 +180,7 @@ init_small_cparam(H5HF_create_t *cparam) /* General parameters */ cparam->id_len = SMALL_ID_LEN; cparam->max_man_size = SMALL_STAND_SIZE; + cparam->checksum_dblocks = SMALL_CHECKSUM_DBLOCKS; /* Managed object doubling-table parameters */ cparam->managed.width = SMALL_MAN_WIDTH; @@ -214,6 +217,7 @@ init_large_cparam(H5HF_create_t *cparam) /* General parameters */ cparam->id_len = LARGE_ID_LEN; cparam->max_man_size = LARGE_STAND_SIZE; + cparam->checksum_dblocks = LARGE_CHECKSUM_DBLOCKS; /* Managed object doubling-table parameters */ cparam->managed.width = LARGE_MAN_WIDTH; @@ -2173,7 +2177,7 @@ test_id_limits(hid_t fapl, H5HF_create_t *cparam) /* Set an I/O filter for heap data */ deflate_level = 6; - if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &deflate_level) < 0) + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0) FAIL_STACK_ERROR /* Create absolute heap */ @@ -2449,7 +2453,7 @@ test_filtered_create(hid_t fapl, H5HF_create_t *cparam) /* Set an I/O filter for heap data */ deflate_level = 6; - if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &deflate_level) < 0) + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0) FAIL_STACK_ERROR /* Create absolute heap */ @@ -2587,14 +2591,14 @@ test_man_insert_weird(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa /* Attempt to insert 0-sized object into heap */ H5E_BEGIN_TRY { - ret = H5HF_insert(fh, dxpl, 0, shared_wobj_g, heap_id); + ret = H5HF_insert(fh, dxpl, (size_t)0, shared_wobj_g, heap_id); } H5E_END_TRY; if(ret >= 0) TEST_ERROR H5Eclear_stack(H5E_DEFAULT); /* Insert a 1-sized object into heap (should be a 'tiny' object) */ - if(add_obj(fh, dxpl, (size_t)10, 1, &state, NULL)) + if(add_obj(fh, dxpl, (size_t)10, (size_t)1, &state, NULL)) TEST_ERROR /* Check for closing & re-opening the heap */ @@ -12851,7 +12855,7 @@ test_filtered_huge(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam /* Set an I/O filter for heap data */ deflate_level = 6; - if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &deflate_level) < 0) + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0) FAIL_STACK_ERROR /* Adjust actual ID length, if asking for IDs that can directly access 'huge' objects */ @@ -14009,7 +14013,7 @@ test_filtered_man_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa /* Set an I/O filter for heap data */ deflate_level = 6; - if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &deflate_level) < 0) + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, (size_t)1, &deflate_level) < 0) FAIL_STACK_ERROR /* Perform common file & heap open operations */ |