diff options
Diffstat (limited to 'src/H5Pdcpl.c')
-rw-r--r-- | src/H5Pdcpl.c | 124 |
1 files changed, 79 insertions, 45 deletions
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 575de9c..e647f29 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -57,7 +57,7 @@ #define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0} #define H5D_DEF_STORAGE_CHUNK_INIT {H5D_CHUNK_IDX_BTREE, HADDR_UNDEF, NULL, {{HADDR_UNDEF, NULL}}} #define H5D_DEF_LAYOUT_CHUNK_INIT {(unsigned)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, (uint32_t)0, (hsize_t)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} -#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, TRUE} +#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, H5D_VDS_ERROR, HSIZE_UNDEF} #ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER #define H5D_DEF_STORAGE_COMPACT {H5D_COMPACT, { .compact = H5D_DEF_STORAGE_COMPACT_INIT }} #define H5D_DEF_STORAGE_CONTIG {H5D_CONTIGUOUS, { .contig = H5D_DEF_STORAGE_CONTIG_INIT }} @@ -1599,7 +1599,9 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, H5S_t *vspace; /* Virtual dataset space selection */ H5S_t *src_space; /* Source dataset space selection */ hbool_t new_layout = FALSE; /* Whether we are adding a new virtual layout message to plist */ + H5O_storage_virtual_ent_t *ent = NULL; /* Convenience pointer to new VDS entry */ hbool_t adding_entry = FALSE; /* Whether we are in the middle of adding an entry */ + H5O_storage_virtual_ent_t *old_list = NULL; /* List pointer previously on property list */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1638,16 +1640,22 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, /* If the layout was not already virtual, Start with default virtual layout. * Otherwise, add the mapping to the current list. */ - if(layout.type != H5D_VIRTUAL) { + if(layout.type == H5D_VIRTUAL) + /* Save old list pointer for error recovery */ + old_list = layout.storage.u.virt.list; + else { new_layout = TRUE; HDmemcpy(&layout, &H5D_def_layout_virtual_g, sizeof(H5D_def_layout_virtual_g)); - } /* end if */ + + HDassert(layout.storage.u.virt.list_nalloc == 0); + } /* end else */ /* Expand list if necessary */ if(layout.storage.u.virt.list_nalloc == 0) { /* Allocate initial entry list */ if(NULL == (layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_calloc(H5D_VIRTUAL_DEF_LIST_SIZE * sizeof(H5O_storage_virtual_ent_t)))) HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't allocate virtual dataset mapping list") + adding_entry = TRUE; layout.storage.u.virt.list_nalloc = H5D_VIRTUAL_DEF_LIST_SIZE; } /* end if */ else if(layout.storage.u.virt.list_nused @@ -1656,28 +1664,34 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, /* Double size of entry list. Make sure to zero out new memory. */ if(NULL == (layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_realloc(layout.storage.u.virt.list, (size_t)2 * layout.storage.u.virt.list_nalloc * sizeof(H5O_storage_virtual_ent_t)))) HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't reallocate virtual dataset mapping list") + adding_entry = TRUE; (void)HDmemset(layout.storage.u.virt.list + layout.storage.u.virt.list_nalloc, 0, layout.storage.u.virt.list_nalloc * sizeof(H5O_storage_virtual_ent_t)); layout.storage.u.virt.list_nalloc *= (size_t)2; } /* end if */ /* Add virtual dataset mapping entry */ - if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name = HDstrdup(src_file_name))) + ent = &layout.storage.u.virt.list[layout.storage.u.virt.list_nused]; + if(NULL == (ent->source_dset.file_name = HDstrdup(src_file_name))) HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name") adding_entry = TRUE; - if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name = HDstrdup(src_dset_name))) + if(NULL == (ent->source_dset.dset_name = HDstrdup(src_dset_name))) HGOTO_ERROR(H5E_PLIST, H5E_RESOURCE, FAIL, "can't duplicate source file name") - if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select = H5S_copy(src_space, FALSE, TRUE))) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection") - if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_select = H5S_copy(vspace, FALSE, TRUE))) + if(NULL == (ent->source_dset.virtual_select = H5S_copy(vspace, FALSE, TRUE))) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_dim_source = H5S_get_select_unlim_dim(src_space); - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_dim_virtual = H5S_get_select_unlim_dim(vspace); - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_extent_source = HSIZE_UNDEF; - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_extent_virtual = HSIZE_UNDEF; - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].clip_size_source = HSIZE_UNDEF; - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].clip_size_virtual = HSIZE_UNDEF; - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_space_status = H5O_VIRTUAL_STATUS_USER; - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_space_status = H5O_VIRTUAL_STATUS_USER; + if(NULL == (ent->source_select = H5S_copy(src_space, FALSE, TRUE))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection") + if(H5D_virtual_parse_source_name(ent->source_dset.file_name, &ent->parsed_source_file_name, &ent->psfn_static_strlen, &ent->psfn_nsubs) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source file name") + if(H5D_virtual_parse_source_name(ent->source_dset.dset_name, &ent->parsed_source_dset_name, &ent->psdn_static_strlen, &ent->psdn_nsubs) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't parse source dataset name") + ent->unlim_dim_source = H5S_get_select_unlim_dim(src_space); + ent->unlim_dim_virtual = H5S_get_select_unlim_dim(vspace); + ent->unlim_extent_source = HSIZE_UNDEF; + ent->unlim_extent_virtual = HSIZE_UNDEF; + ent->clip_size_source = HSIZE_UNDEF; + ent->clip_size_virtual = HSIZE_UNDEF; + ent->source_space_status = H5O_VIRTUAL_STATUS_USER; + ent->virtual_space_status = H5O_VIRTUAL_STATUS_USER; /* Update min_dims */ if(H5D_virtual_update_min_dims(&layout, layout.storage.u.virt.list_nused) < 0) @@ -1685,32 +1699,52 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name, /* Finish adding entry */ layout.storage.u.virt.list_nused++; - adding_entry = FALSE; - - /* Set chunk information in property list. If we are adding a new layout, - * use H5P__set_layout so other fields are initialized properly. If we are - * extending the layout, just use H5P_set directly so we don't mess with - * anything else. */ - if(new_layout) { - if(H5P__set_layout(plist, &layout) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout") - } /* end if */ - else - if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout") done: + /* Only need to do things if we started to add an entry */ if(adding_entry) { - HDassert(ret_value < 0); + hbool_t free_list = FALSE; + + /* Set chunk information in property list. If we are adding a new layout, + * use H5P__set_layout so other fields are initialized properly. If we are + * extending the layout, just use H5P_set directly so we don't mess with + * anything else. */ + if(new_layout) { + if(H5P__set_layout(plist, &layout) < 0) { + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout") + free_list = TRUE; + } /* end if */ + } /* end if */ + else + if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &layout) < 0) { + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set layout") + if(old_list != layout.storage.u.virt.list) + free_list = TRUE; + } /* end if */ - /* Free incomplete entry */ - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name = (char *)H5MM_xfree(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_file_name); - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name = (char *)H5MM_xfree(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_dset_name); - if(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select - && H5S_close(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") - layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_select = NULL; - HDassert(layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_select == NULL); + /* Check if the entry has been partly allocated but not added to the + * property list or not included in list_nused */ + if((ret_value < 0) && ent) { + HDassert(ret_value < 0); + + /* Free incomplete entry */ + ent->source_dset.file_name = (char *)H5MM_xfree(ent->source_dset.file_name); + ent->source_dset.dset_name = (char *)H5MM_xfree(ent->source_dset.dset_name); + if(ent->source_dset.virtual_select && H5S_close(ent->source_dset.virtual_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release virtual selection") + ent->source_dset.virtual_select = NULL; + if(ent->source_select && H5S_close(ent->source_select) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release source selection") + ent->source_select = NULL; + H5D_virtual_free_parsed_name(ent->parsed_source_file_name); + ent->parsed_source_file_name = NULL; + H5D_virtual_free_parsed_name(ent->parsed_source_dset_name); + ent->parsed_source_dset_name = NULL; + + /* Free list if necessary */ + if(free_list) + layout.storage.u.virt.list = (H5O_storage_virtual_ent_t *)H5MM_xfree(layout.storage.u.virt.list); + } /* end if */ } /* end if */ FUNC_LEAVE_API(ret_value) @@ -1796,7 +1830,7 @@ H5Pget_virtual_vspace(hid_t dcpl_id, size_t index) if(index >= layout.storage.u.virt.list_nused) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc); - if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].virtual_select, FALSE, TRUE))) + if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].source_dset.virtual_select, FALSE, TRUE))) HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection") /* Clip selection to extent */ @@ -1918,10 +1952,10 @@ H5Pget_virtual_filename(hid_t dcpl_id, size_t index, char *name/*out*/, if(index >= layout.storage.u.virt.list_nused) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc); - HDassert(layout.storage.u.virt.list[index].source_file_name); + HDassert(layout.storage.u.virt.list[index].source_dset.file_name); if(name && (size > 0)) - (void)HDstrncpy(name, layout.storage.u.virt.list[index].source_file_name, size); - ret_value = (ssize_t)HDstrlen(layout.storage.u.virt.list[index].source_file_name); + (void)HDstrncpy(name, layout.storage.u.virt.list[index].source_dset.file_name, size); + ret_value = (ssize_t)HDstrlen(layout.storage.u.virt.list[index].source_dset.file_name); done: FUNC_LEAVE_API(ret_value) @@ -1965,10 +1999,10 @@ H5Pget_virtual_dsetname(hid_t dcpl_id, size_t index, char *name/*out*/, if(index >= layout.storage.u.virt.list_nused) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid index (out of range)") HDassert(layout.storage.u.virt.list_nused <= layout.storage.u.virt.list_nalloc); - HDassert(layout.storage.u.virt.list[index].source_dset_name); + HDassert(layout.storage.u.virt.list[index].source_dset.dset_name); if(name && (size > 0)) - (void)HDstrncpy(name, layout.storage.u.virt.list[index].source_dset_name, size); - ret_value = (ssize_t)HDstrlen(layout.storage.u.virt.list[index].source_dset_name); + (void)HDstrncpy(name, layout.storage.u.virt.list[index].source_dset.dset_name, size); + ret_value = (ssize_t)HDstrlen(layout.storage.u.virt.list[index].source_dset.dset_name); done: FUNC_LEAVE_API(ret_value) |