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://www.hdfgroup.org/licenses.               *
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:             H5AC.c
17  *                      Jul  9 1997
18  *                      Robb Matzke
19  *
20  * Purpose:             Functions in this file implement a cache for
21  *                      things which exist on disk.  All "things" associated
22  *                      with a particular HDF file share the same cache; each
23  *                      HDF file has it's own cache.
24  *
25  *-------------------------------------------------------------------------
26  */
27 
28 /****************/
29 /* Module Setup */
30 /****************/
31 
32 #include "H5ACmodule.h" /* This source code file is part of the H5AC module */
33 #define H5C_FRIEND      /* Suppress error about including H5Cpkg            */
34 #define H5F_FRIEND      /* Suppress error about including H5Fpkg            */
35 
36 /***********/
37 /* Headers */
38 /***********/
39 #include "H5private.h"   /* Generic Functions                        */
40 #include "H5ACpkg.h"     /* Metadata cache                           */
41 #include "H5Clog.h"      /* Cache logging                            */
42 #include "H5Cpkg.h"      /* Cache                                    */
43 #include "H5CXprivate.h" /* API Contexts                             */
44 #include "H5Eprivate.h"  /* Error handling                           */
45 #include "H5Fpkg.h"      /* Files                                    */
46 #include "H5FDprivate.h" /* File drivers                             */
47 #include "H5Iprivate.h"  /* IDs                                      */
48 #include "H5Pprivate.h"  /* Property lists                           */
49 #include "H5SLprivate.h" /* Skip Lists                               */
50 
51 /****************/
52 /* Local Macros */
53 /****************/
54 
55 /******************/
56 /* Local Typedefs */
57 /******************/
58 
59 /********************/
60 /* Local Prototypes */
61 /********************/
62 
63 static herr_t H5AC__check_if_write_permitted(const H5F_t *f, hbool_t *write_permitted_ptr);
64 static herr_t H5AC__ext_config_2_int_config(H5AC_cache_config_t *ext_conf_ptr,
65                                             H5C_auto_size_ctl_t *int_conf_ptr);
66 #if H5AC_DO_TAGGING_SANITY_CHECKS
67 static herr_t H5AC__verify_tag(const H5AC_class_t *type);
68 #endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
69 
70 /*********************/
71 /* Package Variables */
72 /*********************/
73 
74 /* Package initialization variable */
75 hbool_t H5_PKG_INIT_VAR = FALSE;
76 
77 /*****************************/
78 /* Library Private Variables */
79 /*****************************/
80 
81 #ifdef H5_HAVE_PARALLEL
82 /* Environment variable for collective API sanity checks */
83 hbool_t H5_coll_api_sanity_check_g = false;
84 #endif /* H5_HAVE_PARALLEL */
85 
86 /*******************/
87 /* Local Variables */
88 /*******************/
89 
90 /* Metadata entry class list */
91 
92 /* Remember to add new type ID to the H5AC_type_t enum in H5ACprivate.h when
93  *      adding a new class.
94  */
95 
96 static const H5AC_class_t *const H5AC_class_s[] = {
97     H5AC_BT,               /* ( 0) B-tree nodes                    */
98     H5AC_SNODE,            /* ( 1) symbol table nodes              */
99     H5AC_LHEAP_PRFX,       /* ( 2) local heap prefix               */
100     H5AC_LHEAP_DBLK,       /* ( 3) local heap data block           */
101     H5AC_GHEAP,            /* ( 4) global heap                     */
102     H5AC_OHDR,             /* ( 5) object header                   */
103     H5AC_OHDR_CHK,         /* ( 6) object header chunk             */
104     H5AC_BT2_HDR,          /* ( 7) v2 B-tree header                */
105     H5AC_BT2_INT,          /* ( 8) v2 B-tree internal node         */
106     H5AC_BT2_LEAF,         /* ( 9) v2 B-tree leaf node             */
107     H5AC_FHEAP_HDR,        /* (10) fractal heap header             */
108     H5AC_FHEAP_DBLOCK,     /* (11) fractal heap direct block       */
109     H5AC_FHEAP_IBLOCK,     /* (12) fractal heap indirect block     */
110     H5AC_FSPACE_HDR,       /* (13) free space header               */
111     H5AC_FSPACE_SINFO,     /* (14) free space sections             */
112     H5AC_SOHM_TABLE,       /* (15) shared object header message master table */
113     H5AC_SOHM_LIST,        /* (16) shared message index stored as a list */
114     H5AC_EARRAY_HDR,       /* (17) extensible array header         */
115     H5AC_EARRAY_IBLOCK,    /* (18) extensible array index block    */
116     H5AC_EARRAY_SBLOCK,    /* (19) extensible array super block    */
117     H5AC_EARRAY_DBLOCK,    /* (20) extensible array data block     */
118     H5AC_EARRAY_DBLK_PAGE, /* (21) extensible array data block page */
119     H5AC_FARRAY_HDR,       /* (22) fixed array header              */
120     H5AC_FARRAY_DBLOCK,    /* (23) fixed array data block          */
121     H5AC_FARRAY_DBLK_PAGE, /* (24) fixed array data block page     */
122     H5AC_SUPERBLOCK,       /* (25) file superblock                 */
123     H5AC_DRVRINFO,         /* (26) driver info block (supplements superblock) */
124     H5AC_EPOCH_MARKER,     /* (27) epoch marker - always internal to cache */
125     H5AC_PROXY_ENTRY,      /* (28) cache entry proxy               */
126     H5AC_PREFETCHED_ENTRY  /* (29) prefetched entry - always internal to cache */
127 };
128 
129 /*-------------------------------------------------------------------------
130  * Function:    H5AC_init
131  *
132  * Purpose:     Initialize the interface from some other layer.
133  *
134  * Return:      Success:        non-negative
135  *              Failure:        negative
136  *
137  * Programmer:  Quincey Koziol
138  *              Saturday, January 18, 2003
139  *
140  *-------------------------------------------------------------------------
141  */
142 herr_t
H5AC_init(void)143 H5AC_init(void)
144 {
145     herr_t ret_value = SUCCEED; /* Return value */
146 
147     FUNC_ENTER_NOAPI(FAIL)
148     /* FUNC_ENTER() does all the work */
149 
150 done:
151     FUNC_LEAVE_NOAPI(ret_value)
152 } /* end H5AC_init() */
153 
154 /*-------------------------------------------------------------------------
155  * Function:    H5AC__init_package
156  *
157  * Purpose:     Initialize interface-specific information
158  *
159  * Return:      Non-negative on success/Negative on failure
160  *
161  * Programmer:  Quincey Koziol
162  *              Thursday, July 18, 2002
163  *
164  *-------------------------------------------------------------------------
165  */
166 herr_t
H5AC__init_package(void)167 H5AC__init_package(void)
168 {
169     FUNC_ENTER_PACKAGE_NOERR
170 
171 #ifdef H5_HAVE_PARALLEL
172     /* check whether to enable strict collective function calling
173      * sanity checks using MPI barriers
174      */
175     {
176         const char *s; /* String for environment variables */
177 
178         s = HDgetenv("H5_COLL_API_SANITY_CHECK");
179         if (s && HDisdigit(*s)) {
180             long env_val               = HDstrtol(s, NULL, 0);
181             H5_coll_api_sanity_check_g = (0 == env_val) ? FALSE : TRUE;
182         }
183     }
184 #endif /* H5_HAVE_PARALLEL */
185 
186     FUNC_LEAVE_NOAPI(SUCCEED)
187 } /* end H5AC__init_package() */
188 
189 /*-------------------------------------------------------------------------
190  * Function:    H5AC_term_package
191  *
192  * Purpose:     Terminate this interface.
193  *
194  * Return:      Success:        Positive if anything was done that might
195  *                              affect other interfaces; zero otherwise.
196  *              Failure:        Negative.
197  *
198  * Programmer:  Quincey Koziol
199  *              Thursday, July 18, 2002
200  *
201  *-------------------------------------------------------------------------
202  */
203 int
H5AC_term_package(void)204 H5AC_term_package(void)
205 {
206     FUNC_ENTER_NOAPI_NOINIT_NOERR
207 
208     if (H5_PKG_INIT_VAR)
209         /* Reset interface initialization flag */
210         H5_PKG_INIT_VAR = FALSE;
211 
212     FUNC_LEAVE_NOAPI(0)
213 } /* end H5AC_term_package() */
214 
215 /*-------------------------------------------------------------------------
216  *
217  * Function:    H5AC_cache_image_pending()
218  *
219  * Purpose:     Debugging function that tests to see if the load of a
220  *              metadata cache image load is pending (i.e. will be executed
221  *              on the next protect or insert)
222  *
223  *              Returns TRUE if a cache image load is pending, and FALSE
224  *              if not.  Throws an assertion failure on error.
225  *
226  * Return:      TRUE if a cache image load is pending, and FALSE otherwise.
227  *
228  * Programmer:  John Mainzer, 1/10/17
229  *
230  *-------------------------------------------------------------------------
231  */
232 hbool_t
H5AC_cache_image_pending(const H5F_t * f)233 H5AC_cache_image_pending(const H5F_t *f)
234 {
235     H5C_t * cache_ptr;
236     hbool_t ret_value = FALSE; /* Return value */
237 
238     FUNC_ENTER_NOAPI_NOINIT_NOERR
239 
240     /* Sanity checks */
241     HDassert(f);
242     HDassert(f->shared);
243     cache_ptr = f->shared->cache;
244 
245     ret_value = H5C_cache_image_pending(cache_ptr);
246 
247     FUNC_LEAVE_NOAPI(ret_value)
248 } /* H5AC_cache_image_pending() */
249 
250 /*-------------------------------------------------------------------------
251  * Function:    H5AC_create
252  *
253  * Purpose:     Initialize the cache just after a file is opened.  The
254  *              SIZE_HINT is the number of cache slots desired.  If you
255  *              pass an invalid value then H5AC_NSLOTS is used.  You can
256  *              turn off caching by using 1 for the SIZE_HINT value.
257  *
258  * Return:      Success:        Number of slots actually used.
259  *
260  *              Failure:        Negative
261  *
262  * Programmer:  Robb Matzke
263  *              Jul  9 1997
264  *
265  *-------------------------------------------------------------------------
266  */
267 herr_t
H5AC_create(const H5F_t * f,H5AC_cache_config_t * config_ptr,H5AC_cache_image_config_t * image_config_ptr)268 H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr, H5AC_cache_image_config_t *image_config_ptr)
269 {
270 #ifdef H5_HAVE_PARALLEL
271     char        prefix[H5C__PREFIX_LEN] = "";
272     H5AC_aux_t *aux_ptr                 = NULL;
273 #endif /* H5_HAVE_PARALLEL */
274     struct H5C_cache_image_ctl_t int_ci_config = H5C__DEFAULT_CACHE_IMAGE_CTL;
275     herr_t                       ret_value     = SUCCEED; /* Return value */
276 
277     FUNC_ENTER_NOAPI(FAIL)
278 
279     /* Check arguments */
280     HDassert(f);
281     HDassert(NULL == f->shared->cache);
282     HDassert(config_ptr != NULL);
283     HDassert(image_config_ptr != NULL);
284     HDassert(image_config_ptr->version == H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION);
285     HDcompile_assert(NELMTS(H5AC_class_s) == H5AC_NTYPES);
286     HDcompile_assert(H5C__MAX_NUM_TYPE_IDS == H5AC_NTYPES);
287 
288     /* Validate configurations */
289     if (H5AC_validate_config(config_ptr) < 0)
290         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Bad cache configuration")
291     if (H5AC_validate_cache_image_config(image_config_ptr) < 0)
292         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Bad cache image configuration")
293 
294 #ifdef H5_HAVE_PARALLEL
295     if (H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI)) {
296         MPI_Comm mpi_comm;
297         int      mpi_rank;
298         int      mpi_size;
299 
300         if (MPI_COMM_NULL == (mpi_comm = H5F_mpi_get_comm(f)))
301             HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator")
302 
303         if ((mpi_rank = H5F_mpi_get_rank(f)) < 0)
304             HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get mpi rank")
305 
306         if ((mpi_size = H5F_mpi_get_size(f)) < 0)
307             HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get mpi size")
308 
309         if (NULL == (aux_ptr = H5FL_CALLOC(H5AC_aux_t)))
310             HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "Can't allocate H5AC auxiliary structure")
311 
312         aux_ptr->magic                   = H5AC__H5AC_AUX_T_MAGIC;
313         aux_ptr->mpi_comm                = mpi_comm;
314         aux_ptr->mpi_rank                = mpi_rank;
315         aux_ptr->mpi_size                = mpi_size;
316         aux_ptr->write_permitted         = FALSE;
317         aux_ptr->dirty_bytes_threshold   = H5AC__DEFAULT_DIRTY_BYTES_THRESHOLD;
318         aux_ptr->dirty_bytes             = 0;
319         aux_ptr->metadata_write_strategy = H5AC__DEFAULT_METADATA_WRITE_STRATEGY;
320 #if H5AC_DEBUG_DIRTY_BYTES_CREATION
321         aux_ptr->dirty_bytes_propagations      = 0;
322         aux_ptr->unprotect_dirty_bytes         = 0;
323         aux_ptr->unprotect_dirty_bytes_updates = 0;
324         aux_ptr->insert_dirty_bytes            = 0;
325         aux_ptr->insert_dirty_bytes_updates    = 0;
326         aux_ptr->move_dirty_bytes              = 0;
327         aux_ptr->move_dirty_bytes_updates      = 0;
328 #endif /* H5AC_DEBUG_DIRTY_BYTES_CREATION */
329         aux_ptr->d_slist_ptr         = NULL;
330         aux_ptr->c_slist_ptr         = NULL;
331         aux_ptr->candidate_slist_ptr = NULL;
332         aux_ptr->write_done          = NULL;
333         aux_ptr->sync_point_done     = NULL;
334         aux_ptr->p0_image_len        = 0;
335 
336         HDsprintf(prefix, "%d:", mpi_rank);
337 
338         if (mpi_rank == 0) {
339             if (NULL == (aux_ptr->d_slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
340                 HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create dirtied entry list")
341 
342             if (NULL == (aux_ptr->c_slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
343                 HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create cleaned entry list")
344         } /* end if */
345 
346         /* construct the candidate slist for all processes.
347          * when the distributed strategy is selected as all processes
348          * will use it in the case of a flush.
349          */
350         if (NULL == (aux_ptr->candidate_slist_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)))
351             HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL, "can't create candidate entry list")
352 
353         if (aux_ptr->mpi_rank == 0)
354             f->shared->cache = H5C_create(H5AC__DEFAULT_MAX_CACHE_SIZE, H5AC__DEFAULT_MIN_CLEAN_SIZE,
355                                           (H5AC_NTYPES - 1), H5AC_class_s, H5AC__check_if_write_permitted,
356                                           TRUE, H5AC__log_flushed_entry, (void *)aux_ptr);
357         else
358             f->shared->cache =
359                 H5C_create(H5AC__DEFAULT_MAX_CACHE_SIZE, H5AC__DEFAULT_MIN_CLEAN_SIZE, (H5AC_NTYPES - 1),
360                            H5AC_class_s, H5AC__check_if_write_permitted, TRUE, NULL, (void *)aux_ptr);
361     } /* end if */
362     else {
363 #endif /* H5_HAVE_PARALLEL */
364         /* The default max cache size and min clean size will frequently be
365          * overwritten shortly by the subsequent set resize config call.
366          *                                             -- JRM
367          */
368         f->shared->cache =
369             H5C_create(H5AC__DEFAULT_MAX_CACHE_SIZE, H5AC__DEFAULT_MIN_CLEAN_SIZE, (H5AC_NTYPES - 1),
370                        H5AC_class_s, H5AC__check_if_write_permitted, TRUE, NULL, NULL);
371 #ifdef H5_HAVE_PARALLEL
372     }  /* end else */
373 #endif /* H5_HAVE_PARALLEL */
374 
375     if (NULL == f->shared->cache)
376         HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "memory allocation failed")
377 
378 #ifdef H5_HAVE_PARALLEL
379     if (aux_ptr != NULL)
380         if (H5C_set_prefix(f->shared->cache, prefix) < 0)
381             HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL, "H5C_set_prefix() failed")
382 #endif /* H5_HAVE_PARALLEL */
383 
384     /* Turn on metadata cache logging, if being used
385      * This will be JSON until we create a special API call. Trace output
386      * is generated when logging is controlled by the struct.
387      */
388     if (H5F_USE_MDC_LOGGING(f))
389         if (H5C_log_set_up(f->shared->cache, H5F_MDC_LOG_LOCATION(f), H5C_LOG_STYLE_JSON,
390                            H5F_START_MDC_LOG_ON_ACCESS(f)) < 0)
391             HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "mdc logging setup failed")
392 
393     /* Set the cache parameters */
394     if (H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0)
395         HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "auto resize configuration failed")
396 
397     /* Don't need to get the current H5C image config here since the
398      * cache has just been created, and thus f->shared->cache->image_ctl
399      * must still set to its initial value (H5C__DEFAULT_CACHE_IMAGE_CTL).
400      * Note that this not true as soon as control returns to the application
401      * program, as some test code modifies f->shared->cache->image_ctl.
402      */
403     int_ci_config.version            = image_config_ptr->version;
404     int_ci_config.generate_image     = image_config_ptr->generate_image;
405     int_ci_config.save_resize_status = image_config_ptr->save_resize_status;
406     int_ci_config.entry_ageout       = image_config_ptr->entry_ageout;
407     if (H5C_set_cache_image_config(f, f->shared->cache, &int_ci_config) < 0)
408         HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "auto resize configuration failed")
409 
410 done:
411     /* If currently logging, generate a message */
412     if (f->shared->cache->log_info->logging)
413         if (H5C_log_write_create_cache_msg(f->shared->cache, ret_value) < 0)
414             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
415 
416 #ifdef H5_HAVE_PARALLEL
417     /* if there is a failure, try to tidy up the auxiliary structure */
418     if (ret_value < 0) {
419         if (aux_ptr != NULL) {
420             if (aux_ptr->d_slist_ptr != NULL)
421                 H5SL_close(aux_ptr->d_slist_ptr);
422             if (aux_ptr->c_slist_ptr != NULL)
423                 H5SL_close(aux_ptr->c_slist_ptr);
424             if (aux_ptr->candidate_slist_ptr != NULL)
425                 H5SL_close(aux_ptr->candidate_slist_ptr);
426             aux_ptr->magic = 0;
427             aux_ptr        = H5FL_FREE(H5AC_aux_t, aux_ptr);
428         } /* end if */
429     }     /* end if */
430 #endif    /* H5_HAVE_PARALLEL */
431 
432     FUNC_LEAVE_NOAPI(ret_value)
433 } /* H5AC_create() */
434 
435 /*-------------------------------------------------------------------------
436  * Function:    H5AC_dest
437  *
438  * Purpose:     Flushes all data to disk and destroys the cache.
439  *              This function fails if any object are protected since the
440  *              resulting file might not be consistent.
441  *
442  * Return:      Non-negative on success/Negative on failure
443  *
444  * Programmer:  Robb Matzke
445  *              Jul  9 1997
446  *
447  * Changes:
448  *
449  *             In the parallel case, added code to setup the MDC slist
450  *             before the call to H5AC__flush_entries() and take it down
451  *             afterwards.
452  *
453  *                                            JRM -- 7/29/20
454  *
455  *-------------------------------------------------------------------------
456  */
457 herr_t
H5AC_dest(H5F_t * f)458 H5AC_dest(H5F_t *f)
459 {
460     hbool_t log_enabled;  /* TRUE if logging was set up */
461     hbool_t curr_logging; /* TRUE if currently logging */
462 #ifdef H5_HAVE_PARALLEL
463     H5AC_aux_t *aux_ptr = NULL;
464 #endif                          /* H5_HAVE_PARALLEL */
465     herr_t ret_value = SUCCEED; /* Return value */
466 
467     FUNC_ENTER_NOAPI(FAIL)
468 
469     /* Sanity check */
470     HDassert(f);
471     HDassert(f->shared);
472     HDassert(f->shared->cache);
473 
474 #if H5AC_DUMP_STATS_ON_CLOSE
475     /* Dump debugging info */
476     H5AC_stats(f);
477 #endif /* H5AC_DUMP_STATS_ON_CLOSE */
478 
479     /* Check if log messages are being emitted */
480     if (H5C_get_logging_status(f->shared->cache, &log_enabled, &curr_logging) < 0)
481 
482         HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to get logging status")
483     if (log_enabled && curr_logging) {
484 
485         if (H5C_log_write_destroy_cache_msg(f->shared->cache) < 0)
486 
487             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
488     }
489 
490     /* Tear down logging */
491     if (log_enabled) {
492 
493         if (H5C_log_tear_down(f->shared->cache) < 0)
494 
495             HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "mdc logging tear-down failed")
496     }
497 
498 #ifdef H5_HAVE_PARALLEL
499 
500     /* destroying the cache, so clear all collective entries */
501     if (H5C_clear_coll_entries(f->shared->cache, FALSE) < 0)
502 
503         HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "H5C_clear_coll_entries() failed")
504 
505     aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(f->shared->cache);
506 
507     if (aux_ptr) {
508 
509         /* Sanity check */
510         HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
511 
512         /* If the file was opened R/W, attempt to flush all entries
513          * from rank 0 & Bcast clean list to other ranks.
514          *
515          * Must not flush in the R/O case, as this will trigger the
516          * free space manager settle routines.
517          *
518          * Must also enable the skip list before the call to
519          * H5AC__flush_entries() and disable it afterwards, as the
520          * skip list will be disabled after the previous flush.
521          *
522          * Note that H5C_dest() does slist setup and take down as well.
523          * Unfortunately, we can't do the setup and take down just once,
524          * as H5C_dest() is called directly in the test code.
525          *
526          * Fortunately, the cache should be clean or close to it at this
527          * point, so the overhead should be minimal.
528          */
529         if (H5F_ACC_RDWR & H5F_INTENT(f)) {
530 
531             /* enable and load the slist */
532             if (H5C_set_slist_enabled(f->shared->cache, TRUE, FALSE) < 0)
533 
534                 HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "set slist enabled failed")
535 
536             if (H5AC__flush_entries(f) < 0)
537 
538                 HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush")
539 
540             /* disable the slist -- should be empty */
541             if (H5C_set_slist_enabled(f->shared->cache, FALSE, FALSE) < 0)
542 
543                 HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "disable slist failed")
544         }
545     }
546 #endif /* H5_HAVE_PARALLEL */
547 
548     /* Destroy the cache */
549     if (H5C_dest(f) < 0)
550 
551         HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't destroy cache")
552 
553     f->shared->cache = NULL;
554 
555 #ifdef H5_HAVE_PARALLEL
556 
557     if (aux_ptr != NULL) {
558 
559         if (aux_ptr->d_slist_ptr != NULL) {
560 
561             HDassert(H5SL_count(aux_ptr->d_slist_ptr) == 0);
562             H5SL_close(aux_ptr->d_slist_ptr);
563 
564         } /* end if */
565 
566         if (aux_ptr->c_slist_ptr != NULL) {
567 
568             HDassert(H5SL_count(aux_ptr->c_slist_ptr) == 0);
569             H5SL_close(aux_ptr->c_slist_ptr);
570 
571         } /* end if */
572 
573         if (aux_ptr->candidate_slist_ptr != NULL) {
574 
575             HDassert(H5SL_count(aux_ptr->candidate_slist_ptr) == 0);
576             H5SL_close(aux_ptr->candidate_slist_ptr);
577 
578         } /* end if */
579 
580         aux_ptr->magic = 0;
581         aux_ptr        = H5FL_FREE(H5AC_aux_t, aux_ptr);
582 
583     }  /* end if */
584 #endif /* H5_HAVE_PARALLEL */
585 
586 done:
587     FUNC_LEAVE_NOAPI(ret_value)
588 } /* H5AC_dest() */
589 
590 /*-------------------------------------------------------------------------
591  * Function:    H5AC_evict
592  *
593  * Purpose:     Evict all entries except the pinned entries
594  *              in the cache.
595  *
596  * Return:      Non-negative on success/Negative on failure
597  *
598  * Programmer:  Vailin Choi
599  *              Dec 2013
600  *
601  *-------------------------------------------------------------------------
602  */
603 herr_t
H5AC_evict(H5F_t * f)604 H5AC_evict(H5F_t *f)
605 {
606     herr_t ret_value = SUCCEED; /* Return value */
607 
608     FUNC_ENTER_NOAPI(FAIL)
609 
610     /* Sanity check */
611     HDassert(f);
612     HDassert(f->shared);
613     HDassert(f->shared->cache);
614 
615     /* Evict all entries in the cache except the pinned superblock entry */
616     if (H5C_evict(f) < 0)
617         HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "can't evict cache")
618 
619 done:
620     /* If currently logging, generate a message */
621     if (f->shared->cache->log_info->logging)
622         if (H5C_log_write_evict_cache_msg(f->shared->cache, ret_value) < 0)
623             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
624 
625     FUNC_LEAVE_NOAPI(ret_value)
626 } /* H5AC_evict() */
627 
628 /*-------------------------------------------------------------------------
629  * Function:    H5AC_expunge_entry
630  *
631  * Purpose:     Expunge the target entry from the cache without writing it
632  *              to disk even if it is dirty.  The entry must not be either
633  *              pinned or protected.
634  *
635  * Return:      Non-negative on success/Negative on failure
636  *
637  * Programmer:  John Mainzer
638  *              6/30/06
639  *
640  *-------------------------------------------------------------------------
641  */
642 herr_t
H5AC_expunge_entry(H5F_t * f,const H5AC_class_t * type,haddr_t addr,unsigned flags)643 H5AC_expunge_entry(H5F_t *f, const H5AC_class_t *type, haddr_t addr, unsigned flags)
644 {
645     herr_t ret_value = SUCCEED; /* Return value */
646 
647     FUNC_ENTER_NOAPI(FAIL)
648 
649     /* Sanity checks */
650     HDassert(f);
651     HDassert(f->shared);
652     HDassert(f->shared->cache);
653     HDassert(type);
654     HDassert(type->serialize);
655     HDassert(H5F_addr_defined(addr));
656 
657     if (H5C_expunge_entry(f, type, addr, flags) < 0)
658         HGOTO_ERROR(H5E_CACHE, H5E_CANTEXPUNGE, FAIL, "H5C_expunge_entry() failed")
659 
660 done:
661     /* If currently logging, generate a message */
662     if (f->shared->cache->log_info->logging)
663         if (H5C_log_write_expunge_entry_msg(f->shared->cache, addr, type->id, ret_value) < 0)
664             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
665 
666     FUNC_LEAVE_NOAPI(ret_value)
667 } /* H5AC_expunge_entry() */
668 
669 /*-------------------------------------------------------------------------
670  * Function:    H5AC_flush
671  *
672  * Purpose:     Flush (and possibly destroy) the metadata cache associated
673  *              with the specified file.
674  *
675  *              If the cache contains protected entries, the function will
676  *              fail, as protected entries cannot be flushed.  However
677  *              all unprotected entries should be flushed before the
678  *              function returns failure.
679  *
680  * Return:      Non-negative on success/Negative on failure if there was a
681  *              request to flush all items and something was protected.
682  *
683  * Programmer:  Robb Matzke
684  *              Jul  9 1997
685  *
686  *-------------------------------------------------------------------------
687  */
688 herr_t
H5AC_flush(H5F_t * f)689 H5AC_flush(H5F_t *f)
690 {
691     herr_t ret_value = SUCCEED; /* Return value */
692 
693     FUNC_ENTER_NOAPI(FAIL)
694 
695     /* Sanity checks */
696     HDassert(f);
697     HDassert(f->shared);
698     HDassert(f->shared->cache);
699 
700 #ifdef H5_HAVE_PARALLEL
701     /* flushing the cache, so clear all collective entries */
702     if (H5C_clear_coll_entries(f->shared->cache, FALSE) < 0)
703         HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "H5C_clear_coll_entries() failed")
704 
705     /* Attempt to flush all entries from rank 0 & Bcast clean list to other ranks */
706     if (H5AC__flush_entries(f) < 0)
707         HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush")
708 #endif /* H5_HAVE_PARALLEL */
709 
710     /* Flush the cache */
711     /* (Again, in parallel - writes out the superblock) */
712     if (H5C_flush_cache(f, H5AC__NO_FLAGS_SET) < 0)
713         HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush cache")
714 
715 done:
716     /* If currently logging, generate a message */
717     if (f->shared->cache->log_info->logging)
718         if (H5C_log_write_flush_cache_msg(f->shared->cache, ret_value) < 0)
719             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
720 
721     FUNC_LEAVE_NOAPI(ret_value)
722 } /* H5AC_flush() */
723 
724 /*-------------------------------------------------------------------------
725  * Function:    H5AC_get_entry_status
726  *
727  * Purpose:     Given a file address, determine whether the metadata
728  *              cache contains an entry at that location.  If it does,
729  *              also determine whether the entry is dirty, protected,
730  *              pinned, etc. and return that information to the caller
731  *              in *status.
732  *
733  *              If the specified entry doesn't exist, set *status_ptr
734  *              to zero.
735  *
736  *              On error, the value of *status is undefined.
737  *
738  * Return:      Non-negative on success/Negative on failure
739  *
740  * Programmer:  John Mainzer
741  *              4/27/06
742  *
743  *-------------------------------------------------------------------------
744  */
745 herr_t
H5AC_get_entry_status(const H5F_t * f,haddr_t addr,unsigned * status)746 H5AC_get_entry_status(const H5F_t *f, haddr_t addr, unsigned *status)
747 {
748     hbool_t in_cache;     /* Entry @ addr is in the cache */
749     hbool_t is_dirty;     /* Entry @ addr is in the cache and dirty */
750     hbool_t is_protected; /* Entry @ addr is in the cache and protected */
751     hbool_t is_pinned;    /* Entry @ addr is in the cache and pinned */
752     hbool_t is_corked;
753     hbool_t is_flush_dep_child;  /* Entry @ addr is in the cache and is a flush dependency child */
754     hbool_t is_flush_dep_parent; /* Entry @ addr is in the cache and is a flush dependency parent */
755     hbool_t image_is_up_to_date; /* Entry @ addr is in the cache and has an up to date image */
756     herr_t  ret_value = SUCCEED; /* Return value */
757 
758     FUNC_ENTER_NOAPI(FAIL)
759 
760     if ((f == NULL) || (!H5F_addr_defined(addr)) || (status == NULL))
761         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad param(s) on entry")
762 
763     if (H5C_get_entry_status(f, addr, NULL, &in_cache, &is_dirty, &is_protected, &is_pinned, &is_corked,
764                              &is_flush_dep_parent, &is_flush_dep_child, &image_is_up_to_date) < 0)
765         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_entry_status() failed")
766 
767     if (in_cache) {
768         *status |= H5AC_ES__IN_CACHE;
769         if (is_dirty)
770             *status |= H5AC_ES__IS_DIRTY;
771         if (is_protected)
772             *status |= H5AC_ES__IS_PROTECTED;
773         if (is_pinned)
774             *status |= H5AC_ES__IS_PINNED;
775         if (is_corked)
776             *status |= H5AC_ES__IS_CORKED;
777         if (is_flush_dep_parent)
778             *status |= H5AC_ES__IS_FLUSH_DEP_PARENT;
779         if (is_flush_dep_child)
780             *status |= H5AC_ES__IS_FLUSH_DEP_CHILD;
781         if (image_is_up_to_date)
782             *status |= H5AC_ES__IMAGE_IS_UP_TO_DATE;
783     } /* end if */
784     else
785         *status = 0;
786 
787 done:
788     FUNC_LEAVE_NOAPI(ret_value)
789 } /* H5AC_get_entry_status() */
790 
791 /*-------------------------------------------------------------------------
792  * Function:    H5AC_insert_entry
793  *
794  * Purpose:     Adds the specified thing to the cache.  The thing need not
795  *              exist on disk yet, but it must have an address and disk
796  *              space reserved.
797  *
798  * Return:      Non-negative on success/Negative on failure
799  *
800  * Programmer:  Robb Matzke
801  *              Jul  9 1997
802  *
803  *-------------------------------------------------------------------------
804  */
805 herr_t
H5AC_insert_entry(H5F_t * f,const H5AC_class_t * type,haddr_t addr,void * thing,unsigned int flags)806 H5AC_insert_entry(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing, unsigned int flags)
807 {
808     herr_t ret_value = SUCCEED; /* Return value */
809 
810     FUNC_ENTER_NOAPI(FAIL)
811 
812     /* Sanity checks */
813     HDassert(f);
814     HDassert(f->shared);
815     HDassert(f->shared->cache);
816     HDassert(type);
817     HDassert(type->serialize);
818     HDassert(H5F_addr_defined(addr));
819     HDassert(thing);
820 
821     /* Check for invalid access request */
822     if (0 == (H5F_INTENT(f) & H5F_ACC_RDWR))
823         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "no write intent on file")
824 
825 #if H5AC_DO_TAGGING_SANITY_CHECKS
826     if (!H5C_get_ignore_tags(f->shared->cache) && H5AC__verify_tag(type) < 0)
827         HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Bad tag value")
828 #endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
829 
830     /* Insert entry into metadata cache */
831     if (H5C_insert_entry(f, type, addr, thing, flags) < 0)
832         HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C_insert_entry() failed")
833 
834 #ifdef H5_HAVE_PARALLEL
835     {
836         H5AC_aux_t *aux_ptr;
837 
838         if (NULL != (aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(f->shared->cache))) {
839             /* Log the new entry */
840             if (H5AC__log_inserted_entry((H5AC_info_t *)thing) < 0)
841                 HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5AC__log_inserted_entry() failed")
842 
843             /* Check if we should try to flush */
844             if (aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold)
845                 if (H5AC__run_sync_point(f, H5AC_SYNC_POINT_OP__FLUSH_TO_MIN_CLEAN) < 0)
846                     HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't run sync point")
847         } /* end if */
848     }
849 #endif /* H5_HAVE_PARALLEL */
850 
851 done:
852     /* If currently logging, generate a message */
853     if (f->shared->cache->log_info->logging)
854         if (H5C_log_write_insert_entry_msg(f->shared->cache, addr, type->id, flags,
855                                            ((H5C_cache_entry_t *)thing)->size, ret_value) < 0)
856             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
857 
858     FUNC_LEAVE_NOAPI(ret_value)
859 } /* H5AC_insert_entry() */
860 
861 /*-------------------------------------------------------------------------
862  * Function:    H5AC_load_cache_image_on_next_protect
863  *
864  * Purpose:     Load the cache image block at the specified location,
865  *              decode it, and insert its contents into the metadata
866  *              cache.
867  *
868  * Return:      Non-negative on success/Negative on failure
869  *
870  * Programmer:  John Mainzer
871  *              7/6/15
872  *
873  *-------------------------------------------------------------------------
874  */
875 herr_t
H5AC_load_cache_image_on_next_protect(H5F_t * f,haddr_t addr,hsize_t len,hbool_t rw)876 H5AC_load_cache_image_on_next_protect(H5F_t *f, haddr_t addr, hsize_t len, hbool_t rw)
877 {
878     herr_t ret_value = SUCCEED; /* Return value */
879 
880     FUNC_ENTER_NOAPI(FAIL)
881 
882     /* Sanity checks */
883     HDassert(f);
884     HDassert(f->shared);
885     HDassert(f->shared->cache);
886 
887     if (H5C_load_cache_image_on_next_protect(f, addr, len, rw) < 0)
888         HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, FAIL, "call to H5C_load_cache_image_on_next_protect failed")
889 
890 done:
891     FUNC_LEAVE_NOAPI(ret_value)
892 } /* H5AC_load_cache_image_on_next_protect() */
893 
894 /*-------------------------------------------------------------------------
895  * Function:    H5AC_mark_entry_dirty
896  *
897  * Purpose:     Mark a pinned or protected entry as dirty.  The target
898  *              entry MUST be either pinned, protected, or both.
899  *
900  * Return:      Non-negative on success/Negative on failure
901  *
902  * Programmer:  John Mainzer
903  *              5/16/06
904  *
905  *-------------------------------------------------------------------------
906  */
907 herr_t
H5AC_mark_entry_dirty(void * thing)908 H5AC_mark_entry_dirty(void *thing)
909 {
910     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
911     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
912     herr_t       ret_value = SUCCEED; /* Return value */
913 
914     FUNC_ENTER_NOAPI(FAIL)
915 
916     /* Sanity check */
917     HDassert(thing);
918 
919     /* Set up entry & cache pointers */
920     entry_ptr = (H5AC_info_t *)thing;
921     cache_ptr = entry_ptr->cache_ptr;
922 
923 #ifdef H5_HAVE_PARALLEL
924     {
925         H5AC_aux_t *aux_ptr;
926 
927         aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
928         if ((!entry_ptr->is_dirty) && (!entry_ptr->is_protected) && (entry_ptr->is_pinned) &&
929             (NULL != aux_ptr))
930             if (H5AC__log_dirtied_entry(entry_ptr) < 0)
931                 HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "can't log dirtied entry")
932     }
933 #endif /* H5_HAVE_PARALLEL */
934 
935     if (H5C_mark_entry_dirty(thing) < 0)
936         HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "can't mark pinned or protected entry dirty")
937 
938 done:
939     /* If currently logging, generate a message */
940     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
941         if (cache_ptr->log_info->logging)
942             if (H5C_log_write_mark_entry_dirty_msg(cache_ptr, entry_ptr, ret_value) < 0)
943                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
944 
945     FUNC_LEAVE_NOAPI(ret_value)
946 } /* H5AC_mark_entry_dirty() */
947 
948 /*-------------------------------------------------------------------------
949  * Function:    H5AC_mark_entry_clean
950  *
951  * Purpose:     Mark a pinned entry as clean.  The target
952  *              entry MUST be pinned.
953  *
954  * Return:      Non-negative on success/Negative on failure
955  *
956  * Programmer:  Quincey Koziol
957  *              7/23/16
958  *
959  *-------------------------------------------------------------------------
960  */
961 herr_t
H5AC_mark_entry_clean(void * thing)962 H5AC_mark_entry_clean(void *thing)
963 {
964     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
965     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
966     herr_t       ret_value = SUCCEED; /* Return value */
967 
968     FUNC_ENTER_NOAPI(FAIL)
969 
970     /* Sanity check */
971     HDassert(thing);
972 
973     entry_ptr = (H5AC_info_t *)thing;
974     cache_ptr = entry_ptr->cache_ptr;
975 
976 #ifdef H5_HAVE_PARALLEL
977     {
978         H5AC_aux_t *aux_ptr;
979 
980         aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
981         if ((!entry_ptr->is_dirty) && (!entry_ptr->is_protected) && (entry_ptr->is_pinned) &&
982             (NULL != aux_ptr))
983             if (H5AC__log_cleaned_entry(entry_ptr) < 0)
984                 HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKCLEAN, FAIL, "can't log cleaned entry")
985     }
986 #endif /* H5_HAVE_PARALLEL */
987 
988     if (H5C_mark_entry_clean(thing) < 0)
989         HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKCLEAN, FAIL, "can't mark pinned or protected entry clean")
990 
991 done:
992     /* If currently logging, generate a message */
993     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
994         if (cache_ptr->log_info->logging)
995             if (H5C_log_write_mark_entry_clean_msg(cache_ptr, entry_ptr, ret_value) < 0)
996                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
997 
998     FUNC_LEAVE_NOAPI(ret_value)
999 } /* H5AC_mark_entry_clean() */
1000 
1001 /*-------------------------------------------------------------------------
1002  * Function:    H5AC_mark_entry_unserialized
1003  *
1004  * Purpose:     Mark a pinned or protected entry as unserialized.  The target
1005  *              entry MUST be either pinned, protected, or both.
1006  *
1007  * Return:      Non-negative on success/Negative on failure
1008  *
1009  * Programmer:  Quincey Koziol
1010  *              12/22/16
1011  *
1012  *-------------------------------------------------------------------------
1013  */
1014 herr_t
H5AC_mark_entry_unserialized(void * thing)1015 H5AC_mark_entry_unserialized(void *thing)
1016 {
1017     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
1018     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
1019     herr_t       ret_value = SUCCEED; /* Return value */
1020 
1021     FUNC_ENTER_NOAPI(FAIL)
1022 
1023     /* Sanity check */
1024     HDassert(thing);
1025 
1026     /* Set up entry & cache pointers */
1027     entry_ptr = (H5AC_info_t *)thing;
1028     cache_ptr = entry_ptr->cache_ptr;
1029 
1030     if (H5C_mark_entry_unserialized(thing) < 0)
1031         HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKUNSERIALIZED, FAIL, "can't mark entry unserialized")
1032 
1033 done:
1034     /* If currently logging, generate a message */
1035     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
1036         if (cache_ptr->log_info->logging)
1037             if (H5C_log_write_mark_unserialized_entry_msg(cache_ptr, entry_ptr, ret_value) < 0)
1038                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1039 
1040     FUNC_LEAVE_NOAPI(ret_value)
1041 } /* H5AC_mark_entry_unserialized() */
1042 
1043 /*-------------------------------------------------------------------------
1044  * Function:    H5AC_mark_entry_serialized
1045  *
1046  * Purpose:     Mark a pinned entry as serialized.  The target
1047  *              entry MUST be pinned.
1048  *
1049  * Return:      Non-negative on success/Negative on failure
1050  *
1051  * Programmer:  Quincey Koziol
1052  *              12/22/16
1053  *
1054  *-------------------------------------------------------------------------
1055  */
1056 herr_t
H5AC_mark_entry_serialized(void * thing)1057 H5AC_mark_entry_serialized(void *thing)
1058 {
1059     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
1060     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
1061     herr_t       ret_value = SUCCEED; /* Return value */
1062 
1063     FUNC_ENTER_NOAPI(FAIL)
1064 
1065     /* Sanity check */
1066     HDassert(thing);
1067 
1068     entry_ptr = (H5AC_info_t *)thing;
1069     cache_ptr = entry_ptr->cache_ptr;
1070 
1071     if (H5C_mark_entry_serialized(thing) < 0)
1072         HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKSERIALIZED, FAIL, "can't mark entry serialized")
1073 
1074 done:
1075     /* If currently logging, generate a message */
1076     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
1077         if (cache_ptr->log_info->logging)
1078             if (H5C_log_write_mark_serialized_entry_msg(cache_ptr, entry_ptr, ret_value) < 0)
1079                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1080 
1081     FUNC_LEAVE_NOAPI(ret_value)
1082 } /* H5AC_mark_entry_serialized() */
1083 
1084 /*-------------------------------------------------------------------------
1085  * Function:    H5AC_move_entry
1086  *
1087  * Purpose:     Use this function to notify the cache that an object's
1088  *              file address changed.
1089  *
1090  * Return:      Non-negative on success/Negative on failure
1091  *
1092  * Programmer:  Robb Matzke
1093  *              Jul  9 1997
1094  *
1095  *-------------------------------------------------------------------------
1096  */
1097 herr_t
H5AC_move_entry(H5F_t * f,const H5AC_class_t * type,haddr_t old_addr,haddr_t new_addr)1098 H5AC_move_entry(H5F_t *f, const H5AC_class_t *type, haddr_t old_addr, haddr_t new_addr)
1099 {
1100 #ifdef H5_HAVE_PARALLEL
1101     H5AC_aux_t *aux_ptr;
1102 #endif                          /* H5_HAVE_PARALLEL */
1103     herr_t ret_value = SUCCEED; /* Return value */
1104 
1105     FUNC_ENTER_NOAPI(FAIL)
1106 
1107     /* Sanity checks */
1108     HDassert(f);
1109     HDassert(f->shared->cache);
1110     HDassert(type);
1111     HDassert(H5F_addr_defined(old_addr));
1112     HDassert(H5F_addr_defined(new_addr));
1113     HDassert(H5F_addr_ne(old_addr, new_addr));
1114 
1115 #ifdef H5_HAVE_PARALLEL
1116     /* Log moving the entry */
1117     if (NULL != (aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(f->shared->cache)))
1118         if (H5AC__log_moved_entry(f, old_addr, new_addr) < 0)
1119             HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "can't log moved entry")
1120 #endif /* H5_HAVE_PARALLEL */
1121 
1122     if (H5C_move_entry(f->shared->cache, type, old_addr, new_addr) < 0)
1123         HGOTO_ERROR(H5E_CACHE, H5E_CANTMOVE, FAIL, "H5C_move_entry() failed")
1124 
1125 #ifdef H5_HAVE_PARALLEL
1126     /* Check if we should try to flush */
1127     if (NULL != aux_ptr && aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold)
1128         if (H5AC__run_sync_point(f, H5AC_SYNC_POINT_OP__FLUSH_TO_MIN_CLEAN) < 0)
1129             HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't run sync point")
1130 #endif /* H5_HAVE_PARALLEL */
1131 
1132 done:
1133     /* If currently logging, generate a message */
1134     if (f->shared->cache->log_info->logging)
1135         if (H5C_log_write_move_entry_msg(f->shared->cache, old_addr, new_addr, type->id, ret_value) < 0)
1136             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1137 
1138     FUNC_LEAVE_NOAPI(ret_value)
1139 } /* H5AC_move_entry() */
1140 
1141 /*-------------------------------------------------------------------------
1142  * Function:    H5AC_pin_protected_entry()
1143  *
1144  * Purpose:     Pin a protected cache entry.  The entry must be protected
1145  *              at the time of call, and must be unpinned.
1146  *
1147  * Return:      Non-negative on success/Negative on failure
1148  *
1149  * Programmer:  John Mainzer
1150  *              4/27/06
1151  *
1152  *-------------------------------------------------------------------------
1153  */
1154 herr_t
H5AC_pin_protected_entry(void * thing)1155 H5AC_pin_protected_entry(void *thing)
1156 {
1157     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
1158     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
1159     herr_t       ret_value = SUCCEED; /* Return value */
1160 
1161     FUNC_ENTER_NOAPI(FAIL)
1162 
1163     /* Sanity check */
1164     HDassert(thing);
1165 
1166     entry_ptr = (H5AC_info_t *)thing;
1167     cache_ptr = entry_ptr->cache_ptr;
1168     HDassert(cache_ptr);
1169 
1170     /* Pin entry */
1171     if (H5C_pin_protected_entry(thing) < 0)
1172         HGOTO_ERROR(H5E_CACHE, H5E_CANTPIN, FAIL, "can't pin entry")
1173 
1174 done:
1175     /* If currently logging, generate a message */
1176     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
1177         if (cache_ptr->log_info->logging)
1178             if (H5C_log_write_pin_entry_msg(cache_ptr, entry_ptr, ret_value) < 0)
1179                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1180 
1181     FUNC_LEAVE_NOAPI(ret_value)
1182 } /* H5AC_pin_protected_entry() */
1183 
1184 /*-------------------------------------------------------------------------
1185  *
1186  * Function:    H5AC_prep_for_file_close
1187  *
1188  * Purpose:     This function should be called just prior to the cache
1189  *              flushes at file close.
1190  *
1191  *              The objective of the call is to allow the metadata cache
1192  *              to do any preparatory work prior to generation of a
1193  *              cache image.
1194  *
1195  * Return:      Non-negative on success/Negative on failure
1196  *
1197  * Programmer:  John Mainzer
1198  *              7/3/15
1199  *
1200  *-------------------------------------------------------------------------
1201  */
1202 herr_t
H5AC_prep_for_file_close(H5F_t * f)1203 H5AC_prep_for_file_close(H5F_t *f)
1204 {
1205     herr_t ret_value = SUCCEED; /* Return value */
1206 
1207     FUNC_ENTER_NOAPI(FAIL)
1208 
1209     /* Sanity checks */
1210     HDassert(f);
1211     HDassert(f->shared);
1212     HDassert(f->shared->cache);
1213 
1214     if (H5C_prep_for_file_close(f) < 0)
1215         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "cache prep for file close failed")
1216 
1217 done:
1218     FUNC_LEAVE_NOAPI(ret_value)
1219 } /* H5AC_prep_for_file_close() */
1220 
1221 /*-------------------------------------------------------------------------
1222  *
1223  * Function:    H5AC_prep_for_file_flush
1224  *
1225  * Purpose:     This function should be called just prior to the first
1226  *              call to H5AC_flush() during a file flush.
1227  *
1228  *              Its purpose is to handly any setup required prior to
1229  *              metadata cache flush.
1230  *
1231  *              Initially, this means setting up the slist prior to the
1232  *              flush.  We do this in a seperate call because
1233  *              H5F__flush_phase2() make repeated calls to H5AC_flush().
1234  *              Handling this detail in separate calls allows us to avoid
1235  *              the overhead of setting up and taking down the skip list
1236  *              repeatedly.
1237  *
1238  * Return:      Non-negative on success/Negative on failure
1239  *
1240  * Programmer:  John Mainzer
1241  *              5/5/20
1242  *
1243  * Changes:     None.
1244  *
1245  *-------------------------------------------------------------------------
1246  */
1247 herr_t
H5AC_prep_for_file_flush(H5F_t * f)1248 H5AC_prep_for_file_flush(H5F_t *f)
1249 {
1250     herr_t ret_value = SUCCEED; /* Return value */
1251 
1252     FUNC_ENTER_NOAPI(FAIL)
1253 
1254     /* Sanity checks */
1255     HDassert(f);
1256     HDassert(f->shared);
1257     HDassert(f->shared->cache);
1258 
1259     if (H5C_set_slist_enabled(f->shared->cache, TRUE, FALSE) < 0)
1260 
1261         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "slist enabled failed")
1262 
1263 done:
1264 
1265     FUNC_LEAVE_NOAPI(ret_value)
1266 
1267 } /* H5AC_prep_for_file_flush() */
1268 
1269 /*-------------------------------------------------------------------------
1270  *
1271  * Function:    H5AC_secure_from_file_flush
1272  *
1273  * Purpose:     This function should be called just after the last
1274  *              call to H5AC_flush() during a file flush.
1275  *
1276  *              Its purpose is to perform any necessary cleanup after the
1277  *              metadata cache flush.
1278  *
1279  *              The objective of the call is to allow the metadata cache
1280  *              to do any necessary necessary cleanup work after a cache
1281  *              flush.
1282  *
1283  *              Initially, this means taking down the slist after the
1284  *              flush.  We do this in a seperate call because
1285  *              H5F__flush_phase2() make repeated calls to H5AC_flush().
1286  *              Handling this detail in separate calls allows us to avoid
1287  *              the overhead of setting up and taking down the skip list
1288  *              repeatedly.
1289  *
1290  * Return:      Non-negative on success/Negative on failure
1291  *
1292  * Programmer:  John Mainzer
1293  *              5/5/20
1294  *
1295  * Changes:     None.
1296  *
1297  *-------------------------------------------------------------------------
1298  */
1299 herr_t
H5AC_secure_from_file_flush(H5F_t * f)1300 H5AC_secure_from_file_flush(H5F_t *f)
1301 {
1302     herr_t ret_value = SUCCEED; /* Return value */
1303 
1304     FUNC_ENTER_NOAPI(FAIL)
1305 
1306     /* Sanity checks */
1307     HDassert(f);
1308     HDassert(f->shared);
1309     HDassert(f->shared->cache);
1310 
1311     if (H5C_set_slist_enabled(f->shared->cache, FALSE, FALSE) < 0)
1312 
1313         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "slist enabled failed")
1314 
1315 done:
1316 
1317     FUNC_LEAVE_NOAPI(ret_value)
1318 
1319 } /* H5AC_secure_from_file_flush() */
1320 
1321 /*-------------------------------------------------------------------------
1322  *
1323  * Function:    H5AC_create_flush_dependency()
1324  *
1325  * Purpose:     Create a flush dependency between two entries in the metadata
1326  *              cache.
1327  *
1328  * Return:      Non-negative on success/Negative on failure
1329  *
1330  * Programmer:  Quincey Koziol
1331  *              3/24/09
1332  *
1333  *-------------------------------------------------------------------------
1334  */
1335 herr_t
H5AC_create_flush_dependency(void * parent_thing,void * child_thing)1336 H5AC_create_flush_dependency(void *parent_thing, void *child_thing)
1337 {
1338     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
1339     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
1340     herr_t       ret_value = SUCCEED; /* Return value */
1341 
1342     FUNC_ENTER_NOAPI(FAIL)
1343 
1344     /* Sanity check */
1345     HDassert(parent_thing);
1346     HDassert(child_thing);
1347 
1348     entry_ptr = (H5AC_info_t *)parent_thing;
1349     cache_ptr = entry_ptr->cache_ptr;
1350     HDassert(cache_ptr);
1351 
1352     /* Create the flush dependency */
1353     if (H5C_create_flush_dependency(parent_thing, child_thing) < 0)
1354         HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "H5C_create_flush_dependency() failed")
1355 
1356 done:
1357     /* If currently logging, generate a message */
1358     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
1359         if (cache_ptr->log_info->logging)
1360             if (H5C_log_write_create_fd_msg(cache_ptr, (H5AC_info_t *)parent_thing,
1361                                             (H5AC_info_t *)child_thing, ret_value) < 0)
1362                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1363 
1364     FUNC_LEAVE_NOAPI(ret_value)
1365 } /* H5AC_create_flush_dependency() */
1366 
1367 /*-------------------------------------------------------------------------
1368  * Function:    H5AC_protect
1369  *
1370  * Purpose:     If the target entry is not in the cache, load it.  If
1371  *              necessary, attempt to evict one or more entries to keep
1372  *              the cache within its maximum size.
1373  *
1374  *              Mark the target entry as protected, and return its address
1375  *              to the caller.  The caller must call H5AC_unprotect() when
1376  *              finished with the entry.
1377  *
1378  *              While it is protected, the entry may not be either evicted
1379  *              or flushed -- nor may it be accessed by another call to
1380  *              H5AC_protect.  Any attempt to do so will result in a failure.
1381  *
1382  * Return:      Success:        Ptr to the object.
1383  *              Failure:        NULL
1384  *
1385  * Programmer:  Robb Matzke
1386  *              Sep  2 1997
1387  *
1388  *-------------------------------------------------------------------------
1389  */
1390 void *
H5AC_protect(H5F_t * f,const H5AC_class_t * type,haddr_t addr,void * udata,unsigned flags)1391 H5AC_protect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata, unsigned flags)
1392 {
1393     void *thing     = NULL; /* Pointer to native data structure for entry */
1394     void *ret_value = NULL; /* Return value */
1395 
1396     FUNC_ENTER_NOAPI(NULL)
1397 
1398     /* Sanity check */
1399     HDassert(f);
1400     HDassert(f->shared);
1401     HDassert(f->shared->cache);
1402     HDassert(type);
1403     HDassert(type->serialize);
1404     HDassert(H5F_addr_defined(addr));
1405 
1406     /* Check for unexpected flags -- H5C__FLUSH_COLLECTIVELY_FLAG
1407      * only permitted in the parallel case.
1408      */
1409 #ifdef H5_HAVE_PARALLEL
1410     HDassert(0 == (flags &
1411                    (unsigned)(~(H5C__READ_ONLY_FLAG | H5C__FLUSH_LAST_FLAG | H5C__FLUSH_COLLECTIVELY_FLAG))));
1412 #else  /* H5_HAVE_PARALLEL */
1413     HDassert(0 == (flags & (unsigned)(~(H5C__READ_ONLY_FLAG | H5C__FLUSH_LAST_FLAG))));
1414 #endif /* H5_HAVE_PARALLEL */
1415 
1416     /* Check for invalid access request */
1417     if ((0 == (H5F_INTENT(f) & H5F_ACC_RDWR)) && (0 == (flags & H5C__READ_ONLY_FLAG)))
1418         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "no write intent on file")
1419 
1420 #if H5AC_DO_TAGGING_SANITY_CHECKS
1421     if (!H5C_get_ignore_tags(f->shared->cache) && H5AC__verify_tag(type) < 0)
1422         HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, NULL, "Bad tag value")
1423 #endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
1424 
1425     if (NULL == (thing = H5C_protect(f, type, addr, udata, flags)))
1426         HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C_protect() failed")
1427 
1428     /* Set return value */
1429     ret_value = thing;
1430 
1431 done:
1432     /* If currently logging, generate a message */
1433     {
1434         herr_t fake_ret_value = (NULL == ret_value) ? FAIL : SUCCEED;
1435 
1436         if (f->shared->cache->log_info->logging)
1437             if (H5C_log_write_protect_entry_msg(f->shared->cache, (H5AC_info_t *)thing, type->id, flags,
1438                                                 fake_ret_value) < 0)
1439                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, NULL, "unable to emit log message")
1440     }
1441 
1442     FUNC_LEAVE_NOAPI(ret_value)
1443 } /* H5AC_protect() */
1444 
1445 /*-------------------------------------------------------------------------
1446  * Function:    H5AC_resize_entry
1447  *
1448  * Purpose:     Resize a pinned or protected entry.
1449  *
1450  * Return:      Non-negative on success/Negative on failure
1451  *
1452  * Programmer:  John Mainzer
1453  *              7/5/06
1454  *
1455  *-------------------------------------------------------------------------
1456  */
1457 herr_t
H5AC_resize_entry(void * thing,size_t new_size)1458 H5AC_resize_entry(void *thing, size_t new_size)
1459 {
1460     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
1461     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
1462     herr_t       ret_value = SUCCEED; /* Return value */
1463 
1464     FUNC_ENTER_NOAPI(FAIL)
1465 
1466     /* Sanity check */
1467     HDassert(thing);
1468 
1469     entry_ptr = (H5AC_info_t *)thing;
1470     cache_ptr = entry_ptr->cache_ptr;
1471     HDassert(cache_ptr);
1472 
1473     /* Resize the entry */
1474     if (H5C_resize_entry(thing, new_size) < 0)
1475         HGOTO_ERROR(H5E_CACHE, H5E_CANTRESIZE, FAIL, "can't resize entry")
1476 
1477 #ifdef H5_HAVE_PARALLEL
1478     {
1479         H5AC_aux_t *aux_ptr;
1480 
1481         aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
1482         if ((!entry_ptr->is_dirty) && (NULL != aux_ptr))
1483             if (H5AC__log_dirtied_entry(entry_ptr) < 0)
1484                 HGOTO_ERROR(H5E_CACHE, H5E_CANTMARKDIRTY, FAIL, "can't log dirtied entry")
1485     }
1486 #endif /* H5_HAVE_PARALLEL */
1487 
1488 done:
1489     /* If currently logging, generate a message */
1490     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
1491         if (cache_ptr->log_info->logging)
1492             if (H5C_log_write_resize_entry_msg(cache_ptr, entry_ptr, new_size, ret_value) < 0)
1493                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1494 
1495     FUNC_LEAVE_NOAPI(ret_value)
1496 } /* H5AC_resize_entry() */
1497 
1498 /*-------------------------------------------------------------------------
1499  * Function:    H5AC_unpin_entry()
1500  *
1501  * Purpose:     Unpin a cache entry.  The entry must be unprotected at
1502  *              the time of call, and must be pinned.
1503  *
1504  * Return:      Non-negative on success/Negative on failure
1505  *
1506  * Programmer:  John Mainzer
1507  *              4/11/06
1508  *
1509  *-------------------------------------------------------------------------
1510  */
1511 herr_t
H5AC_unpin_entry(void * thing)1512 H5AC_unpin_entry(void *thing)
1513 {
1514     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
1515     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
1516     herr_t       ret_value = SUCCEED; /* Return value */
1517 
1518     FUNC_ENTER_NOAPI(FAIL)
1519 
1520     /* Sanity check */
1521     HDassert(thing);
1522 
1523     entry_ptr = (H5AC_info_t *)thing;
1524     cache_ptr = entry_ptr->cache_ptr;
1525     HDassert(cache_ptr);
1526 
1527     /* Unpin the entry */
1528     if (H5C_unpin_entry(thing) < 0)
1529         HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "can't unpin entry")
1530 
1531 done:
1532     /* If currently logging, generate a message */
1533     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
1534         if (cache_ptr->log_info->logging)
1535             if (H5C_log_write_unpin_entry_msg(cache_ptr, entry_ptr, ret_value) < 0)
1536                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1537 
1538     FUNC_LEAVE_NOAPI(ret_value)
1539 } /* H5AC_unpin_entry() */
1540 
1541 /*-------------------------------------------------------------------------
1542  * Function:    H5AC_destroy_flush_dependency()
1543  *
1544  * Purpose:     Destroy a flush dependency between two entries.
1545  *
1546  * Return:      Non-negative on success/Negative on failure
1547  *
1548  * Programmer:  Quincey Koziol
1549  *              3/24/09
1550  *
1551  *-------------------------------------------------------------------------
1552  */
1553 herr_t
H5AC_destroy_flush_dependency(void * parent_thing,void * child_thing)1554 H5AC_destroy_flush_dependency(void *parent_thing, void *child_thing)
1555 {
1556     H5AC_info_t *entry_ptr = NULL;    /* Pointer to the cache entry */
1557     H5C_t *      cache_ptr = NULL;    /* Pointer to the entry's associated metadata cache */
1558     herr_t       ret_value = SUCCEED; /* Return value */
1559 
1560     FUNC_ENTER_NOAPI(FAIL)
1561 
1562     /* Sanity check */
1563     HDassert(parent_thing);
1564     HDassert(child_thing);
1565 
1566     entry_ptr = (H5AC_info_t *)parent_thing;
1567     cache_ptr = entry_ptr->cache_ptr;
1568     HDassert(cache_ptr);
1569 
1570     /* Destroy the flush dependency */
1571     if (H5C_destroy_flush_dependency(parent_thing, child_thing) < 0)
1572         HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "H5C_destroy_flush_dependency() failed")
1573 
1574 done:
1575     /* If currently logging, generate a message */
1576     if (cache_ptr != NULL && cache_ptr->log_info != NULL)
1577         if (cache_ptr->log_info->logging)
1578             if (H5C_log_write_destroy_fd_msg(cache_ptr, (H5AC_info_t *)parent_thing,
1579                                              (H5AC_info_t *)child_thing, ret_value) < 0)
1580                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1581 
1582     FUNC_LEAVE_NOAPI(ret_value)
1583 } /* H5AC_destroy_flush_dependency() */
1584 
1585 /*-------------------------------------------------------------------------
1586  * Function:    H5AC_unprotect
1587  *
1588  * Purpose:     Undo an H5AC_protect() call -- specifically, mark the
1589  *              entry as unprotected, remove it from the protected list,
1590  *              and give it back to the replacement policy.
1591  *
1592  *              The TYPE and ADDR arguments must be the same as those in
1593  *              the corresponding call to H5AC_protect() and the THING
1594  *              argument must be the value returned by that call to
1595  *              H5AC_protect().
1596  *
1597  *              If the deleted flag is TRUE, simply remove the target entry
1598  *              from the cache, clear it, and free it without writing it to
1599  *              disk.
1600  *
1601  *              This version of the function is a complete re-write to
1602  *              use the new metadata cache.  While there isn't all that
1603  *              much difference between the old and new Purpose sections,
1604  *              the original version is given below.
1605  *
1606  *              Original purpose section:
1607  *
1608  *              This function should be called to undo the effect of
1609  *              H5AC_protect().  The TYPE and ADDR arguments should be the
1610  *              same as the corresponding call to H5AC_protect() and the
1611  *              THING argument should be the value returned by H5AC_protect().
1612  *              If the DELETED flag is set, then this object has been deleted
1613  *              from the file and should not be returned to the cache.
1614  *
1615  * Return:      Non-negative on success/Negative on failure
1616  *
1617  * Programmer:  Robb Matzke
1618  *              Sep  2 1997
1619  *
1620  *-------------------------------------------------------------------------
1621  */
1622 herr_t
H5AC_unprotect(H5F_t * f,const H5AC_class_t * type,haddr_t addr,void * thing,unsigned flags)1623 H5AC_unprotect(H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing, unsigned flags)
1624 {
1625     hbool_t dirtied;
1626     hbool_t deleted;
1627 #ifdef H5_HAVE_PARALLEL
1628     H5AC_aux_t *aux_ptr = NULL;
1629 #endif                          /* H5_HAVE_PARALLEL */
1630     herr_t ret_value = SUCCEED; /* Return value */
1631 
1632     FUNC_ENTER_NOAPI(FAIL)
1633 
1634     /* Sanity checks */
1635     HDassert(f);
1636     HDassert(f->shared);
1637     HDassert(f->shared->cache);
1638     HDassert(type);
1639     HDassert(type->deserialize);
1640     HDassert(type->image_len);
1641     HDassert(H5F_addr_defined(addr));
1642     HDassert(thing);
1643     HDassert(((H5AC_info_t *)thing)->addr == addr);
1644     HDassert(((H5AC_info_t *)thing)->type == type);
1645 
1646     dirtied =
1647         (hbool_t)(((flags & H5AC__DIRTIED_FLAG) == H5AC__DIRTIED_FLAG) || (((H5AC_info_t *)thing)->dirtied));
1648     deleted = (hbool_t)((flags & H5C__DELETED_FLAG) == H5C__DELETED_FLAG);
1649 
1650     /* Check if the size changed out from underneath us, if we're not deleting
1651      *  the entry.
1652      */
1653     if (dirtied && !deleted) {
1654         size_t curr_size = 0;
1655 
1656         if ((type->image_len)(thing, &curr_size) < 0)
1657             HGOTO_ERROR(H5E_CACHE, H5E_CANTGETSIZE, FAIL, "Can't get size of thing")
1658 
1659         if (((H5AC_info_t *)thing)->size != curr_size)
1660             HGOTO_ERROR(H5E_CACHE, H5E_BADSIZE, FAIL, "size of entry changed")
1661     } /* end if */
1662 
1663 #ifdef H5_HAVE_PARALLEL
1664     if (NULL != (aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(f->shared->cache))) {
1665         if (dirtied && ((H5AC_info_t *)thing)->is_dirty == FALSE)
1666             if (H5AC__log_dirtied_entry((H5AC_info_t *)thing) < 0)
1667                 HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "can't log dirtied entry")
1668 
1669         if (deleted && aux_ptr->mpi_rank == 0)
1670             if (H5AC__log_deleted_entry((H5AC_info_t *)thing) < 0)
1671                 HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "H5AC__log_deleted_entry() failed")
1672     }  /* end if */
1673 #endif /* H5_HAVE_PARALLEL */
1674 
1675     if (H5C_unprotect(f, addr, thing, flags) < 0)
1676         HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "H5C_unprotect() failed")
1677 
1678 #ifdef H5_HAVE_PARALLEL
1679     /* Check if we should try to flush */
1680     if ((aux_ptr != NULL) && (aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold))
1681         if (H5AC__run_sync_point(f, H5AC_SYNC_POINT_OP__FLUSH_TO_MIN_CLEAN) < 0)
1682             HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't run sync point")
1683 #endif /* H5_HAVE_PARALLEL */
1684 
1685 done:
1686     /* If currently logging, generate a message */
1687     if (f->shared->cache->log_info->logging)
1688         if (H5C_log_write_unprotect_entry_msg(f->shared->cache, addr, type->id, flags, ret_value) < 0)
1689             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1690 
1691     FUNC_LEAVE_NOAPI(ret_value)
1692 } /* H5AC_unprotect() */
1693 
1694 /*-------------------------------------------------------------------------
1695  * Function:    H5AC_get_cache_auto_resize_config
1696  *
1697  * Purpose:     Wrapper function for H5C_get_cache_auto_resize_config().
1698  *
1699  * Return:      SUCCEED on success, and FAIL on failure.
1700  *
1701  * Programmer:  John Mainzer
1702  *              3/10/05
1703  *
1704  *-------------------------------------------------------------------------
1705  */
1706 herr_t
H5AC_get_cache_auto_resize_config(const H5AC_t * cache_ptr,H5AC_cache_config_t * config_ptr)1707 H5AC_get_cache_auto_resize_config(const H5AC_t *cache_ptr, H5AC_cache_config_t *config_ptr)
1708 {
1709     H5C_auto_size_ctl_t internal_config;
1710     hbool_t             evictions_enabled;
1711     herr_t              ret_value = SUCCEED; /* Return value */
1712 
1713     FUNC_ENTER_NOAPI(FAIL)
1714 
1715     /* Check args */
1716     if ((cache_ptr == NULL) || (config_ptr == NULL) ||
1717         (config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION))
1718         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad cache_ptr or config_ptr on entry")
1719 #ifdef H5_HAVE_PARALLEL
1720     {
1721         H5AC_aux_t *aux_ptr;
1722 
1723         aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
1724         if ((aux_ptr != NULL) && (aux_ptr->magic != H5AC__H5AC_AUX_T_MAGIC))
1725             HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad aux_ptr on entry")
1726     }
1727 #endif /* H5_HAVE_PARALLEL */
1728 
1729     /* Retrieve the configuration */
1730     if (H5C_get_cache_auto_resize_config((const H5C_t *)cache_ptr, &internal_config) < 0)
1731         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_cache_auto_resize_config() failed")
1732     if (H5C_get_evictions_enabled((const H5C_t *)cache_ptr, &evictions_enabled) < 0)
1733         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_resize_enabled() failed")
1734 
1735     /* Set the information to return */
1736     if (internal_config.rpt_fcn == NULL)
1737         config_ptr->rpt_fcn_enabled = FALSE;
1738     else
1739         config_ptr->rpt_fcn_enabled = TRUE;
1740     config_ptr->open_trace_file        = FALSE;
1741     config_ptr->close_trace_file       = FALSE;
1742     config_ptr->trace_file_name[0]     = '\0';
1743     config_ptr->evictions_enabled      = evictions_enabled;
1744     config_ptr->set_initial_size       = internal_config.set_initial_size;
1745     config_ptr->initial_size           = internal_config.initial_size;
1746     config_ptr->min_clean_fraction     = internal_config.min_clean_fraction;
1747     config_ptr->max_size               = internal_config.max_size;
1748     config_ptr->min_size               = internal_config.min_size;
1749     config_ptr->epoch_length           = (long)(internal_config.epoch_length);
1750     config_ptr->incr_mode              = internal_config.incr_mode;
1751     config_ptr->lower_hr_threshold     = internal_config.lower_hr_threshold;
1752     config_ptr->increment              = internal_config.increment;
1753     config_ptr->apply_max_increment    = internal_config.apply_max_increment;
1754     config_ptr->max_increment          = internal_config.max_increment;
1755     config_ptr->decr_mode              = internal_config.decr_mode;
1756     config_ptr->upper_hr_threshold     = internal_config.upper_hr_threshold;
1757     config_ptr->flash_incr_mode        = internal_config.flash_incr_mode;
1758     config_ptr->flash_multiple         = internal_config.flash_multiple;
1759     config_ptr->flash_threshold        = internal_config.flash_threshold;
1760     config_ptr->decrement              = internal_config.decrement;
1761     config_ptr->apply_max_decrement    = internal_config.apply_max_decrement;
1762     config_ptr->max_decrement          = internal_config.max_decrement;
1763     config_ptr->epochs_before_eviction = (int)(internal_config.epochs_before_eviction);
1764     config_ptr->apply_empty_reserve    = internal_config.apply_empty_reserve;
1765     config_ptr->empty_reserve          = internal_config.empty_reserve;
1766 #ifdef H5_HAVE_PARALLEL
1767     {
1768         H5AC_aux_t *aux_ptr;
1769 
1770         if (NULL != (aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr))) {
1771             config_ptr->dirty_bytes_threshold   = aux_ptr->dirty_bytes_threshold;
1772             config_ptr->metadata_write_strategy = aux_ptr->metadata_write_strategy;
1773         } /* end if */
1774         else {
1775 #endif /* H5_HAVE_PARALLEL */
1776             config_ptr->dirty_bytes_threshold   = H5AC__DEFAULT_DIRTY_BYTES_THRESHOLD;
1777             config_ptr->metadata_write_strategy = H5AC__DEFAULT_METADATA_WRITE_STRATEGY;
1778 #ifdef H5_HAVE_PARALLEL
1779         } /* end else */
1780     }
1781 #endif /* H5_HAVE_PARALLEL */
1782 
1783 done:
1784     FUNC_LEAVE_NOAPI(ret_value)
1785 } /* H5AC_get_cache_auto_resize_config() */
1786 
1787 /*-------------------------------------------------------------------------
1788  * Function:    H5AC_get_cache_size
1789  *
1790  * Purpose:     Wrapper function for H5C_get_cache_size().
1791  *
1792  * Return:      SUCCEED on success, and FAIL on failure.
1793  *
1794  * Programmer:  John Mainzer
1795  *              3/11/05
1796  *
1797  *-------------------------------------------------------------------------
1798  */
1799 herr_t
H5AC_get_cache_size(H5AC_t * cache_ptr,size_t * max_size_ptr,size_t * min_clean_size_ptr,size_t * cur_size_ptr,uint32_t * cur_num_entries_ptr)1800 H5AC_get_cache_size(H5AC_t *cache_ptr, size_t *max_size_ptr, size_t *min_clean_size_ptr, size_t *cur_size_ptr,
1801                     uint32_t *cur_num_entries_ptr)
1802 {
1803     herr_t ret_value = SUCCEED; /* Return value */
1804 
1805     FUNC_ENTER_NOAPI(FAIL)
1806 
1807     if (H5C_get_cache_size((H5C_t *)cache_ptr, max_size_ptr, min_clean_size_ptr, cur_size_ptr,
1808                            cur_num_entries_ptr) < 0)
1809         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_cache_size() failed")
1810 
1811 done:
1812     FUNC_LEAVE_NOAPI(ret_value)
1813 } /* H5AC_get_cache_size() */
1814 
1815 /*-------------------------------------------------------------------------
1816  * Function:    H5AC_get_cache_flush_in_progess
1817  *
1818  * Purpose:     Wrapper function for H5C_get_cache_flush_in_progress().
1819  *
1820  * Return:      SUCCEED on success, and FAIL on failure.
1821  *
1822  * Programmer:  John Mainzer
1823  *              3/11/05
1824  *
1825  *-------------------------------------------------------------------------
1826  */
1827 herr_t
H5AC_get_cache_flush_in_progress(H5AC_t * cache_ptr,hbool_t * flush_in_progress_ptr)1828 H5AC_get_cache_flush_in_progress(H5AC_t *cache_ptr, hbool_t *flush_in_progress_ptr)
1829 {
1830     herr_t ret_value = SUCCEED; /* Return value */
1831 
1832     FUNC_ENTER_NOAPI(FAIL)
1833 
1834     if (H5C_get_cache_flush_in_progress((H5C_t *)cache_ptr, flush_in_progress_ptr) < 0)
1835         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_cache_flush_in_progress() failed")
1836 
1837 done:
1838     FUNC_LEAVE_NOAPI(ret_value)
1839 } /* H5AC_get_cache_flush_in_progress() */
1840 
1841 /*-------------------------------------------------------------------------
1842  * Function:    H5AC_get_cache_hit_rate
1843  *
1844  * Purpose:     Wrapper function for H5C_get_cache_hit_rate().
1845  *
1846  * Return:      SUCCEED on success, and FAIL on failure.
1847  *
1848  * Programmer:  John Mainzer
1849  *              3/10/05
1850  *
1851  *-------------------------------------------------------------------------
1852  */
1853 herr_t
H5AC_get_cache_hit_rate(H5AC_t * cache_ptr,double * hit_rate_ptr)1854 H5AC_get_cache_hit_rate(H5AC_t *cache_ptr, double *hit_rate_ptr)
1855 {
1856     herr_t ret_value = SUCCEED; /* Return value */
1857 
1858     FUNC_ENTER_NOAPI(FAIL)
1859 
1860     if (H5C_get_cache_hit_rate((H5C_t *)cache_ptr, hit_rate_ptr) < 0)
1861         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_cache_hit_rate() failed")
1862 
1863 done:
1864     FUNC_LEAVE_NOAPI(ret_value)
1865 } /* H5AC_get_cache_hit_rate() */
1866 
1867 /*-------------------------------------------------------------------------
1868  *
1869  * Function:    H5AC_reset_cache_hit_rate_stats()
1870  *
1871  * Purpose:     Wrapper function for H5C_reset_cache_hit_rate_stats().
1872  *
1873  * Return:      SUCCEED on success, and FAIL on failure.
1874  *
1875  * Programmer:  John Mainzer, 3/10/05
1876  *
1877  *-------------------------------------------------------------------------
1878  */
1879 herr_t
H5AC_reset_cache_hit_rate_stats(H5AC_t * cache_ptr)1880 H5AC_reset_cache_hit_rate_stats(H5AC_t *cache_ptr)
1881 {
1882     herr_t ret_value = SUCCEED; /* Return value */
1883 
1884     FUNC_ENTER_NOAPI(FAIL)
1885 
1886     if (H5C_reset_cache_hit_rate_stats((H5C_t *)cache_ptr) < 0)
1887         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_reset_cache_hit_rate_stats() failed")
1888 
1889 done:
1890     FUNC_LEAVE_NOAPI(ret_value)
1891 } /* H5AC_reset_cache_hit_rate_stats() */
1892 
1893 /*-------------------------------------------------------------------------
1894  * Function:    H5AC_set_cache_auto_resize_config
1895  *
1896  * Purpose:     Wrapper function for H5C_set_cache_auto_resize_config().
1897  *
1898  * Return:      SUCCEED on success, and FAIL on failure.
1899  *
1900  * Programmer:  John Mainzer
1901  *              3/10/05
1902  *
1903  *-------------------------------------------------------------------------
1904  */
1905 herr_t
H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,H5AC_cache_config_t * config_ptr)1906 H5AC_set_cache_auto_resize_config(H5AC_t *cache_ptr, H5AC_cache_config_t *config_ptr)
1907 {
1908     H5C_auto_size_ctl_t internal_config;
1909     herr_t              ret_value = SUCCEED; /* Return value */
1910 
1911     FUNC_ENTER_NOAPI(FAIL)
1912 
1913     /* Sanity checks */
1914     HDassert(cache_ptr);
1915 
1916     if (cache_ptr == NULL)
1917         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "bad cache_ptr on entry")
1918 #ifdef H5_HAVE_PARALLEL
1919     {
1920         H5AC_aux_t *aux_ptr;
1921 
1922         aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr);
1923         if ((aux_ptr != NULL) && (aux_ptr->magic != H5AC__H5AC_AUX_T_MAGIC))
1924             HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "bad aux_ptr on entry")
1925     }
1926 #endif /* H5_HAVE_PARALLEL */
1927 
1928     /* Validate external configuration */
1929     if (H5AC_validate_config(config_ptr) != SUCCEED)
1930         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Bad cache configuration")
1931 
1932     /* If the cache config struct is being used to control logging, perform
1933      * the open/close operations. Note that this is the only place where the
1934      * struct-based control opens and closes the log files so we also have
1935      * to write start/stop messages.
1936      */
1937     /* close */
1938     if (config_ptr->close_trace_file)
1939         if (H5C_log_tear_down((H5C_t *)cache_ptr) < 0)
1940             HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "mdc logging tear-down failed")
1941 
1942     /* open */
1943     if (config_ptr->open_trace_file) {
1944         /* Turn on metadata cache logging.
1945          * This will be trace output until we create a special API call. JSON
1946          * output is generated when logging is controlled by the H5P calls.
1947          */
1948         if (H5C_log_set_up((H5C_t *)cache_ptr, config_ptr->trace_file_name, H5C_LOG_STYLE_TRACE, TRUE) < 0)
1949             HGOTO_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "mdc logging setup failed")
1950     }
1951 
1952     /* Convert external configuration to internal representation */
1953     if (H5AC__ext_config_2_int_config(config_ptr, &internal_config) < 0)
1954         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC__ext_config_2_int_config() failed")
1955 
1956     /* Set configuration */
1957     if (H5C_set_cache_auto_resize_config(cache_ptr, &internal_config) < 0)
1958         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_set_cache_auto_resize_config() failed")
1959     if (H5C_set_evictions_enabled(cache_ptr, config_ptr->evictions_enabled) < 0)
1960         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_set_evictions_enabled() failed")
1961 
1962 #ifdef H5_HAVE_PARALLEL
1963     {
1964         H5AC_aux_t *aux_ptr;
1965 
1966         /* Set parallel configuration values */
1967         /* (Which are only held in the H5AC layer -QAK) */
1968         if (NULL != (aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(cache_ptr))) {
1969             aux_ptr->dirty_bytes_threshold   = config_ptr->dirty_bytes_threshold;
1970             aux_ptr->metadata_write_strategy = config_ptr->metadata_write_strategy;
1971         } /* end if */
1972     }
1973 #endif /* H5_HAVE_PARALLEL */
1974 
1975 done:
1976     /* If currently logging, generate a message */
1977     if (cache_ptr->log_info->logging)
1978         if (H5C_log_write_set_cache_config_msg(cache_ptr, config_ptr, ret_value) < 0)
1979             HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
1980 
1981     FUNC_LEAVE_NOAPI(ret_value)
1982 } /* H5AC_set_cache_auto_resize_config() */
1983 
1984 /*-------------------------------------------------------------------------
1985  * Function:    H5AC_validate_config()
1986  *
1987  * Purpose:     Run a sanity check on the contents of the supplied
1988  *              instance of H5AC_cache_config_t.
1989  *
1990  *              Do nothing and return SUCCEED if no errors are detected,
1991  *              and flag an error and return FAIL otherwise.
1992  *
1993  *              At present, this function operates by packing the data
1994  *              from the instance of H5AC_cache_config_t into an instance
1995  *              of H5C_auto_size_ctl_t, and then calling
1996  *              H5C_validate_resize_config().  As H5AC_cache_config_t and
1997  *              H5C_auto_size_ctl_t diverge, we may have to change this.
1998  *
1999  * Return:      Non-negative on success/Negative on failure
2000  *
2001  * Programmer:  John Mainzer
2002  *              4/6/05
2003  *
2004  *-------------------------------------------------------------------------
2005  */
2006 herr_t
H5AC_validate_config(H5AC_cache_config_t * config_ptr)2007 H5AC_validate_config(H5AC_cache_config_t *config_ptr)
2008 {
2009     H5C_auto_size_ctl_t internal_config;
2010     herr_t              ret_value = SUCCEED; /* Return value */
2011 
2012     FUNC_ENTER_NOAPI(FAIL)
2013 
2014     /* Check args */
2015     if (config_ptr == NULL)
2016         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "NULL config_ptr on entry")
2017     if (config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION)
2018         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Unknown config version")
2019 
2020     /* don't bother to test trace_file_name unless open_trace_file is TRUE */
2021     if (config_ptr->open_trace_file) {
2022         size_t name_len;
2023 
2024         /* Can't really test the trace_file_name field without trying to
2025          * open the file, so we will content ourselves with a couple of
2026          * sanity checks on the length of the file name.
2027          */
2028         name_len = HDstrlen(config_ptr->trace_file_name);
2029         if (name_len == 0)
2030             HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "config_ptr->trace_file_name is empty")
2031         else if (name_len > H5AC__MAX_TRACE_FILE_NAME_LEN)
2032             HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "config_ptr->trace_file_name too long")
2033     } /* end if */
2034 
2035     if ((config_ptr->evictions_enabled == FALSE) &&
2036         ((config_ptr->incr_mode != H5C_incr__off) || (config_ptr->flash_incr_mode != H5C_flash_incr__off) ||
2037          (config_ptr->decr_mode != H5C_decr__off)))
2038         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Can't disable evictions while auto-resize is enabled")
2039 
2040     if (config_ptr->dirty_bytes_threshold < H5AC__MIN_DIRTY_BYTES_THRESHOLD)
2041         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "dirty_bytes_threshold too small")
2042     else if (config_ptr->dirty_bytes_threshold > H5AC__MAX_DIRTY_BYTES_THRESHOLD)
2043         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "dirty_bytes_threshold too big")
2044 
2045     if ((config_ptr->metadata_write_strategy != H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY) &&
2046         (config_ptr->metadata_write_strategy != H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED))
2047         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "config_ptr->metadata_write_strategy out of range")
2048 
2049     if (H5AC__ext_config_2_int_config(config_ptr, &internal_config) < 0)
2050         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC__ext_config_2_int_config() failed")
2051 
2052     if (H5C_validate_resize_config(&internal_config, H5C_RESIZE_CFG__VALIDATE_ALL) < 0)
2053         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "error(s) in new config")
2054 
2055 done:
2056     FUNC_LEAVE_NOAPI(ret_value)
2057 } /* H5AC_validate_config() */
2058 
2059 /*-------------------------------------------------------------------------
2060  * Function:    H5AC_validate_cache_image_config()
2061  *
2062  * Purpose:     Run a sanity check on the contents of the supplied
2063  *              instance of H5AC_cache_image_config_t.
2064  *
2065  *              Do nothing and return SUCCEED if no errors are detected,
2066  *              and flag an error and return FAIL otherwise.
2067  *
2068  *              At present, this function operates by packing the data
2069  *              from the instance of H5AC_cache_image_config_t into an
2070  *              instance of H5C_cache_image_ctl_t, and then calling
2071  *              H5C_validate_cache_image_config().  If and when
2072  *              H5AC_cache_image_config_t and H5C_cache_image_ctl_t
2073  *              diverge, we may have to change this.
2074  *
2075  * Return:      Non-negative on success/Negative on failure
2076  *
2077  * Programmer:  John Mainzer
2078  *              6/25/15
2079  *
2080  *-------------------------------------------------------------------------
2081  */
2082 herr_t
H5AC_validate_cache_image_config(H5AC_cache_image_config_t * config_ptr)2083 H5AC_validate_cache_image_config(H5AC_cache_image_config_t *config_ptr)
2084 {
2085     H5C_cache_image_ctl_t internal_config = H5C__DEFAULT_CACHE_IMAGE_CTL;
2086     herr_t                ret_value       = SUCCEED; /* Return value */
2087 
2088     FUNC_ENTER_NOAPI(FAIL)
2089 
2090     /* Check args */
2091     if (config_ptr == NULL)
2092         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "NULL config_ptr on entry")
2093 
2094     if (config_ptr->version != H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION)
2095         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Unknown image config version")
2096 
2097     /* don't need to get the current H5C image config here since the
2098      * default values of fields not in the H5AC config will always be
2099      * valid.
2100      */
2101     internal_config.version            = config_ptr->version;
2102     internal_config.generate_image     = config_ptr->generate_image;
2103     internal_config.save_resize_status = config_ptr->save_resize_status;
2104     internal_config.entry_ageout       = config_ptr->entry_ageout;
2105 
2106     if (H5C_validate_cache_image_config(&internal_config) < 0)
2107         HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "error(s) in new cache image config")
2108 
2109 done:
2110     FUNC_LEAVE_NOAPI(ret_value)
2111 } /* H5AC_validate_cache_image_config() */
2112 
2113 /*-------------------------------------------------------------------------
2114  *
2115  * Function:    H5AC__check_if_write_permitted
2116  *
2117  * Purpose:     Determine if a write is permitted under the current
2118  *              circumstances, and set *write_permitted_ptr accordingly.
2119  *              As a general rule it is, but when we are running in parallel
2120  *              mode with collective I/O, we must ensure that a read cannot
2121  *              cause a write.
2122  *
2123  *              In the event of failure, the value of *write_permitted_ptr
2124  *              is undefined.
2125  *
2126  * Return:      Non-negative on success/Negative on failure.
2127  *
2128  * Programmer:  John Mainzer, 5/15/04
2129  *
2130  *-------------------------------------------------------------------------
2131  */
2132 static herr_t
H5AC__check_if_write_permitted(const H5F_t H5_ATTR_UNUSED * f,hbool_t * write_permitted_ptr)2133 H5AC__check_if_write_permitted(const H5F_t
2134 #ifndef H5_HAVE_PARALLEL
2135                                    H5_ATTR_UNUSED
2136 #endif /* H5_HAVE_PARALLEL */
2137                                        *f,
2138                                hbool_t *write_permitted_ptr)
2139 {
2140 #ifdef H5_HAVE_PARALLEL
2141     H5AC_aux_t *aux_ptr = NULL;
2142 #endif /* H5_HAVE_PARALLEL */
2143     hbool_t write_permitted = TRUE;
2144 
2145     FUNC_ENTER_STATIC_NOERR
2146 
2147 #ifdef H5_HAVE_PARALLEL
2148     /* Sanity checks */
2149     HDassert(f != NULL);
2150     HDassert(f->shared != NULL);
2151     HDassert(f->shared->cache != NULL);
2152     aux_ptr = (H5AC_aux_t *)H5C_get_aux_ptr(f->shared->cache);
2153     if (aux_ptr != NULL) {
2154         HDassert(aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC);
2155 
2156         if ((aux_ptr->mpi_rank == 0) ||
2157             (aux_ptr->metadata_write_strategy == H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED))
2158             write_permitted = aux_ptr->write_permitted;
2159         else
2160             write_permitted = FALSE;
2161     }  /* end if */
2162 #endif /* H5_HAVE_PARALLEL */
2163 
2164     *write_permitted_ptr = write_permitted;
2165 
2166     FUNC_LEAVE_NOAPI(SUCCEED)
2167 } /* H5AC__check_if_write_permitted() */
2168 
2169 /*-------------------------------------------------------------------------
2170  * Function:    H5AC__ext_config_2_int_config()
2171  *
2172  * Purpose:     Utility function to translate an instance of
2173  *              H5AC_cache_config_t to an instance of H5C_auto_size_ctl_t.
2174  *
2175  *              Places translation in *int_conf_ptr and returns SUCCEED
2176  *              if successful.  Returns FAIL on failure.
2177  *
2178  *              Does only minimal sanity checking.
2179  *
2180  * Return:      Non-negative on success/Negative on failure
2181  *
2182  * Programmer:  John Mainzer
2183  *              1/26/06
2184  *
2185  *-------------------------------------------------------------------------
2186  */
2187 static herr_t
H5AC__ext_config_2_int_config(H5AC_cache_config_t * ext_conf_ptr,H5C_auto_size_ctl_t * int_conf_ptr)2188 H5AC__ext_config_2_int_config(H5AC_cache_config_t *ext_conf_ptr, H5C_auto_size_ctl_t *int_conf_ptr)
2189 {
2190     herr_t ret_value = SUCCEED; /* Return value */
2191 
2192     FUNC_ENTER_STATIC
2193 
2194     if ((ext_conf_ptr == NULL) || (ext_conf_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION) ||
2195         (int_conf_ptr == NULL))
2196         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad ext_conf_ptr or inf_conf_ptr on entry")
2197 
2198     int_conf_ptr->version = H5C__CURR_AUTO_SIZE_CTL_VER;
2199     if (ext_conf_ptr->rpt_fcn_enabled)
2200         int_conf_ptr->rpt_fcn = H5C_def_auto_resize_rpt_fcn;
2201     else
2202         int_conf_ptr->rpt_fcn = NULL;
2203 
2204     int_conf_ptr->set_initial_size   = ext_conf_ptr->set_initial_size;
2205     int_conf_ptr->initial_size       = ext_conf_ptr->initial_size;
2206     int_conf_ptr->min_clean_fraction = ext_conf_ptr->min_clean_fraction;
2207     int_conf_ptr->max_size           = ext_conf_ptr->max_size;
2208     int_conf_ptr->min_size           = ext_conf_ptr->min_size;
2209     int_conf_ptr->epoch_length       = (int64_t)(ext_conf_ptr->epoch_length);
2210 
2211     int_conf_ptr->incr_mode           = ext_conf_ptr->incr_mode;
2212     int_conf_ptr->lower_hr_threshold  = ext_conf_ptr->lower_hr_threshold;
2213     int_conf_ptr->increment           = ext_conf_ptr->increment;
2214     int_conf_ptr->apply_max_increment = ext_conf_ptr->apply_max_increment;
2215     int_conf_ptr->max_increment       = ext_conf_ptr->max_increment;
2216     int_conf_ptr->flash_incr_mode     = ext_conf_ptr->flash_incr_mode;
2217     int_conf_ptr->flash_multiple      = ext_conf_ptr->flash_multiple;
2218     int_conf_ptr->flash_threshold     = ext_conf_ptr->flash_threshold;
2219 
2220     int_conf_ptr->decr_mode              = ext_conf_ptr->decr_mode;
2221     int_conf_ptr->upper_hr_threshold     = ext_conf_ptr->upper_hr_threshold;
2222     int_conf_ptr->decrement              = ext_conf_ptr->decrement;
2223     int_conf_ptr->apply_max_decrement    = ext_conf_ptr->apply_max_decrement;
2224     int_conf_ptr->max_decrement          = ext_conf_ptr->max_decrement;
2225     int_conf_ptr->epochs_before_eviction = (int32_t)(ext_conf_ptr->epochs_before_eviction);
2226     int_conf_ptr->apply_empty_reserve    = ext_conf_ptr->apply_empty_reserve;
2227     int_conf_ptr->empty_reserve          = ext_conf_ptr->empty_reserve;
2228 
2229 done:
2230     FUNC_LEAVE_NOAPI(ret_value)
2231 } /* H5AC__ext_config_2_int_config() */
2232 
2233 /*------------------------------------------------------------------------------
2234  * Function:    H5AC_ignore_tags()
2235  *
2236  * Purpose:     Override all assertion frameworks and force application of
2237  *              global tag everywhere. This should really only be used in the
2238  *              tests that need to access functions without going through
2239  *              API paths.
2240  *
2241  * Return:      SUCCEED on success, FAIL otherwise.
2242  *
2243  * Programmer:  Mike McGreevy
2244  *              December 1, 2009
2245  *
2246  *------------------------------------------------------------------------------
2247  */
2248 herr_t
H5AC_ignore_tags(const H5F_t * f)2249 H5AC_ignore_tags(const H5F_t *f)
2250 {
2251     herr_t ret_value = SUCCEED;
2252 
2253     FUNC_ENTER_NOAPI(FAIL)
2254 
2255     /* Sanity checks */
2256     HDassert(f);
2257     HDassert(f->shared);
2258     HDassert(f->shared->cache);
2259 
2260     /* Set up a new metadata tag */
2261     if (H5C_ignore_tags(f->shared->cache) < 0)
2262         HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "H5C_ignore_tags() failed")
2263 
2264 done:
2265     FUNC_LEAVE_NOAPI(ret_value)
2266 } /* H5AC_ignore_tags() */
2267 
2268 /*------------------------------------------------------------------------------
2269  * Function:    H5AC_tag()
2270  *
2271  * Purpose:     Sets the metadata tag property in the provided property list.
2272  *
2273  * Return:      void
2274  *
2275  * Programmer:  Mike McGreevy
2276  *              December 1, 2009
2277  *
2278  *------------------------------------------------------------------------------
2279  */
2280 void
H5AC_tag(haddr_t metadata_tag,haddr_t * prev_tag)2281 H5AC_tag(haddr_t metadata_tag, haddr_t *prev_tag)
2282 {
2283     FUNC_ENTER_NOAPI_NOINIT_NOERR
2284 
2285     /* Get the current tag value and return that (if prev_tag is NOT null) */
2286     if (prev_tag)
2287         *prev_tag = H5CX_get_tag();
2288 
2289     /* Set the provided tag */
2290     H5CX_set_tag(metadata_tag);
2291 
2292     FUNC_LEAVE_NOAPI_VOID
2293 } /* H5AC_tag */
2294 
2295 /*------------------------------------------------------------------------------
2296  * Function:    H5AC_retag_copied_metadata()
2297  *
2298  * Purpose:     Searches through cache index for all entries with the
2299  *              H5AC__COPIED_TAG, indicating that it was created as a
2300  *              result of an object copy, and applies the provided tag.
2301  *
2302  * Return:      SUCCEED on success, FAIL otherwise.
2303  *
2304  * Programmer:  Mike McGreevy
2305  *              March 17, 2010
2306  *
2307  *------------------------------------------------------------------------------
2308  */
2309 herr_t
H5AC_retag_copied_metadata(const H5F_t * f,haddr_t metadata_tag)2310 H5AC_retag_copied_metadata(const H5F_t *f, haddr_t metadata_tag)
2311 {
2312     herr_t ret_value = SUCCEED; /* Return value */
2313 
2314     FUNC_ENTER_NOAPI(FAIL)
2315 
2316     /* Sanity checks */
2317     HDassert(f);
2318     HDassert(f->shared);
2319 
2320     /* Call cache-level function to re-tag entries with the COPIED tag */
2321     if (H5C_retag_entries(f->shared->cache, H5AC__COPIED_TAG, metadata_tag) < 0)
2322         HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "Can't retag metadata")
2323 
2324 done:
2325     FUNC_LEAVE_NOAPI(ret_value)
2326 } /* H5AC_retag_copied_metadata() */
2327 
2328 /*------------------------------------------------------------------------------
2329  * Function:    H5AC_flush_tagged_metadata()
2330  *
2331  * Purpose:     Wrapper for cache level function which flushes all metadata
2332  *              that contains the specific tag.
2333  *
2334  * Return:      SUCCEED on success, FAIL otherwise.
2335  *
2336  * Programmer:  Mike McGreevy
2337  *              May 19, 2010
2338  *
2339  *------------------------------------------------------------------------------
2340  */
2341 herr_t
H5AC_flush_tagged_metadata(H5F_t * f,haddr_t metadata_tag)2342 H5AC_flush_tagged_metadata(H5F_t *f, haddr_t metadata_tag)
2343 {
2344     /* Variable Declarations */
2345     herr_t ret_value = SUCCEED;
2346 
2347     /* Function Enter Macro */
2348     FUNC_ENTER_NOAPI(FAIL)
2349 
2350     /* Assertions */
2351     HDassert(f);
2352     HDassert(f->shared);
2353 
2354     /* Call cache level function to flush metadata entries with specified tag */
2355     if (H5C_flush_tagged_entries(f, metadata_tag) < 0)
2356         HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot flush metadata")
2357 
2358 done:
2359     FUNC_LEAVE_NOAPI(ret_value)
2360 } /* H5AC_flush_tagged_metadata */
2361 
2362 /*------------------------------------------------------------------------------
2363  * Function:    H5AC_evict_tagged_metadata()
2364  *
2365  * Purpose:     Wrapper for cache level function which flushes all metadata
2366  *              that contains the specific tag.
2367  *
2368  * Return:      SUCCEED on success, FAIL otherwise.
2369  *
2370  * Programmer:  Mike McGreevy
2371  *              May 19, 2010
2372  *
2373  *------------------------------------------------------------------------------
2374  */
2375 herr_t
H5AC_evict_tagged_metadata(H5F_t * f,haddr_t metadata_tag,hbool_t match_global)2376 H5AC_evict_tagged_metadata(H5F_t *f, haddr_t metadata_tag, hbool_t match_global)
2377 {
2378     /* Variable Declarations */
2379     herr_t ret_value = SUCCEED;
2380 
2381     /* Function Enter Macro */
2382     FUNC_ENTER_NOAPI(FAIL)
2383 
2384     /* Assertions */
2385     HDassert(f);
2386     HDassert(f->shared);
2387 
2388     /* Call cache level function to evict metadata entries with specified tag */
2389     if (H5C_evict_tagged_entries(f, metadata_tag, match_global) < 0)
2390         HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot evict metadata")
2391 
2392 done:
2393     FUNC_LEAVE_NOAPI(ret_value)
2394 } /* H5AC_evict_tagged_metadata() */
2395 
2396 /*------------------------------------------------------------------------------
2397  * Function:    H5AC_expunge_tag_type_metadata()
2398  *
2399  * Purpose:     Wrapper for cache level function which expunge entries with
2400  *              a specific tag and type id.
2401  *
2402  * Return:      SUCCEED on success, FAIL otherwise.
2403  *
2404  * Programmer:  Vailin Choi; May 2016
2405  *
2406  *------------------------------------------------------------------------------
2407  */
2408 herr_t
H5AC_expunge_tag_type_metadata(H5F_t * f,haddr_t tag,int type_id,unsigned flags)2409 H5AC_expunge_tag_type_metadata(H5F_t *f, haddr_t tag, int type_id, unsigned flags)
2410 {
2411     /* Variable Declarations */
2412     herr_t ret_value = SUCCEED;
2413 
2414     /* Function Enter Macro */
2415     FUNC_ENTER_NOAPI(FAIL)
2416 
2417     /* Assertions */
2418     HDassert(f);
2419     HDassert(f->shared);
2420 
2421     /* Call cache level function to expunge entries with specified tag and type id */
2422     if (H5C_expunge_tag_type_metadata(f, tag, type_id, flags) < 0)
2423         HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot expunge tagged type entries")
2424 
2425 done:
2426     FUNC_LEAVE_NOAPI(ret_value)
2427 } /* H5AC_expunge_tag_type_metadata*/
2428 
2429 /*------------------------------------------------------------------------------
2430  * Function:    H5AC_get_tag()
2431  *
2432  * Purpose:     Get the tag for a metadata cache entry.
2433  *
2434  * Return:      SUCCEED/FAIL
2435  *
2436  * Programmer:  Dana Robinson
2437  *              Fall 2016
2438  *
2439  *------------------------------------------------------------------------------
2440  */
2441 herr_t
H5AC_get_tag(const void * thing,haddr_t * tag)2442 H5AC_get_tag(const void *thing, haddr_t *tag)
2443 {
2444     /* Variable Declarations */
2445     herr_t ret_value = SUCCEED;
2446 
2447     /* Function Enter Macro */
2448     FUNC_ENTER_NOAPI(FAIL)
2449 
2450     /* Assertions */
2451     HDassert(thing);
2452     HDassert(tag);
2453 
2454     /* Call cache level function to get the tag */
2455     if (H5C_get_tag(thing, tag) < 0)
2456         HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Cannot get tag for metadata cache entry")
2457 
2458 done:
2459     FUNC_LEAVE_NOAPI(ret_value)
2460 } /* end H5AC_get_tag() */
2461 
2462 /*-------------------------------------------------------------------------
2463  * Function:    H5AC_cork
2464  *
2465  * Purpose:     To cork/uncork/get cork status for an object
2466  *
2467  * Return:      Non-negative on success/Negative on failure
2468  *
2469  * Programmer:  Vailin Choi; Jan 2014
2470  *
2471  *-------------------------------------------------------------------------
2472  */
2473 herr_t
H5AC_cork(H5F_t * f,haddr_t obj_addr,unsigned action,hbool_t * corked)2474 H5AC_cork(H5F_t *f, haddr_t obj_addr, unsigned action, hbool_t *corked)
2475 {
2476     herr_t ret_value = SUCCEED; /* Return value */
2477 
2478     FUNC_ENTER_NOAPI(FAIL)
2479 
2480     /* Sanity check */
2481     HDassert(f);
2482     HDassert(f->shared);
2483     HDassert(f->shared->cache);
2484     HDassert(H5F_addr_defined(obj_addr));
2485     HDassert(action == H5AC__SET_CORK || action == H5AC__UNCORK || action == H5AC__GET_CORKED);
2486 
2487     /*  Skip the search on "tag_list" when there are no "corked" objects.
2488      *  This is done to mitigate the slow down when closing objects.
2489      *  Re-visit this optimization when we optimize tag info management
2490      *  in the future.
2491      */
2492     if (action == H5AC__GET_CORKED) {
2493         HDassert(corked);
2494         if (H5C_get_num_objs_corked(f->shared->cache) == 0) {
2495             *corked = FALSE;
2496             HGOTO_DONE(SUCCEED)
2497         }
2498     }
2499 
2500     if (H5C_cork(f->shared->cache, obj_addr, action, corked) < 0)
2501         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Cannot perform the cork action")
2502 
2503 done:
2504     FUNC_LEAVE_NOAPI(ret_value)
2505 } /* H5AC_cork() */
2506 
2507 #if H5AC_DO_TAGGING_SANITY_CHECKS
2508 
2509 /*-------------------------------------------------------------------------
2510  *
2511  * Function:    H5AC__verify_tag
2512  *
2513  * Purpose:     Performs sanity checking on an entry type and tag value
2514  *              stored in a supplied dxpl_id.
2515  *
2516  * Return:      SUCCEED or FAIL.
2517  *
2518  * Programmer:  Mike McGreevy
2519  *              October 20, 2010
2520  *
2521  *-------------------------------------------------------------------------
2522  */
2523 static herr_t
H5AC__verify_tag(const H5AC_class_t * type)2524 H5AC__verify_tag(const H5AC_class_t *type)
2525 {
2526     haddr_t tag;                 /* Entry tag to validate */
2527     herr_t  ret_value = SUCCEED; /* Return value */
2528 
2529     FUNC_ENTER_STATIC
2530 
2531     /* Get the current tag */
2532     tag = H5CX_get_tag();
2533 
2534     /* Verify legal tag value */
2535     if (H5C_verify_tag(type->id, tag) < 0)
2536         HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "tag verification failed")
2537 
2538 done:
2539     FUNC_LEAVE_NOAPI(ret_value)
2540 } /* H5AC__verify_tag */
2541 #endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
2542 
2543 /*-------------------------------------------------------------------------
2544  * Function:    H5AC_get_entry_ring
2545  *
2546  * Purpose:     Given a file address, retrieve the ring for an entry at that
2547  *              address.
2548  *
2549  *              On error, the value of *ring is not modified.
2550  *
2551  * Return:      Non-negative on success/Negative on failure
2552  *
2553  * Programmer:  Quincey Koziol
2554  *              9/8/15
2555  *
2556  *-------------------------------------------------------------------------
2557  */
2558 herr_t
H5AC_get_entry_ring(const H5F_t * f,haddr_t addr,H5AC_ring_t * ring)2559 H5AC_get_entry_ring(const H5F_t *f, haddr_t addr, H5AC_ring_t *ring)
2560 {
2561     herr_t ret_value = SUCCEED; /* Return value */
2562 
2563     FUNC_ENTER_NOAPI(FAIL)
2564 
2565     /* Sanity check */
2566     HDassert(f);
2567     HDassert(H5F_addr_defined(addr));
2568     HDassert(ring);
2569 
2570     /* Retrieve the ring value for the entry at address */
2571     if (H5C_get_entry_ring(f, addr, ring) < 0)
2572         HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "Can't retrieve ring for entry")
2573 
2574 done:
2575     FUNC_LEAVE_NOAPI(ret_value)
2576 } /* H5AC_get_entry_ring() */
2577 
2578 /*-------------------------------------------------------------------------
2579  * Function:    H5AC_set_ring
2580  *
2581  * Purpose:     Routine to set the ring on a DXPL (for passing through
2582  *              to the metadata cache).
2583  *
2584  * Return:      void
2585  *
2586  * Programmer:  Quincey Koziol
2587  *              Tuesday, September 8, 2015
2588  *
2589  *-------------------------------------------------------------------------
2590  */
2591 void
H5AC_set_ring(H5AC_ring_t ring,H5AC_ring_t * orig_ring)2592 H5AC_set_ring(H5AC_ring_t ring, H5AC_ring_t *orig_ring)
2593 {
2594     FUNC_ENTER_NOAPI_NOINIT_NOERR
2595 
2596     /* Note: orig_ring can be NULL so don't check it with HDassert() */
2597 
2598     /* Get the current ring value and return that (if orig_ring is NOT null) */
2599     if (orig_ring)
2600         *orig_ring = H5CX_get_ring();
2601 
2602     /* Set the provided ring */
2603     H5CX_set_ring(ring);
2604 
2605     FUNC_LEAVE_NOAPI_VOID
2606 } /* end H5AC_set_ring() */
2607 
2608 /*-------------------------------------------------------------------------
2609  * Function:    H5AC_unsettle_entry_ring()
2610  *
2611  * Purpose:     Advise the metadata cache that the specified entry's metadata
2612  *              cache manager ring is no longer settled (if it was on entry).
2613  *
2614  *              If the target metadata cache manager ring is already
2615  *              unsettled, do nothing, and return SUCCEED.
2616  *
2617  *              If the target metadata cache manager ring is settled, and
2618  *              we are not in the process of a file shutdown, mark
2619  *              the ring as unsettled, and return SUCCEED.
2620  *
2621  *              If the target metadata cache  manager is settled, and we
2622  *              are in the process of a file shutdown, post an error
2623  *              message, and return FAIL.
2624  *
2625  *              Note that this function simply passes the call on to
2626  *              the metadata cache proper, and returns the result.
2627  *
2628  * Return:      Success:        Non-negative
2629  *              Failure:        Negative
2630  *
2631  * Programmer:  Quincey Koziol
2632  *              September 17, 2016
2633  *
2634  *-------------------------------------------------------------------------
2635  */
2636 herr_t
H5AC_unsettle_entry_ring(void * _entry)2637 H5AC_unsettle_entry_ring(void *_entry)
2638 {
2639     H5AC_info_t *entry     = (H5AC_info_t *)_entry; /* Entry to remove */
2640     herr_t       ret_value = SUCCEED;               /* Return value */
2641 
2642     FUNC_ENTER_NOAPI(FAIL)
2643 
2644     /* Sanity checks */
2645     HDassert(entry);
2646 
2647     /* Unsettle the entry's ring */
2648     if (H5C_unsettle_entry_ring(entry) < 0)
2649         HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "can't remove entry")
2650 
2651 done:
2652     FUNC_LEAVE_NOAPI(ret_value)
2653 } /* H5AC_unsettle_entry_ring() */
2654 
2655 /*-------------------------------------------------------------------------
2656  * Function:    H5AC_unsettle_ring()
2657  *
2658  * Purpose:     Advise the metadata cache that the specified free space
2659  *              manager ring is no longer settled (if it was on entry).
2660  *
2661  *              If the target free space manager ring is already
2662  *              unsettled, do nothing, and return SUCCEED.
2663  *
2664  *              If the target free space manager ring is settled, and
2665  *              we are not in the process of a file shutdown, mark
2666  *              the ring as unsettled, and return SUCCEED.
2667  *
2668  *              If the target free space manager is settled, and we
2669  *              are in the process of a file shutdown, post an error
2670  *              message, and return FAIL.
2671  *
2672  *              Note that this function simply passes the call on to
2673  *              the metadata cache proper, and returns the result.
2674  *
2675  * Return:      Non-negative on success/Negative on failure
2676  *
2677  * Programmer:  John Mainzer
2678  *              10/15/16
2679  *
2680  *-------------------------------------------------------------------------
2681  */
2682 herr_t
H5AC_unsettle_ring(H5F_t * f,H5C_ring_t ring)2683 H5AC_unsettle_ring(H5F_t *f, H5C_ring_t ring)
2684 {
2685     herr_t ret_value = SUCCEED; /* Return value */
2686 
2687     FUNC_ENTER_NOAPI(FAIL)
2688 
2689     if (FAIL == (ret_value = H5C_unsettle_ring(f, ring)))
2690         HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_unsettle_ring() failed")
2691 
2692 done:
2693     FUNC_LEAVE_NOAPI(ret_value)
2694 } /* H5AC_unsettle_ring() */
2695 
2696 /*-------------------------------------------------------------------------
2697  * Function:    H5AC_remove_entry()
2698  *
2699  * Purpose:     Remove an entry from the cache.  Must be not protected, pinned,
2700  *              dirty, involved in flush dependencies, etc.
2701  *
2702  * Return:      Non-negative on success/Negative on failure
2703  *
2704  * Programmer:  Quincey Koziol
2705  *              September 17, 2016
2706  *
2707  *-------------------------------------------------------------------------
2708  */
2709 herr_t
H5AC_remove_entry(void * _entry)2710 H5AC_remove_entry(void *_entry)
2711 {
2712     H5AC_info_t *entry     = (H5AC_info_t *)_entry; /* Entry to remove */
2713     H5C_t *      cache     = NULL;                  /* Pointer to the entry's associated metadata cache */
2714     herr_t       ret_value = SUCCEED;               /* Return value */
2715 
2716     FUNC_ENTER_NOAPI(FAIL)
2717 
2718     /* Sanity checks */
2719     HDassert(entry);
2720     cache = entry->cache_ptr;
2721     HDassert(cache);
2722 
2723     /* Remove the entry from the cache*/
2724     if (H5C_remove_entry(entry) < 0)
2725         HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "can't remove entry")
2726 
2727 done:
2728     /* If currently logging, generate a message */
2729     if (cache != NULL && cache->log_info != NULL)
2730         if (cache->log_info->logging)
2731             if (H5C_log_write_remove_entry_msg(cache, entry, ret_value) < 0)
2732                 HDONE_ERROR(H5E_CACHE, H5E_LOGGING, FAIL, "unable to emit log message")
2733 
2734     FUNC_LEAVE_NOAPI(ret_value)
2735 } /* H5AC_remove_entry() */
2736 
2737 /*-------------------------------------------------------------------------
2738  * Function:    H5AC_get_mdc_image_info
2739  *
2740  * Purpose:     Wrapper function for H5C_get_mdc_image_info().
2741  *
2742  * Return:      SUCCEED on success, and FAIL on failure.
2743  *
2744  * Programmer:  Vailin Choi; March 2017
2745  *
2746  *-------------------------------------------------------------------------
2747  */
2748 herr_t
H5AC_get_mdc_image_info(H5AC_t * cache_ptr,haddr_t * image_addr,hsize_t * image_len)2749 H5AC_get_mdc_image_info(H5AC_t *cache_ptr, haddr_t *image_addr, hsize_t *image_len)
2750 {
2751     herr_t ret_value = SUCCEED; /* Return value */
2752 
2753     FUNC_ENTER_NOAPI(FAIL)
2754 
2755     if (H5C_get_mdc_image_info((H5C_t *)cache_ptr, image_addr, image_len) < 0)
2756         HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "can't retrieve cache image info")
2757 
2758 done:
2759     FUNC_LEAVE_NOAPI(ret_value)
2760 } /* H5AC_get_mdc_image_info() */
2761