From 8ba788ca891f56792bbbbc5a40f9bc2e86a663b5 Mon Sep 17 00:00:00 2001 From: Vailin Choi Date: Fri, 9 Mar 2018 01:25:40 -0600 Subject: Fix for HDFFV-10209 VDS SWMR test failure Free the object header when there are chksum retries. --- src/H5Ocache.c | 39 ++++++++++++++++++++++++++++++++------- src/H5Oint.c | 1 + src/H5Opkg.h | 1 + 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 94049ef..2260e12 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -262,12 +262,23 @@ H5O__cache_verify_chksum(const void *_image, size_t len, void *_udata) uint32_t stored_chksum; /* Stored metadata checksum value */ uint32_t computed_chksum; /* Computed metadata checksum value */ - /* Get stored and computed checksums */ - H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); - - if(stored_chksum != computed_chksum) - ret_value = FALSE; + /* Get stored and computed checksums */ + H5F_get_checksums(image, len, &stored_chksum, &computed_chksum); + + if(stored_chksum != computed_chksum) { + /* These fields are not deserialized yet in H5O__prefix_deserialize() */ + HDassert(udata->oh->chunk == NULL); + HDassert(udata->oh->mesg == NULL); + HDassert(udata->oh->proxy == NULL); + + /* Indicate that udata->oh is to be freed later + in H5O__prefix_deserialize() */ + udata->free_oh = TRUE; + ret_value = FALSE; + } /* end if */ } /* end if */ + else + HDassert(!(udata->common.file_intent & H5F_ACC_SWMR_WRITE)); FUNC_LEAVE_NOAPI(ret_value) } /* end H5O__cache_verify_chksum() */ @@ -1263,8 +1274,22 @@ H5O__prefix_deserialize(const uint8_t *_image, H5O_cache_ud_t *udata) /* Verify object header prefix length */ HDassert((size_t)(image - _image) == (size_t)(H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh))); - /* Save the object header for later use in 'deserialize' callback */ - udata->oh = oh; + /* If udata->oh is to be freed (see H5O__cache_verify_chksum), + save the pointer to udata->oh and free it later after setting + udata->oh with the new object header */ + if(udata->free_oh) { + H5O_t *saved_oh = udata->oh; + HDassert(udata->oh); + + /* Save the object header for later use in 'deserialize' callback */ + udata->oh = oh; + if(H5O__free(saved_oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "can't destroy object header") + udata->free_oh = FALSE; + } else + /* Save the object header for later use in 'deserialize' callback */ + udata->oh = oh; + oh = NULL; done: diff --git a/src/H5Oint.c b/src/H5Oint.c index 08eb28d..2351779 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -875,6 +875,7 @@ H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, unsigned prot_flags, udata.v1_pfx_nmesgs = 0; udata.chunk0_size = 0; udata.oh = NULL; + udata.free_oh = FALSE; udata.common.f = loc->file; udata.common.dxpl_id = dxpl_id; udata.common.file_intent = file_intent; diff --git a/src/H5Opkg.h b/src/H5Opkg.h index e970406..9392fa8 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -379,6 +379,7 @@ typedef struct H5O_cache_ud_t { unsigned v1_pfx_nmesgs; /* Number of messages from v1 prefix header */ size_t chunk0_size; /* Size of serialized first chunk */ H5O_t *oh; /* Partially deserialized object header, for later use */ + hbool_t free_oh; /* Whether to free the object header or not */ H5O_common_cache_ud_t common; /* Common object header cache callback info */ } H5O_cache_ud_t; -- cgit v0.12