diff options
Diffstat (limited to 'src/H5Oint.c')
-rw-r--r-- | src/H5Oint.c | 275 |
1 files changed, 204 insertions, 71 deletions
diff --git a/src/H5Oint.c b/src/H5Oint.c index 52290f2..d3a409c 100644 --- a/src/H5Oint.c +++ b/src/H5Oint.c @@ -83,7 +83,6 @@ static herr_t H5O__visit_cb(hid_t group, const char *name, const H5L_info_t *lin void *_udata); static const H5O_obj_class_t *H5O__obj_class_real(const H5O_t *oh); - /*********************/ /* Package Variables */ /*********************/ @@ -126,12 +125,7 @@ const H5O_msg_class_t *const H5O_msg_class_g[] = { H5O_MSG_REFCOUNT, /*0x0016 Object's ref. count */ H5O_MSG_FSINFO, /*0x0017 Free-space manager info */ H5O_MSG_MDCI, /*0x0018 Metadata cache image */ - H5O_MSG_UNKNOWN, /*0x0019 Placeholder for unknown message */ -#ifdef H5O_ENABLE_BOGUS - H5O_MSG_BOGUS_INVALID, /*0x001A "Bogus invalid" (for testing) */ -#else /* H5O_ENABLE_BOGUS */ - NULL, /*0x001A "Bogus invalid" (for testing) */ -#endif /* H5O_ENABLE_BOGUS */ + H5O_MSG_UNKNOWN /*0x0019 Placeholder for unknown message */ }; /* Format version bounds for object header */ @@ -277,99 +271,183 @@ done: * matzke@llnl.gov * Aug 5 1997 * + * Changes: 2018 August 17 + * Jacob Smith + * Refactor out the operations into two separate steps -- + * preparation and application -- to facilitate overriding the + * library-default size allocated for the object header. This + * function is retained as a wrapper, to minimize changes to + * unaffected calling functions. + * *------------------------------------------------------------------------- */ herr_t -H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, - H5O_loc_t *loc/*out*/) +H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, H5O_loc_t *loc /*out*/) { - H5P_genplist_t *oc_plist; /* Object creation property list */ - H5O_t *oh = NULL; /* Object header created */ - haddr_t oh_addr; /* Address of initial object header */ - size_t oh_size; /* Size of initial object header */ - uint8_t oh_flags; /* Object header's initial status flags */ - unsigned insert_flags = H5AC__NO_FLAGS_SET; /* Flags for inserting object header into cache */ - hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */ - herr_t ret_value = SUCCEED; /* return value */ + H5O_t *oh = NULL; + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) - /* check args */ HDassert(f); HDassert(loc); HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE)); + /* create object header in freelist + * header version is set internally + */ + oh = H5O__create_ohdr(f, ocpl_id); + if(NULL == oh) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "Can't instantiate object header") + + /* apply object header information to file + */ + if(H5O__apply_ohdr(f, oh, ocpl_id, size_hint, initial_rc, loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "Can't apply object header to file") + +done: + if((FAIL == ret_value) && (NULL != oh) && (H5O__free(oh) < 0)) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "can't delete object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_create() */ + + +/*----------------------------------------------------------------------------- + * Function: H5O__create_ohdr + * + * Purpose: Create the object header, set version and flags. + * + * Return: Success: Pointer to the newly-crated header object. + * Failure: NULL + * + * Programmer: Jacob Smith + * 2018 August 17 + * + *----------------------------------------------------------------------------- + */ +H5O_t * +H5O__create_ohdr(H5F_t *f, hid_t ocpl_id) +{ + H5P_genplist_t *oc_plist; + H5O_t *oh = NULL; /* Object header in Freelist */ + uint8_t oh_flags; /* Initial status flags */ + H5O_t *ret_value = NULL; + + FUNC_ENTER_NOAPI(NULL) + + HDassert(f); + HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE)); + /* Check for invalid access request */ if(0 == (H5F_INTENT(f) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "no write intent on file") + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL, "no write intent on file") - /* Make certain we allocate at least a reasonable size for the object header */ - size_hint = H5O_ALIGN_F(f, MAX(H5O_MIN_SIZE, size_hint)); + oh = H5FL_CALLOC(H5O_t); + if(NULL == oh) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* Get the property list */ - if(NULL == (oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list") + oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id); + if(NULL == oc_plist) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL, "not a property list") /* Get any object header status flags set by properties */ if(H5P_get(oc_plist, H5O_CRT_OHDR_FLAGS_NAME, &oh_flags) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get object header flags") - /* Allocate the object header and zero out header fields */ - if(NULL == (oh = H5FL_CALLOC(H5O_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + if(H5O_set_version(f, oh, oh_flags, H5F_STORE_MSG_CRT_IDX(f)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, NULL, "can't set version of object header") + + oh->flags = oh_flags; + + ret_value = oh; + +done: + if((NULL == ret_value) && (NULL != oh) && (H5O__free(oh) < 0)) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "can't delete object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O__create_ohdr() */ + + +/*----------------------------------------------------------------------------- + * Function: H5O__apply_ohdr + * + * Purpose: Initialize and set the object header in the file. + * Record some information at `loc_out`. + * + * Return: Success: SUCCEED (0) (non-negative value) + * Failure: FAIL (-1) (negative value) + * + * Programmer: Jacob Smith + * 2018 August 17 + * + *----------------------------------------------------------------------------- + */ +herr_t +H5O__apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id, size_t size_hint, size_t initial_rc, H5O_loc_t *loc_out) +{ + haddr_t oh_addr; + size_t oh_size; + H5P_genplist_t *oc_plist = NULL; + unsigned insert_flags = H5AC__NO_FLAGS_SET; + herr_t ret_value = SUCCEED; - /* Initialize file-specific information for object header */ - store_msg_crt_idx = H5F_STORE_MSG_CRT_IDX(f); + FUNC_ENTER_NOAPI(FAIL) - if(H5O_set_version(f, oh, oh_flags, store_msg_crt_idx) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set version of objecdt header") + HDassert(f); + HDassert(loc_out); + HDassert(oh); + HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE)); + + /* Allocate at least a reasonable size for the object header */ + size_hint = H5O_ALIGN_F(f, MAX(H5O_MIN_SIZE, size_hint)); oh->sizeof_size = H5F_SIZEOF_SIZE(f); oh->sizeof_addr = H5F_SIZEOF_ADDR(f); - oh->swmr_write = !!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE); + oh->swmr_write = !!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE); /* funky cast */ + #ifdef H5O_ENABLE_BAD_MESG_COUNT /* Check whether the "bad message count" property is set */ - if(H5P_exist_plist(oc_plist, H5O_BAD_MESG_COUNT_NAME) > 0) { - /* Retrieve bad message count flag */ + if(0 < H5P_exist_plist(oc_plist, H5O_BAD_MESG_COUNT_NAME)) + /* Get bad message count flag -- from property list */ if(H5P_get(oc_plist, H5O_BAD_MESG_COUNT_NAME, &oh->store_bad_mesg_count) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get bad message count flag") - } #endif /* H5O_ENABLE_BAD_MESG_COUNT */ /* Create object header proxy if doing SWMR writes */ if(oh->swmr_write) { - /* Create virtual entry, for use as proxy */ - if(NULL == (oh->proxy = H5AC_proxy_entry_create())) + oh->proxy = H5AC_proxy_entry_create(); + if(NULL == oh->proxy) HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create object header proxy") - } - else + } else { oh->proxy = NULL; + } - /* Set initial status flags */ - oh->flags = oh_flags; + oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id); + if(NULL == oc_plist) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list") /* Initialize version-specific fields */ if(oh->version > H5O_VERSION_1) { - /* Initialize all time fields with current time, if we are storing them */ + /* Initialize all time fields */ if(oh->flags & H5O_HDR_STORE_TIMES) oh->atime = oh->mtime = oh->ctime = oh->btime = H5_now(); else oh->atime = oh->mtime = oh->ctime = oh->btime = 0; - /* Make certain attribute creation order tracking is enabled if - * attributes can be shared in this file. - */ - if(store_msg_crt_idx) + if(H5F_STORE_MSG_CRT_IDX(f)) + /* flag to record message creation indices */ oh->flags |= H5O_HDR_ATTR_CRT_ORDER_TRACKED; - /* Retrieve attribute storage phase change values from property list */ + /* Get attribute storage phase change values -- from property list */ if(H5P_get(oc_plist, H5O_CRT_ATTR_MAX_COMPACT_NAME, &oh->max_compact) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get max. # of compact attributes") if(H5P_get(oc_plist, H5O_CRT_ATTR_MIN_DENSE_NAME, &oh->min_dense) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get min. # of dense attributes") /* Check for non-default attribute storage phase change values */ - if(oh->max_compact != H5O_CRT_ATTR_MAX_COMPACT_DEF || oh->min_dense != H5O_CRT_ATTR_MIN_DENSE_DEF) + if(H5O_CRT_ATTR_MAX_COMPACT_DEF != oh->max_compact || H5O_CRT_ATTR_MIN_DENSE_DEF != oh->min_dense ) oh->flags |= H5O_HDR_ATTR_STORE_PHASE_CHANGE; /* Determine correct value for chunk #0 size bits */ @@ -383,23 +461,25 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, oh->flags |= H5O_HDR_CHUNK0_4; else if(size_hint > 255) oh->flags |= H5O_HDR_CHUNK0_2; - } /* end if */ - else { + } else { /* Reset unused time fields */ oh->atime = oh->mtime = oh->ctime = oh->btime = 0; - } /* end else */ + } /* end if/else header version >1 */ /* Compute total size of initial object header */ /* (i.e. object header prefix and first chunk) */ oh_size = (size_t)H5O_SIZEOF_HDR(oh) + size_hint; /* Allocate disk space for header and first chunk */ - if(HADDR_UNDEF == (oh_addr = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)oh_size))) + oh_addr = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)oh_size); + if(HADDR_UNDEF == oh_addr) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header") /* Create the chunk list */ - oh->nchunks = oh->alloc_nchunks = 1; - if(NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks))) + oh->nchunks = 1; + oh->alloc_nchunks = 1; + oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks); + if(NULL == oh->chunk) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Initialize the first chunk */ @@ -409,25 +489,27 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, /* Allocate enough space for the first chunk */ /* (including space for serializing the object header prefix */ - if(NULL == (oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, oh_size))) + oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, oh_size); + if(NULL == oh->chunk[0].image) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") oh->chunk[0].chunk_proxy = NULL; /* Put magic # for object header in first chunk */ - if(oh->version > H5O_VERSION_1) + if(H5O_VERSION_1 < oh->version) HDmemcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); /* Create the message list */ oh->nmesgs = 1; oh->alloc_nmesgs = H5O_NMESGS; - if(NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh->alloc_nmesgs))) + oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh->alloc_nmesgs); + if(NULL == oh->mesg) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* Initialize the initial "null" message, covering the entire first chunk */ + /* Initialize the initial "null" message; covers the entire first chunk */ oh->mesg[0].type = H5O_MSG_NULL; oh->mesg[0].dirty = TRUE; oh->mesg[0].native = NULL; - oh->mesg[0].raw = oh->chunk[0].image + (H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)) + H5O_SIZEOF_MSGHDR_OH(oh); + oh->mesg[0].raw = oh->chunk[0].image + H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh) + H5O_SIZEOF_MSGHDR_OH(oh); oh->mesg[0].raw_size = size_hint - (size_t)H5O_SIZEOF_MSGHDR_OH(oh); oh->mesg[0].chunkno = 0; @@ -452,20 +534,15 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id, H5_END_TAG /* Set up object location */ - loc->file = f; - loc->addr = oh_addr; + loc_out->file = f; + loc_out->addr = oh_addr; - /* Open it */ - if(H5O_open(loc) < 0) + if(H5O_open(loc_out) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header") done: - if(ret_value < 0 && oh) - if(H5O__free(oh) < 0) - HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_create() */ + FUNC_LEAVE_NOAPI(ret_value); +} /* H5O__apply_ohdr() */ /*------------------------------------------------------------------------- @@ -1765,7 +1842,6 @@ H5O_get_loc(hid_t object_id) case H5I_FILE: case H5I_DATASPACE: case H5I_ATTR: - case H5I_REFERENCE: case H5I_VFL: case H5I_VOL: case H5I_GENPROP_CLS: @@ -2421,6 +2497,63 @@ H5O_get_oh_addr(const H5O_t *oh) /*------------------------------------------------------------------------- + * Function: H5O_get_oh_flags + * + * Programmer: Jacob Smith + * 2018 August 17 + * + *------------------------------------------------------------------------- + */ +uint8_t +H5O_get_oh_flags(const H5O_t *oh) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + HDassert(oh); + FUNC_LEAVE_NOAPI(oh->flags); /* flags can be 0 */ +} /* H5O_get_oh_flags() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_get_oh_mtime + * + * Purpose: Retrieve an object's modification time. Assumes that the + * caller has verified that accessing this variable is appropriate + * to the header in question. + * + * Programmer: Jacob Smith + * 2018 August 17 + * + *------------------------------------------------------------------------- + */ +time_t +H5O_get_oh_mtime(const H5O_t *oh) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + HDassert(oh); + HDassert(oh->mtime); + FUNC_LEAVE_NOAPI(oh->mtime); +} /* H5O_get_oh_mtime() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_get_oh_version + * + * Programmer: Jacob Smith + * 2018 August 17 + * + *------------------------------------------------------------------------- + */ +uint8_t +H5O_get_oh_version(const H5O_t *oh) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + HDassert(oh); + HDassert(oh->version); + FUNC_LEAVE_NOAPI(oh->version); +} /* H5O_get_oh_version() */ + + +/*------------------------------------------------------------------------- * Function: H5O_get_rc_and_type * * Purpose: Retrieve an object's reference count and type |