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  *
16  * Created:     H5FAcache.c
17  *		Jul  2 2009
18  *		Quincey Koziol <koziol@hdfgroup.org>
19  *
20  * Purpose:     Implement fixed array metadata cache methods.
21  *
22  *-------------------------------------------------------------------------
23  */
24 
25 /**********************/
26 /* Module Declaration */
27 /**********************/
28 
29 #include "H5FAmodule.h"         /* This source code file is part of the H5FA module */
30 
31 
32 /***********************/
33 /* Other Packages Used */
34 /***********************/
35 
36 
37 /***********/
38 /* Headers */
39 /***********/
40 #include "H5private.h"		/* Generic Functions			*/
41 #include "H5Eprivate.h"		/* Error handling		  	*/
42 #include "H5FApkg.h"		/* Fixed Arrays				*/
43 #include "H5MFprivate.h"	/* File memory management		*/
44 #include "H5VMprivate.h"	/* Vectors and arrays 			*/
45 #include "H5WBprivate.h"        /* Wrapped Buffers                      */
46 
47 
48 /****************/
49 /* Local Macros */
50 /****************/
51 
52 /* Fixed Array format version #'s */
53 #define H5FA_HDR_VERSION        0               /* Header */
54 #define H5FA_DBLOCK_VERSION     0               /* Data block */
55 
56 
57 /******************/
58 /* Local Typedefs */
59 /******************/
60 
61 
62 /********************/
63 /* Package Typedefs */
64 /********************/
65 
66 
67 /********************/
68 /* Local Prototypes */
69 /********************/
70 
71 /* Metadata cache (H5AC) callbacks */
72 static herr_t H5FA__cache_hdr_get_initial_load_size(void *udata, size_t *image_len);
73 static htri_t H5FA__cache_hdr_verify_chksum(const void *image_ptr, size_t len, void *udata_ptr);
74 static void *H5FA__cache_hdr_deserialize(const void *image, size_t len,
75     void *udata, hbool_t *dirty);
76 static herr_t H5FA__cache_hdr_image_len(const void *thing, size_t *image_len);
77 static herr_t H5FA__cache_hdr_serialize(const H5F_t *f, void *image, size_t len,
78     void *thing);
79 static herr_t H5FA__cache_hdr_notify(H5AC_notify_action_t action, void *thing);
80 static herr_t H5FA__cache_hdr_free_icr(void *thing);
81 
82 static herr_t H5FA__cache_dblock_get_initial_load_size(void *udata, size_t *image_len);
83 static htri_t H5FA__cache_dblock_verify_chksum(const void *image_ptr, size_t len, void *udata_ptr);
84 static void *H5FA__cache_dblock_deserialize(const void *image, size_t len,
85     void *udata, hbool_t *dirty);
86 static herr_t H5FA__cache_dblock_image_len(const void *thing, size_t *image_len);
87 static herr_t H5FA__cache_dblock_serialize(const H5F_t *f, void *image, size_t len,
88     void *thing);
89 static herr_t H5FA__cache_dblock_notify(H5AC_notify_action_t action, void *thing);
90 static herr_t H5FA__cache_dblock_free_icr(void *thing);
91 static herr_t H5FA__cache_dblock_fsf_size(const void *thing, hsize_t *fsf_size);
92 
93 static herr_t H5FA__cache_dblk_page_get_initial_load_size(void *udata, size_t *image_len);
94 static htri_t H5FA__cache_dblk_page_verify_chksum(const void *image_ptr, size_t len, void *udata_ptr);
95 static void *H5FA__cache_dblk_page_deserialize(const void *image, size_t len,
96     void *udata, hbool_t *dirty);
97 static herr_t H5FA__cache_dblk_page_image_len(const void *thing, size_t *image_len);
98 static herr_t H5FA__cache_dblk_page_serialize(const H5F_t *f, void *image, size_t len,
99     void *thing);
100 static herr_t H5FA__cache_dblk_page_notify(H5AC_notify_action_t action, void *thing);
101 static herr_t H5FA__cache_dblk_page_free_icr(void *thing);
102 
103 
104 /*********************/
105 /* Package Variables */
106 /*********************/
107 
108 /* H5FA header inherits cache-like properties from H5AC */
109 const H5AC_class_t H5AC_FARRAY_HDR[1] = {{
110     H5AC_FARRAY_HDR_ID,                 /* Metadata client ID */
111     "Fixed-array Header",               /* Metadata client name (for debugging) */
112     H5FD_MEM_FARRAY_HDR,                /* File space memory type for client */
113     H5AC__CLASS_NO_FLAGS_SET,           /* Client class behavior flags */
114     H5FA__cache_hdr_get_initial_load_size,      /* 'get_initial_load_size' callback */
115     NULL,				/* 'get_final_load_size' callback */
116     H5FA__cache_hdr_verify_chksum,	/* 'verify_chksum' callback */
117     H5FA__cache_hdr_deserialize,        /* 'deserialize' callback */
118     H5FA__cache_hdr_image_len,          /* 'image_len' callback */
119     NULL,                               /* 'pre_serialize' callback */
120     H5FA__cache_hdr_serialize,          /* 'serialize' callback */
121     H5FA__cache_hdr_notify,             /* 'notify' callback */
122     H5FA__cache_hdr_free_icr,           /* 'free_icr' callback */
123     NULL,                               /* 'fsf_size' callback */
124 }};
125 
126 /* H5FA data block inherits cache-like properties from H5AC */
127 const H5AC_class_t H5AC_FARRAY_DBLOCK[1] = {{
128     H5AC_FARRAY_DBLOCK_ID,              /* Metadata client ID */
129     "Fixed Array Data Block",           /* Metadata client name (for debugging) */
130     H5FD_MEM_FARRAY_DBLOCK,             /* File space memory type for client */
131     H5AC__CLASS_NO_FLAGS_SET,           /* Client class behavior flags */
132     H5FA__cache_dblock_get_initial_load_size,   /* 'get_initial_load_size' callback */
133     NULL,				/* 'get_final_load_size' callback */
134     H5FA__cache_dblock_verify_chksum,	/* 'verify_chksum' callback */
135     H5FA__cache_dblock_deserialize,     /* 'deserialize' callback */
136     H5FA__cache_dblock_image_len,       /* 'image_len' callback */
137     NULL,                               /* 'pre_serialize' callback */
138     H5FA__cache_dblock_serialize,       /* 'serialize' callback */
139     H5FA__cache_dblock_notify,		/* 'notify' callback */
140     H5FA__cache_dblock_free_icr,        /* 'free_icr' callback */
141     H5FA__cache_dblock_fsf_size,        /* 'fsf_size' callback */
142 }};
143 
144 /* H5FA data block page inherits cache-like properties from H5AC */
145 const H5AC_class_t H5AC_FARRAY_DBLK_PAGE[1] = {{
146     H5AC_FARRAY_DBLK_PAGE_ID,           /* Metadata client ID */
147     "Fixed Array Data Block Page",      /* Metadata client name (for debugging) */
148     H5FD_MEM_FARRAY_DBLK_PAGE,          /* File space memory type for client */
149     H5AC__CLASS_NO_FLAGS_SET,           /* Client class behavior flags */
150     H5FA__cache_dblk_page_get_initial_load_size, /* 'get_initial_load_size' callback */
151     NULL,				/* 'get_final_load_size' callback */
152     H5FA__cache_dblk_page_verify_chksum, /* 'verify_chksum' callback */
153     H5FA__cache_dblk_page_deserialize,  /* 'deserialize' callback */
154     H5FA__cache_dblk_page_image_len,    /* 'image_len' callback */
155     NULL,                               /* 'pre_serialize' callback */
156     H5FA__cache_dblk_page_serialize,    /* 'serialize' callback */
157     H5FA__cache_dblk_page_notify,	/* 'notify' callback */
158     H5FA__cache_dblk_page_free_icr,     /* 'free_icr' callback */
159     NULL,                               /* 'fsf_size' callback */
160 }};
161 
162 
163 /*****************************/
164 /* Library Private Variables */
165 /*****************************/
166 
167 
168 /*******************/
169 /* Local Variables */
170 /*******************/
171 
172 
173 
174 /*-------------------------------------------------------------------------
175  * Function:    H5FA__cache_hdr_get_initial_load_size
176  *
177  * Purpose:     Compute the size of the data structure on disk.
178  *
179  * Return:      Non-negative on success/Negative on failure
180  *
181  * Programmer:  Quincey Koziol
182  *              koziol@hdfgroup.org
183  *              July 31, 2013
184  *
185  *-------------------------------------------------------------------------
186  */
187 BEGIN_FUNC(STATIC, NOERR,
188 herr_t, SUCCEED, -,
189 H5FA__cache_hdr_get_initial_load_size(void *_udata, size_t *image_len))
190 
191     /* Local variables */
192     H5FA_hdr_cache_ud_t *udata = (H5FA_hdr_cache_ud_t *)_udata; /* User data for callback */
193 
194     /* Check arguments */
195     HDassert(udata);
196     HDassert(udata->f);
197     HDassert(image_len);
198 
199     /* Set the image length size */
200     *image_len = (size_t)H5FA_HEADER_SIZE_FILE(udata->f);
201 
202 END_FUNC(STATIC)   /* end H5FA__cache_hdr_get_initial_load_size() */
203 
204 
205 /*-------------------------------------------------------------------------
206  * Function:	H5FA__cache_hdr_verify_chksum
207  *
208  * Purpose:     Verify the computed checksum of the data structure is the
209  *              same as the stored chksum.
210  *
211  * Return:      Success:        TRUE/FALSE
212  *              Failure:        Negative
213  *
214  * Programmer:	Vailin Choi; Aug 2015
215  *
216  *-------------------------------------------------------------------------
217  */
218 BEGIN_FUNC(STATIC, NOERR,
219 htri_t, TRUE, -,
220 H5FA__cache_hdr_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSED *_udata))
221 
222     /* Local variables */
223     const uint8_t *image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
224     uint32_t stored_chksum;     /* Stored metadata checksum value */
225     uint32_t computed_chksum;   /* Computed metadata checksum value */
226 
227     /* Check arguments */
228     HDassert(image);
229 
230     /* Get stored and computed checksums */
231     H5F_get_checksums(image, len, &stored_chksum, &computed_chksum);
232 
233     if(stored_chksum != computed_chksum)
234 	ret_value = FALSE;
235 
236 END_FUNC(STATIC) 	/* end H5FA__cache_hdr_verify_chksum() */
237 
238 
239 /*-------------------------------------------------------------------------
240  * Function:	H5FA__cache_hdr_deserialize
241  *
242  * Purpose:	Loads a data structure from the disk.
243  *
244  * Return:	Success:	Pointer to a new Fixed array
245  *		Failure:	NULL
246  *
247  * Programmer:	Quincey Koziol
248  *              koziol@hdfgroup.org
249  *              August 12, 2013
250  *
251  *-------------------------------------------------------------------------
252  */
253 BEGIN_FUNC(STATIC, ERR,
254 void *, NULL, NULL,
255 H5FA__cache_hdr_deserialize(const void *_image, size_t len,
256     void *_udata, hbool_t H5_ATTR_UNUSED *dirty))
257 
258     /* Local variables */
259     H5FA_cls_id_t       id;		/* ID of fixed array class, as found in file */
260     H5FA_hdr_t		*hdr = NULL;    /* Fixed array info */
261     H5FA_hdr_cache_ud_t *udata = (H5FA_hdr_cache_ud_t *)_udata;
262     const uint8_t	*image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
263     uint32_t            stored_chksum;  /* Stored metadata checksum value */
264 
265     /* Check arguments */
266     HDassert(udata);
267     HDassert(udata->f);
268     HDassert(H5F_addr_defined(udata->addr));
269 
270     /* Allocate space for the fixed array data structure */
271     if(NULL == (hdr = H5FA__hdr_alloc(udata->f)))
272         H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array shared header")
273 
274     /* Set the fixed array header's address */
275     hdr->addr = udata->addr;
276 
277     /* Magic number */
278     if(HDmemcmp(image, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
279         H5E_THROW(H5E_BADVALUE, "wrong fixed array header signature")
280     image += H5_SIZEOF_MAGIC;
281 
282     /* Version */
283     if(*image++ != H5FA_HDR_VERSION)
284         H5E_THROW(H5E_VERSION, "wrong fixed array header version")
285 
286     /* Fixed array class */
287     id = (H5FA_cls_id_t)*image++;
288     if(id >= H5FA_NUM_CLS_ID)
289         H5E_THROW(H5E_BADTYPE, "incorrect fixed array class")
290     hdr->cparam.cls = H5FA_client_class_g[id];
291 
292     /* General array creation/configuration information */
293     hdr->cparam.raw_elmt_size = *image++;             /* Element size in file (in bytes) */
294     hdr->cparam.max_dblk_page_nelmts_bits = *image++; /* Log2(Max. # of elements in data block page) -
295 						         i.e. # of bits needed to store max. # of
296 						         elements in data block page. */
297 
298     /* Array statistics */
299     H5F_DECODE_LENGTH(udata->f, image, hdr->cparam.nelmts);	/* Number of elements */
300 
301     /* Internal information */
302     H5F_addr_decode(udata->f, &image, &hdr->dblk_addr); 		/* Address of index block */
303 
304     /* Check for data block */
305     if(H5F_addr_defined(hdr->dblk_addr)) {
306         H5FA_dblock_t  dblock;  	/* Fake data block for computing size */
307         size_t	dblk_page_nelmts;	/* # of elements per data block page */
308 
309         /* Set up fake data block for computing size on disk */
310         dblock.hdr = hdr;
311         dblock.dblk_page_init_size = 0;
312         dblock.npages = 0;
313         dblk_page_nelmts = (size_t)1 << hdr->cparam.max_dblk_page_nelmts_bits;
314         if(hdr->cparam.nelmts > dblk_page_nelmts) {
315             dblock.npages = (size_t)(((hdr->cparam.nelmts + dblk_page_nelmts) - 1) / dblk_page_nelmts);
316             dblock.dblk_page_init_size = (dblock.npages + 7) / 8;
317         } /* end if */
318 
319         /* Compute Fixed Array data block size for hdr statistics */
320         hdr->stats.dblk_size = (size_t)H5FA_DBLOCK_SIZE(&dblock);
321     } /* end if */
322 
323     /* Sanity check */
324     /* (allow for checksum not decoded yet) */
325     HDassert((size_t)(image - (const uint8_t *)_image) == (len - H5FA_SIZEOF_CHKSUM));
326 
327     /* checksum verification already done in verify_chksum cb */
328 
329     /* Metadata checksum */
330     UINT32DECODE(image, stored_chksum);
331 
332     /* Sanity check */
333     HDassert((size_t)(image - (const uint8_t *)_image) == len);
334 
335     /* Finish initializing fixed array header */
336     if(H5FA__hdr_init(hdr, udata->ctx_udata) < 0)
337         H5E_THROW(H5E_CANTINIT, "initialization failed for fixed array header")
338     HDassert(hdr->size == len);
339 
340     /* Set return value */
341     ret_value = hdr;
342 
343 CATCH
344 
345     /* Release resources */
346     if(!ret_value)
347         if(hdr && H5FA__hdr_dest(hdr) < 0)
348             H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header")
349 
350 END_FUNC(STATIC)   /* end H5FA__cache_hdr_deserialize() */
351 
352 
353 /*-------------------------------------------------------------------------
354  * Function:    H5FA__cache_hdr_image_len
355  *
356  * Purpose:     Compute the size of the data structure on disk.
357  *
358  * Return:      Non-negative on success/Negative on failure
359  *
360  * Programmer:  Quincey Koziol
361  *              koziol@hdfgroup.org
362  *              August 12, 2013
363  *
364  *-------------------------------------------------------------------------
365  */
366 BEGIN_FUNC(STATIC, NOERR,
367 herr_t, SUCCEED, -,
368 H5FA__cache_hdr_image_len(const void *_thing, size_t *image_len))
369 
370     /* Local variables */
371     const H5FA_hdr_t *hdr = (const H5FA_hdr_t *)_thing;      /* Pointer to the object */
372 
373     /* Check arguments */
374     HDassert(hdr);
375     HDassert(image_len);
376 
377     /* Set the image length size */
378     *image_len = hdr->size;
379 
380 END_FUNC(STATIC)   /* end H5FA__cache_hdr_image_len() */
381 
382 
383 /*-------------------------------------------------------------------------
384  * Function:	H5FA__cache_hdr_serialize
385  *
386  * Purpose:	Flushes a dirty object to disk.
387  *
388  * Return:	Non-negative on success/Negative on failure
389  *
390  * Programmer:	Quincey Koziol
391  *              koziol@hdfgroup.org
392  *              August 12, 2013
393  *
394  *-------------------------------------------------------------------------
395  */
396 BEGIN_FUNC(STATIC, NOERR,
397 herr_t, SUCCEED, -,
398 H5FA__cache_hdr_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len,
399     void *_thing))
400 
401     /* Local variables */
402     H5FA_hdr_t *hdr = (H5FA_hdr_t *)_thing;     /* Pointer to the fixed array header */
403     uint8_t *image = (uint8_t *)_image;         /* Pointer into raw data buffer */
404     uint32_t metadata_chksum;   /* Computed metadata checksum value */
405 
406     /* check arguments */
407     HDassert(f);
408     HDassert(image);
409     HDassert(hdr);
410 
411     /* Magic number */
412     HDmemcpy(image, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
413     image += H5_SIZEOF_MAGIC;
414 
415     /* Version # */
416     *image++ = H5FA_HDR_VERSION;
417 
418     /* Fixed array type */
419     *image++ = hdr->cparam.cls->id;
420 
421     /* General array creation/configuration information */
422     *image++ = hdr->cparam.raw_elmt_size;          /* Element size in file (in bytes) */
423     *image++ = hdr->cparam.max_dblk_page_nelmts_bits;  /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */
424 
425     /* Array statistics */
426     H5F_ENCODE_LENGTH(f, image, hdr->stats.nelmts);       /* Number of elements for the fixed array */
427 
428     /* Internal information */
429     H5F_addr_encode(f, &image, hdr->dblk_addr);  /* Address of fixed array data block */
430 
431     /* Compute metadata checksum */
432     metadata_chksum = H5_checksum_metadata(_image, (size_t)(image - (uint8_t *)_image), 0);
433 
434     /* Metadata checksum */
435     UINT32ENCODE(image, metadata_chksum);
436 
437     /* Sanity check */
438     HDassert((size_t)(image - (uint8_t *)_image) == len);
439 
440 END_FUNC(STATIC)   /* end H5FA__cache_hdr_serialize() */
441 
442 
443 /*-------------------------------------------------------------------------
444  * Function:	H5FA__cache_hdr_notify
445  *
446  * Purpose:	Handle cache action notifications
447  *
448  * Return:	Non-negative on success/Negative on failure
449  *
450  * Programmer:	Dana Robinson
451  *              December 2015
452  *
453  *-------------------------------------------------------------------------
454  */
455 BEGIN_FUNC(STATIC, ERR,
456 herr_t, SUCCEED, FAIL,
457 H5FA__cache_hdr_notify(H5AC_notify_action_t action, void *_thing))
458 
459     /* Local variables */
460     H5FA_hdr_t *hdr = (H5FA_hdr_t *)_thing;      /* Pointer to the object */
461 
462     /* Sanity check */
463     HDassert(hdr);
464 
465     /* Check if the file was opened with SWMR-write access */
466     if(hdr->swmr_write) {
467         /* Determine which action to take */
468         switch(action) {
469             case H5AC_NOTIFY_ACTION_AFTER_INSERT:
470             case H5AC_NOTIFY_ACTION_AFTER_LOAD:
471             case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
472             case H5AC_NOTIFY_ACTION_ENTRY_DIRTIED:
473             case H5AC_NOTIFY_ACTION_ENTRY_CLEANED:
474             case H5AC_NOTIFY_ACTION_CHILD_DIRTIED:
475             case H5AC_NOTIFY_ACTION_CHILD_CLEANED:
476             case H5AC_NOTIFY_ACTION_CHILD_UNSERIALIZED:
477             case H5AC_NOTIFY_ACTION_CHILD_SERIALIZED:
478                 /* do nothing */
479                 break;
480 
481             case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
482                 /* If hdr->parent != NULL, hdr->parent is used to destroy
483                  * the flush dependency before the header is evicted.
484                  */
485                 if(hdr->parent) {
486                     /* Sanity check */
487                     HDassert(hdr->top_proxy);
488 
489 		    /* Destroy flush dependency on object header proxy */
490 		    if(H5AC_proxy_entry_remove_child((H5AC_proxy_entry_t *)hdr->parent, (void *)hdr->top_proxy) < 0)
491 		        H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between fixed array and proxy")
492                     hdr->parent = NULL;
493 		} /* end if */
494 
495                 /* Detach from 'top' proxy for fixed array */
496                 if(hdr->top_proxy) {
497                     if(H5AC_proxy_entry_remove_child(hdr->top_proxy, hdr) < 0)
498                         H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between header and fixed array 'top' proxy")
499                     /* Don't reset hdr->top_proxy here, it's destroyed when the header is freed -QAK */
500                 } /* end if */
501                 break;
502 
503             default:
504 #ifdef NDEBUG
505                 H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache")
506 #else /* NDEBUG */
507                 HDassert(0 && "Unknown action?!?");
508 #endif /* NDEBUG */
509         } /* end switch */
510     } /* end if */
511     else
512         HDassert(NULL == hdr->parent);
513 
514 CATCH
515 
516 END_FUNC(STATIC)   /* end H5FA__cache_hdr_notify() */
517 
518 
519 /*-------------------------------------------------------------------------
520  * Function:	H5FA__cache_hdr_free_icr
521  *
522  * Purpose:	Destroy/release an "in core representation" of a data
523  *              structure
524  *
525  * Return:      SUCCEED/FAIL
526  *
527  * Programmer:	Quincey Koziol
528  *              koziol@hdfgroup.org
529  *              August 12, 2013
530  *
531  *-------------------------------------------------------------------------
532  */
533 BEGIN_FUNC(STATIC, ERR,
534 herr_t, SUCCEED, FAIL,
535 H5FA__cache_hdr_free_icr(void *thing))
536 
537     /* Check arguments */
538     HDassert(thing);
539 
540     /* Release the extensible array header */
541     if(H5FA__hdr_dest((H5FA_hdr_t *)thing) < 0)
542         H5E_THROW(H5E_CANTFREE, "can't free fixed array header")
543 
544 CATCH
545 
546 END_FUNC(STATIC)   /* end H5FA__cache_hdr_free_icr() */
547 
548 
549 /*-------------------------------------------------------------------------
550  * Function:    H5FA__cache_dblock_get_initial_load_size
551  *
552  * Purpose:     Compute the size of the data structure on disk.
553  *
554  * Return:      Non-negative on success/Negative on failure
555  *
556  * Programmer:  Quincey Koziol
557  *              koziol@hdfgroup.org
558  *              August 12, 2013
559  *
560  *-------------------------------------------------------------------------
561  */
562 BEGIN_FUNC(STATIC, NOERR,
563 herr_t, SUCCEED, -,
564 H5FA__cache_dblock_get_initial_load_size(void *_udata, size_t *image_len))
565 
566     /* Local variables */
567     H5FA_dblock_cache_ud_t *udata = (H5FA_dblock_cache_ud_t *)_udata;      /* User data */
568     H5FA_dblock_t dblock;           			/* Fake data block for computing size */
569     size_t dblk_page_nelmts;				/* # of elements per data block page */
570 
571     /* Check arguments */
572     HDassert(udata);
573     HDassert(udata->hdr);
574     HDassert(image_len);
575 
576     /* Set up fake data block for computing size on disk */
577     /* (Note: extracted from H5FA__dblock_alloc) */
578     HDmemset(&dblock, 0, sizeof(dblock));
579 
580     /* Set up fake data block for computing size on disk
581      *
582      * need: dblock->hdr
583      *       dblock->npages
584      *       dblock->dblk_page_init_size
585      */
586     dblock.hdr = udata->hdr;
587     dblk_page_nelmts = (size_t)1 << udata->hdr->cparam.max_dblk_page_nelmts_bits;
588     if(udata->hdr->cparam.nelmts > dblk_page_nelmts) {
589         dblock.npages = (size_t)(((udata->hdr->cparam.nelmts + dblk_page_nelmts) - 1) / dblk_page_nelmts);
590         dblock.dblk_page_init_size = (dblock.npages + 7) / 8;
591     } /* end if */
592 
593     /* Set the image length size */
594     if(!dblock.npages)
595         *image_len = (size_t)H5FA_DBLOCK_SIZE(&dblock);
596     else
597         *image_len = (size_t)H5FA_DBLOCK_PREFIX_SIZE(&dblock);
598 
599 END_FUNC(STATIC)   /* end H5FA__cache_dblock_get_initial_load_size() */
600 
601 
602 /*-------------------------------------------------------------------------
603  * Function:	H5FA__cache_dblock_verify_chksum
604  *
605  * Purpose:     Verify the computed checksum of the data structure is the
606  *              same as the stored chksum.
607  *
608  * Return:      Success:        TRUE/FALSE
609  *              Failure:        Negative
610  *
611  * Programmer:	Vailin Choi; Aug 2015
612  *
613  *-------------------------------------------------------------------------
614  */
615 BEGIN_FUNC(STATIC, NOERR,
616 htri_t, TRUE, -,
617 H5FA__cache_dblock_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSED *_udata))
618 
619     /* Local variables */
620     const uint8_t *image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
621     uint32_t stored_chksum;     /* Stored metadata checksum value */
622     uint32_t computed_chksum;   /* Computed metadata checksum value */
623 
624     /* Check arguments */
625     HDassert(image);
626 
627     /* Get stored and computed checksums */
628     H5F_get_checksums(image, len, &stored_chksum, &computed_chksum);
629 
630     if(stored_chksum != computed_chksum)
631 	ret_value = FALSE;
632 
633 END_FUNC(STATIC) 	/* end H5FA__cache_dblock_verify_chksum() */
634 
635 
636 /*-------------------------------------------------------------------------
637  * Function:	H5FA__cache_dblock_deserialize
638  *
639  * Purpose:	Loads a data structure from the disk.
640  *
641  * Return:	Success:	Pointer to a new B-tree.
642  *		Failure:	NULL
643  *
644  * Programmer:	Quincey Koziol
645  *              koziol@hdfgroup.org
646  *              August 14, 2013
647  *
648  *-------------------------------------------------------------------------
649  */
650 BEGIN_FUNC(STATIC, ERR,
651 void *, NULL, NULL,
652 H5FA__cache_dblock_deserialize(const void *_image, size_t len,
653     void *_udata, hbool_t H5_ATTR_UNUSED *dirty))
654 
655     /* Local variables */
656     H5FA_dblock_t  *dblock = NULL;  /* Data block info */
657     H5FA_dblock_cache_ud_t *udata = (H5FA_dblock_cache_ud_t *)_udata; /* User data for loading data block */
658     const uint8_t  *image = (const uint8_t *)_image;    /* Pointer into raw data buffer */
659     uint32_t       stored_chksum;   /* Stored metadata checksum value */
660     haddr_t        arr_addr;        /* Address of array header in the file */
661 
662     /* Sanity check */
663     HDassert(udata);
664     HDassert(udata->hdr);
665 
666     /* Allocate the fixed array data block */
667     if(NULL == (dblock = H5FA__dblock_alloc(udata->hdr)))
668         H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block")
669 
670     HDassert(((!dblock->npages) && (len == (size_t)H5FA_DBLOCK_SIZE(dblock)))
671              || (len == (size_t)H5FA_DBLOCK_PREFIX_SIZE(dblock)));
672 
673     /* Set the fixed array data block's information */
674     dblock->addr = udata->dblk_addr;
675 
676     /* Magic number */
677     if(HDmemcmp(image, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC))
678         H5E_THROW(H5E_BADVALUE, "wrong fixed array data block signature")
679     image += H5_SIZEOF_MAGIC;
680 
681     /* Version */
682     if(*image++ != H5FA_DBLOCK_VERSION)
683         H5E_THROW(H5E_VERSION, "wrong fixed array data block version")
684 
685     /* Fixed array type */
686     if(*image++ != (uint8_t)udata->hdr->cparam.cls->id)
687         H5E_THROW(H5E_BADTYPE, "incorrect fixed array class")
688 
689     /* Address of header for array that owns this block (just for file integrity checks) */
690     H5F_addr_decode(udata->hdr->f, &image, &arr_addr);
691     if(H5F_addr_ne(arr_addr, udata->hdr->addr))
692         H5E_THROW(H5E_BADVALUE, "wrong fixed array header address")
693 
694     /* Page initialization flags */
695     if(dblock->npages > 0) {
696 	HDmemcpy(dblock->dblk_page_init, image, dblock->dblk_page_init_size);
697         image += dblock->dblk_page_init_size;
698     } /* end if */
699 
700     /* Only decode elements if the data block is not paged */
701     if(!dblock->npages) {
702         /* Decode elements in data block */
703         /* Convert from raw elements on disk into native elements in memory */
704         if((udata->hdr->cparam.cls->decode)(image, dblock->elmts, (size_t)udata->hdr->cparam.nelmts, udata->hdr->cb_ctx) < 0)
705             H5E_THROW(H5E_CANTDECODE, "can't decode fixed array data elements")
706         image += (udata->hdr->cparam.nelmts * udata->hdr->cparam.raw_elmt_size);
707     } /* end if */
708 
709     /* Sanity check */
710     /* (allow for checksum not decoded yet) */
711     HDassert((size_t)(image - (const uint8_t *)_image) == (len - H5FA_SIZEOF_CHKSUM));
712 
713     /* Set the data block's size */
714     dblock->size = H5FA_DBLOCK_SIZE(dblock);
715 
716     /* checksum verification already done in verify_chksum cb */
717 
718     /* Metadata checksum */
719     UINT32DECODE(image, stored_chksum);
720 
721     /* Sanity check */
722     HDassert((size_t)(image - (const uint8_t *)_image) == len);
723 
724     /* Set return value */
725     ret_value = dblock;
726 
727 CATCH
728 
729     /* Release resources */
730     if(!ret_value)
731         if(dblock && H5FA__dblock_dest(dblock) < 0)
732             H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block")
733 
734 END_FUNC(STATIC)   /* end H5FA__cache_dblock_deserialize() */
735 
736 
737 /*-------------------------------------------------------------------------
738  * Function:    H5FA__cache_dblock_image_len
739  *
740  * Purpose:     Compute the size of the data structure on disk.
741  *
742  * Return:      Non-negative on success/Negative on failure
743  *
744  * Programmer:  Quincey Koziol
745  *              koziol@hdfgroup.org
746  *              August 14, 2013
747  *
748  *-------------------------------------------------------------------------
749  */
750 BEGIN_FUNC(STATIC, NOERR,
751 herr_t, SUCCEED, -,
752 H5FA__cache_dblock_image_len(const void *_thing, size_t *image_len))
753 
754     /* Local variables */
755     const H5FA_dblock_t *dblock = (const H5FA_dblock_t *)_thing;      /* Pointer to the object */
756 
757     /* Check arguments */
758     HDassert(dblock);
759     HDassert(image_len);
760 
761     /* Set the image length size */
762     if(!dblock->npages)
763         *image_len = (size_t)dblock->size;
764     else
765         *image_len = H5FA_DBLOCK_PREFIX_SIZE(dblock);
766 
767 END_FUNC(STATIC)   /* end H5FA__cache_dblock_image_len() */
768 
769 
770 /*-------------------------------------------------------------------------
771  * Function:	H5FA__cache_dblock_serialize
772  *
773  * Purpose:	Flushes a dirty object to disk.
774  *
775  * Return:	Non-negative on success/Negative on failure
776  *
777  * Programmer:	Quincey Koziol
778  *              koziol@hdfgroup.org
779  *              August 14, 2013
780  *
781  *-------------------------------------------------------------------------
782  */
783 BEGIN_FUNC(STATIC, ERR,
784 herr_t, SUCCEED, FAIL,
785 H5FA__cache_dblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len,
786     void *_thing))
787 
788     /* Local variables */
789     H5FA_dblock_t *dblock = (H5FA_dblock_t *)_thing;      /* Pointer to the object to serialize */
790     uint8_t *image = (uint8_t *)_image;         /* Pointer into raw data buffer */
791     uint32_t metadata_chksum; /* Computed metadata checksum value */
792 
793     /* Check arguments */
794     HDassert(f);
795     HDassert(image);
796     HDassert(dblock);
797     HDassert(dblock->hdr);
798 
799     /* Magic number */
800     HDmemcpy(image, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC);
801     image += H5_SIZEOF_MAGIC;
802 
803     /* Version # */
804     *image++ = H5FA_DBLOCK_VERSION;
805 
806     /* Fixed array type */
807     *image++ = dblock->hdr->cparam.cls->id;
808 
809     /* Address of array header for array which owns this block */
810     H5F_addr_encode(f, &image, dblock->hdr->addr);
811 
812     /* Page init flags */
813     if(dblock->npages > 0) {
814         /* Store the 'page init' bitmasks */
815         HDmemcpy(image, dblock->dblk_page_init, dblock->dblk_page_init_size);
816         image += dblock->dblk_page_init_size;
817     } /* end if */
818 
819     /* Only encode elements if the data block is not paged */
820     if(!dblock->npages) {
821         /* Encode elements in data block */
822 
823         /* Convert from native elements in memory into raw elements on disk */
824         H5_CHECK_OVERFLOW(dblock->hdr->cparam.nelmts, /* From: */hsize_t, /* To: */size_t);
825         if((dblock->hdr->cparam.cls->encode)(image, dblock->elmts, (size_t)dblock->hdr->cparam.nelmts, dblock->hdr->cb_ctx) < 0)
826             H5E_THROW(H5E_CANTENCODE, "can't encode fixed array data elements")
827         image += (dblock->hdr->cparam.nelmts * dblock->hdr->cparam.raw_elmt_size);
828     } /* end if */
829 
830     /* Compute metadata checksum */
831     metadata_chksum = H5_checksum_metadata(_image, (size_t)(image - (uint8_t *)_image), 0);
832 
833     /* Metadata checksum */
834     UINT32ENCODE(image, metadata_chksum);
835 
836     /* Sanity check */
837     HDassert((size_t)(image - (uint8_t *)_image) == len);
838 
839 CATCH
840 
841 END_FUNC(STATIC)   /* end H5FA__cache_dblock_serialize() */
842 
843 
844 /*-------------------------------------------------------------------------
845  * Function:    H5FA__cache_dblock_notify
846  *
847  * Purpose:     Handle cache action notifications
848  *
849  * Return:      SUCCEED/FAIL
850  *
851  * Programmer:  Dana Robinson
852  *              Fall 2012
853  *
854  *-------------------------------------------------------------------------
855  */
856 BEGIN_FUNC(STATIC, ERR,
857 herr_t, SUCCEED, FAIL,
858 H5FA__cache_dblock_notify(H5AC_notify_action_t action, void *_thing))
859 
860     /* Local variables */
861     H5FA_dblock_t *dblock = (H5FA_dblock_t *)_thing;
862 
863     /* Sanity check */
864     HDassert(dblock);
865 
866     /* Check if the file was opened with SWMR-write access */
867     if(dblock->hdr->swmr_write) {
868         /* Determine which action to take */
869         switch(action) {
870             case H5AC_NOTIFY_ACTION_AFTER_INSERT:
871 	    case H5AC_NOTIFY_ACTION_AFTER_LOAD:
872                 /* Create flush dependency on parent */
873                 if(H5FA__create_flush_depend((H5AC_info_t *)dblock->hdr, (H5AC_info_t *)dblock) < 0)
874                     H5E_THROW(H5E_CANTDEPEND, "unable to create flush dependency between data block and header, address = %llu", (unsigned long long)dblock->addr)
875                 break;
876 
877 	    case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
878             case H5AC_NOTIFY_ACTION_ENTRY_DIRTIED:
879             case H5AC_NOTIFY_ACTION_ENTRY_CLEANED:
880             case H5AC_NOTIFY_ACTION_CHILD_DIRTIED:
881             case H5AC_NOTIFY_ACTION_CHILD_CLEANED:
882             case H5AC_NOTIFY_ACTION_CHILD_UNSERIALIZED:
883             case H5AC_NOTIFY_ACTION_CHILD_SERIALIZED:
884                 /* do nothing */
885                 break;
886 
887             case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
888 		/* Destroy flush dependency on parent */
889                 if(H5FA__destroy_flush_depend((H5AC_info_t *)dblock->hdr, (H5AC_info_t *)dblock) < 0)
890                     H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency")
891 
892                 /* Detach from 'top' proxy for fixed array */
893                 if(dblock->top_proxy) {
894                     if(H5AC_proxy_entry_remove_child(dblock->top_proxy, dblock) < 0)
895                         H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block and fixed array 'top' proxy")
896                     dblock->top_proxy = NULL;
897                 } /* end if */
898                 break;
899 
900             default:
901 #ifdef NDEBUG
902                 H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache")
903 #else /* NDEBUG */
904                 HDassert(0 && "Unknown action?!?");
905 #endif /* NDEBUG */
906         } /* end switch */
907     } /* end if */
908 
909 CATCH
910 
911 END_FUNC(STATIC)   /* end H5FA__cache_dblock_notify() */
912 
913 
914 
915 /*-------------------------------------------------------------------------
916  * Function:	H5FA__cache_dblock_free_icr
917  *
918  * Purpose:	Destroy/release an "in core representation" of a data
919  *              structure
920  *
921  * Return:      SUCCEED/FAIL
922  *
923  * Programmer:	Quincey Koziol
924  *              koziol@hdfgroup.org
925  *              August 14, 2013
926  *
927  *-------------------------------------------------------------------------
928  */
929 BEGIN_FUNC(STATIC, ERR,
930 herr_t, SUCCEED, FAIL,
931 H5FA__cache_dblock_free_icr(void *_thing))
932 
933     H5FA_dblock_t *dblock = (H5FA_dblock_t *)_thing;    /* Pointer to the object */
934 
935     /* Check arguments */
936     HDassert(dblock);
937 
938     /* Release the fixed array data block */
939     if(H5FA__dblock_dest(dblock) < 0)
940         H5E_THROW(H5E_CANTFREE, "can't free fixed array data block")
941 
942 CATCH
943 
944 END_FUNC(STATIC)   /* end H5FA__cache_dblock_free_icr() */
945 
946 
947 /*-------------------------------------------------------------------------
948  * Function:	H5FA__cache_dblock_fsf_size
949  *
950  * Purpose:	Tell the metadata cache the actual amount of file space
951  *		to free when a dblock entry is destroyed with the free
952  *		file space block set.
953  *
954  *		This function is needed when the data block is paged, as
955  *		the datablock header and all its pages are allocted as a
956  *		single contiguous chunk of file space, and must be
957  *		deallocated the same way.
958  *
959  *		The size of the chunk of memory in which the dblock
960  *		header and all its pages is stored in the size field,
961  *		so we simply pass that value back to the cache.
962  *
963  *		If the datablock is not paged, then the size field of
964  *		the cache_info contains the correct size.  However this
965  *		value will be the same as the size field, so we return
966  *		the contents of the size field to the cache in this case
967  *		as well.
968  *
969  * Return:	Non-negative on success/Negative on failure
970  *
971  * Programmer:	John Mainzer
972  *              12/5/14
973  *
974  *-------------------------------------------------------------------------
975  */
976 BEGIN_FUNC(STATIC, NOERR,
977 herr_t, SUCCEED, -,
978 H5FA__cache_dblock_fsf_size(const void *_thing, hsize_t *fsf_size))
979 
980     const H5FA_dblock_t *dblock = (const H5FA_dblock_t *)_thing;    /* Pointer to the object */
981 
982     /* Check arguments */
983     HDassert(dblock);
984     HDassert(dblock->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
985     HDassert(dblock->cache_info.type == H5AC_FARRAY_DBLOCK);
986     HDassert(fsf_size);
987 
988     *fsf_size = dblock->size;
989 
990 END_FUNC(STATIC)   /* end H5FA__cache_dblock_fsf_size() */
991 
992 
993 /*-------------------------------------------------------------------------
994  * Function:    H5FA__cache_dblk_page_get_initial_load_size
995  *
996  * Purpose:     Compute the size of the data structure on disk.
997  *
998  * Return:      Non-negative on success/Negative on failure
999  *
1000  * Programmer:  Quincey Koziol
1001  *              koziol@hdfgroup.org
1002  *              August 14, 2013
1003  *
1004  *-------------------------------------------------------------------------
1005  */
1006 BEGIN_FUNC(STATIC, NOERR,
1007 herr_t, SUCCEED, -,
1008 H5FA__cache_dblk_page_get_initial_load_size(void *_udata, size_t *image_len))
1009 
1010     /* Local variables */
1011     H5FA_dblk_page_cache_ud_t *udata = (H5FA_dblk_page_cache_ud_t *)_udata;      /* User data */
1012 
1013     /* Check arguments */
1014     HDassert(udata);
1015     HDassert(udata->hdr);
1016     HDassert(udata->nelmts > 0);
1017     HDassert(image_len);
1018 
1019     /* Set the image length size */
1020     *image_len = (size_t)H5FA_DBLK_PAGE_SIZE(udata->hdr, udata->nelmts);
1021 
1022 END_FUNC(STATIC)   /* end H5FA__cache_dblk_page_get_initial_load_size() */
1023 
1024 
1025 /*-------------------------------------------------------------------------
1026  * Function:	H5FA__cache_dblk_page_verify_chksum
1027  *
1028  * Purpose:     Verify the computed checksum of the data structure is the
1029  *              same as the stored chksum.
1030  *
1031  * Return:      Success:        TRUE/FALSE
1032  *              Failure:        Negative
1033  *
1034  * Programmer:	Vailin Choi; Aug 2015
1035  *
1036  *-------------------------------------------------------------------------
1037  */
1038 BEGIN_FUNC(STATIC, NOERR,
1039 htri_t, TRUE, -,
1040 H5FA__cache_dblk_page_verify_chksum(const void *_image, size_t len, void H5_ATTR_UNUSED *_udata))
1041 
1042     /* Local variables */
1043     const uint8_t *image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
1044     uint32_t stored_chksum;     /* Stored metadata checksum value */
1045     uint32_t computed_chksum;   /* Computed metadata checksum value */
1046 
1047     /* Check arguments */
1048     HDassert(image);
1049 
1050     /* Get stored and computed checksums */
1051     H5F_get_checksums(image, len, &stored_chksum, &computed_chksum);
1052 
1053     if(stored_chksum != computed_chksum)
1054 	ret_value = FALSE;
1055 
1056 END_FUNC(STATIC) 	/* end H5FA__cache_dblk_page_verify_chksum() */
1057 
1058 
1059 /*-------------------------------------------------------------------------
1060  * Function:	H5FA__cache_dblk_page_deserialize
1061  *
1062  * Purpose:	Loads a data structure from the disk.
1063  *
1064  * Return:	Success:	Pointer to a new B-tree.
1065  *		Failure:	NULL
1066  *
1067  * Programmer:	Quincey Koziol
1068  *              koziol@hdfgroup.org
1069  *              August 14, 2013
1070  *
1071  *-------------------------------------------------------------------------
1072  */
1073 BEGIN_FUNC(STATIC, ERR,
1074 void *, NULL, NULL,
1075 H5FA__cache_dblk_page_deserialize(const void *_image, size_t len,
1076     void *_udata, hbool_t H5_ATTR_UNUSED *dirty))
1077 
1078     /* Local variables */
1079     H5FA_dblk_page_t    *dblk_page = NULL; /* Data block page info */
1080     H5FA_dblk_page_cache_ud_t *udata = (H5FA_dblk_page_cache_ud_t *)_udata; /* User data for loading data block page */
1081     const uint8_t	*image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
1082     uint32_t            stored_chksum;  /* Stored metadata checksum value */
1083 
1084     /* Sanity check */
1085     HDassert(udata);
1086     HDassert(udata->hdr);
1087     HDassert(udata->nelmts > 0);
1088     HDassert(H5F_addr_defined(udata->dblk_page_addr));
1089 
1090     /* Allocate the fixed array data block page */
1091     if(NULL == (dblk_page = H5FA__dblk_page_alloc(udata->hdr, udata->nelmts)))
1092         H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block page")
1093 
1094     /* Set the fixed array data block's information */
1095     dblk_page->addr = udata->dblk_page_addr;
1096 
1097     /* Internal information */
1098 
1099     /* Decode elements in data block page */
1100     /* Convert from raw elements on disk into native elements in memory */
1101     if((udata->hdr->cparam.cls->decode)(image, dblk_page->elmts, udata->nelmts, udata->hdr->cb_ctx) < 0)
1102         H5E_THROW(H5E_CANTDECODE, "can't decode fixed array data elements")
1103     image += (udata->nelmts * udata->hdr->cparam.raw_elmt_size);
1104 
1105     /* Sanity check */
1106     /* (allow for checksum not decoded yet) */
1107     HDassert((size_t)(image - (const uint8_t *)_image) == (len - H5FA_SIZEOF_CHKSUM));
1108 
1109     /* Set the data block page's size */
1110     dblk_page->size = len;
1111 
1112     /* checksum verification already done in verify_chksum cb */
1113 
1114     /* Metadata checksum */
1115     UINT32DECODE(image, stored_chksum);
1116 
1117     /* Sanity check */
1118     HDassert((size_t)(image - (const uint8_t *)_image) == dblk_page->size);
1119 
1120     /* Set return value */
1121     ret_value = dblk_page;
1122 
1123 CATCH
1124 
1125     /* Release resources */
1126     if(!ret_value)
1127         if(dblk_page && H5FA__dblk_page_dest(dblk_page) < 0)
1128             H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page")
1129 
1130 END_FUNC(STATIC)   /* end H5FA__cache_dblk_page_deserialize() */
1131 
1132 
1133 /*-------------------------------------------------------------------------
1134  * Function:    H5FA__cache_dblk_page_image_len
1135  *
1136  * Purpose:     Compute the size of the data structure on disk.
1137  *
1138  * Return:      Non-negative on success/Negative on failure
1139  *
1140  * Programmer:  Quincey Koziol
1141  *              koziol@hdfgroup.org
1142  *              August 14, 2013
1143  *
1144  *-------------------------------------------------------------------------
1145  */
1146 BEGIN_FUNC(STATIC, NOERR,
1147 herr_t, SUCCEED, -,
1148 H5FA__cache_dblk_page_image_len(const void *_thing, size_t *image_len))
1149 
1150     /* Local variables */
1151     const H5FA_dblk_page_t *dblk_page = (const H5FA_dblk_page_t *)_thing;      /* Pointer to the object */
1152 
1153     /* Check arguments */
1154     HDassert(dblk_page);
1155     HDassert(image_len);
1156 
1157     /* Set the image length size */
1158     *image_len = dblk_page->size;
1159 
1160 END_FUNC(STATIC)   /* end H5FA__cache_dblk_page_image_len() */
1161 
1162 
1163 /*-------------------------------------------------------------------------
1164  * Function:	H5FA__cache_dblk_page_serialize
1165  *
1166  * Purpose:	Flushes a dirty object to disk.
1167  *
1168  * Return:	SUCCEED/FAIL
1169  *
1170  * Programmer:	Quincey Koziol
1171  *              koziol@hdfgroup.org
1172  *              August 14, 2013
1173  *
1174  *-------------------------------------------------------------------------
1175  */
1176 BEGIN_FUNC(STATIC, ERR,
1177 herr_t, SUCCEED, FAIL,
1178 H5FA__cache_dblk_page_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len,
1179     void *_thing))
1180 
1181     /* Local variables */
1182     H5FA_dblk_page_t *dblk_page = (H5FA_dblk_page_t *)_thing;      /* Pointer to the object to serialize */
1183     uint8_t *image = (uint8_t *)_image;         /* Pointer into raw data buffer */
1184     uint32_t metadata_chksum;   /* Computed metadata checksum value */
1185 
1186     /* Sanity check */
1187     HDassert(f);
1188     HDassert(image);
1189     HDassert(dblk_page);
1190     HDassert(dblk_page->hdr);
1191 
1192     /* Internal information */
1193 
1194     /* Encode elements in data block page */
1195 
1196     /* Convert from native elements in memory into raw elements on disk */
1197     if((dblk_page->hdr->cparam.cls->encode)(image, dblk_page->elmts, dblk_page->nelmts, dblk_page->hdr->cb_ctx) < 0)
1198         H5E_THROW(H5E_CANTENCODE, "can't encode fixed array data elements")
1199     image += (dblk_page->nelmts * dblk_page->hdr->cparam.raw_elmt_size);
1200 
1201     /* Compute metadata checksum */
1202     metadata_chksum = H5_checksum_metadata(_image, (size_t)(image - (uint8_t *)_image), 0);
1203 
1204     /* Metadata checksum */
1205     UINT32ENCODE(image, metadata_chksum);
1206 
1207     /* Sanity check */
1208     HDassert((size_t)(image - (uint8_t *)_image) == len);
1209 
1210 CATCH
1211 
1212 END_FUNC(STATIC)   /* end H5FA__cache_dblk_page_serialize() */
1213 
1214 
1215 /*-------------------------------------------------------------------------
1216  * Function:	H5FA__cache_dblk_page_notify
1217  *
1218  * Purpose:	Handle cache action notifications
1219  *
1220  * Return:	Non-negative on success/Negative on failure
1221  *
1222  * Programmer:	Quincey Koziol
1223  *		koziol@lbl.gov
1224  *		Oct 17 2016
1225  *
1226  *-------------------------------------------------------------------------
1227  */
1228 BEGIN_FUNC(STATIC, ERR,
1229 herr_t, SUCCEED, FAIL,
1230 H5FA__cache_dblk_page_notify(H5AC_notify_action_t action, void *_thing))
1231 
1232     /* Local variables */
1233     H5FA_dblk_page_t *dblk_page = (H5FA_dblk_page_t *)_thing;      /* Pointer to the object */
1234 
1235     /* Sanity check */
1236     HDassert(dblk_page);
1237 
1238     /* Determine which action to take */
1239     switch(action) {
1240         case H5AC_NOTIFY_ACTION_AFTER_INSERT:
1241         case H5AC_NOTIFY_ACTION_AFTER_LOAD:
1242         case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
1243             /* do nothing */
1244             break;
1245 
1246         case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
1247             /* Detach from 'top' proxy for fixed array */
1248             if(dblk_page->top_proxy) {
1249                 if(H5AC_proxy_entry_remove_child(dblk_page->top_proxy, dblk_page) < 0)
1250                     H5E_THROW(H5E_CANTUNDEPEND, "unable to destroy flush dependency between data block page and fixed array 'top' proxy")
1251                 dblk_page->top_proxy = NULL;
1252             } /* end if */
1253             break;
1254 
1255         case H5AC_NOTIFY_ACTION_ENTRY_DIRTIED:
1256         case H5AC_NOTIFY_ACTION_ENTRY_CLEANED:
1257         case H5AC_NOTIFY_ACTION_CHILD_DIRTIED:
1258         case H5AC_NOTIFY_ACTION_CHILD_CLEANED:
1259         case H5AC_NOTIFY_ACTION_CHILD_UNSERIALIZED:
1260         case H5AC_NOTIFY_ACTION_CHILD_SERIALIZED:
1261             /* do nothing */
1262             break;
1263 
1264         default:
1265 #ifdef NDEBUG
1266             H5E_THROW(H5E_BADVALUE, "unknown action from metadata cache")
1267 #else /* NDEBUG */
1268             HDassert(0 && "Unknown action?!?");
1269 #endif /* NDEBUG */
1270     } /* end switch */
1271 
1272 CATCH
1273 
1274 END_FUNC(STATIC)   /* end H5FA__cache_dblk_page_notify() */
1275 
1276 
1277 /*-------------------------------------------------------------------------
1278  * Function:	H5FA__cache_dblk_page_free_icr
1279  *
1280  * Purpose:	Destroy/release an "in core representation" of a data
1281  *              structure
1282  *
1283  * Return:	Non-negative on success/Negative on failure
1284  *
1285  * Programmer:	Quincey Koziol
1286  *              koziol@hdfgroup.org
1287  *              August 14, 2013
1288  *
1289  *-------------------------------------------------------------------------
1290  */
1291 BEGIN_FUNC(STATIC, ERR,
1292 herr_t, SUCCEED, FAIL,
1293 H5FA__cache_dblk_page_free_icr(void *thing))
1294 
1295     /* Check arguments */
1296     HDassert(thing);
1297 
1298     /* Release the fixed array data block page */
1299     if(H5FA__dblk_page_dest((H5FA_dblk_page_t *)thing) < 0)
1300         H5E_THROW(H5E_CANTFREE, "can't free fixed array data block page")
1301 
1302 CATCH
1303 
1304 END_FUNC(STATIC)   /* end H5FA__cache_dblk_page_free_icr() */
1305 
1306