From d91d6d3a4c068424f60a0eb9671c4843f372b1d0 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Sun, 21 May 2017 16:28:26 -0500 Subject: Add support for variable length types (not within compound or array, with no sub-type conversions) with attributes. Added h5dsm_tvlen.c to test this. Other minor fixes/cleanup. --- examples/Makefile.am | 44 +++- examples/h5dsm_test.sh | 8 + examples/h5dsm_ttconv.c | 2 +- examples/h5dsm_tvlen.c | 342 +++++++++++++++++++++++++++++++ src/H5VLdaosm.c | 531 +++++++++++++++++++++++++++++++++++++----------- src/H5VLint.c | 6 +- 6 files changed, 808 insertions(+), 125 deletions(-) create mode 100644 examples/h5dsm_tvlen.c diff --git a/examples/Makefile.am b/examples/Makefile.am index f83145a..3f28819 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -42,9 +42,16 @@ EXAMPLE_PROG = h5_write h5_read h5_extend_write h5_chunk_read h5_compound \ h5_vds h5_vds-exc \ h5_vds-exclim h5_vds-eiger h5_vds-simpleIO h5_vds-percival \ h5_vds-percival-unlim h5_vds-percival-unlim-maxmin \ - h5dsm_file_create h5dsm_file_open h5dsm_dset_create h5dsm_dset_open \ - h5dsm_dset_write h5dsm_dset_read h5dsm_map -TEST_SCRIPT=testh5cc.sh + h5dsm_file_create h5dsm_file_open h5dsm_group_create \ + h5dsm_group_open h5dsm_dset_create h5dsm_dset_open \ + h5dsm_dset_write h5dsm_dset_read + h5dsm_dset_wpartial h5dsm_dset_rpartial h5dsm_dset_w1m \ + h5dsm_dset_r1m h5dsm_link_exists h5dsm_link_iter \ + h5dsm_attr_create h5dsm_attr_open h5dsm_attr_write \ + h5dsm_attr_read h5dsm_attr_iter h5dsm_slink_create \ + h5dsm_obj_open h5dsm_obj_open_addr h5dsm_obj_info h5dsm_map \ + h5dsm_ttconv h5dsm_tvlen +TEST_SCRIPT=testh5cc.sh h5dsm_test.sh TEST_EXAMPLES_SCRIPT=$(INSTALL_SCRIPT_FILES) # Install files @@ -59,8 +66,15 @@ INSTALL_FILES = h5_write.c h5_read.c h5_extend_write.c h5_chunk_read.c \ h5_vds.c h5_vds-exc.c \ h5_vds-exclim.c h5_vds-eiger.c h5_vds-simpleIO.c h5_vds-percival.c \ h5_vds-percival-unlim.c h5_vds-percival-unlim-maxmin.c \ - h5dsm_file_create.c h5dsm_file_open.c h5dsm_dset_create.c \ - h5dsm_dset_open.c h5dsm_dset_write.c h5dsm_dset_read.c + h5dsm_file_create.c h5dsm_file_open.c h5dsm_group_create.c \ + h5dsm_group_open.c h5dsm_dset_create.c \ + h5dsm_dset_open.c h5dsm_dset_write.c h5dsm_dset_read.c \ + h5dsm_dset_wpartial.c h5dsm_dset_rpartial.c h5dsm_dset_w1m.c \ + h5dsm_dset_r1m.c h5dsm_link_exists.c h5dsm_link_iter.c \ + h5dsm_attr_create.c h5dsm_attr_open.c h5dsm_attr_write.c \ + h5dsm_attr_read.c h5dsm_attr_iter.c h5dsm_slink_create.c \ + h5dsm_obj_open.c h5dsm_obj_open_addr.c h5dsm_obj_info.c h5dsm_map.c \ + h5dsm_ttconv.c h5dsm_tvlen.c @@ -140,10 +154,30 @@ h5_vds-percival-unlim: $(srcdir)/h5_vds-percival-unlim.c h5_vds-percival-unlim-maxmin: $(srcdir)/h5_vds-percival-unlim-maxmin.c h5dsm_file_create: $(srcdir)/h5dsm_file_create.c h5dsm_file_open: $(srcdir)/h5dsm_file_open.c +h5dsm_group_create: $(srcdir)/h5dsm_group_create.c +h5dsm_group_open: $(srcdir)/h5dsm_group_open.c h5dsm_dset_create: $(srcdir)/h5dsm_dset_create.c h5dsm_dset_open: $(srcdir)/h5dsm_dset_open.c h5dsm_dset_write: $(srcdir)/h5dsm_dset_write.c h5dsm_dset_read: $(srcdir)/h5dsm_dset_read.c +h5dsm_dset_wpartial: $(srcdir)/h5dsm_dset_wpartial.c +h5dsm_dset_rpartial: $(srcdir)/h5dsm_dset_rpartial.c +h5dsm_dset_w1m: $(srcdir)/h5dsm_dset_w1m.c +h5dsm_dset_r1m: $(srcdir)/h5dsm_dset_r1m.c +h5dsm_link_exists: $(srcdir)/h5dsm_link_exists.c +h5dsm_link_iter: $(srcdir)/h5dsm_link_iter.c +h5dsm_attr_create: $(srcdir)/h5dsm_attr_create.c +h5dsm_attr_open: $(srcdir)/h5dsm_attr_open.c +h5dsm_attr_write: $(srcdir)/h5dsm_attr_write.c +h5dsm_attr_read: $(srcdir)/h5dsm_attr_read.c +h5dsm_attr_iter: $(srcdir)/h5dsm_attr_iter.c +h5dsm_slink_create: $(srcdir)/h5dsm_slink_create.c +h5dsm_obj_open: $(srcdir)/h5dsm_obj_open.c +h5dsm_obj_open_addr: $(srcdir)/h5dsm_obj_open_addr.c +h5dsm_obj_info: $(srcdir)/h5dsm_obj_info.c +h5dsm_map: $(srcdir)/h5dsm_map.c +h5dsm_ttconv: $(srcdir)/h5dsm_ttconv.c +h5dsm_tvlen: $(srcdir)/h5dsm_tvlen.c if BUILD_SHARED_SZIP_CONDITIONAL LD_LIBRARY_PATH=$(LL_PATH) diff --git a/examples/h5dsm_test.sh b/examples/h5dsm_test.sh index 5b7eda6..c38e2ca 100755 --- a/examples/h5dsm_test.sh +++ b/examples/h5dsm_test.sh @@ -552,6 +552,14 @@ if test $? -ne 0; then exit 1 fi +# --------------- Variable Length types --------------- # +echo h5dsm_tvlen +orterun -np 1 $EXEC_ARGS ./h5dsm_tvlen $POOL_UUID -q +if test $? -ne 0; then + echo FAILED + exit 1 +fi + # --------------- Output Comparison --------------- # sed -i -e 's/#.*//' -e 's/[ ^I]*$//' -e '/^$/ d' h5dsm_test.out echo cmp h5dsm_test.out h5dsm_test.out.exp diff --git a/examples/h5dsm_ttconv.c b/examples/h5dsm_ttconv.c index 731573c..6b10d53 100644 --- a/examples/h5dsm_ttconv.c +++ b/examples/h5dsm_ttconv.c @@ -20,7 +20,7 @@ hbool_t verbose_g = 1; int main(int argc, char *argv[]) { uuid_t pool_uuid; char *pool_grp = NULL; - hid_t file = -1, dset = -1, dset_a = -1, dset_b = -1, dset_c = -1, dset2 = -1, attr = -1, attr_a = -1, attr_b = -1 , attr_c = -1, space = -1, space2 = -1, space2_contig, fapl = -1; + hid_t file = -1, dset = -1, dset_a = -1, dset_b = -1, dset_c = -1, dset2 = -1, attr = -1, attr_a = -1, attr_b = -1 , attr_c = -1, space = -1, space2 = -1, space2_contig = -1, fapl = -1; hid_t file_type = -1, file_type_a = -1, file_type_b = -1, file_type_c = -1; hid_t mem_type = -1, mem_type_conv = -1, mem_type_a = -1, mem_type_b = -1, mem_type_c = -1; hsize_t dims[2] = {4, 2}; diff --git a/examples/h5dsm_tvlen.c b/examples/h5dsm_tvlen.c new file mode 100644 index 0000000..ffe4933 --- /dev/null +++ b/examples/h5dsm_tvlen.c @@ -0,0 +1,342 @@ +#include "h5dsm_example.h" +#include + +#define FILE_NAME "tvlen.h5" +#define NITER 10 + +hbool_t verbose_g = 1; + +static void print_vla(const hvl_t *vla) { + int i, j, k; + + for(i = 0; i < 4; i++) { + for(j = 0; j < 2; j++) { + if(j > 0) + printf(", "); + printf("{"); + for(k = 0; k < (int)vla[2 * i + j].len; k++) { + if(k > 0) + printf(", "); + printf("%d", ((int *)vla[2 * i + j].p)[k]); + } /* end for */ + printf("}"); + } /* end for */ + printf("\n"); + } /* end for */ + + return; +} /* end print_vla() */ + +static int check_vla(const hvl_t *vla1, const hvl_t *vla2) { + int i, j, k; + + for(i = 0; i < 4; i++) + for(j = 0; j < 2; j++) { + if(vla1[2 * i + j].len != vla2[2 * i + j].len) + PRINTF_ERROR("vlen array length at location %d, %d does not match", i, j); + for(k = 0; k < (int)vla1[2 * i + j].len; k++) + if(((int *)vla1[2 * i + j].p)[k] != ((int *)vla2[2 * i + j].p)[k]) + PRINTF_ERROR("vlen array data at location %d, %d, %d does not match", i, j, k); + } /* end for */ + + return 0; + +error: + return -1; +} /* end check_vla() */ + +static void print_vls(char **vls) { + int i, j; + + for(i = 0; i < 4; i++) { + for(j = 0; j < 2; j++) { + if(j > 0) + printf(", "); + if(vls[2 * i + j]) + printf("\"%s\"", vls[2 * i + j]); + else + printf("NULL"); + } /* end for */ + printf("\n"); + } /* end for */ + + return; +} /* end print_vls() */ + +static int check_vls(char **vls1, char **vls2) { + int i, j; + + for(i = 0; i < 4; i++) + for(j = 0; j < 2; j++) { + if((vls1[2 * i + j] == NULL) != (vls2[2 * i + j] == NULL)) + PRINTF_ERROR("one vlen string at location %d, %d is NULL and the other is not", i, j); + if(vls1[2 * i + j] && strcmp(vls1[2 * i + j], vls2[2 * i + j])) + PRINTF_ERROR("vlen strings at location %d, %d do not match", i, j); + } /* end for */ + + return 0; + +error: + return -1; +} /* end check_vls() */ + +int main(int argc, char *argv[]) { + uuid_t pool_uuid; + char *pool_grp = NULL; + hid_t file = -1, dset_vla = -1, dset_vls = -1, attr_vla = -1, attr_vls = -1, space = -1, fapl = -1; + hid_t type_vla = -1, type_vls = -1; + hsize_t dims[2] = {4, 2}; + int static_buf_vla[4][2][8]; + char static_buf_vls[4][2][8]; + hvl_t rbuf_vla[4][2]; + char *rbuf_vls[4][2]; + hvl_t wbuf_vla[4][2]; + char *wbuf_vls[4][2]; + int bogus_int = -1; + char bogus_str[3] = {'-', '1', '\0'}; + const hvl_t rbuf_vla_init[4][2] = {{{1, &bogus_int}, {1, &bogus_int}}, + {{1, &bogus_int}, {1, &bogus_int}}, + {{1, &bogus_int}, {1, &bogus_int}}, + {{1, &bogus_int}, {1, &bogus_int}}}; + char * const rbuf_vls_init[4][2] = {{bogus_str, bogus_str}, + {bogus_str, bogus_str}, + {bogus_str, bogus_str}, + {bogus_str, bogus_str}}; + const hvl_t wbuf_vla_init[4][2] = {{{0, &static_buf_vla[0][0][0]}, {0, &static_buf_vla[0][1][0]}}, + {{0, &static_buf_vla[1][0][0]}, {0, &static_buf_vla[1][1][0]}}, + {{0, &static_buf_vla[2][0][0]}, {0, &static_buf_vla[2][1][0]}}, + {{0, &static_buf_vla[3][0][0]}, {1, &static_buf_vla[3][1][0]}}}; + char * const wbuf_vls_init[4][2] = {{&static_buf_vls[0][0][0], &static_buf_vls[0][1][0]}, + {&static_buf_vls[1][0][0], &static_buf_vls[1][1][0]}, + {&static_buf_vls[2][0][0], &static_buf_vls[2][1][0]}, + {&static_buf_vls[3][0][0], &static_buf_vls[3][1][0]}}; + int i, j, k, l; + + (void)MPI_Init(&argc, &argv); + + /* Seed random number generator */ + srand(time(NULL)); + + if((argc != 2) && (argc != 3)) + PRINTF_ERROR("argc must be 2 or 3\n"); + + if(argc == 3) + verbose_g = 0; + + /* Parse UUID */ + if(0 != uuid_parse(argv[1], pool_uuid)) + ERROR; + + /* Initialize VOL */ + if(H5VLdaosm_init(MPI_COMM_WORLD, pool_uuid, pool_grp) < 0) + ERROR; + + /* Set up FAPL */ + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + ERROR; + if(H5Pset_fapl_daosm(fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0) + ERROR; + if(H5Pset_all_coll_metadata_ops(fapl, true) < 0) + ERROR; + + /* Create file */ + if((file = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + ERROR; + + /* Set up dataspace */ + if((space = H5Screate_simple(2, dims, NULL)) < 0) + ERROR; + + /* + * Set up types + */ + /* Create variable length array */ + /* Set up file "all" type */ + if((type_vla = H5Tvlen_create(H5T_NATIVE_INT)) < 0) + ERROR; + + /* Set up variable length string type */ + if((type_vls = H5Tcopy(H5T_C_S1)) < 0) + ERROR; + if(H5Tset_size(type_vls, H5T_VARIABLE) < 0) + ERROR; + + /* + * Create objects + */ + /* Create vla dataset */ + if((dset_vla = H5Dcreate2(file, "vla_dset", type_vla, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + ERROR; + + /* Create vls dataset */ + if((dset_vls = H5Dcreate2(file, "vls_dset", type_vls, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) + ERROR; + + /* Create vla attribute */ + if((attr_vla = H5Acreate2(dset_vla, "vla_attr", type_vla, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + ERROR; + + /* Create vls attribute */ + if((attr_vls = H5Acreate2(dset_vla, "vls_attr", type_vls, space, H5P_DEFAULT, H5P_DEFAULT)) < 0) + ERROR; + + /* + * Test attribute + */ + /* Loop over iterations */ + for(i = 0; i < NITER; i++) { + /* + * Variable length array attribute test + */ + /* Fill write data buffer */ + for(j = 0; j < dims[0]; j++) + for(k = 0; k < dims[1]; k++) + for(l = 0; l < (sizeof(static_buf_vla[0][0]) / sizeof(static_buf_vla[0][0][0])); l++) + static_buf_vla[j][k][l] = rand() % 100; + + /* Fill write buffer */ + memcpy(wbuf_vla, wbuf_vla_init, sizeof(wbuf_vla)); + for(j = 0; j < dims[0]; j++) + for(k = 0; k < dims[1]; k++) { + /* 10% chance of having a NULL sequence */ + if(rand() % 10) + wbuf_vla[j][k].len = rand() % 9; + else { + wbuf_vla[j][k].len = 0; + wbuf_vla[j][k].p = NULL; + } /* end if */ + } /* end for */ + + /* Print message */ + if(verbose_g) { + printf("Writing attribute with variable length arrays. buf =\n"); + print_vla(wbuf_vla[0]); + } /* end if */ + + /* Write data */ + if(H5Awrite(attr_vla, type_vla, wbuf_vla) < 0) + ERROR; + + /* Read data */ + memcpy(rbuf_vla, rbuf_vla_init, sizeof(rbuf_vla)); + if(H5Aread(attr_vla, type_vla, rbuf_vla) < 0) + ERROR; + + /* Print message */ + if(verbose_g) { + printf("Read attribute with variable length arrays. buf =\n"); + print_vla(rbuf_vla[0]); + } /* end if */ + + /* Check buffer */ + if(check_vla(wbuf_vla[0], rbuf_vla[0]) < 0) { + (void)H5Dvlen_reclaim(type_vla, space, H5P_DEFAULT, rbuf_vla); + ERROR; + } /* end if */ + + /* Reclaim read buffer */ + if(H5Dvlen_reclaim(type_vla, space, H5P_DEFAULT, rbuf_vla) < 0) + ERROR; + + if(verbose_g) + printf("\n"); + + /* + * Variable length string attribute test + */ + /* Fill write data buffer */ + for(j = 0; j < dims[0]; j++) + for(k = 0; k < dims[1]; k++) + for(l = 0; l < (sizeof(static_buf_vls[0][0]) / sizeof(static_buf_vls[0][0][0])); l++) + static_buf_vls[j][k][l] = 'a' + rand() % 26; + + /* Fill write buffer */ + memcpy(wbuf_vls, wbuf_vls_init, sizeof(wbuf_vls)); + for(j = 0; j < dims[0]; j++) + for(k = 0; k < dims[1]; k++) { + /* 10% chance of having a NULL sequence */ + if(rand() % 10) + static_buf_vls[j][k][rand() % 8] = '\0'; + else + wbuf_vls[j][k] = NULL; + } /* end for */ + + /* Print message */ + if(verbose_g) { + printf("Writing attribute with variable length strings. buf =\n"); + print_vls(wbuf_vls[0]); + } /* end if */ + + /* Write data */ + if(H5Awrite(attr_vls, type_vls, wbuf_vls) < 0) + ERROR; + + /* Read data */ + memcpy(rbuf_vls, rbuf_vls_init, sizeof(rbuf_vls)); + if(H5Aread(attr_vls, type_vls, rbuf_vls) < 0) + ERROR; + + /* Print message */ + if(verbose_g) { + printf("Read attribute with variable length strings. buf =\n"); + print_vls(rbuf_vls[0]); + } /* end if */ + + /* Check buffer */ + if(check_vls(wbuf_vls[0], rbuf_vls[0]) < 0) { + (void)H5Dvlen_reclaim(type_vls, space, H5P_DEFAULT, rbuf_vls); + ERROR; + } /* end if */ + + /* Reclaim read buffer */ + if(H5Dvlen_reclaim(type_vls, space, H5P_DEFAULT, rbuf_vls) < 0) + ERROR; + + if(verbose_g) + printf("\n"); + } /* end for */ + + /* + * Close + */ + if(H5Aclose(attr_vla) < 0) + ERROR; + if(H5Aclose(attr_vls) < 0) + ERROR; + if(H5Dclose(dset_vla) < 0) + ERROR; + if(H5Dclose(dset_vls) < 0) + ERROR; + if(H5Fclose(file) < 0) + ERROR; + if(H5Tclose(type_vla) < 0) + ERROR; + if(H5Tclose(type_vls) < 0) + ERROR; + if(H5Sclose(space) < 0) + ERROR; + if(H5Pclose(fapl) < 0) + ERROR; + + printf("Success\n"); + + (void)MPI_Finalize(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Aclose(attr_vla); + H5Aclose(attr_vls); + H5Dclose(dset_vla); + H5Dclose(dset_vls); + H5Fclose(file); + H5Tclose(type_vla); + H5Tclose(type_vls); + H5Sclose(space); + H5Pclose(fapl); + } H5E_END_TRY; + + (void)MPI_Finalize(); + return 1; +} + diff --git a/src/H5VLdaosm.c b/src/H5VLdaosm.c index 0e883be..12ec6b3 100644 --- a/src/H5VLdaosm.c +++ b/src/H5VLdaosm.c @@ -5324,20 +5324,22 @@ H5VL_daosm_attribute_read(void *_attr, hid_t mem_type_id, void *buf, size_t akey_len; daos_key_t dkey; char *akey = NULL; - daos_iod_t iod; - daos_recx_t recx; - daos_sg_list_t sgl; - daos_iov_t sg_iov; + uint8_t **akeys = NULL; + daos_iod_t *iods = NULL; + daos_sg_list_t *sgls = NULL; + daos_iov_t *sg_iovs = NULL; char attr_key[] = H5VL_DAOSM_ATTR_KEY; + hid_t base_type_id = FAIL; size_t file_type_size; - size_t mem_type_size; + size_t base_type_size = 0; uint64_t attr_size; void *tconv_buf = NULL; void *bkg_buf = NULL; - H5VL_daosm_tconv_reuse_t reuse = H5VL_DAOSM_TCONV_REUSE_NONE; - hbool_t fill_bkg = FALSE; + H5T_class_t type_class; + hbool_t is_vl = FALSE; + htri_t is_vl_str = FALSE; int ret; - int i; + uint64_t i; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -5350,76 +5352,233 @@ H5VL_daosm_attribute_read(void *_attr, hid_t mem_type_id, void *buf, /* Calculate attribute size */ attr_size = (uint64_t)1; - for(i = 0; i < ndims; i++) + for(i = 0; i < (uint64_t)ndims; i++) attr_size *= (uint64_t)dim[i]; - /* Check for type conversion */ - if(H5VL_daosm_tconv_init(attr->type_id, &file_type_size, mem_type_id, &mem_type_size, (size_t)attr_size, &tconv_buf, &bkg_buf, &reuse, &fill_bkg) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't initialize type conversion") + /* Set up dkey */ + daos_iov_set(&dkey, attr_key, (daos_size_t)(sizeof(attr_key) - 1)); - /* Reuse buffer as appropriate */ - if(reuse == H5VL_DAOSM_TCONV_REUSE_TCONV) - tconv_buf = buf; - else if(reuse == H5VL_DAOSM_TCONV_REUSE_BKG) - bkg_buf = buf; + /* Check for vlen */ + if(H5T_NO_CLASS == (type_class = H5Tget_class(mem_type_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype class") + if(type_class == H5T_VLEN) { + is_vl = TRUE; + + /* Calculate base type size */ + if((base_type_id = H5Tget_super(mem_type_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype base type") + if(0 == (base_type_size = H5Tget_size(base_type_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype base type size") + } /* end if */ + else if(type_class == H5T_STRING) { + /* check for vlen string */ + if((is_vl_str = H5Tis_variable_str(mem_type_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for variable length string") + if(is_vl_str) + is_vl = TRUE; + } /* end if */ - /* Fill background buffer if necessary */ - if(fill_bkg && (bkg_buf != buf)) - (void)HDmemcpy(bkg_buf, buf, (size_t)attr_size * mem_type_size); + /* Check for variable length */ + if(is_vl) { + size_t akey_str_len; + uint64_t offset = 0; + uint8_t *p; + + /* Calculate akey length */ + akey_str_len = HDstrlen(attr->name) + 2; + akey_len = akey_str_len + sizeof(uint64_t); + + /* Allocate array of akey pointers */ + if(NULL == (akeys = (uint8_t **)H5MM_calloc(attr_size * sizeof(uint8_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey array") + + /* Allocate array of iods */ + if(NULL == (iods = (daos_iod_t *)H5MM_malloc(attr_size * sizeof(daos_iod_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for I/O descriptor array") + + /* First loop over elements, set up operation to read vl sizes */ + for(i = 0; i < attr_size; i++) { + /* Create akey for this element */ + if(NULL == (akeys[i] = (uint8_t *)H5MM_malloc(akey_len))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey") + akeys[i][0] = 'V'; + akeys[i][1] = '-'; + (void)HDstrcpy((char *)akeys[i] + 2, attr->name); + p = akeys[i] + akey_str_len; + UINT64ENCODE(p, i) + + /* Set up iod. Use "single" records of varying size. */ + HDmemset(&iods[i], 0, sizeof(iods[0])); + daos_iov_set(&iods[i].iod_name, (void *)akeys[i], (daos_size_t)akey_len); + daos_csum_set(&iods[i].iod_kcsum, NULL, 0); + iods[i].iod_nr = 1u; + iods[i].iod_size = DAOS_REC_ANY; + iods[i].iod_type = DAOS_IOD_SINGLE; + } /* end for */ - /* Set up operation to read data */ - /* Set up dkey */ - daos_iov_set(&dkey, attr_key, (daos_size_t)(sizeof(attr_key) - 1)); + /* Read vl sizes from attribute */ + /* Note cast to unsigned reduces width to 32 bits. Should eventually + * check for overflow and iterate over 2^32 size blocks */ + if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, (unsigned)attr_size, iods, NULL, NULL /*maps*/, NULL /*event*/))) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read vl data sizes from attribute: %d", ret) + + /* Allocate array of sg_iovs */ + if(NULL == (sg_iovs = (daos_iov_t *)H5MM_malloc(attr_size * sizeof(daos_iov_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for scatter gather list") + + /* Allocate array of sgls */ + if(NULL == (sgls = (daos_sg_list_t *)H5MM_malloc(attr_size * sizeof(daos_sg_list_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for scatter gather list array") + + /* Second loop over elements, set up operation to read vl data */ + for(i = 0; i < attr_size; i++) { + /* Set up constant sgl info */ + sgls[i].sg_nr.num = 1; + sgls[i].sg_iovs = &sg_iovs[i]; + + /* Check for empty element */ + if(iods[i].iod_size == 0) { + /* Increment offset, slide down following elements */ + offset++; + + /* Zero out read buffer */ + if(is_vl_str) + ((char **)buf)[i] = NULL; + else + HDmemset(&((hvl_t *)buf)[i], 0, sizeof(hvl_t)); + } /* end if */ + else { + HDassert(i >= offset); - /* Create akey string (prefix "V-") */ - akey_len = HDstrlen(attr->name) + 2; - if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey") - akey[0] = 'V'; - akey[1] = '-'; - (void)HDstrcpy(akey + 2, attr->name); + /* Check for vlen string */ + if(is_vl_str) { + char *elem = NULL; - /* Set up recx */ - recx.rx_idx = (uint64_t)0; - recx.rx_nr = attr_size; + /* Allocate buffer for this vl element */ + if(NULL == (elem = (char *)HDmalloc((size_t)iods[i].iod_size + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate vl data buffer") + ((char **)buf)[i] = elem; - /* Set up iod */ - HDmemset(&iod, 0, sizeof(iod)); - daos_iov_set(&iod.iod_name, (void *)akey, (daos_size_t)akey_len); - daos_csum_set(&iod.iod_kcsum, NULL, 0); - iod.iod_nr = 1u; - iod.iod_recxs = &recx; - iod.iod_size = (uint64_t)file_type_size; - iod.iod_type = DAOS_IOD_ARRAY; + /* Add null terminator */ + elem[iods[i].iod_size] = '\0'; - /* Set up sgl */ - daos_iov_set(&sg_iov, tconv_buf ? tconv_buf : buf, (daos_size_t)(attr_size * (uint64_t)file_type_size)); - sgl.sg_nr.num = 1; - sgl.sg_iovs = &sg_iov; + /* Set buffer location in sgl */ + daos_iov_set(&sg_iovs[i - offset], elem, iods[i].iod_size); + } /* end if */ + else { + /* Standard vlen, find hvl_t struct for this element */ + hvl_t *elem = &((hvl_t *)buf)[i]; - /* Read data from attribute */ - if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/))) - HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret) + HDassert(base_type_size > 0); - /* Perform type conversion if necessary */ - if(tconv_buf) { - /* Type conversion */ - if(H5Tconvert(attr->type_id, mem_type_id, attr_size, tconv_buf, bkg_buf, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "can't perform type conversion") + /* Allocate buffer for this vl element and set size */ + elem->len = (size_t)iods[i].iod_size / base_type_size; + if(NULL == (elem->p = HDmalloc((size_t)iods[i].iod_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate vl data buffer") + + /* Set buffer location in sgl */ + daos_iov_set(&sg_iovs[i - offset], elem->p, iods[i].iod_size); + } /* end if */ + + /* Slide down iod if necessary */ + if(offset) + iods[i - offset] = iods[i]; + } /* end else */ + } /* end for */ - /* Copy to user's buffer if necessary */ - if(buf != tconv_buf) - (void)HDmemcpy(buf, tconv_buf, (size_t)attr_size * mem_type_size); + /* Read data from attribute */ + /* Note cast to unsigned reduces width to 32 bits. Should eventually + * check for overflow and iterate over 2^32 size blocks */ + if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, (unsigned)(attr_size - offset), iods, sgls, NULL /*maps*/, NULL /*event*/))) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret) } /* end if */ + else { + daos_iod_t iod; + daos_recx_t recx; + daos_sg_list_t sgl; + daos_iov_t sg_iov; + size_t mem_type_size; + H5VL_daosm_tconv_reuse_t reuse = H5VL_DAOSM_TCONV_REUSE_NONE; + hbool_t fill_bkg = FALSE; + + /* Check for type conversion */ + if(H5VL_daosm_tconv_init(attr->type_id, &file_type_size, mem_type_id, &mem_type_size, (size_t)attr_size, &tconv_buf, &bkg_buf, &reuse, &fill_bkg) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't initialize type conversion") + + /* Reuse buffer as appropriate */ + if(reuse == H5VL_DAOSM_TCONV_REUSE_TCONV) + tconv_buf = buf; + else if(reuse == H5VL_DAOSM_TCONV_REUSE_BKG) + bkg_buf = buf; + + /* Fill background buffer if necessary */ + if(fill_bkg && (bkg_buf != buf)) + (void)HDmemcpy(bkg_buf, buf, (size_t)attr_size * mem_type_size); + + /* Set up operation to read data */ + /* Create akey string (prefix "V-") */ + akey_len = HDstrlen(attr->name) + 2; + if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey") + akey[0] = 'V'; + akey[1] = '-'; + (void)HDstrcpy(akey + 2, attr->name); + + /* Set up recx */ + recx.rx_idx = (uint64_t)0; + recx.rx_nr = attr_size; + + /* Set up iod */ + HDmemset(&iod, 0, sizeof(iod)); + daos_iov_set(&iod.iod_name, (void *)akey, (daos_size_t)akey_len); + daos_csum_set(&iod.iod_kcsum, NULL, 0); + iod.iod_nr = 1u; + iod.iod_recxs = &recx; + iod.iod_size = (uint64_t)file_type_size; + iod.iod_type = DAOS_IOD_ARRAY; + + /* Set up sgl */ + daos_iov_set(&sg_iov, tconv_buf ? tconv_buf : buf, (daos_size_t)(attr_size * (uint64_t)file_type_size)); + sgl.sg_nr.num = 1; + sgl.sg_iovs = &sg_iov; + + /* Read data from attribute */ + if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/))) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret) + + /* Perform type conversion if necessary */ + if(tconv_buf) { + /* Type conversion */ + if(H5Tconvert(attr->type_id, mem_type_id, attr_size, tconv_buf, bkg_buf, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "can't perform type conversion") + + /* Copy to user's buffer if necessary */ + if(buf != tconv_buf) + (void)HDmemcpy(buf, tconv_buf, (size_t)attr_size * mem_type_size); + } /* end if */ + } /* end else */ done: /* Free memory */ akey = (char *)H5MM_xfree(akey); + iods = (daos_iod_t *)H5MM_xfree(iods); + sgls = (daos_sg_list_t *)H5MM_xfree(sgls); + sg_iovs = (daos_iov_t *)H5MM_xfree(sg_iovs); if(tconv_buf && (tconv_buf != buf)) H5MM_free(tconv_buf); if(bkg_buf && (bkg_buf != buf)) H5MM_free(bkg_buf); + if(akeys) { + for(i = 0; i < attr_size; i++) + H5MM_xfree(akeys[i]); + H5MM_free(akeys); + } /* end if */ + + if(base_type_id != FAIL) + if(H5I_dec_app_ref(base_type_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close base type id") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_daosm_attribute_read() */ @@ -5447,19 +5606,22 @@ H5VL_daosm_attribute_write(void *_attr, hid_t H5_ATTR_UNUSED mem_type_id, size_t akey_len; daos_key_t dkey; char *akey = NULL; - daos_iod_t iod; - daos_recx_t recx; - daos_sg_list_t sgl; - daos_iov_t sg_iov; + uint8_t **akeys = NULL; + daos_iod_t *iods = NULL; + daos_sg_list_t *sgls = NULL; + daos_iov_t *sg_iovs = NULL; char attr_key[] = H5VL_DAOSM_ATTR_KEY; + hid_t base_type_id = FAIL; size_t file_type_size; - size_t mem_type_size; + size_t base_type_size = 0; uint64_t attr_size; void *tconv_buf = NULL; void *bkg_buf = NULL; - hbool_t fill_bkg = FALSE; + H5T_class_t type_class; + hbool_t is_vl = FALSE; + htri_t is_vl_str = FALSE; int ret; - int i; + uint64_t i; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT @@ -5476,79 +5638,214 @@ H5VL_daosm_attribute_write(void *_attr, hid_t H5_ATTR_UNUSED mem_type_id, /* Calculate attribute size */ attr_size = (uint64_t)1; - for(i = 0; i < ndims; i++) + for(i = 0; i < (uint64_t)ndims; i++) attr_size *= (uint64_t)dim[i]; - /* Check for type conversion */ - if(H5VL_daosm_tconv_init(mem_type_id, &mem_type_size, attr->type_id, &file_type_size, (size_t)attr_size, &tconv_buf, &bkg_buf, NULL, &fill_bkg) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't initialize type conversion") - - /* Set up operation to write data */ /* Set up dkey */ daos_iov_set(&dkey, attr_key, (daos_size_t)(sizeof(attr_key) - 1)); - /* Create akey string (prefix "V-") */ - akey_len = HDstrlen(attr->name) + 2; - if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey") - akey[0] = 'V'; - akey[1] = '-'; - (void)HDstrcpy(akey + 2, attr->name); + /* Check for vlen */ + if(H5T_NO_CLASS == (type_class = H5Tget_class(mem_type_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype class") + if(type_class == H5T_VLEN) { + is_vl = TRUE; + + /* Calculate base type size */ + if((base_type_id = H5Tget_super(mem_type_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype base type") + if(0 == (base_type_size = H5Tget_size(base_type_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype base type size") + } /* end if */ + else if(type_class == H5T_STRING) { + /* check for vlen string */ + if((is_vl_str = H5Tis_variable_str(mem_type_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for variable length string") + if(is_vl_str) + is_vl = TRUE; + } /* end if */ - /* Set up recx */ - recx.rx_idx = (uint64_t)0; - recx.rx_nr = attr_size; + /* Check for variable length */ + if(is_vl) { + size_t akey_str_len; + uint8_t *p; + + /* Calculate akey length */ + akey_str_len = HDstrlen(attr->name) + 2; + akey_len = akey_str_len + sizeof(uint64_t); + + /* Allocate array of akey pointers */ + if(NULL == (akeys = (uint8_t **)H5MM_calloc(attr_size * sizeof(uint8_t *)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey array") + + /* Allocate array of iods */ + if(NULL == (iods = (daos_iod_t *)H5MM_malloc(attr_size * sizeof(daos_iod_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for I/O descriptor array") + + /* Allocate array of sg_iovs */ + if(NULL == (sg_iovs = (daos_iov_t *)H5MM_malloc(attr_size * sizeof(daos_iov_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for scatter gather list") + + /* Allocate array of sgls */ + if(NULL == (sgls = (daos_sg_list_t *)H5MM_malloc(attr_size * sizeof(daos_sg_list_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for scatter gather list array") + + /* Loop over elements */ + for(i = 0; i < attr_size; i++) { + /* Create akey for this element */ + if(NULL == (akeys[i] = (uint8_t *)H5MM_malloc(akey_len))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey") + akeys[i][0] = 'V'; + akeys[i][1] = '-'; + (void)HDstrcpy((char *)akeys[i] + 2, attr->name); + p = akeys[i] + akey_str_len; + UINT64ENCODE(p, i) + + /* Set up iod, determine size below. Use "single" records of + * varying size. */ + HDmemset(&iods[i], 0, sizeof(iods[0])); + daos_iov_set(&iods[i].iod_name, (void *)akeys[i], (daos_size_t)akey_len); + daos_csum_set(&iods[i].iod_kcsum, NULL, 0); + iods[i].iod_nr = 1u; + iods[i].iod_type = DAOS_IOD_SINGLE; + + /* Set up constant sgl info */ + sgls[i].sg_nr.num = 1; + sgls[i].sg_iovs = &sg_iovs[i]; + + /* Check for vlen string */ + if(is_vl_str) { + /* Find string for this element */ + char *elem = ((char * const *)buf)[i]; + + /* Set string length in iod and buffer location in sgl. If we + * are writing an empty string ("\0"), increase the size by one + * to differentiate it from NULL strings. Note that this will + * cause the read buffer to be one byte longer than it needs to + * be in this case. This should not cause any ill effects. */ + if(elem) { + iods[i].iod_size = (daos_size_t)HDstrlen(elem); + if(iods[i].iod_size == 0) + iods[i].iod_size = 1; + daos_iov_set(&sg_iovs[i], (void *)elem, iods[i].iod_size); + } /* end if */ + else { + iods[i].iod_size = 0; + daos_iov_set(&sg_iovs[i], NULL, 0); + } /* end else */ + } /* end if */ + else { + /* Standard vlen, find hvl_t struct for this element */ + const hvl_t *elem = &((const hvl_t *)buf)[i]; - /* Set up iod */ - HDmemset(&iod, 0, sizeof(iod)); - daos_iov_set(&iod.iod_name, (void *)akey, (daos_size_t)akey_len); - daos_csum_set(&iod.iod_kcsum, NULL, 0); - iod.iod_nr = 1u; - iod.iod_recxs = &recx; - iod.iod_size = (uint64_t)file_type_size; - iod.iod_type = DAOS_IOD_ARRAY; + HDassert(base_type_size > 0); - /* Set up constant sgl info */ - sgl.sg_nr.num = 1; - sgl.sg_iovs = &sg_iov; + /* Set buffer length in iod and buffer location in sgl */ + if(elem->len > 0) { + iods[i].iod_size = (daos_size_t)(elem->len * base_type_size); + daos_iov_set(&sg_iovs[i], (void *)elem->p, iods[i].iod_size); + } /* end if */ + else { + iods[i].iod_size = 0; + daos_iov_set(&sg_iovs[i], NULL, 0); + } /* end else */ + } /* end if */ + } /* end for */ - /* Check for type conversion */ - if(tconv_buf) { - /* Check if we need to fill background buffer */ - if(fill_bkg) { - HDassert(bkg_buf); + /* Write data to attribute */ + /* Note cast to unsigned reduces width to 32 bits. Should eventually + * check for overflow and iterate over 2^32 size blocks */ + if(0 != (ret = daos_obj_update(attr->parent->obj_oh, attr->item.file->epoch, &dkey, (unsigned)attr_size, iods, sgls, NULL /*event*/))) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't write data to attribute: %d", ret) + } /* end if */ + else { + daos_iod_t iod; + daos_recx_t recx; + daos_sg_list_t sgl; + daos_iov_t sg_iov; + size_t mem_type_size; + hbool_t fill_bkg = FALSE; - /* Read data from attribute to background buffer */ - daos_iov_set(&sg_iov, bkg_buf, (daos_size_t)(attr_size * (uint64_t)file_type_size)); + /* Check for type conversion */ + if(H5VL_daosm_tconv_init(mem_type_id, &mem_type_size, attr->type_id, &file_type_size, (size_t)attr_size, &tconv_buf, &bkg_buf, NULL, &fill_bkg) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't initialize type conversion") - if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/))) - HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret) - } /* end if */ + /* Set up operation to write data */ + /* Create akey string (prefix "V-") */ + akey_len = HDstrlen(attr->name) + 2; + if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey") + akey[0] = 'V'; + akey[1] = '-'; + (void)HDstrcpy(akey + 2, attr->name); - /* Copy data to type conversion buffer */ - (void)HDmemcpy(tconv_buf, buf, (size_t)attr_size * mem_type_size); + /* Set up recx */ + recx.rx_idx = (uint64_t)0; + recx.rx_nr = attr_size; - /* Perform type conversion */ - if(H5Tconvert(mem_type_id, attr->type_id, attr_size, tconv_buf, bkg_buf, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "can't perform type conversion") + /* Set up iod */ + HDmemset(&iod, 0, sizeof(iod)); + daos_iov_set(&iod.iod_name, (void *)akey, (daos_size_t)akey_len); + daos_csum_set(&iod.iod_kcsum, NULL, 0); + iod.iod_nr = 1u; + iod.iod_recxs = &recx; + iod.iod_size = (uint64_t)file_type_size; + iod.iod_type = DAOS_IOD_ARRAY; - /* Set sgl to write from tconv_buf */ - daos_iov_set(&sg_iov, tconv_buf, (daos_size_t)(attr_size * (uint64_t)file_type_size)); - } /* end if */ - else - /* Set sgl to write from buf */ - daos_iov_set(&sg_iov, (void *)buf, (daos_size_t)(attr_size * (uint64_t)file_type_size)); + /* Set up constant sgl info */ + sgl.sg_nr.num = 1; + sgl.sg_iovs = &sg_iov; + + /* Check for type conversion */ + if(tconv_buf) { + /* Check if we need to fill background buffer */ + if(fill_bkg) { + HDassert(bkg_buf); + + /* Read data from attribute to background buffer */ + daos_iov_set(&sg_iov, bkg_buf, (daos_size_t)(attr_size * (uint64_t)file_type_size)); - /* Write data to attribute */ - if(0 != (ret = daos_obj_update(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*event*/))) - HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't write data to attribute: %d", ret) + if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/))) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret) + } /* end if */ + + /* Copy data to type conversion buffer */ + (void)HDmemcpy(tconv_buf, buf, (size_t)attr_size * mem_type_size); + + /* Perform type conversion */ + if(H5Tconvert(mem_type_id, attr->type_id, attr_size, tconv_buf, bkg_buf, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "can't perform type conversion") + + /* Set sgl to write from tconv_buf */ + daos_iov_set(&sg_iov, tconv_buf, (daos_size_t)(attr_size * (uint64_t)file_type_size)); + } /* end if */ + else + /* Set sgl to write from buf */ + daos_iov_set(&sg_iov, (void *)buf, (daos_size_t)(attr_size * (uint64_t)file_type_size)); + + /* Write data to attribute */ + if(0 != (ret = daos_obj_update(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*event*/))) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't write data to attribute: %d", ret) + } /* end else */ done: /* Free memory */ akey = (char *)H5MM_xfree(akey); + iods = (daos_iod_t *)H5MM_xfree(iods); + sgls = (daos_sg_list_t *)H5MM_xfree(sgls); + sg_iovs = (daos_iov_t *)H5MM_xfree(sg_iovs); tconv_buf = H5MM_xfree(tconv_buf); bkg_buf = H5MM_xfree(bkg_buf); + if(akeys) { + for(i = 0; i < attr_size; i++) + H5MM_xfree(akeys[i]); + H5MM_free(akeys); + } /* end if */ + + if(base_type_id != FAIL) + if(H5I_dec_app_ref(base_type_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close base type id") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_daosm_attribute_write() */ @@ -5673,7 +5970,7 @@ H5VL_daosm_attribute_specific(void *_item, H5VL_loc_params_t loc_params, { H5VL_daosm_item_t *item = (H5VL_daosm_item_t *)_item; H5VL_daosm_obj_t *target_obj = NULL; - hid_t target_obj_id = -1; + hid_t target_obj_id = FAIL; char *akey_buf = NULL; size_t akey_buf_len = 0; H5VL_daosm_attr_t *attr = NULL; @@ -5862,10 +6159,10 @@ H5VL_daosm_attribute_specific(void *_item, H5VL_loc_params_t loc_params, } /* end switch */ done: - if(target_obj_id >= 0) { + if(target_obj_id != FAIL) { if(H5I_dec_app_ref(target_obj_id) < 0) HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close object id") - target_obj_id = -1; + target_obj_id = FAIL; target_obj = NULL; } /* end if */ else if(target_obj) { diff --git a/src/H5VLint.c b/src/H5VLint.c index 4dcc095..fda58fa 100644 --- a/src/H5VLint.c +++ b/src/H5VLint.c @@ -378,8 +378,9 @@ H5VL_object(hid_t id) /* Get the symbol table entry */ switch(H5I_get_type(id)) { case H5I_GROUP: + case H5I_MAP: case H5I_DATASET: - case H5I_FILE: + case H5I_FILE: case H5I_ATTR: /* get the object */ if(NULL == (obj = (H5VL_object_t *)H5I_object(id))) @@ -447,8 +448,9 @@ H5VL_object_verify(hid_t id, H5I_type_t obj_type) /* Get the symbol table entry */ switch(obj_type) { case H5I_GROUP: + case H5I_MAP: case H5I_DATASET: - case H5I_FILE: + case H5I_FILE: case H5I_ATTR: /* get the object */ if(NULL == (obj = (H5VL_object_t *)H5I_object_verify(id, obj_type))) -- cgit v0.12