diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5B2cache.c | 76 | ||||
-rw-r--r-- | src/H5B2hdr.c | 4 | ||||
-rw-r--r-- | src/H5B2int.c | 10 | ||||
-rw-r--r-- | src/H5B2pkg.h | 2 |
4 files changed, 80 insertions, 12 deletions
diff --git a/src/H5B2cache.c b/src/H5B2cache.c index 96faa13..31277a7 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -345,34 +345,38 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, /* Metadata checksum */ UINT32ENCODE(p, metadata_chksum); - /* Write the B-tree header. */ + /* Write the B-tree header. */ HDassert((size_t)(p - buf) == hdr->hdr_size); - if(H5F_block_write(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk") + if(H5F_block_write(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk") - hdr->cache_info.is_dirty = FALSE; + hdr->cache_info.is_dirty = FALSE; - /* Clear shadowed node lists, as the header has been flushed and all - * nodes must be shadowed again (if doing SWMR writes). Note that this - * algorithm does one extra iteration at the end, as the last node's - * shadowed_next pointer points to itself. */ - while(hdr->shadowed_internal) { + /* Clear shadowed node lists, as the header has been flushed and all + * nodes must be shadowed again (if doing SWMR writes). Note that this + * algorithm does one extra iteration at the end, as the last node's + * shadowed_next pointer points to itself. */ + while(hdr->shadowed_internal) { H5B2_internal_t *next = hdr->shadowed_internal->shadowed_next; + HDassert(!hdr->shadowed_internal->cache_info.is_dirty); hdr->shadowed_internal->shadowed_next = NULL; + hdr->shadowed_internal->shadowed_prev = NULL; hdr->shadowed_internal = next; } /* end while */ while(hdr->shadowed_leaf) { H5B2_leaf_t *next = hdr->shadowed_leaf->shadowed_next; + HDassert(!hdr->shadowed_leaf->cache_info.is_dirty); hdr->shadowed_leaf->shadowed_next = NULL; + hdr->shadowed_leaf->shadowed_prev = NULL; hdr->shadowed_leaf = next; } /* end while */ } /* end if */ if(destroy) if(H5B2_cache_hdr_dest(f, hdr) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header") + HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header") done: /* Release resources */ @@ -599,6 +603,8 @@ H5B2_cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata) /* Share B-tree information */ internal->hdr = udata->hdr; internal->parent = udata->parent; + internal->shadowed_next = NULL; + internal->shadowed_prev = NULL; /* Read header from disk */ if(H5F_block_read(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0) @@ -808,6 +814,30 @@ H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal) /* If we're going to free the space on disk, the address must be valid */ HDassert(!internal->cache_info.free_file_space_on_destroy || H5F_addr_defined(internal->cache_info.addr)); + /* Unlink from shadowed list */ + if(internal->shadowed_next) { + if(internal->shadowed_next != internal) { + internal->shadowed_next->shadowed_prev = internal->shadowed_prev; + + if(internal->shadowed_prev) + internal->shadowed_prev->shadowed_next = internal->shadowed_next; + else { + HDassert(internal->hdr->shadowed_internal = internal); + + internal->hdr->shadowed_internal = internal->shadowed_next; + } /* end else */ + } /* end if */ + else { + if(internal->shadowed_prev) + internal->shadowed_prev->shadowed_next = internal->shadowed_prev; + else { + HDassert(internal->hdr->shadowed_internal = internal); + + internal->hdr->shadowed_internal = NULL; + } /* end else */ + } /* end else */ + } /* end if */ + /* Check for freeing file space for B-tree internal node */ if(internal->cache_info.free_file_space_on_destroy) { /* Release the space on disk */ @@ -997,6 +1027,8 @@ H5B2_cache_leaf_load(H5F_t UNUSED *f, hid_t dxpl_id, haddr_t addr, void *_udata) /* Share B-tree header information */ leaf->hdr = udata->hdr; leaf->parent = udata->parent; + leaf->shadowed_next = NULL; + leaf->shadowed_prev = NULL; /* Read header from disk */ if(H5F_block_read(udata->f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0) @@ -1172,6 +1204,30 @@ H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf) /* If we're going to free the space on disk, the address must be valid */ HDassert(!leaf->cache_info.free_file_space_on_destroy || H5F_addr_defined(leaf->cache_info.addr)); + /* Unlink from shadowed list */ + if(leaf->shadowed_next) { + if(leaf->shadowed_next != leaf) { + leaf->shadowed_next->shadowed_prev = leaf->shadowed_prev; + + if(leaf->shadowed_prev) + leaf->shadowed_prev->shadowed_next = leaf->shadowed_next; + else { + HDassert(leaf->hdr->shadowed_leaf = leaf); + + leaf->hdr->shadowed_leaf = leaf->shadowed_next; + } /* end else */ + } /* end if */ + else { + if(leaf->shadowed_prev) + leaf->shadowed_prev->shadowed_next = leaf->shadowed_prev; + else { + HDassert(leaf->hdr->shadowed_leaf = leaf); + + leaf->hdr->shadowed_leaf = NULL; + } /* end else */ + } /* end else */ + } /* end if */ + /* Check for freeing file space for B-tree leaf node */ if(leaf->cache_info.free_file_space_on_destroy) { /* Release the space on disk */ diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c index 54842ff..d0ea61b 100644 --- a/src/H5B2hdr.c +++ b/src/H5B2hdr.c @@ -214,6 +214,10 @@ HDmemset(hdr->page, 0, hdr->node_size); && (hdr->cls->id == H5B2_CDSET_ID || hdr->cls->id == H5B2_CDSET_FILT_ID); + /* Clear the shadowed list pointers */ + hdr->shadowed_leaf = NULL; + hdr->shadowed_internal = NULL; + /* Create the callback context, if the callback exists */ if(hdr->cls->crt_context) { if(NULL == (hdr->cb_ctx = (*hdr->cls->crt_context)(ctx_udata))) diff --git a/src/H5B2int.c b/src/H5B2int.c index 29d12e8..3d6ac14 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -4214,6 +4214,7 @@ H5B2_shadow_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, HDassert(internal); HDassert(*internal); HDassert(hdr->swmr_write); + HDassert((*internal)->hdr == hdr); /* We only need to shadow the node if it has not been shadowed since the * last time the header was flushed, as otherwise it will be unreachable by @@ -4254,8 +4255,10 @@ H5B2_shadow_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, node_protected = TRUE; /* Add node to shadowed node list */ - if(hdr->shadowed_internal) + if(hdr->shadowed_internal) { (*internal)->shadowed_next = hdr->shadowed_internal; + hdr->shadowed_internal->shadowed_prev = *internal; + } /* end if */ else (*internal)->shadowed_next = *internal; hdr->shadowed_internal = *internal; @@ -4307,6 +4310,7 @@ H5B2_shadow_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, HDassert(leaf); HDassert(*leaf); HDassert(hdr->swmr_write); + HDassert((*leaf)->hdr == hdr); /* We only need to shadow the node if it has not been shadowed since the * last time the header was flushed, as otherwise it will be unreachable by @@ -4347,8 +4351,10 @@ H5B2_shadow_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, node_protected = TRUE; /* Add node to shadowed node list */ - if(hdr->shadowed_leaf) + if(hdr->shadowed_leaf) { (*leaf)->shadowed_next = hdr->shadowed_leaf; + hdr->shadowed_leaf->shadowed_prev = *leaf; + } /* end if */ else (*leaf)->shadowed_next = *leaf; hdr->shadowed_leaf = *leaf; diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index 96ef54f..eb7d833 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -193,6 +193,7 @@ typedef struct H5B2_leaf_t { uint8_t *leaf_native; /* Pointer to native records */ uint16_t nrec; /* Number of records in node */ struct H5B2_leaf_t *shadowed_next; /* Next node in shadowed list */ + struct H5B2_leaf_t *shadowed_prev; /* Previous node in shadowed list */ } H5B2_leaf_t; /* B-tree internal node information */ @@ -208,6 +209,7 @@ typedef struct H5B2_internal_t { uint16_t nrec; /* Number of records in node */ uint16_t depth; /* Depth of this node in the B-tree */ struct H5B2_internal_t *shadowed_next; /* Next node in shadowed list */ + struct H5B2_internal_t *shadowed_prev; /* Previous node in shadowed list */ } H5B2_internal_t; /* v2 B-tree */ |