Coverage Report

Created: 2026-05-30 06:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5F.c
Line
Count
Source
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 LICENSE 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
/* Module Setup */
15
/****************/
16
17
#include "H5Fmodule.h" /* This source code file is part of the H5F module */
18
19
/***********/
20
/* Headers */
21
/***********/
22
#include "H5private.h"   /* Generic Functions                        */
23
#include "H5ACprivate.h" /* Metadata cache                           */
24
#include "H5CXprivate.h" /* API Contexts                             */
25
#include "H5Eprivate.h"  /* Error handling                           */
26
#include "H5ESprivate.h" /* Event Sets                               */
27
#include "H5Fpkg.h"      /* File access                              */
28
#include "H5FLprivate.h" /* Free lists                               */
29
#include "H5Iprivate.h"  /* IDs                                      */
30
#include "H5Pprivate.h"  /* Property lists                           */
31
#include "H5VLprivate.h" /* Virtual Object Layer                     */
32
33
#include "H5VLnative_private.h" /* Native VOL connector                     */
34
35
/****************/
36
/* Local Macros */
37
/****************/
38
39
/******************/
40
/* Local Typedefs */
41
/******************/
42
43
/* User data for traversal routine to get ID counts */
44
typedef struct {
45
    size_t   obj_count; /* Number of objects counted so far */
46
    unsigned types;     /* Types of objects to be counted */
47
} H5F_trav_obj_cnt_t;
48
49
/* User data for traversal routine to get ID lists */
50
typedef struct {
51
    size_t max_objs;  /* Maximum # of IDs to record */
52
    hid_t *oid_list;  /* Array of recorded IDs*/
53
    size_t obj_count; /* Number of objects counted so far */
54
} H5F_trav_obj_ids_t;
55
56
/********************/
57
/* Package Typedefs */
58
/********************/
59
60
/********************/
61
/* Local Prototypes */
62
/********************/
63
64
/* Callback for getting object counts in a file */
65
static int H5F__get_all_count_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t H5_ATTR_UNUSED obj_id, void *key);
66
67
/* Callback for getting IDs for open objects in a file */
68
static int H5F__get_all_ids_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t obj_id, void *key);
69
70
/* Helper routines for sync/async API calls */
71
static herr_t H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr);
72
static hid_t  H5F__create_api_common(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
73
                                     void **token_ptr);
74
static hid_t  H5F__open_api_common(const char *filename, unsigned flags, hid_t fapl_id, void **token_ptr);
75
static hid_t  H5F__reopen_api_common(hid_t file_id, void **token_ptr);
76
static herr_t H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr,
77
                                    H5VL_object_t **_vol_obj_ptr);
78
79
/*********************/
80
/* Package Variables */
81
/*********************/
82
83
/*****************************/
84
/* Library Private Variables */
85
/*****************************/
86
87
/*******************/
88
/* Local Variables */
89
/*******************/
90
91
/*-------------------------------------------------------------------------
92
 * Function:    H5Fget_create_plist
93
 *
94
 * Purpose:     Get an ID for a copy of the file-creation property list for
95
 *              this file. This function returns an ID with a copy of the
96
 *              properties used to create a file.
97
 *
98
 * Return:      Success:    Object ID for a copy of the file creation
99
 *                          property list.
100
 *
101
 *              Failure:    H5I_INVALID_HID
102
 *
103
 *-------------------------------------------------------------------------
104
 */
105
hid_t
106
H5Fget_create_plist(hid_t file_id)
107
0
{
108
0
    H5VL_object_t       *vol_obj;                     /* File for file_id */
109
0
    H5VL_file_get_args_t vol_cb_args;                 /* Arguments to VOL callback */
110
0
    hid_t                ret_value = H5I_INVALID_HID; /* Return value */
111
112
0
    FUNC_ENTER_API(H5I_INVALID_HID)
113
114
    /* check args */
115
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
116
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier");
117
118
    /* Set up VOL callback arguments */
119
0
    vol_cb_args.op_type               = H5VL_FILE_GET_FCPL;
120
0
    vol_cb_args.args.get_fcpl.fcpl_id = H5I_INVALID_HID;
121
122
    /* Retrieve the file creation property list */
123
0
    if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
124
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, H5I_INVALID_HID, "unable to retrieve file creation properties");
125
126
    /* Set return value */
127
0
    ret_value = vol_cb_args.args.get_fcpl.fcpl_id;
128
129
0
done:
130
0
    FUNC_LEAVE_API(ret_value)
131
0
} /* end H5Fget_create_plist() */
132
133
/*-------------------------------------------------------------------------
134
 * Function:    H5Fget_access_plist
135
 *
136
 * Purpose:     Returns a copy of the file access property list of the
137
 *              specified file.
138
 *
139
 *              NOTE: Make sure that, if you are going to overwrite
140
 *              information in the copied property list that was
141
 *              previously opened and assigned to the property list, then
142
 *              you must close it before overwriting the values.
143
 *
144
 * Return:      Success:    Object ID for a copy of the file access
145
 *                          property list.
146
 *
147
 *              Failure:    H5I_INVALID_HID
148
 *
149
 *-------------------------------------------------------------------------
150
 */
151
hid_t
152
H5Fget_access_plist(hid_t file_id)
153
0
{
154
0
    H5VL_object_t       *vol_obj;                     /* File for file_id */
155
0
    H5VL_file_get_args_t vol_cb_args;                 /* Arguments to VOL callback */
156
0
    hid_t                ret_value = H5I_INVALID_HID; /* Return value */
157
158
0
    FUNC_ENTER_API(H5I_INVALID_HID)
159
160
    /* Check args */
161
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
162
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier");
163
164
    /* Set up VOL callback arguments */
165
0
    vol_cb_args.op_type               = H5VL_FILE_GET_FAPL;
166
0
    vol_cb_args.args.get_fapl.fapl_id = H5I_INVALID_HID;
167
168
    /* Retrieve the file's access property list */
169
0
    if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
170
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get file access property list");
171
172
    /* Set return value */
173
0
    ret_value = vol_cb_args.args.get_fapl.fapl_id;
174
175
0
done:
176
0
    FUNC_LEAVE_API(ret_value)
177
0
} /* end H5Fget_access_plist() */
178
179
/*-------------------------------------------------------------------------
180
 * Function:    H5F__get_all_count_cb
181
 *
182
 * Purpose:     Get counter of all object types currently open.
183
 *
184
 * Return:      Success:    H5_ITER_CONT or H5_ITER_STOP
185
 *
186
 *              Failure:    H5_ITER_ERROR
187
 *
188
 *-------------------------------------------------------------------------
189
 */
190
static int
191
H5F__get_all_count_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t H5_ATTR_UNUSED obj_id, void *key)
192
0
{
193
0
    H5F_trav_obj_cnt_t *udata     = (H5F_trav_obj_cnt_t *)key;
194
0
    int                 ret_value = H5_ITER_CONT; /* Return value */
195
196
0
    FUNC_ENTER_PACKAGE_NOERR
197
198
0
    udata->obj_count++;
199
200
0
    FUNC_LEAVE_NOAPI(ret_value)
201
0
} /* H5F_get_all_count_cb */
202
203
/*-------------------------------------------------------------------------
204
 * Function:    H5Fget_obj_count
205
 *
206
 * Purpose:     Public function returning the number of opened object IDs
207
 *              (files, datasets, groups and datatypes) in the same file.
208
 *
209
 * Return:      Success:    The number of opened object IDs
210
 *
211
 *              Failure:    -1
212
 *
213
 *-------------------------------------------------------------------------
214
 */
215
ssize_t
216
H5Fget_obj_count(hid_t file_id, unsigned types)
217
0
{
218
0
    ssize_t ret_value = 0; /* Return value */
219
220
0
    FUNC_ENTER_API((-1))
221
222
    /* Check arguments */
223
0
    if (0 == (types & H5F_OBJ_ALL))
224
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "not an object type");
225
226
    /* Perform the query */
227
    /* If the 'special' ID wasn't passed in, just make a normal call to
228
     * count the IDs in the file.
229
     */
230
0
    if (file_id != (hid_t)H5F_OBJ_ALL) {
231
0
        H5VL_object_t       *vol_obj;     /* File for file_id */
232
0
        size_t               count = 0;   /* Object count */
233
0
        H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */
234
235
        /* Get the file object */
236
0
        if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
237
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a file id");
238
239
        /* Set up VOL callback arguments */
240
0
        vol_cb_args.op_type                  = H5VL_FILE_GET_OBJ_COUNT;
241
0
        vol_cb_args.args.get_obj_count.types = types;
242
0
        vol_cb_args.args.get_obj_count.count = &count;
243
244
        /* Get the count */
245
0
        if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
246
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get object count in file(s)");
247
248
        /* Set return value */
249
0
        ret_value = (ssize_t)count;
250
0
    }
251
    /* If we passed in the 'special' ID, get the count for everything open in the
252
     * library, iterating over all open files and getting the object count for each.
253
     */
254
0
    else {
255
0
        H5F_trav_obj_cnt_t udata;
256
257
        /* Set up callback context */
258
0
        udata.types     = types | H5F_OBJ_LOCAL;
259
0
        udata.obj_count = 0;
260
261
0
        if (types & H5F_OBJ_FILE)
262
0
            if (H5I_iterate(H5I_FILE, H5F__get_all_count_cb, &udata, true) < 0)
263
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over file IDs failed");
264
0
        if (types & H5F_OBJ_DATASET)
265
0
            if (H5I_iterate(H5I_DATASET, H5F__get_all_count_cb, &udata, true) < 0)
266
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over dataset IDs failed");
267
0
        if (types & H5F_OBJ_GROUP)
268
0
            if (H5I_iterate(H5I_GROUP, H5F__get_all_count_cb, &udata, true) < 0)
269
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over group IDs failed");
270
0
        if (types & H5F_OBJ_DATATYPE)
271
0
            if (H5I_iterate(H5I_DATATYPE, H5F__get_all_count_cb, &udata, true) < 0)
272
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over datatype IDs failed");
273
0
        if (types & H5F_OBJ_ATTR)
274
0
            if (H5I_iterate(H5I_ATTR, H5F__get_all_count_cb, &udata, true) < 0)
275
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over attribute IDs failed");
276
277
        /* Set return value */
278
0
        ret_value = (ssize_t)udata.obj_count;
279
0
    } /* end else */
280
281
0
done:
282
0
    FUNC_LEAVE_API(ret_value)
283
0
} /* end H5Fget_obj_count() */
284
285
/*-------------------------------------------------------------------------
286
 * Function:    H5F__get_all_ids_cb
287
 *
288
 * Purpose:     Get IDs of all currently open objects of a given type.
289
 *
290
 * Return:      Success:    H5_ITER_CONT or H5_ITER_STOP
291
 *
292
 *              Failure:    H5_ITER_ERROR
293
 *
294
 *-------------------------------------------------------------------------
295
 */
296
static int
297
H5F__get_all_ids_cb(void H5_ATTR_UNUSED *obj_ptr, hid_t obj_id, void *key)
298
0
{
299
0
    H5F_trav_obj_ids_t *udata     = (H5F_trav_obj_ids_t *)key;
300
0
    int                 ret_value = H5_ITER_CONT; /* Return value */
301
302
0
    FUNC_ENTER_PACKAGE_NOERR
303
304
0
    if (udata->obj_count >= udata->max_objs)
305
0
        HGOTO_DONE(H5_ITER_STOP);
306
307
    /* Add the ID to the array */
308
0
    udata->oid_list[udata->obj_count] = obj_id;
309
0
    udata->obj_count++;
310
311
0
done:
312
0
    FUNC_LEAVE_NOAPI(ret_value)
313
0
} /* H5F__get_all_ids_cb */
314
315
/*-------------------------------------------------------------------------
316
 * Function:    H5Fget_object_ids
317
 *
318
 * Purpose:     Public function to return a list of opened object IDs.
319
 *
320
 * NOTE:        Type mismatch - You can ask for more objects than can be
321
 *              returned.
322
 *
323
 * NOTE:        Currently, the IDs' ref counts are not incremented.  Is this
324
 *              intentional and documented?
325
 *
326
 * Return:      Success:    The number of IDs in oid_list
327
 *
328
 *              Failure:    -1
329
 *
330
 *-------------------------------------------------------------------------
331
 */
332
ssize_t
333
H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list /*out*/)
334
0
{
335
0
    ssize_t ret_value = 0; /* Return value */
336
337
0
    FUNC_ENTER_API((-1))
338
339
    /* Check arguments */
340
0
    if (0 == (types & H5F_OBJ_ALL))
341
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "not an object type");
342
0
    if (!oid_list)
343
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "object ID list cannot be NULL");
344
345
    /* Perform the query */
346
    /* If the 'special' ID wasn't passed in, just make a normal VOL call to
347
     * get the IDs from the file.
348
     */
349
0
    if (file_id != (hid_t)H5F_OBJ_ALL) {
350
0
        H5VL_object_t       *vol_obj;     /* File for file_id */
351
0
        size_t               count = 0;   /* Object count */
352
0
        H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */
353
354
        /* get the file object */
355
0
        if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
356
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier");
357
358
        /* Set up VOL callback arguments */
359
0
        vol_cb_args.op_type                   = H5VL_FILE_GET_OBJ_IDS;
360
0
        vol_cb_args.args.get_obj_ids.types    = types;
361
0
        vol_cb_args.args.get_obj_ids.max_objs = max_objs;
362
0
        vol_cb_args.args.get_obj_ids.oid_list = oid_list;
363
0
        vol_cb_args.args.get_obj_ids.count    = &count;
364
365
        /* Get the IDs */
366
0
        if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
367
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get object ids in file(s)");
368
369
        /* Set return value */
370
0
        ret_value = (ssize_t)count;
371
0
    } /* end if */
372
    /* If we passed in the 'special' ID, get the count for everything open in the
373
     * library, iterating over all open files and getting the object count for each.
374
     *
375
     * XXX: Note that the RM states that passing in a negative value for max_objs
376
     *      gets you all the objects. This technically works, but is clearly wrong
377
     *      behavior since max_objs is an unsigned type.
378
     */
379
0
    else {
380
0
        H5F_trav_obj_ids_t udata;
381
382
        /* Set up callback context */
383
0
        udata.max_objs  = max_objs;
384
0
        udata.oid_list  = oid_list;
385
0
        udata.obj_count = 0;
386
387
0
        if (types & H5F_OBJ_FILE)
388
0
            if (H5I_iterate(H5I_FILE, H5F__get_all_ids_cb, &udata, true) < 0)
389
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over file IDs failed");
390
0
        if (types & H5F_OBJ_DATASET)
391
0
            if (H5I_iterate(H5I_DATASET, H5F__get_all_ids_cb, &udata, true) < 0)
392
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over dataset IDs failed");
393
0
        if (types & H5F_OBJ_GROUP)
394
0
            if (H5I_iterate(H5I_GROUP, H5F__get_all_ids_cb, &udata, true) < 0)
395
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over group IDs failed");
396
0
        if (types & H5F_OBJ_DATATYPE)
397
0
            if (H5I_iterate(H5I_DATATYPE, H5F__get_all_ids_cb, &udata, true) < 0)
398
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over datatype IDs failed");
399
0
        if (types & H5F_OBJ_ATTR)
400
0
            if (H5I_iterate(H5I_ATTR, H5F__get_all_ids_cb, &udata, true) < 0)
401
0
                HGOTO_ERROR(H5E_FILE, H5E_BADITER, (-1), "iteration over attribute IDs failed");
402
403
        /* Set return value */
404
0
        ret_value = (ssize_t)udata.obj_count;
405
0
    } /* end else */
406
407
0
done:
408
0
    FUNC_LEAVE_API(ret_value)
409
0
} /* end H5Fget_obj_ids() */
410
411
/*-------------------------------------------------------------------------
412
 * Function:    H5Fget_vfd_handle
413
 *
414
 * Purpose:     Returns a pointer to the file handle of the low-level file
415
 *              driver.
416
 *
417
 * Return:      Success:    Non-negative
418
 *              Failure:    Negative
419
 *-------------------------------------------------------------------------
420
 */
421
herr_t
422
H5Fget_vfd_handle(hid_t file_id, hid_t fapl_id, void **file_handle /*out*/)
423
0
{
424
0
    H5VL_object_t                   *vol_obj;             /* File info */
425
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
426
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
427
0
    herr_t                           ret_value = SUCCEED; /* Return value */
428
429
0
    FUNC_ENTER_API(FAIL)
430
431
    /* Check args */
432
0
    if (!file_handle)
433
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file handle pointer");
434
435
    /* Get the file object */
436
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
437
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
438
439
    /* Set up VOL callback arguments */
440
0
    file_opt_args.get_vfd_handle.fapl_id     = fapl_id;
441
0
    file_opt_args.get_vfd_handle.file_handle = file_handle;
442
0
    vol_cb_args.op_type                      = H5VL_NATIVE_FILE_GET_VFD_HANDLE;
443
0
    vol_cb_args.args                         = &file_opt_args;
444
445
    /* Retrieve the VFD handle for the file */
446
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
447
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get VFD handle");
448
449
0
done:
450
0
    FUNC_LEAVE_API(ret_value)
451
0
} /* end H5Fget_vfd_handle() */
452
453
/*-------------------------------------------------------------------------
454
 * Function:    H5Fis_accessible
455
 *
456
 * Purpose:     Check if the file can be opened with the given fapl.
457
 *
458
 * Return:      Success:    true/false
459
 *              Failure:    -1 (includes file does not exist)
460
 *
461
 *-------------------------------------------------------------------------
462
 */
463
htri_t
464
H5Fis_accessible(const char *filename, hid_t fapl_id)
465
0
{
466
0
    H5VL_file_specific_args_t vol_cb_args;           /* Arguments to VOL callback */
467
0
    bool                      is_accessible = false; /* Whether file is accessible */
468
0
    htri_t                    ret_value;             /* Return value */
469
470
0
    FUNC_ENTER_API(FAIL)
471
472
    /* Check args */
473
0
    if (!filename || !*filename)
474
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified");
475
476
    /* Check the file access property list */
477
0
    if (H5P_DEFAULT == fapl_id)
478
0
        fapl_id = H5P_FILE_ACCESS_DEFAULT;
479
0
    else if (true != H5P_isa_class(fapl_id, H5P_FILE_ACCESS))
480
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list");
481
482
    /* Set up VOL callback arguments */
483
0
    vol_cb_args.op_type                       = H5VL_FILE_IS_ACCESSIBLE;
484
0
    vol_cb_args.args.is_accessible.filename   = filename;
485
0
    vol_cb_args.args.is_accessible.fapl_id    = fapl_id;
486
0
    vol_cb_args.args.is_accessible.accessible = &is_accessible;
487
488
    /* Check if file is accessible */
489
0
    if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
490
0
        HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to determine if file is accessible as HDF5");
491
492
    /* Set return value */
493
0
    ret_value = (htri_t)is_accessible;
494
495
0
done:
496
0
    FUNC_LEAVE_API(ret_value)
497
0
} /* end H5Fis_accessible() */
498
499
/*-------------------------------------------------------------------------
500
 * Function:    H5F__post_open_api_common
501
 *
502
 * Purpose:     This is the common function for 'post open' operations
503
 *
504
 * Return:      SUCCEED/FAIL
505
 *
506
 *-------------------------------------------------------------------------
507
 */
508
static herr_t
509
H5F__post_open_api_common(H5VL_object_t *vol_obj, void **token_ptr)
510
674
{
511
674
    uint64_t supported;           /* Whether 'post open' operation is supported by VOL connector */
512
674
    herr_t   ret_value = SUCCEED; /* Return value     */
513
514
674
    FUNC_ENTER_PACKAGE
515
516
    /* Check for 'post open' callback */
517
674
    supported = 0;
518
674
    if (H5VL_introspect_opt_query(vol_obj, H5VL_SUBCLS_FILE, H5VL_NATIVE_FILE_POST_OPEN, &supported) < 0)
519
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't check for 'post open' operation");
520
674
    if (supported & H5VL_OPT_QUERY_SUPPORTED) {
521
674
        H5VL_optional_args_t vol_cb_args; /* Arguments to VOL callback */
522
523
        /* Set up VOL callback arguments */
524
674
        vol_cb_args.op_type = H5VL_NATIVE_FILE_POST_OPEN;
525
674
        vol_cb_args.args    = NULL;
526
527
        /* Make the 'post open' callback */
528
674
        if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
529
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to make file 'post open' callback");
530
674
    } /* end if */
531
532
674
done:
533
674
    FUNC_LEAVE_NOAPI(ret_value)
534
674
} /* end H5F__post_open_api_common() */
535
536
/*-------------------------------------------------------------------------
537
 * Function:    H5F__create_api_common
538
 *
539
 * Purpose:     This is the common function for creating new  HDF5 files.
540
 *
541
 * Return:      Success:    A file ID
542
 *              Failure:    H5I_INVALID_HID
543
 *-------------------------------------------------------------------------
544
 */
545
static hid_t
546
H5F__create_api_common(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id, void **token_ptr)
547
0
{
548
0
    void                 *new_file = NULL;             /* File struct for new file                 */
549
0
    H5P_genplist_t       *plist;                       /* Property list pointer                    */
550
0
    H5VL_connector_prop_t connector_prop;              /* Property for VOL connector ID & info     */
551
0
    hid_t                 ret_value = H5I_INVALID_HID; /* Return value                             */
552
553
0
    FUNC_ENTER_PACKAGE
554
555
    /* Check/fix arguments */
556
0
    if (!filename || !*filename)
557
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid file name");
558
559
    /* In this routine, we only accept the following flags:
560
     *          H5F_ACC_EXCL, H5F_ACC_TRUNC and H5F_ACC_SWMR_WRITE
561
     */
562
0
    if (flags & ~(H5F_ACC_EXCL | H5F_ACC_TRUNC | H5F_ACC_SWMR_WRITE))
563
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid flags");
564
565
    /* The H5F_ACC_EXCL and H5F_ACC_TRUNC flags are mutually exclusive */
566
0
    if ((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_TRUNC))
567
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "mutually exclusive flags for file creation");
568
569
    /* Check file creation property list */
570
0
    if (H5P_DEFAULT == fcpl_id)
571
0
        fcpl_id = H5P_FILE_CREATE_DEFAULT;
572
0
    else if (true != H5P_isa_class(fcpl_id, H5P_FILE_CREATE))
573
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not file create property list");
574
575
    /* Verify access property list and set up collective metadata if appropriate */
576
0
    if (H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, true) < 0)
577
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info");
578
579
    /* Get the VOL info from the fapl */
580
0
    if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
581
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a file access property list");
582
0
    if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0)
583
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector info");
584
585
    /* Stash a copy of the "top-level" connector property, before any pass-through
586
     *  connectors modify or unwrap it.
587
     */
588
0
    if (H5CX_set_vol_connector_prop(&connector_prop) < 0)
589
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context");
590
591
    /* Adjust bit flags by turning on the creation bit and making sure that
592
     * the EXCL or TRUNC bit is set.  All newly-created files are opened for
593
     * reading and writing.
594
     */
595
0
    if (0 == (flags & (H5F_ACC_EXCL | H5F_ACC_TRUNC)))
596
0
        flags |= H5F_ACC_EXCL; /*default*/
597
0
    flags |= H5F_ACC_RDWR | H5F_ACC_CREAT;
598
599
    /* Create a new file or truncate an existing file through the VOL */
600
0
    if (NULL == (new_file = H5VL_file_create(connector_prop.connector, filename, flags, fcpl_id, fapl_id,
601
0
                                             H5P_DATASET_XFER_DEFAULT, token_ptr)))
602
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to create file");
603
604
    /* Get an ID for the file */
605
0
    if ((ret_value = H5VL_register(H5I_FILE, new_file, connector_prop.connector, true)) < 0)
606
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle");
607
608
0
done:
609
0
    FUNC_LEAVE_NOAPI(ret_value)
610
0
} /* end H5F__create_api_common() */
611
612
/*-------------------------------------------------------------------------
613
 * Function:    H5Fcreate
614
 *
615
 * Purpose:     This is the primary function for creating HDF5 files . The
616
 *              flags parameter determines whether an existing file will be
617
 *              overwritten or not.  All newly created files are opened for
618
 *              both reading and writing.  All flags may be combined with the
619
 *              bit-wise OR operator (`|') to change the behavior of the file
620
 *              create call.
621
 *
622
 *              The more complex behaviors of a file's creation and access
623
 *              are controlled through the file-creation and file-access
624
 *              property lists.  The value of H5P_DEFAULT for a template
625
 *              value indicates that the library should use the default
626
 *              values for the appropriate template.
627
 *
628
 * See also:    H5Fpublic.h for the list of supported flags. H5Ppublic.h for
629
 *              the list of file creation and file access properties.
630
 *
631
 * Return:      Success:    A file ID
632
 *
633
 *              Failure:    H5I_INVALID_HID
634
 *
635
 *-------------------------------------------------------------------------
636
 */
637
hid_t
638
H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
639
0
{
640
0
    H5VL_object_t *vol_obj   = NULL;            /* File object */
641
0
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
642
643
0
    FUNC_ENTER_API(H5I_INVALID_HID)
644
645
    /* Create the file synchronously */
646
0
    if ((ret_value = H5F__create_api_common(filename, flags, fcpl_id, fapl_id, NULL)) < 0)
647
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, H5I_INVALID_HID, "unable to synchronously create file");
648
649
    /* Get the file object */
650
0
    if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
651
0
        HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier");
652
653
    /* Perform 'post open' operation */
654
0
    if (H5F__post_open_api_common(vol_obj, NULL) < 0)
655
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed");
656
657
0
done:
658
0
    FUNC_LEAVE_API(ret_value)
659
0
} /* end H5Fcreate() */
660
661
/*-------------------------------------------------------------------------
662
 * Function:    H5Fcreate_async
663
 *
664
 * Purpose:     Asynchronous version of H5Fcreate
665
 *
666
 * See Also:    H5Fpublic.h for a list of possible values for FLAGS.
667
 *
668
 * Return:      Success:    A file ID
669
 *              Failure:    H5I_INVALID_HID
670
 *-------------------------------------------------------------------------
671
 */
672
hid_t
673
H5Fcreate_async(const char *app_file, const char *app_func, unsigned app_line, const char *filename,
674
                unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t es_id)
675
0
{
676
0
    H5VL_object_t *vol_obj   = NULL;            /* File object */
677
0
    void          *token     = NULL;            /* Request token for async operation        */
678
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
679
0
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
680
681
0
    FUNC_ENTER_API(H5I_INVALID_HID)
682
683
    /* Set up request token pointer for asynchronous operation */
684
0
    if (H5ES_NONE != es_id)
685
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
686
687
    /* Create the file, possibly asynchronously */
688
0
    if ((ret_value = H5F__create_api_common(filename, flags, fcpl_id, fapl_id, token_ptr)) < 0)
689
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, H5I_INVALID_HID, "unable to asynchronously create file");
690
691
    /* Get the file object */
692
0
    if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
693
0
        HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier");
694
695
    /* If a token was created, add the token to the event set */
696
0
    if (NULL != token)
697
        /* clang-format off */
698
0
        if (H5ES_insert(es_id, H5VL_OBJ_CONNECTOR(vol_obj), token,
699
0
                        H5ARG_TRACE8(__func__, "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, fcpl_id, fapl_id, es_id)) < 0) {
700
            /* clang-format on */
701
0
            if (H5I_dec_app_ref(ret_value) < 0)
702
0
                HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID");
703
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
704
0
        } /* end if */
705
706
    /* Reset token for 'post open' operation */
707
    /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */
708
0
    token = NULL;
709
710
    /* Perform 'post open' operation */
711
0
    if (H5F__post_open_api_common(vol_obj, token_ptr) < 0)
712
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed");
713
714
    /* If a token was created, add the token to the event set */
715
0
    if (NULL != token)
716
        /* clang-format off */
717
0
        if (H5ES_insert(es_id, H5VL_OBJ_CONNECTOR(vol_obj), token,
718
0
                        H5ARG_TRACE8(__func__, "*s*sIu*sIuiii", app_file, app_func, app_line, filename, flags, fcpl_id, fapl_id, es_id)) < 0)
719
            /* clang-format on */
720
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
721
722
0
done:
723
0
    FUNC_LEAVE_API(ret_value)
724
0
} /* end H5Fcreate_async() */
725
726
/*-------------------------------------------------------------------------
727
 * Function:    H5F__open_api_common
728
 *
729
 * Purpose:     This is the common function for accessing existing HDF5
730
 *              files.
731
 *
732
 * Return:      Success:    A file ID
733
 *              Failure:    H5I_INVALID_HID
734
 *
735
 *-------------------------------------------------------------------------
736
 */
737
static hid_t
738
H5F__open_api_common(const char *filename, unsigned flags, hid_t fapl_id, void **token_ptr)
739
793
{
740
793
    void                 *new_file = NULL;             /* File struct for new file                 */
741
793
    H5P_genplist_t       *plist;                       /* Property list pointer                    */
742
793
    H5VL_connector_prop_t connector_prop;              /* Property for VOL connector ID & info     */
743
793
    hid_t                 ret_value = H5I_INVALID_HID; /* Return value                             */
744
745
793
    FUNC_ENTER_PACKAGE
746
747
    /* Check arguments */
748
793
    if (!filename || !*filename)
749
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid file name");
750
    /* Reject undefined flags (~H5F_ACC_PUBLIC_FLAGS) and the H5F_ACC_TRUNC & H5F_ACC_EXCL flags */
751
793
    if ((flags & ~H5F_ACC_PUBLIC_FLAGS) || (flags & H5F_ACC_TRUNC) || (flags & H5F_ACC_EXCL))
752
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid file open flags");
753
    /* XXX (VOL MERGE): Might want to move SWMR flag checks to H5F_open() */
754
    /* Asking for SWMR write access on a read-only file is invalid */
755
793
    if ((flags & H5F_ACC_SWMR_WRITE) && 0 == (flags & H5F_ACC_RDWR))
756
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID,
757
793
                    "SWMR write access on a file open for read-only access is not allowed");
758
    /* Asking for SWMR read access on a non-read-only file is invalid */
759
793
    if ((flags & H5F_ACC_SWMR_READ) && (flags & H5F_ACC_RDWR))
760
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID,
761
793
                    "SWMR read access on a file open for read-write access is not allowed");
762
763
    /* Verify access property list and set up collective metadata if appropriate */
764
793
    if (H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, true) < 0)
765
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set access property list info");
766
767
    /* Get the VOL info from the fapl */
768
793
    if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
769
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a file access property list");
770
793
    if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0)
771
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL connector info");
772
773
    /* Stash a copy of the "top-level" connector property, before any pass-through
774
     *  connectors modify or unwrap it.
775
     */
776
793
    if (H5CX_set_vol_connector_prop(&connector_prop) < 0)
777
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, H5I_INVALID_HID, "can't set VOL connector info in API context");
778
779
    /* Open the file through the VOL layer */
780
793
    if (NULL == (new_file = H5VL_file_open(connector_prop.connector, filename, flags, fapl_id,
781
793
                                           H5P_DATASET_XFER_DEFAULT, token_ptr)))
782
119
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open file");
783
784
    /* Get an ID for the file */
785
674
    if ((ret_value = H5VL_register(H5I_FILE, new_file, connector_prop.connector, true)) < 0)
786
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle");
787
788
793
done:
789
793
    FUNC_LEAVE_NOAPI(ret_value)
790
793
} /* end H5F__open_api_common() */
791
792
/*-------------------------------------------------------------------------
793
 * Function:    H5Fopen
794
 *
795
 * Purpose:     This is the primary function for accessing existing HDF5
796
 *              files.  The FLAGS argument determines whether writing to an
797
 *              existing file will be allowed or not.  All flags may be
798
 *              combined with the bit-wise OR operator (`|') to change the
799
 *              behavior of the file open call.  The more complex behaviors
800
 *              of a file's access are controlled through the file-access
801
 *              property list.
802
 *
803
 * See Also:    H5Fpublic.h for a list of possible values for FLAGS.
804
 *
805
 * Return:      Success:    A file ID
806
 *
807
 *              Failure:    H5I_INVALID_HID
808
 *
809
 *-------------------------------------------------------------------------
810
 */
811
hid_t
812
H5Fopen(const char *filename, unsigned flags, hid_t fapl_id)
813
793
{
814
793
    H5VL_object_t *vol_obj   = NULL;            /* File object */
815
793
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
816
817
1.58k
    FUNC_ENTER_API(H5I_INVALID_HID)
818
819
    /* Open the file synchronously */
820
1.58k
    if ((ret_value = H5F__open_api_common(filename, flags, fapl_id, NULL)) < 0)
821
119
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to synchronously open file");
822
823
    /* Get the file object */
824
674
    if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
825
0
        HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier");
826
827
    /* Perform 'post open' operation */
828
674
    if (H5F__post_open_api_common(vol_obj, NULL) < 0)
829
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed");
830
831
793
done:
832
793
    FUNC_LEAVE_API(ret_value)
833
674
} /* end H5Fopen() */
834
835
/*-------------------------------------------------------------------------
836
 * Function:    H5Fopen_async
837
 *
838
 * Purpose:     Asynchronous version of H5Fopen
839
 *
840
 * See Also:    H5Fpublic.h for a list of possible values for FLAGS.
841
 *
842
 * Return:      Success:    A file ID
843
 *              Failure:    H5I_INVALID_HID
844
 *
845
 *-------------------------------------------------------------------------
846
 */
847
hid_t
848
H5Fopen_async(const char *app_file, const char *app_func, unsigned app_line, const char *filename,
849
              unsigned flags, hid_t fapl_id, hid_t es_id)
850
0
{
851
0
    H5VL_object_t *vol_obj   = NULL;            /* File object */
852
0
    void          *token     = NULL;            /* Request token for async operation        */
853
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
854
0
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
855
856
0
    FUNC_ENTER_API(H5I_INVALID_HID)
857
858
    /* Set up request token pointer for asynchronous operation */
859
0
    if (H5ES_NONE != es_id)
860
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
861
862
    /* Open the file, possibly asynchronously */
863
0
    if ((ret_value = H5F__open_api_common(filename, flags, fapl_id, token_ptr)) < 0)
864
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to asynchronously open file");
865
866
    /* Get the file object */
867
0
    if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
868
0
        HGOTO_ERROR(H5E_FILE, H5E_BADTYPE, H5I_INVALID_HID, "invalid object identifier");
869
870
    /* If a token was created, add the token to the event set */
871
0
    if (NULL != token)
872
        /* clang-format off */
873
0
        if (H5ES_insert(es_id, H5VL_OBJ_CONNECTOR(vol_obj), token,
874
0
                        H5ARG_TRACE7(__func__, "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, fapl_id, es_id)) < 0) {
875
            /* clang-format on */
876
0
            if (H5I_dec_app_ref(ret_value) < 0)
877
0
                HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID");
878
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
879
0
        } /* end if */
880
881
    /* Reset token for 'post open' operation */
882
    /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */
883
0
    token = NULL;
884
885
    /* Perform 'post open' operation */
886
0
    if (H5F__post_open_api_common(vol_obj, token_ptr) < 0)
887
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed");
888
889
    /* If a token was created, add the token to the event set */
890
0
    if (NULL != token)
891
        /* clang-format off */
892
0
        if (H5ES_insert(es_id, H5VL_OBJ_CONNECTOR(vol_obj), token,
893
0
                        H5ARG_TRACE7(__func__, "*s*sIu*sIuii", app_file, app_func, app_line, filename, flags, fapl_id, es_id)) < 0)
894
            /* clang-format on */
895
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
896
897
0
done:
898
0
    FUNC_LEAVE_API(ret_value)
899
0
} /* end H5Fopen_async() */
900
901
/*-------------------------------------------------------------------------
902
 * Function:    H5F__flush_api_common
903
 *
904
 * Purpose:     This is the common function for flushing an HDF5 file.
905
 *
906
 * Return:      SUCCEED/FAIL
907
 *
908
 *-------------------------------------------------------------------------
909
 */
910
static herr_t
911
H5F__flush_api_common(hid_t object_id, H5F_scope_t scope, void **token_ptr, H5VL_object_t **_vol_obj_ptr)
912
0
{
913
0
    H5VL_object_t  *tmp_vol_obj = NULL; /* Object for loc_id */
914
0
    H5VL_object_t **vol_obj_ptr =
915
0
        (_vol_obj_ptr ? _vol_obj_ptr : &tmp_vol_obj); /* Ptr to object ptr for loc_id */
916
0
    H5I_type_t                obj_type;               /* Type of object to use */
917
0
    H5VL_file_specific_args_t vol_cb_args;            /* Arguments to VOL callback */
918
0
    herr_t                    ret_value = SUCCEED;    /* Return value     */
919
920
0
    FUNC_ENTER_PACKAGE
921
922
    /* Get the type of object we're flushing + sanity check */
923
0
    obj_type = H5I_get_type(object_id);
924
0
    if (H5I_FILE != obj_type && H5I_GROUP != obj_type && H5I_DATATYPE != obj_type &&
925
0
        H5I_DATASET != obj_type && H5I_ATTR != obj_type)
926
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object");
927
928
    /* Get the file object */
929
0
    if (NULL == (*vol_obj_ptr = H5VL_vol_object(object_id)))
930
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
931
932
    /* Set up VOL callback arguments */
933
0
    vol_cb_args.op_type             = H5VL_FILE_FLUSH;
934
0
    vol_cb_args.args.flush.obj_type = obj_type;
935
0
    vol_cb_args.args.flush.scope    = scope;
936
937
    /* Flush the object */
938
0
    if (H5VL_file_specific(*vol_obj_ptr, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
939
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file");
940
941
0
done:
942
0
    FUNC_LEAVE_NOAPI(ret_value)
943
0
} /* H5F__flush_api_common() */
944
945
/*-------------------------------------------------------------------------
946
 * Function:    H5Fflush
947
 *
948
 * Purpose:     Flushes all outstanding buffers of a file to disk but does
949
 *              not remove them from the cache.  The OBJECT_ID can be a file,
950
 *              dataset, group, attribute, or named data type.
951
 *
952
 * Return:      Success:    Non-negative
953
 *              Failure:    Negative
954
 *-------------------------------------------------------------------------
955
 */
956
herr_t
957
H5Fflush(hid_t object_id, H5F_scope_t scope)
958
0
{
959
0
    herr_t ret_value = SUCCEED; /* Return value     */
960
961
0
    FUNC_ENTER_API(FAIL)
962
963
    /* Flush the file synchronously */
964
0
    if (H5F__flush_api_common(object_id, scope, NULL, NULL) < 0)
965
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to synchronously flush file");
966
967
0
done:
968
0
    FUNC_LEAVE_API(ret_value)
969
0
} /* end H5Fflush() */
970
971
/*-------------------------------------------------------------------------
972
 * Function:    H5Fflush_async
973
 *
974
 * Purpose:     Asynchronous version of H5Fflush
975
 *
976
 * Return:      Success:    Non-negative
977
 *              Failure:    Negative
978
 *
979
 *-------------------------------------------------------------------------
980
 */
981
herr_t
982
H5Fflush_async(const char *app_file, const char *app_func, unsigned app_line, hid_t object_id,
983
               H5F_scope_t scope, hid_t es_id)
984
0
{
985
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
986
0
    void          *token     = NULL;            /* Request token for async operation        */
987
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
988
0
    herr_t         ret_value = SUCCEED;         /* Return value     */
989
990
0
    FUNC_ENTER_API(FAIL)
991
992
    /* Set up request token pointer for asynchronous operation */
993
0
    if (H5ES_NONE != es_id)
994
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
995
996
    /* Flush the file asynchronously */
997
0
    if (H5F__flush_api_common(object_id, scope, token_ptr, &vol_obj) < 0)
998
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to asynchronously flush file");
999
1000
    /* If a token was created, add the token to the event set */
1001
0
    if (NULL != token)
1002
        /* clang-format off */
1003
0
        if (H5ES_insert(es_id, H5VL_OBJ_CONNECTOR(vol_obj), token,
1004
0
                H5ARG_TRACE6(__func__, "*s*sIuiFsi", app_file, app_func, app_line, object_id, scope, es_id)) < 0)
1005
            /* clang-format on */
1006
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert token into event set");
1007
1008
0
done:
1009
0
    FUNC_LEAVE_API(ret_value)
1010
0
} /* end H5Fflush_async() */
1011
1012
/*-------------------------------------------------------------------------
1013
 * Function:    H5Fclose
1014
 *
1015
 * Purpose:     This function closes the file specified by FILE_ID by
1016
 *              flushing all data to storage, and terminating access to the
1017
 *              file through FILE_ID.  If objects (e.g., datasets, groups,
1018
 *              etc.) are open in the file then the underlying storage is not
1019
 *              closed until those objects are closed; however, all data for
1020
 *              the file and the open objects is flushed.
1021
 *
1022
 * Return:      Success:    Non-negative
1023
 *              Failure:    Negative
1024
 *-------------------------------------------------------------------------
1025
 */
1026
herr_t
1027
H5Fclose(hid_t file_id)
1028
674
{
1029
674
    herr_t ret_value = SUCCEED; /* Return value */
1030
1031
1.34k
    FUNC_ENTER_API(FAIL)
1032
1033
    /* Check arguments */
1034
1.34k
    if (H5I_FILE != H5I_get_type(file_id))
1035
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID");
1036
1037
    /* Synchronously decrement reference count on ID.
1038
     * When it reaches zero the file will be closed.
1039
     */
1040
674
    if (H5I_dec_app_ref(file_id) < 0)
1041
328
        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed");
1042
1043
674
done:
1044
674
    FUNC_LEAVE_API(ret_value)
1045
674
} /* end H5Fclose() */
1046
1047
/*-------------------------------------------------------------------------
1048
 * Function:    H5Fclose_async
1049
 *
1050
 * Purpose:     Asynchronous version of H5Fclose
1051
 *
1052
 * Return:      SUCCEED/FAIL
1053
 *
1054
 *-------------------------------------------------------------------------
1055
 */
1056
herr_t
1057
H5Fclose_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, hid_t es_id)
1058
0
{
1059
0
    H5VL_object_t    *vol_obj   = NULL;            /* Object for loc_id */
1060
0
    H5VL_connector_t *connector = NULL;            /* VOL connector */
1061
0
    void             *token     = NULL;            /* Request token for async operation        */
1062
0
    void            **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
1063
0
    herr_t            ret_value = SUCCEED;         /* Return value */
1064
1065
0
    FUNC_ENTER_API(FAIL)
1066
1067
    /* Check arguments */
1068
0
    if (H5I_FILE != H5I_get_type(file_id))
1069
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID");
1070
1071
    /* Prepare for possible asynchronous operation */
1072
0
    if (H5ES_NONE != es_id) {
1073
        /* Get file object's connector */
1074
0
        if (NULL == (vol_obj = H5VL_vol_object(file_id)))
1075
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get VOL object for file");
1076
1077
        /* Increase connector's refcount, so it doesn't get closed if closing
1078
         * this file ID closes the file */
1079
0
        connector = H5VL_OBJ_CONNECTOR(vol_obj);
1080
0
        H5VL_conn_inc_rc(connector);
1081
1082
        /* Point at token for operation to set up */
1083
0
        token_ptr = &token;
1084
0
    } /* end if */
1085
1086
    /* Asynchronously decrement reference count on ID.
1087
     * When it reaches zero the file will be closed.
1088
     */
1089
0
    if (H5I_dec_app_ref_async(file_id, token_ptr) < 0)
1090
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed");
1091
1092
    /* If a token was created, add the token to the event set */
1093
0
    if (NULL != token)
1094
        /* clang-format off */
1095
0
        if (H5ES_insert(es_id, H5VL_OBJ_CONNECTOR(vol_obj), token,
1096
0
                        H5ARG_TRACE5(__func__, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0)
1097
            /* clang-format on */
1098
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, FAIL, "can't insert token into event set");
1099
1100
0
done:
1101
0
    if (connector && H5VL_conn_dec_rc(connector) < 0)
1102
0
        HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't decrement ref count on connector");
1103
1104
0
    FUNC_LEAVE_API(ret_value)
1105
0
} /* end H5Fclose_async() */
1106
1107
/*-------------------------------------------------------------------------
1108
 * Function:    H5Fdelete
1109
 *
1110
 * Purpose:     Deletes an HDF5 file.
1111
 *
1112
 * Return:      SUCCEED/FAIL
1113
 *
1114
 *-------------------------------------------------------------------------
1115
 */
1116
herr_t
1117
H5Fdelete(const char *filename, hid_t fapl_id)
1118
0
{
1119
0
    H5P_genplist_t           *plist;                 /* Property list pointer */
1120
0
    H5VL_connector_prop_t     connector_prop;        /* Property for VOL connector ID & info */
1121
0
    H5VL_file_specific_args_t vol_cb_args;           /* Arguments to VOL callback */
1122
0
    bool                      is_accessible = false; /* Whether file is accessible */
1123
0
    herr_t                    ret_value     = SUCCEED;
1124
1125
0
    FUNC_ENTER_API(FAIL)
1126
1127
    /* Check args */
1128
0
    if (!filename || !*filename)
1129
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified");
1130
1131
    /* Verify access property list and set up collective metadata if appropriate */
1132
0
    if (H5CX_set_apl(&fapl_id, H5P_CLS_FACC, H5I_INVALID_HID, true) < 0)
1133
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set access property list info");
1134
1135
    /* Get the VOL info from the fapl */
1136
0
    if (NULL == (plist = (H5P_genplist_t *)H5I_object_verify(fapl_id, H5I_GENPROP_LST)))
1137
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
1138
0
    if (H5P_peek(plist, H5F_ACS_VOL_CONN_NAME, &connector_prop) < 0)
1139
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get VOL connector info");
1140
1141
    /* Stash a copy of the "top-level" connector property, before any pass-through
1142
     *  connectors modify or unwrap it.
1143
     */
1144
0
    if (H5CX_set_vol_connector_prop(&connector_prop) < 0)
1145
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set VOL connector info in API context");
1146
1147
    /* Set up VOL callback arguments */
1148
0
    vol_cb_args.op_type                       = H5VL_FILE_IS_ACCESSIBLE;
1149
0
    vol_cb_args.args.is_accessible.filename   = filename;
1150
0
    vol_cb_args.args.is_accessible.fapl_id    = fapl_id;
1151
0
    vol_cb_args.args.is_accessible.accessible = &is_accessible;
1152
1153
    /* Make sure this is HDF5 storage for this VOL connector */
1154
0
    if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1155
0
        HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to determine if file is accessible as HDF5");
1156
0
    if (!is_accessible)
1157
0
        HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "not an HDF5 file");
1158
1159
    /* Set up VOL callback arguments */
1160
0
    vol_cb_args.op_type           = H5VL_FILE_DELETE;
1161
0
    vol_cb_args.args.del.filename = filename;
1162
0
    vol_cb_args.args.del.fapl_id  = fapl_id;
1163
1164
    /* Delete the file */
1165
0
    if (H5VL_file_specific(NULL, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1166
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "unable to delete the file");
1167
1168
0
done:
1169
0
    FUNC_LEAVE_API(ret_value)
1170
0
} /* end H5Fdelete() */
1171
1172
/*-------------------------------------------------------------------------
1173
 * Function:    H5Fmount
1174
 *
1175
 * Purpose:     Mount file CHILD_ID onto the group specified by LOC_ID and
1176
 *              NAME using mount properties PLIST_ID.
1177
 *
1178
 * Return:      SUCCEED/FAIL
1179
 *
1180
 *-------------------------------------------------------------------------
1181
 */
1182
herr_t
1183
H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id)
1184
0
{
1185
0
    H5VL_object_t             *loc_vol_obj   = NULL; /* Parent object        */
1186
0
    H5VL_object_t             *child_vol_obj = NULL; /* Child object         */
1187
0
    H5VL_group_specific_args_t vol_cb_args;          /* Arguments to VOL callback */
1188
0
    void                      *grp = NULL;           /* Root group opened */
1189
0
    H5I_type_t                 loc_type;             /* ID type of location  */
1190
0
    htri_t                     same_connector; /* Whether parent and child files use the same connector */
1191
0
    herr_t                     ret_value = SUCCEED; /* Return value         */
1192
1193
0
    FUNC_ENTER_API(FAIL)
1194
1195
    /* Check arguments */
1196
0
    loc_type = H5I_get_type(loc_id);
1197
0
    if (H5I_FILE != loc_type && H5I_GROUP != loc_type)
1198
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "loc_id parameter not a file or group ID");
1199
0
    if (!name)
1200
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL");
1201
0
    if (!*name)
1202
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be the empty string");
1203
0
    if (H5I_FILE != H5I_get_type(child_id))
1204
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "child_id parameter not a file ID");
1205
0
    if (H5P_DEFAULT == plist_id)
1206
0
        plist_id = H5P_FILE_MOUNT_DEFAULT;
1207
0
    else if (true != H5P_isa_class(plist_id, H5P_FILE_MOUNT))
1208
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "plist_id is not a file mount property list ID");
1209
1210
    /* Set up collective metadata if appropriate */
1211
0
    if (H5CX_set_loc(loc_id) < 0)
1212
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info");
1213
1214
    /* Get the location object */
1215
    /* Need to open the root group of a file, if a file ID was given as the
1216
     *  'loc_id', because the 'mount' operation is a group specific operation.
1217
     */
1218
0
    if (H5I_FILE == loc_type) {
1219
0
        H5VL_object_t    *vol_obj;    /* Object for loc_id (file) */
1220
0
        H5VL_loc_params_t loc_params; /* Location parameters for object access */
1221
1222
        /* Get the location object */
1223
0
        if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
1224
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier");
1225
1226
        /* Set location parameters */
1227
0
        loc_params.type     = H5VL_OBJECT_BY_SELF;
1228
0
        loc_params.obj_type = loc_type;
1229
1230
        /* Open the root group object */
1231
0
        if (NULL == (grp = H5VL_group_open(vol_obj, &loc_params, "/", H5P_GROUP_ACCESS_DEFAULT,
1232
0
                                           H5P_DATASET_XFER_DEFAULT, NULL)))
1233
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group");
1234
1235
        /* Create a VOL object for the root group */
1236
0
        if (NULL == (loc_vol_obj = H5VL_create_object(grp, H5VL_OBJ_CONNECTOR(vol_obj))))
1237
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "can't create VOL object for root group");
1238
0
    } /* end if */
1239
0
    else {
1240
0
        assert(H5I_GROUP == loc_type);
1241
0
        if (NULL == (loc_vol_obj = H5VL_vol_object(loc_id)))
1242
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object");
1243
0
    } /* end else */
1244
1245
    /* Get the child object */
1246
0
    if (NULL == (child_vol_obj = H5VL_vol_object(child_id)))
1247
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get child object");
1248
1249
    /* Check if both objects are associated with the same VOL connector */
1250
0
    if ((same_connector =
1251
0
             H5VL_conn_same_class(H5VL_OBJ_CONNECTOR(loc_vol_obj), H5VL_OBJ_CONNECTOR(child_vol_obj))) < 0)
1252
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTCOMPARE, FAIL, "can't compare connector classes");
1253
0
    if (!same_connector)
1254
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
1255
0
                    "can't mount file onto object from different VOL connector");
1256
1257
    /* Set up VOL callback arguments */
1258
0
    vol_cb_args.op_type         = H5VL_GROUP_MOUNT;
1259
0
    vol_cb_args.args.mount.name = name;
1260
0
    vol_cb_args.args.mount.child_file =
1261
0
        H5VL_OBJ_DATA(child_vol_obj); /* Don't unwrap fully, so each connector can see its object */
1262
0
    vol_cb_args.args.mount.fmpl_id = plist_id;
1263
1264
    /* Perform the mount operation */
1265
    /* (This is on a group, so that the VOL framework always sees groups for
1266
     *  the 'mount' operation, instead of mixing files and groups)
1267
     */
1268
0
    if (H5VL_group_specific(loc_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1269
0
        HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file");
1270
1271
0
done:
1272
    /* Clean up if we temporarily opened the root group for a file */
1273
0
    if (grp) {
1274
0
        assert(loc_vol_obj);
1275
0
        if (H5VL_group_close(loc_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1276
0
            HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "unable to release group");
1277
0
        if (H5VL_free_object(loc_vol_obj) < 0)
1278
0
            HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to free VOL object");
1279
0
    } /* end if */
1280
1281
0
    FUNC_LEAVE_API(ret_value)
1282
0
} /* end H5Fmount() */
1283
1284
/*-------------------------------------------------------------------------
1285
 * Function:    H5Funmount
1286
 *
1287
 * Purpose:     Given a mount point, disassociate the mount point's file
1288
 *              from the file mounted there. Do not close either file.
1289
 *
1290
 *              The mount point can either be the group in the parent or the
1291
 *              root group of the mounted file (both groups have the same
1292
 *              name). If the mount point was opened before the mount then
1293
 *              it's the group in the parent, but if it was opened after the
1294
 *              mount then it's the root group of the child.
1295
 *
1296
 * Return:      SUCCEED/FAIL
1297
 *
1298
 *-------------------------------------------------------------------------
1299
 */
1300
herr_t
1301
H5Funmount(hid_t loc_id, const char *name)
1302
0
{
1303
0
    H5VL_object_t             *loc_vol_obj = NULL;  /* Parent object        */
1304
0
    H5VL_group_specific_args_t vol_cb_args;         /* Arguments to VOL callback */
1305
0
    void                      *grp = NULL;          /* Root group opened */
1306
0
    H5I_type_t                 loc_type;            /* ID type of location  */
1307
0
    herr_t                     ret_value = SUCCEED; /* Return value         */
1308
1309
0
    FUNC_ENTER_API(FAIL)
1310
1311
    /* Check arguments */
1312
0
    loc_type = H5I_get_type(loc_id);
1313
0
    if (H5I_FILE != loc_type && H5I_GROUP != loc_type)
1314
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "loc_id parameter not a file or group ID");
1315
0
    if (!name)
1316
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL");
1317
0
    if (!*name)
1318
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be the empty string");
1319
1320
    /* Set up collective metadata if appropriate */
1321
0
    if (H5CX_set_loc(loc_id) < 0)
1322
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info");
1323
1324
    /* Get the location object */
1325
    /* Need to open the root group of a file, if a file ID was given as the
1326
     *  'loc_id', because the 'mount' operation is a group specific operation.
1327
     */
1328
0
    if (H5I_FILE == loc_type) {
1329
0
        H5VL_object_t    *vol_obj;    /* Object for loc_id (file) */
1330
0
        H5VL_loc_params_t loc_params; /* Location parameters for object access */
1331
1332
        /* Get the location object */
1333
0
        if (NULL == (vol_obj = H5VL_vol_object(loc_id)))
1334
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier");
1335
1336
        /* Set location parameters */
1337
0
        loc_params.type     = H5VL_OBJECT_BY_SELF;
1338
0
        loc_params.obj_type = loc_type;
1339
1340
        /* Open the root group object */
1341
0
        if (NULL == (grp = H5VL_group_open(vol_obj, &loc_params, "/", H5P_GROUP_ACCESS_DEFAULT,
1342
0
                                           H5P_DATASET_XFER_DEFAULT, NULL)))
1343
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "unable to open group");
1344
1345
        /* Create a VOL object for the root group */
1346
0
        if (NULL == (loc_vol_obj = H5VL_create_object(grp, H5VL_OBJ_CONNECTOR(vol_obj))))
1347
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTOPENOBJ, FAIL, "can't create VOL object for root group");
1348
0
    } /* end if */
1349
0
    else {
1350
0
        assert(H5I_GROUP == loc_type);
1351
0
        if (NULL == (loc_vol_obj = H5VL_vol_object(loc_id)))
1352
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get location object");
1353
0
    } /* end else */
1354
1355
    /* Set up VOL callback arguments */
1356
0
    vol_cb_args.op_type           = H5VL_GROUP_UNMOUNT;
1357
0
    vol_cb_args.args.unmount.name = name;
1358
1359
    /* Perform the unmount operation */
1360
    /* (This is on a group, so that the VOL framework always sees groups for
1361
     *  the 'unmount' operation, instead of mixing files and groups)
1362
     */
1363
0
    if (H5VL_group_specific(loc_vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1364
0
        HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file");
1365
1366
0
done:
1367
    /* Clean up if we temporarily opened the root group for a file */
1368
0
    if (grp) {
1369
0
        assert(loc_vol_obj);
1370
0
        if (H5VL_group_close(loc_vol_obj, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1371
0
            HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, FAIL, "unable to release group");
1372
0
        if (H5VL_free_object(loc_vol_obj) < 0)
1373
0
            HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to free VOL object");
1374
0
    } /* end if */
1375
1376
0
    FUNC_LEAVE_API(ret_value)
1377
0
} /* end H5Funmount() */
1378
1379
/*-------------------------------------------------------------------------
1380
 * Function:    H5F__reopen_api_common
1381
 *
1382
 * Purpose:     This is the common function for reopening an HDF5 file
1383
 *              files.
1384
 *
1385
 * Return:      Success:    A file ID
1386
 *              Failure:    H5I_INVALID_HID
1387
 *
1388
 *-------------------------------------------------------------------------
1389
 */
1390
static hid_t
1391
H5F__reopen_api_common(hid_t file_id, void **token_ptr)
1392
0
{
1393
0
    H5VL_object_t            *vol_obj = NULL;                /* Object for loc_id */
1394
0
    H5VL_file_specific_args_t vol_cb_args;                   /* Arguments to VOL callback */
1395
0
    void                     *reopen_file = NULL;            /* Pointer to the re-opened file object */
1396
0
    hid_t                     ret_value   = H5I_INVALID_HID; /* Return value */
1397
1398
0
    FUNC_ENTER_PACKAGE
1399
1400
    /* Get the file object */
1401
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1402
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "invalid file identifier");
1403
1404
    /* Set up VOL callback arguments */
1405
0
    vol_cb_args.op_type          = H5VL_FILE_REOPEN;
1406
0
    vol_cb_args.args.reopen.file = &reopen_file;
1407
1408
    /* Reopen the file */
1409
0
    if (H5VL_file_specific(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, token_ptr) < 0)
1410
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file via the VOL connector");
1411
1412
    /* Make sure that worked */
1413
0
    if (NULL == reopen_file)
1414
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "unable to reopen file");
1415
1416
    /* Get an ID for the file */
1417
0
    if ((ret_value = H5VL_register(H5I_FILE, reopen_file, H5VL_OBJ_CONNECTOR(vol_obj), true)) < 0)
1418
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register file handle");
1419
1420
0
done:
1421
0
    FUNC_LEAVE_NOAPI(ret_value)
1422
0
} /* end H5F__reopen_api_common() */
1423
1424
/*-------------------------------------------------------------------------
1425
 * Function:    H5Freopen
1426
 *
1427
 * Purpose:     Reopen a file.  The new file handle which is returned points
1428
 *              to the same file as the specified file handle.  Both handles
1429
 *              share caches and other information.  The only difference
1430
 *              between the handles is that the new handle is not mounted
1431
 *              anywhere and no files are mounted on it.
1432
 *
1433
 * Return:      Success:    New file ID
1434
 *
1435
 *              Failure:    H5I_INVALID_HID
1436
 *
1437
 *-------------------------------------------------------------------------
1438
 */
1439
hid_t
1440
H5Freopen(hid_t file_id)
1441
0
{
1442
0
    H5VL_object_t *vol_obj   = NULL;            /* File object */
1443
0
    hid_t          ret_value = H5I_INVALID_HID; /* Return value */
1444
1445
0
    FUNC_ENTER_API(H5I_INVALID_HID)
1446
1447
    /* Reopen the file synchronously */
1448
0
    if ((ret_value = H5F__reopen_api_common(file_id, NULL)) < 0)
1449
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to synchronously reopen file");
1450
1451
    /* Get the file object */
1452
0
    if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
1453
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get handle for re-opened file");
1454
1455
    /* Perform 'post open' operation */
1456
0
    if (H5F__post_open_api_common(vol_obj, NULL) < 0)
1457
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed");
1458
1459
0
done:
1460
    /* XXX (VOL MERGE): If registration fails, file will not be closed */
1461
0
    FUNC_LEAVE_API(ret_value)
1462
0
} /* end H5Freopen() */
1463
1464
/*-------------------------------------------------------------------------
1465
 * Function:    H5Freopen_async
1466
 *
1467
 * Purpose:     Asynchronous version of H5Freopen
1468
 *
1469
 * See Also:    H5Fpublic.h for a list of possible values for FLAGS.
1470
 *
1471
 * Return:      Success:    A file ID
1472
 *              Failure:    H5I_INVALID_HID
1473
 *
1474
 *-------------------------------------------------------------------------
1475
 */
1476
hid_t
1477
H5Freopen_async(const char *app_file, const char *app_func, unsigned app_line, hid_t file_id, hid_t es_id)
1478
0
{
1479
0
    H5VL_object_t *vol_obj   = NULL;            /* Object for loc_id */
1480
0
    void          *token     = NULL;            /* Request token for async operation        */
1481
0
    void         **token_ptr = H5_REQUEST_NULL; /* Pointer to request token for async operation        */
1482
0
    hid_t          ret_value;                   /* Return value */
1483
1484
0
    FUNC_ENTER_API(H5I_INVALID_HID)
1485
1486
    /* Set up request token pointer for asynchronous operation */
1487
0
    if (H5ES_NONE != es_id)
1488
0
        token_ptr = &token; /* Point at token for VOL connector to set up */
1489
1490
    /* Reopen the file, possibly asynchronously */
1491
0
    if ((ret_value = H5F__reopen_api_common(file_id, token_ptr)) < 0)
1492
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to asynchronously reopen file");
1493
1494
    /* Get the file object */
1495
0
    if (NULL == (vol_obj = H5VL_vol_object(ret_value)))
1496
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, H5I_INVALID_HID, "can't get handle for re-opened file");
1497
1498
    /* If a token was created, add the token to the event set */
1499
0
    if (NULL != token)
1500
        /* clang-format off */
1501
0
        if (H5ES_insert(es_id, H5VL_OBJ_CONNECTOR(vol_obj), token,
1502
0
                        H5ARG_TRACE5(__func__, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0) {
1503
            /* clang-format on */
1504
0
            if (H5I_dec_app_ref(ret_value) < 0)
1505
0
                HDONE_ERROR(H5E_FILE, H5E_CANTDEC, H5I_INVALID_HID, "can't decrement count on file ID");
1506
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
1507
0
        } /* end if */
1508
1509
    /* Reset token for 'post open' operation */
1510
    /* (Unnecessary if create operation didn't change it, but not worth checking -QAK) */
1511
0
    token = NULL;
1512
1513
    /* Perform 'post open' operation */
1514
0
    if (H5F__post_open_api_common(vol_obj, token_ptr) < 0)
1515
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, H5I_INVALID_HID, "'post open' operation failed");
1516
1517
    /* If a token was created, add the token to the event set */
1518
0
    if (NULL != token)
1519
        /* clang-format off */
1520
0
        if (H5ES_insert(es_id, H5VL_OBJ_CONNECTOR(vol_obj), token,
1521
0
                        H5ARG_TRACE5(__func__, "*s*sIuii", app_file, app_func, app_line, file_id, es_id)) < 0)
1522
            /* clang-format on */
1523
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, H5I_INVALID_HID, "can't insert token into event set");
1524
1525
0
done:
1526
0
    FUNC_LEAVE_API(ret_value)
1527
0
} /* end H5Freopen_async() */
1528
1529
/*-------------------------------------------------------------------------
1530
 * Function:    H5Fget_intent
1531
 *
1532
 * Purpose:     Public API to retrieve the file's 'intent' flags passed
1533
 *              during H5Fopen()
1534
 *
1535
 * Return:      Success:    Non-negative
1536
 *              Failure:    Negative
1537
 *-------------------------------------------------------------------------
1538
 */
1539
herr_t
1540
H5Fget_intent(hid_t file_id, unsigned *intent_flags /*out*/)
1541
0
{
1542
0
    herr_t ret_value = SUCCEED;
1543
1544
0
    FUNC_ENTER_API(FAIL)
1545
1546
    /* If no intent flags were passed in, exit quietly */
1547
0
    if (intent_flags) {
1548
0
        H5VL_object_t       *vol_obj;     /* File for file_id */
1549
0
        H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */
1550
1551
        /* Get the internal file structure */
1552
0
        if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1553
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
1554
1555
        /* Set up VOL callback arguments */
1556
0
        vol_cb_args.op_type               = H5VL_FILE_GET_INTENT;
1557
0
        vol_cb_args.args.get_intent.flags = intent_flags;
1558
1559
        /* Get the flags */
1560
0
        if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1561
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file's intent flags");
1562
0
    } /* end if */
1563
1564
0
done:
1565
0
    FUNC_LEAVE_API(ret_value)
1566
0
} /* end H5Fget_intent() */
1567
1568
/*-------------------------------------------------------------------------
1569
 * Function:    H5Fget_fileno
1570
 *
1571
 * Purpose:     Public API to retrieve the file's 'file number' that uniquely
1572
 *              identifies each open file.
1573
 *
1574
 * Return:      SUCCEED/FAIL
1575
 *
1576
 *-------------------------------------------------------------------------
1577
 */
1578
herr_t
1579
H5Fget_fileno(hid_t file_id, unsigned long *fnumber /*out*/)
1580
0
{
1581
0
    herr_t ret_value = SUCCEED;
1582
1583
0
    FUNC_ENTER_API(FAIL)
1584
1585
    /* If no fnumber pointer was passed in, exit quietly */
1586
0
    if (fnumber) {
1587
0
        H5VL_object_t       *vol_obj;     /* File for file_id */
1588
0
        H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */
1589
1590
        /* Get the internal file structure */
1591
0
        if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1592
0
            HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
1593
1594
        /* Set up VOL callback arguments */
1595
0
        vol_cb_args.op_type                = H5VL_FILE_GET_FILENO;
1596
0
        vol_cb_args.args.get_fileno.fileno = fnumber;
1597
1598
        /* Get the 'file number' */
1599
0
        if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1600
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file's 'file number'");
1601
0
    } /* end if */
1602
1603
0
done:
1604
0
    FUNC_LEAVE_API(ret_value)
1605
0
} /* end H5Fget_fileno() */
1606
1607
/*-------------------------------------------------------------------------
1608
 * Function:    H5Fget_freespace
1609
 *
1610
 * Purpose:     Retrieves the amount of free space in the file.
1611
 *
1612
 * Return:      Success:    Amount of free space for type
1613
 *              Failure:    -1
1614
 *-------------------------------------------------------------------------
1615
 */
1616
hssize_t
1617
H5Fget_freespace(hid_t file_id)
1618
0
{
1619
0
    H5VL_object_t                   *vol_obj = NULL;
1620
0
    H5VL_optional_args_t             vol_cb_args;        /* Arguments to VOL callback */
1621
0
    H5VL_native_file_optional_args_t file_opt_args;      /* Arguments for optional operation */
1622
0
    hsize_t                          file_freespace = 0; /* Size of freespace in the file */
1623
0
    hssize_t                         ret_value;          /* Return value */
1624
1625
0
    FUNC_ENTER_API((-1))
1626
1627
    /* Get the file object */
1628
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1629
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier");
1630
1631
    /* Set up VOL callback arguments */
1632
0
    file_opt_args.get_freespace.size = &file_freespace;
1633
0
    vol_cb_args.op_type              = H5VL_NATIVE_FILE_GET_FREE_SPACE;
1634
0
    vol_cb_args.args                 = &file_opt_args;
1635
1636
    /* Get the amount of free space in the file */
1637
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1638
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file free space");
1639
1640
    /* Set return value */
1641
0
    ret_value = (hssize_t)file_freespace;
1642
1643
0
done:
1644
0
    FUNC_LEAVE_API(ret_value)
1645
0
} /* end H5Fget_freespace() */
1646
1647
/*-------------------------------------------------------------------------
1648
 * Function:    H5Fget_filesize
1649
 *
1650
 * Purpose:     Retrieves the file size of the HDF5 file. This function
1651
 *              is called after an existing file is opened in order
1652
 *              to learn the true size of the underlying file.
1653
 *
1654
 * Return:      Success:        Non-negative
1655
 *              Failure:        Negative
1656
 *-------------------------------------------------------------------------
1657
 */
1658
herr_t
1659
H5Fget_filesize(hid_t file_id, hsize_t *size /*out*/)
1660
0
{
1661
0
    H5VL_object_t                   *vol_obj;             /* File info */
1662
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
1663
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
1664
0
    herr_t                           ret_value = SUCCEED; /* Return value */
1665
1666
0
    FUNC_ENTER_API(FAIL)
1667
1668
    /* Check args */
1669
0
    if (!size)
1670
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "size parameter cannot be NULL");
1671
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1672
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID");
1673
1674
    /* Set up VOL callback arguments */
1675
0
    file_opt_args.get_size.size = size;
1676
0
    vol_cb_args.op_type         = H5VL_NATIVE_FILE_GET_SIZE;
1677
0
    vol_cb_args.args            = &file_opt_args;
1678
1679
    /* Get the file size */
1680
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1681
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size");
1682
1683
0
done:
1684
0
    FUNC_LEAVE_API(ret_value)
1685
0
} /* end H5Fget_filesize() */
1686
1687
/*-------------------------------------------------------------------------
1688
 * Function:    H5Fget_file_image
1689
 *
1690
 * Purpose:     If a buffer is provided (via the buf_ptr argument) and is
1691
 *              big enough (size in buf_len argument), load *buf_ptr with
1692
 *              an image of the open file whose ID is provided in the
1693
 *              file_id parameter, and return the number of bytes copied
1694
 *              to the buffer.
1695
 *
1696
 *              If the buffer exists, but is too small to contain an image
1697
 *              of the indicated file, return a negative number.
1698
 *
1699
 *              Finally, if no buffer is provided, return the size of the
1700
 *              buffer needed.  This value is simply the eoa of the target
1701
 *              file.
1702
 *
1703
 *              Note that any user block is skipped.
1704
 *
1705
 *              Also note that the function may not be used on files
1706
 *              opened with either the split/multi file driver or the
1707
 *              family file driver.
1708
 *
1709
 *              In the former case, the sparse address space makes the
1710
 *              get file image operation impractical, due to the size of
1711
 *              the image typically required.
1712
 *
1713
 *              In the case of the family file driver, the problem is
1714
 *              the driver message in the super block, which will prevent
1715
 *              the image being opened with any driver other than the
1716
 *              family file driver -- which negates the purpose of the
1717
 *              operation.  This can be fixed, but no resources for
1718
 *              this now.
1719
 *
1720
 * Return:      Success:    Bytes copied / number of bytes needed
1721
 *              Failure:    -1
1722
 *-------------------------------------------------------------------------
1723
 */
1724
ssize_t
1725
H5Fget_file_image(hid_t file_id, void *buf /*out*/, size_t buf_len)
1726
0
{
1727
0
    H5VL_object_t                   *vol_obj;       /* File object for file ID  */
1728
0
    H5VL_optional_args_t             vol_cb_args;   /* Arguments to VOL callback */
1729
0
    H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */
1730
0
    size_t                           image_len = 0; /* Size of image buffer */
1731
0
    ssize_t                          ret_value;     /* Return value             */
1732
1733
0
    FUNC_ENTER_API((-1))
1734
1735
    /* Check args */
1736
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1737
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "not a file ID");
1738
1739
    /* Set up VOL callback arguments */
1740
0
    file_opt_args.get_file_image.buf_size  = buf_len;
1741
0
    file_opt_args.get_file_image.buf       = buf;
1742
0
    file_opt_args.get_file_image.image_len = &image_len;
1743
0
    vol_cb_args.op_type                    = H5VL_NATIVE_FILE_GET_FILE_IMAGE;
1744
0
    vol_cb_args.args                       = &file_opt_args;
1745
1746
    /* Get the file image */
1747
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1748
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file image");
1749
1750
    /* Set return value */
1751
0
    ret_value = (ssize_t)image_len;
1752
1753
0
done:
1754
0
    FUNC_LEAVE_API(ret_value)
1755
0
} /* H5Fget_file_image() */
1756
1757
/*-------------------------------------------------------------------------
1758
 * Function:    H5Fget_mdc_config
1759
 *
1760
 * Purpose:     Retrieves the current automatic cache resize configuration
1761
 *              from the metadata cache, and return it in *config_ptr.
1762
 *
1763
 *              Note that the version field of *config_Ptr must be correctly
1764
 *              filled in by the caller.  This allows us to adapt for
1765
 *              obsolete versions of the structure.
1766
 *
1767
 * Return:      Success:    Non-negative
1768
 *              Failure:    Negative
1769
 *-------------------------------------------------------------------------
1770
 */
1771
herr_t
1772
H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config /*out*/)
1773
0
{
1774
0
    H5VL_object_t                   *vol_obj = NULL;
1775
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
1776
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
1777
0
    herr_t                           ret_value = SUCCEED; /* Return value */
1778
1779
0
    FUNC_ENTER_API(FAIL)
1780
1781
    /* Check args */
1782
0
    if ((NULL == config) || (config->version != H5AC__CURR_CACHE_CONFIG_VERSION))
1783
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Bad config ptr");
1784
1785
    /* Get the file object */
1786
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1787
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
1788
1789
    /* Set up VOL callback arguments */
1790
0
    file_opt_args.get_mdc_config.config = config;
1791
0
    vol_cb_args.op_type                 = H5VL_NATIVE_FILE_GET_MDC_CONF;
1792
0
    vol_cb_args.args                    = &file_opt_args;
1793
1794
    /* Get the metadata cache configuration */
1795
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1796
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get metadata cache configuration");
1797
1798
0
done:
1799
0
    FUNC_LEAVE_API(ret_value)
1800
0
} /* H5Fget_mdc_config() */
1801
1802
/*-------------------------------------------------------------------------
1803
 * Function:    H5Fset_mdc_config
1804
 *
1805
 * Purpose:     Sets the current metadata cache automatic resize
1806
 *              configuration, using the contents of the instance of
1807
 *              H5AC_cache_config_t pointed to by config_ptr.
1808
 *
1809
 * Return:      Success:    Non-negative
1810
 *              Failure:    Negative
1811
 *-------------------------------------------------------------------------
1812
 */
1813
herr_t
1814
H5Fset_mdc_config(hid_t file_id, const H5AC_cache_config_t *config_ptr)
1815
0
{
1816
0
    H5VL_object_t                   *vol_obj = NULL;
1817
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
1818
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
1819
0
    herr_t                           ret_value = SUCCEED; /* Return value */
1820
1821
0
    FUNC_ENTER_API(FAIL)
1822
1823
    /* Get the file object */
1824
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1825
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
1826
1827
    /* Set up VOL callback arguments */
1828
0
    file_opt_args.set_mdc_config.config = config_ptr;
1829
0
    vol_cb_args.op_type                 = H5VL_NATIVE_FILE_SET_MDC_CONFIG;
1830
0
    vol_cb_args.args                    = &file_opt_args;
1831
1832
    /* Set the metadata cache configuration  */
1833
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1834
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set metadata cache configuration");
1835
1836
0
done:
1837
0
    FUNC_LEAVE_API(ret_value)
1838
0
} /* H5Fset_mdc_config() */
1839
1840
/*-------------------------------------------------------------------------
1841
 * Function:    H5Fget_mdc_hit_rate
1842
 *
1843
 * Purpose:     Retrieves the current hit rate from the metadata cache.
1844
 *              This rate is the overall hit rate since the last time
1845
 *              the hit rate statistics were reset either manually or
1846
 *              automatically.
1847
 *
1848
 * Return:      Success:    Non-negative
1849
 *              Failure:    Negative
1850
 *-------------------------------------------------------------------------
1851
 */
1852
herr_t
1853
H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate /*out*/)
1854
0
{
1855
0
    H5VL_object_t                   *vol_obj;
1856
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
1857
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
1858
0
    herr_t                           ret_value = SUCCEED; /* Return value */
1859
1860
0
    FUNC_ENTER_API(FAIL)
1861
1862
    /* Check args */
1863
0
    if (NULL == hit_rate)
1864
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL hit rate pointer");
1865
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1866
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID");
1867
1868
    /* Set up VOL callback arguments */
1869
0
    file_opt_args.get_mdc_hit_rate.hit_rate = hit_rate;
1870
0
    vol_cb_args.op_type                     = H5VL_NATIVE_FILE_GET_MDC_HR;
1871
0
    vol_cb_args.args                        = &file_opt_args;
1872
1873
    /* Get the current hit rate */
1874
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1875
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get MDC hit rate");
1876
1877
0
done:
1878
0
    FUNC_LEAVE_API(ret_value)
1879
0
} /* H5Fget_mdc_hit_rate() */
1880
1881
/*-------------------------------------------------------------------------
1882
 * Function:    H5Fget_mdc_size
1883
 *
1884
 * Purpose:     Retrieves the maximum size, minimum clean size, current
1885
 *              size, and current number of entries from the metadata
1886
 *              cache associated with the specified file.  If any of
1887
 *              the ptr parameters are NULL, the associated datum is
1888
 *              not returned.
1889
 *
1890
 * Return:      Success:    Non-negative
1891
 *              Failure:    Negative
1892
 *-------------------------------------------------------------------------
1893
 */
1894
herr_t
1895
H5Fget_mdc_size(hid_t file_id, size_t *max_size /*out*/, size_t *min_clean_size /*out*/,
1896
                size_t *cur_size /*out*/, int *cur_num_entries /*out*/)
1897
0
{
1898
0
    H5VL_object_t                   *vol_obj;
1899
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
1900
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
1901
0
    uint32_t                         index_len = 0;       /* Size of cache index */
1902
0
    herr_t                           ret_value = SUCCEED; /* Return value */
1903
1904
0
    FUNC_ENTER_API(FAIL)
1905
1906
    /* Check args */
1907
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1908
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID");
1909
1910
    /* Set up VOL callback arguments */
1911
0
    file_opt_args.get_mdc_size.max_size        = max_size;
1912
0
    file_opt_args.get_mdc_size.min_clean_size  = min_clean_size;
1913
0
    file_opt_args.get_mdc_size.cur_size        = cur_size;
1914
0
    file_opt_args.get_mdc_size.cur_num_entries = &index_len;
1915
0
    vol_cb_args.op_type                        = H5VL_NATIVE_FILE_GET_MDC_SIZE;
1916
0
    vol_cb_args.args                           = &file_opt_args;
1917
1918
    /* Get the size data */
1919
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1920
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get MDC size");
1921
1922
    /* Set mis-matched return value */
1923
0
    if (cur_num_entries)
1924
0
        *cur_num_entries = (int)index_len;
1925
1926
0
done:
1927
0
    FUNC_LEAVE_API(ret_value)
1928
0
} /* H5Fget_mdc_size() */
1929
1930
/*-------------------------------------------------------------------------
1931
 * Function:    H5Freset_mdc_hit_rate_stats
1932
 *
1933
 * Purpose:     Reset the hit rate statistic whose current value can
1934
 *              be obtained via the H5Fget_mdc_hit_rate() call.  Note
1935
 *              that this statistic will also be reset once per epoch
1936
 *              by the automatic cache resize code if it is enabled.
1937
 *
1938
 *              It is probably a bad idea to call this function unless
1939
 *              you are controlling cache size from your program instead
1940
 *              of using our cache size control code.
1941
 *
1942
 * Return:      Success:    Non-negative
1943
 *              Failure:    Negative
1944
 *-------------------------------------------------------------------------
1945
 */
1946
herr_t
1947
H5Freset_mdc_hit_rate_stats(hid_t file_id)
1948
0
{
1949
0
    H5VL_object_t       *vol_obj = NULL;
1950
0
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
1951
0
    herr_t               ret_value = SUCCEED; /* Return value */
1952
1953
0
    FUNC_ENTER_API(FAIL)
1954
1955
    /* Get the file object */
1956
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
1957
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
1958
1959
    /* Set up VOL callback arguments */
1960
0
    vol_cb_args.op_type = H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE;
1961
0
    vol_cb_args.args    = NULL;
1962
1963
    /* Reset the hit rate statistic */
1964
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
1965
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't reset cache hit rate");
1966
1967
0
done:
1968
0
    FUNC_LEAVE_API(ret_value)
1969
0
} /* H5Freset_mdc_hit_rate_stats() */
1970
1971
/*-------------------------------------------------------------------------
1972
 * Function:    H5Fget_name
1973
 *
1974
 * Purpose:     Gets the name of the file to which object OBJ_ID belongs.
1975
 *
1976
 * Description:
1977
 *              When 'name' is non-NULL:
1978
 *                - if 'size' > 0: writes up to 'size' bytes into the buffer
1979
 *                  (including null terminator) and returns the actual length
1980
 *                  of the name (excluding null terminator).
1981
 *                - if 'size' == 0: treats the call as length query, does not
1982
 *                  write anything to the buffer (not even a null terminator), and
1983
 *                  returns the actual length of the name (excluding null terminator).
1984
 *
1985
 *              When 'name' is NULL: does not write anything regardless of 'size'
1986
 *              and returns the actual length of the name (excluding null terminator).
1987
 *
1988
 *              On error, the buffer is unchanged and the function returns
1989
 *              a negative value.
1990
 *
1991
 * Return:      Success:    Length of the name (excluding null terminator)
1992
 *              Failure:    Negative
1993
 *
1994
 * Note:        This routine returns the name that was used to open the file,
1995
 *              not the actual name after resolving symlinks, etc.
1996
 *-------------------------------------------------------------------------
1997
 */
1998
ssize_t
1999
H5Fget_name(hid_t obj_id, char *name /*out*/, size_t size)
2000
0
{
2001
0
    H5VL_object_t       *vol_obj;     /* File for file_id */
2002
0
    H5VL_file_get_args_t vol_cb_args; /* Arguments to VOL callback */
2003
0
    H5I_type_t           type;
2004
0
    size_t               file_name_len = 0;  /* Length of file name */
2005
0
    ssize_t              ret_value     = -1; /* Return value */
2006
2007
0
    FUNC_ENTER_API((-1))
2008
2009
    /* If name size is zero, treat as length query and do not write, even a '\0' */
2010
0
    if (name && size == 0)
2011
0
        name = NULL;
2012
2013
    /* Check the type */
2014
0
    type = H5I_get_type(obj_id);
2015
0
    if (H5I_FILE != type && H5I_GROUP != type && H5I_DATATYPE != type && H5I_DATASET != type &&
2016
0
        H5I_ATTR != type)
2017
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a file or file object");
2018
2019
    /* Get the file object */
2020
0
    if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
2021
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier");
2022
2023
    /* Set up VOL callback arguments */
2024
0
    vol_cb_args.op_type                     = H5VL_FILE_GET_NAME;
2025
0
    vol_cb_args.args.get_name.type          = type;
2026
0
    vol_cb_args.args.get_name.buf_size      = size;
2027
0
    vol_cb_args.args.get_name.buf           = name;
2028
0
    vol_cb_args.args.get_name.file_name_len = &file_name_len;
2029
2030
    /* Get the filename via the VOL */
2031
0
    if (H5VL_file_get(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2032
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file name");
2033
2034
    /* Set the return value */
2035
0
    ret_value = (ssize_t)file_name_len;
2036
2037
0
done:
2038
0
    FUNC_LEAVE_API(ret_value)
2039
0
} /* end H5Fget_name() */
2040
2041
/*-------------------------------------------------------------------------
2042
 * Function:    H5Fget_info2
2043
 *
2044
 * Purpose:     Gets general information about the file, including:
2045
 *              1. Get storage size for superblock extension if there is one.
2046
 *              2. Get the amount of btree and heap storage for entries
2047
 *                 in the SOHM table if there is one.
2048
 *              3. The amount of free space tracked in the file.
2049
 *
2050
 * Return:      Success:    Non-negative
2051
 *              Failure:    Negative
2052
 *-------------------------------------------------------------------------
2053
 */
2054
herr_t
2055
H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo /*out*/)
2056
0
{
2057
0
    H5VL_object_t                   *vol_obj = NULL;
2058
0
    H5VL_optional_args_t             vol_cb_args;   /* Arguments to VOL callback */
2059
0
    H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */
2060
0
    H5I_type_t                       type;
2061
0
    herr_t                           ret_value = SUCCEED; /* Return value */
2062
2063
0
    FUNC_ENTER_API(FAIL)
2064
2065
    /* Check args */
2066
0
    if (!finfo)
2067
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file info pointer can't be NULL");
2068
2069
    /* Check the type */
2070
0
    type = H5I_get_type(obj_id);
2071
0
    if (H5I_FILE != type && H5I_GROUP != type && H5I_DATATYPE != type && H5I_DATASET != type &&
2072
0
        H5I_ATTR != type)
2073
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object");
2074
2075
    /* Get the file object */
2076
0
    if (NULL == (vol_obj = H5VL_vol_object(obj_id)))
2077
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier");
2078
2079
    /* Set up VOL callback arguments */
2080
0
    file_opt_args.get_info.type  = type;
2081
0
    file_opt_args.get_info.finfo = finfo;
2082
0
    vol_cb_args.op_type          = H5VL_NATIVE_FILE_GET_INFO;
2083
0
    vol_cb_args.args             = &file_opt_args;
2084
2085
    /* Get the file information */
2086
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2087
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info");
2088
2089
0
done:
2090
0
    FUNC_LEAVE_API(ret_value)
2091
0
} /* end H5Fget_info2() */
2092
2093
/*-------------------------------------------------------------------------
2094
 * Function:    H5Fget_metadata_read_retry_info
2095
 *
2096
 * Purpose:     To retrieve the collection of read retries for metadata
2097
 *              items with checksum.
2098
 *
2099
 * Return:      Success:    Non-negative
2100
 *              Failure:    Negative
2101
 *-------------------------------------------------------------------------
2102
 */
2103
herr_t
2104
H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info /*out*/)
2105
0
{
2106
0
    H5VL_object_t                   *vol_obj = NULL;      /* File object for file ID */
2107
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
2108
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
2109
0
    herr_t                           ret_value = SUCCEED; /* Return value */
2110
2111
0
    FUNC_ENTER_API(FAIL)
2112
2113
    /* Check args */
2114
0
    if (!info)
2115
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct");
2116
2117
    /* Get the file pointer */
2118
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2119
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID");
2120
2121
    /* Set up VOL callback arguments */
2122
0
    file_opt_args.get_metadata_read_retry_info.info = info;
2123
0
    vol_cb_args.op_type                             = H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO;
2124
0
    vol_cb_args.args                                = &file_opt_args;
2125
2126
    /* Get the retry info */
2127
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2128
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get metadata read retry info");
2129
2130
0
done:
2131
0
    FUNC_LEAVE_API(ret_value)
2132
0
} /* end H5Fget_metadata_read_retry_info() */
2133
2134
/*-------------------------------------------------------------------------
2135
 * Function:    H5Fget_free_sections
2136
 *
2137
 * Purpose:     To get free-space section information for free-space manager with
2138
 *              TYPE that is associated with file FILE_ID.
2139
 *              If SECT_INFO is null, this routine returns the total # of free-space
2140
 *              sections.
2141
 *
2142
 * Return:      Success:   The total # of free space sections
2143
 *              Failure:   -1
2144
 *-------------------------------------------------------------------------
2145
 */
2146
ssize_t
2147
H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info_t *sect_info /*out*/)
2148
0
{
2149
0
    H5VL_object_t                   *vol_obj = NULL;
2150
0
    H5VL_optional_args_t             vol_cb_args;     /* Arguments to VOL callback */
2151
0
    H5VL_native_file_optional_args_t file_opt_args;   /* Arguments for optional operation */
2152
0
    size_t                           sect_count = 0;  /* Number of sections */
2153
0
    ssize_t                          ret_value  = -1; /* Return value */
2154
2155
0
    FUNC_ENTER_API((-1))
2156
2157
    /* Check args */
2158
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2159
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "invalid file identifier");
2160
0
    if (sect_info && nsects == 0)
2161
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "nsects must be > 0");
2162
2163
    /* Set up VOL callback arguments */
2164
0
    file_opt_args.get_free_sections.type       = type;
2165
0
    file_opt_args.get_free_sections.sect_info  = sect_info;
2166
0
    file_opt_args.get_free_sections.nsects     = nsects;
2167
0
    file_opt_args.get_free_sections.sect_count = &sect_count;
2168
0
    vol_cb_args.op_type                        = H5VL_NATIVE_FILE_GET_FREE_SECTIONS;
2169
0
    vol_cb_args.args                           = &file_opt_args;
2170
2171
    /* Get the free-space section information in the file */
2172
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2173
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, (-1), "unable to get file free sections");
2174
2175
    /* Set return value */
2176
0
    ret_value = (ssize_t)sect_count;
2177
2178
0
done:
2179
0
    FUNC_LEAVE_API(ret_value)
2180
0
} /* end H5Fget_free_sections() */
2181
2182
/*-------------------------------------------------------------------------
2183
 * Function:    H5Fclear_elink_file_cache
2184
 *
2185
 * Purpose:     Releases the external file cache associated with the
2186
 *              provided file, potentially closing any cached files
2187
 *              unless they are held open from somewhere else.
2188
 *
2189
 * Return:      Success:    Non-negative
2190
 *              Failure:    Negative
2191
 *-------------------------------------------------------------------------
2192
 */
2193
herr_t
2194
H5Fclear_elink_file_cache(hid_t file_id)
2195
0
{
2196
0
    H5VL_object_t       *vol_obj;             /* File */
2197
0
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
2198
0
    herr_t               ret_value = SUCCEED; /* Return value */
2199
2200
0
    FUNC_ENTER_API(FAIL)
2201
2202
    /* Check args */
2203
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2204
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID");
2205
2206
    /* Set up VOL callback arguments */
2207
0
    vol_cb_args.op_type = H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE;
2208
0
    vol_cb_args.args    = NULL;
2209
2210
    /* Release the EFC */
2211
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2212
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache");
2213
2214
0
done:
2215
0
    FUNC_LEAVE_API(ret_value)
2216
0
} /* end H5Fclear_elink_file_cache() */
2217
2218
/*-------------------------------------------------------------------------
2219
 * Function:    H5Fstart_swmr_write
2220
 *
2221
 * Purpose:     To enable SWMR writing mode for the file
2222
 *
2223
 *              1) Refresh opened objects: part 1
2224
 *              2) Flush & reset accumulator
2225
 *              3) Mark the file in SWMR writing mode
2226
 *              4) Set metadata read attempts and retries info
2227
 *              5) Disable accumulator
2228
 *              6) Evict all cache entries except the superblock
2229
 *              7) Refresh opened objects (part 2)
2230
 *              8) Unlock the file
2231
 *
2232
 *              Pre-conditions:
2233
 *
2234
 *              1) The file being opened has v3 superblock
2235
 *              2) The file is opened with H5F_ACC_RDWR
2236
 *              3) The file is not already marked for SWMR writing
2237
 *              4) Current implementation for opened objects:
2238
 *                  --only allow datasets and groups without attributes
2239
 *                  --disallow named datatype with/without attributes
2240
 *                  --disallow opened attributes attached to objects
2241
 *
2242
 * NOTE:        Currently, only opened groups and datasets are allowed
2243
 *              when enabling SWMR via H5Fstart_swmr_write().
2244
 *              Will later implement a different approach--
2245
 *              set up flush dependency/proxy even for file opened without
2246
 *              SWMR to resolve issues with opened objects.
2247
 *
2248
 * Return:      Success:    Non-negative
2249
 *              Failure:    Negative
2250
 *-------------------------------------------------------------------------
2251
 */
2252
herr_t
2253
H5Fstart_swmr_write(hid_t file_id)
2254
0
{
2255
0
    H5VL_object_t       *vol_obj = NULL;      /* File info */
2256
0
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
2257
0
    herr_t               ret_value = SUCCEED; /* Return value */
2258
2259
0
    FUNC_ENTER_API(FAIL)
2260
2261
    /* Check args */
2262
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2263
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID");
2264
2265
    /* Set up collective metadata if appropriate */
2266
0
    if (H5CX_set_loc(file_id) < 0)
2267
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info");
2268
2269
    /* Set up VOL callback arguments */
2270
0
    vol_cb_args.op_type = H5VL_NATIVE_FILE_START_SWMR_WRITE;
2271
0
    vol_cb_args.args    = NULL;
2272
2273
    /* Start SWMR writing */
2274
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2275
0
        HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to start SWMR writing");
2276
2277
0
done:
2278
0
    FUNC_LEAVE_API(ret_value)
2279
0
} /* end H5Fstart_swmr_write() */
2280
2281
/*-------------------------------------------------------------------------
2282
 * Function:    H5Fstart_mdc_logging
2283
 *
2284
 * Purpose:     Start metadata cache logging operations for a file.
2285
 *                  - Logging must have been set up via the fapl.
2286
 *
2287
 * Return:      Success:    Non-negative
2288
 *              Failure:    Negative
2289
 *-------------------------------------------------------------------------
2290
 */
2291
herr_t
2292
H5Fstart_mdc_logging(hid_t file_id)
2293
0
{
2294
0
    H5VL_object_t       *vol_obj;             /* File info */
2295
0
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
2296
0
    herr_t               ret_value = SUCCEED; /* Return value */
2297
2298
0
    FUNC_ENTER_API(FAIL)
2299
2300
    /* Sanity check */
2301
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2302
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID");
2303
2304
    /* Set up VOL callback arguments */
2305
0
    vol_cb_args.op_type = H5VL_NATIVE_FILE_START_MDC_LOGGING;
2306
0
    vol_cb_args.args    = NULL;
2307
2308
    /* Call mdc logging function */
2309
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2310
0
        HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to start mdc logging");
2311
2312
0
done:
2313
0
    FUNC_LEAVE_API(ret_value)
2314
0
} /* H5Fstart_mdc_logging() */
2315
2316
/*-------------------------------------------------------------------------
2317
 * Function:    H5Fstop_mdc_logging
2318
 *
2319
 * Purpose:     Stop metadata cache logging operations for a file.
2320
 *                  - Does not close the log file.
2321
 *                  - Logging must have been set up via the fapl.
2322
 *
2323
 * Return:      Success:    Non-negative
2324
 *              Failure:    Negative
2325
 *-------------------------------------------------------------------------
2326
 */
2327
herr_t
2328
H5Fstop_mdc_logging(hid_t file_id)
2329
0
{
2330
0
    H5VL_object_t       *vol_obj;             /* File info */
2331
0
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
2332
0
    herr_t               ret_value = SUCCEED; /* Return value */
2333
2334
0
    FUNC_ENTER_API(FAIL)
2335
2336
    /* Sanity check */
2337
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2338
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID");
2339
2340
    /* Set up VOL callback arguments */
2341
0
    vol_cb_args.op_type = H5VL_NATIVE_FILE_STOP_MDC_LOGGING;
2342
0
    vol_cb_args.args    = NULL;
2343
2344
    /* Call mdc logging function */
2345
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2346
0
        HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to stop mdc logging");
2347
2348
0
done:
2349
0
    FUNC_LEAVE_API(ret_value)
2350
0
} /* H5Fstop_mdc_logging() */
2351
2352
/*-------------------------------------------------------------------------
2353
 * Function:    H5Fget_mdc_logging_status
2354
 *
2355
 * Purpose:     Get the logging flags. is_enabled determines if logging was
2356
 *              set up via the fapl. is_currently_logging determines if
2357
 *              log messages are being recorded at this time.
2358
 *
2359
 * Return:      Success:    Non-negative
2360
 *              Failure:    Negative
2361
 *-------------------------------------------------------------------------
2362
 */
2363
herr_t
2364
H5Fget_mdc_logging_status(hid_t file_id, bool *is_enabled /*out*/, bool *is_currently_logging /*out*/)
2365
0
{
2366
0
    H5VL_object_t                   *vol_obj;             /* File info */
2367
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
2368
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
2369
0
    herr_t                           ret_value = SUCCEED; /* Return value */
2370
2371
0
    FUNC_ENTER_API(FAIL)
2372
2373
    /* Sanity check */
2374
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2375
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID");
2376
2377
    /* Set up VOL callback arguments */
2378
0
    file_opt_args.get_mdc_logging_status.is_enabled           = is_enabled;
2379
0
    file_opt_args.get_mdc_logging_status.is_currently_logging = is_currently_logging;
2380
0
    vol_cb_args.op_type                                       = H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS;
2381
0
    vol_cb_args.args                                          = &file_opt_args;
2382
2383
    /* Call mdc logging function */
2384
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2385
0
        HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to get logging status");
2386
2387
0
done:
2388
0
    FUNC_LEAVE_API(ret_value)
2389
0
} /* H5Fget_mdc_logging_status() */
2390
2391
/*-------------------------------------------------------------------------
2392
 * Function:    H5Fset_libver_bounds
2393
 *
2394
 * Purpose:     Set to a different low and high bounds while a file is open.
2395
 *              This public routine is introduced in place of
2396
 *              H5Fset_latest_format() starting release 1.10.2.
2397
 *              See explanation for H5Fset_latest_format() in H5Fdeprec.c.
2398
 *
2399
 * Return:      Success:    Non-negative
2400
 *              Failure:    Negative
2401
 *-------------------------------------------------------------------------
2402
 */
2403
herr_t
2404
H5Fset_libver_bounds(hid_t file_id, H5F_libver_t low, H5F_libver_t high)
2405
0
{
2406
0
    H5VL_object_t                   *vol_obj;             /* File as VOL object           */
2407
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
2408
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
2409
0
    herr_t                           ret_value = SUCCEED; /* Return value         */
2410
2411
0
    FUNC_ENTER_API(FAIL)
2412
2413
    /* Check args */
2414
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2415
0
        HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "not a file ID");
2416
2417
    /* Set up collective metadata if appropriate */
2418
0
    if (H5CX_set_loc(file_id) < 0)
2419
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info");
2420
2421
    /* Set up VOL callback arguments */
2422
0
    file_opt_args.set_libver_bounds.low  = low;
2423
0
    file_opt_args.set_libver_bounds.high = high;
2424
0
    vol_cb_args.op_type                  = H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS;
2425
0
    vol_cb_args.args                     = &file_opt_args;
2426
2427
    /* Set the library's version bounds */
2428
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2429
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set library version bounds");
2430
2431
0
done:
2432
0
    FUNC_LEAVE_API(ret_value)
2433
0
} /* end H5Fset_libver_bounds() */
2434
2435
/*-------------------------------------------------------------------------
2436
 * Function:    H5Fformat_convert (Internal)
2437
 *
2438
 * Purpose:     Downgrade the superblock version to v2 and
2439
 *              downgrade persistent file space to non-persistent
2440
 *              for 1.8 library.
2441
 *
2442
 * Return:      Success:    Non-negative
2443
 *              Failure:    Negative
2444
 *-------------------------------------------------------------------------
2445
 */
2446
herr_t
2447
H5Fformat_convert(hid_t file_id)
2448
0
{
2449
0
    H5VL_object_t       *vol_obj = NULL;      /* File */
2450
0
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
2451
0
    herr_t               ret_value = SUCCEED; /* Return value */
2452
2453
0
    FUNC_ENTER_API(FAIL)
2454
2455
    /* Check args */
2456
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2457
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "file_id parameter is not a valid file identifier");
2458
2459
    /* Set up collective metadata if appropriate */
2460
0
    if (H5CX_set_loc(file_id) < 0)
2461
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set collective metadata read info");
2462
2463
    /* Set up VOL callback arguments */
2464
0
    vol_cb_args.op_type = H5VL_NATIVE_FILE_FORMAT_CONVERT;
2465
0
    vol_cb_args.args    = NULL;
2466
2467
    /* Convert the format */
2468
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2469
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTCONVERT, FAIL, "can't convert file format");
2470
2471
0
done:
2472
0
    FUNC_LEAVE_API(ret_value)
2473
0
} /* end H5Fformat_convert() */
2474
2475
/*-------------------------------------------------------------------------
2476
 * Function:    H5Freset_page_buffering_stats
2477
 *
2478
 * Purpose:     Resets statistics for the page buffer layer.
2479
 *
2480
 * Return:      Success:    Non-negative
2481
 *              Failure:    Negative
2482
 *-------------------------------------------------------------------------
2483
 */
2484
herr_t
2485
H5Freset_page_buffering_stats(hid_t file_id)
2486
0
{
2487
0
    H5VL_object_t       *vol_obj;             /* File to reset stats on */
2488
0
    H5VL_optional_args_t vol_cb_args;         /* Arguments to VOL callback */
2489
0
    herr_t               ret_value = SUCCEED; /* Return value */
2490
2491
0
    FUNC_ENTER_API(FAIL)
2492
2493
    /* Check args */
2494
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2495
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
2496
2497
    /* Set up VOL callback arguments */
2498
0
    vol_cb_args.op_type = H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS;
2499
0
    vol_cb_args.args    = NULL;
2500
2501
    /* Reset the statistics */
2502
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2503
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't reset stats for page buffering");
2504
2505
0
done:
2506
0
    FUNC_LEAVE_API(ret_value)
2507
0
} /* H5Freset_page_buffering_stats() */
2508
2509
/*-------------------------------------------------------------------------
2510
 * Function:    H5Fget_page_buffering_stats
2511
 *
2512
 * Purpose:     Retrieves statistics for the page buffer layer.
2513
 *
2514
 * Return:      Success:    Non-negative
2515
 *              Failure:    Negative
2516
 *-------------------------------------------------------------------------
2517
 */
2518
herr_t
2519
H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2] /*out*/, unsigned hits[2] /*out*/,
2520
                            unsigned misses[2] /*out*/, unsigned evictions[2] /*out*/,
2521
                            unsigned bypasses[2] /*out*/)
2522
0
{
2523
0
    H5VL_object_t                   *vol_obj;             /* File object */
2524
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
2525
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
2526
0
    herr_t                           ret_value = SUCCEED; /* Return value */
2527
2528
0
    FUNC_ENTER_API(FAIL)
2529
2530
    /* Check args */
2531
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2532
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID");
2533
0
    if (NULL == accesses || NULL == hits || NULL == misses || NULL == evictions || NULL == bypasses)
2534
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL input parameters for stats");
2535
2536
    /* Set up VOL callback arguments */
2537
0
    file_opt_args.get_page_buffering_stats.accesses  = accesses;
2538
0
    file_opt_args.get_page_buffering_stats.hits      = hits;
2539
0
    file_opt_args.get_page_buffering_stats.misses    = misses;
2540
0
    file_opt_args.get_page_buffering_stats.evictions = evictions;
2541
0
    file_opt_args.get_page_buffering_stats.bypasses  = bypasses;
2542
0
    vol_cb_args.op_type                              = H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS;
2543
0
    vol_cb_args.args                                 = &file_opt_args;
2544
2545
    /* Get the statistics */
2546
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2547
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stats for page buffering");
2548
2549
0
done:
2550
0
    FUNC_LEAVE_API(ret_value)
2551
0
} /* H5Fget_page_buffering_stats() */
2552
2553
/*-------------------------------------------------------------------------
2554
 * Function:    H5Fget_mdc_image_info
2555
 *
2556
 * Purpose:     Retrieves the image_addr and image_len for the cache image in the file.
2557
 *              image_addr:  --base address of the on disk metadata cache image
2558
 *                           --HADDR_UNDEF if no cache image
2559
 *              image_len:   --size of the on disk metadata cache image
2560
 *                           --zero if no cache image
2561
 *
2562
 * Return:      Success:    Non-negative
2563
 *              Failure:    Negative
2564
 *-------------------------------------------------------------------------
2565
 */
2566
herr_t
2567
H5Fget_mdc_image_info(hid_t file_id, haddr_t *image_addr /*out*/, hsize_t *image_len /*out*/)
2568
0
{
2569
0
    H5VL_object_t                   *vol_obj;             /* File info */
2570
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
2571
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
2572
0
    herr_t                           ret_value = SUCCEED; /* Return value */
2573
2574
0
    FUNC_ENTER_API(FAIL)
2575
2576
    /* Check args */
2577
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2578
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID");
2579
2580
    /* Set up VOL callback arguments */
2581
0
    file_opt_args.get_mdc_image_info.addr = image_addr;
2582
0
    file_opt_args.get_mdc_image_info.len  = image_len;
2583
0
    vol_cb_args.op_type                   = H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO;
2584
0
    vol_cb_args.args                      = &file_opt_args;
2585
2586
    /* Go get the address and size of the cache image */
2587
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2588
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve cache image info");
2589
2590
0
done:
2591
0
    FUNC_LEAVE_API(ret_value)
2592
0
} /* H5Fget_mdc_image_info() */
2593
2594
/*-------------------------------------------------------------------------
2595
 * Function:    H5Fget_eoa
2596
 *
2597
 * Purpose:     Gets the address of the first byte after the last
2598
 *              allocated memory in the file.
2599
 *              (See H5FDget_eoa() in H5FD.c)
2600
 *
2601
 * Return:      Success:    Non-negative
2602
 *              Failure:    Negative
2603
 *-------------------------------------------------------------------------
2604
 */
2605
herr_t
2606
H5Fget_eoa(hid_t file_id, haddr_t *eoa /*out*/)
2607
0
{
2608
0
    H5VL_object_t *vol_obj;             /* File info */
2609
0
    herr_t         ret_value = SUCCEED; /* Return value */
2610
2611
0
    FUNC_ENTER_API(FAIL)
2612
2613
    /* Check args */
2614
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2615
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID");
2616
2617
    /* Only do work if valid pointer to fill in */
2618
0
    if (eoa) {
2619
0
        H5VL_optional_args_t             vol_cb_args;   /* Arguments to VOL callback */
2620
0
        H5VL_native_file_optional_args_t file_opt_args; /* Arguments for optional operation */
2621
2622
        /* Set up VOL callback arguments */
2623
0
        file_opt_args.get_eoa.eoa = eoa;
2624
0
        vol_cb_args.op_type       = H5VL_NATIVE_FILE_GET_EOA;
2625
0
        vol_cb_args.args          = &file_opt_args;
2626
2627
        /* Retrieve the EOA for the file */
2628
0
        if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2629
0
            HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get EOA");
2630
0
    } /* end if */
2631
2632
0
done:
2633
0
    FUNC_LEAVE_API(ret_value)
2634
0
} /* H5Fget_eoa() */
2635
2636
/*-------------------------------------------------------------------------
2637
 * Function:    H5Fincrement_filesize
2638
 *
2639
 * Purpose:     Set the EOA for the file to the maximum of (EOA, EOF) + increment
2640
 *
2641
 * Return:      Success:    Non-negative
2642
 *              Failure:    Negative
2643
 *-------------------------------------------------------------------------
2644
 */
2645
herr_t
2646
H5Fincrement_filesize(hid_t file_id, hsize_t increment)
2647
0
{
2648
0
    H5VL_object_t                   *vol_obj;             /* File info */
2649
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
2650
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
2651
0
    herr_t                           ret_value = SUCCEED; /* Return value */
2652
2653
0
    FUNC_ENTER_API(FAIL)
2654
2655
    /* Check args */
2656
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2657
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID");
2658
2659
    /* Set up VOL callback arguments */
2660
0
    file_opt_args.increment_filesize.increment = increment;
2661
0
    vol_cb_args.op_type                        = H5VL_NATIVE_FILE_INCR_FILESIZE;
2662
0
    vol_cb_args.args                           = &file_opt_args;
2663
2664
    /* Increment the file size */
2665
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2666
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to increment file size");
2667
2668
0
done:
2669
0
    FUNC_LEAVE_API(ret_value)
2670
0
} /* H5Fincrement_filesize() */
2671
2672
/*-------------------------------------------------------------------------
2673
 * Function:    H5Fget_dset_no_attrs_hint
2674
 *
2675
 * Purpose:     Get the file-level setting to create minimized dataset object headers.
2676
 *              Result is stored at pointer `minimize`.
2677
 *
2678
 * Return:      Success:    Non-negative
2679
 *              Failure:    Negative
2680
 *-------------------------------------------------------------------------
2681
 */
2682
herr_t
2683
H5Fget_dset_no_attrs_hint(hid_t file_id, bool *minimize /*out*/)
2684
0
{
2685
0
    H5VL_object_t                   *vol_obj;             /* File info */
2686
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
2687
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
2688
0
    herr_t                           ret_value = SUCCEED; /* Return value */
2689
2690
0
    FUNC_ENTER_API(FAIL)
2691
2692
    /* Check args */
2693
0
    if (NULL == minimize)
2694
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "out pointer 'minimize' cannot be NULL");
2695
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2696
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
2697
2698
    /* Set up VOL callback arguments */
2699
0
    file_opt_args.get_min_dset_ohdr_flag.minimize = minimize;
2700
0
    vol_cb_args.op_type                           = H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG;
2701
0
    vol_cb_args.args                              = &file_opt_args;
2702
2703
    /* Get the dataset object header minimum size flag */
2704
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2705
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set file's dataset header minimization flag");
2706
2707
0
done:
2708
0
    FUNC_LEAVE_API(ret_value)
2709
0
} /* H5Fget_dset_no_attrs_hint */
2710
2711
/*-------------------------------------------------------------------------
2712
 * Function:    H5Fset_dset_no_attrs_hint
2713
 *
2714
 * Purpose:     Set the file-level setting to create minimized dataset object
2715
 *              headers.
2716
 *
2717
 * Return:      Success:    Non-negative
2718
 *              Failure:    Negative
2719
 *-------------------------------------------------------------------------
2720
 */
2721
herr_t
2722
H5Fset_dset_no_attrs_hint(hid_t file_id, bool minimize)
2723
0
{
2724
0
    H5VL_object_t                   *vol_obj;             /* File info */
2725
0
    H5VL_optional_args_t             vol_cb_args;         /* Arguments to VOL callback */
2726
0
    H5VL_native_file_optional_args_t file_opt_args;       /* Arguments for optional operation */
2727
0
    herr_t                           ret_value = SUCCEED; /* Return value */
2728
2729
0
    FUNC_ENTER_API(FAIL)
2730
2731
    /* Check args */
2732
0
    if (NULL == (vol_obj = H5VL_vol_object_verify(file_id, H5I_FILE)))
2733
0
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier");
2734
2735
    /* Set up VOL callback arguments */
2736
0
    file_opt_args.set_min_dset_ohdr_flag.minimize = minimize;
2737
0
    vol_cb_args.op_type                           = H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG;
2738
0
    vol_cb_args.args                              = &file_opt_args;
2739
2740
    /* Set the 'minimize dataset object headers flag' */
2741
0
    if (H5VL_file_optional(vol_obj, &vol_cb_args, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0)
2742
0
        HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to set file's dataset header minimization flag");
2743
2744
0
done:
2745
    FUNC_LEAVE_API(ret_value)
2746
0
} /* H5Fset_dset_no_attrs_hint */