1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the files COPYING and Copyright.html. COPYING can be found at the root *
9 * of the source code distribution tree; Copyright.html can be found at the *
10 * root level of an installed copy of the electronic HDF5 document set and *
11 * is linked from the top-level documents page. It can also be found at *
12 * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
13 * access to either file, you may request a copy from help@hdfgroup.org. *
14 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15
16 /*
17 * Programmer: Robb Matzke <matzke@llnl.gov>
18 * Monday, July 26, 1999
19 *
20 * Purpose: The Virtual File Layer as described in documentation.
21 * This is the greatest common denominator for all types of
22 * storage access whether a file, memory, network, etc. This
23 * layer usually just dispatches the request to an actual
24 * file driver layer.
25 */
26
27 /****************/
28 /* Module Setup */
29 /****************/
30
31 #define H5F_PACKAGE /*suppress error about including H5Fpkg */
32 #define H5FD_PACKAGE /*suppress error about including H5FDpkg */
33
34 /* Interface initialization */
35 #define H5_INTERFACE_INIT_FUNC H5FD_init_interface
36
37
38 /***********/
39 /* Headers */
40 /***********/
41 #include "H5private.h" /* Generic Functions */
42 #include "H5Dprivate.h" /* Datasets */
43 #include "H5Eprivate.h" /* Error handling */
44 #include "H5Fpkg.h" /* File access */
45 #include "H5FDpkg.h" /* File Drivers */
46 #include "H5FDcore.h" /* Files stored entirely in memory */
47 #include "H5FDfamily.h" /* File families */
48 #include "H5FDlog.h" /* sec2 driver with I/O logging (for debugging) */
49 #include "H5FDmpi.h" /* MPI-based file drivers */
50 #include "H5FDmulti.h" /* Usage-partitioned file family */
51 #include "H5FDsec2.h" /* POSIX unbuffered file I/O */
52 #include "H5FDstdio.h" /* Standard C buffered I/O */
53 #ifdef H5_HAVE_WINDOWS
54 #include "H5FDwindows.h" /* Windows buffered I/O */
55 #endif
56 #include "H5FDdirect.h" /* Direct file I/O */
57 #include "H5Iprivate.h" /* IDs */
58 #include "H5MMprivate.h" /* Memory management */
59 #include "H5Pprivate.h" /* Property lists */
60
61 /****************/
62 /* Local Macros */
63 /****************/
64
65
66 /******************/
67 /* Local Typedefs */
68 /******************/
69
70
71 /********************/
72 /* Package Typedefs */
73 /********************/
74
75
76 /********************/
77 /* Local Prototypes */
78 /********************/
79 static herr_t H5FD_pl_copy(void *(*copy_func)(const void *), size_t pl_size,
80 const void *old_pl, void **copied_pl);
81 static herr_t H5FD_pl_close(hid_t driver_id, herr_t (*free_func)(void *),
82 void *pl);
83 static herr_t H5FD_free_cls(H5FD_class_t *cls);
84 static herr_t H5FD_fapl_copy(hid_t driver_id, const void *fapl, void **copied_fapl);
85 static int H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/);
86 static int H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags/*out*/);
87
88 /*********************/
89 /* Package Variables */
90 /*********************/
91
92
93 /*****************************/
94 /* Library Private Variables */
95 /*****************************/
96
97
98 /*******************/
99 /* Local Variables */
100 /*******************/
101
102 /*
103 * Global count of the number of H5FD_t's handed out. This is used as a
104 * "serial number" for files that are currently open and is used for the
105 * 'fileno' field in H5O_info_t. However, if a VFL driver is not able
106 * to detect whether two files are the same, a file that has been opened
107 * by H5Fopen more than once with that VFL driver will have two different
108 * serial numbers. :-/
109 *
110 * Also, if a file is opened, the 'fileno' field is retrieved for an
111 * object and the file is closed and re-opened, the 'fileno' value will
112 * be different.
113 */
114 static unsigned long file_serial_no;
115
116 /* File driver ID class */
117 static const H5I_class_t H5I_VFL_CLS[1] = {{
118 H5I_VFL, /* ID class value */
119 H5I_CLASS_REUSE_IDS, /* Class flags */
120 0, /* # of reserved IDs for class */
121 (H5I_free_t)H5FD_free_cls /* Callback routine for closing objects of this class */
122 }};
123
124
125
126 /*-------------------------------------------------------------------------
127 * Function: H5FD_init
128 *
129 * Purpose: Initialize the interface from some other package.
130 *
131 * Return: Success: non-negative
132 * Failure: negative
133 *
134 * Programmer: Quincey Koziol
135 * Thursday, January 3, 2007
136 *
137 *-------------------------------------------------------------------------
138 */
139 herr_t
H5FD_init(void)140 H5FD_init(void)
141 {
142 herr_t ret_value = SUCCEED; /* Return value */
143
144 FUNC_ENTER_NOAPI(FAIL)
145 /* FUNC_ENTER() does all the work */
146
147 done:
148 FUNC_LEAVE_NOAPI(ret_value)
149 } /* end H5FD_init() */
150
151
152 /*-------------------------------------------------------------------------
153 * Function: H5FD_init_interface
154 *
155 * Purpose: Initialize the virtual file layer.
156 *
157 * Return: Success: Non-negative
158 *
159 * Failure: Negative
160 *
161 * Programmer: Robb Matzke
162 * Monday, July 26, 1999
163 *
164 * Modifications:
165 *
166 *-------------------------------------------------------------------------
167 */
168 static herr_t
H5FD_init_interface(void)169 H5FD_init_interface(void)
170 {
171 herr_t ret_value = SUCCEED; /* Return value */
172
173 FUNC_ENTER_NOAPI_NOINIT
174
175 if(H5I_register_type(H5I_VFL_CLS) < 0)
176 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize interface")
177
178 /* Reset the file serial numbers */
179 file_serial_no = 0;
180
181 done:
182 FUNC_LEAVE_NOAPI(ret_value)
183 } /* end H5FD_init_interface() */
184
185
186 /*-------------------------------------------------------------------------
187 * Function: H5FD_term_interface
188 *
189 * Purpose: Terminate this interface: free all memory and reset global
190 * variables to their initial values. Release all ID groups
191 * associated with this interface.
192 *
193 * Return: Success: Positive if anything was done that might
194 * have affected other interfaces; zero
195 * otherwise.
196 *
197 * Failure: Never fails.
198 *
199 * Programmer: Robb Matzke
200 * Friday, February 19, 1999
201 *
202 * Modifications:
203 *
204 *-------------------------------------------------------------------------
205 */
206 int
H5FD_term_interface(void)207 H5FD_term_interface(void)
208 {
209 int n = 0;
210
211 FUNC_ENTER_NOAPI_NOINIT_NOERR
212
213 if(H5_interface_initialize_g) {
214 if((n=H5I_nmembers(H5I_VFL))!=0) {
215 H5I_clear_type(H5I_VFL, FALSE, FALSE);
216
217 /* Reset the VFL drivers, if they've been closed */
218 if(H5I_nmembers(H5I_VFL)==0) {
219 H5FD_sec2_term();
220 #ifdef H5_HAVE_DIRECT
221 H5FD_direct_term();
222 #endif
223 H5FD_log_term();
224 H5FD_stdio_term();
225 #ifdef H5_HAVE_WINDOWS
226 H5FD_windows_term();
227 #endif
228 H5FD_family_term();
229 H5FD_core_term();
230 H5FD_multi_term();
231 #ifdef H5_HAVE_PARALLEL
232 H5FD_mpio_term();
233 #endif /* H5_HAVE_PARALLEL */
234 } /* end if */
235 } else {
236 H5I_dec_type_ref(H5I_VFL);
237 H5_interface_initialize_g = 0;
238 n = 1; /*H5I*/
239 }
240 }
241 FUNC_LEAVE_NOAPI(n)
242 }
243
244
245 /*-------------------------------------------------------------------------
246 * Function: H5FD_free_cls
247 *
248 * Purpose: Frees a file driver class struct and returns an indication of
249 * success. This function is used as the free callback for the
250 * virtual file layer object identifiers (cf H5FD_init_interface).
251 *
252 * Return: Success: Non-negative
253 *
254 * Failure: Negative
255 *
256 * Programmer: Robb Matzke
257 * Monday, July 26, 1999
258 *
259 * Modifications:
260 *
261 *-------------------------------------------------------------------------
262 */
263 static herr_t
H5FD_free_cls(H5FD_class_t * cls)264 H5FD_free_cls(H5FD_class_t *cls)
265 {
266 FUNC_ENTER_NOAPI_NOINIT_NOERR
267
268 H5MM_xfree(cls);
269
270 FUNC_LEAVE_NOAPI(SUCCEED)
271 } /* end H5FD_free_cls() */
272
273
274 /*-------------------------------------------------------------------------
275 * Function: H5FDregister
276 *
277 * Purpose: Registers a new file driver as a member of the virtual file
278 * driver class. Certain fields of the class struct are
279 * required and that is checked here so it doesn't have to be
280 * checked every time the field is accessed.
281 *
282 * Return: Success: A file driver ID which is good until the
283 * library is closed or the driver is
284 * unregistered.
285 *
286 * Failure: A negative value.
287 *
288 * Programmer: Robb Matzke
289 * Monday, July 26, 1999
290 *
291 * Modifications:
292 * Copied guts of function into H5FD_register
293 * Quincey Koziol
294 * Friday, January 30, 2004
295 *
296 *-------------------------------------------------------------------------
297 */
298 hid_t
H5FDregister(const H5FD_class_t * cls)299 H5FDregister(const H5FD_class_t *cls)
300 {
301 hid_t ret_value;
302 H5FD_mem_t type;
303
304 FUNC_ENTER_API(FAIL)
305 H5TRACE1("i", "*x", cls);
306
307 /* Check arguments */
308 if(!cls)
309 HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "null class pointer is disallowed")
310 if(!cls->open || !cls->close)
311 HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`open' and/or `close' methods are not defined")
312 if(!cls->get_eoa || !cls->set_eoa)
313 HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`get_eoa' and/or `set_eoa' methods are not defined")
314 if(!cls->get_eof)
315 HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`get_eof' method is not defined")
316 if(!cls->read || !cls->write)
317 HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "`read' and/or `write' method is not defined")
318 for (type=H5FD_MEM_DEFAULT; type<H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,type))
319 if(cls->fl_map[type]<H5FD_MEM_NOLIST || cls->fl_map[type]>=H5FD_MEM_NTYPES)
320 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid free-list mapping")
321
322 /* Create the new class ID */
323 if((ret_value=H5FD_register(cls, sizeof(H5FD_class_t), TRUE)) < 0)
324 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register file driver ID")
325
326 done:
327 FUNC_LEAVE_API(ret_value)
328 } /* end H5FDregister() */
329
330
331 /*-------------------------------------------------------------------------
332 * Function: H5FD_register
333 *
334 * Purpose: Registers a new file driver as a member of the virtual file
335 * driver class. Certain fields of the class struct are
336 * required and that is checked here so it doesn't have to be
337 * checked every time the field is accessed.
338 *
339 * Return: Success: A file driver ID which is good until the
340 * library is closed or the driver is
341 * unregistered.
342 *
343 * Failure: A negative value.
344 *
345 * Programmer: Robb Matzke
346 * Monday, July 26, 1999
347 *
348 * Modifications:
349 * Broke into public and internal routines & added 'size'
350 * parameter to internal routine, which allows us to create
351 * sub-classes of H5FD_class_t for internal support (see the
352 * MPI drivers, etc.)
353 * Quincey Koziol
354 * January 30, 2004
355 *
356 *-------------------------------------------------------------------------
357 */
358 hid_t
H5FD_register(const void * _cls,size_t size,hbool_t app_ref)359 H5FD_register(const void *_cls, size_t size, hbool_t app_ref)
360 {
361 const H5FD_class_t *cls = (const H5FD_class_t *)_cls;
362 H5FD_class_t *saved = NULL;
363 H5FD_mem_t type;
364 hid_t ret_value;
365
366 FUNC_ENTER_NOAPI(FAIL)
367
368 /* Check arguments */
369 HDassert(cls);
370 HDassert(cls->open && cls->close);
371 HDassert(cls->get_eoa && cls->set_eoa);
372 HDassert(cls->get_eof);
373 HDassert(cls->read && cls->write);
374 for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t, type))
375 HDassert(cls->fl_map[type] >= H5FD_MEM_NOLIST && cls->fl_map[type] < H5FD_MEM_NTYPES);
376
377 /* Copy the class structure so the caller can reuse or free it */
378 if(NULL == (saved = (H5FD_class_t *)H5MM_malloc(size)))
379 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for file driver class struct")
380 HDmemcpy(saved, cls, size);
381
382 /* Create the new class ID */
383 if((ret_value = H5I_register(H5I_VFL, saved, app_ref)) < 0)
384 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register file driver ID")
385
386 done:
387 if(ret_value < 0)
388 if(saved)
389 H5MM_xfree(saved);
390
391 FUNC_LEAVE_NOAPI(ret_value)
392 } /* end H5FD_register() */
393
394
395 /*-------------------------------------------------------------------------
396 * Function: H5FDunregister
397 *
398 * Purpose: Removes a driver ID from the library. This in no way affects
399 * file access property lists which have been defined to use
400 * this driver or files which are already opened under this
401 * driver.
402 *
403 * Return: Success: Non-negative
404 *
405 * Failure: Negative
406 *
407 * Programmer: Robb Matzke
408 * Monday, July 26, 1999
409 *
410 *-------------------------------------------------------------------------
411 */
412 herr_t
H5FDunregister(hid_t driver_id)413 H5FDunregister(hid_t driver_id)
414 {
415 herr_t ret_value = SUCCEED; /* Return value */
416
417 FUNC_ENTER_API(FAIL)
418 H5TRACE1("e", "i", driver_id);
419
420 /* Check arguments */
421 if(NULL == H5I_object_verify(driver_id, H5I_VFL))
422 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file driver")
423
424 /* The H5FD_class_t struct will be freed by this function */
425 if(H5I_dec_app_ref(driver_id) < 0)
426 HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "unable to unregister file driver")
427
428 done:
429 FUNC_LEAVE_API(ret_value)
430 } /* end H5FDunregister() */
431
432
433 /*-------------------------------------------------------------------------
434 * Function: H5FD_get_class
435 *
436 * Purpose: Obtains a pointer to the driver struct containing all the
437 * callback pointers, etc. The PLIST_ID argument can be a file
438 * access property list, a data transfer property list, or a
439 * file driver identifier.
440 *
441 * Return: Success: Ptr to the driver information. The pointer is
442 * only valid as long as the driver remains
443 * registered or some file or property list
444 * exists which references the driver.
445 *
446 * Failure: NULL
447 *
448 * Programmer: Robb Matzke
449 * Friday, August 20, 1999
450 *
451 *-------------------------------------------------------------------------
452 */
453 H5FD_class_t *
H5FD_get_class(hid_t id)454 H5FD_get_class(hid_t id)
455 {
456 H5FD_class_t *ret_value = NULL;
457
458 FUNC_ENTER_NOAPI(NULL)
459
460 if(H5I_VFL == H5I_get_type(id))
461 ret_value = (H5FD_class_t *)H5I_object(id);
462 else {
463 H5P_genplist_t *plist; /* Property list pointer */
464 hid_t driver_id = -1;
465
466 /* Get the plist structure */
467 if(NULL == (plist = (H5P_genplist_t *)H5I_object(id)))
468 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID")
469
470 if(TRUE == H5P_isa_class(id, H5P_FILE_ACCESS)) {
471 if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0)
472 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID")
473 ret_value = H5FD_get_class(driver_id);
474 } /* end if */
475 else
476 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a driver id or file access property list")
477 } /* end if */
478
479 done:
480 FUNC_LEAVE_NOAPI(ret_value)
481 } /* end H5FD_get_class() */
482
483
484 /*-------------------------------------------------------------------------
485 * Function: H5FD_sb_size
486 *
487 * Purpose: Obtains the number of bytes required to store the driver file
488 * access data in the HDF5 superblock.
489 *
490 * Return: Success: Number of bytes required.
491 *
492 * Failure: 0 if an error occurs or if the driver has no
493 * data to store in the superblock.
494 *
495 * Programmer: Robb Matzke
496 * Monday, August 16, 1999
497 *
498 * Modifications:
499 *
500 *-------------------------------------------------------------------------
501 */
502 hsize_t
H5FD_sb_size(H5FD_t * file)503 H5FD_sb_size(H5FD_t *file)
504 {
505 hsize_t ret_value=0;
506
507 FUNC_ENTER_NOAPI(0)
508
509 HDassert(file && file->cls);
510
511 if(file->cls->sb_size)
512 ret_value = (file->cls->sb_size)(file);
513
514 done:
515 FUNC_LEAVE_NOAPI(ret_value)
516 }
517
518
519 /*-------------------------------------------------------------------------
520 * Function: H5FD_sb_encode
521 *
522 * Purpose: Encode driver-specific data into the output arguments. The
523 * NAME is a nine-byte buffer which should get an
524 * eight-character driver name and/or version followed by a null
525 * terminator. The BUF argument is a buffer to receive the
526 * encoded driver-specific data. The size of the BUF array is
527 * the size returned by the H5FD_sb_size() call.
528 *
529 * Return: Success: Non-negative
530 *
531 * Failure: Negative
532 *
533 * Programmer: Robb Matzke
534 * Monday, August 16, 1999
535 *
536 * Modifications:
537 *
538 *-------------------------------------------------------------------------
539 */
540 herr_t
H5FD_sb_encode(H5FD_t * file,char * name,uint8_t * buf)541 H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf)
542 {
543 herr_t ret_value=SUCCEED; /* Return value */
544
545 FUNC_ENTER_NOAPI(FAIL)
546
547 HDassert(file && file->cls);
548 if(file->cls->sb_encode &&
549 (file->cls->sb_encode)(file, name/*out*/, buf/*out*/) < 0)
550 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver sb_encode request failed")
551
552 done:
553 FUNC_LEAVE_NOAPI(ret_value)
554 }
555
556
557 /*-------------------------------------------------------------------------
558 * Function: H5FD_sb_decode
559 *
560 * Purpose: Decodes the driver information block.
561 *
562 * Return: Success: Non-negative
563 * Failure: Negative
564 *
565 * Programmer: Robb Matzke
566 * Monday, August 16, 1999
567 *
568 *-------------------------------------------------------------------------
569 */
570 herr_t
H5FD_sb_decode(H5FD_t * file,const char * name,const uint8_t * buf)571 H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf)
572 {
573 herr_t ret_value = SUCCEED; /* Return value */
574
575 FUNC_ENTER_NOAPI(FAIL)
576
577 HDassert(file && file->cls);
578 if(file->cls->sb_decode && (file->cls->sb_decode)(file, name, buf) < 0)
579 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver sb_decode request failed")
580
581 done:
582 FUNC_LEAVE_NOAPI(ret_value)
583 } /* end H5FD_sb_decode() */
584
585
586 /*-------------------------------------------------------------------------
587 * Function: H5FD_pl_copy
588 *
589 * Purpose: Copies the driver-specific part of the a property list.
590 * This is common code, used by both the dataset transfer and
591 * file access property list routines.
592 *
593 * Return: Success: non-negative
594 *
595 * Failure: negative
596 *
597 * Programmer: Quincey Koziol
598 * Thursday, October 23, 2003
599 *
600 * Modifications:
601 * Pedro Vicente Nunes, Wednesday, July 26, 2006
602 * added a HGOTO_ERROR call in the case the copy function returns NULL
603 *
604 *-------------------------------------------------------------------------
605 */
606 static herr_t
H5FD_pl_copy(void * (* copy_func)(const void *),size_t pl_size,const void * old_pl,void ** copied_pl)607 H5FD_pl_copy(void *(*copy_func)(const void *), size_t pl_size, const void *old_pl, void **copied_pl)
608 {
609 void *new_pl = NULL; /* Copy of property list */
610 herr_t ret_value=SUCCEED; /* Return value */
611
612 FUNC_ENTER_NOAPI_NOINIT
613
614 /* Copy old pl, if one exists */
615 if(old_pl) {
616 /* Allow the driver to copy or do it ourselves */
617 if(copy_func) {
618 new_pl = (copy_func)(old_pl);
619 if(new_pl==NULL)
620 HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "property list copy failed")
621 } else if(pl_size>0) {
622 if((new_pl = H5MM_malloc(pl_size))==NULL)
623 HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "property list allocation failed")
624 HDmemcpy(new_pl, old_pl, pl_size);
625 } else
626 HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "no way to copy driver property list")
627 } /* end if */
628
629 /* Set copied value */
630 *copied_pl=new_pl;
631
632 done:
633 FUNC_LEAVE_NOAPI(ret_value)
634 } /* end H5FD_pl_copy() */
635
636
637 /*-------------------------------------------------------------------------
638 * Function: H5FD_pl_close
639 *
640 * Purpose: Closes a driver for a property list
641 * This is common code, used by both the dataset transfer and
642 * file access property list routines.
643 *
644 * Return: Success: non-negative
645 * Failure: negative
646 *
647 * Programmer: Quincey Koziol
648 * Thursday, October 23, 2003
649 *
650 *-------------------------------------------------------------------------
651 */
652 static herr_t
H5FD_pl_close(hid_t driver_id,herr_t (* free_func)(void *),void * pl)653 H5FD_pl_close(hid_t driver_id, herr_t (*free_func)(void *), void *pl)
654 {
655 herr_t ret_value = SUCCEED; /* Return value */
656
657 FUNC_ENTER_NOAPI_NOINIT
658
659 /* Allow driver to free or do it ourselves */
660 if(pl && free_func) {
661 if((free_func)(pl) < 0)
662 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed")
663 } /* end if */
664 else
665 H5MM_xfree(pl);
666
667 /* Decrement reference count for driver */
668 if(H5I_dec_ref(driver_id) < 0)
669 HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't decrement reference count for driver")
670
671 done:
672 FUNC_LEAVE_NOAPI(ret_value)
673 } /* end H5FD_pl_close() */
674
675
676 /*-------------------------------------------------------------------------
677 * Function: H5FD_fapl_get
678 *
679 * Purpose: Gets the file access property list associated with a file.
680 * Usually the file will copy what it needs from the original
681 * file access property list when the file is created. The
682 * purpose of this function is to create a new file access
683 * property list based on the settings in the file, which may
684 * have been modified from the original file access property
685 * list.
686 *
687 * Return: Success: Pointer to a new file access property list
688 * with all members copied. If the file is
689 * closed then this property list lives on, and
690 * vice versa.
691 *
692 * Failure: NULL, including when the file has no
693 * properties.
694 *
695 * Programmer: Robb Matzke
696 * Friday, August 13, 1999
697 *
698 * Modifications:
699 *
700 *-------------------------------------------------------------------------
701 */
702 void *
H5FD_fapl_get(H5FD_t * file)703 H5FD_fapl_get(H5FD_t *file)
704 {
705 void *ret_value=NULL;
706
707 FUNC_ENTER_NOAPI(NULL)
708
709 HDassert(file);
710
711 if(file->cls->fapl_get)
712 ret_value = (file->cls->fapl_get)(file);
713
714 done:
715 FUNC_LEAVE_NOAPI(ret_value)
716 } /* end H5FD_fapl_get() */
717
718
719 /*-------------------------------------------------------------------------
720 * Function: H5FD_fapl_open
721 *
722 * Purpose: Mark a driver as used by a file access property list
723 *
724 * Return: Success: non-negative
725 *
726 * Failure: negative
727 *
728 * Programmer: Quincey Koziol
729 * Thursday, October 23, 2003
730 *
731 * Modifications:
732 *
733 *-------------------------------------------------------------------------
734 */
735 herr_t
H5FD_fapl_open(H5P_genplist_t * plist,hid_t driver_id,const void * driver_info)736 H5FD_fapl_open(H5P_genplist_t *plist, hid_t driver_id, const void *driver_info)
737 {
738 void *copied_driver_info = NULL; /* Temporary VFL driver info */
739 herr_t ret_value = SUCCEED; /* Return value */
740
741 FUNC_ENTER_NOAPI(FAIL)
742
743 /* Increment the reference count on driver and copy driver info */
744 if(H5I_inc_ref(driver_id, FALSE) < 0)
745 HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver")
746 if(H5FD_fapl_copy(driver_id, driver_info, &copied_driver_info) < 0)
747 HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "can't copy VFL driver info")
748
749 /* Set the driver properties for the list */
750 if(H5P_set(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0)
751 HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set driver ID")
752 if(H5P_set(plist, H5F_ACS_FILE_DRV_INFO_NAME, &copied_driver_info) < 0)
753 HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set driver info")
754 copied_driver_info = NULL;
755
756 done:
757 if(ret_value < 0)
758 if(copied_driver_info && H5FD_fapl_close(driver_id, copied_driver_info) < 0)
759 HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close copy of driver info")
760
761 FUNC_LEAVE_NOAPI(ret_value)
762 } /* end H5FD_fapl_open() */
763
764
765 /*-------------------------------------------------------------------------
766 * Function: H5FD_fapl_copy
767 *
768 * Purpose: Copies the driver-specific part of the file access property
769 * list.
770 *
771 * Return: Success: non-negative
772 *
773 * Failure: negative
774 *
775 * Programmer: Robb Matzke
776 * Tuesday, August 3, 1999
777 *
778 *-------------------------------------------------------------------------
779 */
780 static herr_t
H5FD_fapl_copy(hid_t driver_id,const void * old_fapl,void ** copied_fapl)781 H5FD_fapl_copy(hid_t driver_id, const void *old_fapl, void **copied_fapl)
782 {
783 H5FD_class_t *driver;
784 herr_t ret_value = SUCCEED; /* Return value */
785
786 FUNC_ENTER_NOAPI_NOINIT
787
788 /* Check args */
789 if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
790 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID")
791
792 /* Copy the file access property list */
793 if(H5FD_pl_copy(driver->fapl_copy, driver->fapl_size, old_fapl, copied_fapl) < 0)
794 HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "can't copy driver file access property list")
795
796 done:
797 FUNC_LEAVE_NOAPI(ret_value)
798 }
799
800
801 /*-------------------------------------------------------------------------
802 * Function: H5FD_fapl_close
803 *
804 * Purpose: Closes a driver for a dataset transfer property list
805 *
806 * Return: Success: non-negative
807 * Failure: negative
808 *
809 * Programmer: Robb Matzke
810 * Tuesday, August 3, 1999
811 *
812 * Modifications:
813 *
814 *-------------------------------------------------------------------------
815 */
816 herr_t
H5FD_fapl_close(hid_t driver_id,void * fapl)817 H5FD_fapl_close(hid_t driver_id, void *fapl)
818 {
819 H5FD_class_t *driver = NULL;
820 herr_t ret_value = SUCCEED; /* Return value */
821
822 FUNC_ENTER_NOAPI(FAIL)
823
824 /* Check args */
825 if(driver_id > 0) {
826 if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
827 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a driver ID")
828
829 /* Close the driver for the property list */
830 if(H5FD_pl_close(driver_id, driver->fapl_free, fapl) < 0)
831 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver fapl_free request failed")
832 } /* end if */
833
834 done:
835 FUNC_LEAVE_NOAPI(ret_value)
836 } /* end H5FD_fapl_close() */
837
838
839 /*-------------------------------------------------------------------------
840 * Function: H5FDopen
841 *
842 * Purpose: Opens a file named NAME for the type(s) of access described
843 * by the bit vector FLAGS according to a file access property
844 * list FAPL_ID (which may be the constant H5P_DEFAULT). The
845 * file should expect to handle format addresses in the range [0,
846 * MAXADDR] (if MAXADDR is the undefined address then the caller
847 * doesn't care about the address range).
848 *
849 * Possible values for the FLAGS bits are:
850 *
851 * H5F_ACC_RDWR: Open the file for read and write access. If
852 * this bit is not set then open the file for
853 * read only access. It is permissible to open a
854 * file for read and write access when only read
855 * access is requested by the library (the
856 * library will never attempt to write to a file
857 * which it opened with only read access).
858 *
859 * H5F_ACC_CREATE: Create the file if it doesn't already exist.
860 * However, see H5F_ACC_EXCL below.
861 *
862 * H5F_ACC_TRUNC: Truncate the file if it already exists. This
863 * is equivalent to deleting the file and then
864 * creating a new empty file.
865 *
866 * H5F_ACC_EXCL: When used with H5F_ACC_CREATE, if the file
867 * already exists then the open should fail.
868 * Note that this is unsupported/broken with
869 * some file drivers (e.g., sec2 across nfs) and
870 * will contain a race condition when used to
871 * perform file locking.
872 *
873 * The MAXADDR is the maximum address which will be requested by
874 * the library during an allocation operation. Usually this is
875 * the same value as the MAXADDR field of the class structure,
876 * but it can be smaller if the driver is being used under some
877 * other driver.
878 *
879 * Note that when the driver `open' callback gets control that
880 * the public part of the file struct (the H5FD_t part) will be
881 * incomplete and will be filled in after that callback returns.
882 *
883 * Return: Success: Pointer to a new file driver struct.
884 *
885 * Failure: NULL
886 *
887 * Programmer: Robb Matzke
888 * Tuesday, July 27, 1999
889 *
890 * Modifications:
891 *
892 *-------------------------------------------------------------------------
893 */
894 H5FD_t *
H5FDopen(const char * name,unsigned flags,hid_t fapl_id,haddr_t maxaddr)895 H5FDopen(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
896 {
897 H5FD_t *ret_value=NULL;
898
899 FUNC_ENTER_API(NULL)
900
901 /* Check arguments */
902 if(H5P_DEFAULT == fapl_id)
903 fapl_id = H5P_FILE_ACCESS_DEFAULT;
904 else
905 if(TRUE!=H5P_isa_class(fapl_id,H5P_FILE_ACCESS))
906 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
907
908 if(NULL==(ret_value=H5FD_open(name, flags, fapl_id, maxaddr)))
909 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to open file")
910
911 done:
912 FUNC_LEAVE_API(ret_value)
913 }
914
915
916 /*-------------------------------------------------------------------------
917 * Function: H5FD_open
918 *
919 * Purpose: Private version of H5FDopen()
920 *
921 * Return: Success: Pointer to a new file driver struct
922 *
923 * Failure: NULL
924 *
925 * Programmer: Robb Matzke
926 * Wednesday, August 4, 1999
927 *
928 * Modifications:
929 *
930 * Raymond Lu
931 * Tuesday, Oct 23, 2001
932 * Changed the file access list to the new generic property
933 * list.
934 *
935 *-------------------------------------------------------------------------
936 */
937 H5FD_t *
H5FD_open(const char * name,unsigned flags,hid_t fapl_id,haddr_t maxaddr)938 H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
939 {
940 H5FD_class_t *driver; /* VFD for file */
941 H5FD_t *file = NULL; /* VFD file struct */
942 hid_t driver_id = -1; /* VFD ID */
943 H5P_genplist_t *plist; /* Property list pointer */
944 unsigned long driver_flags = 0; /* File-inspecific driver feature flags */
945 H5FD_file_image_info_t file_image_info; /* Initial file image */
946 H5FD_t *ret_value; /* Return value */
947
948 FUNC_ENTER_NOAPI(NULL)
949
950 /* Sanity check */
951 if(0 == maxaddr)
952 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "zero format address range")
953
954 /* Get file access property list */
955 if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id)))
956 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
957
958 /* Get the VFD to open the file with */
959 if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0)
960 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID")
961
962 /* Get driver info */
963 if(NULL == (driver = (H5FD_class_t *)H5I_object(driver_id)))
964 HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid driver ID in file access property list")
965 if(NULL == driver->open)
966 HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file driver has no `open' method")
967
968 /* Query driver flag */
969 H5FD_driver_query(driver, &driver_flags);
970
971 /* Get initial file image info */
972 if(H5P_get(plist, H5F_ACS_FILE_IMAGE_INFO_NAME, &file_image_info) < 0)
973 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file image info")
974
975 /* If an image is provided, make sure the driver supports this feature */
976 HDassert(((file_image_info.buffer != NULL) && (file_image_info.size > 0)) ||
977 ((file_image_info.buffer == NULL) && (file_image_info.size == 0)));
978 if((file_image_info.buffer != NULL) && !(driver_flags & H5FD_FEAT_ALLOW_FILE_IMAGE))
979 HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, NULL, "file image set, but not supported.")
980
981 /* Dispatch to file driver */
982 if(HADDR_UNDEF == maxaddr)
983 maxaddr = driver->maxaddr;
984 if(NULL == (file = (driver->open)(name, flags, fapl_id, maxaddr)))
985 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed")
986
987 /*
988 * Fill in public fields. We must increment the reference count on the
989 * driver ID to prevent it from being freed while this file is open.
990 */
991 file->driver_id = driver_id;
992 if(H5I_inc_ref(file->driver_id, FALSE) < 0)
993 HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver")
994 file->cls = driver;
995 file->maxaddr = maxaddr;
996 if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(file->threshold)) < 0)
997 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold")
998 if(H5P_get(plist, H5F_ACS_ALIGN_NAME, &(file->alignment)) < 0)
999 HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment")
1000
1001 /* Retrieve the VFL driver feature flags */
1002 if(H5FD_query(file, &(file->feature_flags)) < 0)
1003 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to query file driver")
1004
1005 /* Increment the global serial number & assign it to this H5FD_t object */
1006 if(++file_serial_no == 0) {
1007 /* (Just error out if we wrap around for now...) */
1008 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "unable to get file serial number")
1009 } /* end if */
1010 file->fileno = file_serial_no;
1011
1012 /* Start with base address set to 0 */
1013 /* (This will be changed later, when the superblock is located) */
1014 file->base_addr = 0;
1015
1016 /* Set return value */
1017 ret_value = file;
1018
1019 done:
1020 /* Can't cleanup 'file' information, since we don't know what type it is */
1021 FUNC_LEAVE_NOAPI(ret_value)
1022 } /* end H5FD_open() */
1023
1024
1025 /*-------------------------------------------------------------------------
1026 * Function: H5FDclose
1027 *
1028 * Purpose: Closes the file by calling the driver `close' callback, which
1029 * should free all driver-private data and free the file struct.
1030 * Note that the public part of the file struct (the H5FD_t part)
1031 * will be all zero during the driver close callback like during
1032 * the `open' callback.
1033 *
1034 * Return: Success: Non-negative
1035 * Failure: Negative
1036 *
1037 * Programmer: Robb Matzke
1038 * Tuesday, July 27, 1999
1039 *
1040 *-------------------------------------------------------------------------
1041 */
1042 herr_t
H5FDclose(H5FD_t * file)1043 H5FDclose(H5FD_t *file)
1044 {
1045 herr_t ret_value=SUCCEED; /* Return value */
1046
1047 FUNC_ENTER_API(FAIL)
1048 H5TRACE1("e", "*x", file);
1049
1050 if(!file || !file->cls)
1051 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
1052
1053 if(H5FD_close(file) < 0)
1054 HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close file")
1055
1056 done:
1057 FUNC_LEAVE_API(ret_value)
1058 } /* end H5FDclose() */
1059
1060
1061 /*-------------------------------------------------------------------------
1062 * Function: H5FD_close
1063 *
1064 * Purpose: Private version of H5FDclose()
1065 *
1066 * Return: Success: Non-negative
1067 * Failure: Negative
1068 *
1069 * Programmer: Robb Matzke
1070 * Wednesday, August 4, 1999
1071 *
1072 *-------------------------------------------------------------------------
1073 */
1074 herr_t
H5FD_close(H5FD_t * file)1075 H5FD_close(H5FD_t *file)
1076 {
1077 const H5FD_class_t *driver;
1078 herr_t ret_value = SUCCEED;
1079
1080 FUNC_ENTER_NOAPI(FAIL)
1081
1082 /* check args */
1083 HDassert(file && file->cls);
1084
1085 /* Prepare to close file by clearing all public fields */
1086 driver = file->cls;
1087 if(H5I_dec_ref(file->driver_id) < 0)
1088 HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID")
1089
1090 /*
1091 * Dispatch to the driver for actual close. If the driver fails to
1092 * close the file then the file will be in an unusable state.
1093 */
1094 HDassert(driver->close);
1095 if((driver->close)(file) < 0)
1096 HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "close failed")
1097
1098 done:
1099 FUNC_LEAVE_NOAPI(ret_value)
1100 } /* end H5FD_close() */
1101
1102
1103 /*-------------------------------------------------------------------------
1104 * Function: H5FDcmp
1105 *
1106 * Purpose: Compare the keys of two files using the file driver callback
1107 * if the files belong to the same driver, otherwise sort the
1108 * files by driver class pointer value.
1109 *
1110 * Return: Success: A value like strcmp()
1111 *
1112 * Failure: Must never fail. If both file handles are
1113 * invalid then they compare equal. If one file
1114 * handle is invalid then it compares less than
1115 * the other. If both files belong to the same
1116 * driver and the driver doesn't provide a
1117 * comparison callback then the file pointers
1118 * themselves are compared.
1119 *
1120 * Programmer: Robb Matzke
1121 * Tuesday, July 27, 1999
1122 *
1123 * Modifications:
1124 *
1125 *-------------------------------------------------------------------------
1126 */
1127 int
H5FDcmp(const H5FD_t * f1,const H5FD_t * f2)1128 H5FDcmp(const H5FD_t *f1, const H5FD_t *f2)
1129 {
1130 int ret_value;
1131
1132 FUNC_ENTER_API(-1) /*return value is arbitrary*/
1133 H5TRACE2("Is", "*x*x", f1, f2);
1134
1135 ret_value = H5FD_cmp(f1, f2);
1136
1137 done:
1138 FUNC_LEAVE_API(ret_value)
1139 }
1140
1141
1142 /*-------------------------------------------------------------------------
1143 * Function: H5FD_cmp
1144 *
1145 * Purpose: Private version of H5FDcmp()
1146 *
1147 * Return: Success: A value like strcmp()
1148 *
1149 * Failure: Must never fail.
1150 *
1151 * Programmer: Robb Matzke
1152 * Wednesday, August 4, 1999
1153 *
1154 * Modifications:
1155 *
1156 *-------------------------------------------------------------------------
1157 */
1158 int
H5FD_cmp(const H5FD_t * f1,const H5FD_t * f2)1159 H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2)
1160 {
1161 int ret_value;
1162
1163 FUNC_ENTER_NOAPI(-1) /*return value is arbitrary*/
1164
1165 if((!f1 || !f1->cls) && (!f2 || !f2->cls))
1166 HGOTO_DONE(0)
1167 if(!f1 || !f1->cls)
1168 HGOTO_DONE(-1)
1169 if(!f2 || !f2->cls)
1170 HGOTO_DONE(1)
1171 if(f1->cls < f2->cls)
1172 HGOTO_DONE(-1)
1173 if(f1->cls > f2->cls)
1174 HGOTO_DONE(1)
1175
1176 /* Files are same driver; no cmp callback */
1177 if(!f1->cls->cmp) {
1178 if(f1<f2)
1179 HGOTO_DONE(-1)
1180 if(f1>f2)
1181 HGOTO_DONE(1)
1182 HGOTO_DONE(0)
1183 }
1184
1185 ret_value = (f1->cls->cmp)(f1, f2);
1186
1187 done:
1188 FUNC_LEAVE_NOAPI(ret_value)
1189 }
1190
1191
1192 /*-------------------------------------------------------------------------
1193 * Function: H5FDquery
1194 *
1195 * Purpose: Query a VFL driver for its feature flags. (listed in H5FDpublic.h)
1196 *
1197 * Return: Success: non-negative
1198 *
1199 * Failure: negative
1200 *
1201 * Programmer: Quincey Koziol
1202 * Friday, August 25, 2000
1203 *
1204 * Modifications:
1205 *
1206 *-------------------------------------------------------------------------
1207 */
1208 int
H5FDquery(const H5FD_t * f,unsigned long * flags)1209 H5FDquery(const H5FD_t *f, unsigned long *flags/*out*/)
1210 {
1211 int ret_value;
1212
1213 FUNC_ENTER_API(FAIL)
1214 H5TRACE2("Is", "*xx", f, flags);
1215
1216 HDassert(f);
1217 HDassert(flags);
1218
1219 ret_value = H5FD_query(f, flags);
1220
1221 done:
1222 FUNC_LEAVE_API(ret_value)
1223 }
1224
1225
1226 /*-------------------------------------------------------------------------
1227 * Function: H5FD_query
1228 *
1229 * Purpose: Private version of H5FDquery()
1230 *
1231 * Return: Success: non-negative
1232 *
1233 * Failure: negative
1234 *
1235 * Programmer: Quincey Koziol
1236 * Friday, August 25, 2000
1237 *
1238 *-------------------------------------------------------------------------
1239 */
1240 static int
H5FD_query(const H5FD_t * f,unsigned long * flags)1241 H5FD_query(const H5FD_t *f, unsigned long *flags/*out*/)
1242 {
1243 int ret_value = 0; /* Return value */
1244
1245 FUNC_ENTER_NOAPI_NOINIT_NOERR
1246
1247 HDassert(f);
1248 HDassert(flags);
1249
1250 /* Check for query driver and call it */
1251 if(f->cls->query)
1252 ret_value = (f->cls->query)(f, flags);
1253 else
1254 *flags=0;
1255
1256 FUNC_LEAVE_NOAPI(ret_value)
1257 } /* end H5FD_query() */
1258
1259
1260 /*-------------------------------------------------------------------------
1261 * Function: H5FD_driver_query
1262 *
1263 * Purpose: Similar to H5FD_query(), but intended for cases when we don't
1264 * have a file available (e.g. before one is opened). Since we
1265 * can't use the file to get the driver, the driver is passed in
1266 * as a parameter.
1267 *
1268 * Return: Success: non-negative
1269 * Failure: negative
1270 *
1271 * Programmer: Jacob Gruber
1272 * Wednesday, August 17, 2011
1273 *
1274 *-------------------------------------------------------------------------
1275 */
1276 static int
H5FD_driver_query(const H5FD_class_t * driver,unsigned long * flags)1277 H5FD_driver_query(const H5FD_class_t *driver, unsigned long *flags/*out*/)
1278 {
1279 int ret_value = 0; /* Return value */
1280
1281 FUNC_ENTER_NOAPI_NOINIT_NOERR
1282
1283 HDassert(driver);
1284 HDassert(flags);
1285
1286 /* Check for the driver to query and then query it */
1287 if(driver->query)
1288 ret_value = (driver->query)(NULL, flags);
1289 else
1290 *flags = 0;
1291
1292 FUNC_LEAVE_NOAPI(ret_value)
1293 } /* end H5FD_driver_query() */
1294
1295
1296 /*-------------------------------------------------------------------------
1297 * Function: H5FDalloc
1298 *
1299 * Purpose: Allocates SIZE bytes of memory from the FILE. The memory will
1300 * be used according to the allocation class TYPE. First we try
1301 * to satisfy the request from one of the free lists, according
1302 * to the free list map provided by the driver. The free list
1303 * array has one entry for each request type and the value of
1304 * that array element can be one of four possibilities:
1305 *
1306 * It can be the constant H5FD_MEM_DEFAULT (or zero) which
1307 * indicates that the identity mapping is used. In other
1308 * words, the request type maps to its own free list.
1309 *
1310 * It can be the request type itself, which has the same
1311 * effect as the H5FD_MEM_DEFAULT value above.
1312 *
1313 * It can be the ID for another request type, which
1314 * indicates that the free list for the specified type
1315 * should be used instead.
1316 *
1317 * It can be the constant H5FD_MEM_NOLIST which means that
1318 * no free list should be used for this type of request.
1319 *
1320 * If the request cannot be satisfied from a free list then
1321 * either the driver's `alloc' callback is invoked (if one was
1322 * supplied) or the end-of-address marker is extended. The
1323 * `alloc' callback is always called with the same arguments as
1324 * the H5FDalloc().
1325 *
1326 * Return: Success: The format address of the new file memory.
1327 *
1328 * Failure: The undefined address HADDR_UNDEF
1329 *
1330 * Programmer: Robb Matzke
1331 * Tuesday, July 27, 1999
1332 *
1333 *-------------------------------------------------------------------------
1334 */
1335 haddr_t
H5FDalloc(H5FD_t * file,H5FD_mem_t type,hid_t dxpl_id,hsize_t size)1336 H5FDalloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
1337 {
1338 haddr_t ret_value = HADDR_UNDEF;
1339
1340 FUNC_ENTER_API(HADDR_UNDEF)
1341 H5TRACE4("a", "*xMtih", file, type, dxpl_id, size);
1342
1343 /* Check args */
1344 if(!file || !file->cls)
1345 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer")
1346 if(type < H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES)
1347 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid request type")
1348 if(size == 0)
1349 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "zero-size request")
1350 if(H5P_DEFAULT == dxpl_id)
1351 dxpl_id = H5P_DATASET_XFER_DEFAULT;
1352 else
1353 if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1354 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a data transfer property list")
1355
1356 /* Do the real work */
1357 if(HADDR_UNDEF == (ret_value = H5FD_alloc_real(file, dxpl_id, type, size, NULL, NULL)))
1358 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "unable to allocate file memory")
1359
1360 /* (Note compensating for base address subtraction in internal routine) */
1361 ret_value += file->base_addr;
1362
1363 done:
1364 FUNC_LEAVE_API(ret_value)
1365 } /* end H5FDalloc() */
1366
1367
1368 /*-------------------------------------------------------------------------
1369 * Function: H5FDfree
1370 *
1371 * Purpose: Frees format addresses starting with ADDR and continuing for
1372 * SIZE bytes in the file FILE. The type of space being freed is
1373 * specified by TYPE, which is mapped to a free list as
1374 * described for the H5FDalloc() function above. If the request
1375 * doesn't map to a free list then either the application `free'
1376 * callback is invoked (if defined) or the memory is leaked.
1377 *
1378 * Return: Success: Non-negative
1379 *
1380 * Failure: Negative
1381 *
1382 * Programmer: Robb Matzke
1383 * Wednesday, July 28, 1999
1384 *
1385 * Modifications:
1386 *
1387 *-------------------------------------------------------------------------
1388 */
1389 herr_t
H5FDfree(H5FD_t * file,H5FD_mem_t type,hid_t dxpl_id,haddr_t addr,hsize_t size)1390 H5FDfree(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size)
1391 {
1392 herr_t ret_value=SUCCEED; /* Return value */
1393
1394 FUNC_ENTER_API(FAIL)
1395 H5TRACE5("e", "*xMtiah", file, type, dxpl_id, addr, size);
1396
1397 /* Check args */
1398 if(!file || !file->cls)
1399 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
1400 if(type < H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES)
1401 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid request type")
1402 if(H5P_DEFAULT == dxpl_id)
1403 dxpl_id = H5P_DATASET_XFER_DEFAULT;
1404 else
1405 if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1406 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
1407
1408 /* Do the real work */
1409 /* (Note compensating for base address addition in internal routine) */
1410 if(H5FD_free_real(file, dxpl_id, type, addr - file->base_addr, size) < 0)
1411 HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "file deallocation request failed")
1412
1413 done:
1414 FUNC_LEAVE_API(ret_value)
1415 } /* end H5FDfree() */
1416
1417
1418 /*-------------------------------------------------------------------------
1419 * Function: H5FDget_eoa
1420 *
1421 * Purpose: Returns the address of the first byte after the last
1422 * allocated memory in the file.
1423 *
1424 * Return: Success: First byte after allocated memory.
1425 * Failure: HADDR_UNDEF
1426 *
1427 * Programmer: Robb Matzke
1428 * Friday, July 30, 1999
1429 *
1430 *-------------------------------------------------------------------------
1431 */
1432 haddr_t
H5FDget_eoa(H5FD_t * file,H5FD_mem_t type)1433 H5FDget_eoa(H5FD_t *file, H5FD_mem_t type)
1434 {
1435 haddr_t ret_value;
1436
1437 FUNC_ENTER_API(HADDR_UNDEF)
1438 H5TRACE2("a", "*xMt", file, type);
1439
1440 /* Check args */
1441 if(!file || !file->cls)
1442 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer")
1443 if(type < H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES)
1444 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file type")
1445
1446 /* The real work */
1447 if(HADDR_UNDEF == (ret_value = H5FD_get_eoa(file, type)))
1448 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file get eoa request failed")
1449
1450 /* (Note compensating for base address subtraction in internal routine) */
1451 ret_value += file->base_addr;
1452
1453 done:
1454 FUNC_LEAVE_API(ret_value)
1455 } /* end H5FDget_eoa() */
1456
1457
1458 /*-------------------------------------------------------------------------
1459 * Function: H5FDset_eoa
1460 *
1461 * Purpose: Set the end-of-address marker for the file. The ADDR is the
1462 * address of the first byte past the last allocated byte of the
1463 * file. This function is called from two places:
1464 *
1465 * It is called after an existing file is opened in order to
1466 * "allocate" enough space to read the superblock and then
1467 * to "allocate" the entire hdf5 file based on the contents
1468 * of the superblock.
1469 *
1470 * It is called during file memory allocation if the
1471 * allocation request cannot be satisfied from the free list
1472 * and the driver didn't supply an allocation callback.
1473 *
1474 * Return: Success: Non-negative
1475 * Failure: Negative, no side effect
1476 *
1477 * Programmer: Robb Matzke
1478 * Friday, July 30, 1999
1479 *
1480 *-------------------------------------------------------------------------
1481 */
1482 herr_t
H5FDset_eoa(H5FD_t * file,H5FD_mem_t type,haddr_t addr)1483 H5FDset_eoa(H5FD_t *file, H5FD_mem_t type, haddr_t addr)
1484 {
1485 herr_t ret_value = SUCCEED; /* Return value */
1486
1487 FUNC_ENTER_API(FAIL)
1488 H5TRACE3("e", "*xMta", file, type, addr);
1489
1490 /* Check args */
1491 if(!file || !file->cls)
1492 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
1493 if(type < H5FD_MEM_DEFAULT || type >= H5FD_MEM_NTYPES)
1494 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file type")
1495 if(!H5F_addr_defined(addr) || addr > file->maxaddr)
1496 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid end-of-address value")
1497
1498 /* The real work */
1499 /* (Note compensating for base address addition in internal routine) */
1500 if(H5FD_set_eoa(file, type, addr - file->base_addr) < 0)
1501 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "file set eoa request failed")
1502
1503 done:
1504 FUNC_LEAVE_API(ret_value)
1505 } /* end H5FDset_eoa() */
1506
1507
1508 /*-------------------------------------------------------------------------
1509 * Function: H5FDget_eof
1510 *
1511 * Purpose: Returns the end-of-file address, which is the greater of the
1512 * end-of-format address and the actual EOF marker. This
1513 * function is called after an existing file is opened in order
1514 * for the library to learn the true size of the underlying file
1515 * and to determine whether the hdf5 data has been truncated.
1516 *
1517 * It is also used when a file is first opened to learn whether
1518 * the file is empty or not.
1519 *
1520 * It is permissible for the driver to return the maximum address
1521 * for the file size if the file is not empty.
1522 *
1523 * Return: Success: The EOF address.
1524 *
1525 * Failure: HADDR_UNDEF
1526 *
1527 * Programmer: Robb Matzke
1528 * Thursday, July 29, 1999
1529 *
1530 * Modifications:
1531 *
1532 *-------------------------------------------------------------------------
1533 */
1534 haddr_t
H5FDget_eof(H5FD_t * file)1535 H5FDget_eof(H5FD_t *file)
1536 {
1537 haddr_t ret_value;
1538
1539 FUNC_ENTER_API(HADDR_UNDEF)
1540 H5TRACE1("a", "*x", file);
1541
1542 /* Check arguments */
1543 if(!file || !file->cls)
1544 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, HADDR_UNDEF, "invalid file pointer")
1545
1546 /* The real work */
1547 if(HADDR_UNDEF == (ret_value = H5FD_get_eof(file)))
1548 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, HADDR_UNDEF, "file get eof request failed")
1549
1550 /* (Note compensating for base address subtraction in internal routine) */
1551 ret_value += file->base_addr;
1552
1553 done:
1554 FUNC_LEAVE_API(ret_value)
1555 } /* end H5FDget_eof() */
1556
1557
1558 /*-------------------------------------------------------------------------
1559 * Function: H5FD_get_maxaddr
1560 *
1561 * Purpose: Private version of H5FDget_eof()
1562 *
1563 * Return: Success: The maximum address allowed in the file.
1564 * Failure: HADDR_UNDEF
1565 *
1566 * Programmer: Quincey Koziol
1567 * Thursday, January 3, 2008
1568 *
1569 *-------------------------------------------------------------------------
1570 */
1571 haddr_t
H5FD_get_maxaddr(const H5FD_t * file)1572 H5FD_get_maxaddr(const H5FD_t *file)
1573 {
1574 haddr_t ret_value; /* Return value */
1575
1576 FUNC_ENTER_NOAPI(HADDR_UNDEF)
1577
1578 HDassert(file);
1579
1580 /* Set return value */
1581 ret_value = file->maxaddr;
1582
1583 done:
1584 FUNC_LEAVE_NOAPI(ret_value)
1585 } /* end H5FD_get_maxaddr() */
1586
1587
1588 /*-------------------------------------------------------------------------
1589 * Function: H5FD_get_feature_flags
1590 *
1591 * Purpose: Retrieve the feature flags for the VFD
1592 *
1593 * Return: Success: Non-negative
1594 * Failure: Negative
1595 *
1596 * Programmer: Quincey Koziol
1597 * Tuesday, January 8, 2008
1598 *
1599 *-------------------------------------------------------------------------
1600 */
1601 herr_t
H5FD_get_feature_flags(const H5FD_t * file,unsigned long * feature_flags)1602 H5FD_get_feature_flags(const H5FD_t *file, unsigned long *feature_flags)
1603 {
1604 FUNC_ENTER_NOAPI_NOINIT_NOERR
1605
1606 HDassert(file);
1607 HDassert(feature_flags);
1608
1609 /* Set feature flags to return */
1610 *feature_flags = file->feature_flags;
1611
1612 FUNC_LEAVE_NOAPI(SUCCEED)
1613 } /* end H5FD_get_feature_flags() */
1614
1615
1616 /*-------------------------------------------------------------------------
1617 * Function: H5FD_get_fs_type_map
1618 *
1619 * Purpose: Retrieve the free space type mapping for the VFD
1620 *
1621 * Return: Success: Non-negative
1622 * Failure: Negative
1623 *
1624 * Programmer: Quincey Koziol
1625 * Thursday, January 17, 2008
1626 *
1627 *-------------------------------------------------------------------------
1628 */
1629 herr_t
H5FD_get_fs_type_map(const H5FD_t * file,H5FD_mem_t * type_map)1630 H5FD_get_fs_type_map(const H5FD_t *file, H5FD_mem_t *type_map)
1631 {
1632 herr_t ret_value = SUCCEED; /* Return value */
1633
1634 FUNC_ENTER_NOAPI(FAIL)
1635
1636 /* Sanity check */
1637 HDassert(file && file->cls);
1638 HDassert(type_map);
1639
1640 /* Check for VFD class providing a type map retrieval rouine */
1641 if(file->cls->get_type_map) {
1642 /* Retrieve type mapping for this file */
1643 if((file->cls->get_type_map)(file, type_map) < 0)
1644 HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "driver get type map failed")
1645 } /* end if */
1646 else
1647 /* Copy class's default free space type mapping */
1648 HDmemcpy(type_map, file->cls->fl_map, sizeof(file->cls->fl_map));
1649
1650 done:
1651 FUNC_LEAVE_NOAPI(ret_value)
1652 } /* end H5FD_get_fs_type_map() */
1653
1654
1655 /*-------------------------------------------------------------------------
1656 * Function: H5FDread
1657 *
1658 * Purpose: Reads SIZE bytes from FILE beginning at address ADDR
1659 * according to the data transfer property list DXPL_ID (which may
1660 * be the constant H5P_DEFAULT). The result is written into the
1661 * buffer BUF.
1662 *
1663 * Return: Success: Non-negative. The read result is written into
1664 * the BUF buffer which should be allocated by
1665 * the caller.
1666 *
1667 * Failure: Negative. The contents of BUF is undefined.
1668 *
1669 * Programmer: Robb Matzke
1670 * Thursday, July 29, 1999
1671 *
1672 * Modifications:
1673 *
1674 *-------------------------------------------------------------------------
1675 */
1676 herr_t
H5FDread(H5FD_t * file,H5FD_mem_t type,hid_t dxpl_id,haddr_t addr,size_t size,void * buf)1677 H5FDread(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
1678 void *buf/*out*/)
1679 {
1680 herr_t ret_value = SUCCEED; /* Return value */
1681
1682 FUNC_ENTER_API(FAIL)
1683 H5TRACE6("e", "*xMtiazx", file, type, dxpl_id, addr, size, buf);
1684
1685 /* Check args */
1686 if(!file || !file->cls)
1687 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
1688
1689 /* Get the default dataset transfer property list if the user didn't provide one */
1690 if(H5P_DEFAULT == dxpl_id)
1691 dxpl_id = H5P_DATASET_XFER_DEFAULT;
1692 else
1693 if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1694 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
1695 if(!buf)
1696 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null result buffer")
1697
1698 /* Do the real work */
1699 /* (Note compensating for base address addition in internal routine) */
1700 if(H5FD_read(file, dxpl_id, type, addr - file->base_addr, size, buf) < 0)
1701 HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file read request failed")
1702
1703 done:
1704 FUNC_LEAVE_API(ret_value)
1705 } /* end H5FDread() */
1706
1707
1708 /*-------------------------------------------------------------------------
1709 * Function: H5FDwrite
1710 *
1711 * Purpose: Writes SIZE bytes to FILE beginning at address ADDR according
1712 * to the data transfer property list DXPL_ID (which may be the
1713 * constant H5P_DEFAULT). The bytes to be written come from the
1714 * buffer BUF.
1715 *
1716 * Return: Success: Non-negative
1717 *
1718 * Failure: Negative
1719 *
1720 * Programmer: Robb Matzke
1721 * Thursday, July 29, 1999
1722 *
1723 * Modifications:
1724 *
1725 *-------------------------------------------------------------------------
1726 */
1727 herr_t
H5FDwrite(H5FD_t * file,H5FD_mem_t type,hid_t dxpl_id,haddr_t addr,size_t size,const void * buf)1728 H5FDwrite(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size,
1729 const void *buf)
1730 {
1731 herr_t ret_value = SUCCEED; /* Return value */
1732
1733 FUNC_ENTER_API(FAIL)
1734 H5TRACE6("e", "*xMtiaz*x", file, type, dxpl_id, addr, size, buf);
1735
1736 /* Check args */
1737 if(!file || !file->cls)
1738 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
1739 /* Get the default dataset transfer property list if the user didn't provide one */
1740 if(H5P_DEFAULT == dxpl_id)
1741 dxpl_id = H5P_DATASET_XFER_DEFAULT;
1742 else
1743 if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1744 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
1745 if(!buf)
1746 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null buffer")
1747
1748 /* The real work */
1749 /* (Note compensating for base address addition in internal routine) */
1750 if(H5FD_write(file, dxpl_id, type, addr - file->base_addr, size, buf) < 0)
1751 HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file write request failed")
1752
1753 done:
1754 FUNC_LEAVE_API(ret_value)
1755 } /* end H5FDwrite() */
1756
1757
1758 /*-------------------------------------------------------------------------
1759 * Function: H5FDflush
1760 *
1761 * Purpose: Notify driver to flush all cached data. If the driver has no
1762 * flush method then nothing happens.
1763 *
1764 * Return: Success: Non-negative
1765 *
1766 * Failure: Negative
1767 *
1768 * Programmer: Robb Matzke
1769 * Thursday, July 29, 1999
1770 *
1771 * Modifications:
1772 * Quincey Koziol, May 20, 2002
1773 * Added 'closing' parameter
1774 *
1775 *-------------------------------------------------------------------------
1776 */
1777 herr_t
H5FDflush(H5FD_t * file,hid_t dxpl_id,unsigned closing)1778 H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing)
1779 {
1780 herr_t ret_value = SUCCEED; /* Return value */
1781
1782 FUNC_ENTER_API(FAIL)
1783 H5TRACE3("e", "*xiIu", file, dxpl_id, closing);
1784
1785 /* Check args */
1786 if(!file || !file->cls)
1787 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
1788 if(H5P_DEFAULT == dxpl_id)
1789 dxpl_id = H5P_DATASET_XFER_DEFAULT;
1790 else
1791 if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1792 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
1793
1794 /* Do the real work */
1795 if(H5FD_flush(file, dxpl_id, closing) < 0)
1796 HGOTO_ERROR(H5E_VFL, H5E_CANTFLUSH, FAIL, "file flush request failed")
1797
1798 done:
1799 FUNC_LEAVE_API(ret_value)
1800 }
1801
1802
1803 /*-------------------------------------------------------------------------
1804 * Function: H5FD_flush
1805 *
1806 * Purpose: Private version of H5FDflush()
1807 *
1808 * Return: Success: Non-negative
1809 * Failure: Negative
1810 *
1811 * Programmer: Robb Matzke
1812 * Wednesday, August 4, 1999
1813 *
1814 *-------------------------------------------------------------------------
1815 */
1816 herr_t
H5FD_flush(H5FD_t * file,hid_t dxpl_id,unsigned closing)1817 H5FD_flush(H5FD_t *file, hid_t dxpl_id, unsigned closing)
1818 {
1819 herr_t ret_value = SUCCEED; /* Return value */
1820
1821 FUNC_ENTER_NOAPI(FAIL)
1822
1823 HDassert(file && file->cls);
1824
1825 if(file->cls->flush && (file->cls->flush)(file, dxpl_id, closing) < 0)
1826 HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver flush request failed")
1827
1828 done:
1829 FUNC_LEAVE_NOAPI(ret_value)
1830 } /* end H5FD_flush() */
1831
1832
1833 /*-------------------------------------------------------------------------
1834 * Function: H5FDtruncate
1835 *
1836 * Purpose: Notify driver to truncate the file back to the allocated size.
1837 *
1838 * Return: Success: Non-negative
1839 * Failure: Negative
1840 *
1841 * Programmer: Quincey Koziol
1842 * Thursday, January 31, 2008
1843 *
1844 *-------------------------------------------------------------------------
1845 */
1846 herr_t
H5FDtruncate(H5FD_t * file,hid_t dxpl_id,unsigned closing)1847 H5FDtruncate(H5FD_t *file, hid_t dxpl_id, unsigned closing)
1848 {
1849 herr_t ret_value = SUCCEED; /* Return value */
1850
1851 FUNC_ENTER_API(FAIL)
1852 H5TRACE3("e", "*xiIu", file, dxpl_id, closing);
1853
1854 /* Check args */
1855 if(!file || !file->cls)
1856 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer")
1857 if(H5P_DEFAULT == dxpl_id)
1858 dxpl_id = H5P_DATASET_XFER_DEFAULT;
1859 else
1860 if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
1861 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
1862
1863 /* Do the real work */
1864 if(H5FD_truncate(file, dxpl_id, closing) < 0)
1865 HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "file flush request failed")
1866
1867 done:
1868 FUNC_LEAVE_API(ret_value)
1869 }
1870
1871
1872 /*-------------------------------------------------------------------------
1873 * Function: H5FD_truncate
1874 *
1875 * Purpose: Private version of H5FDtruncate()
1876 *
1877 * Return: Success: Non-negative
1878 * Failure: Negative
1879 *
1880 * Programmer: Quincey Koziol
1881 * Thursday, January 31, 2008
1882 *
1883 *-------------------------------------------------------------------------
1884 */
1885 herr_t
H5FD_truncate(H5FD_t * file,hid_t dxpl_id,unsigned closing)1886 H5FD_truncate(H5FD_t *file, hid_t dxpl_id, unsigned closing)
1887 {
1888 herr_t ret_value = SUCCEED; /* Return value */
1889
1890 FUNC_ENTER_NOAPI(FAIL)
1891
1892 HDassert(file && file->cls);
1893
1894 if(file->cls->truncate && (file->cls->truncate)(file, dxpl_id, closing) < 0)
1895 HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "driver truncate request failed")
1896
1897 done:
1898 FUNC_LEAVE_NOAPI(ret_value)
1899 } /* end H5FD_truncate() */
1900
1901
1902 /*-------------------------------------------------------------------------
1903 * Function: H5FD_get_fileno
1904 *
1905 * Purpose: Quick and dirty routine to retrieve the file's 'fileno' value
1906 * (Mainly added to stop non-file routines from poking about in the
1907 * H5FD_t data structure)
1908 *
1909 * Return: Non-negative on success/Negative on failure
1910 *
1911 * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
1912 * March 27, 2002
1913 *
1914 *-------------------------------------------------------------------------
1915 */
1916 herr_t
H5FD_get_fileno(const H5FD_t * file,unsigned long * filenum)1917 H5FD_get_fileno(const H5FD_t *file, unsigned long *filenum)
1918 {
1919 FUNC_ENTER_NOAPI_NOINIT_NOERR
1920
1921 HDassert(file);
1922 HDassert(filenum);
1923
1924 /* Retrieve the file's serial number */
1925 *filenum = file->fileno;
1926
1927 FUNC_LEAVE_NOAPI(SUCCEED)
1928 } /* end H5FD_get_fileno() */
1929
1930
1931 /*--------------------------------------------------------------------------
1932 * Function: H5FDget_vfd_handle
1933 *
1934 * Purpose: Returns a pointer to the file handle of low-level virtual
1935 * file driver.
1936 *
1937 * Return: Non-negative if succeed; negative otherwise.
1938 *
1939 * Programmer: Raymond Lu
1940 * Sep. 16, 2002
1941 *
1942 * Modifications:
1943 *
1944 *--------------------------------------------------------------------------
1945 */
1946 herr_t
H5FDget_vfd_handle(H5FD_t * file,hid_t fapl,void ** file_handle)1947 H5FDget_vfd_handle(H5FD_t *file, hid_t fapl, void **file_handle)
1948 {
1949 herr_t ret_value;
1950
1951 FUNC_ENTER_API(FAIL)
1952 H5TRACE3("e", "*xi**x", file, fapl, file_handle);
1953
1954 /* Check arguments */
1955 HDassert(file);
1956 HDassert(file_handle);
1957
1958 ret_value = H5FD_get_vfd_handle(file, fapl, file_handle);
1959
1960 done:
1961 FUNC_LEAVE_API(ret_value)
1962 } /* end H5FDget_vfd_handle() */
1963
1964
1965 /*--------------------------------------------------------------------------
1966 * Function: H5FD_get_vfd_handle
1967 *
1968 * Purpose: Retrieve the file handle for file driver.
1969 *
1970 * Return: Non-negative if succeed; negative if fails.
1971 *
1972 * Programmer: Raymond Lu
1973 * Sep. 16, 2002
1974 *
1975 *--------------------------------------------------------------------------
1976 */
1977 herr_t
H5FD_get_vfd_handle(H5FD_t * file,hid_t fapl,void ** file_handle)1978 H5FD_get_vfd_handle(H5FD_t *file, hid_t fapl, void **file_handle)
1979 {
1980 herr_t ret_value = SUCCEED;
1981
1982 FUNC_ENTER_NOAPI(FAIL)
1983
1984 /* Sanity check */
1985 HDassert(file);
1986 HDassert(file_handle);
1987
1988 if(NULL == file->cls->get_handle)
1989 HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "file driver has no `get_vfd_handle' method")
1990 if((file->cls->get_handle)(file, fapl, file_handle) < 0)
1991 HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file handle for file driver")
1992
1993 done:
1994 FUNC_LEAVE_NOAPI(ret_value)
1995 } /* end H5FD_get_vfd_handle() */
1996
1997
1998 /*--------------------------------------------------------------------------
1999 * Function: H5FD_set_base_addr
2000 *
2001 * Purpose: Set the base address for the file
2002 *
2003 * Return: Non-negative if succeed; negative if fails.
2004 *
2005 * Programmer: Quincey Koziol
2006 * Jan. 17, 2008
2007 *
2008 *--------------------------------------------------------------------------
2009 */
2010 herr_t
H5FD_set_base_addr(H5FD_t * file,haddr_t base_addr)2011 H5FD_set_base_addr(H5FD_t *file, haddr_t base_addr)
2012 {
2013 FUNC_ENTER_NOAPI_NOINIT_NOERR
2014
2015 HDassert(file);
2016 HDassert(H5F_addr_defined(base_addr));
2017
2018 /* Set the file's base address */
2019 file->base_addr = base_addr;
2020
2021 FUNC_LEAVE_NOAPI(SUCCEED)
2022 } /* end H5FD_set_base_addr() */
2023
2024
2025 /*--------------------------------------------------------------------------
2026 * Function: H5FD_get_base_addr
2027 *
2028 * Purpose: Get the base address for the file
2029 *
2030 * Return: Success: The absolute base address of the file
2031 * Failure: The undefined address (HADDR_UNDEF)
2032 *
2033 * Programmer: Quincey Koziol
2034 * Sept. 10, 2009
2035 *
2036 *--------------------------------------------------------------------------
2037 */
2038 haddr_t
H5FD_get_base_addr(const H5FD_t * file)2039 H5FD_get_base_addr(const H5FD_t *file)
2040 {
2041 FUNC_ENTER_NOAPI_NOINIT_NOERR
2042
2043 HDassert(file);
2044
2045 /* Return the file's base address */
2046 FUNC_LEAVE_NOAPI(file->base_addr)
2047 } /* end H5FD_get_base_addr() */
2048
2049