Coverage Report

Created: 2023-11-19 06:19

/src/hdf5/src/H5VL.c
Line
Count
Source (jump to first uncovered line)
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:     The Virtual Object Layer as described in documentation.
15
 *              The purpose is to provide an abstraction on how to access the
16
 *              underlying HDF5 container, whether in a local file with
17
 *              a specific file format, or remotely on other machines, etc...
18
 */
19
20
/****************/
21
/* Module Setup */
22
/****************/
23
24
#include "H5VLmodule.h" /* This source code file is part of the H5VL module */
25
26
/***********/
27
/* Headers */
28
/***********/
29
30
#include "H5private.h"   /* Generic Functions                    */
31
#include "H5CXprivate.h" /* API Contexts                         */
32
#include "H5Eprivate.h"  /* Error handling                       */
33
#include "H5Iprivate.h"  /* IDs                                  */
34
#include "H5Pprivate.h"  /* Property lists                       */
35
#include "H5Tprivate.h"  /* Datatypes                            */
36
#include "H5VLpkg.h"     /* Virtual Object Layer                 */
37
38
/* VOL connectors */
39
#include "H5VLnative.h" /* Native VOL connector                 */
40
41
/****************/
42
/* Local Macros */
43
/****************/
44
45
/******************/
46
/* Local Typedefs */
47
/******************/
48
49
/********************/
50
/* Local Prototypes */
51
/********************/
52
53
/*********************/
54
/* Package Variables */
55
/*********************/
56
57
/*****************************/
58
/* Library Private Variables */
59
/*****************************/
60
61
/*******************/
62
/* Local Variables */
63
/*******************/
64
65
/*-------------------------------------------------------------------------
66
 * Function:    H5VLregister_connector
67
 *
68
 * Purpose:     Registers a new VOL connector as a member of the virtual object
69
 *              layer class.
70
 *
71
 *              VIPL_ID is a VOL initialization property list which must be
72
 *              created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
73
 *
74
 * Return:      Success:    A VOL connector ID which is good until the
75
 *                          library is closed or the connector is
76
 *                          unregistered.
77
 *
78
 *              Failure:    H5I_INVALID_HID
79
 *
80
 *-------------------------------------------------------------------------
81
 */
82
hid_t
83
H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id)
84
0
{
85
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
86
87
0
    FUNC_ENTER_API(H5I_INVALID_HID)
88
0
    H5TRACE2("i", "*#i", cls, vipl_id);
89
90
    /* Check VOL initialization property list */
91
0
    if (H5P_DEFAULT == vipl_id)
92
0
        vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
93
0
    else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
94
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list");
95
96
    /* Register connector */
97
0
    if ((ret_value = H5VL__register_connector_by_class(cls, true, vipl_id)) < 0)
98
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector");
99
100
0
done:
101
0
    FUNC_LEAVE_API(ret_value)
102
0
} /* end H5VLregister_connector() */
103
104
/*-------------------------------------------------------------------------
105
 * Function:    H5VLregister_connector_by_name
106
 *
107
 * Purpose:     Registers a new VOL connector as a member of the virtual object
108
 *              layer class.
109
 *
110
 *              VIPL_ID is a VOL initialization property list which must be
111
 *              created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
112
 *
113
 * Return:      Success:    A VOL connector ID which is good until the
114
 *                          library is closed or the connector is
115
 *                          unregistered.
116
 *
117
 *              Failure:    H5I_INVALID_HID
118
 *
119
 *-------------------------------------------------------------------------
120
 */
121
hid_t
122
H5VLregister_connector_by_name(const char *name, hid_t vipl_id)
123
0
{
124
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
125
126
0
    FUNC_ENTER_API(H5I_INVALID_HID)
127
0
    H5TRACE2("i", "*si", name, vipl_id);
128
129
    /* Check arguments */
130
0
    if (!name)
131
0
        HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "null VOL connector name is disallowed");
132
0
    if (0 == strlen(name))
133
0
        HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID,
134
0
                    "zero-length VOL connector name is disallowed");
135
136
    /* Check VOL initialization property list */
137
0
    if (H5P_DEFAULT == vipl_id)
138
0
        vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
139
0
    else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
140
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list");
141
142
    /* Register connector */
143
0
    if ((ret_value = H5VL__register_connector_by_name(name, true, vipl_id)) < 0)
144
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector");
145
146
0
done:
147
0
    FUNC_LEAVE_API(ret_value)
148
0
} /* end H5VLregister_connector_by_name() */
149
150
/*-------------------------------------------------------------------------
151
 * Function:    H5VLregister_connector_by_value
152
 *
153
 * Purpose:     Registers a new VOL connector as a member of the virtual object
154
 *              layer class.
155
 *
156
 *              VIPL_ID is a VOL initialization property list which must be
157
 *              created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT).
158
 *
159
 * Return:      Success:    A VOL connector ID which is good until the
160
 *                          library is closed or the connector is
161
 *                          unregistered.
162
 *
163
 *              Failure:    H5I_INVALID_HID
164
 *
165
 *-------------------------------------------------------------------------
166
 */
167
hid_t
168
H5VLregister_connector_by_value(H5VL_class_value_t value, hid_t vipl_id)
169
0
{
170
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
171
172
0
    FUNC_ENTER_API(H5I_INVALID_HID)
173
0
    H5TRACE2("i", "VCi", value, vipl_id);
174
175
    /* Check arguments */
176
0
    if (value < 0)
177
0
        HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID,
178
0
                    "negative VOL connector value is disallowed");
179
180
    /* Check VOL initialization property list */
181
0
    if (H5P_DEFAULT == vipl_id)
182
0
        vipl_id = H5P_VOL_INITIALIZE_DEFAULT;
183
0
    else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE))
184
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list");
185
186
    /* Register connector */
187
0
    if ((ret_value = H5VL__register_connector_by_value(value, true, vipl_id)) < 0)
188
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector");
189
190
0
done:
191
0
    FUNC_LEAVE_API(ret_value)
192
0
} /* end H5VLregister_connector_by_value() */
193
194
/*-------------------------------------------------------------------------
195
 * Function:    H5VLis_connector_registered_by_name
196
 *
197
 * Purpose:     Tests whether a VOL class has been registered or not
198
 *              according to a supplied connector name.
199
 *
200
 * Return:      >0 if a VOL connector with that name has been registered
201
 *              0 if a VOL connector with that name has NOT been registered
202
 *              <0 on errors
203
 *
204
 *-------------------------------------------------------------------------
205
 */
206
htri_t
207
H5VLis_connector_registered_by_name(const char *name)
208
0
{
209
0
    htri_t ret_value = false; /* Return value */
210
211
0
    FUNC_ENTER_API(FAIL)
212
0
    H5TRACE1("t", "*s", name);
213
214
    /* Check if connector with this name is registered */
215
0
    if ((ret_value = H5VL__is_connector_registered_by_name(name)) < 0)
216
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL");
217
218
0
done:
219
0
    FUNC_LEAVE_API(ret_value)
220
0
} /* end H5VLis_connector_registered_by_name() */
221
222
/*-------------------------------------------------------------------------
223
 * Function:    H5VLis_connector_registered_by_value
224
 *
225
 * Purpose:     Tests whether a VOL class has been registered or not
226
 *              according to a supplied connector value (ID).
227
 *
228
 * Return:      >0 if a VOL connector with that value has been registered
229
 *              0 if a VOL connector with that value hasn't been registered
230
 *              <0 on errors
231
 *
232
 *-------------------------------------------------------------------------
233
 */
234
htri_t
235
H5VLis_connector_registered_by_value(H5VL_class_value_t connector_value)
236
0
{
237
0
    htri_t ret_value = false;
238
239
0
    FUNC_ENTER_API(FAIL)
240
0
    H5TRACE1("t", "VC", connector_value);
241
242
    /* Check if connector with this value is registered */
243
0
    if ((ret_value = H5VL__is_connector_registered_by_value(connector_value)) < 0)
244
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL");
245
246
0
done:
247
0
    FUNC_LEAVE_API(ret_value)
248
0
} /* end H5VLis_connector_registered_by_value() */
249
250
/*-------------------------------------------------------------------------
251
 * Function:    H5VLget_connector_id
252
 *
253
 * Purpose:     Retrieves the VOL connector ID for a given object ID.
254
 *
255
 * Return:      A valid VOL connector ID. This ID will need to be closed
256
 *              using H5VLclose().
257
 *
258
 *              H5I_INVALID_HID on error.
259
 *
260
 *-------------------------------------------------------------------------
261
 */
262
hid_t
263
H5VLget_connector_id(hid_t obj_id)
264
0
{
265
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
266
267
0
    FUNC_ENTER_API(H5I_INVALID_HID)
268
0
    H5TRACE1("i", "i", obj_id);
269
270
    /* Get connector ID */
271
0
    if ((ret_value = H5VL__get_connector_id(obj_id, true)) < 0)
272
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id");
273
274
0
done:
275
0
    FUNC_LEAVE_API(ret_value)
276
0
} /* end H5VLget_connector_id() */
277
278
/*-------------------------------------------------------------------------
279
 * Function:    H5VLget_connector_id_by_name
280
 *
281
 * Purpose:     Retrieves the ID for a registered VOL connector.
282
 *
283
 * Return:      A valid VOL connector ID if a connector by that name has
284
 *              been registered. This ID will need to be closed using
285
 *              H5VLclose().
286
 *
287
 *              H5I_INVALID_HID on error or if a VOL connector of that
288
 *              name has not been registered.
289
 *
290
 *-------------------------------------------------------------------------
291
 */
292
hid_t
293
H5VLget_connector_id_by_name(const char *name)
294
0
{
295
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
296
297
0
    FUNC_ENTER_API(H5I_INVALID_HID)
298
0
    H5TRACE1("i", "*s", name);
299
300
    /* Get connector ID with this name */
301
0
    if ((ret_value = H5VL__get_connector_id_by_name(name, true)) < 0)
302
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id");
303
304
0
done:
305
0
    FUNC_LEAVE_API(ret_value)
306
0
} /* end H5VLget_connector_id_by_name() */
307
308
/*-------------------------------------------------------------------------
309
 * Function:    H5VLget_connector_id_by_value
310
 *
311
 * Purpose:     Retrieves the ID for a registered VOL connector.
312
 *
313
 * Return:      A valid VOL connector ID if a connector with that value has
314
 *              been registered. This ID will need to be closed using
315
 *              H5VLclose().
316
 *
317
 *              H5I_INVALID_HID on error or if a VOL connector with that
318
 *              value has not been registered.
319
 *
320
 *-------------------------------------------------------------------------
321
 */
322
hid_t
323
H5VLget_connector_id_by_value(H5VL_class_value_t connector_value)
324
0
{
325
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
326
327
0
    FUNC_ENTER_API(H5I_INVALID_HID)
328
0
    H5TRACE1("i", "VC", connector_value);
329
330
    /* Get connector ID with this value */
331
0
    if ((ret_value = H5VL__get_connector_id_by_value(connector_value, true)) < 0)
332
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id");
333
334
0
done:
335
0
    FUNC_LEAVE_API(ret_value)
336
0
} /* end H5VLget_connector_id_by_value() */
337
338
/*-------------------------------------------------------------------------
339
 * Function:    H5VLpeek_connector_id_by_name
340
 *
341
 * Purpose:     Retrieves the ID for a registered VOL connector.
342
 *
343
 * Return:      A valid VOL connector ID if a connector by that name has
344
 *              been registered. This ID is *not* owned by the caller and
345
 *              H5VLclose() should not be called.  Intended for use by VOL
346
 *              connectors to find their own ID.
347
 *
348
 *              H5I_INVALID_HID on error or if a VOL connector of that
349
 *              name has not been registered.
350
 *
351
 *-------------------------------------------------------------------------
352
 */
353
hid_t
354
H5VLpeek_connector_id_by_name(const char *name)
355
0
{
356
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
357
358
0
    FUNC_ENTER_API(H5I_INVALID_HID)
359
0
    H5TRACE1("i", "*s", name);
360
361
    /* Get connector ID with this name */
362
0
    if ((ret_value = H5VL__peek_connector_id_by_name(name)) < 0)
363
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id");
364
365
0
done:
366
0
    FUNC_LEAVE_API(ret_value)
367
0
} /* end H5VLpeek_connector_id_by_name() */
368
369
/*-------------------------------------------------------------------------
370
 * Function:    H5VLpeek_connector_id_by_value
371
 *
372
 * Purpose:     Retrieves the ID for a registered VOL connector.
373
 *
374
 * Return:      A valid VOL connector ID if a connector with that value
375
 *              has been registered. This ID is *not* owned by the caller
376
 *              and H5VLclose() should not be called.  Intended for use by
377
 *              VOL connectors to find their own ID.
378
 *
379
 *              H5I_INVALID_HID on error or if a VOL connector with that
380
 *              value has not been registered.
381
 *
382
 *-------------------------------------------------------------------------
383
 */
384
hid_t
385
H5VLpeek_connector_id_by_value(H5VL_class_value_t value)
386
0
{
387
0
    hid_t ret_value = H5I_INVALID_HID; /* Return value */
388
389
0
    FUNC_ENTER_API(H5I_INVALID_HID)
390
0
    H5TRACE1("i", "VC", value);
391
392
    /* Get connector ID with this value */
393
0
    if ((ret_value = H5VL__peek_connector_id_by_value(value)) < 0)
394
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id");
395
396
0
done:
397
0
    FUNC_LEAVE_API(ret_value)
398
0
} /* end H5VLpeek_connector_id_by_value() */
399
400
/*-------------------------------------------------------------------------
401
 * Function:    H5VLget_connector_name
402
 *
403
 * Purpose:     Returns the connector name for the VOL associated with the
404
 *              object or file ID.
405
 *
406
 *              This works like other calls where the caller must provide a
407
 *              buffer of the appropriate size for the library to fill in.
408
 *              i.e., passing in a NULL pointer for NAME will return the
409
 *              required size of the buffer.
410
 *
411
 * Return:      Success:        The length of the connector name
412
 *
413
 *              Failure:        Negative
414
 *
415
 *-------------------------------------------------------------------------
416
 */
417
ssize_t
418
H5VLget_connector_name(hid_t obj_id, char *name /*out*/, size_t size)
419
0
{
420
0
    ssize_t ret_value = -1;
421
422
0
    FUNC_ENTER_API(FAIL)
423
0
    H5TRACE3("Zs", "ixz", obj_id, name, size);
424
425
    /* Call internal routine */
426
0
    if ((ret_value = H5VL__get_connector_name(obj_id, name, size)) < 0)
427
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "Can't get connector name");
428
429
0
done:
430
0
    FUNC_LEAVE_API(ret_value)
431
0
} /* end H5VLget_connector_name() */
432
433
/*-------------------------------------------------------------------------
434
 * Function:    H5VLclose
435
 *
436
 * Purpose:     Closes a VOL connector ID.  This in no way affects
437
 *              file access property lists which have been defined to use
438
 *              this VOL connector or files which are already opened under with
439
 *              this connector.
440
 *
441
 * Return:      Success:    Non-negative
442
 *              Failure:    Negative
443
 *
444
 *-------------------------------------------------------------------------
445
 */
446
herr_t
447
H5VLclose(hid_t vol_id)
448
0
{
449
0
    herr_t ret_value = SUCCEED; /* Return value */
450
451
0
    FUNC_ENTER_API(FAIL)
452
0
    H5TRACE1("e", "i", vol_id);
453
454
    /* Check args */
455
0
    if (NULL == H5I_object_verify(vol_id, H5I_VOL))
456
0
        HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector");
457
458
    /* Decrement the ref count on the ID, possibly releasing the VOL connector */
459
0
    if (H5I_dec_app_ref(vol_id) < 0)
460
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to close VOL connector ID");
461
462
0
done:
463
0
    FUNC_LEAVE_API(ret_value)
464
0
} /* end H5VLclose() */
465
466
/*-------------------------------------------------------------------------
467
 * Function:    H5VLunregister_connector
468
 *
469
 * Purpose:     Removes a VOL connector ID from the library. This in no way affects
470
 *              file access property lists which have been defined to use
471
 *              this VOL connector or files which are already opened under with
472
 *              this connector.
473
 *
474
 *              The native VOL connector cannot be unregistered and attempts
475
 *              to do so are considered an error.
476
 *
477
 * Return:      Success:    Non-negative
478
 *
479
 *              Failure:    Negative
480
 *
481
 *-------------------------------------------------------------------------
482
 */
483
herr_t
484
H5VLunregister_connector(hid_t vol_id)
485
0
{
486
0
    hid_t  native_id = H5I_INVALID_HID;
487
0
    herr_t ret_value = SUCCEED; /* Return value */
488
489
0
    FUNC_ENTER_API(FAIL)
490
0
    H5TRACE1("e", "i", vol_id);
491
492
    /* Check arguments */
493
0
    if (NULL == H5I_object_verify(vol_id, H5I_VOL))
494
0
        HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID");
495
496
    /* For the time being, we disallow unregistering the native VOL connector */
497
0
    if (H5I_INVALID_HID == (native_id = H5VL__get_connector_id_by_name(H5VL_NATIVE_NAME, false)))
498
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to find the native VOL connector ID");
499
0
    if (vol_id == native_id)
500
0
        HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "unregistering the native VOL connector is not allowed");
501
502
    /* The H5VL_class_t struct will be freed by this function */
503
0
    if (H5I_dec_app_ref(vol_id) < 0)
504
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to unregister VOL connector");
505
506
0
done:
507
0
    if (native_id != H5I_INVALID_HID)
508
0
        if (H5I_dec_ref(native_id) < 0)
509
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement count on native_id");
510
511
0
    FUNC_LEAVE_API(ret_value)
512
0
} /* end H5VLunregister_connector() */
513
514
/*---------------------------------------------------------------------------
515
 * Function:    H5VLcmp_connector_cls
516
 *
517
 * Purpose:     Compares two connector classes (based on their value field)
518
 *
519
 * Note:        This routine is _only_ for HDF5 VOL connector authors!  It is
520
 *              _not_ part of the public API for HDF5 application developers.
521
 *
522
 * Return:      Success:    Non-negative, *cmp set to a value like strcmp
523
 *
524
 *              Failure:    Negative, *cmp unset
525
 *
526
 *---------------------------------------------------------------------------
527
 */
528
herr_t
529
H5VLcmp_connector_cls(int *cmp, hid_t connector_id1, hid_t connector_id2)
530
0
{
531
0
    H5VL_class_t *cls1, *cls2;         /* connectors for IDs */
532
0
    herr_t        ret_value = SUCCEED; /* Return value */
533
534
0
    FUNC_ENTER_API(FAIL)
535
0
    H5TRACE3("e", "*Isii", cmp, connector_id1, connector_id2);
536
537
    /* Check args and get class pointers */
538
0
    if (NULL == (cls1 = (H5VL_class_t *)H5I_object_verify(connector_id1, H5I_VOL)))
539
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
540
0
    if (NULL == (cls2 = (H5VL_class_t *)H5I_object_verify(connector_id2, H5I_VOL)))
541
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID");
542
543
    /* Compare the two VOL connector classes */
544
0
    if (H5VL_cmp_connector_cls(cmp, cls1, cls2) < 0)
545
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare connector classes");
546
547
0
done:
548
0
    FUNC_LEAVE_API(ret_value)
549
0
} /* H5VLcmp_connector_cls() */
550
551
/*---------------------------------------------------------------------------
552
 * Function:    H5VLwrap_register
553
 *
554
 * Purpose:     Wrap an internal object with a "wrap context" and register an
555
 *              hid_t for the resulting object.
556
 *
557
 * Note:        This routine is mainly targeted toward wrapping objects for
558
 *              iteration routine callbacks (i.e. the callbacks from H5Aiterate*,
559
 *              H5Literate* / H5Lvisit*, and H5Ovisit* ).
560
 *
561
 *              type must be a VOL-managed object class (H5I_FILE,
562
 *              H5I_GROUP, H5I_DATATYPE, H5I_DATASET, H5I_MAP, or H5I_ATTR).
563
 *
564
 * Return:      Success:    Non-negative hid_t for the object.
565
 *              Failure:    Negative (H5I_INVALID_HID)
566
 *
567
 *---------------------------------------------------------------------------
568
 */
569
hid_t
570
H5VLwrap_register(void *obj, H5I_type_t type)
571
0
{
572
0
    hid_t ret_value; /* Return value */
573
574
    /* Use FUNC_ENTER_API_NOINIT here, so the API context doesn't get reset */
575
0
    FUNC_ENTER_API_NOINIT
576
0
    H5TRACE2("i", "*xIt", obj, type);
577
578
    /* Check args */
579
    /* Use a switch here for (hopefully) better performance than a series of
580
     * equality checks.  We could also group these types together in H5I_type_t,
581
     * make some assertions here to guarantee that, then just check the range.
582
     */
583
0
    switch (type) {
584
0
        case H5I_FILE:
585
0
        case H5I_GROUP:
586
0
        case H5I_DATATYPE:
587
0
        case H5I_DATASET:
588
0
        case H5I_MAP:
589
0
        case H5I_ATTR:
590
            /* VOL-managed objects, call is valid */
591
0
            break;
592
0
        case H5I_UNINIT:
593
0
        case H5I_BADID:
594
0
        case H5I_DATASPACE:
595
0
        case H5I_VFL:
596
0
        case H5I_VOL:
597
0
        case H5I_GENPROP_CLS:
598
0
        case H5I_GENPROP_LST:
599
0
        case H5I_ERROR_CLASS:
600
0
        case H5I_ERROR_MSG:
601
0
        case H5I_ERROR_STACK:
602
0
        case H5I_SPACE_SEL_ITER:
603
0
        case H5I_EVENTSET:
604
0
        case H5I_NTYPES:
605
0
        default:
606
0
            HGOTO_ERROR(H5E_VOL, H5E_BADRANGE, H5I_INVALID_HID, "invalid type number");
607
0
    } /* end switch */
608
0
    if (NULL == obj)
609
0
        HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, H5I_INVALID_HID, "obj is NULL");
610
611
    /* Wrap the object and register an ID for it */
612
0
    if ((ret_value = H5VL_wrap_register(type, obj, true)) < 0)
613
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to wrap object");
614
615
0
done:
616
0
    FUNC_LEAVE_API_NOINIT(ret_value)
617
0
} /* H5VLwrap_register() */
618
619
/*---------------------------------------------------------------------------
620
 * Function:    H5VLobject
621
 *
622
 * Purpose:     Retrieve the object pointer associated with an hid_t for a
623
 *              VOL object.
624
 *
625
 * Note:        This routine is mainly targeted toward unwrapping objects for
626
 *              testing.
627
 *
628
 * Return:      Success:    Object pointer
629
 *              Failure:    NULL
630
 *
631
 *---------------------------------------------------------------------------
632
 */
633
void *
634
H5VLobject(hid_t id)
635
0
{
636
0
    void *ret_value; /* Return value */
637
638
0
    FUNC_ENTER_API(NULL)
639
0
    H5TRACE1("*x", "i", id);
640
641
    /* Retrieve the object pointer for the ID */
642
0
    if (NULL == (ret_value = H5VL_object(id)))
643
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to retrieve object");
644
645
0
done:
646
0
    FUNC_LEAVE_API(ret_value)
647
0
} /* H5VLobject() */
648
649
/*---------------------------------------------------------------------------
650
 * Function:    H5VLobject_is_native
651
 *
652
 * Purpose:     Determines whether an object ID represents a native VOL
653
 *              connector object.
654
 *
655
 * Return:      Non-negative on success/Negative on failure
656
 *
657
 *---------------------------------------------------------------------------
658
 */
659
herr_t
660
H5VLobject_is_native(hid_t obj_id, hbool_t *is_native)
661
0
{
662
0
    H5VL_object_t *vol_obj   = NULL;
663
0
    herr_t         ret_value = SUCCEED;
664
665
0
    FUNC_ENTER_API(FAIL)
666
0
    H5TRACE2("e", "i*b", obj_id, is_native);
667
668
0
    if (!is_native)
669
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "`is_native` argument is NULL");
670
671
    /* Get the location object for the ID */
672
0
    if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
673
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
674
675
0
    if (H5VL_object_is_native(vol_obj, is_native) < 0)
676
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if object is a native connector object");
677
678
0
done:
679
0
    FUNC_LEAVE_API(ret_value)
680
0
} /* H5VLobject_is_native() */
681
682
/*-------------------------------------------------------------------------
683
 * Function:    H5VLget_file_type
684
 *
685
 * Purpose:     Returns a copy of dtype_id with its location set to be in
686
 *              the file, with updated size, etc.
687
 *
688
 * Return:      Non-negative on success/Negative on failure
689
 *
690
 *-------------------------------------------------------------------------
691
 */
692
hid_t
693
H5VLget_file_type(void *file_obj, hid_t connector_id, hid_t dtype_id)
694
0
{
695
0
    H5T_t         *dtype;               /* unregistered type       */
696
0
    H5T_t         *file_type    = NULL; /* copied file type        */
697
0
    hid_t          file_type_id = -1;   /* copied file type id     */
698
0
    H5VL_object_t *file_vol_obj = NULL; /* VOL object for file     */
699
0
    hid_t          ret_value    = -1;   /* Return value            */
700
701
0
    FUNC_ENTER_API(FAIL)
702
0
    H5TRACE3("i", "*xii", file_obj, connector_id, dtype_id);
703
704
    /* Check args */
705
0
    if (!file_obj)
706
0
        HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "no file object supplied");
707
0
    if (NULL == (dtype = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE)))
708
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
709
710
    /* Create VOL object for file if necessary (force_conv will be true if and
711
     * only if file needs to be passed to H5T_set_loc) */
712
0
    if (H5T_GET_FORCE_CONV(dtype) &&
713
0
        (NULL == (file_vol_obj = H5VL_create_object_using_vol_id(H5I_FILE, file_obj, connector_id))))
714
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create VOL object");
715
716
    /* Copy the datatype */
717
0
    if (NULL == (file_type = H5T_copy(dtype, H5T_COPY_TRANSIENT)))
718
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "unable to copy datatype");
719
720
    /* Register file type id */
721
0
    if ((file_type_id = H5I_register(H5I_DATATYPE, file_type, false)) < 0) {
722
0
        (void)H5T_close_real(file_type);
723
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "unable to register file datatype");
724
0
    } /* end if */
725
726
    /* Set the location of the datatype to be in the file */
727
0
    if (H5T_set_loc(file_type, file_vol_obj, H5T_LOC_DISK) < 0)
728
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't set datatype location");
729
730
    /* Release our reference to file_type */
731
0
    if (file_vol_obj) {
732
0
        if (H5VL_free_object(file_vol_obj) < 0)
733
0
            HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to free VOL object");
734
0
        file_vol_obj = NULL;
735
0
    } /* end if */
736
737
    /* Set return value */
738
0
    ret_value = file_type_id;
739
740
0
done:
741
    /* Cleanup on error */
742
0
    if (ret_value < 0) {
743
0
        if (file_vol_obj && H5VL_free_object(file_vol_obj) < 0)
744
0
            HDONE_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to free VOL object");
745
0
        if (file_type_id >= 0 && H5I_dec_ref(file_type_id) < 0)
746
0
            HDONE_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to close file datatype");
747
0
    } /* end if */
748
749
0
    FUNC_LEAVE_API(ret_value)
750
0
} /* end H5VLget_file_type() */
751
752
/*---------------------------------------------------------------------------
753
 * Function:    H5VLretrieve_lib_state
754
 *
755
 * Purpose:     Retrieves a copy of the internal state of the HDF5 library,
756
 *              so that it can be restored later.
757
 *
758
 * Note:        This routine is _only_ for HDF5 VOL connector authors!  It is
759
 *              _not_ part of the public API for HDF5 application developers.
760
 *
761
 * Return:      Success:    Non-negative, *state set
762
 *              Failure:    Negative, *state unset
763
 *
764
 *---------------------------------------------------------------------------
765
 */
766
herr_t
767
H5VLretrieve_lib_state(void **state /*out*/)
768
0
{
769
0
    herr_t ret_value = SUCCEED; /* Return value */
770
771
    /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */
772
0
    FUNC_ENTER_API_NOINIT
773
0
    H5TRACE1("e", "x", state);
774
775
    /* Check args */
776
0
    if (NULL == state)
777
0
        HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer");
778
779
    /* Retrieve the library state */
780
0
    if (H5VL_retrieve_lib_state(state) < 0)
781
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve library state");
782
783
0
done:
784
0
    FUNC_LEAVE_API_NOINIT(ret_value)
785
0
} /* H5VLretrieve_lib_state() */
786
787
/*---------------------------------------------------------------------------
788
 * Function:    H5VLstart_lib_state
789
 *
790
 * Purpose:     Opens a new internal state for the HDF5 library.
791
 *
792
 * Note:        This routine is _only_ for HDF5 VOL connector authors!  It is
793
 *              _not_ part of the public API for HDF5 application developers.
794
 *
795
 * Return:      Success:    Non-negative
796
 *              Failure:    Negative
797
 *
798
 *---------------------------------------------------------------------------
799
 */
800
herr_t
801
H5VLstart_lib_state(void)
802
0
{
803
0
    herr_t ret_value = SUCCEED; /* Return value */
804
805
    /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */
806
0
    FUNC_ENTER_API_NOINIT
807
0
    H5TRACE0("e", "");
808
809
    /* Start a new library state */
810
0
    if (H5VL_start_lib_state() < 0)
811
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't start new library state");
812
813
0
done:
814
0
    FUNC_LEAVE_API_NOINIT(ret_value)
815
0
} /* H5VLstart_lib_state() */
816
817
/*---------------------------------------------------------------------------
818
 * Function:    H5VLrestore_lib_state
819
 *
820
 * Purpose:     Restores the internal state of the HDF5 library.
821
 *
822
 * Note:        This routine is _only_ for HDF5 VOL connector authors!  It is
823
 *              _not_ part of the public API for HDF5 application developers.
824
 *
825
 * Return:      Success:    Non-negative
826
 *              Failure:    Negative
827
 *
828
 *---------------------------------------------------------------------------
829
 */
830
herr_t
831
H5VLrestore_lib_state(const void *state)
832
0
{
833
0
    herr_t ret_value = SUCCEED; /* Return value */
834
835
    /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */
836
0
    FUNC_ENTER_API_NOINIT
837
0
    H5TRACE1("e", "*x", state);
838
839
    /* Check args */
840
0
    if (NULL == state)
841
0
        HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer");
842
843
    /* Restore the library state */
844
0
    if (H5VL_restore_lib_state(state) < 0)
845
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't restore library state");
846
847
0
done:
848
0
    FUNC_LEAVE_API_NOINIT(ret_value)
849
0
} /* H5VLrestore_lib_state() */
850
851
/*---------------------------------------------------------------------------
852
 * Function:    H5VLfinish_lib_state
853
 *
854
 * Purpose:     Closes the internal state of the HDF5 library, undoing the
855
 *              affects of H5VLstart_lib_state.
856
 *
857
 * Note:        This routine is _only_ for HDF5 VOL connector authors!  It is
858
 *              _not_ part of the public API for HDF5 application developers.
859
 *
860
 * Note:        This routine must be called as a "pair" with
861
 *              H5VLstart_lib_state.  It can be called before / after /
862
 *              independently of H5VLfree_lib_state.
863
 *
864
 * Return:      Success:    Non-negative
865
 *              Failure:    Negative
866
 *
867
 *---------------------------------------------------------------------------
868
 */
869
herr_t
870
H5VLfinish_lib_state(void)
871
0
{
872
0
    herr_t ret_value = SUCCEED; /* Return value */
873
874
    /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */
875
0
    FUNC_ENTER_API_NOINIT
876
0
    H5TRACE0("e", "");
877
878
    /* Reset the library state */
879
0
    if (H5VL_finish_lib_state() < 0)
880
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset library state");
881
882
0
done:
883
0
    FUNC_LEAVE_API_NOINIT(ret_value)
884
0
} /* H5VLfinish_lib_state() */
885
886
/*---------------------------------------------------------------------------
887
 * Function:    H5VLfree_lib_state
888
 *
889
 * Purpose:     Free a retrieved library state.
890
 *
891
 * Note:        This routine is _only_ for HDF5 VOL connector authors!  It is
892
 *              _not_ part of the public API for HDF5 application developers.
893
 *
894
 * Note:        This routine must be called as a "pair" with
895
 *              H5VLretrieve_lib_state.
896
 *
897
 * Return:      Success:    Non-negative
898
 *              Failure:    Negative
899
 *
900
 *---------------------------------------------------------------------------
901
 */
902
herr_t
903
H5VLfree_lib_state(void *state)
904
0
{
905
0
    herr_t ret_value = SUCCEED; /* Return value */
906
907
0
    FUNC_ENTER_API(FAIL)
908
0
    H5TRACE1("e", "*x", state);
909
910
    /* Check args */
911
0
    if (NULL == state)
912
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid state pointer");
913
914
    /* Free the library state */
915
0
    if (H5VL_free_lib_state(state) < 0)
916
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "can't free library state");
917
918
0
done:
919
0
    FUNC_LEAVE_API(ret_value)
920
0
} /* H5VLfree_lib_state() */
921
922
/*---------------------------------------------------------------------------
923
 * Function:    H5VLquery_optional
924
 *
925
 * Purpose:     Determine if a VOL connector supports a particular optional
926
 *              callback operation, and a general sense of the operation's
927
 *              behavior.
928
 *
929
 * Return:      Success:    Non-negative
930
 *              Failure:    Negative
931
 *
932
 *---------------------------------------------------------------------------
933
 */
934
herr_t
935
H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags /*out*/)
936
0
{
937
0
    H5VL_object_t *vol_obj   = NULL;
938
0
    herr_t         ret_value = SUCCEED; /* Return value */
939
940
0
    FUNC_ENTER_API(FAIL)
941
0
    H5TRACE4("e", "iVSIsx", obj_id, subcls, opt_type, flags);
942
943
    /* Check args */
944
0
    if (NULL == flags)
945
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid 'flags' pointer");
946
0
    if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
947
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
948
949
    /* Query the connector */
950
0
    if (H5VL_introspect_opt_query(vol_obj, subcls, opt_type, flags) < 0)
951
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to query VOL connector operation");
952
953
0
done:
954
0
    FUNC_LEAVE_API(ret_value)
955
0
} /* H5VLquery_optional() */
956
957
/*---------------------------------------------------------------------------
958
 * Function:    H5VLregister_opt_operation
959
 *
960
 * Purpose:     Allow a VOL connector to register a new optional operation
961
 *              for a VOL object subclass.   The operation name must be runtime
962
 *              unique for each operation, preferably avoiding naming clashes
963
 *              by using a Uniform Type Identifier (UTI,
964
 *https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html)
965
 *              for each operation name.  The value returned in the 'op_val'
966
 *              pointer will be unique for that VOL connector to use for its
967
 *              operation on that subclass.
968
 *
969
 *              For example, registering a 'prefetch' operation for the
970
 *              caching VOL connector written at the ALCF at Argonne National
971
 *              Laboratory could have a UTI of: "gov.anl.alcf.cache.prefetch",
972
 *              and the "evict" operation for the same connector could have a
973
 *              UTI of: "gov.anl.alcf.cache.evict".   Registering a "suspend
974
 *              background threads" operation for the asynchronous VOL connector
975
 *              written at NERSC at Lawrence Berkeley National Laboratory could
976
 *              have a UTI of: "gov.lbnl.nersc.async.suspend_bkg_threads".
977
 *
978
 * Note:        The first 1024 values of each subclass's optional operations
979
 *              are reserved for the native VOL connector's use.
980
 *
981
 * Return:      Success:    Non-negative
982
 *              Failure:    Negative
983
 *
984
 *---------------------------------------------------------------------------
985
 */
986
herr_t
987
H5VLregister_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/)
988
0
{
989
0
    herr_t ret_value = SUCCEED; /* Return value */
990
991
0
    FUNC_ENTER_API(FAIL)
992
0
    H5TRACE3("e", "VS*sx", subcls, op_name, op_val);
993
994
    /* Check args */
995
0
    if (NULL == op_val)
996
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer");
997
0
    if (NULL == op_name)
998
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer");
999
0
    if ('\0' == *op_name)
1000
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string");
1001
0
    if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) ||
1002
0
          (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) ||
1003
0
          (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls)))
1004
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type");
1005
1006
    /* Register the operation */
1007
0
    if (H5VL__register_opt_operation(subcls, op_name, op_val) < 0)
1008
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't register dynamic optional operation: '%s'",
1009
0
                    op_name);
1010
1011
0
done:
1012
0
    FUNC_LEAVE_API(ret_value)
1013
0
} /* H5VLregister_opt_operation() */
1014
1015
/*---------------------------------------------------------------------------
1016
 * Function:    H5VLfind_opt_operation
1017
 *
1018
 * Purpose:     Look up a optional operation for a VOL object subclass, by name.
1019
 *
1020
 * Return:      Success:    Non-negative
1021
 *              Failure:    Negative
1022
 *
1023
 *---------------------------------------------------------------------------
1024
 */
1025
herr_t
1026
H5VLfind_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/)
1027
0
{
1028
0
    herr_t ret_value = SUCCEED; /* Return value */
1029
1030
0
    FUNC_ENTER_API(FAIL)
1031
0
    H5TRACE3("e", "VS*sx", subcls, op_name, op_val);
1032
1033
    /* Check args */
1034
0
    if (NULL == op_val)
1035
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer");
1036
0
    if (NULL == op_name)
1037
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer");
1038
0
    if ('\0' == *op_name)
1039
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string");
1040
0
    if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) ||
1041
0
          (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) ||
1042
0
          (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls)))
1043
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type");
1044
1045
    /* Find the operation */
1046
0
    if (H5VL__find_opt_operation(subcls, op_name, op_val) < 0)
1047
0
        HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "can't find dynamic optional operation: '%s'", op_name);
1048
1049
0
done:
1050
0
    FUNC_LEAVE_API(ret_value)
1051
0
} /* H5VLfind_opt_operation() */
1052
1053
/*---------------------------------------------------------------------------
1054
 * Function:    H5VLunregister_opt_operation
1055
 *
1056
 * Purpose:     Unregister a optional operation for a VOL object subclass, by name.
1057
 *
1058
 * Return:      Success:    Non-negative
1059
 *              Failure:    Negative
1060
 *
1061
 *---------------------------------------------------------------------------
1062
 */
1063
herr_t
1064
H5VLunregister_opt_operation(H5VL_subclass_t subcls, const char *op_name)
1065
0
{
1066
0
    herr_t ret_value = SUCCEED; /* Return value */
1067
1068
0
    FUNC_ENTER_API(FAIL)
1069
0
    H5TRACE2("e", "VS*s", subcls, op_name);
1070
1071
    /* Check args */
1072
0
    if (NULL == op_name)
1073
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer");
1074
0
    if ('\0' == *op_name)
1075
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string");
1076
0
    if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) ||
1077
0
          (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) ||
1078
0
          (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls)))
1079
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type");
1080
1081
    /* Unregister the operation */
1082
0
    if (H5VL__unregister_opt_operation(subcls, op_name) < 0)
1083
0
        HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "can't unregister dynamic optional operation: '%s'",
1084
0
                    op_name);
1085
1086
0
done:
1087
0
    FUNC_LEAVE_API(ret_value)
1088
0
} /* H5VLunregister_opt_operation() */