From f8388993411146f38ca0f4ce52ad94a5e1024ec9 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Fri, 10 May 2024 16:44:59 -0500 Subject: [PATCH] Properly clean up cache when failing to load an object header --- src/H5Gint.c | 11 +++++++++-- src/H5Oint.c | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/H5Gint.c b/src/H5Gint.c index 34072df90e6..85718fbf7d0 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -506,6 +506,7 @@ static herr_t H5G__open_oid(H5G_t *grp) { bool obj_opened = false; + htri_t msg_exists; herr_t ret_value = SUCCEED; FUNC_ENTER_PACKAGE @@ -523,8 +524,14 @@ H5G__open_oid(H5G_t *grp) obj_opened = true; /* Check if this object has the right message(s) to be treated as a group */ - if ((H5O_msg_exists(&(grp->oloc), H5O_STAB_ID) <= 0) && (H5O_msg_exists(&(grp->oloc), H5O_LINFO_ID) <= 0)) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "not a group"); + if ((msg_exists = H5O_msg_exists(&(grp->oloc), H5O_STAB_ID)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check if symbol table message exists"); + if (!msg_exists) { + if ((msg_exists = H5O_msg_exists(&(grp->oloc), H5O_LINFO_ID)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check if link info message exists"); + if (!msg_exists) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "not a group"); + } done: if (ret_value < 0) { diff --git a/src/H5Oint.c b/src/H5Oint.c index a98e22a1821..af65d1d8295 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -1113,7 +1113,8 @@ H5O_protect(const H5O_loc_t *loc, unsigned prot_flags, bool pin_all_chunks) if (cont_msg_info.msgs) cont_msg_info.msgs = (H5O_cont_t *)H5FL_SEQ_FREE(H5O_cont_t, cont_msg_info.msgs); - if (H5O_unprotect(loc, oh, H5AC__NO_FLAGS_SET) < 0) + /* Unprotect the ohdr and delete it from cache since if we failed to load it it's in an inconsistent state */ + if (H5O_unprotect(loc, oh, H5AC__DELETED_FLAG) < 0) HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, NULL, "unable to release object header"); } @@ -1234,10 +1235,21 @@ H5O_unprotect(const H5O_loc_t *loc, H5O_t *oh, unsigned oh_flags) } /* end if */ } /* end for */ - /* Reet the flag from the unprotect */ + /* Reset the flag from the unprotect */ oh->chunks_pinned = false; } /* end if */ + /* Remove the other chunks if we're removing the ohdr (due to a failure) */ + if (oh_flags & H5AC__DELETED_FLAG) { + unsigned u; /* Local index variable */ + + /* Iterate over chunks > 0 */ + for (u = 1; u < oh->nchunks; u++) + /* Expunge chunk proxy from cache */ + if (H5AC_expunge_entry(loc->file, H5AC_OHDR_CHK, oh->chunk[u].addr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPIN, FAIL, "unable to expunge object header chunk"); + } /* end if */ + /* Unprotect the object header */ if (H5AC_unprotect(loc->file, H5AC_OHDR, oh->chunk[0].addr, oh, oh_flags) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header");