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:		H5Fsuper_cache.c
17  *			Aug 15 2009
18  *			Quincey Koziol <koziol@hdfgroup.org>
19  *
20  * Purpose:		Implement file superblock & driver info metadata cache methods.
21  *
22  *-------------------------------------------------------------------------
23  */
24 
25 /****************/
26 /* Module Setup */
27 /****************/
28 
29 #include "H5Fmodule.h"          /* This source code file is part of the H5F module */
30 #define H5G_FRIEND		/*suppress error about including H5Gpkg	  */
31 
32 
33 /***********/
34 /* Headers */
35 /***********/
36 #include "H5private.h"		/* Generic Functions			*/
37 #include "H5Eprivate.h"		/* Error handling		  	*/
38 #include "H5Fpkg.h"             /* File access				*/
39 #include "H5FDprivate.h"	/* File drivers				*/
40 #include "H5FLprivate.h"        /* Free Lists                           */
41 #include "H5Gpkg.h"		/* Groups		  		*/
42 #include "H5Iprivate.h"		/* IDs			  		*/
43 #include "H5MMprivate.h"        /* Memory management                    */
44 #include "H5Pprivate.h"		/* Property lists			*/
45 #include "H5SMprivate.h"        /* Shared Object Header Messages        */
46 
47 
48 /****************/
49 /* Local Macros */
50 /****************/
51 
52 
53 /******************/
54 /* Local Typedefs */
55 /******************/
56 
57 
58 /********************/
59 /* Package Typedefs */
60 /********************/
61 
62 
63 /********************/
64 /* Local Prototypes */
65 /********************/
66 
67 /* Metadata cache (H5AC) callbacks */
68 static herr_t H5F__cache_superblock_get_initial_load_size(void *udata, size_t *image_len);
69 static herr_t H5F__cache_superblock_get_final_load_size(const void *image_ptr,
70     size_t image_len, void *udata, size_t *actual_len);
71 static htri_t H5F__cache_superblock_verify_chksum(const void *image_ptr, size_t len, void *udata_ptr);
72 static void *H5F__cache_superblock_deserialize(const void *image, size_t len,
73     void *udata, hbool_t *dirty);
74 static herr_t H5F__cache_superblock_image_len(const void *thing, size_t *image_len);
75 static herr_t H5F__cache_superblock_serialize(const H5F_t *f, void *image, size_t len,
76     void *thing);
77 static herr_t H5F__cache_superblock_free_icr(void *thing);
78 
79 static herr_t H5F__cache_drvrinfo_get_initial_load_size(void *udata, size_t *image_len);
80 static herr_t H5F__cache_drvrinfo_get_final_load_size(const void *image_ptr,
81     size_t image_len, void *udata, size_t *actual_len);
82 static void *H5F__cache_drvrinfo_deserialize(const void *image, size_t len,
83     void *udata, hbool_t *dirty);
84 static herr_t H5F__cache_drvrinfo_image_len(const void *thing, size_t *image_len);
85 static herr_t H5F__cache_drvrinfo_serialize(const H5F_t *f, void *image, size_t len,
86     void *thing);
87 static herr_t H5F__cache_drvrinfo_free_icr(void *thing);
88 
89 /* Local encode/decode routines */
90 static herr_t H5F__superblock_prefix_decode(H5F_super_t *sblock,
91     const uint8_t **image_ref, const H5F_superblock_cache_ud_t *udata,
92     hbool_t extend_eoa);
93 static herr_t H5F__drvrinfo_prefix_decode(H5O_drvinfo_t *drvinfo, char *drv_name,
94     const uint8_t **image_ref, H5F_drvrinfo_cache_ud_t *udata,
95     hbool_t extend_eoa);
96 
97 
98 /*********************/
99 /* Package Variables */
100 /*********************/
101 
102 /* H5F superblock inherits cache-like properties from H5AC */
103 const H5AC_class_t H5AC_SUPERBLOCK[1] = {{
104     H5AC_SUPERBLOCK_ID,                 /* Metadata client ID */
105     "Superblock",                       /* Metadata client name (for debugging) */
106     H5FD_MEM_SUPER,                     /* File space memory type for client */
107     H5AC__CLASS_SPECULATIVE_LOAD_FLAG,  /* Client class behavior flags */
108     H5F__cache_superblock_get_initial_load_size,/* 'get_initial_load_size' callback */
109     H5F__cache_superblock_get_final_load_size, /* 'get_final_load_size' callback */
110     H5F__cache_superblock_verify_chksum, /* 'verify_chksum' callback */
111     H5F__cache_superblock_deserialize,  /* 'deserialize' callback */
112     H5F__cache_superblock_image_len,    /* 'image_len' callback */
113     NULL,                               /* 'pre_serialize' callback */
114     H5F__cache_superblock_serialize,    /* 'serialize' callback */
115     NULL,       			/* 'notify' callback */
116     H5F__cache_superblock_free_icr,     /* 'free_icr' callback */
117     NULL,                               /* 'fsf_size' callback */
118 }};
119 
120 /* H5F driver info block inherits cache-like properties from H5AC */
121 const H5AC_class_t H5AC_DRVRINFO[1] = {{
122     H5AC_DRVRINFO_ID,                   /* Metadata client ID */
123     "Driver info block",                /* Metadata client name (for debugging) */
124     H5FD_MEM_SUPER,                     /* File space memory type for client */
125     H5AC__CLASS_SPECULATIVE_LOAD_FLAG,  /* Client class behavior flags */
126     H5F__cache_drvrinfo_get_initial_load_size,  /* 'get_initial_load_size' callback */
127     H5F__cache_drvrinfo_get_final_load_size, /* 'get_final_load_size' callback */
128     NULL,				/* 'verify_chksum' callback */
129     H5F__cache_drvrinfo_deserialize,    /* 'deserialize' callback */
130     H5F__cache_drvrinfo_image_len,      /* 'image_len' callback */
131     NULL,                               /* 'pre_serialize' callback */
132     H5F__cache_drvrinfo_serialize,      /* 'serialize' callback */
133     NULL,                               /* 'notify' callback */
134     H5F__cache_drvrinfo_free_icr,       /* 'free_icr' callback */
135     NULL,                               /* 'fsf_size' callback */
136 }};
137 
138 
139 /*****************************/
140 /* Library Private Variables */
141 /*****************************/
142 
143 /* Declare extern the free list to manage the H5F_super_t struct */
144 H5FL_EXTERN(H5F_super_t);
145 
146 
147 /*******************/
148 /* Local Variables */
149 /*******************/
150 
151 
152 
153 /*-------------------------------------------------------------------------
154  * Function:    H5F__superblock_prefix_decode
155  *
156  * Purpose:	Decode a superblock prefix
157  *
158  * Return:      Non-negative on success/Negative on failure
159  *
160  * Programmer:  Quincey Koziol
161  *              December 15, 2016
162  *
163  *-------------------------------------------------------------------------
164  */
165 static herr_t
H5F__superblock_prefix_decode(H5F_super_t * sblock,const uint8_t ** image_ref,const H5F_superblock_cache_ud_t * udata,hbool_t extend_eoa)166 H5F__superblock_prefix_decode(H5F_super_t *sblock, const uint8_t **image_ref,
167     const H5F_superblock_cache_ud_t *udata, hbool_t extend_eoa)
168 {
169     const uint8_t *image = (const uint8_t *)*image_ref; /* Pointer into raw data buffer */
170     htri_t ret_value = SUCCEED;         /* Return value */
171 
172     FUNC_ENTER_STATIC
173 
174     /* Check arguments */
175     HDassert(sblock);
176     HDassert(image_ref);
177     HDassert(image);
178     HDassert(udata);
179     HDassert(udata->f);
180 
181     /* Skip over signature (already checked when locating the superblock) */
182     image += H5F_SIGNATURE_LEN;
183 
184     /* Superblock version */
185     sblock->super_vers = *image++;
186     if(sblock->super_vers > HDF5_SUPERBLOCK_VERSION_LATEST)
187         HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad superblock version number")
188 
189     /* Sanity check */
190     HDassert(((size_t)(image - (const uint8_t *)*image_ref)) == H5F_SUPERBLOCK_FIXED_SIZE);
191 
192     /* Determine the size of addresses & size of offsets, for computing the
193      * variable-sized portion of the superblock.
194      */
195     if(sblock->super_vers < HDF5_SUPERBLOCK_VERSION_2) {
196         sblock->sizeof_addr = image[4];
197         sblock->sizeof_size = image[5];
198     } /* end if */
199     else {
200         sblock->sizeof_addr = image[0];
201         sblock->sizeof_size = image[1];
202     } /* end else */
203     if(sblock->sizeof_addr != 2 && sblock->sizeof_addr != 4 &&
204             sblock->sizeof_addr != 8 && sblock->sizeof_addr != 16 && sblock->sizeof_addr != 32)
205         HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number in an address")
206     if(sblock->sizeof_size != 2 && sblock->sizeof_size != 4 &&
207             sblock->sizeof_size != 8 && sblock->sizeof_size != 16 && sblock->sizeof_size != 32)
208         HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number for object size")
209 
210     /* Check for extending the EOA for the file */
211     if(extend_eoa) {
212         size_t variable_size;   /* Variable size of superblock */
213 
214         /* Determine the size of the variable-length part of the superblock */
215         variable_size = (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(sblock->super_vers, sblock->sizeof_addr, sblock->sizeof_size);
216         HDassert(variable_size > 0);
217 
218         /* Make certain we can read the variable-sized portion of the superblock */
219         if(H5F__set_eoa(udata->f, H5FD_MEM_SUPER, (haddr_t)(H5F_SUPERBLOCK_FIXED_SIZE + variable_size)) < 0)
220             HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
221     } /* end if */
222 
223     /* Update the image buffer pointer */
224     *image_ref = image;
225 
226 done:
227     FUNC_LEAVE_NOAPI(ret_value)
228 } /* end H5F__superblock_prefix_decode() */
229 
230 
231 /*-------------------------------------------------------------------------
232  * Function:	H5F__drvrinfo_prefix_decode
233  *
234  * Purpose:	Decode a driver info prefix
235  *
236  * Return:      Non-negative on success/Negative on failure
237  *
238  * Programmer:  Quincey Koziol
239  *              December 15, 2016
240  *
241  *-------------------------------------------------------------------------
242  */
243 static herr_t
H5F__drvrinfo_prefix_decode(H5O_drvinfo_t * drvrinfo,char * drv_name,const uint8_t ** image_ref,H5F_drvrinfo_cache_ud_t * udata,hbool_t extend_eoa)244 H5F__drvrinfo_prefix_decode(H5O_drvinfo_t *drvrinfo, char *drv_name,
245     const uint8_t **image_ref, H5F_drvrinfo_cache_ud_t *udata,
246     hbool_t extend_eoa)
247 {
248     const uint8_t	*image = (const uint8_t *)*image_ref;   /* Pointer into raw data buffer */
249     unsigned            drv_vers;       /* Version of driver info block */
250     herr_t ret_value = SUCCEED;         /* Return value */
251 
252     FUNC_ENTER_STATIC
253 
254     /* Sanity check */
255     HDassert(drvrinfo);
256     HDassert(image_ref);
257     HDassert(image);
258     HDassert(udata);
259     HDassert(udata->f);
260 
261     /* Version number */
262     drv_vers = *image++;
263     if(drv_vers != HDF5_DRIVERINFO_VERSION_0)
264         HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad driver information block version number")
265 
266     image += 3; /* reserved bytes */
267 
268     /* Driver info size */
269     UINT32DECODE(image, drvrinfo->len);
270 
271     /* Driver name and/or version */
272     if(drv_name) {
273         HDmemcpy(drv_name, (const char *)image, (size_t)8);
274         drv_name[8] = '\0';
275         image += 8; /* advance past name/version */
276     } /* end if */
277 
278     /* Extend the EOA if required so that we can read the complete driver info block */
279     if(extend_eoa) {
280         haddr_t eoa;                /* Current EOA for the file */
281         haddr_t min_eoa;            /* Minimum EOA needed for reading the driver info */
282 
283         /* Get current EOA... */
284         eoa = H5FD_get_eoa(udata->f->shared->lf, H5FD_MEM_SUPER);
285         if(!H5F_addr_defined(eoa))
286             HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
287 
288         /* ... if it is too small, extend it. */
289         min_eoa = udata->driver_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drvrinfo->len;
290 
291         /* If it grew, set it */
292         if(H5F_addr_gt(min_eoa, eoa))
293             if(H5FD_set_eoa(udata->f->shared->lf, H5FD_MEM_SUPER, min_eoa) < 0)
294                 HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed")
295     } /* end if */
296 
297     /* Update the image buffer pointer */
298     *image_ref = image;
299 
300 done:
301     FUNC_LEAVE_NOAPI(ret_value)
302 } /* end H5F__drvrinfo_prefix_decode() */
303 
304 
305 /*-------------------------------------------------------------------------
306  * Function:    H5F__cache_superblock_get_initial_load_size
307  *
308  * Purpose:     Compute the size of the data structure on disk.
309  *
310  * Return:      Non-negative on success/Negative on failure
311  *
312  * Programmer:  Quincey Koziol
313  *              koziol@hdfgroup.org
314  *              July 17, 2013
315  *
316  *-------------------------------------------------------------------------
317  */
318 static herr_t
H5F__cache_superblock_get_initial_load_size(void H5_ATTR_UNUSED * _udata,size_t * image_len)319 H5F__cache_superblock_get_initial_load_size(void H5_ATTR_UNUSED *_udata, size_t *image_len)
320 {
321     FUNC_ENTER_STATIC_NOERR
322 
323     /* Check arguments */
324     HDassert(image_len);
325 
326     /* Set the initial image length size */
327     *image_len = H5F_SUPERBLOCK_FIXED_SIZE +    /* Fixed size of superblock */
328                  H5F_SUPERBLOCK_MINIMAL_VARLEN_SIZE;
329 
330     FUNC_LEAVE_NOAPI(SUCCEED)
331 } /* end H5F__cache_superblock_get_initial_load_size() */
332 
333 
334 /*-------------------------------------------------------------------------
335  * Function:    H5F__cache_superblock_get_final_load_size
336  *
337  * Purpose:     Compute the final size of the data structure on disk.
338  *
339  * Return:      Non-negative on success/Negative on failure
340  *
341  * Programmer:  Quincey Koziol
342  *              koziol@lbl.gov
343  *              November 17, 2016
344  *
345  *-------------------------------------------------------------------------
346  */
347 static herr_t
H5F__cache_superblock_get_final_load_size(const void * _image,size_t image_len,void * _udata,size_t * actual_len)348 H5F__cache_superblock_get_final_load_size(const void *_image, size_t image_len,
349     void *_udata, size_t *actual_len)
350 {
351     const uint8_t *image = (const uint8_t *)_image;   			    /* Pointer into raw data buffer */
352     H5F_superblock_cache_ud_t *udata = (H5F_superblock_cache_ud_t *)_udata; /* User data */
353     H5F_super_t sblock;                 /* Temporary file superblock */
354     htri_t ret_value = SUCCEED;         /* Return value */
355 
356     FUNC_ENTER_STATIC
357 
358     /* Check arguments */
359     HDassert(image);
360     HDassert(udata);
361     HDassert(actual_len);
362     HDassert(*actual_len == image_len);
363     HDassert(image_len >= H5F_SUPERBLOCK_FIXED_SIZE + 6);
364 
365     /* Deserialize the file superblock's prefix */
366     if(H5F__superblock_prefix_decode(&sblock, &image, udata, TRUE) < 0)
367         HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, FAIL, "can't decode file superblock prefix")
368 
369     /* Save the version to be used in verify_chksum callback */
370     udata->super_vers = sblock.super_vers;
371 
372     /* Set the final size for the cache image */
373     *actual_len = H5F_SUPERBLOCK_FIXED_SIZE +
374             (size_t)H5F_SUPERBLOCK_VARLEN_SIZE(sblock.super_vers, sblock.sizeof_addr, sblock.sizeof_size);
375 
376 done:
377     FUNC_LEAVE_NOAPI(ret_value)
378 } /* end H5F__cache_superblock_get_final_load_size() */
379 
380 
381 /*-------------------------------------------------------------------------
382  * Function:    H5F__cache_superblock_verify_chksum
383  *
384  * Purpose:	Verify the computed checksum of the data structure is the
385  *		same as the stored chksum.
386  *
387  * Return:      Success:        TRUE/FALSE
388  *              Failure:        Negative
389  *
390  * Programmer:  Vailin Choi; Aug 2015
391  *
392  *-------------------------------------------------------------------------
393  */
394 static htri_t
H5F__cache_superblock_verify_chksum(const void * _image,size_t len,void * _udata)395 H5F__cache_superblock_verify_chksum(const void *_image, size_t len, void *_udata)
396 {
397     const uint8_t *image = (const uint8_t *)_image;    	/* Pointer into raw data buffer */
398     H5F_superblock_cache_ud_t *udata = (H5F_superblock_cache_ud_t *)_udata; /* User data */
399     uint32_t stored_chksum;     /* Stored metadata checksum value */
400     uint32_t computed_chksum;   /* Computed metadata checksum value */
401     htri_t ret_value = TRUE;	/* Return value */
402 
403     FUNC_ENTER_STATIC_NOERR
404 
405     /* Check arguments */
406     HDassert(image);
407     HDassert(udata);
408 
409     /* No checksum for version 0 & 1 */
410     if(udata->super_vers >= HDF5_SUPERBLOCK_VERSION_2) {
411 
412 	/* Get stored and computed checksums */
413 	H5F_get_checksums(image, len, &stored_chksum, &computed_chksum);
414 
415 	if(stored_chksum != computed_chksum)
416 	    ret_value = FALSE;
417     } /* end if */
418 
419     FUNC_LEAVE_NOAPI(ret_value)
420 } /* end H5F__cache_superblock_verify_chksum() */
421 
422 
423 /*-------------------------------------------------------------------------
424  * Function:	H5F__cache_superblock_deserialize
425  *
426  * Purpose:	Loads an object from the disk.
427  *
428  * Return:	Success:	Pointer to new object
429  *		Failure:	NULL
430  *
431  * Programmer:	Quincey Koziol
432  *		koziol@hdfgroup.org
433  *		July 18 2013
434  *
435  *-------------------------------------------------------------------------
436  */
437 static void *
H5F__cache_superblock_deserialize(const void * _image,size_t len,void * _udata,hbool_t H5_ATTR_UNUSED * dirty)438 H5F__cache_superblock_deserialize(const void *_image, size_t len, void *_udata,
439     hbool_t H5_ATTR_UNUSED *dirty)
440 {
441     H5F_super_t         *sblock = NULL; /* File's superblock */
442     H5F_superblock_cache_ud_t *udata = (H5F_superblock_cache_ud_t *)_udata; /* User data */
443     const uint8_t	*image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
444     H5F_super_t         *ret_value = NULL;      /* Return value */
445 
446     FUNC_ENTER_STATIC
447 
448     /* Check arguments */
449     HDassert(image);
450     HDassert(udata);
451     HDassert(udata->f);
452     HDassert(len >= H5F_SUPERBLOCK_FIXED_SIZE + 6);
453 
454     /* Allocate space for the superblock */
455     if(NULL == (sblock = H5FL_CALLOC(H5F_super_t)))
456         HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
457 
458     /* Deserialize the file superblock's prefix */
459     if(H5F__superblock_prefix_decode(sblock, &image, udata, FALSE) < 0)
460         HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode file superblock prefix")
461 
462     /* Check for older version of superblock format */
463     if(sblock->super_vers < HDF5_SUPERBLOCK_VERSION_2) {
464 	uint32_t    status_flags;	    /* File status flags	   */
465 	unsigned    sym_leaf_k;         /* Symbol table leaf node's 'K' value */
466 	unsigned    snode_btree_k;      /* B-tree symbol table internal node 'K' value */
467 	unsigned    chunk_btree_k;      /* B-tree chunk internal node 'K' value */
468 
469 	/* Freespace version (hard-wired) */
470 	if(HDF5_FREESPACE_VERSION != *image++)
471 	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad free space version number")
472 
473 	/* Root group version number (hard-wired) */
474 	if(HDF5_OBJECTDIR_VERSION != *image++)
475 	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad object directory version number")
476 
477 	/* Skip over reserved byte */
478 	image++;
479 
480 	/* Shared header version number (hard-wired) */
481 	if(HDF5_SHAREDHEADER_VERSION != *image++)
482 	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad shared-header format version number")
483 
484 	/* Skip over size of file addresses (already decoded) */
485 	image++;
486 	udata->f->shared->sizeof_addr = sblock->sizeof_addr;  /* Keep a local copy also */
487 
488 	/* Skip over size of file sizes (already decoded) */
489 	image++;
490 	udata->f->shared->sizeof_size = sblock->sizeof_size;  /* Keep a local copy also */
491 
492 	/* Skip over reserved byte */
493 	image++;
494 
495 	/* Various B-tree sizes */
496 	UINT16DECODE(image, sym_leaf_k);
497 	if(sym_leaf_k == 0)
498 	    HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad symbol table leaf node 1/2 rank")
499         udata->sym_leaf_k = sym_leaf_k;    /* Keep a local copy also */
500 
501         /* Need 'get' call to set other array values */
502         UINT16DECODE(image, snode_btree_k);
503         if(snode_btree_k == 0)
504 	    HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, NULL, "bad 1/2 rank for btree internal nodes")
505 	udata->btree_k[H5B_SNODE_ID] = snode_btree_k;
506 
507 	/*
508          * Delay setting the value in the property list until we've checked
509          * for the indexed storage B-tree internal 'K' value later.
510          */
511 
512         /* File status flags (not really used yet) */
513         UINT32DECODE(image, status_flags);
514         HDassert(status_flags <= 255);
515         sblock->status_flags = (uint8_t)status_flags;
516         if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
517 	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")
518 
519 	/*
520          * If the superblock version # is greater than 0, read in the indexed
521          * storage B-tree internal 'K' value
522          */
523         if(sblock->super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
524 	    UINT16DECODE(image, chunk_btree_k);
525 
526 	    /* Reserved bytes are present only in version 1 */
527 	    if(sblock->super_vers == HDF5_SUPERBLOCK_VERSION_1)
528 		image += 2;   /* reserved */
529 	} /* end if */
530 	else
531 	    chunk_btree_k = HDF5_BTREE_CHUNK_IK_DEF;
532 	udata->btree_k[H5B_CHUNK_ID] = chunk_btree_k;
533 
534 	/* Remainder of "variable-sized" portion of superblock */
535 	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->base_addr/*out*/);
536 	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->ext_addr/*out*/);
537 	H5F_addr_decode(udata->f, (const uint8_t **)&image, &udata->stored_eof/*out*/);
538 	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->driver_addr/*out*/);
539 
540 	/* Allocate space for the root group symbol table entry */
541 	HDassert(!sblock->root_ent);
542 	if(NULL == (sblock->root_ent = (H5G_entry_t *)H5MM_calloc(sizeof(H5G_entry_t))))
543 	    HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "can't allocate space for root group symbol table entry")
544 
545 	/* decode the root group symbol table entry */
546 	if(H5G_ent_decode(udata->f, (const uint8_t **)&image, sblock->root_ent) < 0)
547 	    HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode root group symbol table entry")
548 
549 	/* Set the root group address to the correct value */
550 	sblock->root_addr = sblock->root_ent->header;
551 
552 	/* This step is for h5repart tool only. If user wants to change file driver
553          *  from family to sec2 while using h5repart, set the driver address to
554          *  undefined to let the library ignore the family driver information saved
555          *  in the superblock.
556          */
557 	if(udata->ignore_drvrinfo && H5F_addr_defined(sblock->driver_addr)) {
558 	    /* Eliminate the driver info */
559 	    sblock->driver_addr = HADDR_UNDEF;
560             udata->drvrinfo_removed = TRUE;
561 	} /* end if */
562 
563 	/* NOTE: Driver info block is decoded separately, later */
564 
565     } /* end if */
566     else {
567 	uint32_t read_chksum;           /* Checksum read from file  */
568 
569         /* Skip over size of file addresses (already decoded) */
570         image++;
571 	udata->f->shared->sizeof_addr = sblock->sizeof_addr;  /* Keep a local copy also */
572 
573 	/* Skip over size of file sizes (already decoded) */
574 	image++;
575 	udata->f->shared->sizeof_size = sblock->sizeof_size;  /* Keep a local copy also */
576 
577 	/* File status flags (not really used yet) */
578 	sblock->status_flags = *image++;
579 	if(sblock->status_flags & ~H5F_SUPER_ALL_FLAGS)
580 	    HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad flag value for superblock")
581 
582 	/* Base, superblock extension, end of file & root group object header addresses */
583 	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->base_addr/*out*/);
584 	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->ext_addr/*out*/);
585 	H5F_addr_decode(udata->f, (const uint8_t **)&image, &udata->stored_eof/*out*/);
586 	H5F_addr_decode(udata->f, (const uint8_t **)&image, &sblock->root_addr/*out*/);
587 
588 	/* checksum verification already done in verify_chksum cb */
589 
590 	/* Decode checksum */
591 	UINT32DECODE(image, read_chksum);
592 
593 	/* The Driver Information Block may not appear with the version
594 	 * 2 super block.  Thus we set the driver_addr field of the in
595          * core representation of the super block HADDR_UNDEF to prevent
596          * any attempt to load the Driver Information Block.
597 	 */
598 	sblock->driver_addr = HADDR_UNDEF;
599     } /* end else */
600 
601     /* Sanity check */
602     HDassert((size_t)(image - (const uint8_t *)_image) <= len);
603 
604     /* Set return value */
605     ret_value = sblock;
606 
607 done:
608     /* Release the [possibly partially initialized] superblock on error */
609     if(!ret_value && sblock)
610         if(H5F__super_free(sblock) < 0)
611             HDONE_ERROR(H5E_FILE, H5E_CANTFREE, NULL, "unable to destroy superblock data")
612 
613     FUNC_LEAVE_NOAPI(ret_value)
614 } /* end H5F__cache_superblock_deserialize() */
615 
616 
617 /*-------------------------------------------------------------------------
618  * Function:    H5F__cache_superblock_image_len
619  *
620  * Purpose:     Compute the size of the data structure on disk.
621  *
622  * Return:      Non-negative on success/Negative on failure
623  *
624  * Programmer:  Quincey Koziol
625  *              koziol@hdfgroup.org
626  *              July 19, 2013
627  *
628  *-------------------------------------------------------------------------
629  */
630 static herr_t
H5F__cache_superblock_image_len(const void * _thing,size_t * image_len)631 H5F__cache_superblock_image_len(const void *_thing, size_t *image_len)
632 {
633     const H5F_super_t *sblock = (const H5F_super_t *)_thing;    /* Pointer to the object */
634 
635     FUNC_ENTER_STATIC_NOERR
636 
637     /* Check arguments */
638     HDassert(sblock);
639     HDassert(sblock->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
640     HDassert(sblock->cache_info.type == H5AC_SUPERBLOCK);
641     HDassert(image_len);
642 
643     /* Set the image length size */
644     *image_len = (size_t)H5F_SUPERBLOCK_SIZE(sblock);
645 
646     FUNC_LEAVE_NOAPI(SUCCEED)
647 } /* end H5F__cache_superblock_image_len() */
648 
649 
650 /*-------------------------------------------------------------------------
651  * Function:	H5F__cache_superblock_serialize
652  *
653  * Purpose:	Flushes a dirty object to disk.
654  *
655  * Return:	Non-negative on success/Negative on failure
656  *
657  * Programmer:	Quincey Koziol
658  *		koziol@hdfgroup.org
659  *		July 19 2013
660  *
661  *-------------------------------------------------------------------------
662  */
663 static herr_t
H5F__cache_superblock_serialize(const H5F_t * f,void * _image,size_t H5_ATTR_UNUSED len,void * _thing)664 H5F__cache_superblock_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len,
665     void *_thing)
666 {
667     H5F_super_t *sblock = (H5F_super_t *)_thing;      /* Pointer to the object */
668     uint8_t *image = (uint8_t *)_image;         /* Pointer into raw data buffer */
669     haddr_t rel_eof;            /* Relative EOF for file */
670     herr_t ret_value = SUCCEED; /* Return value */
671 
672     FUNC_ENTER_STATIC
673 
674     /* Sanity check */
675     HDassert(f);
676     HDassert(image);
677     HDassert(sblock);
678 
679     /* Assert that the superblock is marked as being flushed last (and
680        collectively in parallel) */
681     /* (We'll rely on the cache to make sure it actually *is* flushed
682        last (and collectively in parallel), but this check doesn't hurt) */
683     HDassert(sblock->cache_info.flush_me_last);
684 
685     /* Encode the common portion of the file superblock for all versions */
686     HDmemcpy(image, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN);
687     image += H5F_SIGNATURE_LEN;
688     *image++ = (uint8_t)sblock->super_vers;
689 
690     /* Check for older version of superblock format */
691     if(sblock->super_vers < HDF5_SUPERBLOCK_VERSION_2) {
692         *image++ = (uint8_t)HDF5_FREESPACE_VERSION;     /* (hard-wired) */
693         *image++ = (uint8_t)HDF5_OBJECTDIR_VERSION;     /* (hard-wired) */
694         *image++ = 0;   /* reserved*/
695 
696         *image++ = (uint8_t)HDF5_SHAREDHEADER_VERSION;  /* (hard-wired) */
697         *image++ = sblock->sizeof_addr;
698         *image++ = sblock->sizeof_size;
699         *image++ = 0;   /* reserved */
700 
701         UINT16ENCODE(image, sblock->sym_leaf_k);
702         UINT16ENCODE(image, sblock->btree_k[H5B_SNODE_ID]);
703         UINT32ENCODE(image, (uint32_t)sblock->status_flags);
704 
705         /*
706          * Versions of the superblock >0 have the indexed storage B-tree
707          * internal 'K' value stored
708          */
709         if(sblock->super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
710             UINT16ENCODE(image, sblock->btree_k[H5B_CHUNK_ID]);
711             *image++ = 0;   /*reserved */
712             *image++ = 0;   /*reserved */
713         } /* end if */
714 
715         /* Encode the base address */
716         H5F_addr_encode(f, &image, sblock->base_addr);
717 
718         /* Encode the address of global free-space index */
719         H5F_addr_encode(f, &image, sblock->ext_addr);
720 
721         /* Encode the end-of-file address. Note that at this point in time,
722          * the EOF value itself may not be reflective of the file's size, as
723          * we will eventually truncate the file to match the EOA value. As
724          * such, use the EOA value in its place, knowing that the current EOF
725          * value will ultimately match it. */
726         if ((rel_eof = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER)) == HADDR_UNDEF)
727             HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
728         H5F_addr_encode(f, &image, (rel_eof + sblock->base_addr));
729 
730         /* Encode the driver informaton block address */
731         H5F_addr_encode(f, &image, sblock->driver_addr);
732 
733         /* Encode the root group object entry, including the cached stab info */
734         if(H5G_ent_encode(f, &image, sblock->root_ent) < 0)
735             HGOTO_ERROR(H5E_FILE, H5E_CANTENCODE, FAIL, "can't encode root group symbol table entry")
736 
737         /* NOTE: Driver info block is handled separately */
738 
739     } /* end if */
740     else { /* sblock->super_vers >= HDF5_SUPERBLOCK_VERSION_2 */
741         uint32_t        chksum;                 /* Checksum temporary variable      */
742         H5O_loc_t       *root_oloc;             /* Pointer to root group's object location */
743 
744         /* Size of file addresses & offsets, and status flags */
745         *image++ = sblock->sizeof_addr;
746         *image++ = sblock->sizeof_size;
747         *image++ = sblock->status_flags;
748 
749         /* Encode the base address */
750         H5F_addr_encode(f, &image, sblock->base_addr);
751 
752         /* Encode the address of the superblock extension */
753         H5F_addr_encode(f, &image, sblock->ext_addr);
754 
755         /* At this point in time, the EOF value itself may
756          * not be reflective of the file's size, since we'll eventually
757          * truncate it to match the EOA value. As such, use the EOA value
758          * in its place, knowing that the current EOF value will
759          * ultimately match it. */
760         if ((rel_eof = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER)) == HADDR_UNDEF)
761             HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
762         H5F_addr_encode(f, &image, (rel_eof + sblock->base_addr));
763 
764         /* Retrieve information for root group */
765         if(NULL == (root_oloc = H5G_oloc(f->shared->root_grp)))
766             HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to retrieve root group information")
767 
768         /* Encode address of root group's object header */
769         H5F_addr_encode(f, &image, root_oloc->addr);
770 
771         /* Compute superblock checksum */
772         chksum = H5_checksum_metadata(_image, ((size_t)H5F_SUPERBLOCK_SIZE(sblock) - H5F_SIZEOF_CHKSUM), 0);
773 
774         /* Superblock checksum */
775         UINT32ENCODE(image, chksum);
776 
777         /* Sanity check */
778         HDassert((size_t)(image - (uint8_t *)_image) == (size_t)H5F_SUPERBLOCK_SIZE(sblock));
779     } /* end else */
780 
781     /* Sanity check */
782     HDassert((size_t)(image - (uint8_t *)_image) == len);
783 
784 done:
785     FUNC_LEAVE_NOAPI(ret_value)
786 } /* H5F__cache_superblock_serialize() */
787 
788 
789 /*-------------------------------------------------------------------------
790  * Function:	H5F__cache_superblock_free_icr
791  *
792  * Purpose:	Destroy/release an "in core representation" of a data
793  *              structure
794  *
795  * Note:	The metadata cache sets the object's cache_info.magic to
796  *		H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC before calling a free_icr
797  *		callback (checked in assert).
798  *
799  * Return:	Non-negative on success/Negative on failure
800  *
801  * Programmer:	Quincey Koziol
802  *              koziol@hdfgroup.org
803  *              July 20, 2013
804  *
805  *-------------------------------------------------------------------------
806  */
807 static herr_t
H5F__cache_superblock_free_icr(void * _thing)808 H5F__cache_superblock_free_icr(void *_thing)
809 {
810     H5F_super_t *sblock = (H5F_super_t *)_thing;        /* Pointer to the object */
811     herr_t ret_value = SUCCEED;         /* Return value */
812 
813     FUNC_ENTER_STATIC
814 
815     /* Sanity check */
816     HDassert(sblock);
817     HDassert(sblock->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC);
818     HDassert(sblock->cache_info.type == H5AC_SUPERBLOCK);
819 
820     /* Destroy superblock */
821     if(H5F__super_free(sblock) < 0)
822         HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free superblock")
823 
824 done:
825     FUNC_LEAVE_NOAPI(ret_value)
826 } /* H5F__cache_superblock_free_icr() */
827 
828 
829 /*-------------------------------------------------------------------------
830  * Function:    H5F__cache_drvrinfo_get_initial_load_size
831  *
832  * Purpose:     Compute the intiial size of the data structure on disk.
833  *
834  * Return:      Non-negative on success/Negative on failure
835  *
836  * Programmer:  Quincey Koziol
837  *              koziol@hdfgroup.org
838  *              July 20, 2013
839  *
840  *-------------------------------------------------------------------------
841  */
842 static herr_t
H5F__cache_drvrinfo_get_initial_load_size(void H5_ATTR_UNUSED * _udata,size_t * image_len)843 H5F__cache_drvrinfo_get_initial_load_size(void H5_ATTR_UNUSED *_udata, size_t *image_len)
844 {
845     FUNC_ENTER_STATIC_NOERR
846 
847     /* Check arguments */
848     HDassert(image_len);
849 
850     /* Set the initial image length size */
851     *image_len = H5F_DRVINFOBLOCK_HDR_SIZE;     /* Fixed size portion of driver info block */
852 
853     FUNC_LEAVE_NOAPI(SUCCEED)
854 } /* end H5F__cache_drvrinfo_get_initial_load_size() */
855 
856 
857 /*-------------------------------------------------------------------------
858  * Function:    H5F__cache_drvrinfo_get_final_load_size
859  *
860  * Purpose:     Compute the final size of the data structure on disk.
861  *
862  * Return:      Non-negative on success/Negative on failure
863  *
864  * Programmer:  Quincey Koziol
865  *              koziol@lbl.gov
866  *              November 17, 2016
867  *
868  *-------------------------------------------------------------------------
869  */
870 static herr_t
H5F__cache_drvrinfo_get_final_load_size(const void * _image,size_t image_len,void * _udata,size_t * actual_len)871 H5F__cache_drvrinfo_get_final_load_size(const void *_image, size_t image_len,
872     void *_udata, size_t *actual_len)
873 {
874     const uint8_t *image = (const uint8_t *)_image;   			/* Pointer into raw data buffer */
875     H5F_drvrinfo_cache_ud_t *udata = (H5F_drvrinfo_cache_ud_t *)_udata;	/* User data */
876     H5O_drvinfo_t drvrinfo;     /* Driver info */
877     herr_t ret_value = SUCCEED; /* Return value */
878 
879     FUNC_ENTER_STATIC
880 
881     /* Check arguments */
882     HDassert(image);
883     HDassert(udata);
884     HDassert(actual_len);
885     HDassert(*actual_len == image_len);
886     HDassert(image_len == H5F_DRVINFOBLOCK_HDR_SIZE);
887 
888     /* Deserialize the file driver info's prefix */
889     if(H5F__drvrinfo_prefix_decode(&drvrinfo, NULL, &image, udata, TRUE) < 0)
890         HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, FAIL, "can't decode file driver info prefix")
891 
892     /* Set the final size for the cache image */
893     *actual_len = H5F_DRVINFOBLOCK_HDR_SIZE + drvrinfo.len;
894 
895 done:
896     FUNC_LEAVE_NOAPI(ret_value)
897 } /* end H5F__cache_drvrinfo_get_final_load_size() */
898 
899 
900 /*-------------------------------------------------------------------------
901  * Function:	H5F__cache_drvrinfo_deserialize
902  *
903  * Purpose:	Loads an object from the disk.
904  *
905  * Return:	Success:	Pointer to a new driver info struct
906  *		Failure:	NULL
907  *
908  * Programmer:	Quincey Koziol
909  *		koziol@hdfgroup.org
910  *		July 20 2013
911  *
912  *-------------------------------------------------------------------------
913  */
914 static void *
H5F__cache_drvrinfo_deserialize(const void * _image,size_t len,void * _udata,hbool_t H5_ATTR_UNUSED * dirty)915 H5F__cache_drvrinfo_deserialize(const void *_image, size_t len, void *_udata,
916     hbool_t H5_ATTR_UNUSED *dirty)
917 {
918     H5O_drvinfo_t       *drvinfo = NULL; /* Driver info */
919     H5F_drvrinfo_cache_ud_t *udata = (H5F_drvrinfo_cache_ud_t *)_udata;     /* User data */
920     const uint8_t	*image = (const uint8_t *)_image;       /* Pointer into raw data buffer */
921     char                drv_name[9];    /* Name of driver */
922     H5O_drvinfo_t       *ret_value = NULL;      /* Return value */
923 
924     FUNC_ENTER_STATIC
925 
926     /* Sanity check */
927     HDassert(image);
928     HDassert(len >= H5F_DRVINFOBLOCK_HDR_SIZE);
929     HDassert(udata);
930     HDassert(udata->f);
931 
932     /* Allocate space for the driver info */
933     if(NULL == (drvinfo = (H5O_drvinfo_t *)H5MM_calloc(sizeof(H5O_drvinfo_t))))
934 	HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, NULL, "memory allocation failed for driver info message")
935 
936     /* Deserialize the file driver info's prefix */
937     if(H5F__drvrinfo_prefix_decode(drvinfo, drv_name, &image, udata, FALSE) < 0)
938         HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "can't decode file driver info prefix")
939 
940     /* Sanity check */
941     HDassert(len == (H5F_DRVINFOBLOCK_HDR_SIZE + drvinfo->len));
942 
943     /* Validate and decode driver information */
944     if(H5FD_sb_load(udata->f->shared->lf, drv_name, image) < 0)
945 	HGOTO_ERROR(H5E_FILE, H5E_CANTDECODE, NULL, "unable to decode driver information")
946 
947     /* Sanity check */
948     HDassert((size_t)(image - (const uint8_t *)_image) <= len);
949 
950     /* Set return value */
951     ret_value = drvinfo;
952 
953 done:
954     /* Release the [possibly partially initialized] driver info message on error */
955     if(!ret_value && drvinfo)
956         H5MM_xfree(drvinfo);
957 
958     FUNC_LEAVE_NOAPI(ret_value)
959 } /* end H5F__cache_drvrinfo_deserialize() */
960 
961 
962 /*-------------------------------------------------------------------------
963  * Function:    H5F__cache_drvrinfo_image_len
964  *
965  * Purpose:     Compute the size of the data structure on disk.
966  *
967  * Return:      Non-negative on success/Negative on failure
968  *
969  * Programmer:  Quincey Koziol
970  *              koziol@hdfgroup.org
971  *              July 20, 2013
972  *
973  *-------------------------------------------------------------------------
974  */
975 static herr_t
H5F__cache_drvrinfo_image_len(const void * _thing,size_t * image_len)976 H5F__cache_drvrinfo_image_len(const void *_thing, size_t *image_len)
977 {
978     const H5O_drvinfo_t *drvinfo = (const H5O_drvinfo_t *)_thing;       /* Pointer to the object */
979 
980     FUNC_ENTER_STATIC_NOERR
981 
982     /* Check arguments */
983     HDassert(drvinfo);
984     HDassert(drvinfo->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
985     HDassert(drvinfo->cache_info.type == H5AC_DRVRINFO);
986     HDassert(image_len);
987 
988     /* Set the image length size */
989     *image_len = (size_t)(H5F_DRVINFOBLOCK_HDR_SIZE +   /* Fixed-size portion of driver info block */
990             drvinfo->len);                              /* Variable-size portion of driver info block */
991 
992     FUNC_LEAVE_NOAPI(SUCCEED)
993 } /* end H5F__cache_drvrinfo_image_len() */
994 
995 
996 /*-------------------------------------------------------------------------
997  * Function:	H5F__cache_drvrinfo_serialize
998  *
999  * Purpose:	Flushes a dirty object to disk.
1000  *
1001  * Return:	Non-negative on success/Negative on failure
1002  *
1003  * Programmer:	Quincey Koziol
1004  *		koziol@hdfgroup.org
1005  *		July 20 2013
1006  *
1007  *-------------------------------------------------------------------------
1008  */
1009 static herr_t
H5F__cache_drvrinfo_serialize(const H5F_t * f,void * _image,size_t len,void * _thing)1010 H5F__cache_drvrinfo_serialize(const H5F_t *f, void *_image, size_t len,
1011     void *_thing)
1012 {
1013     H5O_drvinfo_t *drvinfo = (H5O_drvinfo_t *)_thing;   /* Pointer to the object */
1014     uint8_t *image = (uint8_t *)_image;         /* Pointer into raw data buffer */
1015     uint8_t *dbuf;              /* Pointer to beginning of driver info */
1016     herr_t ret_value = SUCCEED; /* Return value */
1017 
1018     FUNC_ENTER_STATIC
1019 
1020     /* check arguments */
1021     HDassert(f);
1022     HDassert(image);
1023     HDassert(drvinfo);
1024     HDassert(drvinfo->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
1025     HDassert(drvinfo->cache_info.type == H5AC_DRVRINFO);
1026     HDassert(len == (size_t)(H5F_DRVINFOBLOCK_HDR_SIZE + drvinfo->len));
1027 
1028     /* Save pointer to beginning of driver info */
1029     dbuf = image;
1030 
1031     /* Encode the driver information block */
1032     *image++ = HDF5_DRIVERINFO_VERSION_0; /* Version */
1033     *image++ = 0; /* reserved */
1034     *image++ = 0; /* reserved */
1035     *image++ = 0; /* reserved */
1036 
1037     /* Driver info size, excluding header */
1038     UINT32ENCODE(image, drvinfo->len);
1039 
1040     /* Encode driver-specific data */
1041     if(H5FD_sb_encode(f->shared->lf, (char *)image, dbuf + H5F_DRVINFOBLOCK_HDR_SIZE) < 0)
1042         HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information")
1043 
1044     /* Advance buffer pointer past name & variable-sized portion of driver info */
1045     image += 8 + drvinfo->len;
1046 
1047     /* Sanity check */
1048     HDassert((size_t)(image - (uint8_t *)_image) == len);
1049 
1050 done:
1051     FUNC_LEAVE_NOAPI(ret_value)
1052 } /* H5F__cache_drvrinfo_serialize() */
1053 
1054 
1055 /*-------------------------------------------------------------------------
1056  * Function:	H5F__cache_drvrinfo_free_icr
1057  *
1058  * Purpose:	Destroy/release an "in core representation" of a data
1059  *              structure
1060  *
1061  * Note:	The metadata cache sets the object's cache_info.magic to
1062  *		H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC before calling a free_icr
1063  *		callback (checked in assert).
1064  *
1065  * Return:	Non-negative on success/Negative on failure
1066  *
1067  * Programmer:	Quincey Koziol
1068  *              koziol@hdfgroup.org
1069  *              July 20, 2013
1070  *
1071  *-------------------------------------------------------------------------
1072  */
1073 static herr_t
H5F__cache_drvrinfo_free_icr(void * _thing)1074 H5F__cache_drvrinfo_free_icr(void *_thing)
1075 {
1076     H5O_drvinfo_t *drvinfo = (H5O_drvinfo_t *)_thing;    /* Pointer to the object */
1077 
1078     FUNC_ENTER_STATIC_NOERR
1079 
1080     /* Check arguments */
1081     HDassert(drvinfo);
1082     HDassert(drvinfo->cache_info.magic == H5C__H5C_CACHE_ENTRY_T_BAD_MAGIC);
1083     HDassert(drvinfo->cache_info.type == H5AC_DRVRINFO);
1084 
1085     /* Destroy driver info message */
1086     H5MM_xfree(drvinfo);
1087 
1088     FUNC_LEAVE_NOAPI(SUCCEED)
1089 } /* H5F__cache_drvrinfo_free_icr() */
1090 
1091