1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * All rights reserved. *
4 * *
5 * This file is part of HDF5. The full HDF5 copyright notice, including *
6 * terms governing use, modification, and redistribution, is contained in *
7 * the COPYING file, which can be found at the root of the source code *
8 * distribution tree, or in https://www.hdfgroup.org/licenses. *
9 * If you do not have access to either file, you may request a copy from *
10 * help@hdfgroup.org. *
11 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13 /*
14 * Purpose: This is a "pass through" VOL connector, which forwards each
15 * VOL callback to an underlying connector.
16 *
17 * It is designed as an example VOL connector for developers to
18 * use when creating new connectors, especially connectors that
19 * are outside of the HDF5 library. As such, it should _NOT_
20 * include _any_ private HDF5 header files. This connector should
21 * therefore only make public HDF5 API calls and use standard C /
22 * POSIX calls.
23 *
24 * Note that the HDF5 error stack must be preserved on code paths
25 * that could be invoked when the underlying VOL connector's
26 * callback can fail.
27 *
28 */
29
30 /* Header files needed */
31 /* Do NOT include private HDF5 files here! */
32 #include <assert.h>
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 /* Public HDF5 file */
39 #include "hdf5.h"
40
41 /* This connector's header */
42 #include "H5VLpassthru.h"
43
44 /**********/
45 /* Macros */
46 /**********/
47
48 /* Whether to display log messge when callback is invoked */
49 /* (Uncomment to enable) */
50 /* #define ENABLE_PASSTHRU_LOGGING */
51
52 /* Hack for missing va_copy() in old Visual Studio editions
53 * (from H5win2_defs.h - used on VS2012 and earlier)
54 */
55 #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER < 1800)
56 #define va_copy(D, S) ((D) = (S))
57 #endif
58
59 /************/
60 /* Typedefs */
61 /************/
62
63 /* The pass through VOL info object */
64 typedef struct H5VL_pass_through_t {
65 hid_t under_vol_id; /* ID for underlying VOL connector */
66 void *under_object; /* Info object for underlying VOL connector */
67 } H5VL_pass_through_t;
68
69 /* The pass through VOL wrapper context */
70 typedef struct H5VL_pass_through_wrap_ctx_t {
71 hid_t under_vol_id; /* VOL ID for under VOL */
72 void *under_wrap_ctx; /* Object wrapping context for under VOL */
73 } H5VL_pass_through_wrap_ctx_t;
74
75 /********************* */
76 /* Function prototypes */
77 /********************* */
78
79 /* Helper routines */
80 static herr_t H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id,
81 H5VL_file_specific_t specific_type, hid_t dxpl_id,
82 void **req, ...);
83 static herr_t H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id,
84 H5VL_request_specific_t specific_type, ...);
85 static herr_t H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type, void *obj,
86 const H5VL_loc_params_t *loc_params, hid_t connector_id,
87 hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id, void **req,
88 ...);
89 static H5VL_pass_through_t *H5VL_pass_through_new_obj(void *under_obj, hid_t under_vol_id);
90 static herr_t H5VL_pass_through_free_obj(H5VL_pass_through_t *obj);
91
92 /* "Management" callbacks */
93 static herr_t H5VL_pass_through_init(hid_t vipl_id);
94 static herr_t H5VL_pass_through_term(void);
95
96 /* VOL info callbacks */
97 static void * H5VL_pass_through_info_copy(const void *info);
98 static herr_t H5VL_pass_through_info_cmp(int *cmp_value, const void *info1, const void *info2);
99 static herr_t H5VL_pass_through_info_free(void *info);
100 static herr_t H5VL_pass_through_info_to_str(const void *info, char **str);
101 static herr_t H5VL_pass_through_str_to_info(const char *str, void **info);
102
103 /* VOL object wrap / retrieval callbacks */
104 static void * H5VL_pass_through_get_object(const void *obj);
105 static herr_t H5VL_pass_through_get_wrap_ctx(const void *obj, void **wrap_ctx);
106 static void * H5VL_pass_through_wrap_object(void *obj, H5I_type_t obj_type, void *wrap_ctx);
107 static void * H5VL_pass_through_unwrap_object(void *obj);
108 static herr_t H5VL_pass_through_free_wrap_ctx(void *obj);
109
110 /* Attribute callbacks */
111 static void * H5VL_pass_through_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
112 hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id,
113 hid_t dxpl_id, void **req);
114 static void * H5VL_pass_through_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
115 hid_t aapl_id, hid_t dxpl_id, void **req);
116 static herr_t H5VL_pass_through_attr_read(void *attr, hid_t mem_type_id, void *buf, hid_t dxpl_id,
117 void **req);
118 static herr_t H5VL_pass_through_attr_write(void *attr, hid_t mem_type_id, const void *buf, hid_t dxpl_id,
119 void **req);
120 static herr_t H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req,
121 va_list arguments);
122 static herr_t H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params,
123 H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req,
124 va_list arguments);
125 static herr_t H5VL_pass_through_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id,
126 void **req, va_list arguments);
127 static herr_t H5VL_pass_through_attr_close(void *attr, hid_t dxpl_id, void **req);
128
129 /* Dataset callbacks */
130 static void * H5VL_pass_through_dataset_create(void *obj, const H5VL_loc_params_t *loc_params,
131 const char *name, hid_t lcpl_id, hid_t type_id, hid_t space_id,
132 hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id, void **req);
133 static void * H5VL_pass_through_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
134 hid_t dapl_id, hid_t dxpl_id, void **req);
135 static herr_t H5VL_pass_through_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id,
136 hid_t file_space_id, hid_t plist_id, void *buf, void **req);
137 static herr_t H5VL_pass_through_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id,
138 hid_t file_space_id, hid_t plist_id, const void *buf,
139 void **req);
140 static herr_t H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id,
141 void **req, va_list arguments);
142 static herr_t H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type,
143 hid_t dxpl_id, void **req, va_list arguments);
144 static herr_t H5VL_pass_through_dataset_optional(void *obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id,
145 void **req, va_list arguments);
146 static herr_t H5VL_pass_through_dataset_close(void *dset, hid_t dxpl_id, void **req);
147
148 /* Datatype callbacks */
149 static void *H5VL_pass_through_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params,
150 const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id,
151 hid_t tapl_id, hid_t dxpl_id, void **req);
152 static void *H5VL_pass_through_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
153 hid_t tapl_id, hid_t dxpl_id, void **req);
154 static herr_t H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id,
155 void **req, va_list arguments);
156 static herr_t H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type,
157 hid_t dxpl_id, void **req, va_list arguments);
158 static herr_t H5VL_pass_through_datatype_optional(void *obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id,
159 void **req, va_list arguments);
160 static herr_t H5VL_pass_through_datatype_close(void *dt, hid_t dxpl_id, void **req);
161
162 /* File callbacks */
163 static void * H5VL_pass_through_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
164 hid_t dxpl_id, void **req);
165 static void * H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id,
166 void **req);
167 static herr_t H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req,
168 va_list arguments);
169 static herr_t H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id,
170 void **req, va_list arguments);
171 static herr_t H5VL_pass_through_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t dxpl_id,
172 void **req, va_list arguments);
173 static herr_t H5VL_pass_through_file_close(void *file, hid_t dxpl_id, void **req);
174
175 /* Group callbacks */
176 static void * H5VL_pass_through_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
177 hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id,
178 void **req);
179 static void * H5VL_pass_through_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
180 hid_t gapl_id, hid_t dxpl_id, void **req);
181 static herr_t H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req,
182 va_list arguments);
183 static herr_t H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id,
184 void **req, va_list arguments);
185 static herr_t H5VL_pass_through_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id,
186 void **req, va_list arguments);
187 static herr_t H5VL_pass_through_group_close(void *grp, hid_t dxpl_id, void **req);
188
189 /* Link callbacks */
190 static herr_t H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj,
191 const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id,
192 hid_t dxpl_id, void **req, va_list arguments);
193 static herr_t H5VL_pass_through_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
194 const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id,
195 hid_t dxpl_id, void **req);
196 static herr_t H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
197 const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id,
198 hid_t dxpl_id, void **req);
199 static herr_t H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params,
200 H5VL_link_get_t get_type, hid_t dxpl_id, void **req,
201 va_list arguments);
202 static herr_t H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params,
203 H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req,
204 va_list arguments);
205 static herr_t H5VL_pass_through_link_optional(void *obj, H5VL_link_optional_t opt_type, hid_t dxpl_id,
206 void **req, va_list arguments);
207
208 /* Object callbacks */
209 static void * H5VL_pass_through_object_open(void *obj, const H5VL_loc_params_t *loc_params,
210 H5I_type_t *opened_type, hid_t dxpl_id, void **req);
211 static herr_t H5VL_pass_through_object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params,
212 const char *src_name, void *dst_obj,
213 const H5VL_loc_params_t *dst_loc_params, const char *dst_name,
214 hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req);
215 static herr_t H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params,
216 H5VL_object_get_t get_type, hid_t dxpl_id, void **req,
217 va_list arguments);
218 static herr_t H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params,
219 H5VL_object_specific_t specific_type, hid_t dxpl_id,
220 void **req, va_list arguments);
221 static herr_t H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id,
222 void **req, va_list arguments);
223
224 /* Container/connector introspection callbacks */
225 static herr_t H5VL_pass_through_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl,
226 const H5VL_class_t **conn_cls);
227 static herr_t H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type,
228 hbool_t *supported);
229
230 /* Async request callbacks */
231 static herr_t H5VL_pass_through_request_wait(void *req, uint64_t timeout, H5ES_status_t *status);
232 static herr_t H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx);
233 static herr_t H5VL_pass_through_request_cancel(void *req);
234 static herr_t H5VL_pass_through_request_specific(void *req, H5VL_request_specific_t specific_type,
235 va_list arguments);
236 static herr_t H5VL_pass_through_request_optional(void *req, H5VL_request_optional_t opt_type,
237 va_list arguments);
238 static herr_t H5VL_pass_through_request_free(void *req);
239
240 /* Blob callbacks */
241 static herr_t H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx);
242 static herr_t H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t size, void *ctx);
243 static herr_t H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type,
244 va_list arguments);
245 static herr_t H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t opt_type,
246 va_list arguments);
247
248 /* Token callbacks */
249 static herr_t H5VL_pass_through_token_cmp(void *obj, const H5O_token_t *token1, const H5O_token_t *token2,
250 int *cmp_value);
251 static herr_t H5VL_pass_through_token_to_str(void *obj, H5I_type_t obj_type, const H5O_token_t *token,
252 char **token_str);
253 static herr_t H5VL_pass_through_token_from_str(void *obj, H5I_type_t obj_type, const char *token_str,
254 H5O_token_t *token);
255
256 /* Generic optional callback */
257 static herr_t H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req,
258 va_list arguments);
259
260 /*******************/
261 /* Local variables */
262 /*******************/
263
264 /* Pass through VOL connector class struct */
265 static const H5VL_class_t H5VL_pass_through_g = {
266 H5VL_VERSION, /* VOL class struct version */
267 (H5VL_class_value_t)H5VL_PASSTHRU_VALUE, /* value */
268 H5VL_PASSTHRU_NAME, /* name */
269 0, /* capability flags */
270 H5VL_pass_through_init, /* initialize */
271 H5VL_pass_through_term, /* terminate */
272 {
273 /* info_cls */
274 sizeof(H5VL_pass_through_info_t), /* size */
275 H5VL_pass_through_info_copy, /* copy */
276 H5VL_pass_through_info_cmp, /* compare */
277 H5VL_pass_through_info_free, /* free */
278 H5VL_pass_through_info_to_str, /* to_str */
279 H5VL_pass_through_str_to_info /* from_str */
280 },
281 {
282 /* wrap_cls */
283 H5VL_pass_through_get_object, /* get_object */
284 H5VL_pass_through_get_wrap_ctx, /* get_wrap_ctx */
285 H5VL_pass_through_wrap_object, /* wrap_object */
286 H5VL_pass_through_unwrap_object, /* unwrap_object */
287 H5VL_pass_through_free_wrap_ctx /* free_wrap_ctx */
288 },
289 {
290 /* attribute_cls */
291 H5VL_pass_through_attr_create, /* create */
292 H5VL_pass_through_attr_open, /* open */
293 H5VL_pass_through_attr_read, /* read */
294 H5VL_pass_through_attr_write, /* write */
295 H5VL_pass_through_attr_get, /* get */
296 H5VL_pass_through_attr_specific, /* specific */
297 H5VL_pass_through_attr_optional, /* optional */
298 H5VL_pass_through_attr_close /* close */
299 },
300 {
301 /* dataset_cls */
302 H5VL_pass_through_dataset_create, /* create */
303 H5VL_pass_through_dataset_open, /* open */
304 H5VL_pass_through_dataset_read, /* read */
305 H5VL_pass_through_dataset_write, /* write */
306 H5VL_pass_through_dataset_get, /* get */
307 H5VL_pass_through_dataset_specific, /* specific */
308 H5VL_pass_through_dataset_optional, /* optional */
309 H5VL_pass_through_dataset_close /* close */
310 },
311 {
312 /* datatype_cls */
313 H5VL_pass_through_datatype_commit, /* commit */
314 H5VL_pass_through_datatype_open, /* open */
315 H5VL_pass_through_datatype_get, /* get_size */
316 H5VL_pass_through_datatype_specific, /* specific */
317 H5VL_pass_through_datatype_optional, /* optional */
318 H5VL_pass_through_datatype_close /* close */
319 },
320 {
321 /* file_cls */
322 H5VL_pass_through_file_create, /* create */
323 H5VL_pass_through_file_open, /* open */
324 H5VL_pass_through_file_get, /* get */
325 H5VL_pass_through_file_specific, /* specific */
326 H5VL_pass_through_file_optional, /* optional */
327 H5VL_pass_through_file_close /* close */
328 },
329 {
330 /* group_cls */
331 H5VL_pass_through_group_create, /* create */
332 H5VL_pass_through_group_open, /* open */
333 H5VL_pass_through_group_get, /* get */
334 H5VL_pass_through_group_specific, /* specific */
335 H5VL_pass_through_group_optional, /* optional */
336 H5VL_pass_through_group_close /* close */
337 },
338 {
339 /* link_cls */
340 H5VL_pass_through_link_create, /* create */
341 H5VL_pass_through_link_copy, /* copy */
342 H5VL_pass_through_link_move, /* move */
343 H5VL_pass_through_link_get, /* get */
344 H5VL_pass_through_link_specific, /* specific */
345 H5VL_pass_through_link_optional /* optional */
346 },
347 {
348 /* object_cls */
349 H5VL_pass_through_object_open, /* open */
350 H5VL_pass_through_object_copy, /* copy */
351 H5VL_pass_through_object_get, /* get */
352 H5VL_pass_through_object_specific, /* specific */
353 H5VL_pass_through_object_optional /* optional */
354 },
355 {
356 /* introspect_cls */
357 H5VL_pass_through_introspect_get_conn_cls, /* get_conn_cls */
358 H5VL_pass_through_introspect_opt_query, /* opt_query */
359 },
360 {
361 /* request_cls */
362 H5VL_pass_through_request_wait, /* wait */
363 H5VL_pass_through_request_notify, /* notify */
364 H5VL_pass_through_request_cancel, /* cancel */
365 H5VL_pass_through_request_specific, /* specific */
366 H5VL_pass_through_request_optional, /* optional */
367 H5VL_pass_through_request_free /* free */
368 },
369 {
370 /* blob_cls */
371 H5VL_pass_through_blob_put, /* put */
372 H5VL_pass_through_blob_get, /* get */
373 H5VL_pass_through_blob_specific, /* specific */
374 H5VL_pass_through_blob_optional /* optional */
375 },
376 {
377 /* token_cls */
378 H5VL_pass_through_token_cmp, /* cmp */
379 H5VL_pass_through_token_to_str, /* to_str */
380 H5VL_pass_through_token_from_str /* from_str */
381 },
382 H5VL_pass_through_optional /* optional */
383 };
384
385 /* The connector identification number, initialized at runtime */
386 static hid_t H5VL_PASSTHRU_g = H5I_INVALID_HID;
387
388 /*-------------------------------------------------------------------------
389 * Function: H5VL__pass_through_new_obj
390 *
391 * Purpose: Create a new pass through object for an underlying object
392 *
393 * Return: Success: Pointer to the new pass through object
394 * Failure: NULL
395 *
396 * Programmer: Quincey Koziol
397 * Monday, December 3, 2018
398 *
399 *-------------------------------------------------------------------------
400 */
401 static H5VL_pass_through_t *
H5VL_pass_through_new_obj(void * under_obj,hid_t under_vol_id)402 H5VL_pass_through_new_obj(void *under_obj, hid_t under_vol_id)
403 {
404 H5VL_pass_through_t *new_obj;
405
406 new_obj = (H5VL_pass_through_t *)calloc(1, sizeof(H5VL_pass_through_t));
407 new_obj->under_object = under_obj;
408 new_obj->under_vol_id = under_vol_id;
409 H5Iinc_ref(new_obj->under_vol_id);
410
411 return new_obj;
412 } /* end H5VL__pass_through_new_obj() */
413
414 /*-------------------------------------------------------------------------
415 * Function: H5VL__pass_through_free_obj
416 *
417 * Purpose: Release a pass through object
418 *
419 * Note: Take care to preserve the current HDF5 error stack
420 * when calling HDF5 API calls.
421 *
422 * Return: Success: 0
423 * Failure: -1
424 *
425 * Programmer: Quincey Koziol
426 * Monday, December 3, 2018
427 *
428 *-------------------------------------------------------------------------
429 */
430 static herr_t
H5VL_pass_through_free_obj(H5VL_pass_through_t * obj)431 H5VL_pass_through_free_obj(H5VL_pass_through_t *obj)
432 {
433 hid_t err_id;
434
435 err_id = H5Eget_current_stack();
436
437 H5Idec_ref(obj->under_vol_id);
438
439 H5Eset_current_stack(err_id);
440
441 free(obj);
442
443 return 0;
444 } /* end H5VL__pass_through_free_obj() */
445
446 /*-------------------------------------------------------------------------
447 * Function: H5VL_pass_through_register
448 *
449 * Purpose: Register the pass-through VOL connector and retrieve an ID
450 * for it.
451 *
452 * Return: Success: The ID for the pass-through VOL connector
453 * Failure: -1
454 *
455 * Programmer: Quincey Koziol
456 * Wednesday, November 28, 2018
457 *
458 *-------------------------------------------------------------------------
459 */
460 hid_t
H5VL_pass_through_register(void)461 H5VL_pass_through_register(void)
462 {
463 /* Singleton register the pass-through VOL connector ID */
464 if (H5VL_PASSTHRU_g < 0)
465 H5VL_PASSTHRU_g = H5VLregister_connector(&H5VL_pass_through_g, H5P_DEFAULT);
466
467 return H5VL_PASSTHRU_g;
468 } /* end H5VL_pass_through_register() */
469
470 /*-------------------------------------------------------------------------
471 * Function: H5VL_pass_through_init
472 *
473 * Purpose: Initialize this VOL connector, performing any necessary
474 * operations for the connector that will apply to all containers
475 * accessed with the connector.
476 *
477 * Return: Success: 0
478 * Failure: -1
479 *
480 *-------------------------------------------------------------------------
481 */
482 static herr_t
H5VL_pass_through_init(hid_t vipl_id)483 H5VL_pass_through_init(hid_t vipl_id)
484 {
485 #ifdef ENABLE_PASSTHRU_LOGGING
486 printf("------- PASS THROUGH VOL INIT\n");
487 #endif
488
489 /* Shut compiler up about unused parameter */
490 (void)vipl_id;
491
492 return 0;
493 } /* end H5VL_pass_through_init() */
494
495 /*---------------------------------------------------------------------------
496 * Function: H5VL_pass_through_term
497 *
498 * Purpose: Terminate this VOL connector, performing any necessary
499 * operations for the connector that release connector-wide
500 * resources (usually created / initialized with the 'init'
501 * callback).
502 *
503 * Return: Success: 0
504 * Failure: (Can't fail)
505 *
506 *---------------------------------------------------------------------------
507 */
508 static herr_t
H5VL_pass_through_term(void)509 H5VL_pass_through_term(void)
510 {
511 #ifdef ENABLE_PASSTHRU_LOGGING
512 printf("------- PASS THROUGH VOL TERM\n");
513 #endif
514
515 /* Reset VOL ID */
516 H5VL_PASSTHRU_g = H5I_INVALID_HID;
517
518 return 0;
519 } /* end H5VL_pass_through_term() */
520
521 /*---------------------------------------------------------------------------
522 * Function: H5VL_pass_through_info_copy
523 *
524 * Purpose: Duplicate the connector's info object.
525 *
526 * Returns: Success: New connector info object
527 * Failure: NULL
528 *
529 *---------------------------------------------------------------------------
530 */
531 static void *
H5VL_pass_through_info_copy(const void * _info)532 H5VL_pass_through_info_copy(const void *_info)
533 {
534 const H5VL_pass_through_info_t *info = (const H5VL_pass_through_info_t *)_info;
535 H5VL_pass_through_info_t * new_info;
536
537 #ifdef ENABLE_PASSTHRU_LOGGING
538 printf("------- PASS THROUGH VOL INFO Copy\n");
539 #endif
540
541 /* Allocate new VOL info struct for the pass through connector */
542 new_info = (H5VL_pass_through_info_t *)calloc(1, sizeof(H5VL_pass_through_info_t));
543
544 /* Increment reference count on underlying VOL ID, and copy the VOL info */
545 new_info->under_vol_id = info->under_vol_id;
546 H5Iinc_ref(new_info->under_vol_id);
547 if (info->under_vol_info)
548 H5VLcopy_connector_info(new_info->under_vol_id, &(new_info->under_vol_info), info->under_vol_info);
549
550 return new_info;
551 } /* end H5VL_pass_through_info_copy() */
552
553 /*---------------------------------------------------------------------------
554 * Function: H5VL_pass_through_info_cmp
555 *
556 * Purpose: Compare two of the connector's info objects, setting *cmp_value,
557 * following the same rules as strcmp().
558 *
559 * Return: Success: 0
560 * Failure: -1
561 *
562 *---------------------------------------------------------------------------
563 */
564 static herr_t
H5VL_pass_through_info_cmp(int * cmp_value,const void * _info1,const void * _info2)565 H5VL_pass_through_info_cmp(int *cmp_value, const void *_info1, const void *_info2)
566 {
567 const H5VL_pass_through_info_t *info1 = (const H5VL_pass_through_info_t *)_info1;
568 const H5VL_pass_through_info_t *info2 = (const H5VL_pass_through_info_t *)_info2;
569
570 #ifdef ENABLE_PASSTHRU_LOGGING
571 printf("------- PASS THROUGH VOL INFO Compare\n");
572 #endif
573
574 /* Sanity checks */
575 assert(info1);
576 assert(info2);
577
578 /* Initialize comparison value */
579 *cmp_value = 0;
580
581 /* Compare under VOL connector classes */
582 H5VLcmp_connector_cls(cmp_value, info1->under_vol_id, info2->under_vol_id);
583 if (*cmp_value != 0)
584 return 0;
585
586 /* Compare under VOL connector info objects */
587 H5VLcmp_connector_info(cmp_value, info1->under_vol_id, info1->under_vol_info, info2->under_vol_info);
588 if (*cmp_value != 0)
589 return 0;
590
591 return 0;
592 } /* end H5VL_pass_through_info_cmp() */
593
594 /*---------------------------------------------------------------------------
595 * Function: H5VL_pass_through_info_free
596 *
597 * Purpose: Release an info object for the connector.
598 *
599 * Note: Take care to preserve the current HDF5 error stack
600 * when calling HDF5 API calls.
601 *
602 * Return: Success: 0
603 * Failure: -1
604 *
605 *---------------------------------------------------------------------------
606 */
607 static herr_t
H5VL_pass_through_info_free(void * _info)608 H5VL_pass_through_info_free(void *_info)
609 {
610 H5VL_pass_through_info_t *info = (H5VL_pass_through_info_t *)_info;
611 hid_t err_id;
612
613 #ifdef ENABLE_PASSTHRU_LOGGING
614 printf("------- PASS THROUGH VOL INFO Free\n");
615 #endif
616
617 err_id = H5Eget_current_stack();
618
619 /* Release underlying VOL ID and info */
620 if (info->under_vol_info)
621 H5VLfree_connector_info(info->under_vol_id, info->under_vol_info);
622 H5Idec_ref(info->under_vol_id);
623
624 H5Eset_current_stack(err_id);
625
626 /* Free pass through info object itself */
627 free(info);
628
629 return 0;
630 } /* end H5VL_pass_through_info_free() */
631
632 /*---------------------------------------------------------------------------
633 * Function: H5VL_pass_through_info_to_str
634 *
635 * Purpose: Serialize an info object for this connector into a string
636 *
637 * Return: Success: 0
638 * Failure: -1
639 *
640 *---------------------------------------------------------------------------
641 */
642 static herr_t
H5VL_pass_through_info_to_str(const void * _info,char ** str)643 H5VL_pass_through_info_to_str(const void *_info, char **str)
644 {
645 const H5VL_pass_through_info_t *info = (const H5VL_pass_through_info_t *)_info;
646 H5VL_class_value_t under_value = (H5VL_class_value_t)-1;
647 char * under_vol_string = NULL;
648 size_t under_vol_str_len = 0;
649
650 #ifdef ENABLE_PASSTHRU_LOGGING
651 printf("------- PASS THROUGH VOL INFO To String\n");
652 #endif
653
654 /* Get value and string for underlying VOL connector */
655 H5VLget_value(info->under_vol_id, &under_value);
656 H5VLconnector_info_to_str(info->under_vol_info, info->under_vol_id, &under_vol_string);
657
658 /* Determine length of underlying VOL info string */
659 if (under_vol_string)
660 under_vol_str_len = strlen(under_vol_string);
661
662 /* Allocate space for our info */
663 *str = (char *)H5allocate_memory(32 + under_vol_str_len, (hbool_t)0);
664 assert(*str);
665
666 /* Encode our info
667 * Normally we'd use snprintf() here for a little extra safety, but that
668 * call had problems on Windows until recently. So, to be as platform-independent
669 * as we can, we're using sprintf() instead.
670 */
671 sprintf(*str, "under_vol=%u;under_info={%s}", (unsigned)under_value,
672 (under_vol_string ? under_vol_string : ""));
673
674 return 0;
675 } /* end H5VL_pass_through_info_to_str() */
676
677 /*---------------------------------------------------------------------------
678 * Function: H5VL_pass_through_str_to_info
679 *
680 * Purpose: Deserialize a string into an info object for this connector.
681 *
682 * Return: Success: 0
683 * Failure: -1
684 *
685 *---------------------------------------------------------------------------
686 */
687 static herr_t
H5VL_pass_through_str_to_info(const char * str,void ** _info)688 H5VL_pass_through_str_to_info(const char *str, void **_info)
689 {
690 H5VL_pass_through_info_t *info;
691 unsigned under_vol_value;
692 const char * under_vol_info_start, *under_vol_info_end;
693 hid_t under_vol_id;
694 void * under_vol_info = NULL;
695
696 #ifdef ENABLE_PASSTHRU_LOGGING
697 printf("------- PASS THROUGH VOL INFO String To Info\n");
698 #endif
699
700 /* Retrieve the underlying VOL connector value and info */
701 sscanf(str, "under_vol=%u;", &under_vol_value);
702 under_vol_id = H5VLregister_connector_by_value((H5VL_class_value_t)under_vol_value, H5P_DEFAULT);
703 under_vol_info_start = strchr(str, '{');
704 under_vol_info_end = strrchr(str, '}');
705 assert(under_vol_info_end > under_vol_info_start);
706 if (under_vol_info_end != (under_vol_info_start + 1)) {
707 char *under_vol_info_str;
708
709 under_vol_info_str = (char *)malloc((size_t)(under_vol_info_end - under_vol_info_start));
710 memcpy(under_vol_info_str, under_vol_info_start + 1,
711 (size_t)((under_vol_info_end - under_vol_info_start) - 1));
712 *(under_vol_info_str + (under_vol_info_end - under_vol_info_start)) = '\0';
713
714 H5VLconnector_str_to_info(under_vol_info_str, under_vol_id, &under_vol_info);
715
716 free(under_vol_info_str);
717 } /* end else */
718
719 /* Allocate new pass-through VOL connector info and set its fields */
720 info = (H5VL_pass_through_info_t *)calloc(1, sizeof(H5VL_pass_through_info_t));
721 info->under_vol_id = under_vol_id;
722 info->under_vol_info = under_vol_info;
723
724 /* Set return value */
725 *_info = info;
726
727 return 0;
728 } /* end H5VL_pass_through_str_to_info() */
729
730 /*---------------------------------------------------------------------------
731 * Function: H5VL_pass_through_get_object
732 *
733 * Purpose: Retrieve the 'data' for a VOL object.
734 *
735 * Return: Success: 0
736 * Failure: -1
737 *
738 *---------------------------------------------------------------------------
739 */
740 static void *
H5VL_pass_through_get_object(const void * obj)741 H5VL_pass_through_get_object(const void *obj)
742 {
743 const H5VL_pass_through_t *o = (const H5VL_pass_through_t *)obj;
744
745 #ifdef ENABLE_PASSTHRU_LOGGING
746 printf("------- PASS THROUGH VOL Get object\n");
747 #endif
748
749 return H5VLget_object(o->under_object, o->under_vol_id);
750 } /* end H5VL_pass_through_get_object() */
751
752 /*---------------------------------------------------------------------------
753 * Function: H5VL_pass_through_get_wrap_ctx
754 *
755 * Purpose: Retrieve a "wrapper context" for an object
756 *
757 * Return: Success: 0
758 * Failure: -1
759 *
760 *---------------------------------------------------------------------------
761 */
762 static herr_t
H5VL_pass_through_get_wrap_ctx(const void * obj,void ** wrap_ctx)763 H5VL_pass_through_get_wrap_ctx(const void *obj, void **wrap_ctx)
764 {
765 const H5VL_pass_through_t * o = (const H5VL_pass_through_t *)obj;
766 H5VL_pass_through_wrap_ctx_t *new_wrap_ctx;
767
768 #ifdef ENABLE_PASSTHRU_LOGGING
769 printf("------- PASS THROUGH VOL WRAP CTX Get\n");
770 #endif
771
772 /* Allocate new VOL object wrapping context for the pass through connector */
773 new_wrap_ctx = (H5VL_pass_through_wrap_ctx_t *)calloc(1, sizeof(H5VL_pass_through_wrap_ctx_t));
774
775 /* Increment reference count on underlying VOL ID, and copy the VOL info */
776 new_wrap_ctx->under_vol_id = o->under_vol_id;
777 H5Iinc_ref(new_wrap_ctx->under_vol_id);
778 H5VLget_wrap_ctx(o->under_object, o->under_vol_id, &new_wrap_ctx->under_wrap_ctx);
779
780 /* Set wrap context to return */
781 *wrap_ctx = new_wrap_ctx;
782
783 return 0;
784 } /* end H5VL_pass_through_get_wrap_ctx() */
785
786 /*---------------------------------------------------------------------------
787 * Function: H5VL_pass_through_wrap_object
788 *
789 * Purpose: Use a "wrapper context" to wrap a data object
790 *
791 * Return: Success: Pointer to wrapped object
792 * Failure: NULL
793 *
794 *---------------------------------------------------------------------------
795 */
796 static void *
H5VL_pass_through_wrap_object(void * obj,H5I_type_t obj_type,void * _wrap_ctx)797 H5VL_pass_through_wrap_object(void *obj, H5I_type_t obj_type, void *_wrap_ctx)
798 {
799 H5VL_pass_through_wrap_ctx_t *wrap_ctx = (H5VL_pass_through_wrap_ctx_t *)_wrap_ctx;
800 H5VL_pass_through_t * new_obj;
801 void * under;
802
803 #ifdef ENABLE_PASSTHRU_LOGGING
804 printf("------- PASS THROUGH VOL WRAP Object\n");
805 #endif
806
807 /* Wrap the object with the underlying VOL */
808 under = H5VLwrap_object(obj, obj_type, wrap_ctx->under_vol_id, wrap_ctx->under_wrap_ctx);
809 if (under)
810 new_obj = H5VL_pass_through_new_obj(under, wrap_ctx->under_vol_id);
811 else
812 new_obj = NULL;
813
814 return new_obj;
815 } /* end H5VL_pass_through_wrap_object() */
816
817 /*---------------------------------------------------------------------------
818 * Function: H5VL_pass_through_unwrap_object
819 *
820 * Purpose: Unwrap a wrapped object, discarding the wrapper, but returning
821 * underlying object.
822 *
823 * Return: Success: Pointer to unwrapped object
824 * Failure: NULL
825 *
826 *---------------------------------------------------------------------------
827 */
828 static void *
H5VL_pass_through_unwrap_object(void * obj)829 H5VL_pass_through_unwrap_object(void *obj)
830 {
831 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
832 void * under;
833
834 #ifdef ENABLE_PASSTHRU_LOGGING
835 printf("------- PASS THROUGH VOL UNWRAP Object\n");
836 #endif
837
838 /* Unrap the object with the underlying VOL */
839 under = H5VLunwrap_object(o->under_object, o->under_vol_id);
840
841 if (under)
842 H5VL_pass_through_free_obj(o);
843
844 return under;
845 } /* end H5VL_pass_through_unwrap_object() */
846
847 /*---------------------------------------------------------------------------
848 * Function: H5VL_pass_through_free_wrap_ctx
849 *
850 * Purpose: Release a "wrapper context" for an object
851 *
852 * Note: Take care to preserve the current HDF5 error stack
853 * when calling HDF5 API calls.
854 *
855 * Return: Success: 0
856 * Failure: -1
857 *
858 *---------------------------------------------------------------------------
859 */
860 static herr_t
H5VL_pass_through_free_wrap_ctx(void * _wrap_ctx)861 H5VL_pass_through_free_wrap_ctx(void *_wrap_ctx)
862 {
863 H5VL_pass_through_wrap_ctx_t *wrap_ctx = (H5VL_pass_through_wrap_ctx_t *)_wrap_ctx;
864 hid_t err_id;
865
866 #ifdef ENABLE_PASSTHRU_LOGGING
867 printf("------- PASS THROUGH VOL WRAP CTX Free\n");
868 #endif
869
870 err_id = H5Eget_current_stack();
871
872 /* Release underlying VOL ID and wrap context */
873 if (wrap_ctx->under_wrap_ctx)
874 H5VLfree_wrap_ctx(wrap_ctx->under_wrap_ctx, wrap_ctx->under_vol_id);
875 H5Idec_ref(wrap_ctx->under_vol_id);
876
877 H5Eset_current_stack(err_id);
878
879 /* Free pass through wrap context object itself */
880 free(wrap_ctx);
881
882 return 0;
883 } /* end H5VL_pass_through_free_wrap_ctx() */
884
885 /*-------------------------------------------------------------------------
886 * Function: H5VL_pass_through_attr_create
887 *
888 * Purpose: Creates an attribute on an object.
889 *
890 * Return: Success: Pointer to attribute object
891 * Failure: NULL
892 *
893 *-------------------------------------------------------------------------
894 */
895 static void *
H5VL_pass_through_attr_create(void * obj,const H5VL_loc_params_t * loc_params,const char * name,hid_t type_id,hid_t space_id,hid_t acpl_id,hid_t aapl_id,hid_t dxpl_id,void ** req)896 H5VL_pass_through_attr_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t type_id,
897 hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t dxpl_id, void **req)
898 {
899 H5VL_pass_through_t *attr;
900 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
901 void * under;
902
903 #ifdef ENABLE_PASSTHRU_LOGGING
904 printf("------- PASS THROUGH VOL ATTRIBUTE Create\n");
905 #endif
906
907 under = H5VLattr_create(o->under_object, loc_params, o->under_vol_id, name, type_id, space_id, acpl_id,
908 aapl_id, dxpl_id, req);
909 if (under) {
910 attr = H5VL_pass_through_new_obj(under, o->under_vol_id);
911
912 /* Check for async request */
913 if (req && *req)
914 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
915 } /* end if */
916 else
917 attr = NULL;
918
919 return (void *)attr;
920 } /* end H5VL_pass_through_attr_create() */
921
922 /*-------------------------------------------------------------------------
923 * Function: H5VL_pass_through_attr_open
924 *
925 * Purpose: Opens an attribute on an object.
926 *
927 * Return: Success: Pointer to attribute object
928 * Failure: NULL
929 *
930 *-------------------------------------------------------------------------
931 */
932 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)933 H5VL_pass_through_attr_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t aapl_id,
934 hid_t dxpl_id, void **req)
935 {
936 H5VL_pass_through_t *attr;
937 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
938 void * under;
939
940 #ifdef ENABLE_PASSTHRU_LOGGING
941 printf("------- PASS THROUGH VOL ATTRIBUTE Open\n");
942 #endif
943
944 under = H5VLattr_open(o->under_object, loc_params, o->under_vol_id, name, aapl_id, dxpl_id, req);
945 if (under) {
946 attr = H5VL_pass_through_new_obj(under, o->under_vol_id);
947
948 /* Check for async request */
949 if (req && *req)
950 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
951 } /* end if */
952 else
953 attr = NULL;
954
955 return (void *)attr;
956 } /* end H5VL_pass_through_attr_open() */
957
958 /*-------------------------------------------------------------------------
959 * Function: H5VL_pass_through_attr_read
960 *
961 * Purpose: Reads data from attribute.
962 *
963 * Return: Success: 0
964 * Failure: -1
965 *
966 *-------------------------------------------------------------------------
967 */
968 static herr_t
H5VL_pass_through_attr_read(void * attr,hid_t mem_type_id,void * buf,hid_t dxpl_id,void ** req)969 H5VL_pass_through_attr_read(void *attr, hid_t mem_type_id, void *buf, hid_t dxpl_id, void **req)
970 {
971 H5VL_pass_through_t *o = (H5VL_pass_through_t *)attr;
972 herr_t ret_value;
973
974 #ifdef ENABLE_PASSTHRU_LOGGING
975 printf("------- PASS THROUGH VOL ATTRIBUTE Read\n");
976 #endif
977
978 ret_value = H5VLattr_read(o->under_object, o->under_vol_id, mem_type_id, buf, dxpl_id, req);
979
980 /* Check for async request */
981 if (req && *req)
982 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
983
984 return ret_value;
985 } /* end H5VL_pass_through_attr_read() */
986
987 /*-------------------------------------------------------------------------
988 * Function: H5VL_pass_through_attr_write
989 *
990 * Purpose: Writes data to attribute.
991 *
992 * Return: Success: 0
993 * Failure: -1
994 *
995 *-------------------------------------------------------------------------
996 */
997 static herr_t
H5VL_pass_through_attr_write(void * attr,hid_t mem_type_id,const void * buf,hid_t dxpl_id,void ** req)998 H5VL_pass_through_attr_write(void *attr, hid_t mem_type_id, const void *buf, hid_t dxpl_id, void **req)
999 {
1000 H5VL_pass_through_t *o = (H5VL_pass_through_t *)attr;
1001 herr_t ret_value;
1002
1003 #ifdef ENABLE_PASSTHRU_LOGGING
1004 printf("------- PASS THROUGH VOL ATTRIBUTE Write\n");
1005 #endif
1006
1007 ret_value = H5VLattr_write(o->under_object, o->under_vol_id, mem_type_id, buf, dxpl_id, req);
1008
1009 /* Check for async request */
1010 if (req && *req)
1011 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1012
1013 return ret_value;
1014 } /* end H5VL_pass_through_attr_write() */
1015
1016 /*-------------------------------------------------------------------------
1017 * Function: H5VL_pass_through_attr_get
1018 *
1019 * Purpose: Gets information about an attribute
1020 *
1021 * Return: Success: 0
1022 * Failure: -1
1023 *
1024 *-------------------------------------------------------------------------
1025 */
1026 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)1027 H5VL_pass_through_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t dxpl_id, void **req, va_list arguments)
1028 {
1029 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1030 herr_t ret_value;
1031
1032 #ifdef ENABLE_PASSTHRU_LOGGING
1033 printf("------- PASS THROUGH VOL ATTRIBUTE Get\n");
1034 #endif
1035
1036 ret_value = H5VLattr_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
1037
1038 /* Check for async request */
1039 if (req && *req)
1040 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1041
1042 return ret_value;
1043 } /* end H5VL_pass_through_attr_get() */
1044
1045 /*-------------------------------------------------------------------------
1046 * Function: H5VL_pass_through_attr_specific
1047 *
1048 * Purpose: Specific operation on attribute
1049 *
1050 * Return: Success: 0
1051 * Failure: -1
1052 *
1053 *-------------------------------------------------------------------------
1054 */
1055 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)1056 H5VL_pass_through_attr_specific(void *obj, const H5VL_loc_params_t *loc_params,
1057 H5VL_attr_specific_t specific_type, hid_t dxpl_id, void **req,
1058 va_list arguments)
1059 {
1060 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1061 herr_t ret_value;
1062
1063 #ifdef ENABLE_PASSTHRU_LOGGING
1064 printf("------- PASS THROUGH VOL ATTRIBUTE Specific\n");
1065 #endif
1066
1067 ret_value = H5VLattr_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req,
1068 arguments);
1069
1070 /* Check for async request */
1071 if (req && *req)
1072 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1073
1074 return ret_value;
1075 } /* end H5VL_pass_through_attr_specific() */
1076
1077 /*-------------------------------------------------------------------------
1078 * Function: H5VL_pass_through_attr_optional
1079 *
1080 * Purpose: Perform a connector-specific operation on an attribute
1081 *
1082 * Return: Success: 0
1083 * Failure: -1
1084 *
1085 *-------------------------------------------------------------------------
1086 */
1087 static herr_t
H5VL_pass_through_attr_optional(void * obj,H5VL_attr_optional_t opt_type,hid_t dxpl_id,void ** req,va_list arguments)1088 H5VL_pass_through_attr_optional(void *obj, H5VL_attr_optional_t opt_type, hid_t dxpl_id, void **req,
1089 va_list arguments)
1090 {
1091 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1092 herr_t ret_value;
1093
1094 #ifdef ENABLE_PASSTHRU_LOGGING
1095 printf("------- PASS THROUGH VOL ATTRIBUTE Optional\n");
1096 #endif
1097
1098 ret_value = H5VLattr_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments);
1099
1100 /* Check for async request */
1101 if (req && *req)
1102 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1103
1104 return ret_value;
1105 } /* end H5VL_pass_through_attr_optional() */
1106
1107 /*-------------------------------------------------------------------------
1108 * Function: H5VL_pass_through_attr_close
1109 *
1110 * Purpose: Closes an attribute.
1111 *
1112 * Return: Success: 0
1113 * Failure: -1, attr not closed.
1114 *
1115 *-------------------------------------------------------------------------
1116 */
1117 static herr_t
H5VL_pass_through_attr_close(void * attr,hid_t dxpl_id,void ** req)1118 H5VL_pass_through_attr_close(void *attr, hid_t dxpl_id, void **req)
1119 {
1120 H5VL_pass_through_t *o = (H5VL_pass_through_t *)attr;
1121 herr_t ret_value;
1122
1123 #ifdef ENABLE_PASSTHRU_LOGGING
1124 printf("------- PASS THROUGH VOL ATTRIBUTE Close\n");
1125 #endif
1126
1127 ret_value = H5VLattr_close(o->under_object, o->under_vol_id, dxpl_id, req);
1128
1129 /* Check for async request */
1130 if (req && *req)
1131 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1132
1133 /* Release our wrapper, if underlying attribute was closed */
1134 if (ret_value >= 0)
1135 H5VL_pass_through_free_obj(o);
1136
1137 return ret_value;
1138 } /* end H5VL_pass_through_attr_close() */
1139
1140 /*-------------------------------------------------------------------------
1141 * Function: H5VL_pass_through_dataset_create
1142 *
1143 * Purpose: Creates a dataset in a container
1144 *
1145 * Return: Success: Pointer to a dataset object
1146 * Failure: NULL
1147 *
1148 *-------------------------------------------------------------------------
1149 */
1150 static void *
H5VL_pass_through_dataset_create(void * obj,const H5VL_loc_params_t * loc_params,const char * name,hid_t lcpl_id,hid_t type_id,hid_t space_id,hid_t dcpl_id,hid_t dapl_id,hid_t dxpl_id,void ** req)1151 H5VL_pass_through_dataset_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
1152 hid_t lcpl_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id,
1153 hid_t dxpl_id, void **req)
1154 {
1155 H5VL_pass_through_t *dset;
1156 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1157 void * under;
1158
1159 #ifdef ENABLE_PASSTHRU_LOGGING
1160 printf("------- PASS THROUGH VOL DATASET Create\n");
1161 #endif
1162
1163 under = H5VLdataset_create(o->under_object, loc_params, o->under_vol_id, name, lcpl_id, type_id, space_id,
1164 dcpl_id, dapl_id, dxpl_id, req);
1165 if (under) {
1166 dset = H5VL_pass_through_new_obj(under, o->under_vol_id);
1167
1168 /* Check for async request */
1169 if (req && *req)
1170 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1171 } /* end if */
1172 else
1173 dset = NULL;
1174
1175 return (void *)dset;
1176 } /* end H5VL_pass_through_dataset_create() */
1177
1178 /*-------------------------------------------------------------------------
1179 * Function: H5VL_pass_through_dataset_open
1180 *
1181 * Purpose: Opens a dataset in a container
1182 *
1183 * Return: Success: Pointer to a dataset object
1184 * Failure: NULL
1185 *
1186 *-------------------------------------------------------------------------
1187 */
1188 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)1189 H5VL_pass_through_dataset_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
1190 hid_t dapl_id, hid_t dxpl_id, void **req)
1191 {
1192 H5VL_pass_through_t *dset;
1193 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1194 void * under;
1195
1196 #ifdef ENABLE_PASSTHRU_LOGGING
1197 printf("------- PASS THROUGH VOL DATASET Open\n");
1198 #endif
1199
1200 under = H5VLdataset_open(o->under_object, loc_params, o->under_vol_id, name, dapl_id, dxpl_id, req);
1201 if (under) {
1202 dset = H5VL_pass_through_new_obj(under, o->under_vol_id);
1203
1204 /* Check for async request */
1205 if (req && *req)
1206 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1207 } /* end if */
1208 else
1209 dset = NULL;
1210
1211 return (void *)dset;
1212 } /* end H5VL_pass_through_dataset_open() */
1213
1214 /*-------------------------------------------------------------------------
1215 * Function: H5VL_pass_through_dataset_read
1216 *
1217 * Purpose: Reads data elements from a dataset into a buffer.
1218 *
1219 * Return: Success: 0
1220 * Failure: -1
1221 *
1222 *-------------------------------------------------------------------------
1223 */
1224 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)1225 H5VL_pass_through_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
1226 hid_t plist_id, void *buf, void **req)
1227 {
1228 H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
1229 herr_t ret_value;
1230
1231 #ifdef ENABLE_PASSTHRU_LOGGING
1232 printf("------- PASS THROUGH VOL DATASET Read\n");
1233 #endif
1234
1235 ret_value = H5VLdataset_read(o->under_object, o->under_vol_id, mem_type_id, mem_space_id, file_space_id,
1236 plist_id, buf, req);
1237
1238 /* Check for async request */
1239 if (req && *req)
1240 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1241
1242 return ret_value;
1243 } /* end H5VL_pass_through_dataset_read() */
1244
1245 /*-------------------------------------------------------------------------
1246 * Function: H5VL_pass_through_dataset_write
1247 *
1248 * Purpose: Writes data elements from a buffer into a dataset.
1249 *
1250 * Return: Success: 0
1251 * Failure: -1
1252 *
1253 *-------------------------------------------------------------------------
1254 */
1255 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)1256 H5VL_pass_through_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id,
1257 hid_t plist_id, const void *buf, void **req)
1258 {
1259 H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
1260 herr_t ret_value;
1261
1262 #ifdef ENABLE_PASSTHRU_LOGGING
1263 printf("------- PASS THROUGH VOL DATASET Write\n");
1264 #endif
1265
1266 ret_value = H5VLdataset_write(o->under_object, o->under_vol_id, mem_type_id, mem_space_id, file_space_id,
1267 plist_id, buf, req);
1268
1269 /* Check for async request */
1270 if (req && *req)
1271 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1272
1273 return ret_value;
1274 } /* end H5VL_pass_through_dataset_write() */
1275
1276 /*-------------------------------------------------------------------------
1277 * Function: H5VL_pass_through_dataset_get
1278 *
1279 * Purpose: Gets information about a dataset
1280 *
1281 * Return: Success: 0
1282 * Failure: -1
1283 *
1284 *-------------------------------------------------------------------------
1285 */
1286 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)1287 H5VL_pass_through_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t dxpl_id, void **req,
1288 va_list arguments)
1289 {
1290 H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
1291 herr_t ret_value;
1292
1293 #ifdef ENABLE_PASSTHRU_LOGGING
1294 printf("------- PASS THROUGH VOL DATASET Get\n");
1295 #endif
1296
1297 ret_value = H5VLdataset_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
1298
1299 /* Check for async request */
1300 if (req && *req)
1301 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1302
1303 return ret_value;
1304 } /* end H5VL_pass_through_dataset_get() */
1305
1306 /*-------------------------------------------------------------------------
1307 * Function: H5VL_pass_through_dataset_specific
1308 *
1309 * Purpose: Specific operation on a dataset
1310 *
1311 * Return: Success: 0
1312 * Failure: -1
1313 *
1314 *-------------------------------------------------------------------------
1315 */
1316 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)1317 H5VL_pass_through_dataset_specific(void *obj, H5VL_dataset_specific_t specific_type, hid_t dxpl_id,
1318 void **req, va_list arguments)
1319 {
1320 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1321 hid_t under_vol_id;
1322 herr_t ret_value;
1323
1324 #ifdef ENABLE_PASSTHRU_LOGGING
1325 printf("------- PASS THROUGH VOL H5Dspecific\n");
1326 #endif
1327
1328 // Save copy of underlying VOL connector ID and prov helper, in case of
1329 // refresh destroying the current object
1330 under_vol_id = o->under_vol_id;
1331
1332 ret_value =
1333 H5VLdataset_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
1334
1335 /* Check for async request */
1336 if (req && *req)
1337 *req = H5VL_pass_through_new_obj(*req, under_vol_id);
1338
1339 return ret_value;
1340 } /* end H5VL_pass_through_dataset_specific() */
1341
1342 /*-------------------------------------------------------------------------
1343 * Function: H5VL_pass_through_dataset_optional
1344 *
1345 * Purpose: Perform a connector-specific operation on a dataset
1346 *
1347 * Return: Success: 0
1348 * Failure: -1
1349 *
1350 *-------------------------------------------------------------------------
1351 */
1352 static herr_t
H5VL_pass_through_dataset_optional(void * obj,H5VL_dataset_optional_t opt_type,hid_t dxpl_id,void ** req,va_list arguments)1353 H5VL_pass_through_dataset_optional(void *obj, H5VL_dataset_optional_t opt_type, hid_t dxpl_id, void **req,
1354 va_list arguments)
1355 {
1356 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1357 herr_t ret_value;
1358
1359 #ifdef ENABLE_PASSTHRU_LOGGING
1360 printf("------- PASS THROUGH VOL DATASET Optional\n");
1361 #endif
1362
1363 ret_value = H5VLdataset_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments);
1364
1365 /* Check for async request */
1366 if (req && *req)
1367 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1368
1369 return ret_value;
1370 } /* end H5VL_pass_through_dataset_optional() */
1371
1372 /*-------------------------------------------------------------------------
1373 * Function: H5VL_pass_through_dataset_close
1374 *
1375 * Purpose: Closes a dataset.
1376 *
1377 * Return: Success: 0
1378 * Failure: -1, dataset not closed.
1379 *
1380 *-------------------------------------------------------------------------
1381 */
1382 static herr_t
H5VL_pass_through_dataset_close(void * dset,hid_t dxpl_id,void ** req)1383 H5VL_pass_through_dataset_close(void *dset, hid_t dxpl_id, void **req)
1384 {
1385 H5VL_pass_through_t *o = (H5VL_pass_through_t *)dset;
1386 herr_t ret_value;
1387
1388 #ifdef ENABLE_PASSTHRU_LOGGING
1389 printf("------- PASS THROUGH VOL DATASET Close\n");
1390 #endif
1391
1392 ret_value = H5VLdataset_close(o->under_object, o->under_vol_id, dxpl_id, req);
1393
1394 /* Check for async request */
1395 if (req && *req)
1396 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1397
1398 /* Release our wrapper, if underlying dataset was closed */
1399 if (ret_value >= 0)
1400 H5VL_pass_through_free_obj(o);
1401
1402 return ret_value;
1403 } /* end H5VL_pass_through_dataset_close() */
1404
1405 /*-------------------------------------------------------------------------
1406 * Function: H5VL_pass_through_datatype_commit
1407 *
1408 * Purpose: Commits a datatype inside a container.
1409 *
1410 * Return: Success: Pointer to datatype object
1411 * Failure: NULL
1412 *
1413 *-------------------------------------------------------------------------
1414 */
1415 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)1416 H5VL_pass_through_datatype_commit(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
1417 hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t dxpl_id,
1418 void **req)
1419 {
1420 H5VL_pass_through_t *dt;
1421 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1422 void * under;
1423
1424 #ifdef ENABLE_PASSTHRU_LOGGING
1425 printf("------- PASS THROUGH VOL DATATYPE Commit\n");
1426 #endif
1427
1428 under = H5VLdatatype_commit(o->under_object, loc_params, o->under_vol_id, name, type_id, lcpl_id, tcpl_id,
1429 tapl_id, dxpl_id, req);
1430 if (under) {
1431 dt = H5VL_pass_through_new_obj(under, o->under_vol_id);
1432
1433 /* Check for async request */
1434 if (req && *req)
1435 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1436 } /* end if */
1437 else
1438 dt = NULL;
1439
1440 return (void *)dt;
1441 } /* end H5VL_pass_through_datatype_commit() */
1442
1443 /*-------------------------------------------------------------------------
1444 * Function: H5VL_pass_through_datatype_open
1445 *
1446 * Purpose: Opens a named datatype inside a container.
1447 *
1448 * Return: Success: Pointer to datatype object
1449 * Failure: NULL
1450 *
1451 *-------------------------------------------------------------------------
1452 */
1453 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)1454 H5VL_pass_through_datatype_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
1455 hid_t tapl_id, hid_t dxpl_id, void **req)
1456 {
1457 H5VL_pass_through_t *dt;
1458 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1459 void * under;
1460
1461 #ifdef ENABLE_PASSTHRU_LOGGING
1462 printf("------- PASS THROUGH VOL DATATYPE Open\n");
1463 #endif
1464
1465 under = H5VLdatatype_open(o->under_object, loc_params, o->under_vol_id, name, tapl_id, dxpl_id, req);
1466 if (under) {
1467 dt = H5VL_pass_through_new_obj(under, o->under_vol_id);
1468
1469 /* Check for async request */
1470 if (req && *req)
1471 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1472 } /* end if */
1473 else
1474 dt = NULL;
1475
1476 return (void *)dt;
1477 } /* end H5VL_pass_through_datatype_open() */
1478
1479 /*-------------------------------------------------------------------------
1480 * Function: H5VL_pass_through_datatype_get
1481 *
1482 * Purpose: Get information about a datatype
1483 *
1484 * Return: Success: 0
1485 * Failure: -1
1486 *
1487 *-------------------------------------------------------------------------
1488 */
1489 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)1490 H5VL_pass_through_datatype_get(void *dt, H5VL_datatype_get_t get_type, hid_t dxpl_id, void **req,
1491 va_list arguments)
1492 {
1493 H5VL_pass_through_t *o = (H5VL_pass_through_t *)dt;
1494 herr_t ret_value;
1495
1496 #ifdef ENABLE_PASSTHRU_LOGGING
1497 printf("------- PASS THROUGH VOL DATATYPE Get\n");
1498 #endif
1499
1500 ret_value = H5VLdatatype_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
1501
1502 /* Check for async request */
1503 if (req && *req)
1504 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1505
1506 return ret_value;
1507 } /* end H5VL_pass_through_datatype_get() */
1508
1509 /*-------------------------------------------------------------------------
1510 * Function: H5VL_pass_through_datatype_specific
1511 *
1512 * Purpose: Specific operations for datatypes
1513 *
1514 * Return: Success: 0
1515 * Failure: -1
1516 *
1517 *-------------------------------------------------------------------------
1518 */
1519 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)1520 H5VL_pass_through_datatype_specific(void *obj, H5VL_datatype_specific_t specific_type, hid_t dxpl_id,
1521 void **req, va_list arguments)
1522 {
1523 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1524 hid_t under_vol_id;
1525 herr_t ret_value;
1526
1527 #ifdef ENABLE_PASSTHRU_LOGGING
1528 printf("------- PASS THROUGH VOL DATATYPE Specific\n");
1529 #endif
1530
1531 // Save copy of underlying VOL connector ID and prov helper, in case of
1532 // refresh destroying the current object
1533 under_vol_id = o->under_vol_id;
1534
1535 ret_value =
1536 H5VLdatatype_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
1537
1538 /* Check for async request */
1539 if (req && *req)
1540 *req = H5VL_pass_through_new_obj(*req, under_vol_id);
1541
1542 return ret_value;
1543 } /* end H5VL_pass_through_datatype_specific() */
1544
1545 /*-------------------------------------------------------------------------
1546 * Function: H5VL_pass_through_datatype_optional
1547 *
1548 * Purpose: Perform a connector-specific operation on a datatype
1549 *
1550 * Return: Success: 0
1551 * Failure: -1
1552 *
1553 *-------------------------------------------------------------------------
1554 */
1555 static herr_t
H5VL_pass_through_datatype_optional(void * obj,H5VL_datatype_optional_t opt_type,hid_t dxpl_id,void ** req,va_list arguments)1556 H5VL_pass_through_datatype_optional(void *obj, H5VL_datatype_optional_t opt_type, hid_t dxpl_id, void **req,
1557 va_list arguments)
1558 {
1559 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1560 herr_t ret_value;
1561
1562 #ifdef ENABLE_PASSTHRU_LOGGING
1563 printf("------- PASS THROUGH VOL DATATYPE Optional\n");
1564 #endif
1565
1566 ret_value = H5VLdatatype_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments);
1567
1568 /* Check for async request */
1569 if (req && *req)
1570 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1571
1572 return ret_value;
1573 } /* end H5VL_pass_through_datatype_optional() */
1574
1575 /*-------------------------------------------------------------------------
1576 * Function: H5VL_pass_through_datatype_close
1577 *
1578 * Purpose: Closes a datatype.
1579 *
1580 * Return: Success: 0
1581 * Failure: -1, datatype not closed.
1582 *
1583 *-------------------------------------------------------------------------
1584 */
1585 static herr_t
H5VL_pass_through_datatype_close(void * dt,hid_t dxpl_id,void ** req)1586 H5VL_pass_through_datatype_close(void *dt, hid_t dxpl_id, void **req)
1587 {
1588 H5VL_pass_through_t *o = (H5VL_pass_through_t *)dt;
1589 herr_t ret_value;
1590
1591 #ifdef ENABLE_PASSTHRU_LOGGING
1592 printf("------- PASS THROUGH VOL DATATYPE Close\n");
1593 #endif
1594
1595 assert(o->under_object);
1596
1597 ret_value = H5VLdatatype_close(o->under_object, o->under_vol_id, dxpl_id, req);
1598
1599 /* Check for async request */
1600 if (req && *req)
1601 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1602
1603 /* Release our wrapper, if underlying datatype was closed */
1604 if (ret_value >= 0)
1605 H5VL_pass_through_free_obj(o);
1606
1607 return ret_value;
1608 } /* end H5VL_pass_through_datatype_close() */
1609
1610 /*-------------------------------------------------------------------------
1611 * Function: H5VL_pass_through_file_create
1612 *
1613 * Purpose: Creates a container using this connector
1614 *
1615 * Return: Success: Pointer to a file object
1616 * Failure: NULL
1617 *
1618 *-------------------------------------------------------------------------
1619 */
1620 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)1621 H5VL_pass_through_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id,
1622 void **req)
1623 {
1624 H5VL_pass_through_info_t *info;
1625 H5VL_pass_through_t * file;
1626 hid_t under_fapl_id;
1627 void * under;
1628
1629 #ifdef ENABLE_PASSTHRU_LOGGING
1630 printf("------- PASS THROUGH VOL FILE Create\n");
1631 #endif
1632
1633 /* Get copy of our VOL info from FAPL */
1634 H5Pget_vol_info(fapl_id, (void **)&info);
1635
1636 /* Make sure we have info about the underlying VOL to be used */
1637 if (!info)
1638 return NULL;
1639
1640 /* Copy the FAPL */
1641 under_fapl_id = H5Pcopy(fapl_id);
1642
1643 /* Set the VOL ID and info for the underlying FAPL */
1644 H5Pset_vol(under_fapl_id, info->under_vol_id, info->under_vol_info);
1645
1646 /* Open the file with the underlying VOL connector */
1647 under = H5VLfile_create(name, flags, fcpl_id, under_fapl_id, dxpl_id, req);
1648 if (under) {
1649 file = H5VL_pass_through_new_obj(under, info->under_vol_id);
1650
1651 /* Check for async request */
1652 if (req && *req)
1653 *req = H5VL_pass_through_new_obj(*req, info->under_vol_id);
1654 } /* end if */
1655 else
1656 file = NULL;
1657
1658 /* Close underlying FAPL */
1659 H5Pclose(under_fapl_id);
1660
1661 /* Release copy of our VOL info */
1662 H5VL_pass_through_info_free(info);
1663
1664 return (void *)file;
1665 } /* end H5VL_pass_through_file_create() */
1666
1667 /*-------------------------------------------------------------------------
1668 * Function: H5VL_pass_through_file_open
1669 *
1670 * Purpose: Opens a container created with this connector
1671 *
1672 * Return: Success: Pointer to a file object
1673 * Failure: NULL
1674 *
1675 *-------------------------------------------------------------------------
1676 */
1677 static void *
H5VL_pass_through_file_open(const char * name,unsigned flags,hid_t fapl_id,hid_t dxpl_id,void ** req)1678 H5VL_pass_through_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t dxpl_id, void **req)
1679 {
1680 H5VL_pass_through_info_t *info;
1681 H5VL_pass_through_t * file;
1682 hid_t under_fapl_id;
1683 void * under;
1684
1685 #ifdef ENABLE_PASSTHRU_LOGGING
1686 printf("------- PASS THROUGH VOL FILE Open\n");
1687 #endif
1688
1689 /* Get copy of our VOL info from FAPL */
1690 H5Pget_vol_info(fapl_id, (void **)&info);
1691
1692 /* Make sure we have info about the underlying VOL to be used */
1693 if (!info)
1694 return NULL;
1695
1696 /* Copy the FAPL */
1697 under_fapl_id = H5Pcopy(fapl_id);
1698
1699 /* Set the VOL ID and info for the underlying FAPL */
1700 H5Pset_vol(under_fapl_id, info->under_vol_id, info->under_vol_info);
1701
1702 /* Open the file with the underlying VOL connector */
1703 under = H5VLfile_open(name, flags, under_fapl_id, dxpl_id, req);
1704 if (under) {
1705 file = H5VL_pass_through_new_obj(under, info->under_vol_id);
1706
1707 /* Check for async request */
1708 if (req && *req)
1709 *req = H5VL_pass_through_new_obj(*req, info->under_vol_id);
1710 } /* end if */
1711 else
1712 file = NULL;
1713
1714 /* Close underlying FAPL */
1715 H5Pclose(under_fapl_id);
1716
1717 /* Release copy of our VOL info */
1718 H5VL_pass_through_info_free(info);
1719
1720 return (void *)file;
1721 } /* end H5VL_pass_through_file_open() */
1722
1723 /*-------------------------------------------------------------------------
1724 * Function: H5VL_pass_through_file_get
1725 *
1726 * Purpose: Get info about a file
1727 *
1728 * Return: Success: 0
1729 * Failure: -1
1730 *
1731 *-------------------------------------------------------------------------
1732 */
1733 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)1734 H5VL_pass_through_file_get(void *file, H5VL_file_get_t get_type, hid_t dxpl_id, void **req, va_list arguments)
1735 {
1736 H5VL_pass_through_t *o = (H5VL_pass_through_t *)file;
1737 herr_t ret_value;
1738
1739 #ifdef ENABLE_PASSTHRU_LOGGING
1740 printf("------- PASS THROUGH VOL FILE Get\n");
1741 #endif
1742
1743 ret_value = H5VLfile_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
1744
1745 /* Check for async request */
1746 if (req && *req)
1747 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1748
1749 return ret_value;
1750 } /* end H5VL_pass_through_file_get() */
1751
1752 /*-------------------------------------------------------------------------
1753 * Function: H5VL_pass_through_file_specific_reissue
1754 *
1755 * Purpose: Re-wrap vararg arguments into a va_list and reissue the
1756 * file specific callback to the underlying VOL connector.
1757 *
1758 * Return: Success: 0
1759 * Failure: -1
1760 *
1761 *-------------------------------------------------------------------------
1762 */
1763 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,...)1764 H5VL_pass_through_file_specific_reissue(void *obj, hid_t connector_id, H5VL_file_specific_t specific_type,
1765 hid_t dxpl_id, void **req, ...)
1766 {
1767 va_list arguments;
1768 herr_t ret_value;
1769
1770 va_start(arguments, req);
1771 ret_value = H5VLfile_specific(obj, connector_id, specific_type, dxpl_id, req, arguments);
1772 va_end(arguments);
1773
1774 return ret_value;
1775 } /* end H5VL_pass_through_file_specific_reissue() */
1776
1777 /*-------------------------------------------------------------------------
1778 * Function: H5VL_pass_through_file_specific
1779 *
1780 * Purpose: Specific operation on file
1781 *
1782 * Return: Success: 0
1783 * Failure: -1
1784 *
1785 *-------------------------------------------------------------------------
1786 */
1787 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)1788 H5VL_pass_through_file_specific(void *file, H5VL_file_specific_t specific_type, hid_t dxpl_id, void **req,
1789 va_list arguments)
1790 {
1791 H5VL_pass_through_t *o = (H5VL_pass_through_t *)file;
1792 hid_t under_vol_id = -1;
1793 herr_t ret_value;
1794
1795 #ifdef ENABLE_PASSTHRU_LOGGING
1796 printf("------- PASS THROUGH VOL FILE Specific\n");
1797 #endif
1798
1799 /* Unpack arguments to get at the child file pointer when mounting a file */
1800 if (specific_type == H5VL_FILE_MOUNT) {
1801 H5I_type_t loc_type;
1802 const char * name;
1803 H5VL_pass_through_t *child_file;
1804 hid_t plist_id;
1805
1806 /* Retrieve parameters for 'mount' operation, so we can unwrap the child file */
1807 loc_type = (H5I_type_t)va_arg(arguments, int); /* enum work-around */
1808 name = va_arg(arguments, const char *);
1809 child_file = (H5VL_pass_through_t *)va_arg(arguments, void *);
1810 plist_id = va_arg(arguments, hid_t);
1811
1812 /* Keep the correct underlying VOL ID for possible async request token */
1813 under_vol_id = o->under_vol_id;
1814
1815 /* Re-issue 'file specific' call, using the unwrapped pieces */
1816 ret_value = H5VL_pass_through_file_specific_reissue(o->under_object, o->under_vol_id, specific_type,
1817 dxpl_id, req, (int)loc_type, name,
1818 child_file->under_object, plist_id);
1819 } /* end if */
1820 else if (specific_type == H5VL_FILE_IS_ACCESSIBLE || specific_type == H5VL_FILE_DELETE) {
1821 H5VL_pass_through_info_t *info;
1822 hid_t fapl_id, under_fapl_id;
1823 const char * name;
1824 htri_t * ret;
1825
1826 /* Get the arguments for the 'is accessible' check */
1827 fapl_id = va_arg(arguments, hid_t);
1828 name = va_arg(arguments, const char *);
1829 ret = va_arg(arguments, htri_t *);
1830
1831 /* Get copy of our VOL info from FAPL */
1832 H5Pget_vol_info(fapl_id, (void **)&info);
1833
1834 /* Make sure we have info about the underlying VOL to be used */
1835 if (!info)
1836 return (-1);
1837
1838 /* Copy the FAPL */
1839 under_fapl_id = H5Pcopy(fapl_id);
1840
1841 /* Set the VOL ID and info for the underlying FAPL */
1842 H5Pset_vol(under_fapl_id, info->under_vol_id, info->under_vol_info);
1843
1844 /* Keep the correct underlying VOL ID for possible async request token */
1845 under_vol_id = info->under_vol_id;
1846
1847 /* Re-issue 'file specific' call */
1848 ret_value = H5VL_pass_through_file_specific_reissue(NULL, info->under_vol_id, specific_type, dxpl_id,
1849 req, under_fapl_id, name, ret);
1850
1851 /* Close underlying FAPL */
1852 H5Pclose(under_fapl_id);
1853
1854 /* Release copy of our VOL info */
1855 H5VL_pass_through_info_free(info);
1856 } /* end else-if */
1857 else {
1858 va_list my_arguments;
1859
1860 /* Make a copy of the argument list for later, if reopening */
1861 if (specific_type == H5VL_FILE_REOPEN)
1862 va_copy(my_arguments, arguments);
1863
1864 /* Keep the correct underlying VOL ID for possible async request token */
1865 under_vol_id = o->under_vol_id;
1866
1867 ret_value =
1868 H5VLfile_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
1869
1870 /* Wrap file struct pointer, if we reopened one */
1871 if (specific_type == H5VL_FILE_REOPEN) {
1872 if (ret_value >= 0) {
1873 void **ret = va_arg(my_arguments, void **);
1874
1875 if (ret && *ret)
1876 *ret = H5VL_pass_through_new_obj(*ret, o->under_vol_id);
1877 } /* end if */
1878
1879 /* Finish use of copied vararg list */
1880 va_end(my_arguments);
1881 } /* end if */
1882 } /* end else */
1883
1884 /* Check for async request */
1885 if (req && *req)
1886 *req = H5VL_pass_through_new_obj(*req, under_vol_id);
1887
1888 return ret_value;
1889 } /* end H5VL_pass_through_file_specific() */
1890
1891 /*-------------------------------------------------------------------------
1892 * Function: H5VL_pass_through_file_optional
1893 *
1894 * Purpose: Perform a connector-specific operation on a file
1895 *
1896 * Return: Success: 0
1897 * Failure: -1
1898 *
1899 *-------------------------------------------------------------------------
1900 */
1901 static herr_t
H5VL_pass_through_file_optional(void * file,H5VL_file_optional_t opt_type,hid_t dxpl_id,void ** req,va_list arguments)1902 H5VL_pass_through_file_optional(void *file, H5VL_file_optional_t opt_type, hid_t dxpl_id, void **req,
1903 va_list arguments)
1904 {
1905 H5VL_pass_through_t *o = (H5VL_pass_through_t *)file;
1906 herr_t ret_value;
1907
1908 #ifdef ENABLE_PASSTHRU_LOGGING
1909 printf("------- PASS THROUGH VOL File Optional\n");
1910 #endif
1911
1912 ret_value = H5VLfile_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments);
1913
1914 /* Check for async request */
1915 if (req && *req)
1916 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1917
1918 return ret_value;
1919 } /* end H5VL_pass_through_file_optional() */
1920
1921 /*-------------------------------------------------------------------------
1922 * Function: H5VL_pass_through_file_close
1923 *
1924 * Purpose: Closes a file.
1925 *
1926 * Return: Success: 0
1927 * Failure: -1, file not closed.
1928 *
1929 *-------------------------------------------------------------------------
1930 */
1931 static herr_t
H5VL_pass_through_file_close(void * file,hid_t dxpl_id,void ** req)1932 H5VL_pass_through_file_close(void *file, hid_t dxpl_id, void **req)
1933 {
1934 H5VL_pass_through_t *o = (H5VL_pass_through_t *)file;
1935 herr_t ret_value;
1936
1937 #ifdef ENABLE_PASSTHRU_LOGGING
1938 printf("------- PASS THROUGH VOL FILE Close\n");
1939 #endif
1940
1941 ret_value = H5VLfile_close(o->under_object, o->under_vol_id, dxpl_id, req);
1942
1943 /* Check for async request */
1944 if (req && *req)
1945 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1946
1947 /* Release our wrapper, if underlying file was closed */
1948 if (ret_value >= 0)
1949 H5VL_pass_through_free_obj(o);
1950
1951 return ret_value;
1952 } /* end H5VL_pass_through_file_close() */
1953
1954 /*-------------------------------------------------------------------------
1955 * Function: H5VL_pass_through_group_create
1956 *
1957 * Purpose: Creates a group inside a container
1958 *
1959 * Return: Success: Pointer to a group object
1960 * Failure: NULL
1961 *
1962 *-------------------------------------------------------------------------
1963 */
1964 static void *
H5VL_pass_through_group_create(void * obj,const H5VL_loc_params_t * loc_params,const char * name,hid_t lcpl_id,hid_t gcpl_id,hid_t gapl_id,hid_t dxpl_id,void ** req)1965 H5VL_pass_through_group_create(void *obj, const H5VL_loc_params_t *loc_params, const char *name,
1966 hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id, hid_t dxpl_id, void **req)
1967 {
1968 H5VL_pass_through_t *group;
1969 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
1970 void * under;
1971
1972 #ifdef ENABLE_PASSTHRU_LOGGING
1973 printf("------- PASS THROUGH VOL GROUP Create\n");
1974 #endif
1975
1976 under = H5VLgroup_create(o->under_object, loc_params, o->under_vol_id, name, lcpl_id, gcpl_id, gapl_id,
1977 dxpl_id, req);
1978 if (under) {
1979 group = H5VL_pass_through_new_obj(under, o->under_vol_id);
1980
1981 /* Check for async request */
1982 if (req && *req)
1983 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
1984 } /* end if */
1985 else
1986 group = NULL;
1987
1988 return (void *)group;
1989 } /* end H5VL_pass_through_group_create() */
1990
1991 /*-------------------------------------------------------------------------
1992 * Function: H5VL_pass_through_group_open
1993 *
1994 * Purpose: Opens a group inside a container
1995 *
1996 * Return: Success: Pointer to a group object
1997 * Failure: NULL
1998 *
1999 *-------------------------------------------------------------------------
2000 */
2001 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)2002 H5VL_pass_through_group_open(void *obj, const H5VL_loc_params_t *loc_params, const char *name, hid_t gapl_id,
2003 hid_t dxpl_id, void **req)
2004 {
2005 H5VL_pass_through_t *group;
2006 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2007 void * under;
2008
2009 #ifdef ENABLE_PASSTHRU_LOGGING
2010 printf("------- PASS THROUGH VOL GROUP Open\n");
2011 #endif
2012
2013 under = H5VLgroup_open(o->under_object, loc_params, o->under_vol_id, name, gapl_id, dxpl_id, req);
2014 if (under) {
2015 group = H5VL_pass_through_new_obj(under, o->under_vol_id);
2016
2017 /* Check for async request */
2018 if (req && *req)
2019 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2020 } /* end if */
2021 else
2022 group = NULL;
2023
2024 return (void *)group;
2025 } /* end H5VL_pass_through_group_open() */
2026
2027 /*-------------------------------------------------------------------------
2028 * Function: H5VL_pass_through_group_get
2029 *
2030 * Purpose: Get info about a group
2031 *
2032 * Return: Success: 0
2033 * Failure: -1
2034 *
2035 *-------------------------------------------------------------------------
2036 */
2037 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)2038 H5VL_pass_through_group_get(void *obj, H5VL_group_get_t get_type, hid_t dxpl_id, void **req,
2039 va_list arguments)
2040 {
2041 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2042 herr_t ret_value;
2043
2044 #ifdef ENABLE_PASSTHRU_LOGGING
2045 printf("------- PASS THROUGH VOL GROUP Get\n");
2046 #endif
2047
2048 ret_value = H5VLgroup_get(o->under_object, o->under_vol_id, get_type, dxpl_id, req, arguments);
2049
2050 /* Check for async request */
2051 if (req && *req)
2052 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2053
2054 return ret_value;
2055 } /* end H5VL_pass_through_group_get() */
2056
2057 /*-------------------------------------------------------------------------
2058 * Function: H5VL_pass_through_group_specific
2059 *
2060 * Purpose: Specific operation on a group
2061 *
2062 * Return: Success: 0
2063 * Failure: -1
2064 *
2065 *-------------------------------------------------------------------------
2066 */
2067 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)2068 H5VL_pass_through_group_specific(void *obj, H5VL_group_specific_t specific_type, hid_t dxpl_id, void **req,
2069 va_list arguments)
2070 {
2071 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2072 hid_t under_vol_id;
2073 herr_t ret_value;
2074
2075 #ifdef ENABLE_PASSTHRU_LOGGING
2076 printf("------- PASS THROUGH VOL GROUP Specific\n");
2077 #endif
2078
2079 // Save copy of underlying VOL connector ID and prov helper, in case of
2080 // refresh destroying the current object
2081 under_vol_id = o->under_vol_id;
2082
2083 ret_value = H5VLgroup_specific(o->under_object, o->under_vol_id, specific_type, dxpl_id, req, arguments);
2084
2085 /* Check for async request */
2086 if (req && *req)
2087 *req = H5VL_pass_through_new_obj(*req, under_vol_id);
2088
2089 return ret_value;
2090 } /* end H5VL_pass_through_group_specific() */
2091
2092 /*-------------------------------------------------------------------------
2093 * Function: H5VL_pass_through_group_optional
2094 *
2095 * Purpose: Perform a connector-specific operation on a group
2096 *
2097 * Return: Success: 0
2098 * Failure: -1
2099 *
2100 *-------------------------------------------------------------------------
2101 */
2102 static herr_t
H5VL_pass_through_group_optional(void * obj,H5VL_group_optional_t opt_type,hid_t dxpl_id,void ** req,va_list arguments)2103 H5VL_pass_through_group_optional(void *obj, H5VL_group_optional_t opt_type, hid_t dxpl_id, void **req,
2104 va_list arguments)
2105 {
2106 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2107 herr_t ret_value;
2108
2109 #ifdef ENABLE_PASSTHRU_LOGGING
2110 printf("------- PASS THROUGH VOL GROUP Optional\n");
2111 #endif
2112
2113 ret_value = H5VLgroup_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments);
2114
2115 /* Check for async request */
2116 if (req && *req)
2117 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2118
2119 return ret_value;
2120 } /* end H5VL_pass_through_group_optional() */
2121
2122 /*-------------------------------------------------------------------------
2123 * Function: H5VL_pass_through_group_close
2124 *
2125 * Purpose: Closes a group.
2126 *
2127 * Return: Success: 0
2128 * Failure: -1, group not closed.
2129 *
2130 *-------------------------------------------------------------------------
2131 */
2132 static herr_t
H5VL_pass_through_group_close(void * grp,hid_t dxpl_id,void ** req)2133 H5VL_pass_through_group_close(void *grp, hid_t dxpl_id, void **req)
2134 {
2135 H5VL_pass_through_t *o = (H5VL_pass_through_t *)grp;
2136 herr_t ret_value;
2137
2138 #ifdef ENABLE_PASSTHRU_LOGGING
2139 printf("------- PASS THROUGH VOL H5Gclose\n");
2140 #endif
2141
2142 ret_value = H5VLgroup_close(o->under_object, o->under_vol_id, dxpl_id, req);
2143
2144 /* Check for async request */
2145 if (req && *req)
2146 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2147
2148 /* Release our wrapper, if underlying file was closed */
2149 if (ret_value >= 0)
2150 H5VL_pass_through_free_obj(o);
2151
2152 return ret_value;
2153 } /* end H5VL_pass_through_group_close() */
2154
2155 /*-------------------------------------------------------------------------
2156 * Function: H5VL_pass_through_link_create_reissue
2157 *
2158 * Purpose: Re-wrap vararg arguments into a va_list and reissue the
2159 * link create callback to the underlying VOL connector.
2160 *
2161 * Return: Success: 0
2162 * Failure: -1
2163 *
2164 *-------------------------------------------------------------------------
2165 */
2166 static herr_t
H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type,void * obj,const H5VL_loc_params_t * loc_params,hid_t connector_id,hid_t lcpl_id,hid_t lapl_id,hid_t dxpl_id,void ** req,...)2167 H5VL_pass_through_link_create_reissue(H5VL_link_create_type_t create_type, void *obj,
2168 const H5VL_loc_params_t *loc_params, hid_t connector_id, hid_t lcpl_id,
2169 hid_t lapl_id, hid_t dxpl_id, void **req, ...)
2170 {
2171 va_list arguments;
2172 herr_t ret_value;
2173
2174 va_start(arguments, req);
2175 ret_value = H5VLlink_create(create_type, obj, loc_params, connector_id, lcpl_id, lapl_id, dxpl_id, req,
2176 arguments);
2177 va_end(arguments);
2178
2179 return ret_value;
2180 } /* end H5VL_pass_through_link_create_reissue() */
2181
2182 /*-------------------------------------------------------------------------
2183 * Function: H5VL_pass_through_link_create
2184 *
2185 * Purpose: Creates a hard / soft / UD / external link.
2186 *
2187 * Return: Success: 0
2188 * Failure: -1
2189 *
2190 *-------------------------------------------------------------------------
2191 */
2192 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,va_list arguments)2193 H5VL_pass_through_link_create(H5VL_link_create_type_t create_type, void *obj,
2194 const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t lapl_id,
2195 hid_t dxpl_id, void **req, va_list arguments)
2196 {
2197 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2198 hid_t under_vol_id = -1;
2199 herr_t ret_value;
2200
2201 #ifdef ENABLE_PASSTHRU_LOGGING
2202 printf("------- PASS THROUGH VOL LINK Create\n");
2203 #endif
2204
2205 /* Try to retrieve the "under" VOL id */
2206 if (o)
2207 under_vol_id = o->under_vol_id;
2208
2209 /* Fix up the link target object for hard link creation */
2210 if (H5VL_LINK_CREATE_HARD == create_type) {
2211 void * cur_obj;
2212 H5VL_loc_params_t *cur_params;
2213
2214 /* Retrieve the object & loc params for the link target */
2215 cur_obj = va_arg(arguments, void *);
2216 cur_params = va_arg(arguments, H5VL_loc_params_t *);
2217
2218 /* If it's a non-NULL pointer, find the 'under object' and re-set the property */
2219 if (cur_obj) {
2220 /* Check if we still need the "under" VOL ID */
2221 if (under_vol_id < 0)
2222 under_vol_id = ((H5VL_pass_through_t *)cur_obj)->under_vol_id;
2223
2224 /* Set the object for the link target */
2225 cur_obj = ((H5VL_pass_through_t *)cur_obj)->under_object;
2226 } /* end if */
2227
2228 /* Re-issue 'link create' call, using the unwrapped pieces */
2229 ret_value = H5VL_pass_through_link_create_reissue(create_type, (o ? o->under_object : NULL),
2230 loc_params, under_vol_id, lcpl_id, lapl_id, dxpl_id,
2231 req, cur_obj, cur_params);
2232 } /* end if */
2233 else
2234 ret_value = H5VLlink_create(create_type, (o ? o->under_object : NULL), loc_params, under_vol_id,
2235 lcpl_id, lapl_id, dxpl_id, req, arguments);
2236
2237 /* Check for async request */
2238 if (req && *req)
2239 *req = H5VL_pass_through_new_obj(*req, under_vol_id);
2240
2241 return ret_value;
2242 } /* end H5VL_pass_through_link_create() */
2243
2244 /*-------------------------------------------------------------------------
2245 * Function: H5VL_pass_through_link_copy
2246 *
2247 * Purpose: Renames an object within an HDF5 container and copies it to a new
2248 * group. The original name SRC is unlinked from the group graph
2249 * and then inserted with the new name DST (which can specify a
2250 * new path for the object) as an atomic operation. The names
2251 * are interpreted relative to SRC_LOC_ID and
2252 * DST_LOC_ID, which are either file IDs or group ID.
2253 *
2254 * Return: Success: 0
2255 * Failure: -1
2256 *
2257 *-------------------------------------------------------------------------
2258 */
2259 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)2260 H5VL_pass_through_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
2261 const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id,
2262 void **req)
2263 {
2264 H5VL_pass_through_t *o_src = (H5VL_pass_through_t *)src_obj;
2265 H5VL_pass_through_t *o_dst = (H5VL_pass_through_t *)dst_obj;
2266 hid_t under_vol_id = -1;
2267 herr_t ret_value;
2268
2269 #ifdef ENABLE_PASSTHRU_LOGGING
2270 printf("------- PASS THROUGH VOL LINK Copy\n");
2271 #endif
2272
2273 /* Retrieve the "under" VOL id */
2274 if (o_src)
2275 under_vol_id = o_src->under_vol_id;
2276 else if (o_dst)
2277 under_vol_id = o_dst->under_vol_id;
2278 assert(under_vol_id > 0);
2279
2280 ret_value =
2281 H5VLlink_copy((o_src ? o_src->under_object : NULL), loc_params1, (o_dst ? o_dst->under_object : NULL),
2282 loc_params2, under_vol_id, lcpl_id, lapl_id, dxpl_id, req);
2283
2284 /* Check for async request */
2285 if (req && *req)
2286 *req = H5VL_pass_through_new_obj(*req, under_vol_id);
2287
2288 return ret_value;
2289 } /* end H5VL_pass_through_link_copy() */
2290
2291 /*-------------------------------------------------------------------------
2292 * Function: H5VL_pass_through_link_move
2293 *
2294 * Purpose: Moves a link within an HDF5 file to a new group. The original
2295 * name SRC is unlinked from the group graph
2296 * and then inserted with the new name DST (which can specify a
2297 * new path for the object) as an atomic operation. The names
2298 * are interpreted relative to SRC_LOC_ID and
2299 * DST_LOC_ID, which are either file IDs or group ID.
2300 *
2301 * Return: Success: 0
2302 * Failure: -1
2303 *
2304 *-------------------------------------------------------------------------
2305 */
2306 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)2307 H5VL_pass_through_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj,
2308 const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id,
2309 void **req)
2310 {
2311 H5VL_pass_through_t *o_src = (H5VL_pass_through_t *)src_obj;
2312 H5VL_pass_through_t *o_dst = (H5VL_pass_through_t *)dst_obj;
2313 hid_t under_vol_id = -1;
2314 herr_t ret_value;
2315
2316 #ifdef ENABLE_PASSTHRU_LOGGING
2317 printf("------- PASS THROUGH VOL LINK Move\n");
2318 #endif
2319
2320 /* Retrieve the "under" VOL id */
2321 if (o_src)
2322 under_vol_id = o_src->under_vol_id;
2323 else if (o_dst)
2324 under_vol_id = o_dst->under_vol_id;
2325 assert(under_vol_id > 0);
2326
2327 ret_value =
2328 H5VLlink_move((o_src ? o_src->under_object : NULL), loc_params1, (o_dst ? o_dst->under_object : NULL),
2329 loc_params2, under_vol_id, lcpl_id, lapl_id, dxpl_id, req);
2330
2331 /* Check for async request */
2332 if (req && *req)
2333 *req = H5VL_pass_through_new_obj(*req, under_vol_id);
2334
2335 return ret_value;
2336 } /* end H5VL_pass_through_link_move() */
2337
2338 /*-------------------------------------------------------------------------
2339 * Function: H5VL_pass_through_link_get
2340 *
2341 * Purpose: Get info about a link
2342 *
2343 * Return: Success: 0
2344 * Failure: -1
2345 *
2346 *-------------------------------------------------------------------------
2347 */
2348 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)2349 H5VL_pass_through_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_t get_type,
2350 hid_t dxpl_id, void **req, va_list arguments)
2351 {
2352 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2353 herr_t ret_value;
2354
2355 #ifdef ENABLE_PASSTHRU_LOGGING
2356 printf("------- PASS THROUGH VOL LINK Get\n");
2357 #endif
2358
2359 ret_value = H5VLlink_get(o->under_object, loc_params, o->under_vol_id, get_type, dxpl_id, req, arguments);
2360
2361 /* Check for async request */
2362 if (req && *req)
2363 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2364
2365 return ret_value;
2366 } /* end H5VL_pass_through_link_get() */
2367
2368 /*-------------------------------------------------------------------------
2369 * Function: H5VL_pass_through_link_specific
2370 *
2371 * Purpose: Specific operation on a link
2372 *
2373 * Return: Success: 0
2374 * Failure: -1
2375 *
2376 *-------------------------------------------------------------------------
2377 */
2378 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)2379 H5VL_pass_through_link_specific(void *obj, const H5VL_loc_params_t *loc_params,
2380 H5VL_link_specific_t specific_type, hid_t dxpl_id, void **req,
2381 va_list arguments)
2382 {
2383 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2384 herr_t ret_value;
2385
2386 #ifdef ENABLE_PASSTHRU_LOGGING
2387 printf("------- PASS THROUGH VOL LINK Specific\n");
2388 #endif
2389
2390 ret_value = H5VLlink_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req,
2391 arguments);
2392
2393 /* Check for async request */
2394 if (req && *req)
2395 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2396
2397 return ret_value;
2398 } /* end H5VL_pass_through_link_specific() */
2399
2400 /*-------------------------------------------------------------------------
2401 * Function: H5VL_pass_through_link_optional
2402 *
2403 * Purpose: Perform a connector-specific operation on a link
2404 *
2405 * Return: Success: 0
2406 * Failure: -1
2407 *
2408 *-------------------------------------------------------------------------
2409 */
2410 static herr_t
H5VL_pass_through_link_optional(void * obj,H5VL_link_optional_t opt_type,hid_t dxpl_id,void ** req,va_list arguments)2411 H5VL_pass_through_link_optional(void *obj, H5VL_link_optional_t opt_type, hid_t dxpl_id, void **req,
2412 va_list arguments)
2413 {
2414 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2415 herr_t ret_value;
2416
2417 #ifdef ENABLE_PASSTHRU_LOGGING
2418 printf("------- PASS THROUGH VOL LINK Optional\n");
2419 #endif
2420
2421 ret_value = H5VLlink_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments);
2422
2423 /* Check for async request */
2424 if (req && *req)
2425 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2426
2427 return ret_value;
2428 } /* end H5VL_pass_through_link_optional() */
2429
2430 /*-------------------------------------------------------------------------
2431 * Function: H5VL_pass_through_object_open
2432 *
2433 * Purpose: Opens an object inside a container.
2434 *
2435 * Return: Success: Pointer to object
2436 * Failure: NULL
2437 *
2438 *-------------------------------------------------------------------------
2439 */
2440 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)2441 H5VL_pass_through_object_open(void *obj, const H5VL_loc_params_t *loc_params, H5I_type_t *opened_type,
2442 hid_t dxpl_id, void **req)
2443 {
2444 H5VL_pass_through_t *new_obj;
2445 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2446 void * under;
2447
2448 #ifdef ENABLE_PASSTHRU_LOGGING
2449 printf("------- PASS THROUGH VOL OBJECT Open\n");
2450 #endif
2451
2452 under = H5VLobject_open(o->under_object, loc_params, o->under_vol_id, opened_type, dxpl_id, req);
2453 if (under) {
2454 new_obj = H5VL_pass_through_new_obj(under, o->under_vol_id);
2455
2456 /* Check for async request */
2457 if (req && *req)
2458 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2459 } /* end if */
2460 else
2461 new_obj = NULL;
2462
2463 return (void *)new_obj;
2464 } /* end H5VL_pass_through_object_open() */
2465
2466 /*-------------------------------------------------------------------------
2467 * Function: H5VL_pass_through_object_copy
2468 *
2469 * Purpose: Copies an object inside a container.
2470 *
2471 * Return: Success: 0
2472 * Failure: -1
2473 *
2474 *-------------------------------------------------------------------------
2475 */
2476 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)2477 H5VL_pass_through_object_copy(void *src_obj, const H5VL_loc_params_t *src_loc_params, const char *src_name,
2478 void *dst_obj, const H5VL_loc_params_t *dst_loc_params, const char *dst_name,
2479 hid_t ocpypl_id, hid_t lcpl_id, hid_t dxpl_id, void **req)
2480 {
2481 H5VL_pass_through_t *o_src = (H5VL_pass_through_t *)src_obj;
2482 H5VL_pass_through_t *o_dst = (H5VL_pass_through_t *)dst_obj;
2483 herr_t ret_value;
2484
2485 #ifdef ENABLE_PASSTHRU_LOGGING
2486 printf("------- PASS THROUGH VOL OBJECT Copy\n");
2487 #endif
2488
2489 ret_value =
2490 H5VLobject_copy(o_src->under_object, src_loc_params, src_name, o_dst->under_object, dst_loc_params,
2491 dst_name, o_src->under_vol_id, ocpypl_id, lcpl_id, dxpl_id, req);
2492
2493 /* Check for async request */
2494 if (req && *req)
2495 *req = H5VL_pass_through_new_obj(*req, o_src->under_vol_id);
2496
2497 return ret_value;
2498 } /* end H5VL_pass_through_object_copy() */
2499
2500 /*-------------------------------------------------------------------------
2501 * Function: H5VL_pass_through_object_get
2502 *
2503 * Purpose: Get info about an object
2504 *
2505 * Return: Success: 0
2506 * Failure: -1
2507 *
2508 *-------------------------------------------------------------------------
2509 */
2510 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)2511 H5VL_pass_through_object_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_object_get_t get_type,
2512 hid_t dxpl_id, void **req, va_list arguments)
2513 {
2514 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2515 herr_t ret_value;
2516
2517 #ifdef ENABLE_PASSTHRU_LOGGING
2518 printf("------- PASS THROUGH VOL OBJECT Get\n");
2519 #endif
2520
2521 ret_value =
2522 H5VLobject_get(o->under_object, loc_params, o->under_vol_id, get_type, dxpl_id, req, arguments);
2523
2524 /* Check for async request */
2525 if (req && *req)
2526 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2527
2528 return ret_value;
2529 } /* end H5VL_pass_through_object_get() */
2530
2531 /*-------------------------------------------------------------------------
2532 * Function: H5VL_pass_through_object_specific
2533 *
2534 * Purpose: Specific operation on an object
2535 *
2536 * Return: Success: 0
2537 * Failure: -1
2538 *
2539 *-------------------------------------------------------------------------
2540 */
2541 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)2542 H5VL_pass_through_object_specific(void *obj, const H5VL_loc_params_t *loc_params,
2543 H5VL_object_specific_t specific_type, hid_t dxpl_id, void **req,
2544 va_list arguments)
2545 {
2546 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2547 hid_t under_vol_id;
2548 herr_t ret_value;
2549
2550 #ifdef ENABLE_PASSTHRU_LOGGING
2551 printf("------- PASS THROUGH VOL OBJECT Specific\n");
2552 #endif
2553
2554 // Save copy of underlying VOL connector ID and prov helper, in case of
2555 // refresh destroying the current object
2556 under_vol_id = o->under_vol_id;
2557
2558 ret_value = H5VLobject_specific(o->under_object, loc_params, o->under_vol_id, specific_type, dxpl_id, req,
2559 arguments);
2560
2561 /* Check for async request */
2562 if (req && *req)
2563 *req = H5VL_pass_through_new_obj(*req, under_vol_id);
2564
2565 return ret_value;
2566 } /* end H5VL_pass_through_object_specific() */
2567
2568 /*-------------------------------------------------------------------------
2569 * Function: H5VL_pass_through_object_optional
2570 *
2571 * Purpose: Perform a connector-specific operation for an object
2572 *
2573 * Return: Success: 0
2574 * Failure: -1
2575 *
2576 *-------------------------------------------------------------------------
2577 */
2578 static herr_t
H5VL_pass_through_object_optional(void * obj,H5VL_object_optional_t opt_type,hid_t dxpl_id,void ** req,va_list arguments)2579 H5VL_pass_through_object_optional(void *obj, H5VL_object_optional_t opt_type, hid_t dxpl_id, void **req,
2580 va_list arguments)
2581 {
2582 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2583 herr_t ret_value;
2584
2585 #ifdef ENABLE_PASSTHRU_LOGGING
2586 printf("------- PASS THROUGH VOL OBJECT Optional\n");
2587 #endif
2588
2589 ret_value = H5VLobject_optional(o->under_object, o->under_vol_id, opt_type, dxpl_id, req, arguments);
2590
2591 /* Check for async request */
2592 if (req && *req)
2593 *req = H5VL_pass_through_new_obj(*req, o->under_vol_id);
2594
2595 return ret_value;
2596 } /* end H5VL_pass_through_object_optional() */
2597
2598 /*-------------------------------------------------------------------------
2599 * Function: H5VL_pass_through_introspect_get_conn_clss
2600 *
2601 * Purpose: Query the connector class.
2602 *
2603 * Return: SUCCEED / FAIL
2604 *
2605 *-------------------------------------------------------------------------
2606 */
2607 herr_t
H5VL_pass_through_introspect_get_conn_cls(void * obj,H5VL_get_conn_lvl_t lvl,const H5VL_class_t ** conn_cls)2608 H5VL_pass_through_introspect_get_conn_cls(void *obj, H5VL_get_conn_lvl_t lvl, const H5VL_class_t **conn_cls)
2609 {
2610 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2611 herr_t ret_value;
2612
2613 #ifdef ENABLE_PASSTHRU_LOGGING
2614 printf("------- PASS THROUGH VOL INTROSPECT GetConnCls\n");
2615 #endif
2616
2617 /* Check for querying this connector's class */
2618 if (H5VL_GET_CONN_LVL_CURR == lvl) {
2619 *conn_cls = &H5VL_pass_through_g;
2620 ret_value = 0;
2621 } /* end if */
2622 else
2623 ret_value = H5VLintrospect_get_conn_cls(o->under_object, o->under_vol_id, lvl, conn_cls);
2624
2625 return ret_value;
2626 } /* end H5VL_pass_through_introspect_get_conn_cls() */
2627
2628 /*-------------------------------------------------------------------------
2629 * Function: H5VL_pass_through_introspect_opt_query
2630 *
2631 * Purpose: Query if an optional operation is supported by this connector
2632 *
2633 * Return: SUCCEED / FAIL
2634 *
2635 *-------------------------------------------------------------------------
2636 */
2637 herr_t
H5VL_pass_through_introspect_opt_query(void * obj,H5VL_subclass_t cls,int opt_type,hbool_t * supported)2638 H5VL_pass_through_introspect_opt_query(void *obj, H5VL_subclass_t cls, int opt_type, hbool_t *supported)
2639 {
2640 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2641 herr_t ret_value;
2642
2643 #ifdef ENABLE_PASSTHRU_LOGGING
2644 printf("------- PASS THROUGH VOL INTROSPECT OptQuery\n");
2645 #endif
2646
2647 ret_value = H5VLintrospect_opt_query(o->under_object, o->under_vol_id, cls, opt_type, supported);
2648
2649 return ret_value;
2650 } /* end H5VL_pass_through_introspect_opt_query() */
2651
2652 /*-------------------------------------------------------------------------
2653 * Function: H5VL_pass_through_request_wait
2654 *
2655 * Purpose: Wait (with a timeout) for an async operation to complete
2656 *
2657 * Note: Releases the request if the operation has completed and the
2658 * connector callback succeeds
2659 *
2660 * Return: Success: 0
2661 * Failure: -1
2662 *
2663 *-------------------------------------------------------------------------
2664 */
2665 static herr_t
H5VL_pass_through_request_wait(void * obj,uint64_t timeout,H5ES_status_t * status)2666 H5VL_pass_through_request_wait(void *obj, uint64_t timeout, H5ES_status_t *status)
2667 {
2668 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2669 herr_t ret_value;
2670
2671 #ifdef ENABLE_PASSTHRU_LOGGING
2672 printf("------- PASS THROUGH VOL REQUEST Wait\n");
2673 #endif
2674
2675 ret_value = H5VLrequest_wait(o->under_object, o->under_vol_id, timeout, status);
2676
2677 if (ret_value >= 0 && *status != H5ES_STATUS_IN_PROGRESS)
2678 H5VL_pass_through_free_obj(o);
2679
2680 return ret_value;
2681 } /* end H5VL_pass_through_request_wait() */
2682
2683 /*-------------------------------------------------------------------------
2684 * Function: H5VL_pass_through_request_notify
2685 *
2686 * Purpose: Registers a user callback to be invoked when an asynchronous
2687 * operation completes
2688 *
2689 * Note: Releases the request, if connector callback succeeds
2690 *
2691 * Return: Success: 0
2692 * Failure: -1
2693 *
2694 *-------------------------------------------------------------------------
2695 */
2696 static herr_t
H5VL_pass_through_request_notify(void * obj,H5VL_request_notify_t cb,void * ctx)2697 H5VL_pass_through_request_notify(void *obj, H5VL_request_notify_t cb, void *ctx)
2698 {
2699 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2700 herr_t ret_value;
2701
2702 #ifdef ENABLE_PASSTHRU_LOGGING
2703 printf("------- PASS THROUGH VOL REQUEST Notify\n");
2704 #endif
2705
2706 ret_value = H5VLrequest_notify(o->under_object, o->under_vol_id, cb, ctx);
2707
2708 if (ret_value >= 0)
2709 H5VL_pass_through_free_obj(o);
2710
2711 return ret_value;
2712 } /* end H5VL_pass_through_request_notify() */
2713
2714 /*-------------------------------------------------------------------------
2715 * Function: H5VL_pass_through_request_cancel
2716 *
2717 * Purpose: Cancels an asynchronous operation
2718 *
2719 * Note: Releases the request, if connector callback succeeds
2720 *
2721 * Return: Success: 0
2722 * Failure: -1
2723 *
2724 *-------------------------------------------------------------------------
2725 */
2726 static herr_t
H5VL_pass_through_request_cancel(void * obj)2727 H5VL_pass_through_request_cancel(void *obj)
2728 {
2729 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2730 herr_t ret_value;
2731
2732 #ifdef ENABLE_PASSTHRU_LOGGING
2733 printf("------- PASS THROUGH VOL REQUEST Cancel\n");
2734 #endif
2735
2736 ret_value = H5VLrequest_cancel(o->under_object, o->under_vol_id);
2737
2738 if (ret_value >= 0)
2739 H5VL_pass_through_free_obj(o);
2740
2741 return ret_value;
2742 } /* end H5VL_pass_through_request_cancel() */
2743
2744 /*-------------------------------------------------------------------------
2745 * Function: H5VL_pass_through_request_specific_reissue
2746 *
2747 * Purpose: Re-wrap vararg arguments into a va_list and reissue the
2748 * request specific callback to the underlying VOL connector.
2749 *
2750 * Return: Success: 0
2751 * Failure: -1
2752 *
2753 *-------------------------------------------------------------------------
2754 */
2755 static herr_t
H5VL_pass_through_request_specific_reissue(void * obj,hid_t connector_id,H5VL_request_specific_t specific_type,...)2756 H5VL_pass_through_request_specific_reissue(void *obj, hid_t connector_id,
2757 H5VL_request_specific_t specific_type, ...)
2758 {
2759 va_list arguments;
2760 herr_t ret_value;
2761
2762 va_start(arguments, specific_type);
2763 ret_value = H5VLrequest_specific(obj, connector_id, specific_type, arguments);
2764 va_end(arguments);
2765
2766 return ret_value;
2767 } /* end H5VL_pass_through_request_specific_reissue() */
2768
2769 /*-------------------------------------------------------------------------
2770 * Function: H5VL_pass_through_request_specific
2771 *
2772 * Purpose: Specific operation on a request
2773 *
2774 * Return: Success: 0
2775 * Failure: -1
2776 *
2777 *-------------------------------------------------------------------------
2778 */
2779 static herr_t
H5VL_pass_through_request_specific(void * obj,H5VL_request_specific_t specific_type,va_list arguments)2780 H5VL_pass_through_request_specific(void *obj, H5VL_request_specific_t specific_type, va_list arguments)
2781 {
2782 herr_t ret_value = -1;
2783
2784 #ifdef ENABLE_PASSTHRU_LOGGING
2785 printf("------- PASS THROUGH VOL REQUEST Specific\n");
2786 #endif
2787
2788 if (H5VL_REQUEST_WAITANY == specific_type || H5VL_REQUEST_WAITSOME == specific_type ||
2789 H5VL_REQUEST_WAITALL == specific_type) {
2790 va_list tmp_arguments;
2791 size_t req_count;
2792
2793 /* Sanity check */
2794 assert(obj == NULL);
2795
2796 /* Get enough info to call the underlying connector */
2797 va_copy(tmp_arguments, arguments);
2798 req_count = va_arg(tmp_arguments, size_t);
2799
2800 /* Can only use a request to invoke the underlying VOL connector when there's >0 requests */
2801 if (req_count > 0) {
2802 void ** req_array;
2803 void ** under_req_array;
2804 uint64_t timeout;
2805 H5VL_pass_through_t *o;
2806 size_t u; /* Local index variable */
2807
2808 /* Get the request array */
2809 req_array = va_arg(tmp_arguments, void **);
2810
2811 /* Get a request to use for determining the underlying VOL connector */
2812 o = (H5VL_pass_through_t *)req_array[0];
2813
2814 /* Create array of underlying VOL requests */
2815 under_req_array = (void **)malloc(req_count * sizeof(void **));
2816 for (u = 0; u < req_count; u++)
2817 under_req_array[u] = ((H5VL_pass_through_t *)req_array[u])->under_object;
2818
2819 /* Remove the timeout value from the vararg list (it's used in all the calls below) */
2820 timeout = va_arg(tmp_arguments, uint64_t);
2821
2822 /* Release requests that have completed */
2823 if (H5VL_REQUEST_WAITANY == specific_type) {
2824 size_t * idx; /* Pointer to the index of completed request */
2825 H5ES_status_t *status; /* Pointer to the request's status */
2826
2827 /* Retrieve the remaining arguments */
2828 idx = va_arg(tmp_arguments, size_t *);
2829 assert(*idx <= req_count);
2830 status = va_arg(tmp_arguments, H5ES_status_t *);
2831
2832 /* Reissue the WAITANY 'request specific' call */
2833 ret_value = H5VL_pass_through_request_specific_reissue(o->under_object, o->under_vol_id,
2834 specific_type, req_count,
2835 under_req_array, timeout, idx, status);
2836
2837 /* Release the completed request, if it completed */
2838 if (ret_value >= 0 && *status != H5ES_STATUS_IN_PROGRESS) {
2839 H5VL_pass_through_t *tmp_o;
2840
2841 tmp_o = (H5VL_pass_through_t *)req_array[*idx];
2842 H5VL_pass_through_free_obj(tmp_o);
2843 } /* end if */
2844 } /* end if */
2845 else if (H5VL_REQUEST_WAITSOME == specific_type) {
2846 size_t * outcount; /* # of completed requests */
2847 unsigned * array_of_indices; /* Array of indices for completed requests */
2848 H5ES_status_t *array_of_statuses; /* Array of statuses for completed requests */
2849
2850 /* Retrieve the remaining arguments */
2851 outcount = va_arg(tmp_arguments, size_t *);
2852 assert(*outcount <= req_count);
2853 array_of_indices = va_arg(tmp_arguments, unsigned *);
2854 array_of_statuses = va_arg(tmp_arguments, H5ES_status_t *);
2855
2856 /* Reissue the WAITSOME 'request specific' call */
2857 ret_value = H5VL_pass_through_request_specific_reissue(
2858 o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout,
2859 outcount, array_of_indices, array_of_statuses);
2860
2861 /* If any requests completed, release them */
2862 if (ret_value >= 0 && *outcount > 0) {
2863 unsigned *idx_array; /* Array of indices of completed requests */
2864
2865 /* Retrieve the array of completed request indices */
2866 idx_array = va_arg(tmp_arguments, unsigned *);
2867
2868 /* Release the completed requests */
2869 for (u = 0; u < *outcount; u++) {
2870 H5VL_pass_through_t *tmp_o;
2871
2872 tmp_o = (H5VL_pass_through_t *)req_array[idx_array[u]];
2873 H5VL_pass_through_free_obj(tmp_o);
2874 } /* end for */
2875 } /* end if */
2876 } /* end else-if */
2877 else { /* H5VL_REQUEST_WAITALL == specific_type */
2878 H5ES_status_t *array_of_statuses; /* Array of statuses for completed requests */
2879
2880 /* Retrieve the remaining arguments */
2881 array_of_statuses = va_arg(tmp_arguments, H5ES_status_t *);
2882
2883 /* Reissue the WAITALL 'request specific' call */
2884 ret_value = H5VL_pass_through_request_specific_reissue(
2885 o->under_object, o->under_vol_id, specific_type, req_count, under_req_array, timeout,
2886 array_of_statuses);
2887
2888 /* Release the completed requests */
2889 if (ret_value >= 0) {
2890 for (u = 0; u < req_count; u++) {
2891 if (array_of_statuses[u] != H5ES_STATUS_IN_PROGRESS) {
2892 H5VL_pass_through_t *tmp_o;
2893
2894 tmp_o = (H5VL_pass_through_t *)req_array[u];
2895 H5VL_pass_through_free_obj(tmp_o);
2896 } /* end if */
2897 } /* end for */
2898 } /* end if */
2899 } /* end else */
2900
2901 /* Release array of requests for underlying connector */
2902 free(under_req_array);
2903 } /* end if */
2904
2905 /* Finish use of copied vararg list */
2906 va_end(tmp_arguments);
2907 } /* end if */
2908 else {
2909 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2910
2911 ret_value = H5VLrequest_specific(o->under_object, o->under_vol_id, specific_type, arguments);
2912 } /* end else */
2913
2914 return ret_value;
2915 } /* end H5VL_pass_through_request_specific() */
2916
2917 /*-------------------------------------------------------------------------
2918 * Function: H5VL_pass_through_request_optional
2919 *
2920 * Purpose: Perform a connector-specific operation for a request
2921 *
2922 * Return: Success: 0
2923 * Failure: -1
2924 *
2925 *-------------------------------------------------------------------------
2926 */
2927 static herr_t
H5VL_pass_through_request_optional(void * obj,H5VL_request_optional_t opt_type,va_list arguments)2928 H5VL_pass_through_request_optional(void *obj, H5VL_request_optional_t opt_type, va_list arguments)
2929 {
2930 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2931 herr_t ret_value;
2932
2933 #ifdef ENABLE_PASSTHRU_LOGGING
2934 printf("------- PASS THROUGH VOL REQUEST Optional\n");
2935 #endif
2936
2937 ret_value = H5VLrequest_optional(o->under_object, o->under_vol_id, opt_type, arguments);
2938
2939 return ret_value;
2940 } /* end H5VL_pass_through_request_optional() */
2941
2942 /*-------------------------------------------------------------------------
2943 * Function: H5VL_pass_through_request_free
2944 *
2945 * Purpose: Releases a request, allowing the operation to complete without
2946 * application tracking
2947 *
2948 * Return: Success: 0
2949 * Failure: -1
2950 *
2951 *-------------------------------------------------------------------------
2952 */
2953 static herr_t
H5VL_pass_through_request_free(void * obj)2954 H5VL_pass_through_request_free(void *obj)
2955 {
2956 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2957 herr_t ret_value;
2958
2959 #ifdef ENABLE_PASSTHRU_LOGGING
2960 printf("------- PASS THROUGH VOL REQUEST Free\n");
2961 #endif
2962
2963 ret_value = H5VLrequest_free(o->under_object, o->under_vol_id);
2964
2965 if (ret_value >= 0)
2966 H5VL_pass_through_free_obj(o);
2967
2968 return ret_value;
2969 } /* end H5VL_pass_through_request_free() */
2970
2971 /*-------------------------------------------------------------------------
2972 * Function: H5VL_pass_through_blob_put
2973 *
2974 * Purpose: Handles the blob 'put' callback
2975 *
2976 * Return: SUCCEED / FAIL
2977 *
2978 *-------------------------------------------------------------------------
2979 */
2980 herr_t
H5VL_pass_through_blob_put(void * obj,const void * buf,size_t size,void * blob_id,void * ctx)2981 H5VL_pass_through_blob_put(void *obj, const void *buf, size_t size, void *blob_id, void *ctx)
2982 {
2983 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
2984 herr_t ret_value;
2985
2986 #ifdef ENABLE_PASSTHRU_LOGGING
2987 printf("------- PASS THROUGH VOL BLOB Put\n");
2988 #endif
2989
2990 ret_value = H5VLblob_put(o->under_object, o->under_vol_id, buf, size, blob_id, ctx);
2991
2992 return ret_value;
2993 } /* end H5VL_pass_through_blob_put() */
2994
2995 /*-------------------------------------------------------------------------
2996 * Function: H5VL_pass_through_blob_get
2997 *
2998 * Purpose: Handles the blob 'get' callback
2999 *
3000 * Return: SUCCEED / FAIL
3001 *
3002 *-------------------------------------------------------------------------
3003 */
3004 herr_t
H5VL_pass_through_blob_get(void * obj,const void * blob_id,void * buf,size_t size,void * ctx)3005 H5VL_pass_through_blob_get(void *obj, const void *blob_id, void *buf, size_t size, void *ctx)
3006 {
3007 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
3008 herr_t ret_value;
3009
3010 #ifdef ENABLE_PASSTHRU_LOGGING
3011 printf("------- PASS THROUGH VOL BLOB Get\n");
3012 #endif
3013
3014 ret_value = H5VLblob_get(o->under_object, o->under_vol_id, blob_id, buf, size, ctx);
3015
3016 return ret_value;
3017 } /* end H5VL_pass_through_blob_get() */
3018
3019 /*-------------------------------------------------------------------------
3020 * Function: H5VL_pass_through_blob_specific
3021 *
3022 * Purpose: Handles the blob 'specific' callback
3023 *
3024 * Return: SUCCEED / FAIL
3025 *
3026 *-------------------------------------------------------------------------
3027 */
3028 herr_t
H5VL_pass_through_blob_specific(void * obj,void * blob_id,H5VL_blob_specific_t specific_type,va_list arguments)3029 H5VL_pass_through_blob_specific(void *obj, void *blob_id, H5VL_blob_specific_t specific_type,
3030 va_list arguments)
3031 {
3032 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
3033 herr_t ret_value;
3034
3035 #ifdef ENABLE_PASSTHRU_LOGGING
3036 printf("------- PASS THROUGH VOL BLOB Specific\n");
3037 #endif
3038
3039 ret_value = H5VLblob_specific(o->under_object, o->under_vol_id, blob_id, specific_type, arguments);
3040
3041 return ret_value;
3042 } /* end H5VL_pass_through_blob_specific() */
3043
3044 /*-------------------------------------------------------------------------
3045 * Function: H5VL_pass_through_blob_optional
3046 *
3047 * Purpose: Handles the blob 'optional' callback
3048 *
3049 * Return: SUCCEED / FAIL
3050 *
3051 *-------------------------------------------------------------------------
3052 */
3053 herr_t
H5VL_pass_through_blob_optional(void * obj,void * blob_id,H5VL_blob_optional_t opt_type,va_list arguments)3054 H5VL_pass_through_blob_optional(void *obj, void *blob_id, H5VL_blob_optional_t opt_type, va_list arguments)
3055 {
3056 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
3057 herr_t ret_value;
3058
3059 #ifdef ENABLE_PASSTHRU_LOGGING
3060 printf("------- PASS THROUGH VOL BLOB Optional\n");
3061 #endif
3062
3063 ret_value = H5VLblob_optional(o->under_object, o->under_vol_id, blob_id, opt_type, arguments);
3064
3065 return ret_value;
3066 } /* end H5VL_pass_through_blob_optional() */
3067
3068 /*---------------------------------------------------------------------------
3069 * Function: H5VL_pass_through_token_cmp
3070 *
3071 * Purpose: Compare two of the connector's object tokens, setting
3072 * *cmp_value, following the same rules as strcmp().
3073 *
3074 * Return: Success: 0
3075 * Failure: -1
3076 *
3077 *---------------------------------------------------------------------------
3078 */
3079 static herr_t
H5VL_pass_through_token_cmp(void * obj,const H5O_token_t * token1,const H5O_token_t * token2,int * cmp_value)3080 H5VL_pass_through_token_cmp(void *obj, const H5O_token_t *token1, const H5O_token_t *token2, int *cmp_value)
3081 {
3082 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
3083 herr_t ret_value;
3084
3085 #ifdef ENABLE_PASSTHRU_LOGGING
3086 printf("------- PASS THROUGH VOL TOKEN Compare\n");
3087 #endif
3088
3089 /* Sanity checks */
3090 assert(obj);
3091 assert(token1);
3092 assert(token2);
3093 assert(cmp_value);
3094
3095 ret_value = H5VLtoken_cmp(o->under_object, o->under_vol_id, token1, token2, cmp_value);
3096
3097 return ret_value;
3098 } /* end H5VL_pass_through_token_cmp() */
3099
3100 /*---------------------------------------------------------------------------
3101 * Function: H5VL_pass_through_token_to_str
3102 *
3103 * Purpose: Serialize the connector's object token into a string.
3104 *
3105 * Return: Success: 0
3106 * Failure: -1
3107 *
3108 *---------------------------------------------------------------------------
3109 */
3110 static herr_t
H5VL_pass_through_token_to_str(void * obj,H5I_type_t obj_type,const H5O_token_t * token,char ** token_str)3111 H5VL_pass_through_token_to_str(void *obj, H5I_type_t obj_type, const H5O_token_t *token, char **token_str)
3112 {
3113 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
3114 herr_t ret_value;
3115
3116 #ifdef ENABLE_PASSTHRU_LOGGING
3117 printf("------- PASS THROUGH VOL TOKEN To string\n");
3118 #endif
3119
3120 /* Sanity checks */
3121 assert(obj);
3122 assert(token);
3123 assert(token_str);
3124
3125 ret_value = H5VLtoken_to_str(o->under_object, obj_type, o->under_vol_id, token, token_str);
3126
3127 return ret_value;
3128 } /* end H5VL_pass_through_token_to_str() */
3129
3130 /*---------------------------------------------------------------------------
3131 * Function: H5VL_pass_through_token_from_str
3132 *
3133 * Purpose: Deserialize the connector's object token from a string.
3134 *
3135 * Return: Success: 0
3136 * Failure: -1
3137 *
3138 *---------------------------------------------------------------------------
3139 */
3140 static herr_t
H5VL_pass_through_token_from_str(void * obj,H5I_type_t obj_type,const char * token_str,H5O_token_t * token)3141 H5VL_pass_through_token_from_str(void *obj, H5I_type_t obj_type, const char *token_str, H5O_token_t *token)
3142 {
3143 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
3144 herr_t ret_value;
3145
3146 #ifdef ENABLE_PASSTHRU_LOGGING
3147 printf("------- PASS THROUGH VOL TOKEN From string\n");
3148 #endif
3149
3150 /* Sanity checks */
3151 assert(obj);
3152 assert(token);
3153 assert(token_str);
3154
3155 ret_value = H5VLtoken_from_str(o->under_object, obj_type, o->under_vol_id, token_str, token);
3156
3157 return ret_value;
3158 } /* end H5VL_pass_through_token_from_str() */
3159
3160 /*-------------------------------------------------------------------------
3161 * Function: H5VL_pass_through_optional
3162 *
3163 * Purpose: Handles the generic 'optional' callback
3164 *
3165 * Return: SUCCEED / FAIL
3166 *
3167 *-------------------------------------------------------------------------
3168 */
3169 herr_t
H5VL_pass_through_optional(void * obj,int op_type,hid_t dxpl_id,void ** req,va_list arguments)3170 H5VL_pass_through_optional(void *obj, int op_type, hid_t dxpl_id, void **req, va_list arguments)
3171 {
3172 H5VL_pass_through_t *o = (H5VL_pass_through_t *)obj;
3173 herr_t ret_value;
3174
3175 #ifdef ENABLE_PASSTHRU_LOGGING
3176 printf("------- PASS THROUGH VOL generic Optional\n");
3177 #endif
3178
3179 ret_value = H5VLoptional(o->under_object, o->under_vol_id, op_type, dxpl_id, req, arguments);
3180
3181 return ret_value;
3182 } /* end H5VL_pass_through_optional() */
3183