summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5B2cache.c76
-rw-r--r--src/H5B2hdr.c4
-rw-r--r--src/H5B2int.c10
-rw-r--r--src/H5B2pkg.h2
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 */