diff options
author | mainzer <mainzer#hdfgroup.org> | 2019-01-15 22:36:51 (GMT) |
---|---|---|
committer | mainzer <mainzer#hdfgroup.org> | 2019-01-15 22:36:51 (GMT) |
commit | b4f607bc13841c5366f232e16c776d700d15b5be (patch) | |
tree | 1aba531e6d30925e11aa6393a14a4c91a0e0dec8 /src | |
parent | 4f8917f9086088ac5cc7fa3c3deb400afbf33b68 (diff) | |
download | hdf5-b4f607bc13841c5366f232e16c776d700d15b5be.zip hdf5-b4f607bc13841c5366f232e16c776d700d15b5be.tar.gz hdf5-b4f607bc13841c5366f232e16c776d700d15b5be.tar.bz2 |
Intermin commit to allow update from Vailin's recent changes
Diffstat (limited to 'src')
-rw-r--r-- | src/H5AC.c | 22 | ||||
-rw-r--r-- | src/H5C.c | 160 | ||||
-rw-r--r-- | src/H5Cpkg.h | 16 | ||||
-rw-r--r-- | src/H5Cprivate.h | 2 | ||||
-rw-r--r-- | src/H5FD.c | 3 | ||||
-rw-r--r-- | src/H5FDint.c | 2 | ||||
-rw-r--r-- | src/H5FDprivate.h | 4 | ||||
-rw-r--r-- | src/H5FDvfd_swmr.c | 490 | ||||
-rw-r--r-- | src/H5Fint.c | 197 | ||||
-rw-r--r-- | src/H5Ftest.c | 6 | ||||
-rw-r--r-- | src/H5MV.c | 41 | ||||
-rw-r--r-- | src/H5PB.c | 10 |
12 files changed, 783 insertions, 170 deletions
@@ -278,6 +278,11 @@ H5AC_cache_image_pending(const H5F_t *f) * matzke@llnl.gov * Jul 9 1997 * + * Changes: Added code to configrue the metadata cache for VFD SWMR + * reader operations when indicated. + * + * JRM -- 1/15/19 + * *------------------------------------------------------------------------- */ herr_t @@ -418,6 +423,23 @@ H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_co HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "unable to emit log message") } /* end if */ + /* Configure the metadata cache for VFD SWMR reader operation if + * specified. + */ + if ( ( H5F_VFD_SWMR_CONFIG(f) ) && + ( !f->shared->vfd_swmr_config.vfd_swmr_writer ) ) { + + HDassert(!(H5F_INTENT(f) & H5F_ACC_RDWR)); + HDassert(f->shared->fs_page_size > 0); + + if ( H5C_set_vfd_swmr_reader(f->shared->cache, TRUE, + f->shared->fs_page_size) < 0 ) + + HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, \ + "can't configure MDC for VFD SWMR reader operations"); + + } + /* Set the cache parameters */ if(H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "auto resize configuration failed") @@ -336,6 +336,7 @@ H5C_create(size_t max_cache_size, for(i = 0; i < H5C__PAGE_HASH_TABLE_LEN; i++) { (cache_ptr->page_index)[i] = NULL; } + cache_ptr->page_size = 0; /* Tagging Field Initializations */ cache_ptr->ignore_tags = FALSE; @@ -983,7 +984,6 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t * f, uint64_t page, unsigned flush_flags = (H5C__FLUSH_INVALIDATE_FLAG | H5C__FLUSH_CLEAR_ONLY_FLAG); haddr_t tag; - H5PB_t * pb_ptr = NULL; H5C_t * cache_ptr = NULL; H5C_cache_entry_t * entry_ptr; H5C_cache_entry_t * follow_ptr = NULL; @@ -1001,16 +1001,17 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t * f, uint64_t page, HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); HDassert(cache_ptr->vfd_swmr_reader); +#if 1 /* JRM */ + HDfprintf(stderr, + "H5C_evict_or_refresh_all_entries_in_page() entering. page = %lld\n", + page); +#endif /* JRM */ + /* since file must be opened R/O for a VFD SWMR reader, the skip * list must be empty. Verify this. */ HDassert(cache_ptr->slist_len == 0); - pb_ptr = f->shared->pb_ptr; - - HDassert(pb_ptr); - HDassert(pb_ptr->magic == H5PB__H5PB_T_MAGIC); - i = H5C__PI_HASH_FCN(page); entry_ptr = (cache_ptr->page_index)[i]; @@ -1021,8 +1022,9 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t * f, uint64_t page, if ( entry_ptr->page == page ) { - HDassert(entry_ptr->addr >= (haddr_t)(page * pb_ptr->page_size)); - HDassert(entry_ptr->addr < (haddr_t)((page+1) * pb_ptr->page_size)); + HDassert(entry_ptr->addr >= (haddr_t)(page * cache_ptr->page_size)); + HDassert(entry_ptr->addr < + (haddr_t)((page+1) * cache_ptr->page_size)); /* since end of tick occurs only on API call entry in * the VFD SWMR reader case, the entry must not be protected. @@ -1047,6 +1049,11 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t * f, uint64_t page, tag = entry_ptr->tag_info->tag; HDassert(!(entry_ptr->tag_info->corked)); +#if 1 /* JRM */ + HDfprintf(stderr, + "evicting tagged entries addr/page/tag == %lld/%lld/%lld\n", + entry_ptr->addr, entry_ptr->page, tag); +#endif /* JRM */ /* passing TRUE for the match_global parameter. Look * into this and verify that it is the right thing to @@ -1061,6 +1068,10 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t * f, uint64_t page, entry_ptr = NULL; } else if ( entry_ptr->type->refresh ) { +#if 1 /* JRM */ + HDfprintf(stderr, "refreshing addr/page/tag == %lld/%lld\n", + entry_ptr->addr, entry_ptr->page); +#endif /* JRM */ /* If the entry is pinned and not tagged, it is a global * object such as the super block, persistant free * space manager, or a global heap. @@ -1205,6 +1216,19 @@ H5C_evict_or_refresh_all_entries_in_page(H5F_t * f, uint64_t page, * skip list -- thus no need for the * H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG. */ +#if 1 /* JRM */ + if ( entry_ptr->tag_info ) { + + HDfprintf(stderr, + "evicting entry addr/page/tag == %lld/%lld/%lld\n", + entry_ptr->addr, entry_ptr->page, + entry_ptr->tag_info->tag); + } else { + HDfprintf(stderr, + "evicting entry addr/page == %lld/%lld no tag\n", + entry_ptr->addr, entry_ptr->page); + } +#endif /* JRM */ if ( H5C__flush_single_entry(f, entry_ptr, flush_flags) < 0 ) HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, \ @@ -1628,12 +1652,9 @@ H5C_insert_entry(H5F_t * f, HDassert( cache_ptr ); HDassert( cache_ptr->magic == H5C__H5C_T_MAGIC ); - /* if this is a VFD SWMR reader, verify that the page buffer is - * configured. - */ - HDassert( ( ! cache_ptr->vfd_swmr_reader ) || - ( ( f->shared->pb_ptr ) && - ( f->shared->pb_ptr->magic == H5PB__H5PB_T_MAGIC ) ) ); + /* if this is a VFD SWMR reader, verify that the page size is defined */ + HDassert( ( ! cache_ptr->vfd_swmr_reader ) || + ( cache_ptr->page_size > 0 ) ); HDassert( type ); HDassert( type->mem_type == cache_ptr->class_table_ptr[type->id]->mem_type ); @@ -1767,7 +1788,7 @@ H5C_insert_entry(H5F_t * f, /* initialize fields supporting VFD SWMR */ if ( cache_ptr->vfd_swmr_reader ) { - entry_ptr->page = (addr / f->shared->pb_ptr->page_size); + entry_ptr->page = (addr / cache_ptr->page_size); } else { @@ -2256,11 +2277,7 @@ done: * 6/2/04 * * Changes: Added code to update cache entry page field required - * by VFD SWMR. To do this, we need the page size used - * by the page buffer. The simple way to do this was to - * replace the cache_ptr parameter with a pointer to the - * H5F_t, and then lookup the cache_ptr and pb_ptr as - * required. + * by VFD SWMR. * JRM -- 12/13/18 * *------------------------------------------------------------------------- @@ -2287,14 +2304,9 @@ H5C_move_entry(H5F_t * f, HDassert(cache_ptr); HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); - /* if this is a VFD SWMR reader, verify that the page buffer is - * configured. - */ + /* if this is a VFD SWMR reader, verify that the page size is defined */ HDassert(( ! cache_ptr->vfd_swmr_reader ) || - ( ( f->shared->pb_ptr ) && - ( f->shared->pb_ptr->magic == H5PB__H5PB_T_MAGIC ) )); - - + ( cache_ptr->page_size > 0 ) ); HDassert(type); HDassert(H5F_addr_defined(old_addr)); @@ -2375,7 +2387,7 @@ H5C_move_entry(H5F_t * f, */ if ( cache_ptr->vfd_swmr_reader ) { - entry_ptr->page = (new_addr / f->shared->pb_ptr->page_size); + entry_ptr->page = (new_addr / cache_ptr->page_size); } @@ -3411,6 +3423,43 @@ done: /*------------------------------------------------------------------------- + * Function: H5C_set_vfd_swmr_reader() + * + * Purpose: Set cache_ptr->vfd_swmr_reader and cache_ptr->page_size to + * the values specified in the parameter list. + * + * Return: SUCCEED on success, and FAIL on failure. + * + * Programmer: John Mainzer + * 1/15/19 + * + * Changes: None. + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_set_vfd_swmr_reader(H5C_t *cache_ptr, hbool_t vfd_swmr_reader, + hsize_t page_size) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + if((cache_ptr == NULL) || (cache_ptr->magic != H5C__H5C_T_MAGIC)) + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr on entry") + + cache_ptr->vfd_swmr_reader = vfd_swmr_reader; + cache_ptr->page_size = page_size; + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5C_set_vfd_swmr_reader() */ + + +/*------------------------------------------------------------------------- * Function: H5C_unpin_entry() * * Purpose: Unpin a cache entry. The entry can be either protected or @@ -6913,14 +6962,24 @@ H5C__flush_single_entry(H5F_t *f, H5C_cache_entry_t *entry_ptr, unsigned flags) /* Check if we have to update the page buffer with cleared entries * so it doesn't go out of date */ + + /* VFD SWMR TODO: Think on this, and decide if we need to extend + * this for multi page metadata entries. + */ if(update_page_buffer) { /* Sanity check */ HDassert(!destroy); HDassert(entry_ptr->image_ptr); - if(f->shared->pb_ptr && f->shared->pb_ptr->page_size >= entry_ptr->size) - if(H5PB_update_entry(f->shared->pb_ptr, entry_ptr->addr, entry_ptr->size, entry_ptr->image_ptr) > 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Failed to update PB with metadata cache") + if ( ( f->shared->pb_ptr ) && + ( f->shared->pb_ptr->page_size >= entry_ptr->size ) ) { + + if ( H5PB_update_entry(f->shared->pb_ptr, entry_ptr->addr, + entry_ptr->size, entry_ptr->image_ptr) > 0 ) + + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ + "Failed to update PB with metadata cache") + } } /* end if */ if(cache_ptr->log_flush) @@ -7034,6 +7093,7 @@ H5C_load_entry(H5F_t * f, void * thing = NULL; /* Pointer to thing loaded */ H5C_cache_entry_t *entry = NULL; /* Alias for thing loaded, as */ /* cache entry */ + size_t init_len; size_t len; /* Size of image in file */ #ifdef H5_HAVE_PARALLEL int mpi_rank = 0; /* MPI process rank */ @@ -7050,12 +7110,9 @@ H5C_load_entry(H5F_t * f, HDassert(f->shared->cache); HDassert(f->shared->cache->magic == H5C__H5C_T_MAGIC ); - /* if this is a VFD SWMR reader, verify that the page buffer is - * configured. - */ + /* if this is a VFD SWMR reader, verify that the page size is defined */ HDassert( ( ! f->shared->cache->vfd_swmr_reader ) || - ( ( f->shared->pb_ptr ) && - ( f->shared->pb_ptr->magic == H5PB__H5PB_T_MAGIC ) ) ); + ( f->shared->cache->page_size > 0 ) ); HDassert(type); HDassert(H5F_addr_defined(addr)); @@ -7087,6 +7144,8 @@ H5C_load_entry(H5F_t * f, HDassert(len > 0); + init_len = len; + /* Check for possible speculative read off the end of the file */ if ( type->flags & H5C__CLASS_SPECULATIVE_LOAD_FLAG ) { @@ -7296,9 +7355,23 @@ H5C_load_entry(H5F_t * f, } while(--tries); /* Check for too many tries */ - if(tries == 0) + if ( tries == 0 ) { + + haddr_t eoa; + int64_t page = (int64_t)(addr / f->shared->cache->page_size); + + eoa = H5F_get_eoa(f, type->mem_type); + + HDfprintf(stderr, "addr = 0x%llx, init_len = %lld, len = %lld\n", + (int64_t)addr, (int64_t)init_len, (int64_t)len); + HDfprintf(stderr, "type = %s, eoa = 0x%llx, tick = %lld\n", + type->name, (int64_t)eoa, f->shared->tick_num); + HDfprintf(stderr, "page = %lld, index_len = %d\n", + page, f->shared->mdf_idx_entries_used); + H5FD_vfd_swmr_dump_status(f->shared->lf, page); HGOTO_ERROR(H5E_CACHE, H5E_READERROR, NULL, \ "incorrect metadatda checksum after all read attempts") + } /* Calculate and track the # of retries */ retries = max_tries - tries; @@ -7419,7 +7492,7 @@ H5C_load_entry(H5F_t * f, /* initialize fields supporting VFD SWMR */ if ( f->shared->cache->vfd_swmr_reader ) { - entry->page = (addr / f->shared->pb_ptr->page_size); + entry->page = (addr / f->shared->cache->page_size); } else { @@ -9152,12 +9225,9 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr) HDassert(cache_ptr); HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); - /* if this is a VFD SWMR reader, verify that the page buffer is - * configured. - */ + /* if this is a VFD SWMR reader, verify that the page size is defined */ HDassert( ( ! cache_ptr->vfd_swmr_reader ) || - ( ( f->shared->pb_ptr ) && - ( f->shared->pb_ptr->magic == H5PB__H5PB_T_MAGIC ) ) ); + ( cache_ptr->page_size > 0 ) ); HDassert(entry_ptr); HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); @@ -9293,7 +9363,7 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr) /* In the VFD SWMR reader case, update the entry page field */ if ( cache_ptr->vfd_swmr_reader ) { - entry_ptr->page = (new_addr / f->shared->pb_ptr->page_size); + entry_ptr->page = (new_addr / cache_ptr->page_size); } /* And then reinsert in the index and slist */ @@ -9305,7 +9375,7 @@ H5C__generate_image(H5F_t *f, H5C_t *cache_ptr, H5C_cache_entry_t *entry_ptr) HDassert(entry_ptr->addr == new_addr); HDassert(( ! cache_ptr->vfd_swmr_reader ) || ( entry_ptr->page == - (entry_ptr->addr / f->shared->pb_ptr->page_size) )); + (entry_ptr->addr / cache_ptr->page_size) )); } } /* end if */ } /* end if(serialize_flags != H5C__SERIALIZE_NO_FLAGS_SET) */ diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 1fe4523..b82ba41 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -1102,7 +1102,7 @@ if ( ( (cache_ptr) == NULL ) || \ (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) ) || \ ( (cache_ptr)->index_len != (cache_ptr)->il_len ) || \ ( (cache_ptr)->index_size != (cache_ptr)->il_size ) ) { \ - HDassert(FALSE); \ + HDassert(FALSE && "pre HT remove SC failed"); \ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "pre HT remove SC failed") \ } @@ -1113,9 +1113,9 @@ if ( ( (cache_ptr) == NULL ) || \ ( ! H5F_addr_defined((entry_ptr)->addr) ) || \ ( (entry_ptr)->size <= 0 ) || \ ( (entry_ptr)->ht_prev != NULL ) || \ - ( (entry_ptr)->ht_prev != NULL ) || \ - ( (entry_ptr)->pi_prev != NULL ) || \ + ( (entry_ptr)->ht_next != NULL ) || \ ( (entry_ptr)->pi_prev != NULL ) || \ + ( (entry_ptr)->pi_next != NULL ) || \ ( (cache_ptr)->index_size != \ ((cache_ptr)->clean_index_size + \ (cache_ptr)->dirty_index_size) ) || \ @@ -1130,7 +1130,7 @@ if ( ( (cache_ptr) == NULL ) || \ (cache_ptr)->dirty_index_ring_size[(entry_ptr)->ring]) ) || \ ( (cache_ptr)->index_len != (cache_ptr)->il_len ) || \ ( (cache_ptr)->index_size != (cache_ptr)->il_size ) ) { \ - HDassert(FALSE); \ + HDassert(FALSE && "post HT remove SC failed"); \ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "post HT remove SC failed") \ } @@ -1409,10 +1409,10 @@ if ( ( (cache_ptr)->index_size != \ H5C__PRE_HT_REMOVE_SC(cache_ptr, entry_ptr) \ if ( cache_ptr->vfd_swmr_reader ) { \ k = H5C__PI_HASH_FCN((entry_ptr)->page); \ - if ( (entry_ptr)->ht_next ) { \ + if ( (entry_ptr)->pi_next ) { \ (entry_ptr)->pi_next->pi_prev = (entry_ptr)->pi_prev; \ } \ - if ( (entry_ptr)->ht_prev ) { \ + if ( (entry_ptr)->pi_prev ) { \ (entry_ptr)->pi_prev->pi_next = (entry_ptr)->pi_next; \ } \ if ( ( (cache_ptr)->page_index)[k] == (entry_ptr) ) { \ @@ -3814,6 +3814,9 @@ typedef struct H5C_tag_info_t { * H5C__PAGE_HASH_TABLE_LEN. This size must be a power of * two, not the usual prime number. * + * page_size: Convenience copy of the page size used by the page + * buffer. + * * * With the addition of the take ownership flag, it is possible that * an entry may be removed from the cache as the result of the flush of @@ -4802,6 +4805,7 @@ struct H5C_t { /* Fields supporting VFD SWMR */ hbool_t vfd_swmr_reader; H5C_cache_entry_t * page_index[H5C__PAGE_HASH_TABLE_LEN]; + hsize_t page_size; /* Fields to detect entries removed during scans */ int64_t entries_removed_counter; diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index e44475a..9bc9197 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -2445,6 +2445,8 @@ H5_DLL herr_t H5C_set_cache_image_config(const H5F_t *f, H5C_t *cache_ptr, H5C_cache_image_ctl_t *config_ptr); H5_DLL herr_t H5C_set_evictions_enabled(H5C_t *cache_ptr, hbool_t evictions_enabled); +H5_DLL herr_t H5C_set_vfd_swmr_reader(H5C_t *cache_ptr, + hbool_t vfd_swmr_reader, hsize_t page_size); H5_DLL herr_t H5C_set_prefix(H5C_t *cache_ptr, char *prefix); H5_DLL herr_t H5C_set_trace_file_ptr(H5C_t *cache_ptr, FILE *trace_file_ptr); H5_DLL herr_t H5C_stats(H5C_t *cache_ptr, const char *cache_name, @@ -737,6 +737,9 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) /* Dispatch to file driver */ if(HADDR_UNDEF == maxaddr) maxaddr = driver->maxaddr; +#if 0 /* JRM */ + HDfprintf(stderr, "H5FD_open(): calling %s.open().\n", driver->name); +#endif /* JRM */ if(NULL == (file = (driver->open)(name, flags, fapl_id, maxaddr))) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed") diff --git a/src/H5FDint.c b/src/H5FDint.c index b423490..ac6e09a 100644 --- a/src/H5FDint.c +++ b/src/H5FDint.c @@ -183,6 +183,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*o * objects being written within the file by the application performing * SWMR write operations. */ +#if 0 /* JRM */ if(!(file->access_flags & H5F_ACC_SWMR_READ)) { haddr_t eoa; @@ -192,6 +193,7 @@ H5FD_read(H5FD_t *file, H5FD_mem_t type, haddr_t addr, size_t size, void *buf/*o if((addr + file->base_addr + size) > eoa) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size = %llu, eoa = %llu", (unsigned long long)(addr + file->base_addr), (unsigned long long)size, (unsigned long long)eoa) } +#endif /* JRM */ /* Dispatch to driver */ if((file->cls->read)(file, type, dxpl_id, addr + file->base_addr, size, buf) < 0) diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index bded6d5..b40c9f0 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -323,9 +323,11 @@ H5_DLL herr_t H5FD_get_driver_name(const H5FD_t *file, char **driver_name); /* Function prototypes for VFD SWMR */ H5_DLL herr_t H5FD_vfd_swmr_get_tick_and_idx(H5FD_t *_file, hbool_t read_index, - uint64_t *tick_ptr, uint32_t *num_entries_ptr, H5FD_vfd_swmr_idx_entry_t index[]); + uint64_t *tick_ptr, uint32_t *num_entries_ptr, + H5FD_vfd_swmr_idx_entry_t index[]); H5_DLL hbool_t H5FD_is_vfd_swmr_driver(H5FD_t *_file); H5_DLL H5FD_t *H5FD_vfd_swmr_get_underlying_vfd(H5FD_t *_file); +H5_DLL void H5FD_vfd_swmr_dump_status(H5FD_t *_file, int64_t page); /* Function prototypes for MPI based VFDs*/ #ifdef H5_HAVE_PARALLEL diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index 6bf0252..81b7fe7 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -31,44 +31,54 @@ static hid_t H5FD_VFD_SWMR_g = 0; typedef struct H5FD_vfd_swmr_t { - H5FD_t pub; /* public stuff, must be first */ + H5FD_t pub; /* public stuff, must be */ + /* first */ /* HDF5 file */ - char hdf5_filename[H5FD_MAX_FILENAME_LEN]; /* Name of the HDF5 file from open */ - H5FD_t *hdf5_file_lf; /* Driver info for the HDF5 file */ + char hdf5_filename[H5FD_MAX_FILENAME_LEN]; /* Name of the HDF5 file from */ + /* open */ + H5FD_t *hdf5_file_lf; /* Driver info for the HDF5 */ + /* file */ /* Metadata file */ - int md_fd; /* File descriptor for the metadata file */ - int32_t md_pages_reserved; /* # of pages reserved at the head of the metadata file */ - char md_file_path[H5FD_MAX_FILENAME_LEN]; /* Name of the metadate file */ - H5FD_vfd_swmr_md_header md_header; /* Metadata file header */ - H5FD_vfd_swmr_md_index md_index; /* Metadata file index */ + int md_fd; /* File descriptor for the */ + /* metadata file */ + int32_t md_pages_reserved; /* # of pages reserved at the */ + /* head of the metadata file */ + char md_file_path[H5FD_MAX_FILENAME_LEN]; /* Name of the metadate file */ + H5FD_vfd_swmr_md_header md_header; /* Metadata file header */ + H5FD_vfd_swmr_md_index md_index; /* Metadata file index */ } H5FD_vfd_swmr_t; #define MAXADDR (((haddr_t)1<<(8*sizeof(HDoff_t)-1))-1) /* Prototypes */ static herr_t H5FD_vfd_swmr_term(void); -static H5FD_t *H5FD_vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, - haddr_t maxaddr); +static H5FD_t *H5FD_vfd_swmr_open(const char *name, unsigned flags, + hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD_vfd_swmr_close(H5FD_t *_file); static int H5FD_vfd_swmr_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD_vfd_swmr_query(const H5FD_t *_f1, unsigned long *flags); static haddr_t H5FD_vfd_swmr_get_eoa(const H5FD_t *_file, H5FD_mem_t type); -static herr_t H5FD_vfd_swmr_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); +static herr_t H5FD_vfd_swmr_set_eoa(H5FD_t *_file, H5FD_mem_t type, + haddr_t addr); static haddr_t H5FD_vfd_swmr_get_eof(const H5FD_t *_file, H5FD_mem_t type); -static herr_t H5FD_vfd_swmr_get_handle(H5FD_t *_file, hid_t fapl, void** file_handle); -static herr_t H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - size_t size, void *buf); -static herr_t H5FD_vfd_swmr_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, - size_t size, const void *buf); -static herr_t H5FD_vfd_swmr_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); +static herr_t H5FD_vfd_swmr_get_handle(H5FD_t *_file, hid_t fapl, + void** file_handle); +static herr_t H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, + hid_t fapl_id, haddr_t addr, size_t size, void *buf); +static herr_t H5FD_vfd_swmr_write(H5FD_t *_file, H5FD_mem_t type, + hid_t fapl_id, haddr_t addr, size_t size, const void *buf); +static herr_t H5FD_vfd_swmr_truncate(H5FD_t *_file, hid_t dxpl_id, + hbool_t closing); static herr_t H5FD_vfd_swmr_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD_vfd_swmr_unlock(H5FD_t *_file); /* VFD SWMR */ -static herr_t H5FD__vfd_swmr_header_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_header *md_header); -static herr_t H5FD__vfd_swmr_index_deserialize(H5FD_t *_file, H5FD_vfd_swmr_md_index *md_index, H5FD_vfd_swmr_md_header *md_header); +static herr_t H5FD__vfd_swmr_header_deserialize(H5FD_t *_file, + H5FD_vfd_swmr_md_header *md_header); +static herr_t H5FD__vfd_swmr_index_deserialize(H5FD_t *_file, + H5FD_vfd_swmr_md_index *md_index, H5FD_vfd_swmr_md_header *md_header); static herr_t H5FD__vfd_swmr_load_hdr_and_idx(H5FD_t *_file, hbool_t open); static const H5FD_class_t H5FD_vfd_swmr_g = { @@ -236,35 +246,47 @@ done: *------------------------------------------------------------------------- */ static H5FD_t * -H5FD_vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) +H5FD_vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr) { - H5FD_vfd_swmr_t *file = NULL; /* VFD SWMR driver info */ - H5P_genplist_t *plist; /* Property list pointer */ - H5F_vfd_swmr_config_t *vfd_swmr_config = NULL; /* Points to VFD SWMR configuration */ - unsigned file_retries = H5FD_VFD_SWMR_MD_FILE_RETRY_MAX; /* Maximum retries for opening md file */ - uint64_t nanosec = 1; /* # of nanoseconds to sleep between retries */ - H5FD_t *ret_value = NULL; /* Return value */ + H5FD_vfd_swmr_t *file = NULL; /* VFD SWMR driver info */ + H5P_genplist_t *plist; /* Property list pointer */ + H5F_vfd_swmr_config_t *vfd_swmr_config = /* Points to VFD SWMR */ + NULL; /* configuration */ + unsigned file_retries = /* Maximum retries for opening */ + H5FD_VFD_SWMR_MD_FILE_RETRY_MAX; /* md file */ + uint64_t nanosec = 1; /* # of nanoseconds to sleep */ + /* between retries */ + H5FD_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Get file access property list */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") + + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, \ + "not a file access property list") /* Allocate buffer for reading the VFD SWMR configuration */ - if(NULL == (vfd_swmr_config = (H5F_vfd_swmr_config_t *)H5MM_malloc(sizeof(H5F_vfd_swmr_config_t)))) - HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "memory allocation failed for H5F_vfd_swmr_config_t") + if(NULL == (vfd_swmr_config = (H5F_vfd_swmr_config_t *) + H5MM_malloc(sizeof(H5F_vfd_swmr_config_t)))) + + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, \ + "memory allocation failed for H5F_vfd_swmr_config_t") /* Get VFD SWMR configuration */ if(H5P_get(plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, vfd_swmr_config) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get VFD SWMR config info") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, \ + "can't get VFD SWMR config info") /* Ensure that this is the reader */ HDassert(!vfd_swmr_config->vfd_swmr_writer); /* Create the new driver struct */ if(NULL == (file = H5FL_CALLOC(H5FD_vfd_swmr_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") + + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, \ + "unable to allocate file struct") file->hdf5_file_lf = NULL; file->md_pages_reserved = vfd_swmr_config->md_pages_reserved; @@ -274,7 +296,8 @@ H5FD_vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxa file->hdf5_filename[sizeof(file->hdf5_filename) - 1] = '\0'; /* Retain a copy of the metadata file name */ - HDstrncpy(file->md_file_path, vfd_swmr_config->md_file_path, sizeof(file->md_file_path)); + HDstrncpy(file->md_file_path, vfd_swmr_config->md_file_path, + sizeof(file->md_file_path)); file->md_file_path[sizeof(file->md_file_path) - 1] = '\0'; /* Retry on opening the metadata file */ @@ -288,14 +311,21 @@ H5FD_vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxa /* Exhaust all retries for opening the md file */ if(file_retries == 0) - HGOTO_ERROR(H5E_VFL, H5E_OPENERROR, NULL, "unable to open the metadata file after all retry attempts") + HGOTO_ERROR(H5E_VFL, H5E_OPENERROR, NULL, \ + "unable to open the metadata file after all retry attempts") - /* Retry on loading and decoding the header and index in the metadata file */ + /* Retry on loading and decoding the header and index in the + * metadata file + */ if(H5FD__vfd_swmr_load_hdr_and_idx((H5FD_t *)file, TRUE) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "unable to load/decode the md file header/index") + + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, \ + "unable to load/decode the md file header/index") /* Hard-wired to open the underlying HDF5 file with SEC2 */ - if((file->hdf5_file_lf = H5FD_open(name, flags, H5P_FILE_ACCESS_DEFAULT, maxaddr)) == NULL) + if((file->hdf5_file_lf = H5FD_open(name, flags, H5P_FILE_ACCESS_DEFAULT, + maxaddr)) == NULL) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "can't set driver info") /* Set return value */ @@ -308,8 +338,11 @@ done: /* Handle closing if error */ if(NULL == ret_value && file) { + if(H5FD_vfd_swmr_close((H5FD_t *)file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "error from closing") + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -343,21 +376,25 @@ H5FD_vfd_swmr_close(H5FD_t *_file) /* Close the underlying file */ if(file->hdf5_file_lf && H5FD_close(file->hdf5_file_lf) < 0) /* Push error, but keep going */ - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close the HDF5 file") + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, \ + "unable to close the HDF5 file") /* Close the metadata file */ if(file->md_fd >= 0 && HDclose(file->md_fd) < 0) /* Push error, but keep going */ - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close the metadata file") + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, \ + "unable to close the metadata file") /* Free the index entries */ if(file->md_index.num_entries && file->md_index.entries) - file->md_index.entries = H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, file->md_index.entries); + file->md_index.entries = H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, + file->md_index.entries); /* Release the driver info */ file = H5FL_FREE(H5FD_vfd_swmr_t, file); FUNC_LEAVE_NOAPI(ret_value) + } /* end H5FD_vfd_swmr_close() */ @@ -406,13 +443,34 @@ H5FD_vfd_swmr_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* /* Set the VFL feature flags that this driver supports */ if(flags) { *flags = 0; - *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */ - *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */ - *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */ - *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ - *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* get_handle callback returns a POSIX file descriptor */ - *flags |= H5FD_FEAT_SUPPORTS_SWMR_IO; /* VFD supports the single-writer/multiple-readers (SWMR) pattern */ - *flags |= H5FD_FEAT_DEFAULT_VFD_COMPATIBLE; /* VFD creates a file which can be opened with the default VFD */ + *flags |= H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate */ + /* metadata allocations */ + + *flags |= H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate */ + /* metadata for faster */ + /* writes */ + + *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data */ + /* sieving for faster */ + /* raw data reads & */ + /* writes */ + + *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate */ + /* "small" raw data */ + /* allocations */ + + *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* get_handle callback */ + /* returns a POSIX file */ + /* descriptor */ + + *flags |= H5FD_FEAT_SUPPORTS_SWMR_IO; /* VFD supports the */ + /* single-writer/ */ + /* multiple-readers */ + /* (SWMR) pattern */ + + *flags |= H5FD_FEAT_DEFAULT_VFD_COMPATIBLE; /* VFD creates a file */ + /* which can be opened */ + /* with the default VFD */ } /* end if */ @@ -423,9 +481,9 @@ H5FD_vfd_swmr_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* /*------------------------------------------------------------------------- * Function: H5FD_vfd_swmr_get_eoa * - * Purpose: Gets the end-of-address marker for the file for the underlying - * HDF5 file. The EOA marker is the first address past the last byte - * allocated in the format address space. + * Purpose: Gets the end-of-address marker for the file for the + * underlying HDF5 file. The EOA marker is the first address + * past the last byte allocated in the format address space. * * Return: The end-of-address marker. * @@ -440,7 +498,9 @@ H5FD_vfd_swmr_get_eoa(const H5FD_t *_file, H5FD_mem_t type) FUNC_ENTER_NOAPI_NOINIT if((ret_value = H5FD_get_eoa(file->hdf5_file_lf, type)) == HADDR_UNDEF) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, HADDR_UNDEF, "unable to get HDF5 file eoa") + + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, HADDR_UNDEF, \ + "unable to get HDF5 file eoa") done: FUNC_LEAVE_NOAPI(ret_value) @@ -451,8 +511,9 @@ done: * Function: H5FD_vfd_swmr_set_eoa * * Purpose: Set the end-of-address marker for the underlying HDF5 file. - * This function is called shortly after an existing HDF5 file is opened - * in order to tell the driver where the end of the HDF5 data is located. + * This function is called shortly after an existing HDF5 file + * is opened in order to tell the driver where the end of the + * HDF5 data is located. * * Return: SUCCEED (Can't fail) * @@ -467,6 +528,7 @@ H5FD_vfd_swmr_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) FUNC_ENTER_NOAPI_NOINIT if(H5FD_set_eoa(file->hdf5_file_lf, type, addr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to set HDF5 file eoa") done: @@ -496,7 +558,9 @@ H5FD_vfd_swmr_get_eof(const H5FD_t *_file, H5FD_mem_t type) /* LATER: need to determine the metadata file or underlying HDF5 file ? */ if((ret_value = H5FD_get_eof(file->hdf5_file_lf, type)) == HADDR_UNDEF) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, HADDR_UNDEF, "unable to set file eoa") + + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, HADDR_UNDEF, \ + "unable to set file eoa") done: FUNC_LEAVE_NOAPI(ret_value) @@ -525,8 +589,11 @@ H5FD_vfd_swmr_get_handle(H5FD_t *_file, hid_t fapl, void **file_handle) /* LATER? H5P_get(plist, H5F_ACS_SWMR_FILE_NAME, &type) */ - if((ret_value = H5FD_get_vfd_handle(file->hdf5_file_lf, fapl, file_handle)) < 0) - HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "unable to get handle for HDF5 file") + if((ret_value = H5FD_get_vfd_handle(file->hdf5_file_lf, + fapl, file_handle)) < 0) + + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, \ + "unable to get handle for HDF5 file") done: FUNC_LEAVE_NOAPI(ret_value) @@ -545,59 +612,164 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, +H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, + hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, void *buf /*out*/) { - H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ - H5FD_vfd_swmr_idx_entry_t *index = NULL; /* Metadata file index */ - unsigned entry_retries = H5FD_VFD_SWMR_MD_INDEX_RETRY_MAX; /* # of retries */ - uint64_t nanosec = 1; /* # of nanoseconds to sleep between retries */ - uint32_t num_entries = 0; /* Number of entries in index */ - uint32_t fs_page_size; /* Page size */ - unsigned lo = 0, hi; /* Low & high index values */ - unsigned my_idx = 0; /* Final index value */ - int cmp; /* Return from comparison */ - uint32_t computed_chksum; /* Computed checksum */ - herr_t ret_value = SUCCEED; /* Return value */ + haddr_t target_page; + void * read_ptr = NULL; /* prt into buf for read */ + H5FD_vfd_swmr_t *file = /* VFD SWMR file struct */ + (H5FD_vfd_swmr_t *)_file; + H5FD_vfd_swmr_idx_entry_t *index = NULL; /* Metadata file index */ + unsigned entry_retries = /* # of retries */ + H5FD_VFD_SWMR_MD_INDEX_RETRY_MAX; + uint64_t nanosec = 1; /* # of nanoseconds to sleep */ + /* between retries */ + int32_t num_entries = 0; /* Number of entries in index */ + uint32_t fs_page_size; /* Page size */ + int lo = 0, hi; /* Low & high index values */ + int my_idx = 0; /* Final index value */ + int cmp; /* Return from comparison */ + uint32_t computed_chksum; /* Computed checksum */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT HDassert(file && file->pub.cls); HDassert(buf); +#if 0 /* JRM */ + /* index should be loaded only at file open, and at end of tick -- JRM */ + /* Try loading and decoding the header and index in the metadata file */ if(H5FD__vfd_swmr_load_hdr_and_idx(_file, FALSE) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "unable to load/decode the md file header/index") + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, \ + "unable to load/decode the md file header/index") +#endif /* JRM */ - index = file->md_index.entries; + index = file->md_index.entries; + num_entries = (int)file->md_index.num_entries; fs_page_size = file->md_header.fs_page_size; +#if 1 /* JRM */ /* Try finding the addr from the index */ cmp = -1; lo = 0; - hi = num_entries; - while(lo < hi && cmp) { + hi = num_entries - 1; + target_page = addr / fs_page_size; + +#if 0 /* JRM */ + HDfprintf(stderr, "vfd swmr read target page/size = %lld/%lld\n", + (uint64_t)target_page, (uint64_t)size); + HDfprintf(stderr, "vfd swmr read index num_entries = %d\n", num_entries); +#endif /* JRM */ + + while(lo <= hi) { + my_idx = (lo + hi) / 2; - cmp = H5F_addr_cmp(index[my_idx].hdf5_page_offset * fs_page_size, addr); - if(cmp < 0) - hi = my_idx; - else + + if ( target_page < index[my_idx].hdf5_page_offset ) { + + hi = my_idx - 1; + + } else if ( index[my_idx].hdf5_page_offset < target_page ) { + lo = my_idx + 1; + + } else { + + HDassert(target_page == index[my_idx].hdf5_page_offset); + cmp = 0; + lo = hi + 1; /* to exit loop */ + } } /* end while */ +#if 0 /* JRM */ + if ( cmp == 0 ) { + + HDfprintf(stderr, "vfd swrm read found target page/idx %lld/%d.\n", + target_page, my_idx); + } else { + HDfprintf(stderr, + "vfd swrm read passing through page / size = %lld/%lld\n", + (uint64_t)target_page, (uint64_t)size); + } +#endif /* JRM */ +#else /* JRM */ + { + target_page = (addr / fs_page_size); + cmp = -1; + my_idx = 0; + + HDassert(target_page * fs_page_size <= addr); + HDassert(addr < (target_page + 1) * fs_page_size); + + while ( ( cmp == -1 ) && ( my_idx < num_entries ) ) { + + HDassert( ( my_idx == 0 ) || + ( index[my_idx-1].hdf5_page_offset < + index[my_idx].hdf5_page_offset ) ); + + if ( index[my_idx].hdf5_page_offset == (uint64_t)target_page ) { + + cmp = 0; + + } else { + + my_idx++; + } + } + } +#endif /* JRM */ + /* Found in index, read from the metadata file */ - if(cmp == 0) { - HDassert(size == index[my_idx].length); + if( (cmp == 0) && ( target_page != 0)) { + +#if 0 /* JRM */ + HDfprintf(stderr, "addr = %lld, page = %lld, len = %lld\n", + (int64_t)addr, (int64_t)(addr / fs_page_size), + (int64_t)size); + HDfprintf(stderr, + "reading index[%d] fo/mdfo/l/chksum/fc/lc = %lld/%lld/%ld/%llx\n", + my_idx, + index[my_idx].hdf5_page_offset, + index[my_idx].md_file_page_offset, + index[my_idx].length, + (uint64_t)(index[my_idx].chksum)); + + +#endif /* JRM */ + + HDassert(index[my_idx].hdf5_page_offset * fs_page_size <= addr); + HDassert(addr < (index[my_idx].hdf5_page_offset + 1) * fs_page_size); +#if 0 /* JRM */ + if ( size != index[my_idx].length ) { + + HDfprintf(stderr, "size = %lld, index[%d].length = %lld.\n", + (int64_t)size, my_idx, + (int64_t)(index[my_idx].length)); + } +#endif /* JRM */ + HDassert((size == 8) || + (size == index[my_idx].length)); do { - if(HDlseek(file->md_fd, (HDoff_t)index[my_idx].md_file_page_offset * fs_page_size, SEEK_SET) < 0) - HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "unable to seek in metadata file") + + if(HDlseek(file->md_fd, + (HDoff_t)index[my_idx].md_file_page_offset * fs_page_size, + SEEK_SET) < 0) + + HGOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, \ + "unable to seek in metadata file") + + read_ptr = buf; /* Coding borrowed from sec2 read */ while(size > 0) { - h5_posix_io_t bytes_in = 0; /* # of bytes to read */ - h5_posix_io_ret_t bytes_read = -1; /* # of bytes actually read */ + h5_posix_io_t bytes_in = 0; /* # of bytes to read */ + h5_posix_io_ret_t bytes_read = -1; /* # of bytes actually */ + /* read */ /* Trying to read more bytes than the return type can handle is * undefined behavior in POSIX. @@ -608,23 +780,49 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, bytes_in = (h5_posix_io_t)size; do { - bytes_read = HDread(file->md_fd, buf, bytes_in); + bytes_read = HDread(file->md_fd, read_ptr, bytes_in); } while(-1 == bytes_read && EINTR == errno); if(-1 == bytes_read) /* error */ - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "error reading the page/multi-page entry from the md file") + + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, \ + "error reading the page/multi-page entry from the md file") HDassert(bytes_read >= 0); HDassert((size_t)bytes_read <= size); size -= (size_t)bytes_read; addr += (haddr_t)bytes_read; - buf = (char *)buf + bytes_read; + read_ptr = (char *)read_ptr + bytes_read; + } /* end while size */ - /* Verify stored and computed checksums are equal */ - computed_chksum = H5_checksum_metadata(buf, index[my_idx].length, 0); - if(index[my_idx].chksum == computed_chksum) + /* Verify stored and computed checksums are equal */ +#if 0 /* JRM */ + computed_chksum = H5_checksum_metadata(buf, index[my_idx].length,0); +#else /* JRM */ + /* this is a hack to allow the library to find the superblock + * signature -- clean this up. + * JRM -- 1/14/19 + */ + if ( size != 8 ) { + computed_chksum = H5_checksum_metadata(buf, + index[my_idx].length,0); + } else { + computed_chksum = index[my_idx].chksum; + } +#endif /* JRM */ + +#if 0 /* JRM */ + HDfprintf(stderr, + "computed / actual chksum / fc / lc = 0x%llx/0x%llx/%x/%x\n", + (uint64_t)computed_chksum, + (uint64_t)(index[my_idx].chksum), + ((char *)(buf))[0], + ((char *)(buf))[4095]); +#endif /* JRM */ + + if(index[my_idx].chksum == computed_chksum) break; /* Double the sleep time next time */ @@ -635,11 +833,16 @@ H5FD_vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, /* Exhaust all retries for reading the page/multi-page entry */ if(entry_retries == 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTLOAD, FAIL, "error in reading the page/multi-page entry") - } else { /* Cannot find addr in index, read from the underlying hdf5 file */ + HGOTO_ERROR(H5E_VFL, H5E_CANTLOAD, FAIL, \ + "error in reading the page/multi-page entry") + + } else { /* Cannot find addr in index, read from the underlying hdf5 file */ + if(H5FD_read(file->hdf5_file_lf, type, addr, size, buf) < 0) - HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file read request failed") + + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, \ + "file read request failed") } done: @@ -672,6 +875,9 @@ H5FD_vfd_swmr_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id HDassert(file && file->pub.cls); HDassert(buf); + + /* This function should always fail. For now assert FALSE */ + HDassert(FALSE); /* SHOULDN'T come here ?? */ if(H5FD_write(file->hdf5_file_lf, type, addr, size, buf) < 0) @@ -693,13 +899,23 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5FD_vfd_swmr_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, hbool_t closing) +H5FD_vfd_swmr_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, + hbool_t closing) { - H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT + /* The VFD SWMR vfd should only be used by the VFD SWMR reader, + * and thus this file should only be opened R/O. + * + * Thus this function should never be called and should return error + * + * For now, just assert FALSE. + */ + HDassert(FALSE); + HDassert(file); if(H5FD_truncate(file->hdf5_file_lf, closing) < 0) @@ -722,7 +938,7 @@ done: static herr_t H5FD_vfd_swmr_lock(H5FD_t *_file, hbool_t rw) { - H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ + H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -730,7 +946,9 @@ H5FD_vfd_swmr_lock(H5FD_t *_file, hbool_t rw) HDassert(file); if(H5FD_lock(file->hdf5_file_lf, rw) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTLOCK, FAIL, "unable to lock the HDF5 file") + + HGOTO_ERROR(H5E_IO, H5E_CANTLOCK, FAIL, \ + "unable to lock the HDF5 file") done: FUNC_LEAVE_NOAPI(ret_value) @@ -749,20 +967,23 @@ done: static herr_t H5FD_vfd_swmr_unlock(H5FD_t *_file) { - H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT HDassert(file); if(H5FD_unlock(file->hdf5_file_lf) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTUNLOCK, FAIL, "unable to unlock the HDF5 file") + + HGOTO_ERROR(H5E_IO, H5E_CANTUNLOCK, FAIL, \ + "unable to unlock the HDF5 file") done: + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_vfd_swmr_unlock() */ +} /* end H5FD_vfd_swmr_unlock() */ /*------------------------------------------------------------------------- @@ -1059,6 +1280,13 @@ H5FD__vfd_swmr_header_deserialize(H5FD_t *_file, /* Sanity check */ HDassert((size_t)(p - (const uint8_t *)&image[0]) <= H5FD_MD_HEADER_SIZE); +#if 0 /* JRM */ + HDfprintf(stderr, + "---read header ps/tick/idx_off/idx_len = %d / %lld / %lld / %lld\n", + md_header->fs_page_size, md_header->tick_num, + md_header->index_offset, md_header->index_length); +#endif /* JRM */ + done: FUNC_LEAVE_NOAPI(ret_value) @@ -1201,6 +1429,13 @@ H5FD__vfd_swmr_index_deserialize(H5FD_t *_file, /* Sanity check */ HDassert((size_t)(p - image) <= md_header->index_length); +#if 0 /* JRM */ + HDfprintf(stderr, + " ---- read index tick/num_entries = %lld / %d \n", + md_index->tick_num, md_index->num_entries); +#endif /* JRM */ + + done: if(image) { @@ -1302,7 +1537,7 @@ done: hbool_t H5FD_is_vfd_swmr_driver(H5FD_t *_file) { - H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ + H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -1325,7 +1560,7 @@ H5FD_is_vfd_swmr_driver(H5FD_t *_file) H5FD_t * H5FD_vfd_swmr_get_underlying_vfd(H5FD_t *_file) { - H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ + H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ FUNC_ENTER_NOAPI_NOINIT_NOERR @@ -1333,3 +1568,56 @@ H5FD_vfd_swmr_get_underlying_vfd(H5FD_t *_file) FUNC_LEAVE_NOAPI(file->hdf5_file_lf) } /* H5FD_vfd_swmr_get_underlying_vfd() */ + + +/*------------------------------------------------------------------------- + * Function: H5FD_vfd_swmr_dump_status + * + * Purpose: Dump a variety of information about the vfd swmr reader + * vfd to stderr for debugging purposes. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + *------------------------------------------------------------------------- + */ +void +H5FD_vfd_swmr_dump_status(H5FD_t *_file, int64_t page) +{ + hbool_t in_index = FALSE; + int i = 0; + uint32_t num_entries; + H5FD_vfd_swmr_idx_entry_t *index; + H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(file); + + index = file->md_index.entries; + num_entries = file->md_index.num_entries; + + while ( ( ! in_index ) && ( i < (int)num_entries ) ) { + + if ( index[i].hdf5_page_offset == (uint64_t)page ) { + + in_index = TRUE; + } + + HDassert( ( i == 0 ) || + ( index[i-1].hdf5_page_offset < index[i].hdf5_page_offset ) ); + + i++; + } + + HDfprintf(stderr, + "fd: tick = %lld, index_len = %d, page %lld in index = %d.\n", + file->md_index.tick_num, num_entries, page, in_index); + + FUNC_LEAVE_NOAPI_VOID + +} /* H5FD_vfd_swmr_dump_status() */ + + + + diff --git a/src/H5Fint.c b/src/H5Fint.c index d56406e..45f84c0 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -124,6 +124,7 @@ static herr_t H5F__vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing); static herr_t H5F__vfd_swmr_update_end_of_tick_and_tick_num(H5F_t *f, hbool_t incr_tick_num); static herr_t H5F__vfd_swmr_construct_write_md_hdr(H5F_t *f, uint32_t num_entries); static herr_t H5F__vfd_swmr_construct_write_md_idx(H5F_t *f, uint32_t num_entries, struct H5FD_vfd_swmr_idx_entry_t index[]); +static herr_t H5F__vfd_swmr_writer__dump_index(H5F_t * f); static herr_t H5F__idx_entry_cmp(const void *_entry1, const void *_entry2); static herr_t H5F__vfd_swmr_writer__create_index(H5F_t * f); static herr_t H5F_vfd_swmr_writer__prep_for_flush_or_close(H5F_t *f); @@ -3730,14 +3731,33 @@ H5F__vfd_swmr_init(H5F_t *f, hbool_t file_create) vfd_swmr_writer_g = f->shared->vfd_swmr_writer = FALSE; + HDassert(f->shared->mdf_idx == NULL); + + /* allocate an index to save the initial index */ + if ( H5F__vfd_swmr_writer__create_index(f) < 0 ) + + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, \ + "unable to allocate metadata file index") + + /* Set tick_num_g to the current tick read from the metadata file */ + f->shared->mdf_idx_entries_used = f->shared->mdf_idx_len; if ( H5FD_vfd_swmr_get_tick_and_idx(f->shared->lf, FALSE, - &tick_num_g, NULL, NULL) < 0 ) + &tick_num_g, + &(f->shared->mdf_idx_entries_used), + f->shared->mdf_idx) < 0 ) HGOTO_ERROR(H5E_FILE, H5E_CANTLOAD, FAIL, \ "unable to load/decode metadata file") f->shared->tick_num = tick_num_g; + +#if 0 /* JRM */ + HDfprintf(stderr, + "##### initialized index: tick/used/len = %lld/%d/%d #####\n", + f->shared->tick_num, f->shared->mdf_idx_entries_used, + f->shared->mdf_idx_len); +#endif /* JRM */ } /* Update end_of_tick */ @@ -4335,6 +4355,22 @@ H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t num_entries, index[i].chksum = H5_checksum_metadata(index[i].entry_ptr, (size_t)(index[i].length), 0); +#if 0 /* JRM */ + HDfprintf(stderr, + "writing index[%d] fo/mdfo/l/chksum/fc/lc = %lld/%lld/%ld/%lx/%lx/%lx\n", + i, + index[i].hdf5_page_offset, + index[i].md_file_page_offset, + index[i].length, + index[i].chksum, + (((char*)(index[i].entry_ptr))[0]), + (((char*)(index[i].entry_ptr))[4095])); + + HDassert(md_addr == index[i].md_file_page_offset * + f->shared->fs_page_size); + HDassert(f->shared->fs_page_size == 4096); +#endif /* JRM */ + /* Seek and write the entry to the metadata file */ if ( HDlseek(f->shared->vfd_swmr_md_fd, (HDoff_t)md_addr, SEEK_SET) < 0) @@ -4495,7 +4531,7 @@ H5F_vfd_swmr_writer__delay_write(H5F_t *f, uint64_t page, HDassert(idx); - probe = top + bottom / 2; + probe = (top + bottom) / 2; if ( idx[probe].hdf5_page_offset < page ) { @@ -4758,6 +4794,39 @@ H5F_vfd_swmr_writer_end_of_tick(void) HDassert(FALSE); } +#if 1 + /* Test to see if b-tree corruption seen in VFD SWMR tests + * is caused by client hiding data from the metadata cache. Do + * this by calling H5D_flush_all(), which flushes any cached + * dataset storage. Eventually, we will do this regardless + * when the above flush_raw_data flag is set. + */ + + if ( H5D_flush_all(f) < 0 ) + + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "unable to flush dataset cache") + + + if(H5MF_free_aggrs(f) < 0) + + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") + + + if ( f->shared->cache ) { + + if ( H5AC_flush(f) < 0 ) + + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ + "Can't flush metadata cache to the page buffer") + } + + + + if ( H5FD_truncate(f->shared->lf, FALSE) < 0 ) + + HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed") +#endif /* 2) If it exists, flush the metadata cache to the page buffer. */ if ( f->shared->cache ) { @@ -4828,6 +4897,9 @@ H5F_vfd_swmr_writer_end_of_tick(void) HDassert(f->shared->mdf_idx_entries_used <= f->shared->mdf_idx_len); +#if 0 /* JRM */ + H5F__vfd_swmr_writer__dump_index(f); +#endif /* JRM */ /* 7) Release the page buffer tick list. */ if ( H5PB_vfd_swmr__release_tick_list(f) < 0 ) @@ -4851,7 +4923,11 @@ H5F_vfd_swmr_writer_end_of_tick(void) HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, \ "unable to update end of tick") } - +#if 0 /* JRM */ + HDfprintf(stderr, "*** writer EOT %lld exiting. idx len = %d ***\n", + f->shared->tick_num, + (int32_t)(f->shared->mdf_idx_entries_used)); +#endif /* JRM */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -4897,7 +4973,7 @@ H5F__vfd_swmr_writer__create_index(H5F_t * f) HDassert(f); HDassert(f->shared); - HDassert(f->shared->vfd_swmr_writer); + HDassert(f->shared->vfd_swmr); HDassert(f->shared->mdf_idx == NULL); HDassert(f->shared->mdf_idx_len == 0); HDassert(f->shared->mdf_idx_entries_used == 0); @@ -4944,6 +5020,60 @@ done: } /* end H5F__vfd_swmr_writer__create_index() */ + +/*------------------------------------------------------------------------- + * + * Function: H5F__vfd_swmr_writer__dump_index + * + * Purpose: Dump a summary of the metadata file index. + * + * Return: SUCCEED/FAIL + * + * Programmer: John Mainzer 12/14/19 + * + * Changes: None. + * + *------------------------------------------------------------------------- + */ +herr_t +H5F__vfd_swmr_writer__dump_index(H5F_t * f) +{ + int i; + int32_t mdf_idx_len; + int32_t mdf_idx_entries_used; + H5FD_vfd_swmr_idx_entry_t * index = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + f = vfd_swmr_file_g; + + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->vfd_swmr); + HDassert(f->shared->mdf_idx); + + + index = f->shared->mdf_idx; + mdf_idx_len = f->shared->mdf_idx_len; + mdf_idx_entries_used = f->shared->mdf_idx_entries_used; + + HDfprintf(stderr, "\n\nDumping Index:\n\n"); + HDfprintf(stderr, "index len / entries used = %d / %d\n\n", + mdf_idx_len, mdf_idx_entries_used); + + for ( i = 0; i < mdf_idx_entries_used; i++ ) { + + HDfprintf(stderr, "%d: %lld %lld %d\n", i, index[i].hdf5_page_offset, + index[i].md_file_page_offset, index[i].length); + } + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5F__vfd_swmr_writer__create_index() */ + /*------------------------------------------------------------------------- * Function: H5F_vfd_swmr_reader_end_of_tick * @@ -4990,6 +5120,9 @@ H5F_vfd_swmr_reader_end_of_tick(void) uint64_t tmp_tick_num = 0; H5F_t * f; H5FD_vfd_swmr_idx_entry_t * tmp_mdf_idx; + int32_t entries_added = 0; + int32_t entries_removed = 0; + int32_t entries_changed = 0; int32_t tmp_mdf_idx_len; int32_t tmp_mdf_idx_entries_used; uint32_t mdf_idx_entries_used; @@ -5006,7 +5139,11 @@ H5F_vfd_swmr_reader_end_of_tick(void) HDassert(f->shared->vfd_swmr); HDassert(!f->shared->vfd_swmr_writer); HDassert(f->shared->lf); - +#if 0 /* JRM */ + HDfprintf(stderr, "--- reader EOT entering ---\n"); + HDfprintf(stderr, "--- reader EOT init index used / len = %d / %d ---\n", + f->shared->mdf_idx_entries_used, f->shared->mdf_idx_len); +#endif /* JRM */ /* 1) Direct the VFD SWMR reader VFD to load the current header * from the metadata file, and report the current tick. * @@ -5019,6 +5156,11 @@ H5F_vfd_swmr_reader_end_of_tick(void) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, \ "error in retrieving tick_num from driver") +#if 0 /* JRM */ + HDfprintf(stderr, "--- reader EOT curr/new tick = %lld/%lld ---\n", + tick_num_g, tmp_tick_num); +#endif /* JRM */ + if ( tmp_tick_num != tick_num_g ) { /* swap the old and new metadata file indexes */ @@ -5036,13 +5178,20 @@ H5F_vfd_swmr_reader_end_of_tick(void) f->shared->mdf_idx_entries_used = tmp_mdf_idx_entries_used; /* if f->shared->mdf_idx is NULL, allocate an index */ - if ( H5F__vfd_swmr_writer__create_index(f) < 0 ) + if ( ( f->shared->mdf_idx == NULL ) && + ( H5F__vfd_swmr_writer__create_index(f) < 0 ) ) HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, \ "unable to allocate metadata file index") mdf_idx_entries_used = (uint32_t)(f->shared->mdf_idx_len); + +#if 0 /* JRM */ + HDfprintf(stderr, "--- reader EOT mdf_idx_entries_used = %d ---\n", + mdf_idx_entries_used); +#endif /* JRM */ + if ( H5FD_vfd_swmr_get_tick_and_idx(f->shared->lf, FALSE, NULL, &mdf_idx_entries_used, f->shared->mdf_idx) < 0 ) @@ -5050,9 +5199,15 @@ H5F_vfd_swmr_reader_end_of_tick(void) HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, \ "error in retrieving tick_num from driver") - HDassert(tmp_mdf_idx_entries_used <= f->shared->mdf_idx_len); + HDassert(mdf_idx_entries_used <= (uint32_t)(f->shared->mdf_idx_len)); + + f->shared->mdf_idx_entries_used = (int32_t)mdf_idx_entries_used; + +#if 0 /* JRM */ + HDfprintf(stderr, "--- reader EOT index used / len = %d/%d ---\n", + f->shared->mdf_idx_entries_used, f->shared->mdf_idx_len); +#endif /* JRM */ - f->shared->mdf_idx_entries_used = tmp_mdf_idx_entries_used; /* if an old metadata file index exists, compare it with the * new index and evict any modified, new, or deleted pages @@ -5094,6 +5249,8 @@ H5F_vfd_swmr_reader_end_of_tick(void) */ if ( pass == 0 ) { + entries_changed++; + page_addr = (haddr_t) (new_mdf_idx[j].hdf5_page_offset * f->shared->pb_ptr->page_size); @@ -5129,6 +5286,8 @@ H5F_vfd_swmr_reader_end_of_tick(void) */ if ( pass == 0 ) { + entries_removed++; + page_addr = (haddr_t)(old_mdf_idx[i].hdf5_page_offset * f->shared->pb_ptr->page_size); @@ -5154,6 +5313,10 @@ H5F_vfd_swmr_reader_end_of_tick(void) /* the page has been added to the index. No action * is required. */ + if ( pass == 0 ) { + + entries_added++; + } j++; } @@ -5182,6 +5345,8 @@ H5F_vfd_swmr_reader_end_of_tick(void) */ if ( pass == 0 ) { + entries_removed++; + page_addr = (haddr_t)(old_mdf_idx[i].hdf5_page_offset * f->shared->pb_ptr->page_size); @@ -5205,7 +5370,11 @@ H5F_vfd_swmr_reader_end_of_tick(void) pass++; } /* while ( pass <= 1 ) */ - +#if 0 /* JRM */ + HDfprintf(stderr, + "--- reader EOT pre new tick index used/len = %d/ %d ---\n", + f->shared->mdf_idx_entries_used, f->shared->mdf_idx_len); +#endif /* JRM */ /* At this point, we should have evicted or refreshed all stale * page buffer and metadata cache entries. * @@ -5222,6 +5391,16 @@ H5F_vfd_swmr_reader_end_of_tick(void) } /* if ( tmp_tick_num != tick_num_g ) */ +#if 0 /* JRM */ + HDfprintf(stderr, "--- reader EOT final index used / len = %d / %d ---\n", + f->shared->mdf_idx_entries_used, f->shared->mdf_idx_len); + HDfprintf(stderr, "--- reader EOT old index used / len = %d / %d ---\n", + f->shared->old_mdf_idx_entries_used, f->shared->old_mdf_idx_len); + HDfprintf(stderr, "--- reader EOT %lld exiting t/a/r/c = %d/%d/%d/%d---\n", + f->shared->tick_num, (int32_t)(f->shared->mdf_idx_entries_used), + entries_added, entries_removed, entries_changed); +#endif /* JRM */ + done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Ftest.c b/src/H5Ftest.c index 22e296f..46878ba 100644 --- a/src/H5Ftest.c +++ b/src/H5Ftest.c @@ -565,8 +565,14 @@ H5F__vfd_swmr_writer_md_test(hid_t file_id, unsigned num_entries, H5FD_vfd_swmr_ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "error updating the md file with the index") /* Verify the number of entries in the delayed list is as expected */ +#ifdef OUT if(f->shared->dl_len != num_dl_entries) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "incorrect # of entries in the delayed list") +#endif + if(f->shared->dl_len != num_dl_entries) + printf("DIFFERENT: f->shared->dl_len = %u, num_dl_entries=%u\n", f->shared->dl_len, num_dl_entries); + else + printf("SAME: f->shared->dl_len = %u, num_dl_entries=%u\n", f->shared->dl_len, num_dl_entries); /* Open the metadata file */ if((md_fd = HDopen(f->shared->vfd_swmr_config.md_file_path, O_RDONLY)) < 0) @@ -267,6 +267,10 @@ done: haddr_t H5MV_alloc(H5F_t *f, hsize_t size) { + haddr_t eoa; /* EOA for the file */ + hsize_t frag_size = 0; /* Fragment size */ + hsize_t misalign_size = 0; /* Mis-aligned size */ + H5MV_free_section_t *node = NULL; /* Free space section pointer */ haddr_t ret_value = HADDR_UNDEF; /* Return value */ FUNC_ENTER_NOAPI(HADDR_UNDEF) @@ -288,9 +292,42 @@ HDfprintf(stderr, "%s: size = %Hu\n", FUNC, size); /* If no space is found from the free-space manager or no free-space manager, extend md's EOF */ if(!H5F_addr_defined(ret_value)) { - if(HADDR_UNDEF == (ret_value = H5F__alloc_md(f, size))) + + /* Get the EOA for the metadata file */ + if(HADDR_UNDEF == (eoa = H5F_get_vfd_swmr_md_eoa(f))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "Unable to get eoa for VFD SWMR metadata file") + + /* If EOA is mis-aligned, calculate the fragment size */ + if(H5F_addr_gt(eoa, 0) && (misalign_size = eoa % f->shared->fs_page_size)) + frag_size = f->shared->fs_page_size - misalign_size; + + /* Allocate from end of file */ + if(HADDR_UNDEF == (ret_value = H5F__alloc_md(f, size + frag_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "allocation failed") + + /* If there is a mis-aligned fragment at EOA */ + if(frag_size) { + /* Start up the free-space manager if not so */ + if(f->shared->fs_man_md == NULL) { + if(H5MV__create(f) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space manager") + } + HDassert(f->shared->fs_man_md); + + /* Create the free-space section for the fragment */ + if(NULL == (node = H5MV__sect_new(eoa, frag_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't initialize free space section") + + /* Add the section */ + if(H5FS_sect_add(f, f->shared->fs_man_md, (H5FS_section_info_t *)node, H5FS_ADD_RETURNED_SPACE, f) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINSERT, FAIL, "can't re-add section to file free space") + + node = NULL; + } + ret_value += frag_size; + } /* end if */ + HDassert(H5F_addr_defined(ret_value)); done: @@ -377,7 +414,7 @@ HDfprintf(stderr, "%s: dropping addr = %a, size = %Hu, on the floor!\n", FUNC, a HDassert(f->shared->fs_man_md); #ifdef H5MV_VFD_SWMR_DEBUG -HDfprintf(stderr, "%s: Before H5FS_sect_add()\n", FUNC); +HDfprintf(stderr, "%s: Before H5FS_sect_add(): addr=%a, size=%Hu\n", FUNC, addr, size); #endif /* Add the section */ @@ -1700,7 +1700,7 @@ H5PB_vfd_swmr__update_index(H5F_t * f, while ( top >= bottom ) { - probe = top + bottom / 2; + probe = (top + bottom) / 2; if ( idx[probe].hdf5_page_offset < target_page ) { @@ -2560,12 +2560,12 @@ H5PB__load_page(H5F_t *f, H5PB_t *pb_ptr, haddr_t addr, H5FD_mem_t type, HGOTO_ERROR(H5E_PAGEBUF, H5E_CANTGET, FAIL, \ "driver get_eoa request failed") - +#if 0 /* JRM */ if ( addr + ((haddr_t)(pb_ptr->page_size)) > eoa ) HGOTO_ERROR(H5E_PAGEBUF, H5E_SYSTEM, FAIL, \ "Attempt to load page that extends past EOA") - +#endif /* JRM */ if ( HADDR_UNDEF == (eof = H5FD_get_eof(f->shared->lf, H5FD_MEM_DEFAULT)) ) HGOTO_ERROR(H5E_PAGEBUF, H5E_CANTGET, FAIL, \ @@ -2960,10 +2960,8 @@ H5PB__mark_entry_dirty(H5F_t * f, H5PB_t *pb_ptr, H5PB_entry_t *entry_ptr) } else { /* the entry should be a multi-page metadata entry that - * has been modified this tick. Thus it is only on the - * tick list, and no action is required. + * has been modified this tick. Thus no action is required. */ - HDassert(entry_ptr->modified_this_tick); HDassert(entry_ptr->is_mpmde); HDassert(pb_ptr->vfd_swmr_writer); } |