summaryrefslogtreecommitdiffstats
path: root/src/H5VLpassthru.c
diff options
context:
space:
mode:
authorAllen Byrne <byrn@hdfgroup.org>2018-12-05 20:25:58 (GMT)
committerAllen Byrne <byrn@hdfgroup.org>2018-12-05 20:25:58 (GMT)
commit307749cc71603b67c0b6e6fbafcb09b065026800 (patch)
tree34114998b7c028c9c52a0393e44ef37aecee8792 /src/H5VLpassthru.c
parenta68fd292081be9415d9f9c9de41312a9d60bb5ad (diff)
parent55e87e5b86aacbb37c57614cd2e869541291caad (diff)
downloadhdf5-307749cc71603b67c0b6e6fbafcb09b065026800.zip
hdf5-307749cc71603b67c0b6e6fbafcb09b065026800.tar.gz
hdf5-307749cc71603b67c0b6e6fbafcb09b065026800.tar.bz2
Merging in latest from upstream (HDFFV/hdf5:refs/heads/develop)
* commit '55e87e5b86aacbb37c57614cd2e869541291caad': (51 commits) Correct Windows build. Refactor allocating & releasing pass through wrapper objects. Fix typo Remove duplicated comment. Add a couple of missing prototypes for static routines, along with updating a comment from VOL plugin -> connector. Switch H5VL_class_value_t from unsigned to int, and add "invalid" ID value. Correct "make check-vol" regression test target. Switch H5VL_class_value_t from enum to unsigned integer Add support for "make check-vol", along with a few minor cleanups, etc. Refactor infrastructure for setting FAPL information from environment variables during testing, including connecting native, pass-through, and dynamically loaded VOL connectors. Also bring native and pass-through VOL connectors into alignment, removing the "H5VLnative_private.h" header. Remove example VOL connector, since it's been superceded by the pass-through VOL connector in the src subdirectory. Add pass-through VOL connector Update API tracing info for VOL functions and regenerate trace macros for VOL API calls. Added 'notify' callback for async requests; switched VOL class and info comparison to return comparison value as parameter, so they can return error values; "cancelled" -> "canceled"; switched order of 'wrap_object' and 'free_wrap_ctx' management callbacks. Add using FAPL from h5_fileaccess() to more tests. Remove unused test for unimplemented routine. Switch loc_params to VOL callbacks to pass struct by pointer instead of by value. Add info_to_str and str_to_info "management" callbacks for serializing and deserializing a connector's info object. Revert some of the changes to support the original property list value of metadata read attempts. Add VOL connector info to the flie access property list returned from H5Fget_access_plist(). Also, other misc. cleanups, etc. ...
Diffstat (limited to 'src/H5VLpassthru.c')
-rw-r--r--src/H5VLpassthru.c2693
1 files changed, 2693 insertions, 0 deletions
diff --git a/src/H5VLpassthru.c b/src/H5VLpassthru.c
new file mode 100644
index 0000000..a93ac9a
--- /dev/null
+++ b/src/H5VLpassthru.c
@@ -0,0 +1,2693 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the COPYING file, which can be found at the root of the source code *
+ * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
+ * If you do not have access to either file, you may request a copy from *
+ * help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: This is a "pass through" VOL connector, which forwards each
+ * VOL callback to an underlying connector.
+ *
+ * It is designed as an example VOL connector for developers to
+ * use when creating new connectors, especially connectors that
+ * are outside of the HDF5 library. As such, it should _NOT_
+ * include _any_ private HDF5 header files. This connector should
+ * therefore only make public HDF5 API calls and use standard C /
+ * POSIX calls.
+ */
+
+
+/* Header files needed */
+/* (Public HDF5 and standard C / POSIX only) */
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "hdf5.h"
+#include "H5VLpassthru.h"
+
+
+/**********/
+/* Macros */
+/**********/
+
+/* Whether to display log messge when callback is invoked */
+/* (Uncomment to enable) */
+/* #define ENABLE_LOGGING */
+
+
+/************/
+/* Typedefs */
+/************/
+
+/* The pass through VOL info object */
+typedef struct H5VL_pass_through_t {
+ hid_t under_vol_id; /* ID for underlying VOL connector */
+ void *under_object; /* Info object for underlying VOL connector */
+} H5VL_pass_through_t;
+
+/* The pass through VOL wrapper context */
+typedef struct H5VL_pass_through_wrap_ctx_t {
+ hid_t under_vol_id; /* VOL ID for under VOL */
+ void *under_wrap_ctx; /* Object wrapping context for under VOL */
+} H5VL_pass_through_wrap_ctx_t;
+
+
+/********************* */
+/* Function prototypes */
+/********************* */
+
+/* Helper routines */
+static herr_t H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id,
+ H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, ...);
+static herr_t H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id,
+ H5VL_request_specific_t specific_type, ...);
+static H5VL_pass_through_t *H5VL_pass_through_new_obj(void *under_obj,
+ hid_t under_vol_id);
+static herr_t H5VL_pass_through_free_obj(H5VL_pass_through_t *obj);
+
+/* "Management" callbacks */
+static herr_t H5VL_pass_through_init(hid_t vipl_id);
+static herr_t H5VL_pass_through_term(void);
+static void *H5VL_pass_through_info_copy(const void *info);
+static herr_t H5VL_pass_through_info_cmp(int *cmp_value, const void *info1, const void *info2);
+static herr_t H5VL_pass_through_info_free(void *info);
+static herr_t H5VL_pass_through_info_to_str(const void *info, char **str);
+static herr_t H5VL_pass_through_str_to_info(const char *str, void **info);
+static void *H5VL_pass_through_get_object(const void *obj);
+static herr_t H5VL_pass_through_get_wrap_ctx(const void *obj, void **wrap_ctx);
+static herr_t H5VL_pass_through_free_wrap_ctx(void *obj);
+static void *H5VL_pass_through_wrap_object(void *obj, void *wrap_ctx);
+
+/* Attribute callbacks */
+static void *H5VL_pass_through_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_pass_through_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t aapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_attr_read(void *attr, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_attr_write(void *attr, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_attr_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_attr_close(void *attr, hid_t dxpl_id, void **req);
+
+/* Dataset callbacks */
+static void *H5VL_pass_through_dataset_create(void *obj, const 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_pass_through_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t dapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_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_pass_through_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_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_dataset_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_dataset_close(void *dset, hid_t dxpl_id, void **req);
+
+/* Datatype callbacks */
+static void *H5VL_pass_through_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_pass_through_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t tapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_datatype_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_datatype_close(void *dt, hid_t dxpl_id, void **req);
+
+/* File callbacks */
+static void *H5VL_pass_through_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_file_optional(void *file, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_file_close(void *file, hid_t dxpl_id, void **req);
+
+/* Group callbacks */
+static void *H5VL_pass_through_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req);
+static void *H5VL_pass_through_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_group_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_group_close(void *grp, hid_t dxpl_id, void **req);
+
+/* Link callbacks */
+static herr_t H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_link_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments);
+
+/* Object callbacks */
+static void *H5VL_pass_through_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_type_t *opened_type, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name, void *dst_obj, const H5VL_loc_params_t *dst_loc_params, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req);
+static herr_t H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments);
+static herr_t H5VL_pass_through_object_optional(void *obj, hid_t dxpl_id, void **req, va_list arguments);
+
+/* Async request callbacks */
+static herr_t H5VL_pass_through_request_wait(void *req, uint64_t timeout, H5ES_status_t *status);
+static herr_t H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx);
+static herr_t H5VL_pass_through_request_cancel(void *req);
+static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specific_t specific_type, va_list arguments);
+static herr_t H5VL_pass_through_request_optional(void *req, va_list arguments);
+static herr_t H5VL_pass_through_request_free(void *req);
+
+/*******************/
+/* Local variables */
+/*******************/
+
+/* Pass through VOL connector class struct */
+static const H5VL_class_t H5VL_pass_through_g = {
+ H5VL_PASSTHRU_VERSION, /* version */
+ (H5VL_class_value_t)H5VL_PASSTHRU_VALUE, /* value */
+ H5VL_PASSTHRU_NAME, /* name */
+ 0, /* capability flags */
+ H5VL_pass_through_init, /* initialize */
+ H5VL_pass_through_term, /* terminate */
+ sizeof(H5VL_pass_through_t), /* info size */
+ H5VL_pass_through_info_copy, /* info copy */
+ H5VL_pass_through_info_cmp, /* info compare */
+ H5VL_pass_through_info_free, /* info free */
+ H5VL_pass_through_info_to_str, /* info to str */
+ H5VL_pass_through_str_to_info, /* str to info */
+ H5VL_pass_through_get_object, /* get_object */
+ H5VL_pass_through_get_wrap_ctx, /* get_wrap_ctx */
+ H5VL_pass_through_wrap_object, /* wrap_object */
+ H5VL_pass_through_free_wrap_ctx, /* free_wrap_ctx */
+ { /* attribute_cls */
+ H5VL_pass_through_attr_create, /* create */
+ H5VL_pass_through_attr_open, /* open */
+ H5VL_pass_through_attr_read, /* read */
+ H5VL_pass_through_attr_write, /* write */
+ H5VL_pass_through_attr_get, /* get */
+ H5VL_pass_through_attr_specific, /* specific */
+ H5VL_pass_through_attr_optional, /* optional */
+ H5VL_pass_through_attr_close /* close */
+ },
+ { /* dataset_cls */
+ H5VL_pass_through_dataset_create, /* create */
+ H5VL_pass_through_dataset_open, /* open */
+ H5VL_pass_through_dataset_read, /* read */
+ H5VL_pass_through_dataset_write, /* write */
+ H5VL_pass_through_dataset_get, /* get */
+ H5VL_pass_through_dataset_specific, /* specific */
+ H5VL_pass_through_dataset_optional, /* optional */
+ H5VL_pass_through_dataset_close /* close */
+ },
+ { /* datatype_cls */
+ H5VL_pass_through_datatype_commit, /* commit */
+ H5VL_pass_through_datatype_open, /* open */
+ H5VL_pass_through_datatype_get, /* get_size */
+ H5VL_pass_through_datatype_specific, /* specific */
+ H5VL_pass_through_datatype_optional, /* optional */
+ H5VL_pass_through_datatype_close /* close */
+ },
+ { /* file_cls */
+ H5VL_pass_through_file_create, /* create */
+ H5VL_pass_through_file_open, /* open */
+ H5VL_pass_through_file_get, /* get */
+ H5VL_pass_through_file_specific, /* specific */
+ H5VL_pass_through_file_optional, /* optional */
+ H5VL_pass_through_file_close /* close */
+ },
+ { /* group_cls */
+ H5VL_pass_through_group_create, /* create */
+ H5VL_pass_through_group_open, /* open */
+ H5VL_pass_through_group_get, /* get */
+ H5VL_pass_through_group_specific, /* specific */
+ H5VL_pass_through_group_optional, /* optional */
+ H5VL_pass_through_group_close /* close */
+ },
+ { /* link_cls */
+ H5VL_pass_through_link_create, /* create */
+ H5VL_pass_through_link_copy, /* copy */
+ H5VL_pass_through_link_move, /* move */
+ H5VL_pass_through_link_get, /* get */
+ H5VL_pass_through_link_specific, /* specific */
+ H5VL_pass_through_link_optional, /* optional */
+ },
+ { /* object_cls */
+ H5VL_pass_through_object_open, /* open */
+ H5VL_pass_through_object_copy, /* copy */
+ H5VL_pass_through_object_get, /* get */
+ H5VL_pass_through_object_specific, /* specific */
+ H5VL_pass_through_object_optional, /* optional */
+ },
+ { /* request_cls */
+ H5VL_pass_through_request_wait, /* wait */
+ H5VL_pass_through_request_notify, /* notify */
+ H5VL_pass_through_request_cancel, /* cancel */
+ H5VL_pass_through_request_specific, /* specific */
+ H5VL_pass_through_request_optional, /* optional */
+ H5VL_pass_through_request_free /* free */
+ },
+ NULL /* optional */
+};
+
+/* The connector identification number, initialized at runtime */
+static hid_t H5VL_PASSTHRU_g = H5I_INVALID_HID;
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__pass_through_new_obj
+ *
+ * Purpose: Create a new pass through object for an underlying object
+ *
+ * Return: Success: Pointer to the new pass through object
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, December 3, 2018
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5VL_pass_through_t *
+H5VL_pass_through_new_obj(void *under_obj, hid_t under_vol_id)
+{
+ H5VL_pass_through_t *new_obj;
+
+ new_obj = (H5VL_pass_through_t *)calloc(1, sizeof(H5VL_pass_through_t));
+ new_obj->under_object = under_obj;
+ new_obj->under_vol_id = under_vol_id;
+ H5Iinc_ref(new_obj->under_vol_id);
+
+ return(new_obj);
+} /* end H5VL__pass_through_new_obj() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL__pass_through_free_obj
+ *
+ * Purpose: Release a pass through object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, December 3, 2018
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_free_obj(H5VL_pass_through_t *obj)
+{
+ H5Idec_ref(obj->under_vol_id);
+ free(obj);
+
+ return(0);
+} /* end H5VL__pass_through_free_obj() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_register
+ *
+ * Purpose: Register the pass-through VOL connector and retrieve an ID
+ * for it.
+ *
+ * Return: Success: The ID for the pass-through VOL connector
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, November 28, 2018
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5VL_pass_through_register(void)
+{
+ /* Clear the error stack */
+ H5Eclear2(H5E_DEFAULT);
+
+ /* Singleton register the pass-through VOL connector ID */
+ if(H5I_VOL != H5Iget_type(H5VL_PASSTHRU_g))
+ H5VL_PASSTHRU_g = H5VLregister_connector(&H5VL_pass_through_g, H5P_DEFAULT);
+
+ return(H5VL_PASSTHRU_g);
+} /* end H5VL_pass_through_register() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_init
+ *
+ * Purpose: Initialize this VOL connector, performing any necessary
+ * operations for the connector that will apply to all containers
+ * accessed with the connector.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_init(hid_t vipl_id)
+{
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL INIT\n");
+#endif
+
+ /* Shut compiler up about unused parameter */
+ vipl_id = vipl_id;
+
+ return(0);
+} /* end H5VL_pass_through_init() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_term
+ *
+ * Purpose: Terminate this VOL connector, performing any necessary
+ * operations for the connector that release connector-wide
+ * resources (usually created / initialized with the 'init'
+ * callback).
+ *
+ * Return: Success: 0
+ * Failure: (Can't fail)
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_term(void)
+{
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL TERM\n");
+#endif
+
+ /* Reset VOL ID */
+ H5VL_PASSTHRU_g = H5I_INVALID_HID;
+
+ return(0);
+} /* end H5VL_pass_through_term() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_info_copy
+ *
+ * Purpose: Duplicate the connector's info object.
+ *
+ * Returns: Success: New connector info object
+ * Failure: NULL
+ *
+ *---------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_info_copy(const void *_info)
+{
+ const H5VL_pass_through_info_t *info = (const H5VL_pass_through_info_t *)_info;
+ H5VL_pass_through_info_t *new_info;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL INFO Copy\n");
+#endif
+
+ /* Allocate new VOL info struct for the pass through connector */
+ new_info = (H5VL_pass_through_info_t *)calloc(1, sizeof(H5VL_pass_through_info_t));
+
+ /* Increment reference count on underlying VOL ID, and copy the VOL info */
+ new_info->under_vol_id = info->under_vol_id;
+ H5Iinc_ref(new_info->under_vol_id);
+ if(info->under_vol_info)
+ H5VLcopy_connector_info(new_info->under_vol_id, &(new_info->under_vol_info), info->under_vol_info);
+
+ return(new_info);
+} /* end H5VL_pass_through_info_copy() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_info_cmp
+ *
+ * Purpose: Compare two of the connector's info objects, setting *cmp_value,
+ * following the same rules as strcmp().
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_info_cmp(int *cmp_value, const void *_info1, const void *_info2)
+{
+ const H5VL_pass_through_info_t *info1 = (const H5VL_pass_through_info_t *)_info1;
+ const H5VL_pass_through_info_t *info2 = (const H5VL_pass_through_info_t *)_info2;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL INFO Compare\n");
+#endif
+
+ /* Sanity checks */
+ assert(info1);
+ assert(info2);
+
+ /* Initialize comparison value */
+ *cmp_value = 0;
+
+ /* Compare under VOL connector classes */
+ H5VLcmp_connector_cls(cmp_value, info1->under_vol_id, info2->under_vol_id);
+ if(*cmp_value != 0)
+ return(0);
+
+ /* Compare under VOL connector info objects */
+ H5VLcmp_connector_info(cmp_value, info1->under_vol_id, info1->under_vol_info, info2->under_vol_info);
+ if(*cmp_value != 0)
+ return(0);
+
+ return(0);
+} /* end H5VL_pass_through_info_cmp() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_info_free
+ *
+ * Purpose: Release an info object for the connector.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_info_free(void *_info)
+{
+ H5VL_pass_through_info_t *info = (H5VL_pass_through_info_t *)_info;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL INFO Free\n");
+#endif
+
+ /* Release underlying VOL ID and info */
+ if(info->under_vol_info)
+ H5VLfree_connector_info(info->under_vol_id, info->under_vol_info);
+ H5Idec_ref(info->under_vol_id);
+
+ /* Free pass through info object itself */
+ free(info);
+
+ return(0);
+} /* end H5VL_pass_through_info_free() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_info_to_str
+ *
+ * Purpose: Serialize an info object for this connector into a string
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_info_to_str(const void *_info, char **str)
+{
+ const H5VL_pass_through_info_t *info = (const H5VL_pass_through_info_t *)_info;
+ H5VL_class_value_t under_value = (H5VL_class_value_t)-1;
+ char *under_vol_string = NULL;
+ size_t under_vol_str_len = 0;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL INFO To String\n");
+#endif
+
+ /* Get value and string for underlying VOL connector */
+ H5VLget_value(info->under_vol_id, &under_value);
+ H5VLconnector_info_to_str(info->under_vol_info, info->under_vol_id, &under_vol_string);
+
+ /* Determine length of underlying VOL info string */
+ if(under_vol_string)
+ under_vol_str_len = strlen(under_vol_string);
+
+ /* Allocate space for our info */
+ *str = (char *)H5allocate_memory(32 + under_vol_str_len, (hbool_t)0);
+ assert(*str);
+
+ /* Encode our info */
+ snprintf(*str, 32 + under_vol_str_len, "under_vol=%u;under_info={%s}", (unsigned)under_value, (under_vol_string ? under_vol_string : ""));
+
+ return(0);
+} /* end H5VL_pass_through_info_to_str() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_str_to_info
+ *
+ * Purpose: Deserialize a string into an info object for this connector.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_str_to_info(const char *str, void **_info)
+{
+ H5VL_pass_through_info_t *info;
+ unsigned under_vol_value;
+ const char *under_vol_info_start, *under_vol_info_end;
+ hid_t under_vol_id;
+ void *under_vol_info = NULL;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL INFO String To Info\n");
+#endif
+
+ /* Retrieve the underlying VOL connector value and info */
+ sscanf(str, "under_vol=%u;", &under_vol_value);
+ under_vol_id = H5VLregister_connector_by_value((H5VL_class_value_t)under_vol_value, H5P_DEFAULT);
+ under_vol_info_start = strchr(str, '{');
+ under_vol_info_end = strrchr(str, '}');
+ assert(under_vol_info_end > under_vol_info_start);
+ if(under_vol_info_end != (under_vol_info_start + 1)) {
+ char *under_vol_info_str;
+
+ under_vol_info_str = (char *)malloc((size_t)(under_vol_info_end - under_vol_info_start));
+ memcpy(under_vol_info_str, under_vol_info_start + 1, (size_t)((under_vol_info_end - under_vol_info_start) - 1));
+ *(under_vol_info_str + (under_vol_info_end - under_vol_info_start)) = '\0';
+
+ H5VLconnector_str_to_info(under_vol_info_str, under_vol_id, &under_vol_info);
+
+ free(under_vol_info_str);
+ } /* end else */
+
+ /* Allocate new pass-through VOL connector info and set its fields */
+ info = (H5VL_pass_through_info_t *)calloc(1, sizeof(H5VL_pass_through_info_t));
+ info->under_vol_id = under_vol_id;
+ info->under_vol_info = under_vol_info;
+
+ /* Set return value */
+ *_info = info;
+
+ return(0);
+} /* end H5VL_pass_through_str_to_info() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_get_object
+ *
+ * Purpose: Retrieve the 'data' for a VOL object.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *---------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_get_object(const void *obj)
+{
+ const H5VL_pass_through_t *o = (const H5VL_pass_through_t *)obj;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL Get object\n");
+#endif
+
+ return(H5VLget_object(o->under_object, o->under_vol_id));
+} /* end H5VL_pass_through_get_object() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_get_wrap_ctx
+ *
+ * Purpose: Retrieve a "wrapper context" for an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_get_wrap_ctx(const void *obj, void **wrap_ctx)
+{
+ const H5VL_pass_through_t *o = (const H5VL_pass_through_t *)obj;
+ H5VL_pass_through_wrap_ctx_t *new_wrap_ctx;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL WRAP CTX Get\n");
+#endif
+
+ /* Allocate new VOL object wrapping context for the pass through connector */
+ new_wrap_ctx = (H5VL_pass_through_wrap_ctx_t *)calloc(1, sizeof(H5VL_pass_through_wrap_ctx_t));
+
+ /* Increment reference count on underlying VOL ID, and copy the VOL info */
+ new_wrap_ctx->under_vol_id = o->under_vol_id;
+ H5Iinc_ref(new_wrap_ctx->under_vol_id);
+ H5VLget_wrap_ctx(o->under_object, o->under_vol_id, &new_wrap_ctx->under_wrap_ctx);
+
+ /* Set wrap context to return */
+ *wrap_ctx = new_wrap_ctx;
+
+ return(0);
+} /* end H5VL_pass_through_get_wrap_ctx() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_wrap_object
+ *
+ * Purpose: Use a "wrapper context" to wrap a data object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *---------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_wrap_object(void *obj, void *_wrap_ctx)
+{
+ H5VL_pass_through_wrap_ctx_t *wrap_ctx = (H5VL_pass_through_wrap_ctx_t *)_wrap_ctx;
+ H5VL_pass_through_t *new_obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL WRAP Object\n");
+#endif
+
+ /* Wrap the object with the underlying VOL */
+ under = H5VLwrap_object(obj, wrap_ctx->under_vol_id, wrap_ctx->under_wrap_ctx);
+ if(under)
+ new_obj = H5VL_pass_through_new_obj(under, wrap_ctx->under_vol_id);
+ else
+ new_obj = NULL;
+
+ return(new_obj);
+} /* end H5VL_pass_through_wrap_object() */
+
+
+/*---------------------------------------------------------------------------
+ * Function: H5VL_pass_through_free_wrap_ctx
+ *
+ * Purpose: Release a "wrapper context" for an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *---------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_free_wrap_ctx(void *_wrap_ctx)
+{
+ H5VL_pass_through_wrap_ctx_t *wrap_ctx = (H5VL_pass_through_wrap_ctx_t *)_wrap_ctx;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL WRAP CTX Free\n");
+#endif
+
+ /* Release underlying VOL ID and wrap context */
+ if(wrap_ctx->under_wrap_ctx)
+ H5VLfree_wrap_ctx(wrap_ctx->under_wrap_ctx, wrap_ctx->under_vol_id);
+ H5Idec_ref(wrap_ctx->under_vol_id);
+
+ /* Free pass through wrap context object itself */
+ free(wrap_ctx);
+
+ return(0);
+} /* end H5VL_pass_through_free_wrap_ctx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_attr_create
+ *
+ * Purpose: Creates an attribute on an object.
+ *
+ * Return: Success: Pointer to attribute object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_attr_create(void *obj, const H5VL_loc_params_t *loc_params,
+ const char *name, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *attr;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL ATTRIBUTE Create\n");
+#endif
+
+ under = H5VLattr_create(o->under_object, loc_params, o->under_vol_id, name, acpl_id, aapl_id, dxpl_id, req);
+ if(under) {
+ attr = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ attr = NULL;
+
+ return((void*)attr);
+} /* end H5VL_pass_through_attr_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_attr_open
+ *
+ * Purpose: Opens an attribute on an object.
+ *
+ * Return: Success: Pointer to attribute object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_attr_open(void *obj, const H5VL_loc_params_t *loc_params,
+ const char *name, hid_t aapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *attr;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL ATTRIBUTE Open\n");
+#endif
+
+ under = H5VLattr_open(o->under_object, loc_params, o->under_vol_id, name, aapl_id, dxpl_id, req);
+ if(under) {
+ attr = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ attr = NULL;
+
+ return((void *)attr);
+} /* end H5VL_pass_through_attr_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_attr_read
+ *
+ * Purpose: Reads data from attribute.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_attr_read(void *attr, hid_t mem_type_id, void *buf,
+ hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)attr;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL ATTRIBUTE Read\n");
+#endif
+
+ ret_value = H5VLattr_read(o->under_object, o->under_vol_id, mem_type_id, buf, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_attr_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_attr_write
+ *
+ * Purpose: Writes data to attribute.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_attr_write(void *attr, hid_t mem_type_id, const void *buf,
+ hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)attr;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL ATTRIBUTE Write\n");
+#endif
+
+ ret_value = H5VLattr_write(o->under_object, o->under_vol_id, mem_type_id, buf, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_attr_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_attr_get
+ *
+ * Purpose: Gets information about an attribute
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id,
+ void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL ATTRIBUTE Get\n");
+#endif
+
+ ret_value = H5VLattr_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_attr_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_attr_specific
+ *
+ * Purpose: Specific operation on attribute
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params,
+ H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL ATTRIBUTE Specific\n");
+#endif
+
+ ret_value = H5VLattr_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_attr_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_attr_optional
+ *
+ * Purpose: Perform a connector-specific operation on an attribute
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_attr_optional(void *obj, hid_t dxpl_id, void **req,
+ va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL ATTRIBUTE Optional\n");
+#endif
+
+ ret_value = H5VLattr_optional(o->under_object, o->under_vol_id, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_attr_optional() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_attr_close
+ *
+ * Purpose: Closes an attribute.
+ *
+ * Return: Success: 0
+ * Failure: -1, attr not closed.
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_attr_close(void *attr, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)attr;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL ATTRIBUTE Close\n");
+#endif
+
+ ret_value = H5VLattr_close(o->under_object, o->under_vol_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ /* Release our wrapper, if underlying attribute was closed */
+ if(ret_value >= 0)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_attr_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_dataset_create
+ *
+ * Purpose: Creates a dataset in a container
+ *
+ * Return: Success: Pointer to a dataset object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_dataset_create(void *obj, const H5VL_loc_params_t *loc_params,
+ const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *dset;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATASET Create\n");
+#endif
+
+ under = H5VLdataset_create(o->under_object, loc_params, o->under_vol_id, name, dcpl_id, dapl_id, dxpl_id, req);
+ if(under) {
+ dset = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ dset = NULL;
+
+ return((void *)dset);
+} /* end H5VL_pass_through_dataset_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_dataset_open
+ *
+ * Purpose: Opens a dataset in a container
+ *
+ * Return: Success: Pointer to a dataset object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_dataset_open(void *obj, const H5VL_loc_params_t *loc_params,
+ const char *name, hid_t dapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *dset;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATASET Open\n");
+#endif
+
+ under = H5VLdataset_open(o->under_object, loc_params, o->under_vol_id, name, dapl_id, dxpl_id, req);
+ if(under) {
+ dset = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ dset = NULL;
+
+ return((void *)dset);
+} /* end H5VL_pass_through_dataset_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_dataset_read
+ *
+ * Purpose: Reads data elements from a dataset into a buffer.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_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)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATASET Read\n");
+#endif
+
+ ret_value = H5VLdataset_read(o->under_object, o->under_vol_id, mem_type_id, mem_space_id, file_space_id, plist_id, buf, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_dataset_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_dataset_write
+ *
+ * Purpose: Writes data elements from a buffer into a dataset.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_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)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATASET Write\n");
+#endif
+
+ ret_value = H5VLdataset_write(o->under_object, o->under_vol_id, mem_type_id, mem_space_id, file_space_id, plist_id, buf, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_dataset_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_dataset_get
+ *
+ * Purpose: Gets information about a dataset
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATASET Get\n");
+#endif
+
+ ret_value = H5VLdataset_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_dataset_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_dataset_specific
+ *
+ * Purpose: Specific operation on a dataset
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL H5Dspecific\n");
+#endif
+
+ ret_value = H5VLdataset_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_dataset_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_dataset_optional
+ *
+ * Purpose: Perform a connector-specific operation on a dataset
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_dataset_optional(void *obj, hid_t dxpl_id, void **req,
+ va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATASET Optional\n");
+#endif
+
+ ret_value = H5VLdataset_optional(o->under_object, o->under_vol_id, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_dataset_optional() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_dataset_close
+ *
+ * Purpose: Closes a dataset.
+ *
+ * Return: Success: 0
+ * Failure: -1, dataset not closed.
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_dataset_close(void *dset, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATASET Close\n");
+#endif
+
+ ret_value = H5VLdataset_close(o->under_object, o->under_vol_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ /* Release our wrapper, if underlying dataset was closed */
+ if(ret_value >= 0)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_dataset_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_datatype_commit
+ *
+ * Purpose: Commits a datatype inside a container.
+ *
+ * Return: Success: Pointer to datatype object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params,
+ const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id,
+ hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *dt;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATATYPE Commit\n");
+#endif
+
+ under = H5VLdatatype_commit(o->under_object, loc_params, o->under_vol_id, name, type_id, lcpl_id, tcpl_id, tapl_id, dxpl_id, req);
+ if(under) {
+ dt = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ dt = NULL;
+
+ return((void *)dt);
+} /* end H5VL_pass_through_datatype_commit() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_datatype_open
+ *
+ * Purpose: Opens a named datatype inside a container.
+ *
+ * Return: Success: Pointer to datatype object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_datatype_open(void *obj, const H5VL_loc_params_t *loc_params,
+ const char *name, hid_t tapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *dt;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATATYPE Open\n");
+#endif
+
+ under = H5VLdatatype_open(o->under_object, loc_params, o->under_vol_id, name, tapl_id, dxpl_id, req);
+ if(under) {
+ dt = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ dt = NULL;
+
+ return((void *)dt);
+} /* end H5VL_pass_through_datatype_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_datatype_get
+ *
+ * Purpose: Get information about a datatype
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)dt;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATATYPE Get\n");
+#endif
+
+ ret_value = H5VLdatatype_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_datatype_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_datatype_specific
+ *
+ * Purpose: Specific operations for datatypes
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATATYPE Specific\n");
+#endif
+
+ ret_value = H5VLdatatype_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_datatype_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_datatype_optional
+ *
+ * Purpose: Perform a connector-specific operation on a datatype
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_datatype_optional(void *obj, hid_t dxpl_id, void **req,
+ va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATATYPE Optional\n");
+#endif
+
+ ret_value = H5VLdatatype_optional(o->under_object, o->under_vol_id, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_datatype_optional() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_datatype_close
+ *
+ * Purpose: Closes a datatype.
+ *
+ * Return: Success: 0
+ * Failure: -1, datatype not closed.
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_datatype_close(void *dt, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)dt;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL DATATYPE Close\n");
+#endif
+
+ assert(o->under_object);
+
+ ret_value = H5VLdatatype_close(o->under_object, o->under_vol_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ /* Release our wrapper, if underlying datatype was closed */
+ if(ret_value >= 0)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_datatype_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_file_create
+ *
+ * Purpose: Creates a container using this connector
+ *
+ * Return: Success: Pointer to a file object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_file_create(const char *name, unsigned flags, hid_t fcpl_id,
+ hid_t fapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_info_t *info;
+ H5VL_pass_through_t *file;
+ hid_t under_fapl_id;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL FILE Create\n");
+#endif
+
+ /* Get copy of our VOL info from FAPL */
+ H5Pget_vol_info(fapl_id, (void **)&info);
+
+ /* Copy the FAPL */
+ under_fapl_id = H5Pcopy(fapl_id);
+
+ /* Set the VOL ID and info for the underlying FAPL */
+ H5Pset_vol(under_fapl_id, info->under_vol_id, info->under_vol_info);
+
+ /* Open the file with the underlying VOL connector */
+ under = H5VLfile_create(name, flags, fcpl_id, under_fapl_id, dxpl_id, req);
+ if(under) {
+ file = H5VL_pass_through_new_obj(under, info->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, info->under_vol_id);
+ } /* end if */
+ else
+ file = NULL;
+
+ /* Close underlying FAPL */
+ H5Pclose(under_fapl_id);
+
+ /* Release copy of our VOL info */
+ H5VL_pass_through_info_free(info);
+
+ return((void *)file);
+} /* end H5VL_pass_through_file_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_file_open
+ *
+ * Purpose: Opens a container created with this connector
+ *
+ * Return: Success: Pointer to a file object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id,
+ hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_info_t *info;
+ H5VL_pass_through_t *file;
+ hid_t under_fapl_id;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL FILE Open\n");
+#endif
+
+ /* Get copy of our VOL info from FAPL */
+ H5Pget_vol_info(fapl_id, (void **)&info);
+
+ /* Copy the FAPL */
+ under_fapl_id = H5Pcopy(fapl_id);
+
+ /* Set the VOL ID and info for the underlying FAPL */
+ H5Pset_vol(under_fapl_id, info->under_vol_id, info->under_vol_info);
+
+ /* Open the file with the underlying VOL connector */
+ under = H5VLfile_open(name, flags, under_fapl_id, dxpl_id, req);
+ if(under) {
+ file = H5VL_pass_through_new_obj(under, info->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, info->under_vol_id);
+ } /* end if */
+ else
+ file = NULL;
+
+ /* Close underlying FAPL */
+ H5Pclose(under_fapl_id);
+
+ /* Release copy of our VOL info */
+ H5VL_pass_through_info_free(info);
+
+ return((void *)file);
+} /* end H5VL_pass_through_file_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_file_get
+ *
+ * Purpose: Get info about a file
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id,
+ void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)file;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL FILE Get\n");
+#endif
+
+ ret_value = H5VLfile_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_file_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_file_specific_reissue
+ *
+ * Purpose: Re-wrap vararg arguments into a va_list and reissue the
+ * file specific callback to the underlying VOL connector.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id,
+ H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req, ...)
+{
+ va_list arguments;
+ herr_t ret_value;
+
+ va_start(arguments, req);
+ ret_value = H5VLfile_specific(obj, connector_id, specific_type, dxpl_id, req, arguments);
+ va_end(arguments);
+
+ return(ret_value);
+} /* end H5VL_pass_through_file_specific_reissue() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_file_specific
+ *
+ * Purpose: Specific operation on file
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)file;
+ hid_t under_vol_id = -1;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL FILE Specific\n");
+#endif
+
+ /* Unpack arguments to get at the child file pointer when mounting a file */
+ if(specific_type == H5VL_FILE_MOUNT) {
+ H5I_type_t loc_type;
+ const char *name;
+ H5VL_pass_through_t *child_file;
+ hid_t plist_id;
+
+ /* Retrieve parameters for 'mount' operation, so we can unwrap the child file */
+ loc_type = va_arg(arguments, H5I_type_t);
+ name = va_arg(arguments, const char *);
+ child_file = (H5VL_pass_through_t *)va_arg(arguments, void *);
+ plist_id = va_arg(arguments, hid_t);
+
+ /* Keep the correct underlying VOL ID for possible async request token */
+ under_vol_id = o->under_vol_id;
+
+ /* Re-issue 'file specific' call, using the unwrapped pieces */
+ ret_value = H5VL_pass_through_file_specific_reissue(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, loc_type, name, child_file->under_object, plist_id);
+ } /* end if */
+ else if(specific_type == H5VL_FILE_IS_ACCESSIBLE) {
+ H5VL_pass_through_info_t *info;
+ hid_t fapl_id, under_fapl_id;
+ const char *name;
+ htri_t *ret;
+
+ /* Get the arguments for the 'is accessible' check */
+ fapl_id = va_arg(arguments, hid_t);
+ name = va_arg(arguments, const char *);
+ ret = va_arg(arguments, htri_t *);
+
+ /* Get copy of our VOL info from FAPL */
+ H5Pget_vol_info(fapl_id, (void **)&info);
+
+ /* Copy the FAPL */
+ under_fapl_id = H5Pcopy(fapl_id);
+
+ /* Set the VOL ID and info for the underlying FAPL */
+ H5Pset_vol(under_fapl_id, info->under_vol_id, info->under_vol_info);
+
+ /* Keep the correct underlying VOL ID for possible async request token */
+ under_vol_id = info->under_vol_id;
+
+ /* Re-issue 'file specific' call */
+ ret_value = H5VL_pass_through_file_specific_reissue(NULL, info->under_vol_id, specific_type, dxpl_id, req, under_fapl_id, name, ret);
+
+ /* Close underlying FAPL */
+ H5Pclose(under_fapl_id);
+
+ /* Release copy of our VOL info */
+ H5VL_pass_through_info_free(info);
+ } /* end else-if */
+ else {
+ va_list my_arguments;
+
+ /* Make a copy of the argument list for later, if reopening */
+ if(specific_type == H5VL_FILE_REOPEN)
+ va_copy(my_arguments, arguments);
+
+ /* Keep the correct underlying VOL ID for possible async request token */
+ under_vol_id = o->under_vol_id;
+
+ ret_value = H5VLfile_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
+
+ /* Wrap file struct pointer, if we reopened one */
+ if(specific_type == H5VL_FILE_REOPEN) {
+ if(ret_value >= 0) {
+ void **ret = va_arg(my_arguments, void **);
+
+ if(ret && *ret)
+ *ret = H5VL_pass_through_new_obj(*ret, o->under_vol_id);
+ } /* end if */
+
+ /* Finish use of copied vararg list */
+ va_end(my_arguments);
+ } /* end if */
+ } /* end else */
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_file_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_file_optional
+ *
+ * Purpose: Perform a connector-specific operation on a file
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_file_optional(void *file, hid_t dxpl_id, void **req,
+ va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)file;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL File Optional\n");
+#endif
+
+ ret_value = H5VLfile_optional(o->under_object, o->under_vol_id, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_file_optional() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_file_close
+ *
+ * Purpose: Closes a file.
+ *
+ * Return: Success: 0
+ * Failure: -1, file not closed.
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_file_close(void *file, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)file;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL FILE Close\n");
+#endif
+
+ ret_value = H5VLfile_close(o->under_object, o->under_vol_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ /* Release our wrapper, if underlying file was closed */
+ if(ret_value >= 0)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_file_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_group_create
+ *
+ * Purpose: Creates a group inside a container
+ *
+ * Return: Success: Pointer to a group object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_group_create(void *obj, const H5VL_loc_params_t *loc_params,
+ const char *name, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *group;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL GROUP Create\n");
+#endif
+
+ under = H5VLgroup_create(o->under_object, loc_params, o->under_vol_id, name, gcpl_id, gapl_id, dxpl_id, req);
+ if(under) {
+ group = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ group = NULL;
+
+ return((void *)group);
+} /* end H5VL_pass_through_group_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_group_open
+ *
+ * Purpose: Opens a group inside a container
+ *
+ * Return: Success: Pointer to a group object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_group_open(void *obj, const H5VL_loc_params_t *loc_params,
+ const char *name, hid_t gapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *group;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL GROUP Open\n");
+#endif
+
+ under = H5VLgroup_open(o->under_object, loc_params, o->under_vol_id, name, gapl_id, dxpl_id, req);
+ if(under) {
+ group = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ group = NULL;
+
+ return((void *)group);
+} /* end H5VL_pass_through_group_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_group_get
+ *
+ * Purpose: Get info about a group
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id,
+ void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL GROUP Get\n");
+#endif
+
+ ret_value = H5VLgroup_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_group_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_group_specific
+ *
+ * Purpose: Specific operation on a group
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type,
+ hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL GROUP Specific\n");
+#endif
+
+ ret_value = H5VLgroup_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_group_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_group_optional
+ *
+ * Purpose: Perform a connector-specific operation on a group
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_group_optional(void *obj, hid_t dxpl_id, void **req,
+ va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL GROUP Optional\n");
+#endif
+
+ ret_value = H5VLgroup_optional(o->under_object, o->under_vol_id, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_group_optional() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_group_close
+ *
+ * Purpose: Closes a group.
+ *
+ * Return: Success: 0
+ * Failure: -1, group not closed.
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_group_close(void *grp, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)grp;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL H5Gclose\n");
+#endif
+
+ ret_value = H5VLgroup_close(o->under_object, o->under_vol_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ /* Release our wrapper, if underlying file was closed */
+ if(ret_value >= 0)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_group_close() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_link_create
+ *
+ * Purpose: Creates a hard / soft / UD / external link.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ hid_t under_vol_id = -1;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL LINK Create\n");
+#endif
+
+ /* Try to retrieve the "under" VOL id */
+ if(o)
+ under_vol_id = o->under_vol_id;
+
+ /* Fix up the link target object for hard link creation */
+ if(H5VL_LINK_CREATE_HARD == create_type) {
+ void *cur_obj;
+
+ /* Retrieve the object for the link target */
+ H5Pget(lcpl_id, H5VL_PROP_LINK_TARGET, &cur_obj);
+
+ /* If it's a non-NULL pointer, find the 'under object' and re-set the property */
+ if(cur_obj) {
+ /* Check if we still need the "under" VOL ID */
+ if(under_vol_id < 0)
+ under_vol_id = ((H5VL_pass_through_t *)cur_obj)->under_vol_id;
+
+ /* Set the object for the link target */
+ H5Pset(lcpl_id, H5VL_PROP_LINK_TARGET, &(((H5VL_pass_through_t *)cur_obj)->under_object));
+ } /* end if */
+ } /* end if */
+
+ ret_value = H5VLlink_create(create_type, (o ? o->under_object : NULL), loc_params, under_vol_id, lcpl_id, lapl_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_link_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_link_copy
+ *
+ * Purpose: Renames an object within an HDF5 container and copies it to a new
+ * group. The original name SRC is unlinked from the group graph
+ * and then inserted with the new name DST (which can specify a
+ * new path for the object) as an atomic operation. The names
+ * are interpreted relative to SRC_LOC_ID and
+ * DST_LOC_ID, which are either file IDs or group ID.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1,
+ void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id,
+ hid_t lapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o_src = (H5VL_pass_through_t *)src_obj;
+ H5VL_pass_through_t *o_dst = (H5VL_pass_through_t *)dst_obj;
+ hid_t under_vol_id = -1;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL LINK Copy\n");
+#endif
+
+ /* Retrieve the "under" VOL id */
+ if(o_src)
+ under_vol_id = o_src->under_vol_id;
+ else if(o_dst)
+ under_vol_id = o_dst->under_vol_id;
+ assert(under_vol_id > 0);
+
+ ret_value = H5VLlink_copy((o_src ? o_src->under_object : NULL), loc_params1, (o_dst ? o_dst->under_object : NULL), loc_params2, under_vol_id, lcpl_id, lapl_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_link_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function:
+H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1,
+ *
+ * Purpose: Moves a link within an HDF5 file to a new group. The original
+ * name SRC is unlinked from the group graph
+ * and then inserted with the new name DST (which can specify a
+ * new path for the object) as an atomic operation. The names
+ * are interpreted relative to SRC_LOC_ID and
+ * DST_LOC_ID, which are either file IDs or group ID.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1,
+ void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id,
+ hid_t lapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *o_src = (H5VL_pass_through_t *)src_obj;
+ H5VL_pass_through_t *o_dst = (H5VL_pass_through_t *)dst_obj;
+ hid_t under_vol_id = -1;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL LINK Move\n");
+#endif
+
+ /* Retrieve the "under" VOL id */
+ if(o_src)
+ under_vol_id = o_src->under_vol_id;
+ else if(o_dst)
+ under_vol_id = o_dst->under_vol_id;
+ assert(under_vol_id > 0);
+
+ ret_value = H5VLlink_move((o_src ? o_src->under_object : NULL), loc_params1, (o_dst ? o_dst->under_object : NULL), loc_params2, under_vol_id, lcpl_id, lapl_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_link_move() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_link_get
+ *
+ * Purpose: Get info about a link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params,
+ H5VL_link_get_t get_type, hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL LINK Get\n");
+#endif
+
+ ret_value = H5VLlink_get(o->under_object, loc_params, o->under_vol_id, get_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_link_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_link_specific
+ *
+ * Purpose: Specific operation on a link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params,
+ H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL LINK Specific\n");
+#endif
+
+ ret_value = H5VLlink_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_link_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_link_optional
+ *
+ * Purpose: Perform a connector-specific operation on a link
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_link_optional(void *obj, hid_t dxpl_id, void **req,
+ va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL LINK Optional\n");
+#endif
+
+ ret_value = H5VLlink_optional(o->under_object, o->under_vol_id, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_link_optional() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_object_open
+ *
+ * Purpose: Opens an object inside a container.
+ *
+ * Return: Success: Pointer to object
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5VL_pass_through_object_open(void *obj, const H5VL_loc_params_t *loc_params,
+ H5I_type_t *opened_type, hid_t dxpl_id, void **req)
+{
+ H5VL_pass_through_t *new_obj;
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ void *under;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL OBJECT Open\n");
+#endif
+
+ under = H5VLobject_open(o->under_object, loc_params, o->under_vol_id, opened_type, dxpl_id, req);
+ if(under) {
+ new_obj = H5VL_pass_through_new_obj(under, o->under_vol_id);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+ } /* end if */
+ else
+ new_obj = NULL;
+
+ return((void *)new_obj);
+} /* end H5VL_pass_through_object_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_object_copy
+ *
+ * Purpose: Copies an object inside a container.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params,
+ const char *src_name, void *dst_obj, const H5VL_loc_params_t *dst_loc_params,
+ const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id,
+ void **req)
+{
+ H5VL_pass_through_t *o_src = (H5VL_pass_through_t *)src_obj;
+ H5VL_pass_through_t *o_dst = (H5VL_pass_through_t *)dst_obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL OBJECT Copy\n");
+#endif
+
+ ret_value = H5VLobject_copy(o_src->under_object, src_loc_params, src_name, o_dst->under_object, dst_loc_params, dst_name, o_src->under_vol_id, ocpypl_id, lcpl_id, dxpl_id, req);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o_src->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_object_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_object_get
+ *
+ * Purpose: Get info about an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type, hid_t dxpl_id, void **req, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL OBJECT Get\n");
+#endif
+
+ ret_value = H5VLobject_get(o->under_object, loc_params, o->under_vol_id, get_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_object_get() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_object_specific
+ *
+ * Purpose: Specific operation on an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params,
+ H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req,
+ va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL OBJECT Specific\n");
+#endif
+
+ ret_value = H5VLobject_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_object_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_object_optional
+ *
+ * Purpose: Perform a connector-specific operation for an object
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_object_optional(void *obj, hid_t dxpl_id, void **req,
+ va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL OBJECT Optional\n");
+#endif
+
+ ret_value = H5VLobject_optional(o->under_object, o->under_vol_id, dxpl_id, req, arguments);
+
+ /* Check for async request */
+ if(req && *req)
+ *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
+
+ return(ret_value);
+} /* end H5VL_pass_through_object_optional() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_request_wait
+ *
+ * Purpose: Wait (with a timeout) for an async operation to complete
+ *
+ * Note: Releases the request if the operation has completed and the
+ * connector callback succeeds
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_request_wait(void *obj, uint64_t timeout,
+ H5ES_status_t *status)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL REQUEST Wait\n");
+#endif
+
+ ret_value = H5VLrequest_wait(o->under_object, o->under_vol_id, timeout, status);
+
+ if(ret_value >= 0 && *status != H5ES_STATUS_IN_PROGRESS)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_request_wait() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_request_notify
+ *
+ * Purpose: Registers a user callback to be invoked when an asynchronous
+ * operation completes
+ *
+ * Note: Releases the request, if connector callback succeeds
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL REQUEST Wait\n");
+#endif
+
+ ret_value = H5VLrequest_notify(o->under_object, o->under_vol_id, cb, ctx);
+
+ if(ret_value >= 0)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_request_notify() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_request_cancel
+ *
+ * Purpose: Cancels an asynchronous operation
+ *
+ * Note: Releases the request, if connector callback succeeds
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_request_cancel(void *obj)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL REQUEST Cancel\n");
+#endif
+
+ ret_value = H5VLrequest_cancel(o->under_object, o->under_vol_id);
+
+ if(ret_value >= 0)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_request_cancel() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_request_specific_reissue
+ *
+ * Purpose: Re-wrap vararg arguments into a va_list and reissue the
+ * request specific callback to the underlying VOL connector.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id,
+ H5VL_request_specific_t specific_type, ...)
+{
+ va_list arguments;
+ herr_t ret_value;
+
+ va_start(arguments, specific_type);
+ ret_value = H5VLrequest_specific(obj, connector_id, specific_type, arguments);
+ va_end(arguments);
+
+ return(ret_value);
+} /* end H5VL_pass_through_request_specific_reissue() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_request_specific
+ *
+ * Purpose: Specific operation on a request
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_type,
+ va_list arguments)
+{
+ herr_t ret_value = -1;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL REQUEST Specific\n");
+#endif
+
+ if(H5VL_REQUEST_WAITANY == specific_type ||
+ H5VL_REQUEST_WAITSOME == specific_type ||
+ H5VL_REQUEST_WAITALL == specific_type) {
+ va_list tmp_arguments;
+ size_t req_count;
+
+ /* Sanity check */
+ assert(obj == NULL);
+
+ /* Get enough info to call the underlying connector */
+ va_copy(tmp_arguments, arguments);
+ req_count = va_arg(tmp_arguments, size_t);
+
+ /* Can only use a request to invoke the underlying VOL connector when there's >0 requests */
+ if(req_count > 0) {
+ void **req_array;
+ void **under_req_array;
+ uint64_t timeout;
+ H5VL_pass_through_t *o;
+ size_t u; /* Local index variable */
+
+ /* Get the request array */
+ req_array = va_arg(tmp_arguments, void **);
+
+ /* Get a request to use for determining the underlying VOL connector */
+ o = (H5VL_pass_through_t *)req_array[0];
+
+ /* Create array of underlying VOL requests */
+ under_req_array = (void **)malloc(req_count * sizeof(void **));
+ for(u = 0; u < req_count; u++)
+ under_req_array[u] = ((H5VL_pass_through_t *)req_array[u])->under_object;
+
+ /* Remove the timeout value from the vararg list (it's used in all the calls below) */
+ timeout = va_arg(tmp_arguments, uint64_t);
+
+ /* Release requests that have completed */
+ if(H5VL_REQUEST_WAITANY == specific_type) {
+ size_t *index; /* Pointer to the index of completed request */
+ H5ES_status_t *status; /* Pointer to the request's status */
+
+ /* Retrieve the remaining arguments */
+ index = va_arg(tmp_arguments, size_t *);
+ assert(*index <= req_count);
+ status = va_arg(tmp_arguments, H5ES_status_t *);
+
+ /* Reissue the WAITANY 'request specific' call */
+ ret_value = H5VL_pass_through_request_specific_reissue(o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout, index, status);
+
+ /* Release the completed request, if it completed */
+ if(ret_value >= 0 && *status != H5ES_STATUS_IN_PROGRESS) {
+ H5VL_pass_through_t *tmp_o;
+
+ tmp_o = (H5VL_pass_through_t *)req_array[*index];
+ H5VL_pass_through_free_obj(tmp_o);
+ } /* end if */
+ } /* end if */
+ else if(H5VL_REQUEST_WAITSOME == specific_type) {
+ size_t *outcount; /* # of completed requests */
+ unsigned *array_of_indices; /* Array of indices for completed requests */
+ H5ES_status_t *array_of_statuses; /* Array of statuses for completed requests */
+
+ /* Retrieve the remaining arguments */
+ outcount = va_arg(tmp_arguments, size_t *);
+ assert(*outcount <= req_count);
+ array_of_indices = va_arg(tmp_arguments, unsigned *);
+ array_of_statuses = va_arg(tmp_arguments, H5ES_status_t *);
+
+ /* Reissue the WAITSOME 'request specific' call */
+ ret_value = H5VL_pass_through_request_specific_reissue(o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout, outcount, array_of_indices, array_of_statuses);
+
+ /* If any requests completed, release them */
+ if(ret_value >= 0 && *outcount > 0) {
+ unsigned *idx_array; /* Array of indices of completed requests */
+
+ /* Retrieve the array of completed request indices */
+ idx_array = va_arg(tmp_arguments, unsigned *);
+
+ /* Release the completed requests */
+ for(u = 0; u < *outcount; u++) {
+ H5VL_pass_through_t *tmp_o;
+
+ tmp_o = (H5VL_pass_through_t *)req_array[idx_array[u]];
+ H5VL_pass_through_free_obj(tmp_o);
+ } /* end for */
+ } /* end if */
+ } /* end else-if */
+ else { /* H5VL_REQUEST_WAITALL == specific_type */
+ H5ES_status_t *array_of_statuses; /* Array of statuses for completed requests */
+
+ /* Retrieve the remaining arguments */
+ array_of_statuses = va_arg(tmp_arguments, H5ES_status_t *);
+
+ /* Reissue the WAITALL 'request specific' call */
+ ret_value = H5VL_pass_through_request_specific_reissue(o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout, array_of_statuses);
+
+ /* Release the completed requests */
+ if(ret_value >= 0) {
+ for(u = 0; u < req_count; u++) {
+ if(array_of_statuses[u] != H5ES_STATUS_IN_PROGRESS) {
+ H5VL_pass_through_t *tmp_o;
+
+ tmp_o = (H5VL_pass_through_t *)req_array[u];
+ H5VL_pass_through_free_obj(tmp_o);
+ } /* end if */
+ } /* end for */
+ } /* end if */
+ } /* end else */
+
+ /* Release array of requests for underlying connector */
+ free(under_req_array);
+ } /* end if */
+
+ /* Finish use of copied vararg list */
+ va_end(tmp_arguments);
+ } /* end if */
+ else
+ assert(0 && "Unknown 'specific' operation");
+
+ return(ret_value);
+} /* end H5VL_pass_through_request_specific() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_request_optional
+ *
+ * Purpose: Perform a connector-specific operation for a request
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_request_optional(void *obj, va_list arguments)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL REQUEST Optional\n");
+#endif
+
+ ret_value = H5VLrequest_optional(o->under_object, o->under_vol_id, arguments);
+
+ return(ret_value);
+} /* end H5VL_pass_through_request_optional() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_pass_through_request_free
+ *
+ * Purpose: Releases a request, allowing the operation to complete without
+ * application tracking
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_pass_through_request_free(void *obj)
+{
+ H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
+ herr_t ret_value;
+
+#ifdef ENABLE_LOGGING
+ printf("------- PASS THROUGH VOL REQUEST Free\n");
+#endif
+
+ ret_value = H5VLrequest_free(o->under_object, o->under_vol_id);
+
+ if(ret_value >= 0)
+ H5VL_pass_through_free_obj(o);
+
+ return(ret_value);
+} /* end H5VL_pass_through_request_free() */
+