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 COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /*
15  * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
16  *	       Thursday, September 30, 2004
17  */
18 
19 /****************/
20 /* Module Setup */
21 /****************/
22 
23 #define H5D_PACKAGE		/*suppress error about including H5Dpkg	  */
24 
25 
26 /***********/
27 /* Headers */
28 /***********/
29 #include "H5private.h"          /* Generic Functions                        */
30 #include "H5Dpkg.h"             /* Datasets                                 */
31 #include "H5Eprivate.h"         /* Error handling                           */
32 #include "H5Fprivate.h"         /* Files                                    */
33 #include "H5HLprivate.h"        /* Local Heaps                              */
34 #include "H5MMprivate.h"        /* Memory management                        */
35 #include "H5VMprivate.h"        /* Vector and array functions               */
36 
37 
38 /****************/
39 /* Local Macros */
40 /****************/
41 
42 
43 /******************/
44 /* Local Typedefs */
45 /******************/
46 
47 /* Callback info for readvv operation */
48 typedef struct H5D_efl_readvv_ud_t {
49     const H5O_efl_t *efl;       /* Pointer to efl info */
50     const H5D_t *dset;          /* The dataset */
51     unsigned char *rbuf;        /* Read buffer */
52 } H5D_efl_readvv_ud_t;
53 
54 /* Callback info for writevv operation */
55 typedef struct H5D_efl_writevv_ud_t {
56     const H5O_efl_t *efl;       /* Pointer to efl info */
57     const H5D_t *dset;          /* The dataset */
58     const unsigned char *wbuf;  /* Write buffer */
59 } H5D_efl_writevv_ud_t;
60 
61 
62 /********************/
63 /* Local Prototypes */
64 /********************/
65 
66 /* Layout operation callbacks */
67 static herr_t H5D__efl_construct(H5F_t *f, H5D_t *dset);
68 static herr_t H5D__efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
69     hsize_t nelmts, const H5S_t *file_space, const H5S_t *mem_space,
70     H5D_chunk_map_t *cm);
71 static ssize_t H5D__efl_readvv(const H5D_io_info_t *io_info,
72     size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
73     size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
74 static ssize_t H5D__efl_writevv(const H5D_io_info_t *io_info,
75     size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
76     size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[]);
77 
78 /* Helper routines */
79 static herr_t H5D__efl_read(const H5O_efl_t *efl, const H5D_t *dset, haddr_t addr, size_t size,
80     uint8_t *buf);
81 static herr_t H5D__efl_write(const H5O_efl_t *efl, const H5D_t *dset, haddr_t addr, size_t size,
82     const uint8_t *buf);
83 
84 
85 /*********************/
86 /* Package Variables */
87 /*********************/
88 
89 /* External File List (EFL) storage layout I/O ops */
90 const H5D_layout_ops_t H5D_LOPS_EFL[1] = {{
91     H5D__efl_construct,
92     NULL,
93     H5D__efl_is_space_alloc,
94     H5D__efl_io_init,
95     H5D__contig_read,
96     H5D__contig_write,
97 #ifdef H5_HAVE_PARALLEL
98     NULL,
99     NULL,
100 #endif /* H5_HAVE_PARALLEL */
101     H5D__efl_readvv,
102     H5D__efl_writevv,
103     NULL,
104     NULL
105 }};
106 
107 
108 /*******************/
109 /* Local Variables */
110 /*******************/
111 
112 
113 
114 /*-------------------------------------------------------------------------
115  * Function:	H5D__efl_construct
116  *
117  * Purpose:	Constructs new EFL layout information for dataset
118  *
119  * Return:	Non-negative on success/Negative on failure
120  *
121  * Programmer:	Quincey Koziol
122  *              Thursday, May 22, 2008
123  *
124  *-------------------------------------------------------------------------
125  */
126 static herr_t
H5D__efl_construct(H5F_t * f,H5D_t * dset)127 H5D__efl_construct(H5F_t *f, H5D_t *dset)
128 {
129     size_t dt_size;                     /* Size of datatype */
130     hsize_t dim[H5O_LAYOUT_NDIMS];	/* Current size of data in elements */
131     hsize_t max_dim[H5O_LAYOUT_NDIMS];  /* Maximum size of data in elements */
132     hssize_t stmp_size;                 /* Temporary holder for raw data size */
133     hsize_t tmp_size;                   /* Temporary holder for raw data size */
134     hsize_t max_points;                 /* Maximum elements */
135     hsize_t max_storage;                /* Maximum storage size */
136     int ndims;                          /* Rank of dataspace */
137     int i;                              /* Local index variable */
138     herr_t ret_value = SUCCEED;         /* Return value */
139 
140     FUNC_ENTER_STATIC
141 
142     /* Sanity checks */
143     HDassert(f);
144     HDassert(dset);
145 
146     /*
147      * The maximum size of the dataset cannot exceed the storage size.
148      * Also, only the slowest varying dimension of a simple data space
149      * can be extendible (currently only for external data storage).
150      */
151 
152     /* Check for invalid dataset dimensions */
153     if((ndims = H5S_get_simple_extent_dims(dset->shared->space, dim, max_dim)) < 0)
154         HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize contiguous storage")
155     for(i = 1; i < ndims; i++)
156         if(max_dim[i] > dim[i])
157             HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "only the first dimension can be extendible")
158 
159     /* Retrieve the size of the dataset's datatype */
160     if(0 == (dt_size = H5T_get_size(dset->shared->type)))
161         HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to determine datatype size")
162 
163     /* Check for storage overflows */
164     max_points = H5S_get_npoints_max(dset->shared->space);
165     max_storage = H5O_efl_total_size(&dset->shared->dcpl_cache.efl);
166     if(H5S_UNLIMITED == max_points) {
167         if(H5O_EFL_UNLIMITED != max_storage)
168             HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unlimited dataspace but finite storage")
169     } /* end if */
170     else if((max_points * dt_size) < max_points)
171         HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "dataspace * type size overflowed")
172     else if((max_points * dt_size) > max_storage)
173         HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "dataspace size exceeds external storage size")
174 
175     /* Compute the total size of dataset */
176     stmp_size = H5S_GET_EXTENT_NPOINTS(dset->shared->space);
177     HDassert(stmp_size >= 0);
178     tmp_size = (hsize_t)stmp_size * dt_size;
179     H5_CHECKED_ASSIGN(dset->shared->layout.storage.u.contig.size, hsize_t, tmp_size, hssize_t);
180 
181     /* Get the sieve buffer size for this dataset */
182     dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(f);
183 
184 done:
185     FUNC_LEAVE_NOAPI(ret_value)
186 } /* end H5D__efl_construct() */
187 
188 
189 /*-------------------------------------------------------------------------
190  * Function:	H5D__efl_is_space_alloc
191  *
192  * Purpose:	Query if space is allocated for layout
193  *
194  * Return:	Non-negative on success/Negative on failure
195  *
196  * Programmer:	Quincey Koziol
197  *              Thursday, January 15, 2009
198  *
199  *-------------------------------------------------------------------------
200  */
201 hbool_t
H5D__efl_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED * storage)202 H5D__efl_is_space_alloc(const H5O_storage_t H5_ATTR_UNUSED *storage)
203 {
204     FUNC_ENTER_PACKAGE_NOERR
205 
206     /* Sanity checks */
207     HDassert(storage);
208 
209     /* EFL storage is currently always treated as allocated */
210     FUNC_LEAVE_NOAPI(TRUE)
211 } /* end H5D__efl_is_space_alloc() */
212 
213 
214 /*-------------------------------------------------------------------------
215  * Function:	H5D__efl_io_init
216  *
217  * Purpose:	Performs initialization before any sort of I/O on the raw data
218  *
219  * Return:	Non-negative on success/Negative on failure
220  *
221  * Programmer:	Quincey Koziol
222  *              Thursday, March 20, 2008
223  *
224  *-------------------------------------------------------------------------
225  */
226 static herr_t
H5D__efl_io_init(const H5D_io_info_t * io_info,const H5D_type_info_t H5_ATTR_UNUSED * type_info,hsize_t H5_ATTR_UNUSED nelmts,const H5S_t H5_ATTR_UNUSED * file_space,const H5S_t H5_ATTR_UNUSED * mem_space,H5D_chunk_map_t H5_ATTR_UNUSED * cm)227 H5D__efl_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t H5_ATTR_UNUSED *type_info,
228     hsize_t H5_ATTR_UNUSED nelmts, const H5S_t H5_ATTR_UNUSED *file_space, const H5S_t H5_ATTR_UNUSED *mem_space,
229     H5D_chunk_map_t H5_ATTR_UNUSED *cm)
230 {
231     FUNC_ENTER_STATIC_NOERR
232 
233     HDmemcpy(&io_info->store->efl, &(io_info->dset->shared->dcpl_cache.efl), sizeof(H5O_efl_t));
234 
235     FUNC_LEAVE_NOAPI(SUCCEED)
236 } /* end H5D__efl_io_init() */
237 
238 
239 /*-------------------------------------------------------------------------
240  * Function:    H5D__efl_read
241  *
242  * Purpose:     Reads data from an external file list.  It is an error to
243  *              read past the logical end of file, but reading past the end
244  *              of any particular member of the external file list results in
245  *              zeros.
246  *
247  * Return:      SUCCEED/FAIL
248  *
249  * Programmer:  Robb Matzke
250  *              Wednesday, March  4, 1998
251  *
252  *-------------------------------------------------------------------------
253  */
254 static herr_t
H5D__efl_read(const H5O_efl_t * efl,const H5D_t * dset,haddr_t addr,size_t size,uint8_t * buf)255 H5D__efl_read(const H5O_efl_t *efl, const H5D_t *dset, haddr_t addr, size_t size, uint8_t *buf)
256 {
257     int		fd = -1;
258     size_t	to_read;
259 #ifndef NDEBUG
260     hsize_t     tempto_read;
261 #endif /* NDEBUG */
262     hsize_t     skip = 0;
263     haddr_t     cur;
264     ssize_t	n;
265     size_t      u;                      /* Local index variable */
266     char *full_name = NULL;             /* File name with prefix */
267     herr_t      ret_value = SUCCEED;    /* Return value */
268 
269     FUNC_ENTER_STATIC
270 
271     /* Check args */
272     HDassert(efl && efl->nused > 0);
273     HDassert(H5F_addr_defined(addr));
274     HDassert(size < SIZET_MAX);
275     HDassert(buf || 0 == size);
276 
277     /* Find the first efl member from which to read */
278     for (u=0, cur=0; u<efl->nused; u++) {
279         if(H5O_EFL_UNLIMITED == efl->slot[u].size || addr < cur + efl->slot[u].size) {
280             skip = addr - cur;
281             break;
282         } /* end if */
283         cur += efl->slot[u].size;
284     } /* end for */
285 
286     /* Read the data */
287     while(size) {
288         HDassert(buf);
289         if(u >= efl->nused)
290             HGOTO_ERROR(H5E_EFL, H5E_OVERFLOW, FAIL, "read past logical end of file")
291         if(H5F_OVERFLOW_HSIZET2OFFT(efl->slot[u].offset + skip))
292             HGOTO_ERROR(H5E_EFL, H5E_OVERFLOW, FAIL, "external file address overflowed")
293         if(H5_combine_path(dset->shared->extfile_prefix, efl->slot[u].name, &full_name) < 0)
294             HGOTO_ERROR(H5E_EFL, H5E_NOSPACE, FAIL, "can't build external file name")
295         if((fd = HDopen(full_name, O_RDONLY, 0)) < 0)
296             HGOTO_ERROR(H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file")
297         if(HDlseek(fd, (HDoff_t)(efl->slot[u].offset + skip), SEEK_SET) < 0)
298             HGOTO_ERROR(H5E_EFL, H5E_SEEKERROR, FAIL, "unable to seek in external raw data file")
299 #ifndef NDEBUG
300         tempto_read = MIN((size_t)(efl->slot[u].size-skip), (hsize_t)size);
301         H5_CHECK_OVERFLOW(tempto_read, hsize_t, size_t);
302         to_read = (size_t)tempto_read;
303 #else /* NDEBUG */
304         to_read = MIN((size_t)(efl->slot[u].size - skip), (hsize_t)size);
305 #endif /* NDEBUG */
306         if((n = HDread(fd, buf, to_read)) < 0)
307             HGOTO_ERROR(H5E_EFL, H5E_READERROR, FAIL, "read error in external raw data file")
308         else if((size_t)n < to_read)
309             HDmemset(buf + n, 0, to_read - (size_t)n);
310         full_name = (char *)H5MM_xfree(full_name);
311         HDclose(fd);
312         fd = -1;
313         size -= to_read;
314         buf += to_read;
315         skip = 0;
316         u++;
317     } /* end while */
318 
319 done:
320     if(full_name)
321         full_name = (char *)H5MM_xfree(full_name);
322     if(fd >= 0)
323         HDclose(fd);
324 
325     FUNC_LEAVE_NOAPI(ret_value)
326 } /* end H5D__efl_read() */
327 
328 
329 /*-------------------------------------------------------------------------
330  * Function:	H5D__efl_write
331  *
332  * Purpose:	Writes data to an external file list.  It is an error to
333  *		write past the logical end of file, but writing past the end
334  *		of any particular member of the external file list just
335  *		extends that file.
336  *
337  * Return:	Non-negative on success/Negative on failure
338  *
339  * Programmer:	Robb Matzke
340  *              Wednesday, March  4, 1998
341  *
342  * Modifications:
343  *		Robb Matzke, 1999-07-28
344  *		The ADDR argument is passed by value.
345  *-------------------------------------------------------------------------
346  */
347 static herr_t
H5D__efl_write(const H5O_efl_t * efl,const H5D_t * dset,haddr_t addr,size_t size,const uint8_t * buf)348 H5D__efl_write(const H5O_efl_t *efl, const H5D_t *dset, haddr_t addr, size_t size, const uint8_t *buf)
349 {
350     int		fd = -1;
351     size_t	to_write;
352 #ifndef NDEBUG
353     hsize_t	tempto_write;
354 #endif /* NDEBUG */
355     haddr_t     cur;
356     hsize_t     skip = 0;
357     size_t	u;                          /* Local index variable */
358     char *full_name = NULL;             /* File name with prefix */
359     herr_t      ret_value = SUCCEED;    /* Return value */
360 
361     FUNC_ENTER_STATIC
362 
363     /* Check args */
364     HDassert(efl && efl->nused > 0);
365     HDassert(H5F_addr_defined(addr));
366     HDassert(size < SIZET_MAX);
367     HDassert(buf || 0 == size);
368 
369     /* Find the first efl member in which to write */
370     for(u = 0, cur = 0; u < efl->nused; u++) {
371         if(H5O_EFL_UNLIMITED == efl->slot[u].size || addr < cur + efl->slot[u].size) {
372             skip = addr - cur;
373             break;
374         } /* end if */
375         cur += efl->slot[u].size;
376     } /* end for */
377 
378     /* Write the data */
379     while(size) {
380         HDassert(buf);
381         if(u >= efl->nused)
382             HGOTO_ERROR(H5E_EFL, H5E_OVERFLOW, FAIL, "write past logical end of file")
383         if(H5F_OVERFLOW_HSIZET2OFFT(efl->slot[u].offset + skip))
384             HGOTO_ERROR(H5E_EFL, H5E_OVERFLOW, FAIL, "external file address overflowed")
385         if(H5_combine_path(dset->shared->extfile_prefix, efl->slot[u].name, &full_name) < 0)
386             HGOTO_ERROR(H5E_EFL, H5E_NOSPACE, FAIL, "can't build external file name")
387         if((fd = HDopen(full_name, O_CREAT | O_RDWR, 0666)) < 0) {
388             if(HDaccess(full_name, F_OK) < 0)
389                 HGOTO_ERROR(H5E_EFL, H5E_CANTOPENFILE, FAIL, "external raw data file does not exist")
390             else
391                 HGOTO_ERROR(H5E_EFL, H5E_CANTOPENFILE, FAIL, "unable to open external raw data file")
392             } /* end if */
393         if(HDlseek(fd, (HDoff_t)(efl->slot[u].offset + skip), SEEK_SET) < 0)
394             HGOTO_ERROR(H5E_EFL, H5E_SEEKERROR, FAIL, "unable to seek in external raw data file")
395 #ifndef NDEBUG
396         tempto_write = MIN(efl->slot[u].size - skip, (hsize_t)size);
397         H5_CHECK_OVERFLOW(tempto_write, hsize_t, size_t);
398         to_write = (size_t)tempto_write;
399 #else /* NDEBUG */
400         to_write = MIN((size_t)(efl->slot[u].size - skip), size);
401 #endif /* NDEBUG */
402         if((size_t)HDwrite(fd, buf, to_write) != to_write)
403             HGOTO_ERROR(H5E_EFL, H5E_READERROR, FAIL, "write error in external raw data file")
404         full_name = (char *)H5MM_xfree(full_name);
405         HDclose (fd);
406         fd = -1;
407         size -= to_write;
408         buf += to_write;
409         skip = 0;
410         u++;
411     } /* end while */
412 
413 done:
414     if(full_name)
415         full_name = (char *)H5MM_xfree(full_name);
416     if(fd >= 0)
417         HDclose(fd);
418 
419     FUNC_LEAVE_NOAPI(ret_value)
420 } /* end H5D__efl_write() */
421 
422 
423 /*-------------------------------------------------------------------------
424  * Function:	H5D__efl_readvv_cb
425  *
426  * Purpose:	Callback operator for H5D__efl_readvv().
427  *
428  * Return:	Non-negative on success/Negative on failure
429  *
430  * Programmer:	Quincey Koziol
431  *              Thursday, Sept 30, 2010
432  *
433  *-------------------------------------------------------------------------
434  */
435 static herr_t
H5D__efl_readvv_cb(hsize_t dst_off,hsize_t src_off,size_t len,void * _udata)436 H5D__efl_readvv_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata)
437 {
438     H5D_efl_readvv_ud_t *udata = (H5D_efl_readvv_ud_t *)_udata; /* User data for H5VM_opvv() operator */
439     herr_t ret_value = SUCCEED;         /* Return value */
440 
441     FUNC_ENTER_STATIC
442 
443     /* Read data */
444     if(H5D__efl_read(udata->efl, udata->dset, dst_off, len, (udata->rbuf + src_off)) < 0)
445         HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "EFL read failed")
446 
447 done:
448     FUNC_LEAVE_NOAPI(ret_value)
449 } /* end H5D__efl_readvv_cb() */
450 
451 
452 /*-------------------------------------------------------------------------
453  * Function:	H5D__efl_readvv
454  *
455  * Purpose:	Reads data from an external file list.  It is an error to
456  *		read past the logical end of file, but reading past the end
457  *		of any particular member of the external file list results in
458  *		zeros.
459  *
460  * Return:	Non-negative on success/Negative on failure
461  *
462  * Programmer:	Quincey Koziol
463  *              Wednesday, May  7, 2003
464  *
465  *-------------------------------------------------------------------------
466  */
467 static ssize_t
H5D__efl_readvv(const H5D_io_info_t * io_info,size_t dset_max_nseq,size_t * dset_curr_seq,size_t dset_len_arr[],hsize_t dset_off_arr[],size_t mem_max_nseq,size_t * mem_curr_seq,size_t mem_len_arr[],hsize_t mem_off_arr[])468 H5D__efl_readvv(const H5D_io_info_t *io_info,
469     size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[],
470     size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
471 {
472     H5D_efl_readvv_ud_t udata;  /* User data for H5VM_opvv() operator */
473     ssize_t ret_value;          /* Return value (Total size of sequence in bytes) */
474 
475     FUNC_ENTER_STATIC
476 
477     /* Check args */
478     HDassert(io_info);
479     HDassert(io_info->store->efl.nused > 0);
480     HDassert(io_info->u.rbuf);
481     HDassert(io_info->dset);
482     HDassert(io_info->dset->shared);
483     HDassert(io_info->dset->shared->extfile_prefix);
484     HDassert(dset_curr_seq);
485     HDassert(dset_len_arr);
486     HDassert(dset_off_arr);
487     HDassert(mem_curr_seq);
488     HDassert(mem_len_arr);
489     HDassert(mem_off_arr);
490 
491     /* Set up user data for H5VM_opvv() */
492     udata.efl = &(io_info->store->efl);
493     udata.dset = io_info->dset;
494     udata.rbuf = (unsigned char *)io_info->u.rbuf;
495 
496     /* Call generic sequence operation routine */
497     if((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr,
498             mem_max_nseq, mem_curr_seq, mem_len_arr, mem_off_arr,
499             H5D__efl_readvv_cb, &udata)) < 0)
500         HGOTO_ERROR(H5E_DATASET, H5E_CANTOPERATE, FAIL, "can't perform vectorized EFL read")
501 
502 done:
503     FUNC_LEAVE_NOAPI(ret_value)
504 } /* end H5D__efl_readvv() */
505 
506 
507 /*-------------------------------------------------------------------------
508  * Function:	H5D__efl_writevv_cb
509  *
510  * Purpose:	Callback operator for H5D__efl_writevv().
511  *
512  * Return:	Non-negative on success/Negative on failure
513  *
514  * Programmer:	Quincey Koziol
515  *              Thursday, Sept 30, 2010
516  *
517  *-------------------------------------------------------------------------
518  */
519 static herr_t
H5D__efl_writevv_cb(hsize_t dst_off,hsize_t src_off,size_t len,void * _udata)520 H5D__efl_writevv_cb(hsize_t dst_off, hsize_t src_off, size_t len, void *_udata)
521 {
522     H5D_efl_writevv_ud_t *udata = (H5D_efl_writevv_ud_t *)_udata; /* User data for H5VM_opvv() operator */
523     herr_t ret_value = SUCCEED;         /* Return value */
524 
525     FUNC_ENTER_STATIC
526 
527     /* Write data */
528     if(H5D__efl_write(udata->efl, udata->dset, dst_off, len, (udata->wbuf + src_off)) < 0)
529         HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "EFL write failed")
530 
531 done:
532     FUNC_LEAVE_NOAPI(ret_value)
533 } /* end H5D__efl_writevv_cb() */
534 
535 
536 /*-------------------------------------------------------------------------
537  * Function:	H5D__efl_writevv
538  *
539  * Purpose:	Writes data to an external file list.  It is an error to
540  *		write past the logical end of file, but writing past the end
541  *		of any particular member of the external file list just
542  *		extends that file.
543  *
544  * Return:	Non-negative on success/Negative on failure
545  *
546  * Programmer:	Quincey Koziol
547  *              Friday, May  2, 2003
548  *
549  *-------------------------------------------------------------------------
550  */
551 static ssize_t
H5D__efl_writevv(const H5D_io_info_t * io_info,size_t dset_max_nseq,size_t * dset_curr_seq,size_t dset_len_arr[],hsize_t dset_off_arr[],size_t mem_max_nseq,size_t * mem_curr_seq,size_t mem_len_arr[],hsize_t mem_off_arr[])552 H5D__efl_writevv(const H5D_io_info_t *io_info,
553     size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_off_arr[],
554     size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_off_arr[])
555 {
556     H5D_efl_writevv_ud_t udata;  /* User data for H5VM_opvv() operator */
557     ssize_t ret_value;          /* Return value (Total size of sequence in bytes) */
558 
559     FUNC_ENTER_STATIC
560 
561     /* Check args */
562     HDassert(io_info);
563     HDassert(io_info->store->efl.nused > 0);
564     HDassert(io_info->u.wbuf);
565     HDassert(io_info->dset);
566     HDassert(io_info->dset->shared);
567     HDassert(io_info->dset->shared->extfile_prefix);
568     HDassert(dset_curr_seq);
569     HDassert(dset_len_arr);
570     HDassert(dset_off_arr);
571     HDassert(mem_curr_seq);
572     HDassert(mem_len_arr);
573     HDassert(mem_off_arr);
574 
575     /* Set up user data for H5VM_opvv() */
576     udata.efl = &(io_info->store->efl);
577     udata.dset = io_info->dset;
578     udata.wbuf = (const unsigned char *)io_info->u.wbuf;
579 
580     /* Call generic sequence operation routine */
581     if((ret_value = H5VM_opvv(dset_max_nseq, dset_curr_seq, dset_len_arr, dset_off_arr,
582             mem_max_nseq, mem_curr_seq, mem_len_arr, mem_off_arr,
583             H5D__efl_writevv_cb, &udata)) < 0)
584         HGOTO_ERROR(H5E_DATASET, H5E_CANTOPERATE, FAIL, "can't perform vectorized EFL write")
585 done:
586     FUNC_LEAVE_NOAPI(ret_value)
587 } /* end H5D__efl_writevv() */
588 
589 
590 /*-------------------------------------------------------------------------
591  * Function:    H5D__efl_bh_info
592  *
593  * Purpose:     Retrieve the amount of heap storage used for External File
594  *		List message
595  *
596  * Return:      Success:        Non-negative
597  *              Failure:        negative
598  *
599  * Programmer:  Vailin Choi; August 2009
600  *
601  *-------------------------------------------------------------------------
602  */
603 herr_t
H5D__efl_bh_info(H5F_t * f,hid_t dxpl_id,H5O_efl_t * efl,hsize_t * heap_size)604 H5D__efl_bh_info(H5F_t *f, hid_t dxpl_id, H5O_efl_t *efl, hsize_t *heap_size)
605 {
606     herr_t ret_value = SUCCEED;         /* Return value */
607 
608     FUNC_ENTER_PACKAGE
609 
610     /* Check args */
611     HDassert(f);
612     HDassert(efl);
613     HDassert(H5F_addr_defined(efl->heap_addr));
614     HDassert(heap_size);
615 
616     /* Get the size of the local heap for EFL's file list */
617     if(H5HL_heapsize(f, dxpl_id, efl->heap_addr, heap_size) < 0)
618         HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, FAIL, "unable to retrieve local heap info")
619 
620 done:
621     FUNC_LEAVE_NOAPI(ret_value)
622 } /* end H5D__efl_bh_info() */
623