summaryrefslogtreecommitdiffstats
path: root/src/H5VLdaosm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5VLdaosm.c')
-rw-r--r--src/H5VLdaosm.c501
1 files changed, 455 insertions, 46 deletions
diff --git a/src/H5VLdaosm.c b/src/H5VLdaosm.c
index de5bdf6..bedba85 100644
--- a/src/H5VLdaosm.c
+++ b/src/H5VLdaosm.c
@@ -25,9 +25,12 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5Fprivate.h" /* Files */
#include "H5FDprivate.h" /* File drivers */
+#include "H5FFprivate.h" /* Fast Forward */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspaces */
+#include "H5TRprivate.h" /* Transactions */
#include "H5VLprivate.h" /* VOL plugins */
#include "H5VLdaosm.h" /* DAOS-M plugin */
@@ -43,6 +46,21 @@ static void *H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_i
//static herr_t H5VL_iod_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
static herr_t H5VL_daosm_file_close(void *file, hid_t dxpl_id, void **req);
+/* Group callbacks */
+static herr_t H5VL_daosm_group_close(void *grp, hid_t dxpl_id, void **req);
+
+/* Dataset callbacks */
+static void *H5VL_daosm_dataset_create(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_daosm_dataset_open(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
+/*static herr_t H5VL_daosm_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t plist_id, void *buf, void **req);
+static herr_t H5VL_daosm_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t plist_id, const void *buf, void **req);
+static herr_t H5VL_daosm_dataset_specific(void *_dset, H5VL_dataset_specific_t specific_type,
+ hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_daosm_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);*/
+static herr_t H5VL_daosm_dataset_close(void *dt, hid_t dxpl_id, void **req);
+
/* DAOSM-specific file access properties */
typedef struct H5VL_daosm_fapl_t {
MPI_Comm comm; /*communicator */
@@ -53,6 +71,8 @@ typedef struct H5VL_daosm_fapl_t {
/* Free list definitions */
H5FL_DEFINE(H5VL_daosm_file_t);
+H5FL_DEFINE(H5VL_daosm_group_t);
+H5FL_DEFINE(H5VL_daosm_dset_t);
/* The DAOS-M VOL plugin struct */
static H5VL_class_t H5VL_daosm_g = {
@@ -75,14 +95,14 @@ static H5VL_class_t H5VL_daosm_g = {
NULL,//H5VL_iod_attribute_close /* close */
},
{ /* dataset_cls */
- NULL,//H5VL_iod_dataset_create, /* create */
- NULL,//H5VL_iod_dataset_open, /* open */
+ H5VL_daosm_dataset_create, /* create */
+ H5VL_daosm_dataset_open, /* open */
NULL,//H5VL_iod_dataset_read, /* read */
NULL,//H5VL_iod_dataset_write, /* write */
NULL,//H5VL_iod_dataset_get, /* get */
NULL,//H5VL_iod_dataset_specific, /* specific */
NULL, /* optional */
- NULL,//H5VL_iod_dataset_close /* close */
+ H5VL_daosm_dataset_close /* close */
},
{ /* datatype_cls */
NULL,//H5VL_iod_datatype_commit, /* commit */
@@ -480,8 +500,8 @@ H5VL_daosm_hash128(const char *name, void *hash)
*-------------------------------------------------------------------------
*/
static void *
-H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
- hid_t H5_ATTR_UNUSED dxpl_id, void **req)
+H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id,
+ hid_t fapl_id, hid_t dxpl_id, void **req)
{
H5VL_daosm_fapl_t *fa = NULL;
H5P_genplist_t *plist = NULL; /* Property list pointer */
@@ -490,6 +510,7 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa
daos_iov_t glob;
uint64_t gh_sizes[2];
char *gh_buf = NULL;
+ daos_obj_id_t oid = {0, 0, 0};
hbool_t must_bcast = FALSE;
int ret;
void *ret_value = NULL;
@@ -515,10 +536,16 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa
if(NULL == (file = H5FL_CALLOC(H5VL_daosm_file_t)))
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate DAOS-M file struct");
file->glob_md_oh = DAOS_HDL_INVAL;
- file->root_oh = DAOS_HDL_INVAL;
+ file->root_grp = NULL;
file->fcpl_id = FAIL;
file->fapl_id = FAIL;
+ /* allocate the root group */
+ if(NULL == (file->root_grp = H5FL_CALLOC(H5VL_daosm_group_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate root group");
+ file->root_grp->obj_oh = DAOS_HDL_INVAL;
+ file->root_grp->gapl_id = FAIL;
+
MPI_Comm_rank(fa->comm, &file->my_rank);
MPI_Comm_size(fa->comm, &file->num_procs);
@@ -527,7 +554,6 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa
if(file->my_rank == 0) {
daos_epoch_state_t epoch_state;
- daos_obj_id_t oid = {0, 0, 0};
/* If there are other processes and we fail we must bcast anyways so they
* don't hang */
@@ -535,6 +561,7 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa
must_bcast = TRUE;
/* Connect to the pool */
+ /* TODO: move pool handling to startup/shutdown routines DSMINC */
if(0 != (ret = daos_pool_connect(fa->pool_uuid, NULL/*fa->pool_grp DSMINC*/, NULL /*pool_svc*/, DAOS_PC_RW, &file->poh, NULL /*&file->pool_info*/, NULL /*event*/)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't connect to pool: %d", ret)
@@ -571,27 +598,18 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa
if(0 != (ret = daos_obj_declare(file->coh, oid, 0, NULL /*oa*/, NULL /*event*/)))
HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, "can't create global metadata object: %d", ret)
- /* Open global metadata object */
- if(0 != (ret = daos_obj_open(file->glob_md_oh, oid, 0, DAOS_OO_EXCL, &file->glob_md_oh, NULL /*event*/)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open global metadata object: %d", ret)
-
/* Create root group */
- HDmemset(&oid, 0, sizeof(oid));
- oid.lo = 1;
- daos_obj_id_generate(&oid, DAOS_OC_TINY_RW);
- if(0 != (ret = daos_obj_declare(file->coh, oid, epoch, NULL /*oa*/, NULL /*event*/)))
+ file->root_grp->oid.lo = 1;
+ daos_obj_id_generate(&file->root_grp->oid, DAOS_OC_TINY_RW);
+ if(0 != (ret = daos_obj_declare(file->coh, file->root_grp->oid, epoch, NULL /*oa*/, NULL /*event*/)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create root group: %d", ret)
/* Open root group */
- if(0 != (ret = daos_obj_open(file->root_oh, oid, epoch, DAOS_OO_RW, &file->root_oh, NULL /*event*/)))
+ if(0 != (ret = daos_obj_open(file->coh, file->root_grp->oid, epoch, DAOS_OO_RW, &file->root_grp->obj_oh, NULL /*event*/)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't open root group: %d", ret)
/* Write root group OID to global metadata object DSMINC */
- /* Flush the epoch */
- if(0 != (ret = daos_epoch_flush(file->coh, epoch, NULL /*state*/, NULL /*event*/)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, NULL, "can't flush epoch: %d", ret)
-
/* Bcast global handles if there are other processes */
if(file->num_procs > 1) {
/* Calculate sizes of global pool and container handles */
@@ -672,16 +690,25 @@ H5VL_daosm_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fa
if(0 != (ret = daos_cont_global2local(file->poh, glob, &file->coh)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't get local container handle: %d", ret)
- /* Leave global md object and root group handles empty for now */
+ /* Leave root group handle empty for now */
/* Handle pool_info and container_info DSMINC */
} /* end else */
+ /* Open global metadata object */
+ if(0 != (ret = daos_obj_open(file->glob_md_oh, oid, 0, DAOS_OO_RW, &file->glob_md_oh, NULL /*event*/)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open global metadata object: %d", ret)
+
/* Finish setting up file struct */
+ file->common.type = H5I_FILE;
+ file->common.file = file;
file->file_name = HDstrdup(name);
file->flags = flags;
- HDmemset(&file->max_oid, 0, sizeof(file->max_oid));
- file->max_oid.lo = 1;
+ file->root_grp->common.type = H5I_GROUP;
+ file->root_grp->common.file = file;
+ if((file->root_grp->gapl_id = H5Pcopy(H5P_GROUP_ACCESS_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy default gapl");
+ file->max_oid = 1;
if((file->fcpl_id = H5Pcopy(fcpl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fcpl");
if((file->fapl_id = H5Pcopy(fapl_id)) < 0)
@@ -697,8 +724,8 @@ done:
/* Clean up */
H5MM_xfree(gh_buf);
- /* If the operation is synchronous and it failed at the server, or
- it failed locally, then cleanup and return fail */
+ /* If the operation is synchronous and it failed at the server, or it failed
+ * locally, then cleanup and return fail */
if(NULL == ret_value) {
/* Bcast gh_sizes as '0' if necessary - this will trigger failures in
* the other processes so we do not need to do the second bcast. */
@@ -732,8 +759,8 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id,
- hid_t dxpl_id, void **req)
+H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id,
+ hid_t dxpl_id, void **req)
{
H5VL_daosm_fapl_t *fa = NULL;
H5P_genplist_t *plist = NULL; /* Property list pointer */
@@ -742,6 +769,7 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id,
daos_iov_t glob;
uint64_t gh_sizes[2];
char *gh_buf = NULL;
+ daos_obj_id_t oid = {0, 0, 0};
hbool_t must_bcast = FALSE;
int ret;
void *ret_value = NULL;
@@ -758,10 +786,16 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id,
if(NULL == (file = H5FL_CALLOC(H5VL_daosm_file_t)))
HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate IOD file struct");
file->glob_md_oh = DAOS_HDL_INVAL;
- file->root_oh = DAOS_HDL_INVAL;
+ file->root_grp = NULL;
file->fcpl_id = FAIL;
file->fapl_id = FAIL;
+ /* allocate the root group */
+ if(NULL == (file->root_grp = H5FL_CALLOC(H5VL_daosm_group_t)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate root group");
+ file->root_grp->obj_oh = DAOS_HDL_INVAL;
+ file->root_grp->gapl_id = FAIL;
+
MPI_Comm_rank(fa->comm, &file->my_rank);
MPI_Comm_size(fa->comm, &file->num_procs);
@@ -770,7 +804,6 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id,
if(file->my_rank == 0) {
daos_epoch_state_t epoch_state;
- daos_obj_id_t oid = {0, 0, 0};
/* If there are other processes and we fail we must bcast anyways so they
* don't hang */
@@ -794,17 +827,11 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id,
if(0 != (ret = daos_epoch_hold(file->coh, &epoch, NULL /*state*/, NULL /*event*/)))
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't hold epoch: %d", ret)
- /* Open global metadata object */
- daos_obj_id_generate(&oid, DAOS_OC_REPLICA_RW);
- if(0 != (ret = daos_obj_open(file->glob_md_oh, oid, 0, DAOS_OO_EXCL, &file->glob_md_oh, NULL /*event*/)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open global metadata object: %d", ret)
-
/* Open root group */
/* Read root group OID from global metadata object DSMINC */
- HDmemset(&oid, 0, sizeof(oid));
- oid.lo = 1;
- daos_obj_id_generate(&oid, DAOS_OC_TINY_RW);
- if(0 != (ret = daos_obj_open(file->root_oh, oid, epoch, DAOS_OO_RW, &file->root_oh, NULL /*event*/)))
+ file->root_grp->oid.lo = 1;
+ daos_obj_id_generate(&file->root_grp->oid, DAOS_OC_TINY_RW);
+ if(0 != (ret = daos_obj_open(file->coh, file->root_grp->oid, epoch, DAOS_OO_RW, &file->root_grp->obj_oh, NULL /*event*/)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't open root group: %d", ret)
/* Bcast global handles if there are other processes */
@@ -882,16 +909,27 @@ H5VL_daosm_file_open(const char *name, unsigned flags, hid_t fapl_id,
if(0 != (ret = daos_cont_global2local(file->poh, glob, &file->coh)))
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't get local container handle: %d", ret)
- /* Leave global md object and root group handles empty for now */
+ /* Leave root group handle empty for now */
/* Handle pool_info and container_info DSMINC */
} /* end else */
+ /* Open global metadata object */
+ daos_obj_id_generate(&oid, DAOS_OC_REPLICA_RW);
+ if(0 != (ret = daos_obj_open(file->glob_md_oh, oid, 0, DAOS_OO_RW, &file->glob_md_oh, NULL /*event*/)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open global metadata object: %d", ret)
+
/* Finish setting up file struct */
+ file->common.type = H5I_FILE;
+ file->common.file = file;
file->file_name = HDstrdup(name);
file->flags = flags;
+ file->root_grp->common.type = H5I_GROUP;
+ file->root_grp->common.file = file;
+ if((file->root_grp->gapl_id = H5Pcopy(H5P_GROUP_ACCESS_DEFAULT)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy default gapl");
HDmemset(&file->max_oid, 0, sizeof(file->max_oid));
- file->max_oid.lo = 1;
+ file->max_oid = 1;
if((file->fapl_id = H5Pcopy(fapl_id)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy fapl");
@@ -905,8 +943,8 @@ done:
/* Clean up buffer */
H5MM_xfree(gh_buf);
- /* If the operation is synchronous and it failed at the server, or
- it failed locally, then cleanup and return fail */
+ /* If the operation is synchronous and it failed at the server, or it failed
+ * locally, then cleanup and return fail */
if(NULL == ret_value) {
/* Bcast gh_sizes as '0' if necessary - this will trigger failures in
* the other processes so we do not need to do the second bcast. */
@@ -940,7 +978,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5VL_daosm_file_close(void *_file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req)
+H5VL_daosm_file_close(void *_file, hid_t dxpl_id, void **req)
{
H5VL_daosm_file_t *file = (H5VL_daosm_file_t *)_file;
daos_handle_t hdl_inval = DAOS_HDL_INVAL;
@@ -951,6 +989,12 @@ H5VL_daosm_file_close(void *_file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UN
HDassert(file);
+#if 0 /* DSMINC */
+ /* Flush the epoch */
+ if(0 != (ret = daos_epoch_flush(file->coh, epoch, NULL /*state*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, NULL, "can't flush epoch: %d", ret)
+#endif
+
/* Free file data structures */
if(file->file_name)
HDfree(file->file_name);
@@ -964,9 +1008,9 @@ H5VL_daosm_file_close(void *_file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UN
if(HDmemcmp(&file->glob_md_oh, &hdl_inval, sizeof(hdl_inval)))
if(0 != (ret = daos_obj_close(file->glob_md_oh, NULL /*event*/)))
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close global metadata object: %d", ret)
- if(HDmemcmp(&file->root_oh, &hdl_inval, sizeof(hdl_inval)))
- if(0 != (ret = daos_obj_close(file->root_oh, NULL /*event*/)))
- HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close root group: %d", ret)
+ if(file->root_grp)
+ if(H5VL_daosm_group_close(file->root_grp, dxpl_id, req) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close root group")
if(HDmemcmp(&file->coh, &hdl_inval, sizeof(hdl_inval)))
if(0 != (ret = daos_cont_close(file->coh, NULL /*event*/)))
HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "can't close container: %d", ret)
@@ -978,3 +1022,368 @@ H5VL_daosm_file_close(void *_file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UN
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_daosm_file_close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daosm_group_close
+ *
+ * Purpose: Closes a daos-m HDF5 group.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Neil Fortner
+ * November, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_daosm_group_close(void *_grp, hid_t H5_ATTR_UNUSED dxpl_id,
+ void H5_ATTR_UNUSED **req)
+{
+ H5VL_daosm_group_t *grp = (H5VL_daosm_group_t *)_grp;
+ daos_handle_t hdl_inval = DAOS_HDL_INVAL;
+ int ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(grp);
+
+ /* Free group data structures */
+ if(grp->gapl_id != FAIL && H5I_dec_ref(grp->gapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(HDmemcmp(&grp->obj_oh, &hdl_inval, sizeof(hdl_inval)))
+ if(0 != (ret = daos_obj_close(grp->obj_oh, NULL /*event*/)))
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close group object: %d", ret)
+ grp = H5FL_FREE(H5VL_daosm_group_t, grp);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_group_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daosm_dataset_create
+ *
+ * Purpose: Sends a request to DAOS-M to create a dataset
+ *
+ * Return: Success: dataset object.
+ * Failure: NULL
+ *
+ * Programmer: Neil Fortner
+ * November, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_daosm_dataset_create(void *_obj,
+ H5VL_loc_params_t H5_ATTR_UNUSED loc_params, const char *name,
+ hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_daosm_obj_t *obj = (H5VL_daosm_obj_t *)_obj;
+ H5VL_daosm_dset_t *dset = NULL;
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ hid_t type_id, space_id;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5VL_daosm_group_t *target_grp = NULL;
+ const char *target_name = NULL;
+ size_t target_name_len;
+ char const_key[4] = {'L', 'i', 'n', 'k'};
+ daos_dkey_t dkey;
+ daos_vec_iod_t iod;
+ daos_recx_t recx;
+ daos_sg_list_t sgl;
+ daos_iov_t sg_iov;
+ uint8_t oid_buf[24];
+ uint8_t *p;
+ int ret;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Get the dcpl plist structure */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+
+ /* get creation properties */
+ if(H5P_get(plist, H5VL_PROP_DSET_TYPE_ID, &type_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id")
+ if(H5P_get(plist, H5VL_PROP_DSET_SPACE_ID, &space_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id")
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID")
+
+ /* Traverse the path */
+ /* Just use obj for now DSMINC */
+ if(obj->type == H5I_FILE)
+ target_grp = ((H5VL_daosm_file_t *)obj)->root_grp;
+ else
+ target_grp = (H5VL_daosm_group_t *)obj;
+ target_name = name;
+ target_name_len = HDstrlen(target_name);
+
+ /* Allocate the dataset object that is returned to the user */
+ if(NULL == (dset = H5FL_CALLOC(H5VL_daosm_dset_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate IOD dataset struct");
+ dset->obj_oh = DAOS_HDL_INVAL;
+ dset->type_id = FAIL;
+ dset->space_id = FAIL;
+ dset->dcpl_id = FAIL;
+ dset->dapl_id = FAIL;
+
+ /* Create dataset */
+ dset->oid.lo = obj->file->max_oid;
+ daos_obj_id_generate(&dset->oid, DAOS_OC_LARGE_RW);
+ if(0 != (ret = daos_obj_declare(obj->file->coh, dset->oid, tr->epoch, NULL /*oa*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create dataset: %d", ret)
+ obj->file->max_oid = dset->oid.lo + (uint64_t)1;
+ obj->file->max_oid_dirty = TRUE;
+
+ /* Set up dkey */
+ /* For now always use dkey = const, akey = name. Add option to switch these
+ * DSMINC */
+ dkey.iov_buf_len = dkey.iov_len = sizeof(const_key);
+ dkey.iov_buf = const_key;
+
+ /* Set up recx */
+ recx.rx_rsize = (uint64_t)sizeof(daos_obj_id_t);
+ recx.rx_idx = (uint64_t)0;
+ recx.rx_nr = (uint64_t)0;
+ recx.rx_cookie = (uint64_t)0;
+
+ /* Set up iod */
+ HDmemset(&iod, 0, sizeof(iod));
+ daos_iov_set(&iod.vd_name, (void *)target_name, (daos_size_t)target_name_len);
+ iod.vd_nr = 1u;
+ iod.vd_recxs = &recx;
+
+ /* Encode dset oid */
+ HDassert(sizeof(oid_buf) == sizeof(dset->oid));
+ p = oid_buf;
+ UINT64ENCODE(p, dset->oid.lo)
+ UINT64ENCODE(p, dset->oid.mid)
+ UINT64ENCODE(p, dset->oid.hi)
+
+ /* Set up sgl */
+ daos_iov_set(&sg_iov, oid_buf, (daos_size_t)sizeof(oid_buf));
+ sgl.sg_nr.num = 1;
+ sgl.sg_nr.num_out = 0;
+ sgl.sg_iovs = &sg_iov;
+
+ /* Create link to dataset */
+ if(0 != (ret = daos_obj_update(target_grp->obj_oh, tr->epoch, &dkey, 1, &iod, &sgl, NULL /*event*/)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create link to dataset: %d", ret)
+
+ /* Open dataset */
+ if(0 != (ret = daos_obj_open(obj->file->coh, dset->oid, tr->epoch, DAOS_OO_RW, &dset->obj_oh, NULL /*event*/)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't open root group: %d", ret)
+
+ /* Write datatype, dataspace, dcpl DSMINC */
+
+ /* Finish setting up dataset struct */
+ dset->common.type = H5I_DATASET;
+ dset->common.file = obj->file;
+ if((dset->type_id = H5Tcopy(type_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy datatype");
+ if((dset->space_id = H5Scopy(space_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dataspace");
+ if((dset->dcpl_id = H5Pcopy(dcpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dcpl");
+ if((dset->dapl_id = H5Pcopy(dapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl");
+
+ ret_value = (void *)dset;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or it failed
+ * locally, then cleanup and return fail */
+ /* Destroy DAOS object if created before failure DSMINC */
+ if(NULL == ret_value)
+ /* Close dataset */
+ if(dset != NULL && H5VL_daosm_dataset_close(dset, dxpl_id, req) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "can't close dataset")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_dataset_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daosm_dataset_open
+ *
+ * Purpose: Sends a request to DAOS-M to open a dataset
+ *
+ * Return: Success: dataset object.
+ * Failure: NULL
+ *
+ * Programmer: Neil Fortner
+ * November, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_daosm_dataset_open(void *_obj,
+ H5VL_loc_params_t H5_ATTR_UNUSED loc_params, const char *name,
+ hid_t dapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_daosm_obj_t *obj = (H5VL_daosm_obj_t *)_obj;
+ H5VL_daosm_dset_t *dset = NULL;
+ H5P_genplist_t *plist = NULL; /* Property list pointer */
+ hid_t type_id, space_id;
+ hid_t trans_id;
+ H5TR_t *tr = NULL;
+ H5VL_daosm_group_t *target_grp = NULL;
+ const char *target_name = NULL;
+ size_t target_name_len;
+ char const_key[4] = {'L', 'i', 'n', 'k'};
+ daos_dkey_t dkey;
+ daos_vec_iod_t iod;
+ daos_recx_t recx;
+ daos_sg_list_t sgl;
+ daos_iov_t sg_iov;
+ uint8_t oid_buf[24];
+ uint8_t *p;
+ int ret;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the transaction ID */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID");
+ if(H5P_get(plist, H5VL_TRANS_ID, &trans_id) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for trans_id");
+
+ /* get the TR object */
+ if(NULL == (tr = (H5TR_t *)H5I_object_verify(trans_id, H5I_TR)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "not a Transaction ID")
+
+ /* Traverse the path */
+ /* Just use obj for now DSMINC */
+ if(obj->type == H5I_FILE)
+ target_grp = ((H5VL_daosm_file_t *)obj)->root_grp;
+ else
+ target_grp = (H5VL_daosm_group_t *)obj;
+ target_name = name;
+ target_name_len = HDstrlen(target_name);
+
+ /* Allocate the dataset object that is returned to the user */
+ if(NULL == (dset = H5FL_CALLOC(H5VL_daosm_dset_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate IOD dataset struct");
+ dset->obj_oh = DAOS_HDL_INVAL;
+ dset->type_id = FAIL;
+ dset->space_id = FAIL;
+ dset->dcpl_id = FAIL;
+ dset->dapl_id = FAIL;
+
+ /* Set up dkey */
+ /* For now always use dkey = const, akey = name. Add option to switch these
+ * DSMINC */
+ dkey.iov_buf_len = dkey.iov_len = sizeof(const_key);
+ dkey.iov_buf = const_key;
+
+ /* Set up recx */
+ recx.rx_rsize = (uint64_t)sizeof(daos_obj_id_t);
+ recx.rx_idx = (uint64_t)0;
+ recx.rx_nr = (uint64_t)0;
+ recx.rx_cookie = (uint64_t)0;
+
+ /* Set up iod */
+ HDmemset(&iod, 0, sizeof(iod));
+ daos_iov_set(&iod.vd_name, (void *)target_name, (daos_size_t)target_name_len);
+ iod.vd_nr = 1u;
+ iod.vd_recxs = &recx;
+
+ /* Set up sgl */
+ daos_iov_set(&sg_iov, oid_buf, (daos_size_t)sizeof(oid_buf));
+ sgl.sg_nr.num = 1;
+ sgl.sg_nr.num_out = 0;
+ sgl.sg_iovs = &sg_iov;
+
+ /* Read link to dataset */
+ if(0 != (ret = daos_obj_fetch(target_grp->obj_oh, tr->epoch, &dkey, 1, &iod, &sgl, NULL /*maps */, NULL /*event*/)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't read link to dataset: %d", ret)
+
+ /* Decode dset oid */
+ HDassert(sizeof(oid_buf) == sizeof(dset->oid));
+ p = oid_buf;
+ UINT64DECODE(p, dset->oid.lo)
+ UINT64DECODE(p, dset->oid.mid)
+ UINT64DECODE(p, dset->oid.hi)
+
+ /* Open dataset */
+ if(0 != (ret = daos_obj_open(obj->file->coh, dset->oid, tr->epoch, DAOS_OO_RW, &dset->obj_oh, NULL /*event*/)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, NULL, "can't open root group: %d", ret)
+
+ /* Read datatype, dataspace, dcpl DSMINC */
+
+ /* Finish setting up dataset struct */
+ dset->common.type = H5I_DATASET;
+ dset->common.file = obj->file;
+ if((dset->dapl_id = H5Pcopy(dapl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy dapl");
+
+ ret_value = (void *)dset;
+
+done:
+ /* If the operation is synchronous and it failed at the server, or it failed
+ * locally, then cleanup and return fail */
+ if(NULL == ret_value)
+ /* Close dataset */
+ if(dset != NULL && H5VL_daosm_dataset_close(dset, dxpl_id, req) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "can't close dataset")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_dataset_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daosm_dataset_close
+ *
+ * Purpose: Closes a daos-m HDF5 dataset.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Neil Fortner
+ * November, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_daosm_dataset_close(void *_dset, hid_t H5_ATTR_UNUSED dxpl_id,
+ void H5_ATTR_UNUSED **req)
+{
+ H5VL_daosm_dset_t *dset = (H5VL_daosm_dset_t *)_dset;
+ daos_handle_t hdl_inval = DAOS_HDL_INVAL;
+ int ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(dset);
+
+ /* Free dataset data structures */
+ if(HDmemcmp(&dset->obj_oh, &hdl_inval, sizeof(hdl_inval)))
+ if(0 != (ret = daos_obj_close(dset->obj_oh, NULL /*event*/)))
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close dataset DAOS object: %d", ret)
+ if(dset->type_id != FAIL && H5I_dec_ref(dset->type_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close datatype");
+ if(dset->space_id != FAIL && H5I_dec_ref(dset->space_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close dataspace");
+ if(dset->dcpl_id != FAIL && H5I_dec_ref(dset->dcpl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ if(dset->dapl_id != FAIL && H5I_dec_ref(dset->dapl_id) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "failed to close plist");
+ dset = H5FL_FREE(H5VL_daosm_dset_t, dset);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_file_close() */
+