Coverage Report

Created: 2024-06-18 06:29

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