1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * All rights reserved. *
4 * *
5 * This file is part of HDF5. The full HDF5 copyright notice, including *
6 * terms governing use, modification, and redistribution, is contained in *
7 * the COPYING file, which can be found at the root of the source code *
8 * distribution tree, or in https://www.hdfgroup.org/licenses. *
9 * If you do not have access to either file, you may request a copy from *
10 * help@hdfgroup.org. *
11 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13 /*
14 * Purpose: File callbacks for the native VOL connector
15 *
16 */
17
18 #define H5F_FRIEND /* Suppress error about including H5Fpkg */
19
20 #include "H5private.h" /* Generic Functions */
21 #include "H5ACprivate.h" /* Metadata cache */
22 #include "H5Cprivate.h" /* Cache */
23 #include "H5Eprivate.h" /* Error handling */
24 #include "H5Fpkg.h" /* Files */
25 #include "H5Gprivate.h" /* Groups */
26 #include "H5Iprivate.h" /* IDs */
27 #include "H5MFprivate.h" /* File memory management */
28 #include "H5Pprivate.h" /* Property lists */
29 #include "H5PBprivate.h" /* Page buffering */
30 #include "H5VLprivate.h" /* Virtual Object Layer */
31
32 #include "H5VLnative_private.h" /* Native VOL connector */
33
34 /*-------------------------------------------------------------------------
35 * Function: H5VL__native_file_create
36 *
37 * Purpose: Handles the file create callback
38 *
39 * Return: Success: file pointer
40 * Failure: NULL
41 *
42 *-------------------------------------------------------------------------
43 */
44 void *
H5VL__native_file_create(const char * name,unsigned flags,hid_t fcpl_id,hid_t fapl_id,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req)45 H5VL__native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id,
46 hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req)
47 {
48 H5F_t *new_file = NULL;
49 void * ret_value = NULL;
50
51 FUNC_ENTER_PACKAGE
52
53 /* Adjust bit flags by turning on the creation bit and making sure that
54 * the EXCL or TRUNC bit is set. All newly-created files are opened for
55 * reading and writing.
56 */
57 if (0 == (flags & (H5F_ACC_EXCL | H5F_ACC_TRUNC)))
58 flags |= H5F_ACC_EXCL; /* default */
59 flags |= H5F_ACC_RDWR | H5F_ACC_CREAT;
60
61 /* Create the file */
62 if (NULL == (new_file = H5F_open(name, flags, fcpl_id, fapl_id)))
63 HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create file")
64 new_file->id_exists = TRUE;
65
66 ret_value = (void *)new_file;
67
68 done:
69 if (NULL == ret_value && new_file)
70 if (H5F__close(new_file) < 0)
71 HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file")
72
73 FUNC_LEAVE_NOAPI(ret_value)
74 } /* end H5VL__native_file_create() */
75
76 /*-------------------------------------------------------------------------
77 * Function: H5VL__native_file_open
78 *
79 * Purpose: Handles the file open callback
80 *
81 * Return: Success: file pointer
82 * Failure: NULL
83 *
84 *-------------------------------------------------------------------------
85 */
86 void *
H5VL__native_file_open(const char * name,unsigned flags,hid_t fapl_id,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req)87 H5VL__native_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t H5_ATTR_UNUSED dxpl_id,
88 void H5_ATTR_UNUSED **req)
89 {
90 H5F_t *new_file = NULL;
91 void * ret_value = NULL;
92
93 FUNC_ENTER_PACKAGE
94
95 /* Open the file */
96 if (NULL == (new_file = H5F_open(name, flags, H5P_FILE_CREATE_DEFAULT, fapl_id)))
97 HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
98 new_file->id_exists = TRUE;
99
100 ret_value = (void *)new_file;
101
102 done:
103 if (NULL == ret_value && new_file && H5F_try_close(new_file, NULL) < 0)
104 HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file")
105
106 FUNC_LEAVE_NOAPI(ret_value)
107 } /* end H5VL__native_file_open() */
108
109 /*-------------------------------------------------------------------------
110 * Function: H5VL__native_file_get
111 *
112 * Purpose: Handles the file get callback
113 *
114 * Return: SUCCEED/FAIL
115 *
116 *-------------------------------------------------------------------------
117 */
118 herr_t
H5VL__native_file_get(void * obj,H5VL_file_get_t get_type,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req,va_list arguments)119 H5VL__native_file_get(void *obj, H5VL_file_get_t get_type, hid_t H5_ATTR_UNUSED dxpl_id,
120 void H5_ATTR_UNUSED **req, va_list arguments)
121 {
122 H5F_t *f = NULL; /* File struct */
123 herr_t ret_value = SUCCEED; /* Return value */
124
125 FUNC_ENTER_PACKAGE
126
127 switch (get_type) {
128 /* "get container info" */
129 case H5VL_FILE_GET_CONT_INFO: {
130 H5VL_file_cont_info_t *info = HDva_arg(arguments, H5VL_file_cont_info_t *);
131
132 /* Retrieve the file's container info */
133 if (H5F__get_cont_info((H5F_t *)obj, info) < 0)
134 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file container info")
135
136 break;
137 }
138
139 /* H5Fget_access_plist */
140 case H5VL_FILE_GET_FAPL: {
141 H5P_genplist_t *new_plist; /* New property list */
142 hid_t * plist_id = HDva_arg(arguments, hid_t *);
143
144 f = (H5F_t *)obj;
145
146 /* Retrieve the file's access property list */
147 if ((*plist_id = H5F_get_access_plist(f, TRUE)) < 0)
148 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file access property list")
149
150 if (NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id)))
151 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
152 break;
153 }
154
155 /* H5Fget_create_plist */
156 case H5VL_FILE_GET_FCPL: {
157 H5P_genplist_t *plist; /* Property list */
158 hid_t * plist_id = HDva_arg(arguments, hid_t *);
159
160 f = (H5F_t *)obj;
161 if (NULL == (plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id)))
162 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
163
164 /* Create the property list object to return */
165 if ((*plist_id = H5P_copy_plist(plist, TRUE)) < 0)
166 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy file creation properties")
167
168 break;
169 }
170
171 /* H5Fget_intent */
172 case H5VL_FILE_GET_INTENT: {
173 unsigned *intent_flags = HDva_arg(arguments, unsigned *);
174
175 f = (H5F_t *)obj;
176
177 /* HDF5 uses some flags internally that users don't know about.
178 * Simplify things for them so that they only get either H5F_ACC_RDWR
179 * or H5F_ACC_RDONLY and any SWMR flags.
180 */
181 if (H5F_INTENT(f) & H5F_ACC_RDWR) {
182 *intent_flags = H5F_ACC_RDWR;
183
184 /* Check for SWMR write access on the file */
185 if (H5F_INTENT(f) & H5F_ACC_SWMR_WRITE)
186 *intent_flags |= H5F_ACC_SWMR_WRITE;
187 } /* end if */
188 else {
189 *intent_flags = H5F_ACC_RDONLY;
190
191 /* Check for SWMR read access on the file */
192 if (H5F_INTENT(f) & H5F_ACC_SWMR_READ)
193 *intent_flags |= H5F_ACC_SWMR_READ;
194 } /* end else */
195
196 break;
197 }
198
199 /* H5Fget_fileno */
200 case H5VL_FILE_GET_FILENO: {
201 unsigned long *fno = HDva_arg(arguments, unsigned long *);
202 unsigned long my_fileno = 0;
203
204 f = (H5F_t *)obj;
205 H5F_GET_FILENO(f, my_fileno);
206 *fno = my_fileno; /* sigh */
207
208 break;
209 }
210
211 /* H5Fget_name */
212 case H5VL_FILE_GET_NAME: {
213 H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */
214 size_t size = HDva_arg(arguments, size_t);
215 char * name = HDva_arg(arguments, char *);
216 ssize_t * ret = HDva_arg(arguments, ssize_t *);
217 size_t len;
218
219 if (H5VL_native_get_file_struct(obj, type, &f) < 0)
220 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
221
222 len = HDstrlen(H5F_OPEN_NAME(f));
223
224 if (name) {
225 HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1, size));
226 if (len >= size)
227 name[size - 1] = '\0';
228 } /* end if */
229
230 /* Set the return value for the API call */
231 *ret = (ssize_t)len;
232 break;
233 }
234
235 /* H5Fget_obj_count */
236 case H5VL_FILE_GET_OBJ_COUNT: {
237 unsigned types = HDva_arg(arguments, unsigned);
238 ssize_t *ret = HDva_arg(arguments, ssize_t *);
239 size_t obj_count = 0; /* Number of opened objects */
240
241 f = (H5F_t *)obj;
242 /* Perform the query */
243 if (H5F_get_obj_count(f, types, TRUE, &obj_count) < 0)
244 HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
245
246 /* Set the return value */
247 *ret = (ssize_t)obj_count;
248 break;
249 }
250
251 /* H5Fget_obj_ids */
252 case H5VL_FILE_GET_OBJ_IDS: {
253 unsigned types = HDva_arg(arguments, unsigned);
254 size_t max_objs = HDva_arg(arguments, size_t);
255 hid_t * oid_list = HDva_arg(arguments, hid_t *);
256 ssize_t *ret = HDva_arg(arguments, ssize_t *);
257 size_t obj_count = 0; /* Number of opened objects */
258
259 f = (H5F_t *)obj;
260 /* Perform the query */
261 if (H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0)
262 HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "H5F_get_obj_ids failed")
263
264 /* Set the return value */
265 *ret = (ssize_t)obj_count;
266 break;
267 }
268
269 default:
270 HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information")
271 } /* end switch */
272
273 done:
274 FUNC_LEAVE_NOAPI(ret_value)
275 } /* end H5VL__native_file_get() */
276
277 /*-------------------------------------------------------------------------
278 * Function: H5VL__native_file_specific
279 *
280 * Purpose: Handles the file specific callback
281 *
282 * Return: SUCCEED/FAIL
283 *
284 *-------------------------------------------------------------------------
285 */
286 herr_t
H5VL__native_file_specific(void * obj,H5VL_file_specific_t specific_type,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req,va_list arguments)287 H5VL__native_file_specific(void *obj, H5VL_file_specific_t specific_type, hid_t H5_ATTR_UNUSED dxpl_id,
288 void H5_ATTR_UNUSED **req, va_list arguments)
289 {
290 herr_t ret_value = SUCCEED; /* Return value */
291
292 FUNC_ENTER_PACKAGE
293
294 switch (specific_type) {
295 /* H5Fflush */
296 case H5VL_FILE_FLUSH: {
297 H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */
298 H5F_scope_t scope = (H5F_scope_t)HDva_arg(arguments, int); /* enum work-around */
299 H5F_t * f = NULL; /* File to flush */
300
301 /* Get the file for the object */
302 if (H5VL_native_get_file_struct(obj, type, &f) < 0)
303 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
304
305 /* Nothing to do if the file is read only. This determination is
306 * made at the shared open(2) flags level, implying that opening a
307 * file twice, once for read-only and once for read-write, and then
308 * calling H5Fflush() with the read-only handle, still causes data
309 * to be flushed.
310 */
311 if (H5F_ACC_RDWR & H5F_INTENT(f)) {
312 /* Flush other files, depending on scope */
313 if (H5F_SCOPE_GLOBAL == scope) {
314 /* Call the flush routine for mounted file hierarchies */
315 if (H5F_flush_mounts(f) < 0)
316 HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy")
317 } /* end if */
318 else {
319 /* Call the flush routine, for this file */
320 if (H5F__flush(f) < 0)
321 HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL,
322 "unable to flush file's cached information")
323 } /* end else */
324 } /* end if */
325 break;
326 }
327
328 /* H5Freopen */
329 case H5VL_FILE_REOPEN: {
330 void **ret = HDva_arg(arguments, void **);
331 H5F_t *new_file = NULL;
332
333 /* Reopen the file through the VOL connector */
334 if (NULL == (new_file = H5F__reopen((H5F_t *)obj)))
335 HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file")
336 new_file->id_exists = TRUE;
337
338 *ret = (void *)new_file;
339 break;
340 }
341
342 /* H5Fmount */
343 case H5VL_FILE_MOUNT: {
344 H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */
345 const char *name = HDva_arg(arguments, const char *);
346 H5F_t * child = HDva_arg(arguments, H5F_t *);
347 hid_t fmpl_id = HDva_arg(arguments, hid_t);
348 H5G_loc_t loc;
349
350 if (H5G_loc_real(obj, type, &loc) < 0)
351 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
352
353 /* Do the mount */
354 if (H5F__mount(&loc, name, child, fmpl_id) < 0)
355 HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file")
356
357 break;
358 }
359
360 /* H5Funmount */
361 case H5VL_FILE_UNMOUNT: {
362 H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */
363 const char *name = HDva_arg(arguments, const char *);
364 H5G_loc_t loc;
365
366 if (H5G_loc_real(obj, type, &loc) < 0)
367 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
368
369 /* Unmount */
370 if (H5F__unmount(&loc, name) < 0)
371 HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file")
372
373 break;
374 }
375
376 /* H5Fis_accessible */
377 case H5VL_FILE_IS_ACCESSIBLE: {
378 hid_t fapl_id = HDva_arg(arguments, hid_t);
379 const char *name = HDva_arg(arguments, const char *);
380 htri_t * result = HDva_arg(arguments, htri_t *);
381
382 /* Call private routine */
383 if ((*result = H5F__is_hdf5(name, fapl_id)) < 0)
384 HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "error in HDF5 file check")
385 break;
386 }
387
388 /* H5Fdelete */
389 case H5VL_FILE_DELETE: {
390 HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL,
391 "H5Fdelete() is currently not supported in the native VOL connector")
392 break;
393 }
394
395 /* Check if two files are the same */
396 case H5VL_FILE_IS_EQUAL: {
397 H5F_t * file2 = (H5F_t *)HDva_arg(arguments, void *);
398 hbool_t *is_equal = HDva_arg(arguments, hbool_t *);
399
400 if (!obj || !file2)
401 *is_equal = FALSE;
402 else
403 *is_equal = (((H5F_t *)obj)->shared == file2->shared);
404 break;
405 }
406
407 default:
408 HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation")
409 } /* end switch */
410
411 done:
412 FUNC_LEAVE_NOAPI(ret_value)
413 } /* end H5VL__native_file_specific() */
414
415 /*-------------------------------------------------------------------------
416 * Function: H5VL__native_file_optional
417 *
418 * Purpose: Handles the file optional callback
419 *
420 * Return: SUCCEED/FAIL
421 *
422 *-------------------------------------------------------------------------
423 */
424 herr_t
H5VL__native_file_optional(void * obj,H5VL_file_optional_t optional_type,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req,va_list arguments)425 H5VL__native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t H5_ATTR_UNUSED dxpl_id,
426 void H5_ATTR_UNUSED **req, va_list arguments)
427 {
428 H5F_t *f = NULL; /* File */
429 herr_t ret_value = SUCCEED; /* Return value */
430
431 FUNC_ENTER_PACKAGE
432
433 f = (H5F_t *)obj;
434 switch (optional_type) {
435 /* H5Fget_filesize */
436 case H5VL_NATIVE_FILE_GET_SIZE: {
437 haddr_t max_eof_eoa; /* Maximum of the EOA & EOF */
438 haddr_t base_addr; /* Base address for the file */
439 hsize_t *size = HDva_arg(arguments, hsize_t *);
440
441 /* Go get the actual file size */
442 if (H5F__get_max_eof_eoa(f, &max_eof_eoa) < 0)
443 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ")
444
445 base_addr = H5FD_get_base_addr(f->shared->lf);
446
447 if (size)
448 *size = (hsize_t)(max_eof_eoa +
449 base_addr); /* Convert relative base address for file to absolute address */
450
451 break;
452 }
453
454 /* H5Fget_file_image */
455 case H5VL_NATIVE_FILE_GET_FILE_IMAGE: {
456 void * buf_ptr = HDva_arg(arguments, void *);
457 ssize_t *ret = HDva_arg(arguments, ssize_t *);
458 size_t buf_len = HDva_arg(arguments, size_t);
459
460 /* Do the actual work */
461 if ((*ret = H5F__get_file_image(f, buf_ptr, buf_len)) < 0)
462 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get file image failed")
463 break;
464 }
465
466 /* H5Fget_freespace */
467 case H5VL_NATIVE_FILE_GET_FREE_SPACE: {
468 hsize_t tot_space; /* Amount of free space in the file */
469 hssize_t *ret = HDva_arg(arguments, hssize_t *);
470
471 /* Go get the actual amount of free space in the file */
472 if (H5MF_get_freespace(f, &tot_space, NULL) < 0)
473 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file")
474 *ret = (hssize_t)tot_space;
475 break;
476 }
477
478 /* H5Fget_free_sections */
479 case H5VL_NATIVE_FILE_GET_FREE_SECTIONS: {
480 H5F_sect_info_t *sect_info = HDva_arg(arguments, H5F_sect_info_t *);
481 ssize_t * ret = HDva_arg(arguments, ssize_t *);
482 H5F_mem_t type = (H5F_mem_t)HDva_arg(arguments, int); /* enum work-around */
483 size_t nsects = HDva_arg(arguments, size_t);
484
485 /* Go get the free-space section information in the file */
486 if ((*ret = H5MF_get_free_sections(f, type, nsects, sect_info)) < 0)
487 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file")
488 break;
489 }
490
491 /* H5Fget_info1/2 */
492 case H5VL_NATIVE_FILE_GET_INFO: {
493 H5I_type_t type = (H5I_type_t)HDva_arg(arguments, int); /* enum work-around */
494 H5F_info2_t *finfo = HDva_arg(arguments, H5F_info2_t *);
495
496 /* Get the file struct. This call is careful to not return the file pointer
497 * for the top file in a mount hierarchy.
498 */
499 if (H5VL_native_get_file_struct(obj, type, &f) < 0)
500 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "could not get a file struct")
501
502 /* Get the file info */
503 if (H5F__get_info(f, finfo) < 0)
504 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to retrieve file info")
505
506 break;
507 }
508
509 /* H5Fget_mdc_config */
510 case H5VL_NATIVE_FILE_GET_MDC_CONF: {
511 H5AC_cache_config_t *config_ptr = HDva_arg(arguments, H5AC_cache_config_t *);
512
513 /* Go get the resize configuration */
514 if (H5AC_get_cache_auto_resize_config(f->shared->cache, config_ptr) < 0)
515 HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_auto_resize_config() failed.")
516 break;
517 }
518
519 /* H5Fget_mdc_hit_rate */
520 case H5VL_NATIVE_FILE_GET_MDC_HR: {
521 double *hit_rate_ptr = HDva_arg(arguments, double *);
522
523 /* Go get the current hit rate */
524 if (H5AC_get_cache_hit_rate(f->shared->cache, hit_rate_ptr) < 0)
525 HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_hit_rate() failed.")
526 break;
527 }
528
529 /* H5Fget_mdc_size */
530 case H5VL_NATIVE_FILE_GET_MDC_SIZE: {
531 size_t * max_size_ptr = HDva_arg(arguments, size_t *);
532 size_t * min_clean_size_ptr = HDva_arg(arguments, size_t *);
533 size_t * cur_size_ptr = HDva_arg(arguments, size_t *);
534 int * cur_num_entries_ptr = HDva_arg(arguments, int *);
535 uint32_t cur_num_entries;
536
537 /* Go get the size data */
538 if (H5AC_get_cache_size(f->shared->cache, max_size_ptr, min_clean_size_ptr, cur_size_ptr,
539 &cur_num_entries) < 0)
540 HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_size() failed.")
541
542 if (cur_num_entries_ptr != NULL)
543 *cur_num_entries_ptr = (int)cur_num_entries;
544 break;
545 }
546
547 /* H5Fget_vfd_handle */
548 case H5VL_NATIVE_FILE_GET_VFD_HANDLE: {
549 void **file_handle = HDva_arg(arguments, void **);
550 hid_t fapl_id = HDva_arg(arguments, hid_t);
551
552 /* Retrieve the VFD handle for the file */
553 if (H5F_get_vfd_handle(f, fapl_id, file_handle) < 0)
554 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle")
555 break;
556 }
557
558 /* H5Fclear_elink_file_cache */
559 case H5VL_NATIVE_FILE_CLEAR_ELINK_CACHE: {
560 /* Release the EFC */
561 if (f->shared->efc)
562 if (H5F__efc_release(f->shared->efc) < 0)
563 HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache")
564 break;
565 }
566
567 /* H5Freset_mdc_hit_rate_stats */
568 case H5VL_NATIVE_FILE_RESET_MDC_HIT_RATE: {
569 /* Reset the hit rate statistic */
570 if (H5AC_reset_cache_hit_rate_stats(f->shared->cache) < 0)
571 HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't reset cache hit rate")
572 break;
573 }
574
575 /* H5Fset_mdc_config */
576 case H5VL_NATIVE_FILE_SET_MDC_CONFIG: {
577 H5AC_cache_config_t *config_ptr = HDva_arg(arguments, H5AC_cache_config_t *);
578
579 /* set the resize configuration */
580 if (H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0)
581 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "H5AC_set_cache_auto_resize_config() failed")
582 break;
583 }
584
585 /* H5Fget_metadata_read_retry_info */
586 case H5VL_NATIVE_FILE_GET_METADATA_READ_RETRY_INFO: {
587 H5F_retry_info_t *info = HDva_arg(arguments, H5F_retry_info_t *);
588
589 if (H5F_get_metadata_read_retry_info(f, info) < 0)
590 HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't get metadata read retry info")
591
592 break;
593 }
594
595 /* H5Fstart_swmr_write */
596 case H5VL_NATIVE_FILE_START_SWMR_WRITE: {
597 if (H5F__start_swmr_write(f) < 0)
598 HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't start SWMR write")
599
600 break;
601 }
602
603 /* H5Fstart_mdc_logging */
604 case H5VL_NATIVE_FILE_START_MDC_LOGGING: {
605 /* Call mdc logging function */
606 if (H5C_start_logging(f->shared->cache) < 0)
607 HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to start mdc logging")
608
609 break;
610 }
611
612 /* H5Fstop_mdc_logging */
613 case H5VL_NATIVE_FILE_STOP_MDC_LOGGING: {
614 /* Call mdc logging function */
615 if (H5C_stop_logging(f->shared->cache) < 0)
616 HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to stop mdc logging")
617
618 break;
619 }
620
621 /* H5Fget_mdc_logging_status */
622 case H5VL_NATIVE_FILE_GET_MDC_LOGGING_STATUS: {
623 hbool_t *is_enabled = HDva_arg(arguments, hbool_t *);
624 hbool_t *is_currently_logging = HDva_arg(arguments, hbool_t *);
625
626 /* Call mdc logging function */
627 if (H5C_get_logging_status(f->shared->cache, is_enabled, is_currently_logging) < 0)
628 HGOTO_ERROR(H5E_FILE, H5E_LOGGING, FAIL, "unable to get logging status")
629
630 break;
631 }
632
633 /* H5Fformat_convert */
634 case H5VL_NATIVE_FILE_FORMAT_CONVERT: {
635 /* Convert the format */
636 if (H5F__format_convert(f) < 0)
637 HGOTO_ERROR(H5E_FILE, H5E_CANTCONVERT, FAIL, "can't convert file format")
638
639 break;
640 }
641
642 /* H5Freset_page_buffering_stats */
643 case H5VL_NATIVE_FILE_RESET_PAGE_BUFFERING_STATS: {
644 /* Sanity check */
645 if (NULL == f->shared->page_buf)
646 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "page buffering not enabled on file")
647
648 /* Reset the statistics */
649 if (H5PB_reset_stats(f->shared->page_buf) < 0)
650 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't reset stats for page buffering")
651
652 break;
653 }
654
655 /* H5Fget_page_buffering_stats */
656 case H5VL_NATIVE_FILE_GET_PAGE_BUFFERING_STATS: {
657 unsigned *accesses = HDva_arg(arguments, unsigned *);
658 unsigned *hits = HDva_arg(arguments, unsigned *);
659 unsigned *misses = HDva_arg(arguments, unsigned *);
660 unsigned *evictions = HDva_arg(arguments, unsigned *);
661 unsigned *bypasses = HDva_arg(arguments, unsigned *);
662
663 /* Sanity check */
664 if (NULL == f->shared->page_buf)
665 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "page buffering not enabled on file")
666
667 /* Get the statistics */
668 if (H5PB_get_stats(f->shared->page_buf, accesses, hits, misses, evictions, bypasses) < 0)
669 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stats for page buffering")
670
671 break;
672 }
673
674 /* H5Fget_mdc_image_info */
675 case H5VL_NATIVE_FILE_GET_MDC_IMAGE_INFO: {
676 haddr_t *image_addr = HDva_arg(arguments, haddr_t *);
677 hsize_t *image_len = HDva_arg(arguments, hsize_t *);
678
679 /* Go get the address and size of the cache image */
680 if (H5AC_get_mdc_image_info(f->shared->cache, image_addr, image_len) < 0)
681 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve cache image info")
682
683 break;
684 }
685
686 /* H5Fget_eoa */
687 case H5VL_NATIVE_FILE_GET_EOA: {
688 haddr_t *eoa = HDva_arg(arguments, haddr_t *);
689 haddr_t rel_eoa; /* Relative address of EOA */
690
691 /* Sanity check */
692 HDassert(eoa);
693
694 /* This routine will work only for drivers with this feature enabled.*/
695 /* We might introduce a new feature flag in the future */
696 if (!H5F_HAS_FEATURE(f, H5FD_FEAT_SUPPORTS_SWMR_IO))
697 HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL,
698 "must use a SWMR-compatible VFD for this public routine")
699
700 /* The real work */
701 if (HADDR_UNDEF == (rel_eoa = H5F_get_eoa(f, H5FD_MEM_DEFAULT)))
702 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get_eoa request failed")
703
704 /* Set return value */
705 /* (Note compensating for base address subtraction in internal routine) */
706 *eoa = rel_eoa + H5F_get_base_addr(f);
707
708 break;
709 }
710
711 /* H5Fincrement_filesize */
712 case H5VL_NATIVE_FILE_INCR_FILESIZE: {
713 hsize_t increment = HDva_arg(arguments, hsize_t);
714 haddr_t max_eof_eoa; /* Maximum of the relative EOA & EOF */
715
716 /* This public routine will work only for drivers with this feature enabled.*/
717 /* We might introduce a new feature flag in the future */
718 if (!H5F_HAS_FEATURE(f, H5FD_FEAT_SUPPORTS_SWMR_IO))
719 HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL,
720 "must use a SWMR-compatible VFD for this public routine")
721
722 /* Get the maximum of EOA and EOF */
723 if (H5F__get_max_eof_eoa(f, &max_eof_eoa) < 0)
724 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "file can't get max eof/eoa ")
725
726 /* Set EOA to the maximum value + increment */
727 if (H5F__set_eoa(f, H5FD_MEM_DEFAULT, max_eof_eoa + increment) < 0)
728 HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "driver set_eoa request failed")
729
730 break;
731 }
732
733 /* H5Fset_latest_format, H5Fset_libver_bounds */
734 case H5VL_NATIVE_FILE_SET_LIBVER_BOUNDS: {
735 H5F_libver_t low = (H5F_libver_t)HDva_arg(arguments, int); /* enum work-around */
736 H5F_libver_t high = (H5F_libver_t)HDva_arg(arguments, int); /* enum work-around */
737
738 /* Call internal set_libver_bounds function */
739 if (H5F__set_libver_bounds(f, low, high) < 0)
740 HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set low/high bounds")
741
742 break;
743 }
744
745 /* H5Fget_dset_no_attrs_hint */
746 case H5VL_NATIVE_FILE_GET_MIN_DSET_OHDR_FLAG: {
747 hbool_t *minimize = HDva_arg(arguments, hbool_t *);
748 *minimize = H5F_GET_MIN_DSET_OHDR(f);
749 break;
750 }
751
752 /* H5Fset_dset_no_attrs_hint */
753 case H5VL_NATIVE_FILE_SET_MIN_DSET_OHDR_FLAG: {
754 int minimize = HDva_arg(arguments, int);
755 if (H5F_set_min_dset_ohdr(f, (hbool_t)minimize) < 0)
756 HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL,
757 "cannot set file's dataset object header minimization flag")
758 break;
759 }
760
761 #ifdef H5_HAVE_PARALLEL
762 /* H5Fget_mpi_atomicity */
763 case H5VL_NATIVE_FILE_GET_MPI_ATOMICITY: {
764 hbool_t *flag = (hbool_t *)HDva_arg(arguments, hbool_t *);
765 if (H5F_get_mpi_atomicity(f, flag) < 0)
766 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "cannot get MPI atomicity");
767 break;
768 }
769
770 /* H5Fset_mpi_atomicity */
771 case H5VL_NATIVE_FILE_SET_MPI_ATOMICITY: {
772 hbool_t flag = (hbool_t)HDva_arg(arguments, int);
773 if (H5F_set_mpi_atomicity(f, flag) < 0)
774 HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "cannot set MPI atomicity");
775 break;
776 }
777 #endif /* H5_HAVE_PARALLEL */
778
779 /* Finalize H5Fopen */
780 case H5VL_NATIVE_FILE_POST_OPEN: {
781 /* Call package routine */
782 if (H5F__post_open((H5F_t *)obj) < 0)
783 HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't finish opening file")
784 break;
785 }
786
787 default:
788 HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid optional operation")
789 } /* end switch */
790
791 done:
792 FUNC_LEAVE_NOAPI(ret_value)
793 } /* end H5VL__native_file_optional() */
794
795 /*-------------------------------------------------------------------------
796 * Function: H5VL__native_file_close
797 *
798 * Purpose: Handles the file close callback
799 *
800 * Return: Success: SUCCEED
801 * Failure: FAIL (file will not be closed)
802 *
803 *-------------------------------------------------------------------------
804 */
805 herr_t
H5VL__native_file_close(void * file,hid_t H5_ATTR_UNUSED dxpl_id,void H5_ATTR_UNUSED ** req)806 H5VL__native_file_close(void *file, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req)
807 {
808 int nref;
809 H5F_t *f = (H5F_t *)file;
810 hid_t file_id = H5I_INVALID_HID;
811 herr_t ret_value = SUCCEED; /* Return value */
812
813 FUNC_ENTER_PACKAGE
814
815 /* This routine should only be called when a file ID's ref count drops to zero */
816 HDassert(H5F_ID_EXISTS(f));
817
818 /* Flush file if this is the last reference to this id and we have write
819 * intent, unless it will be flushed by the "shared" file being closed.
820 * This is only necessary to replicate previous behaviour, and could be
821 * disabled by an option/property to improve performance.
822 */
823 if ((H5F_NREFS(f) > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) {
824 /* Get the file ID corresponding to the H5F_t struct */
825 if (H5I_find_id(f, H5I_FILE, &file_id) < 0 || H5I_INVALID_HID == file_id)
826 HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "invalid atom")
827
828 /* Get the number of references outstanding for this file ID */
829 if ((nref = H5I_get_ref(file_id, FALSE)) < 0)
830 HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count")
831 if (nref == 1)
832 if (H5F__flush(f) < 0)
833 HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
834 } /* end if */
835
836 /* Close the file */
837 if (H5F__close(f) < 0)
838 HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close file")
839
840 done:
841 FUNC_LEAVE_NOAPI(ret_value)
842 } /* end H5VL__native_file_close() */
843