summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5C2.c9
-rw-r--r--src/H5C2journal.c2269
-rw-r--r--src/H5C2pkg.h88
-rw-r--r--src/H5C2private.h74
-rw-r--r--src/H5Fpkg.h7
-rw-r--r--src/H5Fsuper.c286
-rw-r--r--src/H5Ochunk.c2
-rw-r--r--src/H5Omdj_msg.c190
-rw-r--r--src/H5Omessage.c15
-rw-r--r--src/H5Oprivate.h38
10 files changed, 1507 insertions, 1471 deletions
diff --git a/src/H5C2.c b/src/H5C2.c
index 64fa9fd..d8e4a51 100644
--- a/src/H5C2.c
+++ b/src/H5C2.c
@@ -656,10 +656,9 @@ H5C2_create(size_t max_cache_size,
cache_ptr->trans_api_name[0] = '\0';
cache_ptr->trans_num = 0;
cache_ptr->last_trans_on_disk = 0;
- cache_ptr->mdj_file_name_ptr = NULL;
- cache_ptr->mdj_conf_block_addr = HADDR_UNDEF;
- cache_ptr->mdj_conf_block_len = 0;
- cache_ptr->mdj_conf_block_ptr = NULL;
+ cache_ptr->jnl_magic = 0;
+ cache_ptr->jnl_file_name_len = 0;
+ (cache_ptr->jnl_file_name)[0] = '\0';
(cache_ptr->mdj_jbrb).magic =
H5C2__H5C2_JBRB_T_MAGIC;
cache_ptr->tl_len = 0;
@@ -712,7 +711,7 @@ H5C2_create(size_t max_cache_size,
/* We used to check for journaling here, but the super block hasn't
* been read in yet at cache creation time -- thus the check for
* journaling has been moved to H5AC2_check_for_journaling(), which
- * is simply a * wrapper for H5C2_check_for_journaling().
+ * is simply a wrapper for H5C2_check_for_journaling().
*
* H5AC2_check_for_journaling() is called at the end of H5Fopen() --
* at which point the superblock has been read.
diff --git a/src/H5C2journal.c b/src/H5C2journal.c
index ab79a7b..339eb00 100644
--- a/src/H5C2journal.c
+++ b/src/H5C2journal.c
@@ -97,6 +97,14 @@ static herr_t H5C2_shrink_mdjsc_callback_table(H5C2_t * cache_ptr);
* starts, and to call the metadata journaling status
* change callbacks after journaling has been started.
*
+ * JRM -- 2/10/09
+ * Added journal_magic variable and supporting code.
+ *
+ * The idea is to assign a random magic number to both the
+ * journal file, and to the journal configuration information
+ * information in the super block so that it will be hard to
+ * apply the wrong journal file to a corrupted hdf5 file.
+ *
*-------------------------------------------------------------------------
*/
@@ -108,6 +116,7 @@ H5C2_begin_journaling(H5F_t * f,
{
herr_t result;
herr_t ret_value = SUCCEED; /* Return value */
+ int32_t journal_magic;
H5C2_mdj_config_t config;
FUNC_ENTER_NOAPI(H5C2_begin_journaling, FAIL)
@@ -159,11 +168,18 @@ H5C2_begin_journaling(H5F_t * f,
HDfprintf(stdout, "%s Finished flushing the cache.\n", FUNC);
#endif /* JRM */
+ journal_magic = (int32_t)HDrand();
+
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s journal_magic = %d.\n", FUNC, (int)journal_magic);
+#endif /* JRM */
+
#if 0 /* JRM */
HDfprintf(stdout, "%s calling H5C2_jb__init().\n", FUNC);
#endif /* JRM */
result = H5C2_jb__init(&(cache_ptr->mdj_jbrb),
+ journal_magic,
f->name,
config_ptr->journal_file_path,
config_ptr->jbrb_buf_size,
@@ -185,7 +201,7 @@ H5C2_begin_journaling(H5F_t * f,
#endif /* JRM */
/* Note that this call flushes the HDF5 file in passing */
- result = H5C2_mark_journaling_in_progress(f, dxpl_id,
+ result = H5C2_mark_journaling_in_progress(f, dxpl_id, journal_magic,
config_ptr->journal_file_path);
if ( result != SUCCEED ) {
@@ -373,7 +389,8 @@ H5C2_end_journaling(H5F_t * f,
cache_ptr->mdj_enabled = FALSE;
/* Remove the journal configuration information from the superblock
- * extension.
+ * extension. In passing, also discard the cache's copies of the
+ * metadata journaling magic, and the journal file name.
*/
result = H5C2_unmark_journaling_in_progress(f, dxpl_id, cache_ptr);
@@ -411,7 +428,7 @@ H5C2_end_journaling(H5F_t * f,
done:
#if 0 /* JRM */
- HDfprintf(stdout, "%s: entering.\n", FUNC);
+ HDfprintf(stdout, "%s: exiting.\n", FUNC);
#endif /* JRM */
FUNC_LEAVE_NOAPI(ret_value)
@@ -593,7 +610,7 @@ H5C2_get_journal_config(H5C2_t * cache_ptr,
config_ptr->enable_journaling = TRUE;
HDstrncpy(&(config_ptr->journal_file_path[0]),
- cache_ptr->mdj_file_name_ptr,
+ cache_ptr->jnl_file_name,
H5C2__MAX_JOURNAL_FILE_NAME_LEN);
config_ptr->journal_file_path[H5C2__MAX_JOURNAL_FILE_NAME_LEN] = '\0';
@@ -1161,7 +1178,7 @@ done:
/**************************************************************************/
-/***************** journal config block management code *******************/
+/************* superblock journaling message management code **************/
/**************************************************************************/
/*-------------------------------------------------------------------------
@@ -1216,10 +1233,8 @@ H5C2_check_for_journaling(H5F_t * f,
HDassert( f );
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
- HDassert( cache_ptr->mdj_conf_block_addr == HADDR_UNDEF );
- HDassert( cache_ptr->mdj_conf_block_len == 0 );
- HDassert( cache_ptr->mdj_conf_block_ptr == NULL );
- HDassert( cache_ptr->mdj_file_name_ptr == NULL );
+ HDassert( cache_ptr->jnl_magic == 0 );
+ HDassert( cache_ptr->jnl_file_name_len == 0 );
if ( H5C2__check_for_journaling ) {
@@ -1231,8 +1246,8 @@ H5C2_check_for_journaling(H5F_t * f,
"H5C2_get_journaling_in_progress() failed.")
}
- if ( cache_ptr->mdj_file_name_ptr != NULL ) /* journaling was in */
- /* progress */
+ if ( cache_ptr->jnl_file_name_len > 0 ) /* journaling was in */
+ /* progress */
{
#if 0 /* JRM */
HDfprintf(stdout, "%s: journaling was in progress.\n", FUNC);
@@ -1240,8 +1255,9 @@ H5C2_check_for_journaling(H5F_t * f,
if ( journal_recovered ) {
- /* delete the metadata journaling config block and the
- * superblock extenstion refering to it.
+ /* Just forget that we were journaling. Do this by
+ * deleting the superblock extension message that says
+ * we were.
*/
result = H5C2_unmark_journaling_in_progress(f, dxpl_id, cache_ptr);
@@ -1261,7 +1277,7 @@ H5C2_check_for_journaling(H5F_t * f,
(void)H5Epush2(H5E_DEFAULT, __FILE__, FUNC, __LINE__,
H5E_ERR_CLS_g, H5E_CACHE, H5E_CANTJOURNAL,
"%s%s%s%s%s%s", l0, l1, l2, l3,
- cache_ptr->mdj_file_name_ptr, l4);
+ cache_ptr->jnl_file_name, l4);
(void)H5E_dump_api_stack((int)H5_IS_API(FUNC));
HGOTO_DONE(FAIL)
@@ -1285,217 +1301,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5C2_create_journal_config_block()
- *
- * Purpose: Given a string containing a journal file name and a pointer
- * to the associated instance of H5C2_t, allocate a journal
- * configuration block, write it to file, and update the
- * instance of H5C2_t.
- *
- * Note that the method assumes that mdj_conf_block_addr is
- * NULL on entry.
- *
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: John Mainzer
- * March 7, 2008
- *
- *-------------------------------------------------------------------------
- */
-
-herr_t
-H5C2_create_journal_config_block(const H5F_t * f,
- hid_t dxpl_id,
- const char * journal_file_name_ptr)
-{
- H5C2_t * cache_ptr;
- size_t path_len = 0;
- hsize_t block_len = 0;
- haddr_t block_addr = HADDR_UNDEF;
- void * block_ptr = NULL;
- uint8_t version = H5C2__JOURNAL_CONF_VERSION;
- uint8_t * p = NULL;
- char * jfn_ptr = NULL;
- uint32_t chksum;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5C2_create_journal_config_block, FAIL)
-
- HDassert( f );
- HDassert( f->shared );
- cache_ptr = f->shared->cache2;
- HDassert( cache_ptr );
- HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
-
- if ( cache_ptr->mdj_conf_block_ptr != NULL ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "cache_ptr->mdj_conf_block_ptr != NULL on entry?!?")
- }
-
- HDassert( journal_file_name_ptr != NULL );
-
- path_len = HDstrlen(journal_file_name_ptr) + 1;
-
- HDassert( path_len > 0 );
-
- block_len = H5C2__JOURNAL_BLOCK_LEN(path_len, f);
-
- block_ptr = (void *)H5MM_malloc((size_t)block_len);
-
- if ( block_ptr == NULL ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
- "allocation of in core journal config block failed.");
- }
-
- p = (uint8_t *)block_ptr;
-
- /* copy the signature into the config block */
- HDmemcpy(p, H5C2__JOURNAL_CONF_MAGIC, H5C2__JOURNAL_MAGIC_LEN);
- p += H5C2__JOURNAL_MAGIC_LEN;
-
- /* copy the version into the config block */
- HDmemcpy(p, &version, 1);
- p++;
-
- /* copy the length of the journal file path into the config block */
- H5F_ENCODE_LENGTH(f, p, path_len);
-
- /* copy the path to the journal file into the config block, including
- * the terminalting null. Before we do so, make note of p, as its
- * value will be the address of our copy of the journal file path.
- */
- jfn_ptr = (char *)p;
- HDmemcpy(p, journal_file_name_ptr, path_len + 1);
- p += path_len + 1;
-
- HDassert( strcmp(jfn_ptr, journal_file_name_ptr) == 0 );
-
- /* compute and save checksum */
- chksum = H5_checksum_metadata(block_ptr, (size_t)(block_len - 4), 0);
- UINT32ENCODE(p, chksum);
-
- HDassert( (unsigned)(p - (uint8_t *)block_ptr) == block_len );
-
-
- /* having created an in core image of the journaling configuration block,
- * we must now allocate space for it in file, and write it to disk.
- */
-
- block_addr = H5MF_alloc(f,
- H5FD_MEM_MDJCONFIG,
- dxpl_id,
- block_len);
-
- if ( block_addr == HADDR_UNDEF ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
- "allocation of file journal config block failed.");
- }
-
- /* now write the block to disk -- note that we don't sync. We will
- * have to do that later.
- */
- if ( H5F_block_write(f, H5FD_MEM_MDJCONFIG, block_addr,
- (size_t)block_len, dxpl_id, block_ptr) < 0 )
- {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "Can't write metadata journaling config block to file.")
- }
-
- /* finally, if we we get this far, update the cache data structure to
- * record the metadata journaling configuration block.
- */
- cache_ptr->mdj_file_name_ptr = jfn_ptr;
- cache_ptr->mdj_conf_block_addr = block_addr;
- cache_ptr->mdj_conf_block_len = block_len;
- cache_ptr->mdj_conf_block_ptr = block_ptr;
-
-done:
-
- FUNC_LEAVE_NOAPI(ret_value)
-
-} /* H5AC2__create_journal_config_block() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5C2_discard_journal_config_block()
- *
- * Purpose: Free the file and core space allocated to the metadata
- * journaling configuration block, and re-set all the associated
- * fields in the cache's instance of H5C2_t.
- *
- * Note that the method assumes that
- *
- * struct_ptr->mdj_file_name_ptr,
- * struct_ptr->mdj_conf_block_addr,
- * struct_ptr->mdj_conf_block_len, and
- * struct_ptr->mdj_conf_block_ptr
- *
- * are all set up for the current metadata journaling
- * configuration block on entry. On successful exit, these
- * fields will all be reset to their initial values.
- *
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: John Mainzer
- * March 7, 2008
- *
- *-------------------------------------------------------------------------
- */
-
-herr_t
-H5C2_discard_journal_config_block(const H5F_t * f,
- hid_t dxpl_id)
-{
- H5C2_t * cache_ptr;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5C2_discard_journal_config_block, FAIL)
-
- HDassert( f );
- HDassert( f->shared );
- cache_ptr = f->shared->cache2;
- HDassert( cache_ptr );
- HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
-
- if ( ( cache_ptr->mdj_conf_block_addr == HADDR_UNDEF ) ||
- ( cache_ptr->mdj_conf_block_len == 0 ) ||
- ( cache_ptr->mdj_conf_block_ptr == NULL ) ||
- ( cache_ptr->mdj_file_name_ptr == NULL ) ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "metadata journaling config block undefined on entry?!?")
- }
-
- if ( H5MF_xfree(f, H5FD_MEM_MDJCONFIG, dxpl_id,
- cache_ptr->mdj_conf_block_addr,
- cache_ptr->mdj_conf_block_len) < 0 ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "deallocation of file journal config block failed.");
- }
-
- H5MM_xfree(cache_ptr->mdj_conf_block_ptr);
-
- /* if we get this far, go ahead and null out the fields in *cache_ptr */
-
- cache_ptr->mdj_conf_block_addr = HADDR_UNDEF;
- cache_ptr->mdj_conf_block_len = 0;
- cache_ptr->mdj_conf_block_ptr = NULL;
- cache_ptr->mdj_file_name_ptr = NULL;
-
-done:
-
- FUNC_LEAVE_NOAPI(ret_value)
-
-} /* H5AC2_discard_journal_config_block() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5C2_get_journaling_in_progress()
*
* Purpose: Query the HDF5 file to see if it is marked as having
@@ -1524,6 +1329,13 @@ done:
* Programmer: John Mainzer
* March 11, 2008
*
+ * Changes: JRM -- 2/20/09
+ * Reworked to reflect the move of the journal file name
+ * and magic from the journaling configuration block to
+ * the metadata journaling superblock extension message.
+ * Note that the journaling configuration block no longer
+ * exists.
+ *
*-------------------------------------------------------------------------
*/
@@ -1532,7 +1344,6 @@ H5C2_get_journaling_in_progress(const H5F_t * f,
hid_t dxpl_id,
H5C2_t * cache_ptr)
{
- herr_t result;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5C2_get_journaling_in_progress, FAIL)
@@ -1545,31 +1356,42 @@ H5C2_get_journaling_in_progress(const H5F_t * f,
HDassert( f->shared != NULL );
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
- HDassert( cache_ptr->mdj_conf_block_addr == HADDR_UNDEF );
- HDassert( cache_ptr->mdj_conf_block_len == 0 );
- HDassert( cache_ptr->mdj_conf_block_ptr == NULL );
- HDassert( cache_ptr->mdj_file_name_ptr == NULL );
+ HDassert( cache_ptr->jnl_file_name_len == 0 );
#if 0 /* JRM */
- HDfprintf(stdout, "%s: f->shared->mdc_jrnl_enabled = %d.\n", FUNC,
- (int)(f->shared->mdc_jrnl_enabled));
+ HDfprintf(stdout, "%s: f->shared->mdc_jnl_enabled = %d.\n", FUNC,
+ (int)(f->shared->mdc_jnl_enabled));
#endif /* JRM */
- if ( f->shared->mdc_jrnl_enabled == TRUE ) {
+ if ( f->shared->mdc_jnl_enabled == TRUE ) {
- cache_ptr->mdj_conf_block_addr = f->shared->mdc_jrnl_block_loc;
- cache_ptr->mdj_conf_block_len = f->shared->mdc_jrnl_block_len;
-
- result = H5C2_load_journal_config_block(f,
- dxpl_id,
- cache_ptr,
- cache_ptr->mdj_conf_block_addr,
- cache_ptr->mdj_conf_block_len);
- if ( result != SUCCEED ) {
+ if ( f->shared->mdc_jnl_file_name_len <= 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_load_journal_config_block() failed.")
- }
+ "journaling enabled but jnl file name empty?!?.")
+ }
+
+ if ( f->shared->mdc_jnl_file_name_len >
+ H5C2__MAX_JOURNAL_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "journal file name too long?!?.")
+ }
+
+ cache_ptr->jnl_magic = f->shared->mdc_jnl_magic;
+ cache_ptr->jnl_file_name_len = f->shared->mdc_jnl_file_name_len;
+ HDstrncpy(cache_ptr->jnl_file_name,
+ f->shared->mdc_jnl_file_name,
+ f->shared->mdc_jnl_file_name_len + 1);
+
+ if ( ( (cache_ptr->jnl_file_name)[cache_ptr->jnl_file_name_len]
+ != '\0' ) ||
+ ( strlen(cache_ptr->jnl_file_name) !=
+ (size_t)(cache_ptr->jnl_file_name_len) ) ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "bad jnl file name or name len?!?.")
+ }
}
#if 0 /* JRM */
@@ -1588,140 +1410,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5C2_load_journal_config_block()
- *
- * Purpose: Given the base address and lenght of a journal configuration
- * block, attempt to load it, and store it in the cache structure.
- *
- * Note that the method assumes that mdj_conf_block_addr is
- * NULL on entry.
- *
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: John Mainzer
- * March 11, 2008
- *
- *-------------------------------------------------------------------------
- */
-
-herr_t
-H5C2_load_journal_config_block(const H5F_t * f,
- hid_t dxpl_id,
- H5C2_t * cache_ptr,
- haddr_t block_addr,
- hsize_t block_len)
-{
- size_t path_len = 0;
- void * block_ptr = NULL;
- uint8_t version;
- uint8_t * p = NULL;
- char * jfn_ptr = NULL;
- uint32_t computed_chksum;
- uint32_t read_chksum;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5C2_load_journal_config_block, FAIL)
-
- HDassert( f );
- HDassert( f->shared );
- HDassert( cache_ptr );
- HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
-
- if ( cache_ptr->mdj_conf_block_ptr != NULL ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "cache_ptr->mdj_conf_block_ptr != NULL on entry?!?")
- }
-
- block_ptr = (void *)H5MM_malloc((size_t)block_len);
-
- if ( block_ptr == NULL ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
- "allocation of in core journal config block failed.");
- }
-
- p = (uint8_t *)block_ptr;
-
- /* read the metadata journaling block from file */
- if ( H5F_block_read(f, H5FD_MEM_MDJCONFIG, block_addr,
- (size_t)block_len, dxpl_id, block_ptr) < 0 ) {
-
-#if 0 /* JRM */
- HDfprintf(stdout, "%s: block_addr = %lld, block_len = %lld.\n",
- FUNC, (long long)block_addr, (long long)block_len);
-#endif /* JRM */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "Can't read metadata journaling configuration block.")
- }
-
- /* verify the signature */
- if ( HDmemcmp(p, H5C2__JOURNAL_CONF_MAGIC, H5C2__JOURNAL_MAGIC_LEN) != 0 ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "Bad signature on metadata journaling configuration block.")
- }
- p += H5C2__JOURNAL_MAGIC_LEN;
-
- /* get the version of the config block */
- version = *p++;
-
- if ( version != H5C2__JOURNAL_CONF_VERSION ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "Bad version on metadata journaling configuration block.")
- }
-
- /* get the length of the journal file path into the config block */
- H5F_DECODE_LENGTH(f, p, path_len);
-
- /* Verify that the length matches the actual path length. Also,
- * make note of p, as its value will be the address of our copy of
- * the journal file path.
- */
- jfn_ptr = (char *)p;
- if ( HDstrlen(jfn_ptr) != path_len - 1 ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "Bad path_len in metadata journaling configuration block.")
- }
-
- p += path_len + 1;
-
- /* get the checksum from the block */
- UINT32DECODE(p, read_chksum);
-
- /* compute the actual checksum */
- computed_chksum =
- H5_checksum_metadata(block_ptr, (size_t)(block_len - 4), 0);
-
- /* verify that the computed and read checksums match */
- if ( computed_chksum != read_chksum ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "Bad checksum in metadata journaling configuration block.")
- }
-
- HDassert( (unsigned)(p - (uint8_t *)block_ptr) == block_len );
-
- /* finally, if we we get this far, we have read the metadata journaling
- * configuration block successfully. Record the data in the cache
- * structure.
- */
- cache_ptr->mdj_file_name_ptr = jfn_ptr;
- cache_ptr->mdj_conf_block_addr = block_addr;
- cache_ptr->mdj_conf_block_len = block_len;
- cache_ptr->mdj_conf_block_ptr = block_ptr;
-
-done:
-
- FUNC_LEAVE_NOAPI(ret_value)
-
-} /* H5C2_load_journal_config_block() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5C2_mark_journaling_in_progress()
*
* Purpose: Modify the HDF5 file to indicate that journaling is
@@ -1740,12 +1428,22 @@ done:
* Programmer: John Mainzer
* March 11, 2008
*
+ * Changes: JRM -- 2/10/09
+ * Added the journal_magic parameter and related code.
+ *
+ * JRM -- 2/20/09
+ * Reworked function to reflect the move of the journal
+ * file name and magic to the super block extension message
+ * and out of the metadata journaling configuration block
+ * which no longer exists.
+ *
*-------------------------------------------------------------------------
*/
herr_t
H5C2_mark_journaling_in_progress(H5F_t * f,
hid_t dxpl_id,
+ const int32_t journal_magic,
const char * journal_file_name_ptr)
{
H5C2_t * cache_ptr;
@@ -1758,16 +1456,13 @@ H5C2_mark_journaling_in_progress(H5F_t * f,
#endif /* JRM */
HDassert( f != NULL );
HDassert( f->shared != NULL );
- HDassert( ! f->shared->mdc_jrnl_enabled );
+ HDassert( ! f->shared->mdc_jnl_enabled );
cache_ptr = f->shared->cache2;
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
- HDassert( cache_ptr->mdj_conf_block_addr == HADDR_UNDEF );
- HDassert( cache_ptr->mdj_conf_block_len == 0 );
- HDassert( cache_ptr->mdj_conf_block_ptr == NULL );
- HDassert( cache_ptr->mdj_file_name_ptr == NULL );
+ HDassert( cache_ptr->jnl_file_name_len == 0 );
HDassert( journal_file_name_ptr != NULL );
/* Can't journal a read only file, so verify that we are
@@ -1779,32 +1474,35 @@ H5C2_mark_journaling_in_progress(H5F_t * f,
"File is opened read only.")
}
- /* first, create a metadata journaling configuration block */
-#if 0 /* JRM */
- HDfprintf(stdout, "%s: creating mdj config block.\n", FUNC);
-#endif /* JRM */
- result = H5C2_create_journal_config_block(f,
- dxpl_id,
- journal_file_name_ptr);
+ cache_ptr->jnl_magic = journal_magic;
+ cache_ptr->jnl_file_name_len = strlen(journal_file_name_ptr);
- if ( result != SUCCEED ) {
+ if ( cache_ptr->jnl_file_name_len <= 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_create_journal_config_block() failed.")
+ "length of journal file name is zero.")
}
- HDassert( cache_ptr->mdj_conf_block_addr != HADDR_UNDEF );
- HDassert( cache_ptr->mdj_conf_block_len != 0 );
- HDassert( cache_ptr->mdj_conf_block_ptr != NULL );
- HDassert( cache_ptr->mdj_file_name_ptr != NULL );
+ if ( cache_ptr->jnl_file_name_len > H5C2__MAX_JOURNAL_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "journal file name too long.")
+ }
- /* now, load the base addr and length of the configuration block
- * into shared, and then call H5F_super_write_mdj_msg() to write
- * the metadata journaling superblock extension message to file.
+ HDstrncpy(cache_ptr->jnl_file_name,
+ journal_file_name_ptr,
+ (size_t)(cache_ptr->jnl_file_name_len + 1));
+
+ /* now, load the journaling information into shared, and then call
+ * H5F_super_write_mdj_msg() to write the metadata journaling
+ * superblock extension message to file.
*/
- f->shared->mdc_jrnl_enabled = TRUE;
- f->shared->mdc_jrnl_block_loc = cache_ptr->mdj_conf_block_addr;
- f->shared->mdc_jrnl_block_len = cache_ptr->mdj_conf_block_len;
+ f->shared->mdc_jnl_enabled = TRUE;
+ f->shared->mdc_jnl_magic = journal_magic;
+ f->shared->mdc_jnl_file_name_len = (size_t)(cache_ptr->jnl_file_name_len);
+ HDstrncpy(f->shared->mdc_jnl_file_name,
+ journal_file_name_ptr,
+ (size_t)(cache_ptr->jnl_file_name_len + 1));
#if 0 /* JRM */
HDfprintf(stdout, "%s: writing superblock extension.\n", FUNC);
@@ -1868,6 +1566,13 @@ done:
* Programmer: John Mainzer
* March 11, 2008
*
+ * Changes: JRM -- 2/20/09
+ * Reworked function to reflect the move of the journal
+ * file name and magic from the metadata journaling config
+ * block and into a superblock extension message. Note that
+ * the metadata journaling configuration block no longer
+ * exists.
+ *
*-------------------------------------------------------------------------
*/
@@ -1890,18 +1595,11 @@ H5C2_unmark_journaling_in_progress(H5F_t * f,
#endif /* JRM */
HDassert( f != NULL );
HDassert( f->shared != NULL );
- HDassert( f->shared->mdc_jrnl_enabled );
+ HDassert( f->shared->mdc_jnl_enabled );
HDassert( f->shared->cache2 == cache_ptr );
HDassert( cache_ptr );
HDassert( cache_ptr->magic == H5C2__H5C2_T_MAGIC );
- HDassert( cache_ptr->mdj_conf_block_addr != HADDR_UNDEF );
- HDassert( cache_ptr->mdj_conf_block_len > 0 );
- HDassert( cache_ptr->mdj_conf_block_ptr != NULL );
- HDassert( cache_ptr->mdj_file_name_ptr != NULL );
- HDassert( f->shared->mdc_jrnl_block_loc ==
- cache_ptr->mdj_conf_block_addr );
- HDassert( f->shared->mdc_jrnl_block_len ==
- cache_ptr->mdj_conf_block_len );
+ HDassert( cache_ptr->jnl_file_name_len > 0 );
/* Can't journal a read only file, so verify that we are
@@ -1913,27 +1611,19 @@ H5C2_unmark_journaling_in_progress(H5F_t * f,
"File is opened read only.")
}
- /* next, discard the metadata journaling configuration block */
- result = H5C2_discard_journal_config_block(f, dxpl_id);
-
- if ( result != SUCCEED ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_discard_journal_config_block() failed.")
- }
-
- HDassert( cache_ptr->mdj_conf_block_addr == HADDR_UNDEF );
- HDassert( cache_ptr->mdj_conf_block_len == 0 );
- HDassert( cache_ptr->mdj_conf_block_ptr == NULL );
- HDassert( cache_ptr->mdj_file_name_ptr == NULL );
+ /* Discard the journal file name and magic in *cache_ptr */
+ cache_ptr->jnl_magic = 0;
+ cache_ptr->jnl_file_name_len = 0;
+ (cache_ptr->jnl_file_name)[0] = '\0';
/* now, mark f->shared to indicate that journaling is not in
* progress, and then call H5F_super_write_mdj_msg() to write
* the changes to disk.
*/
- f->shared->mdc_jrnl_enabled = FALSE;
- f->shared->mdc_jrnl_block_loc = HADDR_UNDEF;
- f->shared->mdc_jrnl_block_len = 0;
+ f->shared->mdc_jnl_enabled = FALSE;
+ f->shared->mdc_jnl_magic = 0;
+ f->shared->mdc_jnl_file_name_len = 0;
+ (f->shared->mdc_jnl_file_name)[0] = '\0';
if ( H5F_super_write_mdj_msg(f, dxpl_id) < 0 ) {
@@ -2655,134 +2345,277 @@ done:
} /* H5C2_shrink_mdjsc_callback_table() */
-
+
/**************************************************************************/
/********************** journal file management code **********************/
/**************************************************************************/
/******************************************************************************
*
- * Function: H5C2_jb__flush_full_buffers
+ * Function: H5C2_jb__bin2hex
+ *
+ * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
+ * Tuesday, March 4, 2008
+ *
+ * Purpose: Convert binary data into hexadecimal.
+ *
+ * Returns: SUCCEED on success.
+ *
+ ******************************************************************************/
+
+herr_t
+H5C2_jb__bin2hex(const uint8_t * buf,
+ char * hexdata,
+ size_t * hexlength,
+ size_t buf_size)
+
+{
+ size_t v; /* Local index variable */
+ uint8_t c;
+ char * t;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5C2_jb__bin2hex)
+
+ t = hexdata;
+ t[0] = ' ';
+ for (v = 0; v < buf_size; v++) {
+
+ t = &hexdata[v * 3 + 1];
+ c = buf[v];
+ HDsnprintf(t, (size_t)3, "%02x ", c);
+ t[2] = ' ';
+
+ } /* end for */
+ t[3] = '\n';
+ t[4] = 0;
+
+ * hexlength = v * 3 + 2;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+
+} /* end H5C2_jb__bin2hex*/
+
+
+/******************************************************************************
+ *
+ * Function: H5C2_jb__comment
*
* Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
* Wednesday, February 6, 2008
*
- * Purpose: Flush all the dirtied buffers in the ring buffer
- * starting with the buffer referenced by struct_ptr->get
- * and ending with the buffer right before the one
- * referenced by struct_ptr->put.
+ * Purpose: Insert the supplied comment in the journal file. This
+ * call may be ignored if the journal file is machine
+ * readable.
*
* Returns: SUCCEED on success.
*
******************************************************************************/
herr_t
-H5C2_jb__flush_full_buffers(H5C2_jbrb_t * struct_ptr)
+H5C2_jb__comment(H5C2_jbrb_t * struct_ptr,
+ const char * comment_ptr)
{
- hbool_t verbose = FALSE;
- int result;
+ char * temp = NULL;
+ size_t temp_len;
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(H5C2_jb__flush_full_buffers, FAIL)
-
- if ( verbose ) { HDfprintf(stdout, "%s: entering.\n", FUNC); }
+ FUNC_ENTER_NOAPI(H5C2_jb__comment, FAIL)
- /* this asserts that at least one buffer is in use */
- HDassert(struct_ptr->bufs_in_use > 0);
- /* write an assert to verify that at least one buffer is full */
- HDassert( (struct_ptr->put != struct_ptr->get) ||
- (struct_ptr->rb_free_space == 0) );
-
- /* flush all full, dirtied journal buffers to disk */
- if (struct_ptr->get < struct_ptr->put) {
+ /* Check Arguments */
+ HDassert(struct_ptr);
+ HDassert(comment_ptr);
+ HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
+ HDassert(struct_ptr->hdf5_file_name);
- /* can write solid chunk from get up to, but not
- * including, put
- */
- result = HDwrite(struct_ptr->journal_file_fd,
- (*struct_ptr->buf)[struct_ptr->get],
- (struct_ptr->put - struct_ptr->get) * struct_ptr->buf_size);
+ /* Verify that header message is present in journal file or ring buffer.
+ * If not, write it.
+ */
+ if ( struct_ptr->header_present == FALSE ) {
- if ( result == -1 ) {
+ if ( H5C2_jb__write_header_entry(struct_ptr) != SUCCEED ) {
- if ( verbose ) { HDfprintf(stdout, "%s: write failed 1.\n", FUNC); }
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
- "Journal file write failed (1).")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_header_entry() failed.\n")
}
- struct_ptr->bufs_in_use -= (struct_ptr->put - struct_ptr->get);
- struct_ptr->rb_free_space += (struct_ptr->put - struct_ptr->get) * struct_ptr->buf_size;
+ } /* end if */
+
+ temp_len = HDstrlen(comment_ptr) + 11;
+ if ( ( temp = H5MM_malloc(HDstrlen(comment_ptr) + 11) ) == NULL ) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
+ "allocation of temp buffer failed.");
} /* end if */
- else {
+ /* Write comment message */
+ HDsnprintf(temp, temp_len, "C comment %s", comment_ptr);
- /* write from get through end of buffer */
- result = HDwrite(struct_ptr->journal_file_fd,
- (*struct_ptr->buf)[struct_ptr->get],
- (struct_ptr->num_bufs - struct_ptr->get) * struct_ptr->buf_size);
+ if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp, FALSE, struct_ptr->cur_trans ) < 0 ) {
- if ( result == -1 ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_to_buffer() failed.\n")
+ } /* end if */
- if ( verbose ) { HDfprintf(stdout, "%s: write failed 2.\n", FUNC); }
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
- "Journal file write failed (2).")
- }
+ if ( H5C2_jb__write_to_buffer(struct_ptr, 1, "\n", FALSE, struct_ptr->cur_trans ) < 0 ) {
- struct_ptr->bufs_in_use -= (struct_ptr->num_bufs - struct_ptr->get);
- struct_ptr->rb_free_space += (struct_ptr->num_bufs - struct_ptr->get) * struct_ptr->buf_size;
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_to_buffer() failed.\n")
+ } /* end if */
- /* if put = 0, then everything that needs to be flushed will have been
- flushed, so we can stop here. Otherwise, need to flush all buffers
- from the start of the ring buffer's allocated space up to, but not
- including, the buffer indexed by put. */
- if (struct_ptr->put != 0) {
+done:
- result = HDwrite(struct_ptr->journal_file_fd,
- (*struct_ptr->buf)[0],
- (struct_ptr->put) * struct_ptr->buf_size);
+ if ( temp != NULL ) {
- if ( result == -1 ) {
+ temp = H5MM_xfree(temp);
+ if ( temp != NULL ) {
- if ( verbose ) {
- HDfprintf(stdout, "%s: write failed 3.\n", FUNC);
- }
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
- "Journal file write failed(3).")
- } /* end if */
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
+ "free of assembly buffer failed.");
+ }
+ }
- struct_ptr->rb_free_space += (struct_ptr->put * struct_ptr->buf_size);
+ FUNC_LEAVE_NOAPI(ret_value)
- } /* end if */
+} /* end H5C2_jb__comment */
- struct_ptr->bufs_in_use -= struct_ptr->put;
+
+/*****************************************************************************
+ *
+ * Function: H5C2_jb__end_transaction
+ *
+ * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
+ * Wednesday, February 6, 2008
+ *
+ * Purpose: Verify that the supplied transaction is in progress,
+ * and that at least one journal entry has been written
+ * under it. Then construct an end transaction message,
+ * and write it to the current journal buffer. Make note
+ * that the supplied transaction is closed, and that no
+ * transaction is in progress.
+ *
+ * Returns: SUCCEED on success.
+ *
+ *****************************************************************************/
+herr_t
+H5C2_jb__end_transaction(H5C2_jbrb_t * struct_ptr,
+ uint64_t trans_num)
+{
+ char temp[25];
+ herr_t ret_value = SUCCEED;
- } /* end else */
+ FUNC_ENTER_NOAPI(H5C2_jb__end_transaction, FAIL)
+#if 0 /* JRM */
+ HDfprintf(stdout, "%s trans_num = %lld.\n", FUNC, trans_num);
+#endif /* JRM */
+ /* Check Arguments */
+ HDassert(struct_ptr);
+ HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
- HDassert(struct_ptr->bufs_in_use <= 1);
+ /* Verify that the supplied transaction is in progress */
+ if ( ( struct_ptr->trans_in_prog != TRUE ) ||
+ ( struct_ptr->cur_trans != trans_num ) ) {
- /* update get index */
- struct_ptr->get = struct_ptr->put;
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Transaction not in progress or bad transaction number.")
+ } /* end if */
- /* record last transaction number that made it to disk */
- if (struct_ptr->put == 0) {
+ /* Verify that at least one journal entry has been written under
+ * the current transaction
+ */
+ if ( struct_ptr->jentry_written != TRUE ) {
- struct_ptr->last_trans_on_disk =
- (*struct_ptr->trans_tracking)[struct_ptr->num_bufs - 1];
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Empty transaction -- at least one journal entry required.")
+ } /* end if */
- } else {
- struct_ptr->last_trans_on_disk =
- (*struct_ptr->trans_tracking)[struct_ptr->put - 1];
- }
+ /* Prepare end transaction message */
+ HDsnprintf(temp, (size_t)25, "3 end_trans %llu\n", trans_num);
+
+ /* Write end transaction message */
+ if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp,
+ TRUE, trans_num ) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_to_buffer() failed.\n")
+ } /* end if */
+
+ /* reset boolean flag indicating if at least one journal entry has
+ * been written under transaction
+ */
+ struct_ptr->jentry_written = FALSE;
+
+ /* Close current transaction */
+ struct_ptr->trans_in_prog = FALSE;
done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
- if ( verbose ) { HDfprintf(stdout, "%s: exiting.\n", FUNC); }
+} /* end H5C2_jb__end_transaction */
+
+
+/******************************************************************************
+ *
+ * Function: H5C2_jb__eoa
+ *
+ * Programmer: Mike McGreevy <mamcgree@hdfgroup.org>
+ * July 29, 2008
+ *
+ * Purpose: Insert the supplied EOA into the journal file.
+ *
+ * Returns: SUCCEED on success.
+ *
+ ******************************************************************************/
+
+herr_t
+H5C2_jb__eoa(H5C2_jbrb_t * struct_ptr,
+ haddr_t eoa)
+{
+ char temp[40];
+ size_t temp_len = 40;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5C2_jb__eoa, FAIL)
+
+ /* Check Arguments */
+ HDassert(struct_ptr);
+ HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
+ HDassert(struct_ptr->hdf5_file_name);
+
+ /* Verify that header message is present in journal file or ring buffer.
+ * If not, write it.
+ */
+ if ( struct_ptr->header_present == FALSE ) {
+
+ if ( H5C2_jb__write_header_entry(struct_ptr) != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_header_entry() failed.\n")
+ }
+ } /* end if */
+
+ /* Write EOA message */
+ HDsnprintf(temp, temp_len, "E eoa_value 0x%llx", eoa);
+
+ if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp, FALSE, struct_ptr->cur_trans ) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_to_buffer() failed.\n")
+ } /* end if */
+
+ if ( H5C2_jb__write_to_buffer(struct_ptr, 1, "\n", FALSE,
+ struct_ptr->cur_trans ) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_to_buffer() failed.\n")
+ } /* end if */
+
+done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5C2_jb__flush_full_buffers */
+} /* end H5C2_jb__eoa */
/******************************************************************************
@@ -2934,279 +2767,188 @@ done:
/******************************************************************************
*
- * Function: H5C2_jb__write_to_buffer
+ * Function: H5C2_jb__flush_full_buffers
*
* Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
* Wednesday, February 6, 2008
*
- * Purpose: Put the contents of data into the journal buffers. This
- * is done as follows: While the data to be written is
- * larger than the amount of space left in the ring buffer,
- * the ring buffer is filled to capacity with data and
- * flushed. This repeats until the unwritten data remaining
- * can fit in the ring buffer without having to loop around
- * to the top.
- *
- * At this point, the rest of the data can just be written
- * without having to break it up further. In the event
- * the data covers more than one journal buffer, the get
- * and put indices are updated to state this fact. Any
- * journal buffers that were filled during the write are
- * flushed.
+ * Purpose: Flush all the dirtied buffers in the ring buffer
+ * starting with the buffer referenced by struct_ptr->get
+ * and ending with the buffer right before the one
+ * referenced by struct_ptr->put.
*
* Returns: SUCCEED on success.
*
******************************************************************************/
herr_t
-H5C2_jb__write_to_buffer(H5C2_jbrb_t * struct_ptr,
- size_t size,
- const char * data,
- hbool_t is_end_trans,
- uint64_t trans_num)
+H5C2_jb__flush_full_buffers(H5C2_jbrb_t * struct_ptr)
{
+ hbool_t verbose = FALSE;
+ int result;
herr_t ret_value = SUCCEED;
- unsigned long track_last_trans = 0;
- int oldput = 0;
- int i;
-
- FUNC_ENTER_NOAPI(H5C2_jb__write_to_buffer, FAIL)
- /* Check Arguments */
- HDassert(struct_ptr);
- HDassert(data);
- HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
- HDassert(HDstrlen(data) == size);
- HDassert(struct_ptr->rb_space_to_rollover <=
- struct_ptr->num_bufs * struct_ptr->buf_size);
- HDassert(struct_ptr->rb_space_to_rollover > 0);
-
- /* If the data size exceeds the bounds of the ring buffer's allocated
- * memory, loop around to top
- */
- if (size >= struct_ptr->rb_space_to_rollover) {
-
- while (size >= struct_ptr->rb_space_to_rollover) {
-
- /* Assertions */
- HDassert(size != 0);
- HDassert(HDstrlen(data) >= struct_ptr->rb_space_to_rollover);
-
- /* fill up remaining space in the ring buffer */
- HDmemcpy(struct_ptr->head, data, struct_ptr->rb_space_to_rollover);
-
- /* move head to point to start of ring buffer */
- struct_ptr->head = (*struct_ptr->buf)[0];
-
- /* make note of last transaction on disk */
- track_last_trans = (*struct_ptr->trans_tracking)[struct_ptr->put];
-
- /* update rb_free_space */
- struct_ptr->rb_free_space -= struct_ptr->rb_space_to_rollover;
-
- /* Fill out the remainder of the trans_tracking array with
- the most recent transaction in the array.*/
- (*struct_ptr->trans_tracking)[0] = track_last_trans;
- for (i=struct_ptr->put; i<struct_ptr->num_bufs; i++)
- {
- (*struct_ptr->trans_tracking)[i] = track_last_trans;
- }
-
- /* reset put index */
- struct_ptr->put = 0;
-
- /* update bufs_in_use as necessary */
- struct_ptr->bufs_in_use = struct_ptr->num_bufs - struct_ptr->get;
-
- /* check to see if trans_tracking needs to be updated. If so,
- then update it */
- if ((size == struct_ptr->rb_space_to_rollover) &&
- (is_end_trans == TRUE)) {
-
- (*struct_ptr->trans_tracking)[struct_ptr->num_bufs - 1]
- = trans_num;
- (*struct_ptr->trans_tracking)[0] = trans_num;
- }
-
- /* flush buffers */
- if ( H5C2_jb__flush_full_buffers(struct_ptr) < 0 ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__flush_full_buffers() failed.\n")
- }
-
- /* update remaining size of data to be written */
- size = size - struct_ptr->rb_space_to_rollover;
-
- /* update the data pointer to point to the remaining data to be
- * written
- */
- data = &data[struct_ptr->rb_space_to_rollover];
-
- /* update the amount of space left at end of ring buffer */
- struct_ptr->rb_space_to_rollover =
- struct_ptr->buf_size * struct_ptr->num_bufs;
-
- /* update the amount of space in the current buffer */
- struct_ptr->cur_buf_free_space = struct_ptr->buf_size;
+ FUNC_ENTER_NOAPI(H5C2_jb__flush_full_buffers, FAIL)
- } /* end while */
- } /* end if */
+ if ( verbose ) { HDfprintf(stdout, "%s: entering.\n", FUNC); }
- /* If the size of the data exceeds the bounds of a single journal
- * buffer, will write into multiple
- */
- if (size > struct_ptr->cur_buf_free_space) {
+ /* this asserts that at least one buffer is in use */
+ HDassert(struct_ptr->bufs_in_use > 0);
+ /* write an assert to verify that at least one buffer is full */
+ HDassert( (struct_ptr->put != struct_ptr->get) ||
+ (struct_ptr->rb_free_space == 0) );
- HDassert(struct_ptr->cur_buf_free_space != 0);
+ /* flush all full, dirtied journal buffers to disk */
+ if (struct_ptr->get < struct_ptr->put) {
- /* write data into journal buffers */
- HDmemcpy(struct_ptr->head, data, size);
+ /* can write solid chunk from get up to, but not
+ * including, put
+ */
+ result = HDwrite(struct_ptr->journal_file_fd,
+ (*struct_ptr->buf)[struct_ptr->get],
+ (struct_ptr->put - struct_ptr->get) *
+ struct_ptr->buf_size);
- /* update head pointer */
- struct_ptr->head = &struct_ptr->head[size];
+ if ( result == -1 ) {
- /* make note of last transaction on disk */
- track_last_trans = (*struct_ptr->trans_tracking)[struct_ptr->put];
- oldput = struct_ptr->put;
+ if ( verbose ) { HDfprintf(stdout, "%s: write failed 1.\n", FUNC); }
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
+ "Journal file write failed (1).")
+ }
- /* update rb_free_space */
- struct_ptr->rb_free_space -= size;
+ struct_ptr->bufs_in_use -= (struct_ptr->put - struct_ptr->get);
+ struct_ptr->rb_free_space += (struct_ptr->put - struct_ptr->get) * struct_ptr->buf_size;
- /* update put index */
- struct_ptr->put +=
- (size-struct_ptr->cur_buf_free_space)/(struct_ptr->buf_size) + 1;
+ } /* end if */
- /* Drag the last transaction in a filled buffer value residing in the
- old put location through the trans_tracking array to the new
- corresponding put position. */
- for (i=oldput; i<struct_ptr->put+1; i++)
- {
- (*struct_ptr->trans_tracking)[i] = track_last_trans;
- }
+ else {
- /* update current buffer usage */
- struct_ptr->cur_buf_free_space =
- struct_ptr->rb_space_to_rollover - size -
- (struct_ptr->num_bufs - (struct_ptr->put + 1)) *
- (struct_ptr->buf_size );
+ /* write from get through end of buffer */
+ result = HDwrite(struct_ptr->journal_file_fd,
+ (*struct_ptr->buf)[struct_ptr->get],
+ (struct_ptr->num_bufs - struct_ptr->get) * struct_ptr->buf_size);
- /* update bufs_in_use as necessary */
- struct_ptr->bufs_in_use = struct_ptr->put - struct_ptr->get;
- if (struct_ptr->cur_buf_free_space < struct_ptr->buf_size) {
+ if ( result == -1 ) {
- struct_ptr->bufs_in_use++;
+ if ( verbose ) { HDfprintf(stdout, "%s: write failed 2.\n", FUNC); }
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
+ "Journal file write failed (2).")
}
- /* check to see if trans_tracking needs to be updated. If so,
- then update it */
- if (is_end_trans == TRUE) {
-
- if (struct_ptr->cur_buf_free_space == struct_ptr->buf_size) {
- (*struct_ptr->trans_tracking)[struct_ptr->put - 1] = trans_num;
- }
- else {
- (*struct_ptr->trans_tracking)[struct_ptr->put] = trans_num;
- }
-
- } /* end if */
+ struct_ptr->bufs_in_use -= (struct_ptr->num_bufs - struct_ptr->get);
+ struct_ptr->rb_free_space += (struct_ptr->num_bufs - struct_ptr->get) *
+ struct_ptr->buf_size;
- /* flush buffers */
- if ( H5C2_jb__flush_full_buffers(struct_ptr) < 0 ) {
+ /* if put = 0, then everything that needs to be flushed will have been
+ * flushed, so we can stop here. Otherwise, need to flush all buffers
+ * from the start of the ring buffer's allocated space up to, but not
+ * including, the buffer indexed by put.
+ */
+ if (struct_ptr->put != 0) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__flush_full_buffers() failed.\n")
- }
+ result = HDwrite(struct_ptr->journal_file_fd,
+ (*struct_ptr->buf)[0],
+ (struct_ptr->put) * struct_ptr->buf_size);
- /* update space left at end of ring buffer */
- struct_ptr->rb_space_to_rollover -= size;
+ if ( result == -1 ) {
- } /* end if */
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: write failed 3.\n", FUNC);
+ }
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, \
+ "Journal file write failed(3).")
+ } /* end if */
- /* if the data can fit in the remaining space in the current journal
- * buffer indexed by put
- */
- else if (size > 0) {
+ struct_ptr->rb_free_space += (struct_ptr->put * struct_ptr->buf_size);
- HDassert(size <= struct_ptr->cur_buf_free_space);
-
- /* write data into journal buffer */
- HDmemcpy(struct_ptr->head, data, size);
+ } /* end if */
- /* increment bufs_in_use as necessary */
- if ( ( struct_ptr->bufs_in_use == 0 ) ) {
+ struct_ptr->bufs_in_use -= struct_ptr->put;
- struct_ptr->bufs_in_use++;
- }
+ } /* end else */
+
+ HDassert(struct_ptr->bufs_in_use <= 1);
- /* update head pointer */
- struct_ptr->head = &struct_ptr->head[size];
+ /* update get index */
+ struct_ptr->get = struct_ptr->put;
+
+ /* record last transaction number that made it to disk */
+ if (struct_ptr->put == 0) {
- /* update rb_free_space */
- struct_ptr->rb_free_space -= size;
+ struct_ptr->last_trans_on_disk =
+ (*struct_ptr->trans_tracking)[struct_ptr->num_bufs - 1];
- /* update current buffer usage */
- struct_ptr->cur_buf_free_space -= size;
+ } else {
- /* update end of buffer space */
- struct_ptr->rb_space_to_rollover -= size;
-
- /* check to see if trans_tracking needs to be updated. If so,
- then update it */
- if (is_end_trans == TRUE) {
-
- (*struct_ptr->trans_tracking)[struct_ptr->put]
- = trans_num;
- } /* end if */
+ struct_ptr->last_trans_on_disk =
+ (*struct_ptr->trans_tracking)[struct_ptr->put - 1];
+ }
- /* if buffer is full, flush it, and loop to the top of the
- * ring buffer if at the end.
- */
- if (struct_ptr->cur_buf_free_space == 0) {
+done:
- if ( struct_ptr->put != (struct_ptr->num_bufs - 1) ) {
- struct_ptr->put += 1;
+ if ( verbose ) { HDfprintf(stdout, "%s: exiting.\n", FUNC); }
- /* Drag trans_tracking value into next buffer */
- (*struct_ptr->trans_tracking)[struct_ptr->put]
- = (*struct_ptr->trans_tracking)[struct_ptr->put - 1];
+ FUNC_LEAVE_NOAPI(ret_value)
- } /* end if */
-
- else {
+} /* end H5C2_jb__flush_full_buffers */
- struct_ptr->put = 0;
+
+/******************************************************************************
+ *
+ * Function: H5C2_jb__get_last_transaction_on_disk
+ *
+ * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
+ * Wednesday, February 6, 2008
+ *
+ * Purpose: Lookup the number of the last transaction to have been
+ * fully written to disk, and place its transaction
+ * number in *trans_num_ptr. If no transaction has made
+ * it to disk, load zero into *trans_num_ptr.
+ *
+ * Returns: SUCCEED on success.
+ *
+ ******************************************************************************/
- /* Drag trans_tracking value into next buffer */
- (*struct_ptr->trans_tracking)[0]
- = (*struct_ptr->trans_tracking)[struct_ptr->num_bufs - 1];
+herr_t
+H5C2_jb__get_last_transaction_on_disk(H5C2_jbrb_t * struct_ptr,
+ uint64_t * trans_num_ptr)
+{
+ herr_t ret_value = SUCCEED;
- /* reset head pointer and free space values */
- struct_ptr->head = (*struct_ptr->buf)[0];
- struct_ptr->rb_space_to_rollover =
- struct_ptr->buf_size * struct_ptr->num_bufs;
+ FUNC_ENTER_NOAPI(H5C2_jb__get_last_transaction_on_disk, FAIL)
+
+ /* Check Arguments */
+ HDassert( trans_num_ptr != NULL );
- } /* end else */
+ /* This should really be an assert, but the func enter/exit
+ * macros get testy if there isn't at least one goto error
+ * macro call in the funtion.
+ */
+ if ( ( struct_ptr == NULL ) ||
+ ( struct_ptr->magic != H5C2__H5C2_JBRB_T_MAGIC ) ) {
- if ( H5C2_jb__flush_full_buffers(struct_ptr) < 0 ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "bad struct_ptr.")
+ }
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__flush_full_buffers() failed.\n")
- } /* end if */
+ /* JRM: In machine readable version, lets check to see if a sync is
+ * necessary, and call it only if it is.
+ */
+ /* perform a sync to ensure everything gets to disk before continuing */
+ /* Note: there is no HDfsync function, so for now, the standard
+ fsync is being used. */
+ if ( fsync(struct_ptr->journal_file_fd) < 0 ) {
- struct_ptr->cur_buf_free_space = struct_ptr->buf_size;
+ HGOTO_ERROR(H5E_IO, H5E_SYNCFAIL, FAIL, "Jounal file sync failed.")
- } /* end if */
+ } /* end if */
- } /* end else */
-
- HDassert(struct_ptr->bufs_in_use <= struct_ptr->num_bufs);
+ * trans_num_ptr = struct_ptr->last_trans_on_disk;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5C2_jb__write_to_buffer */
+} /* end H5C2_jb__get_last_transaction_on_disk */
/******************************************************************************
@@ -3224,10 +2966,19 @@ done:
*
* Returns: SUCCEED on success.
*
+ * Changes: JRM -- 2/10/09
+ * Added the journal_magic parameter and related code.
+ *
+ * Also deleted code to write the header message.
+ * Since the base address of the journal magic in
+ * the HDF5 file isn't available at this time, wait
+ * until our first real entry to write the header.
+ *
******************************************************************************/
herr_t
H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
+ const int32_t journal_magic,
const char * HDF5_file_name,
const char * journal_file_name,
size_t buf_size,
@@ -3243,16 +2994,60 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
FUNC_ENTER_NOAPI(H5C2_jb__init, FAIL)
/* Check Arguments */
- HDassert(struct_ptr);
- HDassert(HDF5_file_name);
- HDassert(journal_file_name);
- HDassert(buf_size > 0);
- HDassert(num_bufs > 0);
- HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
+ HDassert( struct_ptr );
+ HDassert( HDF5_file_name );
+ HDassert( journal_file_name );
+ HDassert( buf_size > 0 );
+ HDassert( num_bufs > 0 );
+ HDassert( struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC );
+
+ /* Initialize Fields of H5C2_jbrb_t structure. Note that we will
+ * overwrite some of these initializations almost immediately.
+ */
+ struct_ptr->journal_magic = journal_magic;
+ struct_ptr->journal_file_fd = -1;
+ struct_ptr->num_bufs = num_bufs;
+ struct_ptr->buf_size = buf_size;
+ struct_ptr->bufs_in_use = 0;
+ struct_ptr->jvers = H5C2__JOURNAL_VERSION;
+ struct_ptr->get = 0;
+ struct_ptr->put = 0;
+ struct_ptr->jentry_written = FALSE;
+ struct_ptr->use_aio = use_aio;
+ struct_ptr->human_readable = human_readable;
+ struct_ptr->journal_is_empty = TRUE;
+ struct_ptr->cur_trans = 0;
+ struct_ptr->last_trans_on_disk = 0;
+ struct_ptr->trans_in_prog = FALSE;
+ struct_ptr->jname = HDstrdup(journal_file_name);
+
+ if ( struct_ptr->jname == NULL ) {
+
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
+ "allocation of space for copy of journal_file_name failed.");
+ }
+
+ struct_ptr->hdf5_file_name = HDstrdup(HDF5_file_name);
+
+ if ( struct_ptr->jname == NULL ) {
+
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
+ "allocation of space for copy of HDF5_file_name failed.");
+ }
+
+ struct_ptr->header_present = FALSE;
+ struct_ptr->cur_buf_free_space = buf_size;
+ struct_ptr->rb_space_to_rollover = num_bufs * buf_size;
+ struct_ptr->rb_free_space = num_bufs * buf_size;
+ struct_ptr->head = NULL;
+ struct_ptr->trans_tracking = NULL;
+ struct_ptr->buf = NULL;
+
/* Open journal file */
struct_ptr->journal_file_fd =
HDopen(journal_file_name, O_WRONLY|O_CREAT|O_EXCL, 0777);
+
if ( struct_ptr->journal_file_fd == -1) {
HDfprintf(stdout,
@@ -3262,28 +3057,6 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
"Can't create journal file. Does it already exist?")
} /* end if */
- /* Initialize Fields of H5C2_jbrb_t structure */
- /* this should be modified to check error returns, etc. Also, should
- * probably do the same with the HDF5 file name.
- */
- struct_ptr->jname = HDstrdup(journal_file_name);
- struct_ptr->hdf5_file_name = HDF5_file_name;
- struct_ptr->buf_size = buf_size;
- struct_ptr->num_bufs = num_bufs;
- struct_ptr->use_aio = use_aio;
- struct_ptr->human_readable = human_readable;
- struct_ptr->bufs_in_use = 0;
- struct_ptr->trans_in_prog = FALSE;
- struct_ptr->get = 0;
- struct_ptr->put = 0;
- struct_ptr->jvers = H5C2__JOURNAL_VERSION;
- struct_ptr->cur_trans = 0;
- struct_ptr->last_trans_on_disk = 0;
- struct_ptr->cur_buf_free_space = struct_ptr->buf_size;
- struct_ptr->rb_free_space = struct_ptr->num_bufs * struct_ptr->buf_size;
- struct_ptr->rb_space_to_rollover = struct_ptr->num_bufs * struct_ptr->buf_size;
- struct_ptr->jentry_written = FALSE;
- struct_ptr->journal_is_empty = TRUE;
/* Allocate space for the ring buffer's journal buffer pointers */
struct_ptr->buf = H5MM_malloc(struct_ptr->num_bufs * sizeof(char *));
@@ -3334,7 +3107,7 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
/* Make journal buffer pointers point to the right location in
* chunk of allocated memory above
*/
- for (i=1; i<struct_ptr->num_bufs; i++)
+ for ( i = 1; i < struct_ptr->num_bufs; i++ )
{
(*struct_ptr->buf)[i] =
&((*struct_ptr->buf)[0])[i * struct_ptr->buf_size];
@@ -3342,141 +3115,18 @@ H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
/* Define head pointer to point at where we are writing to in the buffer */
struct_ptr->head = (*struct_ptr->buf)[struct_ptr->put];
-
- /* Get the current date */
- current_date = time(NULL);
-
- /* Format the header message into a temporary buffer */
- HDsnprintf(temp,
- (size_t)150,
- "0 ver_num %ld target_file_name %s creation_date %10.10s human_readable %d\n",
- struct_ptr->jvers,
- struct_ptr->hdf5_file_name,
- ctime(&current_date),
- struct_ptr->human_readable);
-
- /* Write the header message into the ring buffer */
- if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp, FALSE,
- (uint64_t)0) < 0) {
-
- HDfprintf(stdout,
- "%s: H5C2_jb__write_to_buffer() failed.\n",
- FUNC);
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
-
- /* Update boolean flags */
- struct_ptr->header_present = TRUE;
- struct_ptr->journal_is_empty = FALSE;
-
-done:
-
- FUNC_LEAVE_NOAPI(ret_value)
-
-} /* end H5C2_jb__init */
-
-
-/******************************************************************************
- *
- * Function: H5C2_jb__start_transaction
- *
- * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
- * Wednesday, February 6, 2008
- *
- * Purpose: Verify that there is no transaction in progress, and
- * that the supplied transaction number greater than
- * the last. Then construct a start transaction message,
- * and write it to the current journal buffer. Make note
- * of the fact that the supplied transaction is in
- * progress.
- *
- * Returns: SUCCEED on success.
- *
- ******************************************************************************/
-
-herr_t
-H5C2_jb__start_transaction(H5C2_jbrb_t * struct_ptr,
- uint64_t trans_num)
-
-{
- char temp[150];
- herr_t ret_value = SUCCEED;
- time_t current_date;
-
- FUNC_ENTER_NOAPI(H5C2_jb__start_transaction, FAIL)
#if 0 /* JRM */
- HDfprintf(stdout, "%s trans_num = %lld.\n", FUNC, trans_num);
-#endif /* JRM */
- /* Check Arguments */
- HDassert(struct_ptr);
- HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
-
- /* Verify that there is no transaction in progress */
- if ( struct_ptr->trans_in_prog != FALSE ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "Transaction already in progress.")
- } /* end if */
-
- /* JRM: Heads up: we may relax this constraint to rquire that the
- * new transaction number is greater than the old, but possibly
- * not the next integer in sequence. Will this cause problems
- * with testing?
- */
-
- /* Verify that the supplied transaction number greater than the last */
- if ( (struct_ptr->cur_trans) >= trans_num ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "New transaction out of sequence.")
- } /* end if */
-
- /* Verify that header message is present in journal file or ring buffer.
- * If not, write it.
- */
- if ( struct_ptr->header_present == FALSE ) {
-
- /* Get the current date */
- current_date = time(NULL);
-
- HDsnprintf(temp,
- (size_t)150,
- "0 ver_num %ld target_file_name %s creation_date %10.10s human_readable %d\n",
- struct_ptr->jvers,
- struct_ptr->hdf5_file_name,
- ctime(&current_date),
- struct_ptr->human_readable);
-
- if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp,
- FALSE, trans_num) < 0 ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
-
- struct_ptr->header_present = 1;
- struct_ptr->journal_is_empty = 0;
- } /* end if */
-
- /* Write start transaction message */
- HDsnprintf(temp, (size_t)150, "1 bgn_trans %llu\n", trans_num);
- if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp,
- FALSE, trans_num) < 0 ) {
+ if ( H5C2_jb__write_header_entry(struct_ptr) != SUCCEED ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
-
- /* Make note of the fact that supplied transaction is in progress */
- struct_ptr->trans_in_prog = TRUE;
- struct_ptr->cur_trans = trans_num;
-
+ "H5C2_jb__write_header_entry() failed.\n")
+ }
+#endif /* JRM */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5C2_jb__start_transaction */
+} /* end H5C2_jb__init */
/******************************************************************************
@@ -3615,31 +3265,34 @@ done:
} /* end H5C2_jb__journal_entry */
-/*****************************************************************************
+/******************************************************************************
*
- * Function: H5C2_jb__end_transaction
+ * Function: H5C2_jb__start_transaction
*
* Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
* Wednesday, February 6, 2008
*
- * Purpose: Verify that the supplied transaction is in progress,
- * and that at least one journal entry has been written
- * under it. Then construct an end transaction message,
+ * Purpose: Verify that there is no transaction in progress, and
+ * that the supplied transaction number greater than
+ * the last. Then construct a start transaction message,
* and write it to the current journal buffer. Make note
- * that the supplied transaction is closed, and that no
- * transaction is in progress.
+ * of the fact that the supplied transaction is in
+ * progress.
*
* Returns: SUCCEED on success.
*
- *****************************************************************************/
-herr_t
-H5C2_jb__end_transaction(H5C2_jbrb_t * struct_ptr,
- uint64_t trans_num)
+ ******************************************************************************/
+
+herr_t
+H5C2_jb__start_transaction(H5C2_jbrb_t * struct_ptr,
+ uint64_t trans_num)
+
{
- char temp[25];
+ char temp[150];
herr_t ret_value = SUCCEED;
+ time_t current_date;
- FUNC_ENTER_NOAPI(H5C2_jb__end_transaction, FAIL)
+ FUNC_ENTER_NOAPI(H5C2_jb__start_transaction, FAIL)
#if 0 /* JRM */
HDfprintf(stdout, "%s trans_num = %lld.\n", FUNC, trans_num);
#endif /* JRM */
@@ -3647,286 +3300,229 @@ H5C2_jb__end_transaction(H5C2_jbrb_t * struct_ptr,
HDassert(struct_ptr);
HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
- /* Verify that the supplied transaction is in progress */
- if ( ( struct_ptr->trans_in_prog != TRUE ) ||
- ( struct_ptr->cur_trans != trans_num ) ) {
+ /* Verify that there is no transaction in progress */
+ if ( struct_ptr->trans_in_prog != FALSE ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "Transaction not in progress or bad transaction number.")
+ "Transaction already in progress.")
} /* end if */
-
- /* Verify that at least one journal entry has been written under
- * the current transaction
+
+ /* JRM: Heads up: we may relax this constraint to rquire that the
+ * new transaction number is greater than the old, but possibly
+ * not the next integer in sequence. Will this cause problems
+ * with testing?
*/
- if ( struct_ptr->jentry_written != TRUE ) {
+
+ /* Verify that the supplied transaction number greater than the last */
+ if ( (struct_ptr->cur_trans) >= trans_num ) {
HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "Empty transaction -- at least one journal entry required.")
+ "New transaction out of sequence.")
} /* end if */
+ /* Verify that header message is present in journal file or ring buffer.
+ * If not, write it.
+ */
+ if ( struct_ptr->header_present == FALSE ) {
- /* Prepare end transaction message */
- HDsnprintf(temp, (size_t)25, "3 end_trans %llu\n", trans_num);
+ if ( H5C2_jb__write_header_entry(struct_ptr) != SUCCEED ) {
- /* Write end transaction message */
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_header_entry() failed.\n")
+ }
+
+ } /* end if */
+
+ /* Write start transaction message */
+ HDsnprintf(temp, (size_t)150, "1 bgn_trans %llu\n", trans_num);
if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp,
- TRUE, trans_num ) < 0 ) {
+ FALSE, trans_num) < 0 ) {
HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
"H5C2_jb__write_to_buffer() failed.\n")
} /* end if */
-
- /* reset boolean flag indicating if at least one journal entry has
- * been written under transaction
- */
- struct_ptr->jentry_written = FALSE;
-
- /* Close current transaction */
- struct_ptr->trans_in_prog = FALSE;
+
+ /* Make note of the fact that supplied transaction is in progress */
+ struct_ptr->trans_in_prog = TRUE;
+ struct_ptr->cur_trans = trans_num;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5C2_jb__end_transaction */
+} /* end H5C2_jb__start_transaction */
/******************************************************************************
*
- * Function: H5C2_jb__comment
+ * Function: H5C2_jb__takedown
*
* Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
- * Wednesday, February 6, 2008
+ * Thursday, February 7, 2008
*
- * Purpose: Insert the supplied comment in the journal file. This
- * call may be ignored if the journal file is machine
- * readable.
+ * Purpose: Verify that the journal buffers are empty, and that the
+ * journal file has been truncated. Then close and delete
+ * the journal file associated with *struct_ptr, and free
+ * all dynamically allocated memory associated with
+ * *struct_ptr.
*
* Returns: SUCCEED on success.
*
******************************************************************************/
herr_t
-H5C2_jb__comment(H5C2_jbrb_t * struct_ptr,
- const char * comment_ptr)
+H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
+
{
- char * temp = NULL;
- size_t temp_len;
herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5C2_jb__comment, FAIL)
+ hbool_t verbose = FALSE;
+ FUNC_ENTER_NOAPI(H5C2_jb__takedown, FAIL)
+
+ if ( verbose ) {
+
+ HDfprintf(stdout, "%s: entering.\n", FUNC);
+ }
+
/* Check Arguments */
HDassert(struct_ptr);
- HDassert(comment_ptr);
HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
- HDassert(struct_ptr->hdf5_file_name);
-
- /* Verify that header message is present in journal file or ring buffer.
- * If not, write it.
- */
- if ( struct_ptr->header_present == FALSE ) {
-
- char buf[150];
- time_t current_date;
+
+ /* Verify that the journal buffers are empty */
+ if ( struct_ptr->bufs_in_use != 0 ) {
- /* Get the current date */
- current_date = time(NULL);
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: Attempt to takedown with non-empty buffers.\n",
+ FUNC);
+ }
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Attempt to takedown with non-empty buffers.")
+ } /* end if */
- HDsnprintf(buf,
- (size_t)150,
- "0 ver_num %ld target_file_name %s creation_date %10.10s human_readable %d\n",
- struct_ptr->jvers,
- struct_ptr->hdf5_file_name,
- ctime(&current_date),
- struct_ptr->human_readable);
+ /* Verify that the journal file has been truncated */
+ if (struct_ptr->journal_is_empty != TRUE) {
- if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(buf), buf,
- FALSE, struct_ptr->cur_trans) < 0 ) {
+ if ( verbose ) {
+ HDfprintf(stdout,
+ "%s: Attempt to takedown with journal file not truncated.\n",
+ FUNC);
+ }
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Attempt to takedown with journal file not truncated.")
+ } /* end if */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
+ /* Close and delete the journal file associated with struct_ptr */
+ if ( HDclose(struct_ptr->journal_file_fd) < 0 ) {
- struct_ptr->header_present = 1;
- struct_ptr->journal_is_empty = 0;
+ if ( verbose ) {
+ HDfprintf(stdout,
+ "%s: journal file close failed. errno = %d(%s), fd = %d.\n",
+ FUNC, errno, strerror(errno), struct_ptr->journal_file_fd);
+ }
+ HGOTO_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "Jounal file close failed.")
} /* end if */
- temp_len = HDstrlen(comment_ptr) + 11;
- if ( ( temp = H5MM_malloc(HDstrlen(comment_ptr) + 11) ) == NULL ) {
+ if ( HDremove(struct_ptr->jname) < 0) {
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
- "allocation of temp buffer failed.");
+ if ( verbose ) {
+ HDfprintf(stdout,
+ "%s: journal file remove failed. errno = %d(%s).\n",
+ FUNC, errno, strerror(errno));
+ }
+ HGOTO_ERROR(H5E_IO, H5E_REMOVEFAIL, FAIL, "Jounal file close failed.")
} /* end if */
- /* Write comment message */
- HDsnprintf(temp, temp_len, "C comment %s", comment_ptr);
-
- if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp, FALSE, struct_ptr->cur_trans ) < 0 ) {
+ /* Free all memory associated with struct_ptr */
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
+ if ( struct_ptr->jname != NULL ) {
- if ( H5C2_jb__write_to_buffer(struct_ptr, 1, "\n", FALSE, struct_ptr->cur_trans ) < 0 ) {
+ struct_ptr->jname = H5MM_xfree(struct_ptr->jname);
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
+ if ( struct_ptr->jname != NULL ) {
-done:
+ if ( verbose ) {
- if ( temp != NULL ) {
+ HDfprintf(stdout, "%s: free of jname failed.\n", FUNC);
- temp = H5MM_xfree(temp);
- if ( temp != NULL ) {
+ }
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "free of assembly buffer failed.");
+ "free of jname failed.");
}
}
- FUNC_LEAVE_NOAPI(ret_value)
+ if ( struct_ptr->hdf5_file_name != NULL ) {
-} /* end H5C2_jb__comment */
+ struct_ptr->hdf5_file_name = H5MM_xfree(struct_ptr->hdf5_file_name);
-
-/******************************************************************************
- *
- * Function: H5C2_jb__eoa
- *
- * Programmer: Mike McGreevy <mamcgree@hdfgroup.org>
- * July 29, 2008
- *
- * Purpose: Insert the supplied EOA into the journal file.
- *
- * Returns: SUCCEED on success.
- *
- ******************************************************************************/
+ if ( struct_ptr->hdf5_file_name != NULL ) {
-herr_t
-H5C2_jb__eoa(H5C2_jbrb_t * struct_ptr,
- haddr_t eoa)
-{
- char temp[40];
- size_t temp_len = 40;
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5C2_jb__eoa, FAIL)
-
- /* Check Arguments */
- HDassert(struct_ptr);
- HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
- HDassert(struct_ptr->hdf5_file_name);
-
- /* Verify that header message is present in journal file or ring buffer.
- * If not, write it.
- */
- if ( struct_ptr->header_present == FALSE ) {
-
- char buf[150];
- time_t current_date;
-
- /* Get the current date */
- current_date = time(NULL);
-
- HDsnprintf(buf,
- (size_t)150,
- "0 ver_num %ld target_file_name %s creation_date %10.10s human_readable %d\n",
- struct_ptr->jvers,
- struct_ptr->hdf5_file_name,
- ctime(&current_date),
- struct_ptr->human_readable);
-
- if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(buf), buf,
- FALSE, struct_ptr->cur_trans) < 0 ) {
-
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
+ if ( verbose ) {
- struct_ptr->header_present = 1;
- struct_ptr->journal_is_empty = 0;
- } /* end if */
+ HDfprintf(stdout, "%s: free of hdf5_file_name failed.\n", FUNC);
- /* Write EOA message */
- HDsnprintf(temp, temp_len, "E eoa_value 0x%llx", eoa);
+ }
- if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(temp), temp, FALSE, struct_ptr->cur_trans ) < 0 ) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
+ "free of hdf5_file_name failed.");
+ }
+ }
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
+ if ( (*struct_ptr->buf)[0] != NULL ) {
- if ( H5C2_jb__write_to_buffer(struct_ptr, 1, "\n", FALSE, struct_ptr->cur_trans ) < 0 ) {
+ (*struct_ptr->buf)[0] = H5MM_xfree((*struct_ptr->buf)[0]);
+ if ( (*struct_ptr->buf)[0] != NULL ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
- "H5C2_jb__write_to_buffer() failed.\n")
- } /* end if */
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: free of buffers failed.\n", FUNC);
+ }
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
+ "free of buffers failed.");
+ }
+ }
-done:
+ if ( struct_ptr->buf != NULL ) {
- FUNC_LEAVE_NOAPI(ret_value)
+ struct_ptr->buf = H5MM_xfree(struct_ptr->buf);
+ if ( struct_ptr->buf != NULL ) {
-} /* end H5C2_jb__eoa */
+ if ( verbose ) {
+ HDfprintf(stdout, "%s: free of buffer ptr array faileid.\n",
+ FUNC);
+ }
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
+ "free of buffer pointer array failed.");
+ }
+ }
-
-/******************************************************************************
- *
- * Function: H5C2_jb__get_last_transaction_on_disk
- *
- * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
- * Wednesday, February 6, 2008
- *
- * Purpose: Lookup the number of the last transaction to have been
- * fully written to disk, and place its transaction
- * number in *trans_num_ptr. If no transaction has made
- * it to disk, load zero into *trans_num_ptr.
- *
- * Returns: SUCCEED on success.
- *
- ******************************************************************************/
+ if ( struct_ptr->trans_tracking != NULL ) {
-herr_t
-H5C2_jb__get_last_transaction_on_disk(H5C2_jbrb_t * struct_ptr,
- uint64_t * trans_num_ptr)
-{
- herr_t ret_value = SUCCEED;
+ struct_ptr->trans_tracking = H5MM_xfree(struct_ptr->trans_tracking);
- FUNC_ENTER_NOAPI(H5C2_jb__get_last_transaction_on_disk, FAIL)
-
- /* Check Arguments */
- HDassert( trans_num_ptr != NULL );
+ if ( struct_ptr->trans_tracking != NULL ) {
- /* This should really be an assert, but the func enter/exit
- * macros get testy if there isn't at least one goto error
- * macro call in the funtion.
- */
- if ( ( struct_ptr == NULL ) ||
- ( struct_ptr->magic != H5C2__H5C2_JBRB_T_MAGIC ) ) {
+ if ( verbose ) {
+ HDfprintf(stdout,
+ "%s: free of trans tracking array faileid.\n",
+ FUNC);
+ }
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "bad struct_ptr.")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
+ "free of transaction tracking array failed.");
+ }
}
- /* JRM: In machine readable version, lets check to see if a sync is
- * necessary, and call it only if it is.
- */
- /* perform a sync to ensure everything gets to disk before continuing */
- /* Note: there is no HDfsync function, so for now, the standard
- fsync is being used. */
- if ( fsync(struct_ptr->journal_file_fd) < 0 ) {
-
- HGOTO_ERROR(H5E_IO, H5E_SYNCFAIL, FAIL, "Jounal file sync failed.")
-
- } /* end if */
+done:
- * trans_num_ptr = struct_ptr->last_trans_on_disk;
+ if ( verbose ) {
-done:
+ HDfprintf(stdout, "%s: exiting.\n", FUNC);
+ fflush(stdout);
+ }
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5C2_jb__get_last_transaction_on_disk */
+} /* end H5C2_jb__takedown */
/******************************************************************************
@@ -4006,193 +3602,456 @@ done:
/******************************************************************************
*
- * Function: H5C2_jb__takedown
+ * Function: H5C2_jb__write_header_entry
*
- * Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
- * Thursday, February 7, 2008
+ * Programmer: John Mainzer
+ * 2/12/09
*
- * Purpose: Verify that the journal buffers are empty, and that the
- * journal file has been truncated. Then close and delete
- * the journal file associated with *struct_ptr, and free
- * all dynamically allocated memory associated with
- * *struct_ptr.
+ * Purpose: Write the header message to the journal file.
+ *
+ * This message appear exactly once in every journal
+ * file, and is always the first message in the file.
+ * It identifies the journal file, and contains
+ * information required to run the journal, should
+ * that be necessary.
*
+ * It is always in human readable format.
+ *
* Returns: SUCCEED on success.
+ * FAIL on failure.
+ *
+ * Changes: JRM -- 3/21/09
+ * Moved the entry tag strings into #defines.
+ * Replaced all white space in the creation date
+ * string with underscores.
*
******************************************************************************/
herr_t
-H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr)
+H5C2_jb__write_header_entry(H5C2_jbrb_t * struct_ptr)
{
- herr_t ret_value = SUCCEED;
- hbool_t verbose = FALSE;
+ herr_t ret_value = SUCCEED;
+ hbool_t verbose = FALSE;
+ char *buf;
+ char * p;
+ char time_buf[32];
+ int chars_written;
+ int i;
+ size_t file_name_len;
+ size_t buf_len;
+ time_t current_date;
- FUNC_ENTER_NOAPI(H5C2_jb__takedown, FAIL)
+ FUNC_ENTER_NOAPI(H5C2_jb__write_header_entry, FAIL)
- if ( verbose ) {
+ /* Check Arguments */
+ HDassert( struct_ptr );
+ HDassert( struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC );
+ HDassert( struct_ptr->hdf5_file_name != NULL );
+ HDassert( struct_ptr->header_present == FALSE );
+ HDassert( struct_ptr->journal_is_empty == TRUE );
- HDfprintf(stdout, "%s: entering.\n", FUNC);
- }
+ file_name_len = strlen(struct_ptr->hdf5_file_name);
- /* Check Arguments */
- HDassert(struct_ptr);
- HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
+ HDassert( file_name_len > 0 );
+
+ buf_len = file_name_len + 256;
- /* Verify that the journal buffers are empty */
- if ( struct_ptr->bufs_in_use != 0 ) {
+ /* Allocate space for journal buffers */
+ buf = H5MM_malloc(buf_len);
- if ( verbose ) {
- HDfprintf(stdout, "%s: Attempt to takedown with non-empty buffers.\n",
- FUNC);
- }
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "Attempt to takedown with non-empty buffers.")
- } /* end if */
+ if ( buf == NULL ) {
- /* Verify that the journal file has been truncated */
- if (struct_ptr->journal_is_empty != TRUE) {
+ if ( verbose ) {
- if ( verbose ) {
- HDfprintf(stdout,
- "%s: Attempt to takedown with journal file not truncated.\n",
- FUNC);
- }
- HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
- "Attempt to takedown with journal file not truncated.")
+ HDfprintf(stdout, "%s: buffer allocation failed.\n", FUNC);
+ }
+
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
+ "buffer allocation failed.");
} /* end if */
+
+ /* Get the current date */
+ current_date = time(NULL);
- /* Close and delete the journal file associated with struct_ptr */
- if ( HDclose(struct_ptr->journal_file_fd) < 0 ) {
+ /* load ascii representation of current_date into time_buf[],
+ * replacing white space with underscores.
+ */
+ time_buf[31] = '\0'; /* just to be safe */
- if ( verbose ) {
- HDfprintf(stdout,
- "%s: journal file close failed. errno = %d(%s), fd = %d.\n",
- FUNC, errno, strerror(errno), struct_ptr->journal_file_fd);
- }
- HGOTO_ERROR(H5E_IO, H5E_CLOSEERROR, FAIL, "Jounal file close failed.")
- } /* end if */
+ if ( (p = HDctime(&current_date)) == NULL ) {
- if ( HDremove(struct_ptr->jname) < 0) {
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "Can't get ascii representation of current date.")
- if ( verbose ) {
- HDfprintf(stdout,
- "%s: journal file remove failed. errno = %d(%s).\n",
- FUNC, errno, strerror(errno));
- }
- HGOTO_ERROR(H5E_IO, H5E_REMOVEFAIL, FAIL, "Jounal file close failed.")
- } /* end if */
+ } else {
- /* Free all memory associated with struct_ptr */
+ /* copy the string into time_buf, replacing white space with
+ * underscores.
+ *
+ * Do this to make parsing the header easier.
+ */
+ i = 0;
- if ( struct_ptr->jname != NULL ) {
+ while ( ( i < 31 ) && ( *p != '\0' ) ) {
- struct_ptr->jname = H5MM_xfree(struct_ptr->jname);
- if ( struct_ptr->jname != NULL ) {
+ if ( isspace(*p) ) {
- if ( verbose ) {
- HDfprintf(stdout, "%s: free of jname failed.\n", FUNC);
- }
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "free of jname failed.");
- }
- }
+ time_buf[i] = '_';
- if ( (*struct_ptr->buf)[0] != NULL ) {
+ } else {
- (*struct_ptr->buf)[0] = H5MM_xfree((*struct_ptr->buf)[0]);
- if ( (*struct_ptr->buf)[0] != NULL ) {
+ time_buf[i] = *p;
+ }
- if ( verbose ) {
- HDfprintf(stdout, "%s: free of buffers failed.\n", FUNC);
- }
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "free of buffers failed.");
+ i++;
+ p++;
}
+
+ time_buf[i] = '\0';
}
- if ( struct_ptr->buf != NULL ) {
+ /* Format the header message in the temporary buffer */
- struct_ptr->buf = H5MM_xfree(struct_ptr->buf);
- if ( struct_ptr->buf != NULL ) {
+ chars_written =
+ HDsnprintf(buf,
+ buf_len - 1,
+ "0 %s %ld %s %s %s %d %s %10.10s %s %d\n",
+ H5C2_JNL__VER_NUM_TAG,
+ struct_ptr->jvers,
+ H5C2_JNL__TGT_FILE_NAME_TAG,
+ struct_ptr->hdf5_file_name,
+ H5C2_JNL__JNL_MAGIC_TAG,
+ (int)(struct_ptr->journal_magic),
+ H5C2_JNL__CREATION_DATE_TAG,
+ time_buf,
+ H5C2_JNL__HUMAN_READABLE_TAG,
+ struct_ptr->human_readable);
- if ( verbose ) {
- HDfprintf(stdout, "%s: free of buffer ptr array faileid.\n",
- FUNC);
- }
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "free of buffer pointer array failed.");
+ if ( chars_written >= buf_len - 1 ) {
+
+ if ( verbose ) {
+
+ HDfprintf(stdout, "%s: tried to overwrite buffer.\n", FUNC);
}
+
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, \
+ "tried to overwrite buffer.");
}
- if ( struct_ptr->trans_tracking != NULL ) {
+ HDassert( strlen(buf) < buf_len );
- struct_ptr->trans_tracking = H5MM_xfree(struct_ptr->trans_tracking);
- if ( struct_ptr->trans_tracking != NULL ) {
+ /* Write the header message into the ring buffer */
+ if ( H5C2_jb__write_to_buffer(struct_ptr, HDstrlen(buf), buf, FALSE,
+ (uint64_t)0) < 0) {
- if ( verbose ) {
- HDfprintf(stdout, "%s: free of trans tracking array faileid.\n",
- FUNC);
- }
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "free of transaction tracking array failed.");
+ if ( verbose ) {
+
+ HDfprintf(stdout,
+ "%s: H5C2_jb__write_to_buffer() failed.\n",
+ FUNC);
}
- }
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__write_to_buffer() failed.\n")
+ } /* end if */
+
+ /* Update boolean flags */
+ struct_ptr->header_present = TRUE;
+ struct_ptr->journal_is_empty = FALSE;
done:
- if ( verbose ) {
+ if ( buf != NULL ) {
- HDfprintf(stdout, "%s: exiting.\n", FUNC);
- fflush(stdout);
+ buf = H5MM_xfree(buf);
+
+ if ( buf != NULL ) {
+
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
+ "free of buf failed.");
+ }
}
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5C2_jb__takedown */
+} /* end H5C2_jb__write_header_entry() */
/******************************************************************************
*
- * Function: H5C2_jb__bin2hex
+ * Function: H5C2_jb__write_to_buffer
*
* Programmer: Mike McGreevy <mcgreevy@hdfgroup.org>
- * Tuesday, March 4, 2008
+ * Wednesday, February 6, 2008
*
- * Purpose: Convert binary data into hexadecimal.
+ * Purpose: Put the contents of data into the journal buffers. This
+ * is done as follows: While the data to be written is
+ * larger than the amount of space left in the ring buffer,
+ * the ring buffer is filled to capacity with data and
+ * flushed. This repeats until the unwritten data remaining
+ * can fit in the ring buffer without having to loop around
+ * to the top.
+ *
+ * At this point, the rest of the data can just be written
+ * without having to break it up further. In the event
+ * the data covers more than one journal buffer, the get
+ * and put indices are updated to state this fact. Any
+ * journal buffers that were filled during the write are
+ * flushed.
*
* Returns: SUCCEED on success.
*
******************************************************************************/
herr_t
-H5C2_jb__bin2hex(const uint8_t * buf,
- char * hexdata,
- size_t * hexlength,
- size_t buf_size)
-
+H5C2_jb__write_to_buffer(H5C2_jbrb_t * struct_ptr,
+ size_t size,
+ const char * data,
+ hbool_t is_end_trans,
+ uint64_t trans_num)
{
- size_t v; /* Local index variable */
- uint8_t c;
- char * t;
+ herr_t ret_value = SUCCEED;
+ unsigned long track_last_trans = 0;
+ int oldput = 0;
+ int i;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5C2_jb__bin2hex)
+ FUNC_ENTER_NOAPI(H5C2_jb__write_to_buffer, FAIL)
- t = hexdata;
- t[0] = ' ';
- for (v = 0; v < buf_size; v++) {
+ /* Check Arguments */
+ HDassert(struct_ptr);
+ HDassert(data);
+ HDassert(struct_ptr->magic == H5C2__H5C2_JBRB_T_MAGIC);
+ HDassert(HDstrlen(data) == size);
+ HDassert(struct_ptr->rb_space_to_rollover <=
+ struct_ptr->num_bufs * struct_ptr->buf_size);
+ HDassert(struct_ptr->rb_space_to_rollover > 0);
- t = &hexdata[v * 3 + 1];
- c = buf[v];
- HDsnprintf(t, (size_t)3, "%02x ", c);
- t[2] = ' ';
+ /* If the data size exceeds the bounds of the ring buffer's allocated
+ * memory, loop around to top
+ */
+ if (size >= struct_ptr->rb_space_to_rollover) {
- } /* end for */
- t[3] = '\n';
- t[4] = 0;
+ while (size >= struct_ptr->rb_space_to_rollover) {
+
+ /* Assertions */
+ HDassert(size != 0);
+ HDassert(HDstrlen(data) >= struct_ptr->rb_space_to_rollover);
- * hexlength = v * 3 + 2;
+ /* fill up remaining space in the ring buffer */
+ HDmemcpy(struct_ptr->head, data, struct_ptr->rb_space_to_rollover);
+
+ /* move head to point to start of ring buffer */
+ struct_ptr->head = (*struct_ptr->buf)[0];
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5C2_jb__bin2hex*/
+ /* make note of last transaction on disk */
+ track_last_trans = (*struct_ptr->trans_tracking)[struct_ptr->put];
+
+ /* update rb_free_space */
+ struct_ptr->rb_free_space -= struct_ptr->rb_space_to_rollover;
+
+ /* Fill out the remainder of the trans_tracking array with
+ the most recent transaction in the array.*/
+ (*struct_ptr->trans_tracking)[0] = track_last_trans;
+ for (i=struct_ptr->put; i<struct_ptr->num_bufs; i++)
+ {
+ (*struct_ptr->trans_tracking)[i] = track_last_trans;
+ }
+
+ /* reset put index */
+ struct_ptr->put = 0;
+
+ /* update bufs_in_use as necessary */
+ struct_ptr->bufs_in_use = struct_ptr->num_bufs - struct_ptr->get;
+
+ /* check to see if trans_tracking needs to be updated. If so,
+ then update it */
+ if ((size == struct_ptr->rb_space_to_rollover) &&
+ (is_end_trans == TRUE)) {
+
+ (*struct_ptr->trans_tracking)[struct_ptr->num_bufs - 1]
+ = trans_num;
+ (*struct_ptr->trans_tracking)[0] = trans_num;
+ }
+
+ /* flush buffers */
+ if ( H5C2_jb__flush_full_buffers(struct_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__flush_full_buffers() failed.\n")
+ }
+
+ /* update remaining size of data to be written */
+ size = size - struct_ptr->rb_space_to_rollover;
+
+ /* update the data pointer to point to the remaining data to be
+ * written
+ */
+ data = &data[struct_ptr->rb_space_to_rollover];
+
+ /* update the amount of space left at end of ring buffer */
+ struct_ptr->rb_space_to_rollover =
+ struct_ptr->buf_size * struct_ptr->num_bufs;
+
+ /* update the amount of space in the current buffer */
+ struct_ptr->cur_buf_free_space = struct_ptr->buf_size;
+
+ } /* end while */
+ } /* end if */
+
+ /* If the size of the data exceeds the bounds of a single journal
+ * buffer, will write into multiple
+ */
+ if (size > struct_ptr->cur_buf_free_space) {
+
+ HDassert(struct_ptr->cur_buf_free_space != 0);
+
+ /* write data into journal buffers */
+ HDmemcpy(struct_ptr->head, data, size);
+
+ /* update head pointer */
+ struct_ptr->head = &struct_ptr->head[size];
+
+ /* make note of last transaction on disk */
+ track_last_trans = (*struct_ptr->trans_tracking)[struct_ptr->put];
+ oldput = struct_ptr->put;
+
+ /* update rb_free_space */
+ struct_ptr->rb_free_space -= size;
+
+ /* update put index */
+ struct_ptr->put +=
+ (size-struct_ptr->cur_buf_free_space)/(struct_ptr->buf_size) + 1;
+
+ /* Drag the last transaction in a filled buffer value residing in the
+ old put location through the trans_tracking array to the new
+ corresponding put position. */
+ for (i=oldput; i<struct_ptr->put+1; i++)
+ {
+ (*struct_ptr->trans_tracking)[i] = track_last_trans;
+ }
+
+ /* update current buffer usage */
+ struct_ptr->cur_buf_free_space =
+ struct_ptr->rb_space_to_rollover - size -
+ (struct_ptr->num_bufs - (struct_ptr->put + 1)) *
+ (struct_ptr->buf_size );
+
+ /* update bufs_in_use as necessary */
+ struct_ptr->bufs_in_use = struct_ptr->put - struct_ptr->get;
+ if (struct_ptr->cur_buf_free_space < struct_ptr->buf_size) {
+
+ struct_ptr->bufs_in_use++;
+ }
+
+ /* check to see if trans_tracking needs to be updated. If so,
+ then update it */
+ if (is_end_trans == TRUE) {
+
+ if (struct_ptr->cur_buf_free_space == struct_ptr->buf_size) {
+ (*struct_ptr->trans_tracking)[struct_ptr->put - 1] = trans_num;
+ }
+ else {
+ (*struct_ptr->trans_tracking)[struct_ptr->put] = trans_num;
+ }
+
+ } /* end if */
+
+ /* flush buffers */
+ if ( H5C2_jb__flush_full_buffers(struct_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__flush_full_buffers() failed.\n")
+ }
+
+ /* update space left at end of ring buffer */
+ struct_ptr->rb_space_to_rollover -= size;
+
+ } /* end if */
+
+ /* if the data can fit in the remaining space in the current journal
+ * buffer indexed by put
+ */
+ else if (size > 0) {
+
+ HDassert(size <= struct_ptr->cur_buf_free_space);
+
+ /* write data into journal buffer */
+ HDmemcpy(struct_ptr->head, data, size);
+
+ /* increment bufs_in_use as necessary */
+ if ( ( struct_ptr->bufs_in_use == 0 ) ) {
+
+ struct_ptr->bufs_in_use++;
+ }
+
+ /* update head pointer */
+ struct_ptr->head = &struct_ptr->head[size];
+
+ /* update rb_free_space */
+ struct_ptr->rb_free_space -= size;
+
+ /* update current buffer usage */
+ struct_ptr->cur_buf_free_space -= size;
+
+ /* update end of buffer space */
+ struct_ptr->rb_space_to_rollover -= size;
+
+ /* check to see if trans_tracking needs to be updated. If so,
+ then update it */
+ if (is_end_trans == TRUE) {
+
+ (*struct_ptr->trans_tracking)[struct_ptr->put]
+ = trans_num;
+ } /* end if */
+
+ /* if buffer is full, flush it, and loop to the top of the
+ * ring buffer if at the end.
+ */
+ if (struct_ptr->cur_buf_free_space == 0) {
+
+ if ( struct_ptr->put != (struct_ptr->num_bufs - 1) ) {
+ struct_ptr->put += 1;
+
+ /* Drag trans_tracking value into next buffer */
+ (*struct_ptr->trans_tracking)[struct_ptr->put]
+ = (*struct_ptr->trans_tracking)[struct_ptr->put - 1];
+
+ } /* end if */
+
+ else {
+
+ struct_ptr->put = 0;
+
+ /* Drag trans_tracking value into next buffer */
+ (*struct_ptr->trans_tracking)[0]
+ = (*struct_ptr->trans_tracking)[struct_ptr->num_bufs - 1];
+
+ /* reset head pointer and free space values */
+ struct_ptr->head = (*struct_ptr->buf)[0];
+ struct_ptr->rb_space_to_rollover =
+ struct_ptr->buf_size * struct_ptr->num_bufs;
+
+ } /* end else */
+
+ if ( H5C2_jb__flush_full_buffers(struct_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTJOURNAL, FAIL, \
+ "H5C2_jb__flush_full_buffers() failed.\n")
+ } /* end if */
+
+ struct_ptr->cur_buf_free_space = struct_ptr->buf_size;
+
+ } /* end if */
+
+ } /* end else */
+
+ HDassert(struct_ptr->bufs_in_use <= struct_ptr->num_bufs);
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* end H5C2_jb__write_to_buffer */
diff --git a/src/H5C2pkg.h b/src/H5C2pkg.h
index 3510dc7..af3ac81 100644
--- a/src/H5C2pkg.h
+++ b/src/H5C2pkg.h
@@ -62,9 +62,17 @@
*
*
* magic: Unsigned 32-bit integer always set to
- * H5C2__H5C2_JBRB_T_MAGIC. This field is used to validate
- * pointers to instances of H5C_jbrb_t.
- *
+ * H5C2__H5C2_JBRB_T_MAGIC. This field is used to
+ * validate pointers to instances of H5C_jbrb_t.
+ *
+ * journal_magic: int32_t used to store a randomly selected integer
+ * used to tag both the journal file and the
+ * mdj_config_block. Should the journal ever be
+ * run, we will check to see if the magic number
+ * from the target HDF5 file matches that in the
+ * journal, and refuse to run the journal if it does
+ * not.
+ *
* journal_file_fd: File Descriptor of the journal file that is being
* written to from this ring buffer.
*
@@ -157,9 +165,17 @@
#define H5C2__H5C2_JBRB_T_MAGIC (unsigned)0x00D0A03
#define H5C2__JOURNAL_VERSION 1
+/* tags used to mark entries in the journal file header */
+#define H5C2_JNL__VER_NUM_TAG "ver_num"
+#define H5C2_JNL__TGT_FILE_NAME_TAG "target_file_name"
+#define H5C2_JNL__JNL_MAGIC_TAG "journal_magic"
+#define H5C2_JNL__CREATION_DATE_TAG "creation_date"
+#define H5C2_JNL__HUMAN_READABLE_TAG "human_readable"
+
struct H5C2_jbrb_t
{
uint32_t magic;
+ int32_t journal_magic;
int journal_file_fd;
int num_bufs;
size_t buf_size;
@@ -794,45 +810,17 @@ typedef struct H5C2_mdjsc_record_t
* been modified have been written to disk in the journal
* file.
*
- * mdj_file_name_ptr: Pointer to a string containing the path of the
- * journal file, or NULL if this path is undefined.
- * At present, the journal will always be stored in an
- * external file, so this field must be defined if
- * journaling is enabled.
- *
- * To avoid allocating extra memory, mdj_file_name_ptr
- * points into the approprite location in the in core
- * image of the metadata journaling configuration block.
- *
- * mdj_conf_block_addr: Address of the metadata journaling configuration
- * block on disk, or HADDR_UNDEF if that block is undefined.
- *
- * mdj_conf_block_len: Length (in bytes) of the metadata journaling
- * configuration block, or 0 if that block is undefined.
- *
- * mdj_conf_block_ptr: Pointer to a dynamically allocated chunk of
- * memory of size mdj_conf_block_len used to construct
- * an image of the on disk metadata journaling configuration
- * block. This block is used to record the path of the
- * journal file in the HDF5 file, so that it can be
- * found in the event of a crash.
+ * jnl_magic: Randomly selected int32_t used to reduce the possibility
+ * of running the wrong journal on an HDF5 file. The basic
+ * idea is to pick a random number, store it in both the HDF5
+ * file and the journal file, and then refuse to run the
+ * journal unless the numbers match.
*
- * The metadata journaling configuration block has the
- * following format:
+ * jnl_file_name_len: Length of the journal file name, or zero if the
+ * journal file name is undefined.
*
- * 4 bytes signature
- *
- * 1 byte version
- *
- * 4 bytes path length
- *
- * variable string containing path of journal file
- *
- * 4 bytes checksum
- *
- * The base address and lenth of the metadata journaling
- * configuration block is stored in the mdj_msg superblock
- * extension message.
+ * jnl_file_name: Array of char of length H5C2__MAX_JOURNAL_FILE_NAME_LEN
+ * + 1 used to store the journal file path.
*
* mdj_jbrb: Instance of H5C2_jbrb_t used to manage logging of journal
* entries to the journal file.
@@ -1160,16 +1148,6 @@ typedef struct H5C2_mdjsc_record_t
#define H5C2__PREFIX_LEN 32
#define H5C2__MAX_API_NAME_LEN 128
-#define H5C2__JOURNAL_MAGIC_LEN (size_t)4
-#define H5C2__JOURNAL_CONF_MAGIC "MDJC"
-#define H5C2__JOURNAL_CONF_VERSION ((uint8_t)1)
-#define H5C2__JOURNAL_BLOCK_LEN(pathLen, f) \
- ( H5C2__JOURNAL_MAGIC_LEN + \
- 1 + /* version */ \
- H5F_SIZEOF_SIZE(f) + \
- ((pathLen) + 1) + \
- 4 /* checksum */ )
-
#define H5C2__MIN_MDJSC_CB_TBL_LEN 16
#define H5C2__MDJSC_CB_TBL_MIN_ACTIVE_RATIO 0.25
@@ -1216,7 +1194,7 @@ struct H5C2_t
int32_t pel_len;
size_t pel_size;
- H5C2_cache_entry_t * pel_head_ptr;
+ H5C2_cache_entry_t * pel_head_ptr;
H5C2_cache_entry_t * pel_tail_ptr;
int32_t LRU_list_len;
@@ -1259,10 +1237,10 @@ struct H5C2_t
char trans_api_name[H5C2__MAX_API_NAME_LEN];
uint64_t trans_num;
uint64_t last_trans_on_disk;
- char * mdj_file_name_ptr;
- haddr_t mdj_conf_block_addr;
- hsize_t mdj_conf_block_len;
- void * mdj_conf_block_ptr;
+ int32_t jnl_magic;
+ int32_t jnl_file_name_len;
+ char jnl_file_name[H5C2__MAX_JOURNAL_FILE_NAME_LEN
+ + 1];
struct H5C2_jbrb_t mdj_jbrb;
int32_t tl_len;
size_t tl_size;
diff --git a/src/H5C2private.h b/src/H5C2private.h
index 833bfa1..c9e55ca 100644
--- a/src/H5C2private.h
+++ b/src/H5C2private.h
@@ -1591,17 +1591,35 @@ H5_DLL herr_t H5C2_update_for_new_last_trans_on_disk(H5C2_t * cache_ptr,
typedef struct H5C2_jbrb_t H5C2_jbrb_t;
+H5_DLL herr_t H5C2_jb__bin2hex(const uint8_t * buf,
+ char * hexdata,
+ size_t * hexlength,
+ size_t buf_size);
+
+H5_DLL herr_t H5C2_jb__comment(H5C2_jbrb_t * struct_ptr,
+ const char * comment_ptr);
+
+H5_DLL herr_t H5C2_jb__end_transaction(H5C2_jbrb_t * struct_ptr,
+ uint64_t trans_num);
+
+H5_DLL herr_t H5C2_jb__eoa(H5C2_jbrb_t * struct_ptr,
+ haddr_t eoa);
+
+H5_DLL herr_t H5C2_jb__get_last_transaction_on_disk(H5C2_jbrb_t * struct_ptr,
+ uint64_t * trans_num_ptr);
+
H5_DLL herr_t H5C2_jb__flush_full_buffers(H5C2_jbrb_t * struct_ptr);
H5_DLL herr_t H5C2_jb__flush(H5C2_jbrb_t * struct_ptr);
-H5_DLL herr_t H5C2_jb__write_to_buffer(H5C2_jbrb_t * struct_ptr,
- size_t size,
- const char * data,
- hbool_t is_end_trans,
- uint64_t trans_num);
+H5_DLL herr_t H5C2_jb__journal_entry(H5C2_jbrb_t * struct_ptr,
+ uint64_t trans_num,
+ haddr_t base_addr,
+ size_t length,
+ const uint8_t * body);
H5_DLL herr_t H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
+ const int32_t journal_magic,
const char * HDF5_file_name,
const char * journal_file_name,
size_t buf_size,
@@ -1612,35 +1630,21 @@ H5_DLL herr_t H5C2_jb__init(H5C2_jbrb_t * struct_ptr,
H5_DLL herr_t H5C2_jb__start_transaction(H5C2_jbrb_t * struct_ptr,
uint64_t trans_num);
-H5_DLL herr_t H5C2_jb__journal_entry(H5C2_jbrb_t * struct_ptr,
- uint64_t trans_num,
- haddr_t base_addr,
- size_t length,
- const uint8_t * body);
-
-H5_DLL herr_t H5C2_jb__end_transaction(H5C2_jbrb_t * struct_ptr,
- uint64_t trans_num);
-
-H5_DLL herr_t H5C2_jb__comment(H5C2_jbrb_t * struct_ptr,
- const char * comment_ptr);
-
-H5_DLL herr_t H5C2_jb__eoa(H5C2_jbrb_t * struct_ptr,
- haddr_t eoa);
-
-H5_DLL herr_t H5C2_jb__get_last_transaction_on_disk(H5C2_jbrb_t * struct_ptr,
- uint64_t * trans_num_ptr);
+H5_DLL herr_t H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr);
H5_DLL herr_t H5C2_jb__trunc(H5C2_jbrb_t * struct_ptr);
-H5_DLL herr_t H5C2_jb__takedown(H5C2_jbrb_t * struct_ptr);
+H5_DLL herr_t H5C2_jb__write_header_entry(H5C2_jbrb_t * struct_ptr);
+
+H5_DLL herr_t H5C2_jb__write_to_buffer(H5C2_jbrb_t * struct_ptr,
+ size_t size,
+ const char * data,
+ hbool_t is_end_trans,
+ uint64_t trans_num);
-H5_DLL herr_t H5C2_jb__bin2hex(const uint8_t * buf,
- char * hexdata,
- size_t * hexlength,
- size_t buf_size);
/*****************************************************************************/
-/********** journal config block management function definitions: ************/
+/***** superblock journaling message management function definitions: ********/
/*****************************************************************************/
H5_DLL herr_t H5C2_check_for_journaling(H5F_t * f,
@@ -1648,25 +1652,13 @@ H5_DLL herr_t H5C2_check_for_journaling(H5F_t * f,
H5C2_t * cache_ptr,
hbool_t journal_recovered);
-H5_DLL herr_t H5C2_create_journal_config_block(const H5F_t *f,
- hid_t dxpl_id,
- const char * journal_file_name_ptr);
-
-H5_DLL herr_t H5C2_discard_journal_config_block(const H5F_t * f,
- hid_t dxpl_id);
-
H5_DLL herr_t H5C2_get_journaling_in_progress(const H5F_t * f,
hid_t dxpl_id,
H5C2_t * cache_ptr);
-H5_DLL herr_t H5C2_load_journal_config_block(const H5F_t * f,
- hid_t dxpl_id,
- H5C2_t * cache_ptr,
- haddr_t block_addr,
- hsize_t block_len);
-
H5_DLL herr_t H5C2_mark_journaling_in_progress(H5F_t * f,
hid_t dxpl_id,
+ const int32_t journal_magic,
const char * journal_file_name_ptr);
H5_DLL herr_t H5C2_unmark_journaling_in_progress(H5F_t * f,
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 08a53a5..1318eb8 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -138,7 +138,12 @@ typedef struct H5F_file_t {
struct H5G_t *root_grp; /* Open root group */
H5FO_t *open_objs; /* Open objects in file */
H5RC_t *grp_btree_shared; /* Ref-counted group B-tree node info */
- hbool_t mdc_jrnl_enabled; /* TRUE iff journaling is in progress */
+ hbool_t mdc_jnl_enabled; /* TRUE iff journaling is in progress */
+ int32_t mdc_jnl_magic; /* journal file magic -- if defined */
+ size_t mdc_jnl_file_name_len; /* journal file name length */
+ char mdc_jnl_file_name[H5C2__MAX_JOURNAL_FILE_NAME_LEN + 1];
+ /* journal file name -- if defined */
+/* todo -- delete the following lines. -- JRM */
haddr_t mdc_jrnl_block_loc; /* Rel addr of mdc journal block */
hsize_t mdc_jrnl_block_len; /* Length of mdc journal block */
} H5F_file_t;
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index 2df6ac1..2e1f564 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -356,9 +356,10 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
* super block to indicate that journaling is not turned on at
* present. These initialization may be overridden shortly.
*/
- shared->mdc_jrnl_enabled = FALSE;
- shared->mdc_jrnl_block_loc = HADDR_UNDEF;
- shared->mdc_jrnl_block_len = 0;
+ shared->mdc_jnl_enabled = FALSE;
+ shared->mdc_jnl_magic = 0;
+ shared->mdc_jnl_file_name_len = 0;
+ (shared->mdc_jnl_file_name)[0] = '\0';
/* Get the shared file creation property list */
if(NULL == (c_plist = H5I_object(shared->fcpl_id)))
@@ -744,17 +745,44 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
} /* end if */
else {
- shared->mdc_jrnl_enabled = mdj_msg.mdc_jrnl_enabled;
+ shared->mdc_jnl_enabled = mdj_msg.mdc_jnl_enabled;
- if ( shared->mdc_jrnl_enabled ) {
+ if ( shared->mdc_jnl_enabled ) {
- shared->mdc_jrnl_block_loc = mdj_msg.mdc_jrnl_block_loc;
- shared->mdc_jrnl_block_len = mdj_msg.mdc_jrnl_block_len;
+ shared->mdc_jnl_magic = mdj_msg.mdc_jnl_magic;
+ shared->mdc_jnl_file_name_len = mdj_msg.mdc_jnl_file_name_len;
+
+ if ( shared->mdc_jnl_file_name_len <= 0 ) {
+
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, \
+ "journaling enabled, but journal file path empty?!?")
+ }
+
+ if ( shared->mdc_jnl_file_name_len >
+ H5C2__MAX_JOURNAL_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, \
+ "journal file path too long")
+ }
+
+ HDstrncpy(shared->mdc_jnl_file_name,
+ mdj_msg.mdc_jnl_file_name,
+ mdj_msg.mdc_jnl_file_name_len + 1);
+
+ if ( ( (shared->mdc_jnl_file_name)
+ [shared->mdc_jnl_file_name_len] != '\0' ) ||
+ ( HDstrlen(shared->mdc_jnl_file_name) !=
+ shared->mdc_jnl_file_name_len ) ) {
+
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, \
+ "bad journal file path and/or path len???")
+ }
}
else
{
- shared->mdc_jrnl_block_loc = HADDR_UNDEF;
- shared->mdc_jrnl_block_len = 0;
+ shared->mdc_jnl_magic = 0;
+ shared->mdc_jnl_file_name_len = 0;
+ (shared->mdc_jnl_file_name)[0] = '\0';
}
/* Reset metadata journaling config message */
@@ -765,9 +793,15 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc)
* closing the file (since this will be the only open object).
*/
f->nopen_objs++;
- if(H5O_close(&ext_loc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENFILE, FAIL, "unable to close superblock extension")
+
+ if(H5O_close(&ext_loc) < 0) {
+
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENFILE, FAIL, \
+ "unable to close superblock extension")
+ }
+
f->nopen_objs--;
+
} /* end if */
done:
@@ -962,15 +996,35 @@ H5F_super_init(H5F_t *f, hid_t dxpl_id)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update driver info header message")
} /* end if */
- /* check for journaling config data to store */
- if ( f->shared->mdc_jrnl_enabled ) {
- struct H5O_mdj_msg_t mdj_conf;
+ /* One might expect us to check to see if journaling is enabled
+ * at this point, and write a metadata journaling message to the
+ * super block extension if it is.
+ *
+ * However, the cache has not been initialized at this point,
+ * so we don't know if we will be successful in creating the
+ * journal file (the journal file may already exist, or some
+ * directory on the journal path may not exist.
+ *
+ * Further, the cache should refuse to allow the file to open if
+ * it detects journaling in progress -- so marking journaling in
+ * progress here would introduce some complexities.
+ * status now
+ *
+ * Thus, don't write the metadata journaling message now. Instead,
+ * initialize the metadata journaling related fields to indicate
+ * that journaling is not in progress. If journaling is requested,
+ * we will write the metadata journaling message after we have
+ * successfully opened the journal file and started journaling.
+ *
+ * JRM -- 2/19/09
+ */
+
+ f->shared->mdc_jnl_enabled = FALSE;
+ f->shared->mdc_jnl_magic = 0;
+ f->shared->mdc_jnl_file_name_len = 0;
+ (f->shared->mdc_jnl_file_name)[0] = '\0';
- mdj_conf.mdc_jrnl_enabled = f->shared->mdc_jrnl_enabled;
- mdj_conf.mdc_jrnl_block_loc = f->shared->mdc_jrnl_block_loc;
- mdj_conf.mdc_jrnl_block_len = f->shared->mdc_jrnl_block_len;
- }
/* Twiddle the number of open objects to avoid closing the file
* (since this will be the only open object currently).
@@ -1139,14 +1193,13 @@ done:
} /* end H5F_super_write() */
-
/*-------------------------------------------------------------------------
* Function: H5F_super_write_mdj_msg
*
* If journaling is enabled, create a superblock extension
* if necessary and then write the current contents of
- * the mdc_jrnl_enabled, mdc_jrnl_block_loc, and
+ * the mdc_jnl_enabled, mdc_jrnl_block_loc, and
* mdc_jrnl_block_len fields of the shared structure to the
* mdj_msg in the superblock extention, overwriting the old
* message if it exists.
@@ -1162,6 +1215,17 @@ done:
*
* Programmer: John Mainzer
* 3/3/08
+ *
+ * Changes: JRM -- 2/17/09
+ * Heavily re-worked the function to move the journal file
+ * name and journal file magic into the metadata journaling
+ * message.
+ *
+ * Note that this makes the metadata journaling message
+ * variable length, so we now delete any existing metadata
+ * journaling message, and then replace it with a new
+ * message if metadata journaling is enabled.
+ *
*-------------------------------------------------------------------------
*/
herr_t
@@ -1204,111 +1268,133 @@ H5F_super_write_mdj_msg(H5F_t *f,
}
}
+ /* The metadata journaling message is a variable length message.
+ * This raises the question of how to deal with any pre-existing
+ * message.
+ *
+ * While in theory we could try to re-size it, after looking through
+ * the code and talking to Quincey, it appears that the standard
+ * practice in such cases seems to be to delete the old message,
+ * and then replace it with a new message.
+ *
+ * Add to this the fact that the metadata journaling message
+ * should not exist unless journaling is enabled (or to put it
+ * another way, the message should never appear in a valid HDF5
+ * file).
+ *
+ * Thus, here we check to see if a metadata jouraling message exists,
+ * and delete it if it does. If metadata data journaling is enabled,
+ * we will replace it with a new message shortly.
+ */
+
tri_result = H5O_msg_exists(&ext_loc, H5O_MDJ_MSG_ID, dxpl_id);
if ( tri_result < 0 ) { /* failure */
HGOTO_ERROR(H5E_SYSTEM, H5E_SYSERRSTR, FAIL, \
- "unable to open superblock extension?!?!");
+ "unable to determine if metadata journaling message exists?!?!");
- } else if ( tri_result == 0 ) {
- /* metadata journaling message doesn't exist */
+ } else if ( tri_result == TRUE ) {
- if ( f->shared->mdc_jrnl_enabled ) {
+ /* metadata journaling message exists -- delete it from the
+ * super block extension now. We will replace it later if
+ * metadata journaling is enabled.
+ */
- /* create a metadata journaling message and insert it in
- * the superblock extension.
- */
- mdj_msg.mdc_jrnl_enabled = f->shared->mdc_jrnl_enabled;
- mdj_msg.mdc_jrnl_block_loc = f->shared->mdc_jrnl_block_loc;
- mdj_msg.mdc_jrnl_block_len = f->shared->mdc_jrnl_block_len;
+ result = H5O_msg_remove(&ext_loc,
+ H5O_MDJ_MSG_ID,
+ H5O_ALL,
+ /* the next parameter is the "adj_link" parameter, which is
+ * boolean. Unfortunately, its meaning is not documented
+ * in the code. The value gets stuffed into an instance of
+ * H5O_iter_rm_t, and then passed along somehow to a function
+ * whose address appears to be picked out of a table somewhere.
+ *
+ * The documentation on the adj_link field of H5O_iter_rm_t
+ * simply says that the value specifies "Whether to adjust
+ * links when removing messages" -- but unfortunately, I
+ * don't know what a "link" is in this context.
+ *
+ * Bottom line is that after spending over an hour dredging
+ * through the code, I haven't a clue as to what the value
+ * of this parameter should be. We will set it to FALSE and
+ * see if anything blows up.
+ *
+ * JRM -- 3/5/08
+ */
+ FALSE,
+ dxpl_id);
- result = H5O_msg_create(&ext_loc,
- H5O_MDJ_MSG_ID,
- H5O_MSG_FLAG_DONTSHARE,
- H5O_UPDATE_TIME,
- &mdj_msg,
- dxpl_id);
+ } else if ( tri_result != FALSE ) {
- if ( result < 0 ) {
+ HGOTO_ERROR(H5E_SYSTEM, H5E_SYSERRSTR, FAIL, \
+ "unexpected return value from H5O_msg_exists()");
+ }
- HGOTO_ERROR(H5E_SYSTEM, H5E_SYSERRSTR, FAIL, \
- "unable to add mdj_msg to superblock extension?!?!");
- }
+ if ( f->shared->mdc_jnl_enabled ) {
- } else {
+ /* create a metadata journaling message and insert it in
+ * the superblock extension.
+ */
+ mdj_msg.mdc_jnl_enabled = f->shared->mdc_jnl_enabled;
+ mdj_msg.mdc_jnl_magic = f->shared->mdc_jnl_magic;
+ mdj_msg.mdc_jnl_file_name_len = f->shared->mdc_jnl_file_name_len;
- /* do nothing */
- }
+ if ( f->shared->mdc_jnl_file_name_len == 0 ) {
- } else {
- /* metadata journaling message exists */
-
- if ( f->shared->mdc_jrnl_enabled ) {
-
- /* overwrite the old metadata journaling message with a
- * new one in the superblock extension.
- */
- mdj_msg.mdc_jrnl_enabled = f->shared->mdc_jrnl_enabled;
- mdj_msg.mdc_jrnl_block_loc = f->shared->mdc_jrnl_block_loc;
- mdj_msg.mdc_jrnl_block_len = f->shared->mdc_jrnl_block_len;
-
- result = H5O_msg_write(&ext_loc,
- H5O_MDJ_MSG_ID,
- H5O_MSG_FLAG_DONTSHARE,
- H5O_UPDATE_TIME,
- &mdj_msg,
- dxpl_id);
-
- if ( result < 0 ) {
-
- HGOTO_ERROR(H5E_SYSTEM, H5E_SYSERRSTR, FAIL, \
- "unable to overwrite mdj_msg in superblock extension?!?!");
- }
-
-
- } else {
-
- /* delete the old metadata journaling message from the
- * superblock extension.
- */
-
- result = H5O_msg_remove(&ext_loc,
- H5O_MDJ_MSG_ID,
- H5O_ALL,
- /* the next parameter is the "adj_link" parameter, which is
- * boolean. Unfortunately, its meaning is not documented
- * in the code. The value gets stuffed into an instance of
- * H5O_iter_rm_t, and then passed along somehow to a funcition
- * whose address appears to be picked out of a table somewhere.
- *
- * The documentation on the adj_link field of H5O_iter_rm_t
- * simply says that the value specifies "Whether to adjust
- * links when removing messages" -- but unfortunately, I
- * don't know what a "link" is in this context.
- *
- * Bottom line is that after spending over an hour dredging
- * through the code, I haven't a clue as to what the value
- * of this parameter should be. We will set it to FALSE and
- * see if anything blows up.
- *
- * JRM -- 3/5/08
- */
- FALSE,
- dxpl_id);
- }
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, \
+ "journaling enabled, but journal file path empty?!?")
- }
+ }
+
+ if ( f->shared->mdc_jnl_file_name_len >
+ H5C2__MAX_JOURNAL_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, \
+ "journal file path too long?!?")
+
+ }
+
+ HDstrncpy(mdj_msg.mdc_jnl_file_name,
+ f->shared->mdc_jnl_file_name,
+ f->shared->mdc_jnl_file_name_len + 1);
+
+ if ( ( (mdj_msg.mdc_jnl_file_name)[mdj_msg.mdc_jnl_file_name_len]
+ != '\0' ) ||
+ ( HDstrlen(mdj_msg.mdc_jnl_file_name) !=
+ mdj_msg.mdc_jnl_file_name_len ) ) {
+
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, \
+ "bad journal file path and/or path len???")
+ }
+
+ result = H5O_msg_create(&ext_loc,
+ H5O_MDJ_MSG_ID,
+ H5O_MSG_FLAG_DONTSHARE,
+ H5O_UPDATE_TIME,
+ &mdj_msg,
+ dxpl_id);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_SYSTEM, H5E_SYSERRSTR, FAIL, \
+ "unable to add mdj_msg to superblock extension?!?!");
+ }
+
+ }
/* Close the extension. Twiddle the number of open objects to avoid
* closing the file (since this may be the only open object).
*/
+
f->nopen_objs++;
+
if(H5O_close(&ext_loc) < 0) {
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENFILE, FAIL,
"unable to close superblock extension")
}
+
f->nopen_objs--;
done:
diff --git a/src/H5Ochunk.c b/src/H5Ochunk.c
index 634c628..813006e 100644
--- a/src/H5Ochunk.c
+++ b/src/H5Ochunk.c
@@ -234,8 +234,10 @@ H5O_chunk_unprotect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_chunk_proxy_t *chk_p
HGOTO_ERROR(H5E_OHDR, H5E_CANTMARKDIRTY, FAIL, "unable to mark object header as dirty")
} /* end else/if */
else
+ {
/* Sanity check */
HDassert(0 && "Unknown chunk proxy flag(s)?!?");
+ }
/* Free fake chunk proxy */
H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);
diff --git a/src/H5Omdj_msg.c b/src/H5Omdj_msg.c
index 044ce4a..6ba1774 100644
--- a/src/H5Omdj_msg.c
+++ b/src/H5Omdj_msg.c
@@ -20,29 +20,34 @@
* John Mainzer
*
* Purpose: A message detailing whether metadata jouraling is enabled,
- * and if so, the base address in file and length of the block
- * that contains the journaling configuration data.
+ * and if so, the journal file magic and journal file path.
+ *
+ * Note that the size of this message is variable.
*
* The mdj_msg only appears in the superblock extension.
*
* Modifications:
*
- * None.
+ * Re-worked message to include the journal file name and
+ * magic, instead of simply containing a pointer to a
+ * journal configuration block containing this data.
*
*-------------------------------------------------------------------------
*/
-#define H5O_PACKAGE /*suppress error about including H5Opkg */
+#define H5O_PACKAGE /* suppress error about including H5Opkg */
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Opkg.h" /* Object headers */
-#include "H5MMprivate.h" /* Memory management */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Opkg.h" /* Object headers */
+#include "H5MMprivate.h" /* Memory management */
-#define MDJ_MSG_LEN(f) ( 1 + /* Version number */ \
- 2 + /* flags */ \
- H5F_SIZEOF_ADDR(f) + /* addr of journal config block */ \
- H5F_SIZEOF_SIZE(f) ) /* journal config block len */
+#define MDJ_MSG_LEN(f, pathlen) \
+ ( 1 + /* Version number */ \
+ 2 + /* flags */ \
+ 4 + /* magic -- sizeof(int32_t) */ \
+ 4 + /* jnl file path len - sizeof(int32_t) */ \
+ pathlen + 1 ) /* jnl file path */
static void * H5O_mdj_msg_decode(H5F_t UNUSED *f,
hid_t UNUSED dxpl_id,
@@ -95,12 +100,6 @@ const H5O_msg_class_t H5O_MSG_MDJ_CONF[1] = {{
H5O_mdj_msg_debug /* debug the message */
}};
-
-/* Current version of the metadata journaling configuration information */
-#define H5O_MDJ_CONF_VERSION 0
-
-#define MDJ_MSG__JOURNALING_ENABLED_FLAG 0x0001
-
/*-------------------------------------------------------------------------
* Function: H5O_mdj_msg_decode
@@ -123,8 +122,12 @@ H5O_mdj_msg_decode(H5F_t *f,
unsigned UNUSED mesg_flags,
const uint8_t *p)
{
+ char ch;
uint16_t flags = 0; /* packed boolean fields */
- H5O_mdj_msg_t *mesg; /* Native message */
+ int i;
+ int32_t journal_magic; /* magic number -- if defined */
+ int32_t path_len; /* journal file path length */
+ H5O_mdj_msg_t *mesg; /* Native message */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_mdj_msg_decode)
@@ -142,7 +145,8 @@ H5O_mdj_msg_decode(H5F_t *f,
/* Allocate space for message */
- if( NULL == ( mesg = H5MM_calloc(sizeof(H5O_mdj_msg_t)))) {
+ if ( NULL ==
+ (mesg = (H5O_mdj_msg_t *)H5MM_calloc(sizeof(H5O_mdj_msg_t))) ) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, \
"memory allocation failed for metadata journaling message.");
@@ -154,21 +158,51 @@ H5O_mdj_msg_decode(H5F_t *f,
if ( (flags & MDJ_MSG__JOURNALING_ENABLED_FLAG) != 0 ) {
- mesg->mdc_jrnl_enabled = TRUE;
+ mesg->mdc_jnl_enabled = TRUE;
} else {
- mesg->mdc_jrnl_enabled = FALSE;
+ mesg->mdc_jnl_enabled = FALSE;
+
+ }
+
+
+ /* get the journal file magic number */
+ INT32DECODE(p, journal_magic);
+
+ mesg->mdc_jnl_magic = journal_magic;
+
+
+ /* get the journal file path length */
+ INT32DECODE(p, path_len);
+
+ if ( path_len > H5C2__MAX_JOURNAL_FILE_NAME_LEN ) {
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "path length too big.")
}
- /* retrieve the journal block location */
+ mesg->mdc_jnl_file_name_len = (size_t)path_len;
- H5F_addr_decode(f, &p, &(mesg->mdc_jrnl_block_loc));
- /* retrieve the journal block length */
+ /* copy out the journal file path -- check length in passing.
+ *
+ * we could probably do this faster with a memcpy(), but this
+ * operation happens very infrequently, and doing it this way
+ * adds a bit of sanity checking.
+ */
+ i = 0;
+ do {
- H5F_DECODE_LENGTH(f, p, mesg->mdc_jrnl_block_len);
+ ch = (char)(*p++);
+ mesg->mdc_jnl_file_name[i++] = ch;
+
+ } while ( ( ch != '\0' ) && ( i <= path_len ) );
+
+ if ( ( ch != '\0' ) || ( i != path_len + 1 ) ) {
+
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, \
+ "bad path and/or path len")
+ }
/* Set return value */
ret_value = (void *)mesg;
@@ -201,6 +235,8 @@ H5O_mdj_msg_encode(H5F_t *f,
{
const H5O_mdj_msg_t *mesg = (const H5O_mdj_msg_t *)_mesg;
uint16_t flags = 0;
+ int32_t magic;
+ int32_t path_len;
herr_t ret_value;
FUNC_ENTER_NOAPI_NOINIT(H5O_mdj_msg_encode)
@@ -210,28 +246,40 @@ H5O_mdj_msg_encode(H5F_t *f,
HDassert(p);
HDassert(mesg);
- /* this error check exists to keep the compiler happy */
if ( ( f == NULL ) || ( p == NULL ) || ( mesg == NULL ) ) {
HGOTO_ERROR(H5E_SYSTEM, H5E_SYSERRSTR, FAIL, "Bad params on entry.");
}
+ if ( mesg->mdc_jnl_file_name_len > H5C2__MAX_JOURNAL_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_SYSTEM, H5E_SYSERRSTR, FAIL, \
+ "Bad params on entry -- path len too long.");
+ }
+
/* setup the flags */
- if ( mesg->mdc_jrnl_enabled ) {
+ if ( mesg->mdc_jnl_enabled ) {
flags |= MDJ_MSG__JOURNALING_ENABLED_FLAG;
}
- /* Store version, flags, internal_loc, path_len, & path buffer */
+ magic = mesg->mdc_jnl_magic;
+
+ path_len = (int32_t)(mesg->mdc_jnl_file_name_len);
+
+ /* Store version, flags, magic, path_len, & path */
*p++ = H5O_MDJ_CONF_VERSION;
UINT16ENCODE(p, flags);
- H5F_addr_encode(f, &p, mesg->mdc_jrnl_block_loc);
-
- H5F_ENCODE_LENGTH(f, p, mesg->mdc_jrnl_block_len);
+ INT32ENCODE(p, magic);
+
+ INT32ENCODE(p, path_len);
+
+ HDmemcpy(p, mesg->mdc_jnl_file_name, path_len + 1);
+ p += path_len + 1;
done:
@@ -267,6 +315,11 @@ H5O_mdj_msg_copy(const void *_mesg, void *_dest)
/* Sanity check */
HDassert(mesg);
+ if ( mesg->mdc_jnl_file_name_len > H5C2__MAX_JOURNAL_FILE_NAME_LEN ) {
+
+ HGOTO_ERROR(H5E_SYSTEM, H5E_SYSERRSTR, FAIL, "path len too long.");
+ }
+
if ( ( ! dest ) &&
( NULL == (dest = H5MM_malloc(sizeof(H5O_mdj_msg_t))) ) ) {
@@ -276,9 +329,41 @@ H5O_mdj_msg_copy(const void *_mesg, void *_dest)
}
/* now copy the message */
- dest->mdc_jrnl_enabled = mesg->mdc_jrnl_enabled;
- dest->mdc_jrnl_block_loc = mesg->mdc_jrnl_block_loc;
- dest->mdc_jrnl_block_len = mesg->mdc_jrnl_block_len;
+ dest->mdc_jnl_enabled = mesg->mdc_jnl_enabled;
+ dest->mdc_jnl_magic = mesg->mdc_jnl_magic;
+ dest->mdc_jnl_file_name_len = mesg->mdc_jnl_file_name_len;
+
+ /* copy the journal file path -- check length in passing.
+ *
+ * we could probably do this faster with a memcpy(), but this
+ * operation happens very infrequently, and doing it this way
+ * adds a bit of sanity checking.
+ */
+ if ( mesg->mdc_jnl_file_name_len == 0 ) {
+
+ (dest->mdc_jnl_file_name)[0] = '\0';
+
+ } else {
+
+ char ch;
+ int i = 0;
+ size_t path_len;
+
+ path_len = mesg->mdc_jnl_file_name_len;
+
+ do {
+
+ ch = (mesg->mdc_jnl_file_name)[i];
+ (dest->mdc_jnl_file_name)[i++] = ch;
+
+ } while ( ( ch != '\0' ) && ( i <= path_len ) );
+
+ if ( ( ch != '\0' ) || ( i != path_len + 1 ) ) {
+
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, \
+ "bad path and/or path len???")
+ }
+ }
/* Set return value */
ret_value = dest;
@@ -314,10 +399,12 @@ H5O_mdj_msg_size(const H5F_t *f,
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_mdj_msg_size)
/* Sanity check */
- HDassert(f);
- HDassert(mesg);
+ HDassert( f );
+ HDassert( mesg );
+ HDassert( mesg->mdc_jnl_file_name_len >= 0 );
+
+ FUNC_LEAVE_NOAPI(MDJ_MSG_LEN(f, mesg->mdc_jnl_file_name_len))
- FUNC_LEAVE_NOAPI(MDJ_MSG_LEN(f))
} /* end H5O_mdj_msg_size() */
@@ -348,11 +435,13 @@ H5O_mdj_msg_reset(void *_mesg)
HDassert(mesg);
/* reset */
- mesg->mdc_jrnl_enabled = FALSE;
- mesg->mdc_jrnl_block_loc = HADDR_UNDEF;
- mesg->mdc_jrnl_block_len = 0;
+ mesg->mdc_jnl_enabled = FALSE;
+ mesg->mdc_jnl_magic = 0;
+ mesg->mdc_jnl_file_name_len = 0;
+ (mesg->mdc_jnl_file_name)[0] = '\0';
FUNC_LEAVE_NOAPI(SUCCEED)
+
} /* H5O_mdj_msg_reset() */
@@ -389,17 +478,22 @@ H5O_mdj_msg_debug(H5F_t UNUSED *f,
HDassert(fwidth >= 0);
HDfprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
- "mdc_jrnl_enabled:",
- (int)(mesg->mdc_jrnl_enabled));
+ "mdc_jnl_enabled:",
+ (int)(mesg->mdc_jnl_enabled));
- HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
- "mdc_jrnl_bloc_loc:",
- mesg->mdc_jrnl_block_loc);
+ HDfprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "mdc_jnl_magic:",
+ (int)(mesg->mdc_jnl_magic));
HDfprintf(stream, "%*s%-*s %d\n", indent, "", fwidth,
- "mdc_jrnl_block_len:",
- (int)(mesg->mdc_jrnl_block_len));
+ "mdc_jnl_file_name_len:",
+ (int)(mesg->mdc_jnl_file_name_len));
+
+ HDfprintf(stream, "%*s%-*s \"%s\"\n", indent, "", fwidth,
+ "mdc_jnl_file_name:",
+ (char *)(mesg->mdc_jnl_file_name));
FUNC_LEAVE_NOAPI(SUCCEED)
+
} /* end H5O_mdj_msg_debug() */
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 3c29c24..9bfe756 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -2012,15 +2012,22 @@ H5O_copy_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
HDassert(mesg);
/* Protect chunk */
- if(NULL == (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, idx_msg->chunkno)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header chunk")
+ if ( NULL ==
+ (chk_proxy = H5O_chunk_protect(f, dxpl_id, oh, idx_msg->chunkno)) ) {
+
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, \
+ "unable to load object header chunk")
+ }
/* Reset existing native information for the header's message */
H5O_msg_reset_real(type, idx_msg->native);
/* Copy the native object for the message */
- if(NULL == (idx_msg->native = (type->copy)(mesg, idx_msg->native)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy message to object header")
+ if ( NULL == (idx_msg->native = (type->copy)(mesg, idx_msg->native)) ) {
+
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, \
+ "unable to copy message to object header")
+ }
/* Update the message flags */
idx_msg->flags = mesg_flags;
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 2b3710c..4cac29d 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -509,30 +509,44 @@ typedef uint32_t H5O_refcount_t; /* Contains # of links to object, if >1
/*
* Metadata journaling message
*
- * Information on whether are being journaled, and if so, the size and
- * location of the on disk block containing the deatils of the journaling.
+ * Information on whether are being journaled, and if so, the magic
+ * number (if defined) and path to the journal file.
* (Data structure in memory)
*
* The fields of the H5O_mdj_msg_t structure are discussed individually
* below:
*
- * mdc_jrnl_enabled: Boolean flag indicating whether metadata journaling
+ * mdc_jnl_enabled: Boolean flag indicating whether metadata journaling
* is currently enabled.
*
- * mdc_jrnl_block_loc: haddr_t containing the base address of the
- * of the block containing the configuration details of the
- * journaling.
+ * mdc_jnl_magic: Randomly selected int32_t used to reduce the possibility
+ * of running the wrong journal on an HDF5 file. The basic idea is
+ * to pick a random number, store it in both the HDF5 file and the
+ * journal file, and then refuse to run the journal unless the numbers
+ * match.
*
- * mdc_jrnl_block_len: hsize_t containing the size of the buffer needed to
- * contain the journaling configuration block
+ * The value of this field is undefined unless mdc_jnl_enabled is TRUE.
*
- * If the journal is internal, this field must be NULL.
+ * mdc_jnl_file_name_len: Length of the journal file name.
+ *
+ * The value of this field is undefined unless mdc_jnl_enabled is TRUE.
+ *
+ * mdc_jnl_file_name: Array of char of length
+ * H5C2__MAX_JOURNAL_FILE_NAME_LEN + 1 used to store the journal
+ * file path.
+ *
+ * The value of this field is undefined unless mdc_jnl_enabled is TRUE.
*/
+
+#define H5O_MDJ_CONF_VERSION 0
+#define MDJ_MSG__JOURNALING_ENABLED_FLAG 0x0001
+
typedef struct H5O_mdj_msg_t {
- hbool_t mdc_jrnl_enabled;
- haddr_t mdc_jrnl_block_loc;
- hsize_t mdc_jrnl_block_len;
+ hbool_t mdc_jnl_enabled;
+ int32_t mdc_jnl_magic;
+ size_t mdc_jnl_file_name_len;
+ char mdc_jnl_file_name[H5C2__MAX_JOURNAL_FILE_NAME_LEN + 1];
} H5O_mdj_msg_t;