diff options
Diffstat (limited to 'src/H5SMcache.c')
-rw-r--r-- | src/H5SMcache.c | 858 |
1 files changed, 469 insertions, 389 deletions
diff --git a/src/H5SMcache.c b/src/H5SMcache.c index 0a8921a..54c2b41 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -47,12 +47,6 @@ /* Local Macros */ /****************/ -/* Size of stack buffer for serialized tables */ -#define H5SM_TBL_BUF_SIZE 1024 - -/* Size of stack buffer for serialized list indices */ -#define H5SM_LST_BUF_SIZE 1024 - /******************/ /* Local Typedefs */ @@ -64,16 +58,29 @@ /********************/ /* Metadata cache (H5AC) callbacks */ -static H5SM_master_table_t *H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata); -static herr_t H5SM_table_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table); -static herr_t H5SM_table_dest(H5F_t *f, H5SM_master_table_t* table); -static herr_t H5SM_table_clear(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy); -static herr_t H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr); -static H5SM_list_t *H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata); -static herr_t H5SM_list_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list); -static herr_t H5SM_list_dest(H5F_t *f, H5SM_list_t* list); -static herr_t H5SM_list_clear(H5F_t *f, H5SM_list_t *list, hbool_t destroy); -static herr_t H5SM_list_size(const H5F_t *f, const H5SM_list_t H5_ATTR_UNUSED *list, size_t *size_ptr); +static herr_t H5SM__cache_table_get_load_size(const void *image_ptr, void *udata, + size_t *image_len, size_t *actual_len, + hbool_t *compressed_ptr, size_t *compressed_image_len_ptr); +static htri_t H5SM__cache_table_verify_chksum(const void *image_ptr, size_t len, void *udata_ptr); +static void *H5SM__cache_table_deserialize(const void *image, size_t len, + void *udata, hbool_t *dirty); +static herr_t H5SM__cache_table_image_len(const void *thing, size_t *image_len, + hbool_t *compressed_ptr, size_t *compressed_image_len_ptr); +static herr_t H5SM__cache_table_serialize(const H5F_t *f, void *image, + size_t len, void *thing); +static herr_t H5SM__cache_table_free_icr(void *thing); + +static herr_t H5SM__cache_list_get_load_size(const void *image_ptr, void *udata, + size_t *image_len, size_t *actual_len, + hbool_t *compressed_ptr, size_t *compressed_image_len_ptr); +static htri_t H5SM__cache_list_verify_chksum(const void *image_ptr, size_t len, void *udata_ptr); +static void *H5SM__cache_list_deserialize(const void *image, size_t len, + void *udata, hbool_t *dirty); +static herr_t H5SM__cache_list_image_len(const void *thing, size_t *image_len, + hbool_t *compressed_ptr, size_t *compressed_image_len_ptr); +static herr_t H5SM__cache_list_serialize(const H5F_t *f, void *image, + size_t len, void *thing); +static herr_t H5SM__cache_list_free_icr(void *thing); /*********************/ @@ -82,23 +89,37 @@ static herr_t H5SM_list_size(const H5F_t *f, const H5SM_list_t H5_ATTR_UNUSED *l /* H5SM inherits cache-like properties from H5AC */ const H5AC_class_t H5AC_SOHM_TABLE[1] = {{ - H5AC_SOHM_TABLE_ID, - (H5AC_load_func_t)H5SM_table_load, - (H5AC_flush_func_t)H5SM_table_flush, - (H5AC_dest_func_t)H5SM_table_dest, - (H5AC_clear_func_t)H5SM_table_clear, - (H5AC_notify_func_t)NULL, - (H5AC_size_func_t)H5SM_table_size, + H5AC_SOHM_TABLE_ID, /* Metadata client ID */ + "shared message table", /* Metadata client name (for debugging) */ + H5FD_MEM_SOHM_TABLE, /* File space memory type for client */ + H5AC__CLASS_NO_FLAGS_SET, /* Client class behavior flags */ + H5SM__cache_table_get_load_size, /* 'get_load_size' callback */ + H5SM__cache_table_verify_chksum, /* 'verify_chksum' callback */ + H5SM__cache_table_deserialize, /* 'deserialize' callback */ + H5SM__cache_table_image_len, /* 'image_len' callback */ + NULL, /* 'pre_serialize' callback */ + H5SM__cache_table_serialize, /* 'serialize' callback */ + NULL, /* 'notify' callback */ + H5SM__cache_table_free_icr, /* 'free_icr' callback */ + NULL, /* 'clear' callback */ + NULL, /* 'fsf_size' callback */ }}; const H5AC_class_t H5AC_SOHM_LIST[1] = {{ - H5AC_SOHM_LIST_ID, - (H5AC_load_func_t)H5SM_list_load, - (H5AC_flush_func_t)H5SM_list_flush, - (H5AC_dest_func_t)H5SM_list_dest, - (H5AC_clear_func_t)H5SM_list_clear, - (H5AC_notify_func_t)NULL, - (H5AC_size_func_t)H5SM_list_size, + H5AC_SOHM_LIST_ID, /* Metadata client ID */ + "shared message list", /* Metadata client name (for debugging) */ + H5FD_MEM_SOHM_TABLE, /* File space memory type for client */ + H5AC__CLASS_NO_FLAGS_SET, /* Client class behavior flags */ + H5SM__cache_list_get_load_size, /* 'get_load_size' callback */ + H5SM__cache_list_verify_chksum, /* 'verify_chksum' callback */ + H5SM__cache_list_deserialize, /* 'deserialize' callback */ + H5SM__cache_list_image_len, /* 'image_len' callback */ + NULL, /* 'pre_serialize' callback */ + H5SM__cache_list_serialize, /* 'serialize' callback */ + NULL, /* 'notify' callback */ + H5SM__cache_list_free_icr, /* 'free_icr' callback */ + NULL, /* 'clear' callback */ + NULL, /* 'fsf_size' callback */ }}; @@ -114,30 +135,119 @@ const H5AC_class_t H5AC_SOHM_LIST[1] = {{ /*------------------------------------------------------------------------- - * Function: H5SM_table_load + * Function: H5SM__cache_table_get_load_size() + * + * Purpose: Return the size of the master table of Shared Object Header + * Message indexes on disk. As this cache client doesn't use + * speculative reads, this value should be accurate. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: John Mainzer + * 7/28/14 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5SM__cache_table_get_load_size(const void *_image, void *_udata, + size_t *image_len, size_t *actual_len, + hbool_t H5_ATTR_UNUSED *compressed_ptr, size_t H5_ATTR_UNUSED *compressed_image_len_ptr) +{ + const uint8_t *image = (const uint8_t *)_image; /* Pointer into raw data buffer */ + const H5SM_table_cache_ud_t *udata = (const H5SM_table_cache_ud_t *)_udata; /* User data for callback */ + + FUNC_ENTER_STATIC_NOERR + + /* Check arguments */ + HDassert(udata); + HDassert(udata->f); + HDassert(image_len); + + if(image == NULL) + *image_len = H5SM_TABLE_SIZE(udata->f); + else { + HDassert(actual_len); + HDassert(*actual_len == *image_len); + } + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM__cache_table_get_load_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5SM__cache_table_verify_chksum + * + * Purpose: Verify the computed checksum of the data structure is the + * same as the stored chksum. + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Vailin Choi; Aug 2015 + * + *------------------------------------------------------------------------- + */ +htri_t +H5SM__cache_table_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSED *_udata) +{ + const uint8_t *image = (const uint8_t *)_image; /* Pointer into raw data buffer */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + uint32_t computed_chksum; /* Computed metadata checksum value */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Check arguments */ + HDassert(image); + + /* Get stored and computed checksums */ + H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + + if(stored_chksum != computed_chksum) + ret_value = FALSE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5SM__cache_table_verify_chksum() */ + + +/*------------------------------------------------------------------------- + * Function: H5SM__cache_table_deserialize * - * Purpose: Loads the master table of Shared Object Header Message - * indexes. + * Purpose: Given a buffer containing the on disk representation of the + * master table of Shared Object Header Message indexes, deserialize + * the table, copy the contents into a newly allocated instance of + * H5SM_master_table_t, and return a pointer to the new instance. * - * Return: Non-negative on success/Negative on failure + * Return: Success: Pointer to in core representation + * Failure: NULL * - * Programmer: James Laird - * November 6, 2006 + * Programmer: John Mainzer + * 7/28/14 * *------------------------------------------------------------------------- */ -static H5SM_master_table_t * -H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void H5_ATTR_UNUSED *udata) +static void * +H5SM__cache_table_deserialize(const void *_image, size_t len, void *_udata, + hbool_t H5_ATTR_UNUSED *dirty) { - H5SM_master_table_t *table = NULL; - H5WB_t *wb = NULL; /* Wrapped buffer for table data */ - uint8_t tbl_buf[H5SM_TBL_BUF_SIZE]; /* Buffer for table */ - uint8_t *buf; /* Reading buffer */ - const uint8_t *p; /* Pointer into input buffer */ - size_t u; /* Counter variable for index headers */ - H5SM_master_table_t *ret_value; + H5F_t *f; /* File pointer -- from user data */ + H5SM_master_table_t *table = NULL; /* Shared message table that we deserializing */ + H5SM_table_cache_ud_t *udata = (H5SM_table_cache_ud_t *)_udata; /* Pointer to user data */ + const uint8_t *image = (const uint8_t *)_image; /* Pointer into input buffer */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + size_t u; /* Counter variable for index headers */ + void * ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC + + /* Check arguments */ + HDassert(image); + HDassert(len > 0); + HDassert(udata); + HDassert(udata->f); + f = udata->f; + HDassert(dirty); /* Verify that we're reading version 0 of the table; this is the only * version defined so far. @@ -150,35 +260,18 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void H5_ATTR_UNUSED *udat /* Read number of indexes and version from file superblock */ table->num_indexes = H5F_SOHM_NINDEXES(f); - - HDassert(addr == H5F_SOHM_ADDR(f)); - HDassert(addr != HADDR_UNDEF); HDassert(table->num_indexes > 0); - /* Wrap the local buffer for serialized table info */ - if(NULL == (wb = H5WB_wrap(tbl_buf, sizeof(tbl_buf)))) - HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, NULL, "can't wrap buffer") - /* Compute the size of the SOHM table header on disk. This is the "table" * itself plus each index within the table */ table->table_size = H5SM_TABLE_SIZE(f); - - /* Get a pointer to a buffer that's large enough for serialized table */ - if(NULL == (buf = (uint8_t *)H5WB_actual(wb, table->table_size))) - HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer") - - /* Read and validate shared message table from disk */ - if(H5F_read_check_metadata(f, dxpl_id, H5FD_MEM_SOHM_TABLE, H5AC_SOHM_TABLE_ID, addr, table->table_size, table->table_size, buf) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message table") - - /* Get temporary pointer to serialized table */ - p = buf; + HDassert(table->table_size == len); /* Check magic number */ - if(HDmemcmp(p, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) - HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature") - p += H5_SIZEOF_MAGIC; + if(HDmemcmp(image, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature") + image += H5_SIZEOF_MAGIC; /* Allocate space for the index headers in memory*/ if(NULL == (table->indexes = (H5SM_index_header_t *)H5FL_ARR_MALLOC(H5SM_index_header_t, (size_t)table->num_indexes))) @@ -187,187 +280,213 @@ H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void H5_ATTR_UNUSED *udat /* Read in the index headers */ for(u = 0; u < table->num_indexes; ++u) { /* Verify correct version of index list */ - if(H5SM_LIST_VERSION != *p++) + if(H5SM_LIST_VERSION != *image++) HGOTO_ERROR(H5E_SOHM, H5E_VERSION, NULL, "bad shared message list version number") /* Type of the index (list or B-tree) */ - table->indexes[u].index_type= (H5SM_index_type_t)*p++; + table->indexes[u].index_type= (H5SM_index_type_t)*image++; /* Type of messages in the index */ - UINT16DECODE(p, table->indexes[u].mesg_types); + UINT16DECODE(image, table->indexes[u].mesg_types); /* Minimum size of message to share */ - UINT32DECODE(p, table->indexes[u].min_mesg_size); + UINT32DECODE(image, table->indexes[u].min_mesg_size); /* List cutoff; fewer than this number and index becomes a list */ - UINT16DECODE(p, table->indexes[u].list_max); + UINT16DECODE(image, table->indexes[u].list_max); /* B-tree cutoff; more than this number and index becomes a B-tree */ - UINT16DECODE(p, table->indexes[u].btree_min); + UINT16DECODE(image, table->indexes[u].btree_min); /* Number of messages shared */ - UINT16DECODE(p, table->indexes[u].num_messages); + UINT16DECODE(image, table->indexes[u].num_messages); /* Address of the actual index */ - H5F_addr_decode(f, &p, &(table->indexes[u].index_addr)); + H5F_addr_decode(f, &image, &(table->indexes[u].index_addr)); /* Address of the index's heap */ - H5F_addr_decode(f, &p, &(table->indexes[u].heap_addr)); + H5F_addr_decode(f, &image, &(table->indexes[u].heap_addr)); /* Compute the size of a list index for this SOHM index */ table->indexes[u].list_size = H5SM_LIST_SIZE(f, table->indexes[u].list_max); + table->indexes[u].list_size = H5SM_LIST_SIZE(f, table->indexes[u].list_max); } /* end for */ - /* Already decoded and compared stored checksum earlier, when reading */ + /* checksum verification already done in verify_chksum cb */ + + /* Read in checksum */ + UINT32DECODE(image, stored_chksum); /* Sanity check */ - HDassert((size_t)(p - (const uint8_t *)buf) == (table->table_size - H5_SIZEOF_CHKSUM)); + HDassert((size_t)(image - (const uint8_t *)_image) == table->table_size); /* Set return value */ ret_value = table; done: - /* Release resources */ - if(wb && H5WB_unwrap(wb) < 0) - HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") if(!ret_value && table) if(H5SM_table_free(table) < 0) HDONE_ERROR(H5E_SOHM, H5E_CANTFREE, NULL, "unable to destroy sohm table") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_table_load() */ +} /* end H5SM__cache_table_deserialize() */ /*------------------------------------------------------------------------- - * Function: H5SM_table_flush + * Function: H5SM__cache_table_image_len * - * Purpose: Flushes (and destroys) the table of Shared Object Header - * Message indexes. + * Purpose: Compute the size in bytes of the specified instance of + * H5SM_master_table_t on disk, and return it in *image_len. + * On failure, the value of *image_len is undefined. * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: James Laird - * November 6, 2006 + * Programmer: John Mainzer + * 7/28/14 * *------------------------------------------------------------------------- */ static herr_t -H5SM_table_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table) +H5SM__cache_table_image_len(const void *_thing, size_t *image_len, + hbool_t H5_ATTR_UNUSED *compressed_ptr, size_t H5_ATTR_UNUSED *compressed_image_len_ptr) { - H5WB_t *wb = NULL; /* Wrapped buffer for table data */ - uint8_t tbl_buf[H5SM_TBL_BUF_SIZE]; /* Buffer for table */ - herr_t ret_value = SUCCEED; /* Return value */ + const H5SM_master_table_t *table = (const H5SM_master_table_t *)_thing; /* Shared message table to query */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC_NOERR - /* check arguments */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); + /* Check arguments */ HDassert(table); + HDassert(table->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + HDassert(table->cache_info.type == H5AC_SOHM_TABLE); + HDassert(image_len); - if(table->cache_info.is_dirty) { - uint8_t *buf; /* Temporary buffer */ - uint8_t *p; /* Pointer into raw data buffer */ - uint32_t computed_chksum; /* Computed metadata checksum value */ - size_t u; /* Counter variable */ + *image_len = table->table_size; - /* Verify that we're writing version 0 of the table; this is the only - * version defined so far. - */ - HDassert(H5F_SOHM_VERS(f) == HDF5_SHAREDHEADER_VERSION); + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM__cache_table_image_len() */ - /* Wrap the local buffer for serialized header info */ - if(NULL == (wb = H5WB_wrap(tbl_buf, sizeof(tbl_buf)))) - HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "can't wrap buffer") +/***************************************/ +/* no H5SM_cache_table_pre_serialize() */ +/***************************************/ - /* Get a pointer to a buffer that's large enough for serialized table */ - if(NULL == (buf = (uint8_t *)H5WB_actual(wb, table->table_size))) - HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't get actual buffer") + +/*------------------------------------------------------------------------- + * Function: H5SM__cache_table_serialize + * + * Purpose: Serialize the contents of the supplied shared message table, and + * load this data into the supplied buffer. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: John Mainzer + * 7/28/14 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5SM__cache_table_serialize(const H5F_t *f, void *_image, size_t len, + void *_thing) +{ + H5SM_master_table_t *table = (H5SM_master_table_t *)_thing; /* Shared message table to encode */ + uint8_t *image = (uint8_t *)_image; /* Pointer into raw data buffer */ + uint32_t computed_chksum; /* Computed metadata checksum value */ + size_t u; /* Counter variable */ - /* Get temporary pointer to buffer for serialized table */ - p = buf; + FUNC_ENTER_STATIC_NOERR - /* Encode magic number */ - HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC); - p += H5_SIZEOF_MAGIC; + /* Check arguments */ + HDassert(f); + HDassert(image); + HDassert(table); + HDassert(table->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + HDassert(table->cache_info.type == H5AC_SOHM_TABLE); + HDassert(table->table_size == len); - /* Encode each index header */ - for(u = 0; u < table->num_indexes; ++u) { - /* Version for this list */ - *p++ = H5SM_LIST_VERSION; + /* Verify that we're writing version 0 of the table; this is the only + * version defined so far. + */ + HDassert(H5F_SOHM_VERS(f) == HDF5_SHAREDHEADER_VERSION); - /* Is message index a list or a B-tree? */ - *p++ = table->indexes[u].index_type; + /* Encode magic number */ + HDmemcpy(image, H5SM_TABLE_MAGIC, (size_t)H5_SIZEOF_MAGIC); + image += H5_SIZEOF_MAGIC; - /* Type of messages in the index */ - UINT16ENCODE(p, table->indexes[u].mesg_types); + /* Encode each index header */ + for(u = 0; u < table->num_indexes; ++u) { + /* Version for this list */ + *image++ = H5SM_LIST_VERSION; - /* Minimum size of message to share */ - UINT32ENCODE(p, table->indexes[u].min_mesg_size); + /* Is message index a list or a B-tree? */ + *image++ = table->indexes[u].index_type; - /* List cutoff; fewer than this number and index becomes a list */ - UINT16ENCODE(p, table->indexes[u].list_max); + /* Type of messages in the index */ + UINT16ENCODE(image, table->indexes[u].mesg_types); - /* B-tree cutoff; more than this number and index becomes a B-tree */ - UINT16ENCODE(p, table->indexes[u].btree_min); + /* Minimum size of message to share */ + UINT32ENCODE(image, table->indexes[u].min_mesg_size); - /* Number of messages shared */ - UINT16ENCODE(p, table->indexes[u].num_messages); + /* List cutoff; fewer than this number and index becomes a list */ + UINT16ENCODE(image, table->indexes[u].list_max); - /* Address of the actual index */ - H5F_addr_encode(f, &p, table->indexes[u].index_addr); + /* B-tree cutoff; more than this number and index becomes a B-tree */ + UINT16ENCODE(image, table->indexes[u].btree_min); - /* Address of the index's heap */ - H5F_addr_encode(f, &p, table->indexes[u].heap_addr); - } /* end for */ + /* Number of messages shared */ + UINT16ENCODE(image, table->indexes[u].num_messages); - /* Compute checksum on buffer */ - computed_chksum = H5_checksum_metadata(buf, (table->table_size - H5SM_SIZEOF_CHECKSUM), 0); - UINT32ENCODE(p, computed_chksum); + /* Address of the actual index */ + H5F_addr_encode(f, &image, table->indexes[u].index_addr); - /* Write the table to disk */ - HDassert((size_t)(p - buf) == table->table_size); - if(H5F_block_write(f, H5FD_MEM_SOHM_TABLE, addr, table->table_size, dxpl_id, buf) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk") + /* Address of the index's heap */ + H5F_addr_encode(f, &image, table->indexes[u].heap_addr); + } /* end for */ - table->cache_info.is_dirty = FALSE; - } /* end if */ + /* Compute checksum on buffer */ + computed_chksum = H5_checksum_metadata(_image, (table->table_size - H5SM_SIZEOF_CHECKSUM), 0); + UINT32ENCODE(image, computed_chksum); - if(destroy) - if(H5SM_table_dest(f, table) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy sohm table") + /* sanity check */ + HDassert((size_t)(image - ((uint8_t *)_image)) == table->table_size); -done: - /* Release resources */ - if(wb && H5WB_unwrap(wb) < 0) - HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer") + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM__cache_table_serialize() */ - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_table_flush() */ +/*****************************************/ +/* no H5SM_cache_table_notify() function */ +/*****************************************/ /*------------------------------------------------------------------------- - * Function: H5SM_table_dest + * Function: H5SM__cache_table_free_icr + * + * Purpose: Free memory used by the SOHM table. * - * Purpose: Frees memory used by the SOHM table. + * Note: The metadata cache sets the object's cache_info.magic to + * H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC before calling a free_icr + * callback (checked in assert). * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: James Laird - * November 6, 2006 + * Programmer: John Mainzer + * 7/28/14 * *------------------------------------------------------------------------- */ static herr_t -H5SM_table_dest(H5F_t H5_ATTR_UNUSED *f, H5SM_master_table_t* table) +H5SM__cache_table_free_icr(void *_thing) { - herr_t ret_value = SUCCEED; /* Return value */ + H5SM_master_table_t *table = (H5SM_master_table_t *)_thing; /* Shared message table to release */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check arguments */ HDassert(table); - HDassert(table->indexes); + HDassert(table->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC); + HDassert(table->cache_info.type == H5AC_SOHM_TABLE); /* Destroy Shared Object Header Message table */ if(H5SM_table_free(table) < 0) @@ -375,104 +494,129 @@ H5SM_table_dest(H5F_t H5_ATTR_UNUSED *f, H5SM_master_table_t* table) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_table_dest() */ +} /* end H5SM_cache_table_free_icr() */ /*------------------------------------------------------------------------- - * Function: H5SM_table_clear + * Function: H5SM__cache_list_get_load_size() * - * Purpose: Mark this table as no longer being dirty. + * Purpose: Return the on disk size of list of SOHM messages. In this case, + * we simply look up the size in the user data, and return that value + * in *image_len. * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: James Laird - * November 6, 2006 + * Programmer: John Mainzer + * 7/28/14 * *------------------------------------------------------------------------- */ static herr_t -H5SM_table_clear(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy) +H5SM__cache_list_get_load_size(const void *_image, void *_udata, + size_t *image_len, size_t *actual_len, + hbool_t H5_ATTR_UNUSED *compressed_ptr, size_t H5_ATTR_UNUSED *compressed_image_len_ptr) { - herr_t ret_value = SUCCEED; /* Return value */ + const uint8_t *image = (const uint8_t *)_image; /* Pointer into raw data buffer */ + const H5SM_list_cache_ud_t *udata = (const H5SM_list_cache_ud_t *)_udata; /* User data for callback */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC_NOERR - /* - * Check arguments. - */ - HDassert(table); - - /* Reset the dirty flag. */ - table->cache_info.is_dirty = FALSE; + /* Check arguments */ + HDassert(udata); + HDassert(udata->header); + HDassert(udata->header->list_size > 0); + HDassert(image_len); - if(destroy) - if(H5SM_table_dest(f, table) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to delete SOHM master table") + if(image == NULL) + *image_len = udata->header->list_size; + else { + HDassert(actual_len); + HDassert(*actual_len == *image_len); + } -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_table_clear() */ + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM__cache_list_get_load_size() */ /*------------------------------------------------------------------------- - * Function: H5SM_table_size + * Function: H5SM__cache_list_verify_chksum * - * Purpose: Returns the size of the table encoded on disk. + * Purpose: Verify the computed checksum of the data structure is the + * same as the stored chksum. * - * Return: Non-negative on success/Negative on failure + * Return: Success: TRUE/FALSE + * Failure: Negative * - * Programmer: James Laird - * November 6, 2006 + * Programmer: Vailin Choi; Aug 2015 * *------------------------------------------------------------------------- */ -static herr_t -H5SM_table_size(const H5F_t H5_ATTR_UNUSED *f, const H5SM_master_table_t *table, size_t *size_ptr) +htri_t +H5SM__cache_list_verify_chksum(const void *_image, size_t H5_ATTR_UNUSED len, void *_udata) { - FUNC_ENTER_NOAPI_NOINIT_NOERR + const uint8_t *image = (const uint8_t *)_image; /* Pointer into raw data buffer */ + H5SM_list_cache_ud_t *udata = (H5SM_list_cache_ud_t *)_udata; /* User data for callback */ + size_t chk_size; /* Exact size of the node with checksum at the end */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + uint32_t computed_chksum; /* Computed metadata checksum value */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_STATIC_NOERR /* Check arguments */ - HDassert(f); - HDassert(table); - HDassert(size_ptr); + HDassert(image); + HDassert(udata); - /* Set size value */ - *size_ptr = table->table_size; + /* Exact size with checksum at the end */ + chk_size = H5SM_LIST_SIZE(udata->f, udata->header->num_messages); - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_table_size() */ + /* Get stored and computed checksums */ + H5F_get_checksums(image, chk_size, &stored_chksum, &computed_chksum); + + if(stored_chksum != computed_chksum) + ret_value = FALSE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5SM__cache_list_verify_chksum() */ /*------------------------------------------------------------------------- - * Function: H5SM_list_load + * Function: H5SM__cache_list_deserialize * - * Purpose: Loads a list of SOHM messages. + * Purpose: Given a buffer containing the on disk image of a list of + * SOHM message, deserialize the list, load it into a newly allocated + * instance of H5SM_list_t, and return a pointer to same. * - * Return: Non-negative on success/Negative on failure + * Return: Success: Pointer to in core representation + * Failure: NULL * - * Programmer: James Laird - * November 6, 2006 + * Programmer: John Mainzer + * 7/28/14 * *------------------------------------------------------------------------- */ -static H5SM_list_t * -H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata) +static void * +H5SM__cache_list_deserialize(const void *_image, size_t len, void *_udata, + hbool_t H5_ATTR_UNUSED *dirty) { - H5SM_list_t *list; /* The SOHM list being read in */ - H5SM_list_cache_ud_t *udata = (H5SM_list_cache_ud_t *)_udata; /* User data for callback */ - H5SM_bt2_ctx_t ctx; /* Message encoding context */ - H5WB_t *wb = NULL; /* Wrapped buffer for list index data */ - uint8_t lst_buf[H5SM_LST_BUF_SIZE]; /* Buffer for list index */ - uint8_t *buf; /* Reading buffer */ - uint8_t *p; /* Pointer into input buffer */ - size_t u; /* Counter variable for messages in list */ - size_t chk_size; /* Exact size with checksum at the end */ - H5SM_list_t *ret_value; /* Return value */ + H5SM_list_t *list = NULL; /* The SOHM list being read in */ + H5SM_list_cache_ud_t *udata = (H5SM_list_cache_ud_t *)_udata; /* User data for callback */ + H5SM_bt2_ctx_t ctx; /* Message encoding context */ + const uint8_t *image = (const uint8_t *)_image; /* Pointer into input buffer */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + size_t u; /* Counter variable for messages in list */ + void * ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check arguments */ + HDassert(image); + HDassert(len > 0); + HDassert(udata); HDassert(udata->header); + HDassert(udata->header->list_size == len); + HDassert(dirty); /* Allocate space for the SOHM list data structure */ if(NULL == (list = H5FL_MALLOC(H5SM_list_t))) @@ -484,41 +628,27 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata) HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "file allocation failed for SOHM list") list->header = udata->header; - /* Wrap the local buffer for serialized list index info */ - if(NULL == (wb = H5WB_wrap(lst_buf, sizeof(lst_buf)))) - HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, NULL, "can't wrap buffer") - - /* Get a pointer to a buffer that's large enough for serialized list index */ - if(NULL == (buf = (uint8_t *)H5WB_actual(wb, udata->header->list_size))) - HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer") - - /* Exact size with checksum at the end */ - chk_size = H5SM_LIST_SIZE(udata->f, udata->header->num_messages); - - /* Read and validate shared message list from disk */ - if(H5F_read_check_metadata(f, dxpl_id, H5FD_MEM_SOHM_INDEX, H5AC_SOHM_LIST_ID, addr, udata->header->list_size, chk_size, buf) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message list") - - /* Get temporary pointer to serialized list index */ - p = buf; - /* Check magic number */ - if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + if(HDmemcmp(image, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC)) HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature") - p += H5_SIZEOF_MAGIC; + image += H5_SIZEOF_MAGIC; /* Read messages into the list array */ ctx.sizeof_addr = H5F_SIZEOF_ADDR(udata->f); for(u = 0; u < udata->header->num_messages; u++) { - if(H5SM_message_decode(p, &(list->messages[u]), &ctx) < 0) + if(H5SM_message_decode(image, &(list->messages[u]), &ctx) < 0) HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "can't decode shared message") - p += H5SM_SOHM_ENTRY_SIZE(udata->f); + + image += H5SM_SOHM_ENTRY_SIZE(udata->f); } /* end for */ - /* Already decoded and compared stored checksum earlier, when reading */ + /* checksum verification already done in verify_chksum cb */ + + /* Read in checksum */ + UINT32DECODE(image, stored_chksum); /* Sanity check */ - HDassert((size_t)(p - buf) <= (udata->header->list_size - H5_SIZEOF_CHKSUM)); + HDassert((size_t)(image - (const uint8_t *)_image) <= udata->header->list_size); /* Initialize the rest of the array */ for(u = udata->header->num_messages; u < udata->header->list_max; u++) @@ -528,9 +658,6 @@ H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata) ret_value = list; done: - /* Release resources */ - if(wb && H5WB_unwrap(wb) < 0) - HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer") if(!ret_value && list) { if(list->messages) list->messages = H5FL_ARR_FREE(H5SM_sohm_t, list->messages); @@ -538,205 +665,158 @@ done: } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_list_load() */ +} /* end H5SM__cache_list_deserialize() */ /*------------------------------------------------------------------------- - * Function: H5SM_list_flush + * Function: H5SM__cache_list_image_len * - * Purpose: Flush this list index. + * Purpose: Get the size of the shared message list on disk. * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: James Laird - * November 6, 2006 + * Programmer: John Mainzer + * 7/28/14 * *------------------------------------------------------------------------- */ static herr_t -H5SM_list_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list) +H5SM__cache_list_image_len(const void *_thing, size_t *image_len, + hbool_t H5_ATTR_UNUSED *compressed_ptr, size_t H5_ATTR_UNUSED *compressed_image_len_ptr) { - H5WB_t *wb = NULL; /* Wrapped buffer for list index data */ - uint8_t lst_buf[H5SM_LST_BUF_SIZE]; /* Buffer for list index */ - herr_t ret_value = SUCCEED; /* Return value */ + const H5SM_list_t *list = (const H5SM_list_t *)_thing; /* Shared message list to query */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC_NOERR - /* check arguments */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); + /* Check arguments */ HDassert(list); + HDassert(list->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + HDassert(list->cache_info.type == H5AC_SOHM_LIST); HDassert(list->header); + HDassert(image_len); - if(list->cache_info.is_dirty) { - H5SM_bt2_ctx_t ctx; /* Message encoding context */ - uint8_t *buf; /* Temporary buffer */ - uint8_t *p; /* Pointer into raw data buffer */ - uint32_t computed_chksum; /* Computed metadata checksum value */ - size_t mesgs_written; /* Number of messages written to list */ - size_t u; /* Local index variable */ - - /* Wrap the local buffer for serialized list index info */ - if(NULL == (wb = H5WB_wrap(lst_buf, sizeof(lst_buf)))) - HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "can't wrap buffer") - - /* Get a pointer to a buffer that's large enough for serialized list index */ - if(NULL == (buf = (uint8_t *)H5WB_actual(wb, list->header->list_size))) - HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't get actual buffer") - - /* Get temporary pointer to buffer for serialized list index */ - p = buf; - - /* Encode magic number */ - HDmemcpy(p, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC); - p += H5_SIZEOF_MAGIC; - - /* Write messages from the messages array to disk */ - mesgs_written = 0; - ctx.sizeof_addr = H5F_SIZEOF_ADDR(f); - for(u = 0; u < list->header->list_max && mesgs_written < list->header->num_messages; u++) { - if(list->messages[u].location != H5SM_NO_LOC) { - if(H5SM_message_encode(p, &(list->messages[u]), &ctx) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to write shared message to disk") - - p += H5SM_SOHM_ENTRY_SIZE(f); - ++mesgs_written; - } /* end if */ - } /* end for */ - HDassert(mesgs_written == list->header->num_messages); - - /* Compute checksum on buffer */ - computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); - UINT32ENCODE(p, computed_chksum); -#ifdef H5_CLEAR_MEMORY -HDmemset(p, 0, (list->header->list_size - (size_t)(p - buf))); -#endif /* H5_CLEAR_MEMORY */ + *image_len = list->header->list_size; - /* Write the list to disk */ - HDassert((size_t)(p - buf) <= list->header->list_size); - if(H5F_block_write(f, H5FD_MEM_SOHM_INDEX, addr, list->header->list_size, dxpl_id, buf) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk") - - list->cache_info.is_dirty = FALSE; - } /* end if */ - - if(destroy) - if(H5SM_list_dest(f, list) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy list") + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM__cache_list_image_len() */ -done: - /* Release resources */ - if(wb && H5WB_unwrap(wb) < 0) - HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_list_flush() */ +/**************************************/ +/* no H5SM_cache_list_pre_serialize() */ +/**************************************/ /*------------------------------------------------------------------------- - * Function: H5SM_list_dest + * Function: H5SM__cache_list_serialize * - * Purpose: Frees all memory used by the list. + * Purpose: Serialize the contents of the supplied shared message list, and + * load this data into the supplied buffer. * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: James Laird - * November 6, 2006 + * Programmer: John Mainzer + * 7/28/14 * *------------------------------------------------------------------------- */ static herr_t -H5SM_list_dest(H5F_t *f, H5SM_list_t* list) +H5SM__cache_list_serialize(const H5F_t *f, void *_image, size_t len, + void *_thing) { - herr_t ret_value = SUCCEED; /* Return value */ + H5SM_list_t *list = (H5SM_list_t *)_thing ; /* Instance being serialized */ + H5SM_bt2_ctx_t ctx; /* Message encoding context */ + uint8_t *image = (uint8_t *)_image; /* Pointer into raw data buffer */ + uint32_t computed_chksum; /* Computed metadata checksum value */ + size_t mesgs_serialized; /* Number of messages serialized */ + size_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC - /* Sanity check */ + /* Check arguments */ + HDassert(f); + HDassert(image); HDassert(list); + HDassert(list->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); + HDassert(list->cache_info.type == H5AC_SOHM_LIST); HDassert(list->header); - HDassert(list->messages); + HDassert(list->header->list_size == len); + + /* Encode magic number */ + HDmemcpy(image, H5SM_LIST_MAGIC, (size_t)H5_SIZEOF_MAGIC); + image += H5_SIZEOF_MAGIC; + + /* serialize messages from the messages array */ + mesgs_serialized = 0; + ctx.sizeof_addr = H5F_SIZEOF_ADDR(f); + for(u = 0; ((u < list->header->list_max) && (mesgs_serialized < list->header->num_messages)); u++) { + if(list->messages[u].location != H5SM_NO_LOC) { + if(H5SM_message_encode(image, &(list->messages[u]), &ctx) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to serialize shared message") + + image += H5SM_SOHM_ENTRY_SIZE(f); + ++mesgs_serialized; + } /* end if */ + } /* end for */ - /* If we're going to free the space on disk, the address must be valid */ - HDassert(!list->cache_info.free_file_space_on_destroy || H5F_addr_defined(list->cache_info.addr)); + HDassert(mesgs_serialized == list->header->num_messages); - /* Check for freeing file space for shared message index list */ - if(list->cache_info.free_file_space_on_destroy) { - /* Release the space on disk */ - /* (XXX: Nasty usage of internal DXPL value! -QAK) */ - if(H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, H5AC_dxpl_id, list->cache_info.addr, (hsize_t)list->header->list_size) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "unable to free shared message list") - } /* end if */ + /* Compute checksum on buffer */ + computed_chksum = H5_checksum_metadata(_image, (size_t)(image - (uint8_t *)_image), 0); + UINT32ENCODE(image, computed_chksum); - /* Destroy Shared Object Header Message list */ - if(H5SM_list_free(list) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTRELEASE, FAIL, "unable to free shared message list") +#ifdef H5_CLEAR_MEMORY + HDmemset(image, 0, (list->header->list_size - (size_t)(image - (uint8_t *)_image))); +#endif /* H5_CLEAR_MEMORY */ + + /* sanity check */ + HDassert((size_t)(image - (uint8_t *)_image) <= list->header->list_size); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_list_dest() */ +} /* end H5SM__cache_list_serialize() */ + +/****************************************/ +/* no H5SM_cache_list_notify() function */ +/****************************************/ /*------------------------------------------------------------------------- - * Function: H5SM_list_clear + * Function: H5SM__cache_list_free_icr + * + * Purpose: Free all memory used by the list. * - * Purpose: Marks a list as not dirty. + * Note: The metadata cache sets the object's cache_info.magic to + * H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC before calling a free_icr + * callback (checked in assert). * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: James Laird - * November 6, 2006 + * Programmer: John Mainzer + * 7/28/14 * *------------------------------------------------------------------------- */ static herr_t -H5SM_list_clear(H5F_t *f, H5SM_list_t *list, hbool_t destroy) +H5SM__cache_list_free_icr(void *_thing) { - herr_t ret_value = SUCCEED; /* Return value */ + H5SM_list_t *list = (H5SM_list_t *)_thing; /* Shared message list to release */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC /* Check arguments */ HDassert(list); + HDassert(list->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC); + HDassert(list->cache_info.type == H5AC_SOHM_LIST); - /* Reset the dirty flag. */ - list->cache_info.is_dirty = FALSE; - - if(destroy) - if(H5SM_list_dest(f, list) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy SOHM list") + /* Destroy Shared Object Header Message list */ + if(H5SM_list_free(list) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_CANTRELEASE, FAIL, "unable to free shared message list") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end of H5SM_list_clear() */ - - -/*------------------------------------------------------------------------- - * Function: H5SM_list_size - * - * Purpose: Gets the size of a list on disk. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: James Laird - * November 6, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5SM_list_size(const H5F_t H5_ATTR_UNUSED *f, const H5SM_list_t *list, size_t *size_ptr) -{ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* check arguments */ - HDassert(f); - HDassert(list); - HDassert(list->header); - HDassert(size_ptr); - - /* Set size value */ - *size_ptr = list->header->list_size; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_list_size() */ +} /* end H5O_cache_list_free_icr() */ |