From b092dbcdfdfc7477596ae49f816f18e0dadf0fb1 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 28 Nov 2016 16:34:36 -0800 Subject: Bring over another batch (hopefully the last) of non-SWMR "normalization" changes from the revise_chunks branch. --- src/H5B2.c | 4 +- src/H5B2int.c | 2 +- src/H5B2pkg.h | 4 +- src/H5Dchunk.c | 1 - src/H5EA.c | 199 +++++++++++++++++++++++++++--------------------- src/H5EAcache.c | 19 ++++- src/H5F.c | 97 ++++++++++++++++++++++++ src/H5FA.c | 210 ++++++++++++++++++++++++++++----------------------- src/H5FAhdr.c | 2 + src/H5FDcore.c | 43 +++++++---- src/H5FDfamily.c | 47 ++++++------ src/H5FDlog.c | 50 ++++++------ src/H5FDsec2.c | 34 +++++---- src/H5FDstdio.c | 49 +++++++----- src/H5Fint.c | 103 +++++++++++++++---------- src/H5Zscaleoffset.c | 52 ------------- test/ohdr.c | 3 +- 17 files changed, 550 insertions(+), 369 deletions(-) diff --git a/src/H5B2.c b/src/H5B2.c index bce6a9f..af5fae7 100644 --- a/src/H5B2.c +++ b/src/H5B2.c @@ -343,11 +343,11 @@ H5B2_update(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op, void *op_ /* Attempt to insert record into B-tree */ if(hdr->depth > 0) { if(H5B2__update_internal(hdr, dxpl_id, hdr->depth, NULL, &hdr->root, &status, H5B2_POS_ROOT, udata, op, op_data) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to update record in B-tree internal node") + HGOTO_ERROR(H5E_BTREE, H5E_CANTUPDATE, FAIL, "unable to update record in B-tree internal node") } /* end if */ else { if(H5B2__update_leaf(hdr, dxpl_id, &hdr->root, &status, H5B2_POS_ROOT, udata, op, op_data) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to update record in B-tree leaf node") + HGOTO_ERROR(H5E_BTREE, H5E_CANTUPDATE, FAIL, "unable to update record in B-tree leaf node") } /* end else */ /* Sanity check */ diff --git a/src/H5B2int.c b/src/H5B2int.c index 3bd788c..a8fa59f 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -1925,7 +1925,7 @@ H5B2__update_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr if((hdr->cls->store)(H5B2_LEAF_NREC(leaf, hdr, idx), udata) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into leaf node") - /* Mark the node as dirty if it changed */ + /* Mark the node as dirty */ leaf_flags |= H5AC__DIRTIED_FLAG; /* Indicate that the record was inserted */ diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index edac296..6a385d4 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -261,8 +261,8 @@ typedef struct H5B2_leaf_cache_ud_t { #ifdef H5B2_TESTING /* Node information for testing */ typedef struct H5B2_node_info_test_t { - unsigned depth; /* Depth of node */ - unsigned nrec; /* Number of records in node */ + uint16_t depth; /* Depth of node */ + uint16_t nrec; /* Number of records in node */ } H5B2_node_info_test_t; #endif /* H5B2_TESTING */ diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index dde83fe..7637339 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -4851,7 +4851,6 @@ H5D__chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim) * will never change. */ chk_store.chunk.scaled = scaled; H5D_BUILD_IO_INFO_RD(&chk_io_info, dset, dxpl_cache, dxpl_id, H5AC_rawdata_dxpl_id, &chk_store, NULL); - chk_io_info.raw_dxpl_id = H5AC_rawdata_dxpl_id; /* Compose chunked index info struct */ idx_info.f = dset->oloc.file; diff --git a/src/H5EA.c b/src/H5EA.c index 8a4c5a1..9c3f3e7 100644 --- a/src/H5EA.c +++ b/src/H5EA.c @@ -78,6 +78,8 @@ static herr_t H5EA__lookup_elmt(const H5EA_t *ea, hid_t dxpl_id, hsize_t idx, hbool_t will_extend, unsigned thing_acc, void **thing, uint8_t **thing_elmt_buf, hsize_t *thing_elmt_idx, H5EA__unprotect_func_t *thing_unprot_func); +static H5EA_t *H5EA__new(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, + hbool_t from_open, void *ctx_udata); /*********************/ @@ -116,49 +118,45 @@ H5FL_BLK_DEFINE(ea_native_elmt); /*------------------------------------------------------------------------- - * Function: H5EA_create + * Function: H5EA__new * - * Purpose: Creates a new empty extensible array in the file. + * Purpose: Allocate and initialize a new extensible array wrapper in memory * - * Return: Pointer to earray wrapper on success + * Return: Pointer to earray wrapper success * NULL on failure * * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Jun 17 2008 + * koziol@lbl.gov + * Oct 10 2016 * *------------------------------------------------------------------------- */ -BEGIN_FUNC(PRIV, ERR, +BEGIN_FUNC(STATIC, ERR, H5EA_t *, NULL, NULL, -H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam, void *ctx_udata)) +H5EA__new(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, hbool_t from_open, void *ctx_udata)) /* Local variables */ H5EA_t *ea = NULL; /* Pointer to new extensible array */ H5EA_hdr_t *hdr = NULL; /* The extensible array header information */ - haddr_t ea_addr; /* Array header address */ /* * Check arguments. */ HDassert(f); - HDassert(cparam); - - /* H5EA interface sanity check */ - HDcompile_assert(H5EA_NUM_CLS_ID == NELMTS(H5EA_client_class_g)); - - /* Create extensible array header */ - if(HADDR_UNDEF == (ea_addr = H5EA__hdr_create(f, dxpl_id, cparam, ctx_udata))) - H5E_THROW(H5E_CANTINIT, "can't create extensible array header") + HDassert(H5F_addr_defined(ea_addr)); /* Allocate extensible array wrapper */ - if(NULL == (ea = H5FL_MALLOC(H5EA_t))) + if(NULL == (ea = H5FL_CALLOC(H5EA_t))) H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array info") /* Lock the array header into memory */ - if(NULL == (hdr = H5EA__hdr_protect(f, dxpl_id, ea_addr, ctx_udata, H5AC__NO_FLAGS_SET))) + if(NULL == (hdr = H5EA__hdr_protect(f, dxpl_id, ea_addr, ctx_udata, H5AC__READ_ONLY_FLAG))) H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header") + /* Check for pending array deletion */ + if(from_open && hdr->pending_delete) + H5E_THROW(H5E_CANTOPENOBJ, "can't open extensible array pending deletion") + /* Point extensible array wrapper at header and bump it's ref count */ ea->hdr = hdr; if(H5EA__hdr_incr(ea->hdr) < 0) @@ -182,6 +180,57 @@ CATCH if(ea && H5EA_close(ea, dxpl_id) < 0) H5E_THROW(H5E_CLOSEERROR, "unable to close extensible array") +END_FUNC(STATIC) /* end H5EA__new() */ + + +/*------------------------------------------------------------------------- + * Function: H5EA_create + * + * Purpose: Creates a new empty extensible array in the file. + * + * Return: Pointer to earray wrapper on success + * NULL on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jun 17 2008 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +H5EA_t *, NULL, NULL, +H5EA_create(H5F_t *f, hid_t dxpl_id, const H5EA_create_t *cparam, void *ctx_udata)) + + /* Local variables */ + H5EA_t *ea = NULL; /* Pointer to new extensible array */ + haddr_t ea_addr; /* Array header address */ + + /* + * Check arguments. + */ + HDassert(f); + HDassert(cparam); + + /* H5EA interface sanity check */ + HDcompile_assert(H5EA_NUM_CLS_ID == NELMTS(H5EA_client_class_g)); + + /* Create extensible array header */ + if(HADDR_UNDEF == (ea_addr = H5EA__hdr_create(f, dxpl_id, cparam, ctx_udata))) + H5E_THROW(H5E_CANTINIT, "can't create extensible array header") + + /* Allocate and initialize new extensible array wrapper */ + if(NULL == (ea = H5EA__new(f, dxpl_id, ea_addr, FALSE, ctx_udata))) + H5E_THROW(H5E_CANTINIT, "allocation and/or initialization failed for extensible array wrapper") + + /* Set the return value */ + ret_value = ea; + +CATCH + + if(!ret_value) + if(ea && H5EA_close(ea, dxpl_id) < 0) + H5E_THROW(H5E_CLOSEERROR, "unable to close extensible array") + END_FUNC(PRIV) /* end H5EA_create() */ @@ -205,7 +254,6 @@ H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata)) /* Local variables */ H5EA_t *ea = NULL; /* Pointer to new extensible array wrapper */ - H5EA_hdr_t *hdr = NULL; /* The extensible array header information */ /* * Check arguments. @@ -213,37 +261,15 @@ H5EA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, void *ctx_udata)) HDassert(f); HDassert(H5F_addr_defined(ea_addr)); - /* Load the array header into memory */ - if(NULL == (hdr = H5EA__hdr_protect(f, dxpl_id, ea_addr, ctx_udata, H5AC__READ_ONLY_FLAG))) - H5E_THROW(H5E_CANTPROTECT, "unable to load extensible array header, address = %llu", (unsigned long long)ea_addr) - - /* Check for pending array deletion */ - if(hdr->pending_delete) - H5E_THROW(H5E_CANTOPENOBJ, "can't open extensible array pending deletion") - - /* Create fractal heap info */ - if(NULL == (ea = H5FL_MALLOC(H5EA_t))) - H5E_THROW(H5E_CANTALLOC, "memory allocation failed for extensible array info") - - /* Point extensible array wrapper at header */ - ea->hdr = hdr; - if(H5EA__hdr_incr(ea->hdr) < 0) - H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") - - /* Increment # of files using this array header */ - if(H5EA__hdr_fuse_incr(ea->hdr) < 0) - H5E_THROW(H5E_CANTINC, "can't increment file reference count on shared array header") - - /* Set file pointer for this array open context */ - ea->f = f; + /* Allocate and initialize new extensible array wrapper */ + if(NULL == (ea = H5EA__new(f, dxpl_id, ea_addr, TRUE, ctx_udata))) + H5E_THROW(H5E_CANTINIT, "allocation and/or initialization failed for extensible array wrapper") /* Set the return value */ ret_value = ea; CATCH - if(hdr && H5EA__hdr_unprotect(hdr, dxpl_id, H5AC__NO_FLAGS_SET) < 0) - H5E_THROW(H5E_CANTUNPROTECT, "unable to release extensible array header") if(!ret_value) if(ea && H5EA_close(ea, dxpl_id) < 0) H5E_THROW(H5E_CLOSEERROR, "unable to close extensible array") @@ -818,26 +844,28 @@ H5EA_close(H5EA_t *ea, hid_t dxpl_id)) */ HDassert(ea); - /* Decrement file reference & check if this is the last open extensible array using the shared array header */ - if(0 == H5EA__hdr_fuse_decr(ea->hdr)) { - /* Set the shared array header's file context for this operation */ - ea->hdr->f = ea->f; - - /* Shut down anything that can't be put in the header's 'flush' callback */ - - /* Check for pending array deletion */ - if(ea->hdr->pending_delete) { - /* Set local info, so array deletion can occur after decrementing the - * header's ref count - */ - pending_delete = TRUE; - ea_addr = ea->hdr->addr; + /* Close the header, if it was set */ + if(ea->hdr) { + /* Decrement file reference & check if this is the last open extensible array using the shared array header */ + if(0 == H5EA__hdr_fuse_decr(ea->hdr)) { + /* Set the shared array header's file context for this operation */ + ea->hdr->f = ea->f; + + /* Shut down anything that can't be put in the header's 'flush' callback */ + + /* Check for pending array deletion */ + if(ea->hdr->pending_delete) { + /* Set local info, so array deletion can occur after decrementing the + * header's ref count + */ + pending_delete = TRUE; + ea_addr = ea->hdr->addr; + } /* end if */ } /* end if */ - } /* end if */ - /* Check for pending array deletion */ - if(pending_delete) { - H5EA_hdr_t *hdr; /* Another pointer to extensible array header */ + /* Check for pending array deletion */ + if(pending_delete) { + H5EA_hdr_t *hdr; /* Another pointer to extensible array header */ #ifndef NDEBUG { @@ -854,33 +882,34 @@ H5EA_close(H5EA_t *ea, hid_t dxpl_id)) } #endif /* NDEBUG */ - /* Lock the array header into memory */ - /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */ - if(NULL == (hdr = H5EA__hdr_protect(ea->f, dxpl_id, ea_addr, NULL, H5AC__NO_FLAGS_SET))) - H5E_THROW(H5E_CANTLOAD, "unable to load extensible array header") + /* Lock the array header into memory */ + /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */ + if(NULL == (hdr = H5EA__hdr_protect(ea->f, dxpl_id, ea_addr, NULL, H5AC__NO_FLAGS_SET))) + H5E_THROW(H5E_CANTLOAD, "unable to load extensible array header") - /* Set the shared array header's file context for this operation */ - hdr->f = ea->f; + /* Set the shared array header's file context for this operation */ + hdr->f = ea->f; - /* Decrement the reference count on the array header */ - /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted - * immediately -QAK) - */ - if(H5EA__hdr_decr(ea->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + /* Decrement the reference count on the array header */ + /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5EA__hdr_decr(ea->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") - /* Delete array, starting with header (unprotects header) */ - if(H5EA__hdr_delete(hdr, dxpl_id) < 0) - H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array") + /* Delete array, starting with header (unprotects header) */ + if(H5EA__hdr_delete(hdr, dxpl_id) < 0) + H5E_THROW(H5E_CANTDELETE, "unable to delete extensible array") + } /* end if */ + else { + /* Decrement the reference count on the array header */ + /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5EA__hdr_decr(ea->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + } /* end else */ } /* end if */ - else { - /* Decrement the reference count on the array header */ - /* (don't put in H5EA_hdr_fuse_decr() as the array header may be evicted - * immediately -QAK) - */ - if(H5EA__hdr_decr(ea->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") - } /* end else */ /* Release the extensible array wrapper */ ea = (H5EA_t *)H5FL_FREE(H5EA_t, ea); diff --git a/src/H5EAcache.c b/src/H5EAcache.c index 4210b07..b7846e9 100644 --- a/src/H5EAcache.c +++ b/src/H5EAcache.c @@ -893,7 +893,11 @@ H5EA__cache_iblock_notify(H5AC_notify_action_t action, void *_thing)) break; default: +#ifdef NDEBUG H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache") +#else /* NDEBUG */ + HDassert(0 && "Unknown action?!?"); +#endif /* NDEBUG */ } /* end switch */ CATCH @@ -955,7 +959,6 @@ H5EA__cache_sblock_get_initial_load_size(void *_udata, size_t *image_len)) /* Check arguments */ HDassert(udata); HDassert(udata->hdr); - HDassert(udata->parent); HDassert(udata->sblk_idx > 0); HDassert(H5F_addr_defined(udata->sblk_addr)); HDassert(image_len); @@ -1293,7 +1296,11 @@ H5EA__cache_sblock_notify(H5AC_notify_action_t action, void *_thing)) break; default: +#ifdef NDEBUG H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache") +#else /* NDEBUG */ + HDassert(0 && "Unknown action?!?"); +#endif /* NDEBUG */ } /* end switch */ CATCH @@ -1355,7 +1362,6 @@ H5EA__cache_dblock_get_initial_load_size(void *_udata, size_t *image_len)) /* Check arguments */ HDassert(udata); HDassert(udata->hdr); - HDassert(udata->parent); HDassert(udata->nelmts > 0); HDassert(image_len); @@ -1694,7 +1700,11 @@ H5EA__cache_dblock_notify(H5AC_notify_action_t action, void *_thing)) break; default: +#ifdef NDEBUG H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache") +#else /* NDEBUG */ + HDassert(0 && "Unknown action?!?"); +#endif /* NDEBUG */ } /* end switch */ CATCH @@ -1802,7 +1812,6 @@ H5EA__cache_dblk_page_get_initial_load_size(void *_udata, size_t *image_len)) /* Check arguments */ HDassert(udata); HDassert(udata->hdr); - HDassert(udata->parent); HDassert(image_len); /* Set the image length size */ @@ -2063,7 +2072,11 @@ H5EA__cache_dblk_page_notify(H5AC_notify_action_t action, void *_thing)) break; default: +#ifdef NDEBUG H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache") +#else /* NDEBUG */ + HDassert(0 && "Unknown action?!?"); +#endif /* NDEBUG */ } /* end switch */ CATCH diff --git a/src/H5F.c b/src/H5F.c index c70f813..d2d002a 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -1367,6 +1367,103 @@ done: /*------------------------------------------------------------------------- + * Function: H5Fget_metadata_read_retry_info + * + * Purpose: To retrieve the collection of read retries for metadata items with checksum. + * + * Return: Success: non-negative on success + * Failure: Negative + * + * Programmer: Vailin Choi; October 2013 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info) +{ + H5F_t *file; /* File object for file ID */ + unsigned i, j; /* Local index variable */ + size_t tot_size; /* Size of each retries[i] */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*x", file_id, info); + + /* Check args */ + if(!info) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct") + + /* Get the file pointer */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + + /* Copy the # of bins for "retries" array */ + info->nbins = file->shared->retries_nbins; + + /* Initialize the array of "retries" */ + HDmemset(info->retries, 0, sizeof(info->retries)); + + /* Return if there are no bins -- no retries */ + if(!info->nbins) + HGOTO_DONE(SUCCEED); + + /* Calculate size for each retries[i] */ + tot_size = info->nbins * sizeof(uint32_t); + + /* Map and copy information to info's retries for metadata items with tracking for read retries */ + j = 0; + for(i = 0; i < H5AC_NTYPES; i++) { + switch(i) { + case H5AC_OHDR_ID: + case H5AC_OHDR_CHK_ID: + case H5AC_BT2_HDR_ID: + case H5AC_BT2_INT_ID: + case H5AC_BT2_LEAF_ID: + case H5AC_FHEAP_HDR_ID: + case H5AC_FHEAP_DBLOCK_ID: + case H5AC_FHEAP_IBLOCK_ID: + case H5AC_FSPACE_HDR_ID: + case H5AC_FSPACE_SINFO_ID: + case H5AC_SOHM_TABLE_ID: + case H5AC_SOHM_LIST_ID: + case H5AC_EARRAY_HDR_ID: + case H5AC_EARRAY_IBLOCK_ID: + case H5AC_EARRAY_SBLOCK_ID: + case H5AC_EARRAY_DBLOCK_ID: + case H5AC_EARRAY_DBLK_PAGE_ID: + case H5AC_FARRAY_HDR_ID: + case H5AC_FARRAY_DBLOCK_ID: + case H5AC_FARRAY_DBLK_PAGE_ID: + case H5AC_SUPERBLOCK_ID: + HDassert(j < H5F_NUM_METADATA_READ_RETRY_TYPES); + if(file->shared->retries[i] != NULL) { + /* Allocate memory for retries[i] + * + * This memory should be released by the user with + * the H5free_memory() call. + */ + if(NULL == (info->retries[j] = (uint32_t *)H5MM_malloc(tot_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Copy the information */ + HDmemcpy(info->retries[j], file->shared->retries[i], tot_size); + } /* end if */ + + /* Increment location in info->retries[] array */ + j++; + break; + + default: + break; + } /* end switch */ + } /* end for */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_metadata_read_retry_info() */ + + +/*------------------------------------------------------------------------- * Function: H5Fget_free_sections * * Purpose: To get free-space section information for free-space manager with diff --git a/src/H5FA.c b/src/H5FA.c index 4435af0..c6c2e1b 100644 --- a/src/H5FA.c +++ b/src/H5FA.c @@ -64,6 +64,8 @@ /********************/ /* Local Prototypes */ /********************/ +static H5FA_t *H5FA__new(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, + hbool_t from_open, void *ctx_udata); /*********************/ @@ -103,51 +105,44 @@ H5FL_BLK_DEFINE(fa_native_elmt); /*------------------------------------------------------------------------- - * Function: H5FA_create + * Function: H5FA__new * - * Purpose: Creates a new fixed array (header) in the file. + * Purpose: Allocate and initialize a new fixe array wrapper in memory * - * Return: Pointer to fixed array wrapper on success + * Return: Pointer to farray wrapper success * NULL on failure * - * Programmer: Vailin Choi - * Thursday, April 30, 2009 + * Programmer: Quincey Koziol + * koziol@lbl.gov + * Oct 17 2016 * *------------------------------------------------------------------------- */ -BEGIN_FUNC(PRIV, ERR, +BEGIN_FUNC(STATIC, ERR, H5FA_t *, NULL, NULL, -H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata)) +H5FA__new(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, hbool_t from_open, void *ctx_udata)) /* Local variables */ H5FA_t *fa = NULL; /* Pointer to new fixed array */ H5FA_hdr_t *hdr = NULL; /* The fixed array header information */ - haddr_t fa_addr; /* Fixed Array header address */ - -#ifdef H5FA_DEBUG -HDfprintf(stderr, "%s: Called\n", FUNC); -#endif /* H5FA_DEBUG */ /* * Check arguments. */ HDassert(f); - HDassert(cparam); - - /* H5FA interface sanity check */ - HDcompile_assert(H5FA_NUM_CLS_ID == NELMTS(H5FA_client_class_g)); - - /* Create fixed array header */ - if(HADDR_UNDEF == (fa_addr = H5FA__hdr_create(f, dxpl_id, cparam, ctx_udata))) - H5E_THROW(H5E_CANTINIT, "can't create fixed array header") + HDassert(H5F_addr_defined(fa_addr)); /* Allocate fixed array wrapper */ - if(NULL == (fa = H5FL_MALLOC(H5FA_t))) - H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info") + if(NULL == (fa = H5FL_CALLOC(H5FA_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info") /* Lock the array header into memory */ - if(NULL == (hdr = H5FA__hdr_protect(f, dxpl_id, fa_addr, ctx_udata, H5AC__NO_FLAGS_SET))) - H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header") + if(NULL == (hdr = H5FA__hdr_protect(f, dxpl_id, fa_addr, ctx_udata, H5AC__READ_ONLY_FLAG))) + H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header") + + /* Check for pending array deletion */ + if(from_open && hdr->pending_delete) + H5E_THROW(H5E_CANTOPENOBJ, "can't open fixed array pending deletion") /* Point fixed array wrapper at header and bump it's ref count */ fa->hdr = hdr; @@ -172,6 +167,56 @@ CATCH if(fa && H5FA_close(fa, dxpl_id) < 0) H5E_THROW(H5E_CLOSEERROR, "unable to close fixed array") +END_FUNC(STATIC) /* end H5FA__new() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_create + * + * Purpose: Creates a new fixed array (header) in the file. + * + * Return: Pointer to fixed array wrapper on success + * NULL on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +H5FA_t *, NULL, NULL, +H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata)) + + /* Local variables */ + H5FA_t *fa = NULL; /* Pointer to new fixed array */ + haddr_t fa_addr; /* Fixed array header address */ + + /* + * Check arguments. + */ + HDassert(f); + HDassert(cparam); + + /* H5FA interface sanity check */ + HDcompile_assert(H5FA_NUM_CLS_ID == NELMTS(H5FA_client_class_g)); + + /* Create fixed array header */ + if(HADDR_UNDEF == (fa_addr = H5FA__hdr_create(f, dxpl_id, cparam, ctx_udata))) + H5E_THROW(H5E_CANTINIT, "can't create fixed array header") + + /* Allocate and initialize new fixed array wrapper */ + if(NULL == (fa = H5FA__new(f, dxpl_id, fa_addr, FALSE, ctx_udata))) + H5E_THROW(H5E_CANTINIT, "allocation and/or initialization failed for fixed array wrapper") + + /* Set the return value */ + ret_value = fa; + +CATCH + + if(!ret_value) + if(fa && H5FA_close(fa, dxpl_id) < 0) + H5E_THROW(H5E_CLOSEERROR, "unable to close fixed array") + END_FUNC(PRIV) /* end H5FA_create() */ @@ -194,7 +239,6 @@ H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata)) /* Local variables */ H5FA_t *fa = NULL; /* Pointer to new fixed array wrapper */ - H5FA_hdr_t *hdr = NULL; /* The fixed array header information */ /* * Check arguments. @@ -202,40 +246,15 @@ H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, void *ctx_udata)) HDassert(f); HDassert(H5F_addr_defined(fa_addr)); - /* Load the array header into memory */ -#ifdef H5FA_DEBUG -HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr); -#endif /* H5FA_DEBUG */ - if(NULL == (hdr = H5FA__hdr_protect(f, dxpl_id, fa_addr, ctx_udata, H5AC__READ_ONLY_FLAG))) - H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header, address = %llu", (unsigned long long)fa_addr) - - /* Check for pending array deletion */ - if(hdr->pending_delete) - H5E_THROW(H5E_CANTOPENOBJ, "can't open fixed array pending deletion") - - /* Create fixed array info */ - if(NULL == (fa = H5FL_MALLOC(H5FA_t))) - H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info") - - /* Point fixed array wrapper at header */ - fa->hdr = hdr; - if(H5FA__hdr_incr(fa->hdr) < 0) - H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") - - /* Increment # of files using this array header */ - if(H5FA__hdr_fuse_incr(fa->hdr) < 0) - H5E_THROW(H5E_CANTINC, "can't increment file reference count on shared array header") - - /* Set file pointer for this array open context */ - fa->f = f; + /* Allocate and initialize new fixed array wrapper */ + if(NULL == (fa = H5FA__new(f, dxpl_id, fa_addr, TRUE, ctx_udata))) + H5E_THROW(H5E_CANTINIT, "allocation and/or initialization failed for fixed array wrapper") /* Set the return value */ ret_value = fa; CATCH - if(hdr && H5FA__hdr_unprotect(hdr, dxpl_id, H5AC__NO_FLAGS_SET) < 0) - H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header") if(!ret_value) if(fa && H5FA_close(fa, dxpl_id) < 0) H5E_THROW(H5E_CLOSEERROR, "unable to close fixed array") @@ -534,26 +553,28 @@ H5FA_close(H5FA_t *fa, hid_t dxpl_id)) */ HDassert(fa); - /* Decrement file reference & check if this is the last open fixed array using the shared array header */ - if(0 == H5FA__hdr_fuse_decr(fa->hdr)) { - /* Set the shared array header's file context for this operation */ - fa->hdr->f = fa->f; - - /* Shut down anything that can't be put in the header's 'flush' callback */ - - /* Check for pending array deletion */ - if(fa->hdr->pending_delete) { - /* Set local info, so array deletion can occur after decrementing the - * header's ref count - */ - pending_delete = TRUE; - fa_addr = fa->hdr->addr; + /* Close the header, if it was set */ + if(fa->hdr) { + /* Decrement file reference & check if this is the last open fixed array using the shared array header */ + if(0 == H5FA__hdr_fuse_decr(fa->hdr)) { + /* Set the shared array header's file context for this operation */ + fa->hdr->f = fa->f; + + /* Shut down anything that can't be put in the header's 'flush' callback */ + + /* Check for pending array deletion */ + if(fa->hdr->pending_delete) { + /* Set local info, so array deletion can occur after decrementing the + * header's ref count + */ + pending_delete = TRUE; + fa_addr = fa->hdr->addr; + } /* end if */ } /* end if */ - } /* end if */ - /* Check for pending array deletion */ - if(pending_delete) { - H5FA_hdr_t *hdr; /* Another pointer to fixed array header */ + /* Check for pending array deletion */ + if(pending_delete) { + H5FA_hdr_t *hdr; /* Another pointer to fixed array header */ #ifndef NDEBUG { @@ -570,33 +591,34 @@ H5FA_close(H5FA_t *fa, hid_t dxpl_id)) } #endif /* NDEBUG */ - /* Lock the array header into memory */ - /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */ - if(NULL == (hdr = H5FA__hdr_protect(fa->f, dxpl_id, fa_addr, NULL, H5AC__NO_FLAGS_SET))) - H5E_THROW(H5E_CANTLOAD, "unable to load fixed array header") + /* Lock the array header into memory */ + /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */ + if(NULL == (hdr = H5FA__hdr_protect(fa->f, dxpl_id, fa_addr, NULL, H5AC__NO_FLAGS_SET))) + H5E_THROW(H5E_CANTLOAD, "unable to load fixed array header") - /* Set the shared array header's file context for this operation */ - hdr->f = fa->f; + /* Set the shared array header's file context for this operation */ + hdr->f = fa->f; - /* Decrement the reference count on the array header */ - /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted - * immediately -QAK) - */ - if(H5FA__hdr_decr(fa->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + /* Decrement the reference count on the array header */ + /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5FA__hdr_decr(fa->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") - /* Delete array, starting with header (unprotects header) */ - if(H5FA__hdr_delete(hdr, dxpl_id) < 0) - H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array") + /* Delete array, starting with header (unprotects header) */ + if(H5FA__hdr_delete(hdr, dxpl_id) < 0) + H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array") + } /* end if */ + else { + /* Decrement the reference count on the array header */ + /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5FA__hdr_decr(fa->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + } /* end else */ } /* end if */ - else { - /* Decrement the reference count on the array header */ - /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted - * immediately -QAK) - */ - if(H5FA__hdr_decr(fa->hdr) < 0) - H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") - } /* end else */ /* Release the fixed array wrapper */ fa = H5FL_FREE(H5FA_t, fa); diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c index d844f06..d6e32dc 100644 --- a/src/H5FAhdr.c +++ b/src/H5FAhdr.c @@ -119,6 +119,7 @@ H5FA__hdr_alloc(H5F_t *f)) ret_value = hdr; CATCH + if(!ret_value) if(hdr && H5FA__hdr_dest(hdr) < 0) H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header") @@ -225,6 +226,7 @@ H5FA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, ret_value = hdr->addr; CATCH + if(!H5F_addr_defined(ret_value)) if(hdr) { /* Release header's disk space */ diff --git a/src/H5FDcore.c b/src/H5FDcore.c index f29e231..9090679 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -1479,23 +1479,31 @@ done: static herr_t H5FD_core_lock(H5FD_t *_file, hbool_t rw) { - H5FD_core_t *file = (H5FD_core_t*)_file; /* VFD file struct */ - int lock; /* The type of lock */ - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_core_t *file = (H5FD_core_t*)_file; /* VFD file struct */ + int lock_flags; /* file locking flags */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT HDassert(file); + + /* Only set the lock if there is a file descriptor. If no file + * descriptor, this is a no-op. + */ if(file->fd >= 0) { - /* Determine the type of lock */ - lock = rw ? LOCK_EX : LOCK_SH; - - /* Place the lock with non-blocking */ - if(HDflock(file->fd, lock | LOCK_NB) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to flock file") - } - /* Otherwise a noop */ + /* Set exclusive or shared lock based on rw status */ + lock_flags = rw ? LOCK_EX : LOCK_SH; + + /* Place a non-blocking lock on the file */ + if(HDflock(file->fd, lock_flags | LOCK_NB) < 0) { + if(ENOSYS == errno) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "file locking disabled on this file system (use HDF5_USE_FILE_LOCKING environment variable to override)") + else + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to lock file") + } /* end if */ + + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1525,11 +1533,16 @@ H5FD_core_unlock(H5FD_t *_file) if(file->fd >= 0) { - if(HDflock(file->fd, LOCK_UN) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to flock (unlock) file") - } - /* Otherwise a noop */ + if(HDflock(file->fd, LOCK_UN) < 0) { + if(ENOSYS == errno) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "file locking disabled on this file system (use HDF5_USE_FILE_LOCKING environment variable to override)") + else + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to unlock file") + } /* end if */ + + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_core_unlock() */ + diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 7ec8751..f0d4dba 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -1339,33 +1339,37 @@ done: static herr_t H5FD_family_lock(H5FD_t *_file, hbool_t rw) { - H5FD_family_t *file = (H5FD_family_t *)_file; /* VFD file struct */ - unsigned u, i; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_family_t *file = (H5FD_family_t *)_file; /* VFD file struct */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Place the lock on all the member files */ - for(u = 0; u < file->nmembs; u++) { - if(file->memb[u]) { + for(u = 0; u < file->nmembs; u++) + if(file->memb[u]) if(H5FD_lock(file->memb[u], rw) < 0) - break; - } /* end if */ - } /* end for */ + break; - if(u < file->nmembs) { /* Try to unlock the member files done before */ - for(i = 0; i < u; i++) { - if(H5FD_unlock(file->memb[i]) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_IO, H5E_CANTUNLOCK, FAIL, "unable to unlock member files") - } - HGOTO_ERROR(H5E_IO, H5E_CANTLOCK, FAIL, "unable to lock member files") + /* If one of the locks failed, try to unlock the locked member files + * in an attempt to return to a fully unlocked state. + */ + if(u < file->nmembs) { + unsigned v; /* Local index variable */ + + for(v = 0; v < v; v++) { + if(H5FD_unlock(file->memb[v]) < 0) + /* Push error, but keep going */ + HDONE_ERROR(H5E_IO, H5E_CANTUNLOCK, FAIL, "unable to unlock member files") + } /* end for */ + HGOTO_ERROR(H5E_IO, H5E_CANTLOCK, FAIL, "unable to lock member files") } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_family_lock() */ + /*------------------------------------------------------------------------- * Function: H5FD_family_unlock * @@ -1381,19 +1385,18 @@ static herr_t H5FD_family_unlock(H5FD_t *_file) { H5FD_family_t *file = (H5FD_family_t *)_file; /* VFD file struct */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Remove the lock on the member files */ - for(u = 0; u < file->nmembs; u++) { - if(file->memb[u]) { + for(u = 0; u < file->nmembs; u++) + if(file->memb[u]) if(H5FD_unlock(file->memb[u]) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTUNLOCK, FAIL, "unable to unlock member files") - } /* end if */ - } /* end for */ + HGOTO_ERROR(H5E_IO, H5E_CANTUNLOCK, FAIL, "unable to unlock member files") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_family_unlock() */ + diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 9f5dfa5..a2891cb 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -1567,15 +1567,7 @@ static herr_t H5FD_log_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, hbool_t H5_ATTR_UNUSED closing) { H5FD_log_t *file = (H5FD_log_t *)_file; -#ifdef H5_HAVE_WIN32_API - LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */ - DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer() - * Only used as an error code here. - */ - DWORD dwError; /* DWORD error code from GetLastError() */ - BOOL bError; /* Boolean error flag */ -#endif /* H5_HAVE_WIN32_API */ -herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1586,6 +1578,14 @@ herr_t ret_value = SUCCEED; /* Return value */ #ifdef H5_HAVE_GETTIMEOFDAY struct timeval timeval_start, timeval_stop; #endif /* H5_HAVE_GETTIMEOFDAY */ +#ifdef H5_HAVE_WIN32_API + LARGE_INTEGER li; /* 64-bit (union) integer for SetFilePointer() call */ + DWORD dwPtrLow; /* Low-order pointer bits from SetFilePointer() + * Only used as an error code here. + */ + DWORD dwError; /* DWORD error code from GetLastError() */ + BOOL bError; /* Boolean error flag */ +#endif /* H5_HAVE_WIN32_API */ #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags & H5FD_LOG_TIME_TRUNCATE) @@ -1677,21 +1677,25 @@ done: static herr_t H5FD_log_lock(H5FD_t *_file, hbool_t rw) { - H5FD_log_t *file = (H5FD_log_t *)_file; - int lock; - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_log_t *file = (H5FD_log_t *)_file; /* VFD file struct */ + int lock_flags; /* file locking flags */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Sanity check */ HDassert(file); - /* Determine the type of lock */ - lock = rw ? LOCK_EX : LOCK_SH; + /* Set exclusive or shared lock based on rw status */ + lock_flags = rw ? LOCK_EX : LOCK_SH; - /* Place the lock with non-blocking */ - if(HDflock(file->fd, lock | LOCK_NB) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to flock file") + /* Place a non-blocking lock on the file */ + if(HDflock(file->fd, lock_flags | LOCK_NB) < 0) { + if(ENOSYS == errno) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "file locking disabled on this file system (use HDF5_USE_FILE_LOCKING environment variable to override)") + else + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to lock file") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1712,15 +1716,19 @@ done: static herr_t H5FD_log_unlock(H5FD_t *_file) { - H5FD_log_t *file = (H5FD_log_t *)_file; /* VFD file struct */ - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_log_t *file = (H5FD_log_t *)_file; /* VFD file struct */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT HDassert(file); - if(HDflock(file->fd, LOCK_UN) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to flock (unlock) file") + if(HDflock(file->fd, LOCK_UN) < 0) { + if(ENOSYS == errno) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "file locking disabled on this file system (use HDF5_USE_FILE_LOCKING environment variable to override)") + else + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to unlock file") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index bb8f004..04a0790 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -922,20 +922,24 @@ done: static herr_t H5FD_sec2_lock(H5FD_t *_file, hbool_t rw) { - H5FD_sec2_t *file = (H5FD_sec2_t *)_file; /* VFD file struct */ - int lock; /* The type of lock */ - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; /* VFD file struct */ + int lock_flags; /* file locking flags */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT HDassert(file); - /* Determine the type of lock */ - lock = rw ? LOCK_EX : LOCK_SH; - - /* Place the lock with non-blocking */ - if(HDflock(file->fd, lock | LOCK_NB) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to flock file") + /* Set exclusive or shared lock based on rw status */ + lock_flags = rw ? LOCK_EX : LOCK_SH; + + /* Place a non-blocking lock on the file */ + if(HDflock(file->fd, lock_flags | LOCK_NB) < 0) { + if(ENOSYS == errno) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "file locking disabled on this file system (use HDF5_USE_FILE_LOCKING environment variable to override)") + else + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to lock file") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -956,15 +960,19 @@ done: static herr_t H5FD_sec2_unlock(H5FD_t *_file) { - H5FD_sec2_t *file = (H5FD_sec2_t *)_file; /* VFD file struct */ - herr_t ret_value = SUCCEED; /* Return value */ + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; /* VFD file struct */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT HDassert(file); - if(HDflock(file->fd, LOCK_UN) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to flock (unlock) file") + if(HDflock(file->fd, LOCK_UN) < 0) { + if(ENOSYS == errno) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "file locking disabled on this file system (use HDF5_USE_FILE_LOCKING environment variable to override)") + else + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to unlock file") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 0168ff4..7056f7f 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -24,6 +24,7 @@ * and is not intended for production use! */ #include +#include #include #include #include @@ -1078,8 +1079,8 @@ H5FD_stdio_truncate(H5FD_t *_file, hid_t /*UNUSED*/ dxpl_id, * Function: H5FD_stdio_lock * * Purpose: Lock a file via flock - * * NOTE: This function is a no-op if flock() is not present. + * * Errors: * IO FCNTL flock failed. * @@ -1093,21 +1094,27 @@ static herr_t H5FD_stdio_lock(H5FD_t *_file, hbool_t rw) { #ifdef H5_HAVE_FLOCK - H5FD_stdio_t *file = (H5FD_stdio_t*)_file; - int lock; /* The type of lock */ - static const char *func = "H5FD_stdio_lock"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t*)_file; /* VFD file struct */ + int lock_flags; /* file locking flags */ + static const char *func = "H5FD_stdio_lock"; /* Function Name for error reporting */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); assert(file); - /* Determine the type of lock */ - lock = rw ? LOCK_EX : LOCK_SH; + /* Set exclusive or shared lock based on rw status */ + lock_flags = rw ? LOCK_EX : LOCK_SH; - /* Place the lock with non-blocking */ - if(flock(file->fd, lock | LOCK_NB) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FCNTL, "flock failed", -1) + /* Place a non-blocking lock on the file */ + if(flock(file->fd, lock_flags | LOCK_NB) < 0) { + if(ENOSYS == errno) + H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FCNTL, "file locking disabled on this file system (use HDF5_USE_FILE_LOCKING environment variable to override)", -1) + else + H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FCNTL, "file lock failed", -1) + } /* end if */ + + /* Flush the stream */ if(fflush(file->fp) < 0) H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1) @@ -1117,16 +1124,15 @@ H5FD_stdio_lock(H5FD_t *_file, hbool_t rw) } /* end H5FD_stdio_lock() */ /*------------------------------------------------------------------------- - * Function: H5F_stdio_unlock - * - * Purpose: Unlock a file via flock + * Function: H5F_stdio_unlock * + * Purpose: Unlock a file via flock + * NOTE: This function is a no-op if flock() is not present. * - * NOTE: This function is a no-op if flock() is not present. * Errors: * IO FCNTL flock failed. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * * Programmer: Vailin Choi; March 2015 * @@ -1136,18 +1142,25 @@ static herr_t H5FD_stdio_unlock(H5FD_t *_file) { #ifdef H5_HAVE_FLOCK - H5FD_stdio_t *file = (H5FD_stdio_t*)_file; - static const char *func = "H5FD_stdio_unlock"; /* Function Name for error reporting */ + H5FD_stdio_t *file = (H5FD_stdio_t*)_file; /* VFD file struct */ + static const char *func = "H5FD_stdio_unlock"; /* Function Name for error reporting */ /* Clear the error stack */ H5Eclear2(H5E_DEFAULT); assert(file); + /* Flush the stream */ if(fflush(file->fp) < 0) H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_WRITEERROR, "fflush failed", -1) - if(flock(file->fd, LOCK_UN) < 0) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FCNTL, "flock (unlock) failed", -1) + + /* Place a non-blocking lock on the file */ + if(flock(file->fd, LOCK_UN) < 0) { + if(ENOSYS == errno) + H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FCNTL, "file locking disabled on this file system (use HDF5_USE_FILE_LOCKING environment variable to override)", -1) + else + H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_FCNTL, "file unlock failed", -1) + } /* end if */ #endif /* H5_HAVE_FLOCK */ diff --git a/src/H5Fint.c b/src/H5Fint.c index dbaf3cc..152148d 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -171,6 +171,8 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) latest_format = TRUE; if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &latest_format) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") + if(H5P_set(new_plist, H5F_ACS_METADATA_READ_ATTEMPTS_NAME, &(f->shared->read_attempts)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'read attempts ' flag") if(H5P_set(new_plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &(f->shared->object_flush)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set object flush callback") @@ -998,6 +1000,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5F_close_degree_t fc_degree; /*file close degree */ hbool_t evict_on_close; /* evict on close value from plist */ H5F_t *ret_value = NULL; /*actual return value */ + char *lock_env_var = NULL;/*env var pointer */ + hbool_t use_file_locking; /*read from env var */ FUNC_ENTER_NOAPI(NULL) @@ -1012,6 +1016,16 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, if(NULL == (drvr = H5FD_get_class(fapl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class") + /* Check the environment variable that determines if we care + * about file locking. File locking should be used unless explicitly + * disabled. + */ + lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING"); + if(lock_env_var && !HDstrcmp(lock_env_var, "FALSE")) + use_file_locking = FALSE; + else + use_file_locking = TRUE; + /* * Opening a file is a two step process. First we try to open the * file in a way which doesn't affect its state (like not truncating @@ -1024,52 +1038,52 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, * way for us to detect it here anyway). */ if(drvr->cmp) - tent_flags = flags & ~(H5F_ACC_CREAT|H5F_ACC_TRUNC|H5F_ACC_EXCL); + tent_flags = flags & ~(H5F_ACC_CREAT|H5F_ACC_TRUNC|H5F_ACC_EXCL); else - tent_flags = flags; + tent_flags = flags; if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { - if(tent_flags == flags) { + if(tent_flags == flags) { #ifndef H5_USING_MEMCHECKER time_t mytime = HDtime(NULL); - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) #else /* H5_USING_MEMCHECKER */ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) #endif /* H5_USING_MEMCHECKER */ } /* end if */ H5E_clear_stack(NULL); - tent_flags = flags; - if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { + tent_flags = flags; + if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { #ifndef H5_USING_MEMCHECKER time_t mytime = HDtime(NULL); - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) #else /* H5_USING_MEMCHECKER */ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) #endif /* H5_USING_MEMCHECKER */ } /* end if */ } /* end if */ /* Is the file already open? */ if((shared = H5F_sfile_search(lf)) != NULL) { - /* - * The file is already open, so use that one instead of the one we - * just opened. We only one one H5FD_t* per file so one doesn't - * confuse the other. But fail if this request was to truncate the - * file (since we can't do that while the file is open), or if the - * request was to create a non-existent file (since the file already - * exists), or if the new request adds write access (since the - * readers don't expect the file to change under them). - */ - if(H5FD_close(lf) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") - if(flags & H5F_ACC_TRUNC) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open") - if(flags & H5F_ACC_EXCL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists") - if((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only") + /* + * The file is already open, so use that one instead of the one we + * just opened. We only one one H5FD_t* per file so one doesn't + * confuse the other. But fail if this request was to truncate the + * file (since we can't do that while the file is open), or if the + * request was to create a non-existent file (since the file already + * exists), or if the new request adds write access (since the + * readers don't expect the file to change under them). + */ + if(H5FD_close(lf) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") + if(flags & H5F_ACC_TRUNC) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open") + if(flags & H5F_ACC_EXCL) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists") + if((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR)) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only") /* Allocate new "high-level" file struct */ if((file = H5F_new(shared, flags, fcpl_id, fapl_id, NULL)) == NULL) @@ -1089,8 +1103,19 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, if(NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") } /* end if */ + + /* Place an advisory lock on the file */ + if(use_file_locking) + if(H5FD_lock(lf, (hbool_t)((flags & H5F_ACC_RDWR) ? TRUE : FALSE)) < 0) { + /* Locking failed - Closing will remove the lock */ + if(H5FD_close(lf) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to lock the file") + } /* end if */ + + /* Create the 'top' file structure */ if(NULL == (file = H5F_new(NULL, flags, fcpl_id, fapl_id, lf))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to initialize file structure") } /* end else */ /* Retain the name the file was opened with */ @@ -1121,15 +1146,16 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, */ if(H5G_mkroot(file, dxpl_id, TRUE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group") - } else if (1 == shared->nrefs) { + } /* end if */ + else if (1 == shared->nrefs) { - /* Read the superblock if it hasn't been read before. */ + /* Read the superblock if it hasn't been read before. */ if(H5F__super_read(file, dxpl_id, TRUE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") + HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") - /* Open the root group */ - if(H5G_mkroot(file, dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group") + /* Open the root group */ + if(H5G_mkroot(file, dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group") } /* end if */ /* Get the file access property list, for future queries */ @@ -1150,7 +1176,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, shared->fc_degree = lf->cls->fc_degree; else shared->fc_degree = fc_degree; - } else if(shared->nrefs > 1) { + } /* end if */ + else if(shared->nrefs > 1) { if(fc_degree == H5F_CLOSE_DEFAULT && shared->fc_degree != lf->cls->fc_degree) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") if(fc_degree != H5F_CLOSE_DEFAULT && fc_degree != shared->fc_degree) @@ -1174,19 +1201,19 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, /* Formulate the absolute path for later search of target file for external links */ if(H5_build_extpath(name, &file->extpath) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") /* Formulate the actual file name, after following symlinks, etc. */ if(H5F_build_actual_name(file, a_plist, name, &file->actual_name) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name") + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name") /* Success */ ret_value = file; done: if(!ret_value && file) - if(H5F_dest(file, dxpl_id, FALSE) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") + if(H5F_dest(file, dxpl_id, FALSE) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_open() */ diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index 91a6c00..1cca9b1 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -667,58 +667,6 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ H5Z_scaleoffset_modify_4(i, type, pow_fun, buf, d_nelmts, min, D_val) \ } -/* Include our own rounding routine and alias it to the stdc macros, if they - * aren't available. - */ -#if !(defined(H5_HAVE_LLROUND) && defined(H5_HAVE_LLROUNDF) && defined(H5_HAVE_LROUND) && defined(H5_HAVE_LROUNDF) && defined(H5_HAVE_ROUND) && defined(H5_HAVE_ROUNDF)) -/* Round a floating-point value to the nearest integer value 4/19/05 */ -/* rounding to the bigger absolute value if val is in the middle, - 0.5 -> 1, -0.5 ->-1 -5/9/05, KY */ -static double -H5Z__scaleoffset_rnd(double val) -{ - double u_val, l_val; - - u_val = HDceil(val); - l_val = HDfloor(val); - - if(val > 0) { - if((u_val - val) <= (val - l_val)) - return u_val; - else - return l_val; - } /* end if */ - else { - if((val - l_val) <= (u_val - val)) - return l_val; - else - return u_val; - } -} /* H5Z__scaleoffset_rnd() */ - -/* Alias rounding macros to routine above, if not defined */ -#if !defined(H5_HAVE_LLROUND) -#define llround(x) H5Z__scaleoffset_rnd(x) -#endif /* !defined(H5_HAVE_LLROUND) */ -#if !defined(H5_HAVE_LLROUNDF) -#define llroundf(x) H5Z__scaleoffset_rnd(x) -#endif /* !defined(H5_HAVE_LLROUNDF) */ -#if !defined(H5_HAVE_LROUND) -#define lround(x) H5Z__scaleoffset_rnd(x) -#endif /* !defined(H5_HAVE_LROUND) */ -#if !defined(H5_HAVE_LROUNDF) -#define lroundf(x) H5Z__scaleoffset_rnd(x) -#endif /* !defined(H5_HAVE_LROUNDF) */ -#if !defined(H5_HAVE_ROUND) -#define round(x) H5Z__scaleoffset_rnd(x) -#endif /* !defined(H5_HAVE_ROUND) */ -#if !defined(H5_HAVE_ROUNDF) -#define roundf(x) H5Z__scaleoffset_rnd(x) -#endif /* !defined(H5_HAVE_ROUNDF) */ - -#endif /* !(defined(H5_HAVE_LLROUND) && defined(H5_HAVE_LLROUNDF) && defined(H5_HAVE_LROUND) && defined(H5_HAVE_LROUNDF) && defined(H5_HAVE_ROUND) && defined(H5_HAVE_ROUNDF)) */ - /*------------------------------------------------------------------------- * Function: H5Z_can_apply_scaleoffset diff --git a/test/ohdr.c b/test/ohdr.c index e613a98..1478c5c 100644 --- a/test/ohdr.c +++ b/test/ohdr.c @@ -609,9 +609,8 @@ main(void) H5F_t *f = NULL; char filename[1024]; H5O_hdr_info_t hdr_info; /* Object info */ - H5O_loc_t oh_loc, oh_loc2; /* Object header locations */ + H5O_loc_t oh_loc; /* Object header locations */ time_t time_new, ro; - int chunkno; /* Chunk index for message */ int i; /* Local index variable */ unsigned b; /* Index for "new format" loop */ herr_t ret; /* Generic return value */ -- cgit v0.12