From fa6fdde1bfb8a29cfc86a4b441c49a63f15fd109 Mon Sep 17 00:00:00 2001 From: Jerome Soumagne Date: Thu, 19 Sep 2019 14:55:03 -0500 Subject: Fix H5VL_blob_get to return size of blob Fix const in blob API Add H5HG_HEAP_ID_SIZE macro to return native blob size Add maximum size for blobs Fix blob API callbacks to pass VOL file object Add public wrappers for blob VOL API Implement passthrough blob callbacks Update H5Tvlen after callback changes Update trace information for H5VL blob routines Fix public header inclusion in native and passthru headers --- bin/trace | 1 + src/H5HGprivate.h | 4 + src/H5Tvlen.c | 69 +++++++++-- src/H5VLcallback.c | 288 ++++++++++++++++++++++++++++++++++++++----- src/H5VLconnector.h | 10 +- src/H5VLconnector_passthru.h | 5 + src/H5VLnative.c | 2 +- src/H5VLnative.h | 4 +- src/H5VLnative_blob.c | 71 ++++------- src/H5VLnative_private.h | 7 +- src/H5VLpassthru.c | 92 +++++++++++++- src/H5VLpassthru.h | 3 + src/H5VLprivate.h | 9 +- src/H5trace.c | 29 +++++ 14 files changed, 490 insertions(+), 104 deletions(-) diff --git a/bin/trace b/bin/trace index 54b6f8f..fe0443d 100755 --- a/bin/trace +++ b/bin/trace @@ -99,6 +99,7 @@ $Source = ""; "unsigned long long" => "UL", "H5VL_attr_get_t" => "Va", "H5VL_attr_specific_t" => "Vb", + "H5VL_blob_specific_t" => "VB", "H5VL_class_value_t" => "VC", "H5VL_dataset_get_t" => "Vc", "H5VL_dataset_specific_t" => "Vd", diff --git a/src/H5HGprivate.h b/src/H5HGprivate.h index 1c609e2..4841847 100644 --- a/src/H5HGprivate.h +++ b/src/H5HGprivate.h @@ -49,6 +49,10 @@ typedef struct H5HG_heap_t H5HG_heap_t; #define H5HG_FREE_SIZE(H) (H5HG_get_free_size(H)) #endif /* H5HG_MODULE */ +/* Size of encoded global heap ID */ +/* (size of file address + 32-bit integer) */ +#define H5HG_HEAP_ID_SIZE(F) ((size_t)H5F_SIZEOF_ADDR(F) + H5_SIZEOF_UINT32_T) + /* Main global heap routines */ H5_DLL herr_t H5HG_insert(H5F_t *f, size_t size, void *obj, H5HG_t *hobj/*out*/); diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index e14bd27..939a26d 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -21,7 +21,7 @@ /****************/ #include "H5Tmodule.h" /* This source code file is part of the H5T module */ - +#define H5F_FRIEND /*suppress error about including H5Fpkg */ /***********/ /* Headers */ @@ -30,6 +30,7 @@ #include "H5CXprivate.h" /* API Contexts */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* File access */ +#include "H5Fpkg.h" /* File */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Tpkg.h" /* Datatypes */ @@ -849,7 +850,9 @@ done: static herr_t H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull) { - const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; + uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -862,11 +865,19 @@ H5T__vlen_disk_isnull(const H5F_t *f, void *_vl, hbool_t *isnull) /* Skip the sequence's length */ vl += 4; + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id((H5F_t *)f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Check if blob ID is "nil" */ - if(H5VL_blob_specific(H5F_VOL_CLS(f), vl, H5VL_BLOB_ISNULL, f, isnull) < 0) + if(H5VL_blob_specific(vol_obj, vl, H5VL_BLOB_ISNULL, isnull) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to check if a blob ID is 'nil'") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_isnull() */ @@ -886,6 +897,8 @@ done: static herr_t H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *bg) { + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ herr_t ret_value = SUCCEED; /* Return value */ @@ -904,11 +917,19 @@ H5T__vlen_disk_setnull(H5F_t *f, void *_vl, void *bg) /* Set the length of the sequence */ UINT32ENCODE(vl, 0); + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Set blob ID to "nil" */ - if(H5VL_blob_specific(H5F_VOL_CLS(f), vl, H5VL_BLOB_SETNULL, f) < 0) + if(H5VL_blob_specific(vol_obj, vl, H5VL_BLOB_SETNULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to set a blob ID to 'nil'") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_setnull() */ @@ -928,6 +949,8 @@ done: static herr_t H5T__vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len) { + H5VL_object_t *vol_obj = NULL;/* Object info */ + hid_t file_id = H5I_INVALID_HID; const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ herr_t ret_value = SUCCEED; /* Return value */ @@ -941,11 +964,19 @@ H5T__vlen_disk_read(H5F_t *f, void *_vl, void *buf, size_t H5_ATTR_UNUSED len) /* Skip the length of the sequence */ vl += 4; + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Retrieve blob */ - if(H5VL_blob_get(H5F_VOL_CLS(f), vl, f, buf) < 0) + if(H5VL_blob_get(vol_obj, vl, buf, NULL, NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get blob") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_read() */ @@ -966,6 +997,8 @@ static herr_t H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_alloc_info, void *_vl, void *buf, void *_bg, size_t seq_len, size_t base_size) { + H5VL_object_t *vol_obj = NULL; /* Object info */ + hid_t file_id = H5I_INVALID_HID; uint8_t *vl = (uint8_t *)_vl; /* Pointer to the user's hvl_t information */ const uint8_t *bg = (const uint8_t *)_bg; /* Pointer to the old data hvl_t */ herr_t ret_value = SUCCEED; /* Return value */ @@ -985,11 +1018,19 @@ H5T__vlen_disk_write(H5F_t *f, const H5T_vlen_alloc_info_t H5_ATTR_UNUSED *vl_al /* Set the length of the sequence */ UINT32ENCODE(vl, seq_len); + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* Store blob */ - if(H5VL_blob_put(H5F_VOL_CLS(f), buf, (seq_len * base_size), f, vl) < 0) + if(H5VL_blob_put(vol_obj, buf, (seq_len * base_size), vl, NULL) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "unable to put blob") done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_write() */ @@ -1010,6 +1051,7 @@ static herr_t H5T__vlen_disk_delete(H5F_t *f, const void *_vl) { const uint8_t *vl = (const uint8_t *)_vl; /* Pointer to the user's hvl_t information */ + hid_t file_id = H5I_INVALID_HID; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -1025,12 +1067,23 @@ H5T__vlen_disk_delete(H5F_t *f, const void *_vl) UINT32DECODE(vl, seq_len); /* Delete object, if length > 0 */ - if(seq_len > 0) - if(H5VL_blob_specific(H5F_VOL_CLS(f), (void *)vl, H5VL_BLOB_DELETE, f) < 0) /* Casting away 'const' OK -QAK */ + if(seq_len > 0) { + H5VL_object_t *vol_obj = NULL; /* Object info */ + + /* TODO temporary hack to retrieve file object */ + if((file_id = H5F__get_file_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + if(NULL == (vol_obj = H5VL_vol_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + if(H5VL_blob_specific(vol_obj, (void *)vl, H5VL_BLOB_DELETE) < 0) /* Casting away 'const' OK -QAK */ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREMOVE, FAIL, "unable to delete blob") + } } /* end if */ done: + if((file_id != H5I_INVALID_HID) && (H5I_dec_ref(file_id) < 0)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on file id") FUNC_LEAVE_NOAPI(ret_value) } /* end H5T__vlen_disk_delete() */ diff --git a/src/H5VLcallback.c b/src/H5VLcallback.c index 43739a6..5400356 100644 --- a/src/H5VLcallback.c +++ b/src/H5VLcallback.c @@ -177,7 +177,12 @@ static herr_t H5VL__request_specific(void *req, const H5VL_class_t *cls, static herr_t H5VL__request_optional(void *req, const H5VL_class_t *cls, va_list arguments); static herr_t H5VL__request_free(void *req, const H5VL_class_t *cls); - +static herr_t H5VL__blob_put(void *obj, const H5VL_class_t *cls, + const void *buf, size_t size, void *blob_id, void *ctx); +static herr_t H5VL__blob_get(void *obj, const H5VL_class_t *cls, + const void *blob_id, void *buf, size_t *size, void *ctx); +static herr_t H5VL__blob_specific(void *obj, const H5VL_class_t *cls, + void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); /*********************/ /* Package Variables */ @@ -6564,81 +6569,230 @@ done: /*------------------------------------------------------------------------- - * Function: H5VL_blob_put + * Function: H5VL__blob_put * * Purpose: Put a blob through the VOL * * Return: SUCCEED / FAIL * - * Programmer: Quincey Koziol - * Wednesday, August 21, 2019 - * *------------------------------------------------------------------------- */ -herr_t -H5VL_blob_put(const H5VL_class_t *cls, void *blob, size_t size, void *ctx, void *id) +static herr_t +H5VL__blob_put(void *obj, const H5VL_class_t *cls, const void *buf, size_t size, + void *blob_id, void *ctx) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC /* Sanity check */ + HDassert(obj); HDassert(cls); - HDassert(size == 0 || blob); - HDassert(id); + HDassert(size == 0 || buf); + HDassert(blob_id); /* Check if the corresponding VOL callback exists */ if(NULL == cls->blob_cls.put) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob put' method") /* Call the corresponding VOL callback */ - if((cls->blob_cls.put)(blob, size, ctx, id) < 0) + if((cls->blob_cls.put)(obj, buf, size, blob_id, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put callback failed") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_blob_put() */ +} /* end H5VL__blob_put() */ /*------------------------------------------------------------------------- - * Function: H5VL_blob_get + * Function: H5VL_blob_put * - * Purpose: Get a blob through the VOL + * Purpose: Put a blob through the VOL * * Return: SUCCEED / FAIL * * Programmer: Quincey Koziol - * Friday, August 16, 2019 + * Wednesday, August 21, 2019 * *------------------------------------------------------------------------- */ herr_t -H5VL_blob_get(const H5VL_class_t *cls, const void *id, void *ctx, void *buf) +H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, + void *blob_id, void *ctx) { + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ + HDassert(vol_obj); + HDassert(size == 0 || buf); + HDassert(blob_id); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding VOL callback */ + if(H5VL__blob_put(vol_obj->data, vol_obj->connector->cls, buf, size, blob_id, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLblob_put + * + * Purpose: Put a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size, + void *blob_id, void *ctx) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE6("e", "*xi*xz*x*x", obj, connector_id, buf, size, blob_id, ctx); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_put(obj, cls, buf, size, blob_id, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "blob put failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__blob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL__blob_get(void *obj, const H5VL_class_t *cls, const void *blob_id, + void *buf, size_t *size, void *ctx) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Sanity check */ + HDassert(obj); HDassert(cls); - HDassert(id); - HDassert(buf); + HDassert(blob_id); + HDassert(size || buf); /* Check if the corresponding VOL callback exists */ if(NULL == cls->blob_cls.get) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob get' method") /* Call the corresponding VOL callback */ - if((cls->blob_cls.get)(id, ctx, buf) < 0) + if((cls->blob_cls.get)(obj, blob_id, buf, size, ctx) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get callback failed") done: FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + HDassert(blob_id); + HDassert(size || buf); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding VOL callback */ + if(H5VL__blob_get(vol_obj->data, vol_obj->connector->cls, blob_id, buf, size, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed") + +done: + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL_blob_get() */ /*------------------------------------------------------------------------- - * Function: H5VL_blob_specific + * Function: H5VLblob_get + * + * Purpose: Get a blob through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE6("e", "*xi*x*x*z*x", obj, connector_id, blob_id, buf, size, ctx); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_get(obj, cls, blob_id, buf, size, ctx) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "blob get failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL__blob_specific * * Purpose: Specific operation on blobs through the VOL * @@ -6649,28 +6803,66 @@ done: * *------------------------------------------------------------------------- */ -herr_t -H5VL_blob_specific(const H5VL_class_t *cls, void *id, - H5VL_blob_specific_t specific_type, ...) +static herr_t +H5VL__blob_specific(void *obj, const H5VL_class_t *cls, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) { - va_list arguments; /* Argument list passed from the API call */ - hbool_t arg_started = FALSE; /* Whether the va_list has been started */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC /* Sanity check */ + HDassert(obj); HDassert(cls); - HDassert(id); + HDassert(blob_id); /* Check if the corresponding VOL callback exists */ if(NULL == cls->blob_cls.specific) HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "VOL connector has no 'blob specific' method") /* Call the corresponding VOL callback */ + if((cls->blob_cls.specific)(obj, blob_id, specific_type, arguments) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL__blob_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_blob_specific + * + * Purpose: Specific operation on blobs through the VOL + * + * Return: Success: Non-negative + * Failure: Negative + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, + H5VL_blob_specific_t specific_type, ...) +{ + va_list arguments; /* Argument list passed from the API call */ + hbool_t arg_started = FALSE; /* Whether the va_list has been started */ + hbool_t vol_wrapper_set = FALSE; /* Whether the VOL object wrapping context was set up */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(vol_obj); + HDassert(blob_id); + + /* Set wrapper info in API context */ + if(H5VL_set_vol_wrapper(vol_obj->data, vol_obj->connector) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't set VOL wrapper info") + vol_wrapper_set = TRUE; + + /* Call the corresponding internal VOL routine */ HDva_start(arguments, specific_type); arg_started = TRUE; - if((cls->blob_cls.specific)(id, specific_type, arguments) < 0) + if((ret_value = H5VL__blob_specific(vol_obj->data, vol_obj->connector->cls, blob_id, specific_type, arguments)) < 0) HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "unable to execute blob specific callback") done: @@ -6678,8 +6870,46 @@ done: if(arg_started) HDva_end(arguments); + /* Reset object wrapping info in API context */ + if(vol_wrapper_set && H5VL_reset_vol_wrapper() < 0) + HDONE_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset VOL wrapper info") + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL_blob_get() */ +} /* end H5VL_blob_specific() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLblob_specific + * + * Purpose: Specific operation on blobs through the VOL + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) +{ + H5VL_class_t *cls; /* VOL connector's class struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API_NOINIT + H5TRACE5("e", "*xi*xVBx", obj, connector_id, blob_id, specific_type, arguments); + + /* Get class pointer */ + if(NULL == obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object") + if(NULL == (cls = (H5VL_class_t *)H5I_object_verify(connector_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID") + + /* Call the corresponding VOL callback */ + if(H5VL__blob_specific(obj, cls, blob_id, specific_type, arguments) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTOPERATE, FAIL, "blob specific operation failed") + +done: + FUNC_LEAVE_API_NOINIT(ret_value) +} /* end H5VLblob_specific() */ /*------------------------------------------------------------------------- diff --git a/src/H5VLconnector.h b/src/H5VLconnector.h index c554dab..1221d88 100644 --- a/src/H5VLconnector.h +++ b/src/H5VLconnector.h @@ -37,6 +37,8 @@ #define H5VL_CAP_FLAG_NONE 0 /* No special connector capabilities */ #define H5VL_CAP_FLAG_THREADSAFE 0x01 /* Connector is threadsafe */ +/* The maximum size allowed for blobs */ +#define H5VL_MAX_BLOB_ID_SIZE (16) /* Allow for 128-bits blob IDs */ /*******************/ /* Public Typedefs */ @@ -365,10 +367,10 @@ typedef struct H5VL_request_class_t { /* 'blob' routines */ typedef struct H5VL_blob_class_t { - herr_t (*put)(void *blob, size_t size, void *ctx, void *id); - herr_t (*get)(const void *id, void *ctx, void *blob); - herr_t (*specific)(void *id, H5VL_blob_specific_t specific_type, va_list arguments); - herr_t (*optional)(void *id, va_list arguments); + herr_t (*put)(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); + herr_t (*get)(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); + herr_t (*specific)(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + herr_t (*optional)(void *obj, void *blob_id, va_list arguments); } H5VL_blob_class_t; /* diff --git a/src/H5VLconnector_passthru.h b/src/H5VLconnector_passthru.h index 65c9117..d0d73d2 100644 --- a/src/H5VLconnector_passthru.h +++ b/src/H5VLconnector_passthru.h @@ -158,6 +158,11 @@ H5_DLL herr_t H5VLrequest_specific(void *req, hid_t connector_id, H5VL_request_s H5_DLL herr_t H5VLrequest_optional(void *req, hid_t connector_id, va_list arguments); H5_DLL herr_t H5VLrequest_free(void *req, hid_t connector_id); +/* Public wrappers for blob callbacks */ +H5_DLL herr_t H5VLblob_put(void *obj, hid_t connector_id, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VLblob_get(void *obj, hid_t connector_id, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VLblob_specific(void *obj, hid_t connector_id, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + /* Public wrappers for generic 'optional' callback */ H5_DLL herr_t H5VLoptional(void *obj, hid_t connector_id, hid_t dxpl_id, void **req, va_list arguments); diff --git a/src/H5VLnative.c b/src/H5VLnative.c index c705aad..78eaee4 100644 --- a/src/H5VLnative.c +++ b/src/H5VLnative.c @@ -124,7 +124,7 @@ static H5VL_class_t H5VL_native_cls_g = { H5VL__native_blob_put, /* put */ H5VL__native_blob_get, /* get */ H5VL__native_blob_specific, /* specific */ - H5VL__native_blob_optional /* optional */ + NULL /* optional */ }, NULL /* optional */ }; diff --git a/src/H5VLnative.h b/src/H5VLnative.h index 96668ac..5b51e66 100644 --- a/src/H5VLnative.h +++ b/src/H5VLnative.h @@ -17,8 +17,8 @@ #ifndef _H5VLnative_H #define _H5VLnative_H -/* Private headers needed by this file */ -#include "H5VLprivate.h" /* Virtual Object Layer */ +/* Public headers needed by this file */ +#include "H5VLpublic.h" /* Virtual Object Layer */ /* Identifier for the native VOL connector */ #define H5VL_NATIVE (H5VL_native_register()) diff --git a/src/H5VLnative_blob.c b/src/H5VLnative_blob.c index 6f2fbe6..b16b407 100644 --- a/src/H5VLnative_blob.c +++ b/src/H5VLnative_blob.c @@ -68,22 +68,23 @@ *------------------------------------------------------------------------- */ herr_t -H5VL__native_blob_put(void *blob, size_t size, void *_ctx, void *_id) +H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, + void H5_ATTR_UNUSED *ctx) { - uint8_t *id = (uint8_t *)_id; /* Pointer to blob ID */ - H5F_t *f = (H5F_t *)_ctx; /* Retrieve file pointer from context */ + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ + uint8_t *id = (uint8_t *)blob_id; /* Pointer to blob ID */ H5HG_t hobjid; /* New VL sequence's heap ID */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Check parameters */ - HDassert(id); - HDassert(size == 0 || blob); HDassert(f); + HDassert(size == 0 || buf); + HDassert(id); /* Write the VL information to disk (allocates space also) */ - if(H5HG_insert(f, size, blob, &hobjid) < 0) + if(H5HG_insert(f, size, (void *)buf, &hobjid) < 0) HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "unable to write blob information") /* Encode the heap information */ @@ -108,18 +109,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_blob_get(const void *_id, void *_ctx, void *buf) +H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, + void H5_ATTR_UNUSED *ctx) { - const uint8_t *id = (const uint8_t *)_id; /* Pointer to the disk blob ID */ - H5F_t *f = (H5F_t *)_ctx; /* Retrieve file pointer from context */ + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the disk blob ID */ H5HG_t hobjid; /* Global heap ID for sequence */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE /* Sanity check */ - HDassert(id); HDassert(f); + HDassert(id); HDassert(buf); /* Get the heap information */ @@ -129,7 +131,7 @@ H5VL__native_blob_get(const void *_id, void *_ctx, void *buf) /* Check if this sequence actually has any data */ if(hobjid.addr > 0) /* Read the VL information from disk */ - if(NULL == H5HG_read(f, &hobjid, buf, NULL)) + if(NULL == H5HG_read(f, &hobjid, buf, size)) HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "unable to read VL information") done: @@ -150,18 +152,22 @@ done: *------------------------------------------------------------------------- */ herr_t -H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, - va_list arguments) +H5VL__native_blob_specific(void *obj, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) { + H5F_t *f = (H5F_t *)obj; /* Retrieve file pointer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE + /* Sanity check */ + HDassert(f); + HDassert(blob_id); + switch(specific_type) { case H5VL_BLOB_GETSIZE: { - const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ - H5F_t *f = HDva_arg(arguments, H5F_t *); + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ size_t *size = HDva_arg(arguments, size_t *); H5HG_t hobjid; /* blob's heap ID */ @@ -182,8 +188,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, case H5VL_BLOB_ISNULL: { - const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ - H5F_t *f = HDva_arg(arguments, H5F_t *); + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ hbool_t *isnull = HDva_arg(arguments, hbool_t *); haddr_t addr; /* Sequence's heap address */ @@ -198,9 +203,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, case H5VL_BLOB_SETNULL: { - uint8_t *id = (uint8_t *)_id; /* Pointer to the blob ID */ - H5F_t *f = HDva_arg(arguments, H5F_t *); - + uint8_t *id = (uint8_t *)blob_id; /* Pointer to the blob ID */ /* Encode the "nil" heap pointer information */ H5F_addr_encode(f, &id, (haddr_t)0); UINT32ENCODE(id, 0); @@ -210,8 +213,7 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, case H5VL_BLOB_DELETE: { - const uint8_t *id = (const uint8_t *)_id; /* Pointer to the blob ID */ - H5F_t *f = HDva_arg(arguments, H5F_t *); + const uint8_t *id = (const uint8_t *)blob_id; /* Pointer to the blob ID */ H5HG_t hobjid; /* VL sequence's heap ID */ /* Get heap information */ @@ -233,28 +235,3 @@ H5VL__native_blob_specific(void *_id, H5VL_blob_specific_t specific_type, done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_blob_specific() */ - - -/*------------------------------------------------------------------------- - * Function: H5VL__native_blob_optional - * - * Purpose: Handles the blob 'optional' callback - * - * Return: SUCCEED / FAIL - * - * Programmer: Quincey Koziol - * Friday, August 15, 2019 - * - *------------------------------------------------------------------------- - */ -herr_t -H5VL__native_blob_optional(void *id, va_list arguments) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5VL__native_blob_optional() */ - diff --git a/src/H5VLnative_private.h b/src/H5VLnative_private.h index df3865b..5ed0b1f 100644 --- a/src/H5VLnative_private.h +++ b/src/H5VLnative_private.h @@ -102,10 +102,9 @@ H5_DLL herr_t H5VL__native_datatype_specific(void *dt, H5VL_datatype_specific_t H5_DLL herr_t H5VL__native_datatype_close(void *dt, hid_t dxpl_id, void **req); /* Blob callbacks */ -H5_DLL herr_t H5VL__native_blob_put(void *blob, size_t size, void *ctx, void *id); -H5_DLL herr_t H5VL__native_blob_get(const void *id, void *ctx, void *buf); -H5_DLL herr_t H5VL__native_blob_specific(void *id, H5VL_blob_specific_t specific_type, va_list arguments); -H5_DLL herr_t H5VL__native_blob_optional(void *id, va_list arguments); +H5_DLL herr_t H5VL__native_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VL__native_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VL__native_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); #ifdef __cplusplus } diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c index 48ef510..85c2211 100644 --- a/src/H5VLpassthru.c +++ b/src/H5VLpassthru.c @@ -178,6 +178,12 @@ static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specifi static herr_t H5VL_pass_through_request_optional(void *req, va_list arguments); static herr_t H5VL_pass_through_request_free(void *req); +/* Blob callbacks */ +static herr_t H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx); +static herr_t H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t *size, void *ctx); +static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type, va_list arguments); + + /*******************/ /* Local variables */ /*******************/ @@ -273,9 +279,9 @@ static const H5VL_class_t H5VL_pass_through_g = { H5VL_pass_through_request_free /* free */ }, { /* blob_cls */ - NULL, /* put */ - NULL, /* get */ - NULL, /* specific */ + H5VL_pass_through_blob_put, /* put */ + H5VL_pass_through_blob_get, /* get */ + H5VL_pass_through_blob_specific, /* specific */ NULL /* optional */ }, NULL /* optional */ @@ -2840,3 +2846,83 @@ H5VL_pass_through_request_free(void *obj) return ret_value; } /* end H5VL_pass_through_request_free() */ + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_put + * + * Purpose: Handles the blob 'put' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, + void *blob_id, void *ctx) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Put\n"); +#endif + + ret_value = H5VLblob_put(o->under_object, o->under_vol_id, buf, size, + blob_id, ctx); + + return ret_value; +} /* end H5VL_pass_through_blob_put() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_get + * + * Purpose: Handles the blob 'get' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, + size_t *size, void *ctx) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Get\n"); +#endif + + ret_value = H5VLblob_get(o->under_object, o->under_vol_id, blob_id, buf, + size, ctx); + + return ret_value; +} /* end H5VL_pass_through_blob_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_pass_through_blob_specific + * + * Purpose: Handles the blob 'specific' callback + * + * Return: SUCCEED / FAIL + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_pass_through_blob_specific(void *obj, void *blob_id, + H5VL_blob_specific_t specific_type, va_list arguments) +{ + H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj; + herr_t ret_value; + +#ifdef ENABLE_PASSTHRU_LOGGING + printf("------- PASS THROUGH VOL BLOB Specific\n"); +#endif + + ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id, + specific_type, arguments); + + return ret_value; +} /* end H5VL_pass_through_blob_specific() */ diff --git a/src/H5VLpassthru.h b/src/H5VLpassthru.h index e640636..d145bcd 100644 --- a/src/H5VLpassthru.h +++ b/src/H5VLpassthru.h @@ -17,6 +17,9 @@ #ifndef _H5VLpassthru_H #define _H5VLpassthru_H +/* Public headers needed by this file */ +#include "H5VLpublic.h" /* Virtual Object Layer */ + /* Identifier for the pass-through VOL connector */ #define H5VL_PASSTHRU (H5VL_pass_through_register()) diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h index 4aeabfa..2889524 100644 --- a/src/H5VLprivate.h +++ b/src/H5VLprivate.h @@ -194,12 +194,9 @@ H5_DLL herr_t H5VL_request_optional(const H5VL_object_t *vol_obj, ...); H5_DLL herr_t H5VL_request_free(const H5VL_object_t *vol_obj); /* Blob functions */ -H5_DLL herr_t H5VL_blob_put(const H5VL_class_t *cls, void *blob, size_t size, - void *ctx, void *id); -H5_DLL herr_t H5VL_blob_get(const H5VL_class_t *cls, const void *id, void *ctx, - void *blob); -H5_DLL herr_t H5VL_blob_specific(const H5VL_class_t *cls, void *id, - H5VL_blob_specific_t specific_type, ...); +H5_DLL herr_t H5VL_blob_put(const H5VL_object_t *vol_obj, const void *buf, size_t size, void *blob_id, void *ctx); +H5_DLL herr_t H5VL_blob_get(const H5VL_object_t *vol_obj, const void *blob_id, void *buf, size_t *size, void *ctx); +H5_DLL herr_t H5VL_blob_specific(const H5VL_object_t *vol_obj, void *blob_id, H5VL_blob_specific_t specific_type, ...); /* Generic functions */ H5_DLL herr_t H5VL_optional(const H5VL_object_t *vol_obj, hid_t dxpl_id,void **req, ...); diff --git a/src/H5trace.c b/src/H5trace.c index b1301dd..e209995 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -2592,6 +2592,35 @@ H5_trace(const double *returning, const char *func, const char *type, ...) } /* end switch */ } /* end else */ break; + case 'B': + if(ptr) { + if(vp) + HDfprintf (out, "0x%lx", (unsigned long)vp); + else + HDfprintf(out, "NULL"); + } /* end if */ + else { + H5VL_blob_specific_t specific = (H5VL_blob_specific_t)HDva_arg(ap, int); + + switch(specific) { + case H5VL_BLOB_DELETE: + HDfprintf(out, "H5VL_BLOB_DELETE"); + break; + case H5VL_BLOB_GETSIZE: + HDfprintf(out, "H5VL_BLOB_GETSIZE"); + break; + case H5VL_BLOB_ISNULL: + HDfprintf(out, "H5VL_BLOB_ISNULL"); + break; + case H5VL_BLOB_SETNULL: + HDfprintf(out, "H5VL_BLOB_SETNULL"); + break; + default: + HDfprintf(out, "%ld", (long)specific); + break; + } /* end switch */ + } /* end else */ + break; case 'C': if(ptr) { if(vp) -- cgit v0.12