1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the files COPYING and Copyright.html.  COPYING can be found at the root   *
9  * of the source code distribution tree; Copyright.html can be found at the  *
10  * root level of an installed copy of the electronic HDF5 document set and   *
11  * is linked from the top-level documents page.  It can also be found at     *
12  * http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have          *
13  * access to either file, you may request a copy from help@hdfgroup.org.     *
14  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /* Programmer:  Quincey Koziol <koziol@hdfgroup.org>
17  *              Monday, December 4, 2006
18  *
19  * Purpose:	Object header testing functions.
20  */
21 
22 /****************/
23 /* Module Setup */
24 /****************/
25 
26 #define H5A_PACKAGE		/*suppress error about including H5Apkg	  */
27 #define H5O_PACKAGE		/*suppress error about including H5Opkg	  */
28 #define H5O_TESTING		/*suppress warning about H5O testing funcs*/
29 
30 
31 /***********/
32 /* Headers */
33 /***********/
34 #include "H5private.h"		/* Generic Functions			*/
35 #include "H5Apkg.h"		/* Attributes	  			*/
36 #include "H5ACprivate.h"	/* Metadata cache			*/
37 #include "H5Eprivate.h"		/* Error handling		  	*/
38 #include "H5Iprivate.h"		/* IDs			  		*/
39 #include "H5Opkg.h"             /* Object headers			*/
40 
41 
42 /****************/
43 /* Local Macros */
44 /****************/
45 
46 
47 /******************/
48 /* Local Typedefs */
49 /******************/
50 
51 
52 /********************/
53 /* Package Typedefs */
54 /********************/
55 
56 
57 /********************/
58 /* Local Prototypes */
59 /********************/
60 
61 
62 /*********************/
63 /* Package Variables */
64 /*********************/
65 
66 
67 /*****************************/
68 /* Library Private Variables */
69 /*****************************/
70 
71 
72 /*******************/
73 /* Local Variables */
74 /*******************/
75 
76 
77 /*--------------------------------------------------------------------------
78  NAME
79     H5O_is_attr_dense_test
80  PURPOSE
81     Determine whether attributes for an object are stored "densely"
82  USAGE
83     htri_t H5O_is_attr_dense_test(oid)
84         hid_t oid;              IN: object to check
85  RETURNS
86     Non-negative TRUE/FALSE on success, negative on failure
87  DESCRIPTION
88     Checks to see if the object is storing attributes in the "dense" or
89     "compact" form.
90  GLOBAL VARIABLES
91  COMMENTS, BUGS, ASSUMPTIONS
92     DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
93  EXAMPLES
94  REVISION LOG
95 --------------------------------------------------------------------------*/
96 htri_t
H5O_is_attr_dense_test(hid_t oid)97 H5O_is_attr_dense_test(hid_t oid)
98 {
99     H5O_t *oh = NULL;           /* Object header */
100     H5O_ainfo_t ainfo;          /* Attribute information for object */
101     H5O_loc_t *loc;             /* Pointer to object's location */
102     htri_t ret_value;           /* Return value */
103 
104     FUNC_ENTER_NOAPI(FAIL)
105 
106     /* Get object location for object */
107     if(NULL == (loc = H5O_get_loc(oid)))
108         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
109 
110     /* Get the object header */
111     if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ)))
112 	HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
113 
114     /* Check for attribute info stored */
115     ainfo.fheap_addr = HADDR_UNDEF;
116     if(oh->version > H5O_VERSION_1) {
117         /* Check for (& retrieve if available) attribute info */
118         if(H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo) < 0)
119             HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
120     } /* end if */
121 
122     /* Check if dense storage is being used */
123     if(H5F_addr_defined(ainfo.fheap_addr)) {
124         /* Check for any messages in object header */
125         HDassert(H5O_msg_count_real(oh, H5O_MSG_ATTR) == 0);
126 
127         ret_value = TRUE;
128     } /* end if */
129     else
130         ret_value = FALSE;
131 
132 done:
133     if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
134 	HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
135 
136     FUNC_LEAVE_NOAPI(ret_value)
137 }   /* H5O_is_attr_dense_test() */
138 
139 
140 /*--------------------------------------------------------------------------
141  NAME
142     H5O_is_attr_empty_test
143  PURPOSE
144     Determine whether there are any attributes for an object
145  USAGE
146     htri_t H5O_is_attr_empty_test(oid)
147         hid_t oid;              IN: object to check
148  RETURNS
149     Non-negative TRUE/FALSE on success, negative on failure
150  DESCRIPTION
151     Checks to see if the object is storing any attributes.
152  GLOBAL VARIABLES
153  COMMENTS, BUGS, ASSUMPTIONS
154     DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
155  EXAMPLES
156  REVISION LOG
157 --------------------------------------------------------------------------*/
158 htri_t
H5O_is_attr_empty_test(hid_t oid)159 H5O_is_attr_empty_test(hid_t oid)
160 {
161     H5O_t *oh = NULL;           /* Object header */
162     H5B2_t *bt2_name = NULL;            /* v2 B-tree handle for name index */
163     H5O_ainfo_t ainfo;          /* Attribute information for object */
164     htri_t ainfo_exists = FALSE;        /* Whether the attribute info exists in the file */
165     H5O_loc_t *loc;            /* Pointer to object's location */
166     hsize_t nattrs;             /* Number of attributes */
167     htri_t ret_value;           /* Return value */
168 
169     FUNC_ENTER_NOAPI(FAIL)
170 
171     /* Get object location for object */
172     if(NULL == (loc = H5O_get_loc(oid)))
173         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
174 
175     /* Get the object header */
176     if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ)))
177 	HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
178 
179     /* Check for attribute info stored */
180     if(oh->version > H5O_VERSION_1) {
181         /* Check for (& retrieve if available) attribute info */
182         if((ainfo_exists = H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo)) < 0)
183             HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
184     } /* end if */
185 
186     /* Retrieve the number of attribute messages in header */
187     nattrs = H5O_msg_count_real(oh, H5O_MSG_ATTR);
188 
189     /* Check for later version of object header format & attribute info available */
190     if(oh->version > H5O_VERSION_1) {
191         if(ainfo_exists) {
192             /* Check for using dense storage */
193             if(H5F_addr_defined(ainfo.fheap_addr)) {
194                 /* Check for any messages in object header */
195                 HDassert(nattrs == 0);
196 
197                 /* Open the name index v2 B-tree */
198                 if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
199                     HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
200 
201                 /* Retrieve # of records in name index */
202                 if(H5B2_get_nrec(bt2_name, &nattrs) < 0)
203                     HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
204             } /* end if */
205 
206             /* Verify that attribute count in object header is correct */
207             HDassert(nattrs == ainfo.nattrs);
208         } /* end if */
209         else
210             HDassert(nattrs == 0);
211     } /* end if */
212 
213     /* Set the return value */
214     ret_value = (nattrs == 0) ? TRUE : FALSE;
215 
216 done:
217     /* Release resources */
218     if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0)
219         HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
220     if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
221 	HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
222 
223     FUNC_LEAVE_NOAPI(ret_value)
224 }   /* H5O_is_attr_empty_test() */
225 
226 
227 /*--------------------------------------------------------------------------
228  NAME
229     H5O_num_attrs_test
230  PURPOSE
231     Determine whether there are any attributes for an object
232  USAGE
233     herr_t H5O_num_attrs_test(oid, nattrs)
234         hid_t oid;              IN: object to check
235         hsize_t *nattrs;        OUT: Number of attributes on object
236  RETURNS
237     Non-negative on success, negative on failure
238  DESCRIPTION
239     Checks the # of attributes on an object
240  GLOBAL VARIABLES
241  COMMENTS, BUGS, ASSUMPTIONS
242     DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
243  EXAMPLES
244  REVISION LOG
245 --------------------------------------------------------------------------*/
246 herr_t
H5O_num_attrs_test(hid_t oid,hsize_t * nattrs)247 H5O_num_attrs_test(hid_t oid, hsize_t *nattrs)
248 {
249     H5O_t *oh = NULL;           /* Object header */
250     H5B2_t *bt2_name = NULL;            /* v2 B-tree handle for name index */
251     H5O_ainfo_t ainfo;          /* Attribute information for object */
252     H5O_loc_t *loc;            /* Pointer to object's location */
253     hsize_t obj_nattrs;         /* Number of attributes */
254     herr_t ret_value = SUCCEED; /* Return value */
255 
256     FUNC_ENTER_NOAPI(FAIL)
257 
258     /* Get object location for object */
259     if(NULL == (loc = H5O_get_loc(oid)))
260         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
261 
262     /* Get the object header */
263     if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ)))
264 	HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
265 
266     /* Check for attribute info stored */
267     ainfo.fheap_addr = HADDR_UNDEF;
268     if(oh->version > H5O_VERSION_1) {
269         /* Check for (& retrieve if available) attribute info */
270         if(H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo) < 0)
271             HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
272     } /* end if */
273 
274     /* Retrieve the number of attribute messages in header */
275     obj_nattrs = H5O_msg_count_real(oh, H5O_MSG_ATTR);
276 
277     /* Check for later version of object header format */
278     if(oh->version > H5O_VERSION_1) {
279         /* Check for using dense storage */
280         if(H5F_addr_defined(ainfo.fheap_addr)) {
281             /* Check for any messages in object header */
282             HDassert(obj_nattrs == 0);
283 
284             /* Open the name index v2 B-tree */
285             if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
286                 HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
287 
288             /* Retrieve # of records in name index */
289             if(H5B2_get_nrec(bt2_name, &obj_nattrs) < 0)
290                 HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
291         } /* end if */
292 
293         /* Verify that attribute count in object header is correct */
294         HDassert(obj_nattrs == ainfo.nattrs);
295     } /* end if */
296 
297     /* Set the number of attributes */
298     *nattrs = obj_nattrs;
299 
300 done:
301     /* Release resources */
302     if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0)
303         HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
304     if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
305 	HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
306 
307     FUNC_LEAVE_NOAPI(ret_value)
308 }   /* H5O_num_attrs_test() */
309 
310 
311 /*--------------------------------------------------------------------------
312  NAME
313     H5O_attr_dense_info_test
314  PURPOSE
315     Retrieve information about the state of the "dense" storage for attributes
316  USAGE
317     herr_t H5O_attr_dense_info_test(oid, name_count, corder_count)
318         hid_t oid;              IN: Object to check
319         hsize_t *name_count;    OUT: Number of attributes in name index
320         hsize_t *corder_count;  OUT: Number of attributes in creation order index
321  RETURNS
322     Non-negative on success, negative on failure
323  DESCRIPTION
324     Currently, just retrieves the number of attributes in each index and returns
325     them.
326  GLOBAL VARIABLES
327  COMMENTS, BUGS, ASSUMPTIONS
328     DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
329  EXAMPLES
330  REVISION LOG
331 --------------------------------------------------------------------------*/
332 herr_t
H5O_attr_dense_info_test(hid_t oid,hsize_t * name_count,hsize_t * corder_count)333 H5O_attr_dense_info_test(hid_t oid, hsize_t *name_count, hsize_t *corder_count)
334 {
335     H5O_t *oh = NULL;           /* Object header */
336     H5B2_t *bt2_name = NULL;    /* v2 B-tree handle for name index */
337     H5B2_t *bt2_corder = NULL;  /* v2 B-tree handle for creation order index */
338     H5O_ainfo_t ainfo;          /* Attribute information for object */
339     H5O_loc_t *loc;            /* Pointer to object's location */
340     herr_t ret_value = SUCCEED; /* Return value */
341 
342     FUNC_ENTER_NOAPI(FAIL)
343 
344     /* Get object location for object */
345     if(NULL == (loc = H5O_get_loc(oid)))
346         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
347 
348     /* Get the object header */
349     if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ)))
350 	HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
351 
352     /* Check for attribute info stored */
353     ainfo.fheap_addr = HADDR_UNDEF;
354     if(oh->version > H5O_VERSION_1) {
355         /* Check for (& retrieve if available) attribute info */
356         if(H5A_get_ainfo(loc->file, H5AC_ind_dxpl_id, oh, &ainfo) < 0)
357             HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for attribute info message")
358     } /* end if */
359 
360     /* Check for 'dense' attribute storage file addresses being defined */
361     if(!H5F_addr_defined(ainfo.fheap_addr))
362         HGOTO_DONE(FAIL)
363     if(!H5F_addr_defined(ainfo.name_bt2_addr))
364         HGOTO_DONE(FAIL)
365 
366     /* Open the name index v2 B-tree */
367     if(NULL == (bt2_name = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.name_bt2_addr, NULL)))
368         HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for name index")
369 
370     /* Retrieve # of records in name index */
371     if(H5B2_get_nrec(bt2_name, name_count) < 0)
372         HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from name index")
373 
374     /* Check if there is a creation order index */
375     if(H5F_addr_defined(ainfo.corder_bt2_addr)) {
376         /* Open the creation order index v2 B-tree */
377         if(NULL == (bt2_corder = H5B2_open(loc->file, H5AC_ind_dxpl_id, ainfo.corder_bt2_addr, NULL)))
378             HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open v2 B-tree for creation order index")
379 
380         /* Retrieve # of records in creation order index */
381         if(H5B2_get_nrec(bt2_corder, corder_count) < 0)
382             HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to retrieve # of records from creation order index")
383     } /* end if */
384     else
385         *corder_count = 0;
386 
387 done:
388     /* Release resources */
389     if(bt2_name && H5B2_close(bt2_name, H5AC_ind_dxpl_id) < 0)
390         HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for name index")
391     if(bt2_corder && H5B2_close(bt2_corder, H5AC_ind_dxpl_id) < 0)
392         HDONE_ERROR(H5E_OHDR, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree for creation order index")
393     if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
394 	HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
395 
396     FUNC_LEAVE_NOAPI(ret_value)
397 }   /* H5O_attr_dense_info_test() */
398 
399 
400 /*--------------------------------------------------------------------------
401  NAME
402     H5O_check_msg_marked_test
403  PURPOSE
404     Check if an unknown message with the "mark if unknown" flag actually gets
405     marked.
406  USAGE
407     herr_t H5O_check_msg_marked_test(oid, flag_val)
408         hid_t oid;              IN: Object to check
409         hbool_t flag_val;       IN: Desired flag value
410  RETURNS
411     Non-negative on success, negative on failure
412  DESCRIPTION
413     Locates the "unknown" message and checks that the "was unknown" flag is set
414     correctly.
415  GLOBAL VARIABLES
416  COMMENTS, BUGS, ASSUMPTIONS
417     DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
418  EXAMPLES
419  REVISION LOG
420 --------------------------------------------------------------------------*/
421 herr_t
H5O_check_msg_marked_test(hid_t oid,hbool_t flag_val)422 H5O_check_msg_marked_test(hid_t oid, hbool_t flag_val)
423 {
424     H5O_t *oh = NULL;           /* Object header */
425     H5O_loc_t *loc;            /* Pointer to object's location */
426     H5O_mesg_t *idx_msg;        /* Pointer to message */
427     unsigned idx;               /* Index of message */
428     herr_t ret_value = SUCCEED; /* Return value */
429 
430     FUNC_ENTER_NOAPI(FAIL)
431 
432     /* Get object location for object */
433     if(NULL == (loc = H5O_get_loc(oid)))
434         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
435 
436     /* Get the object header */
437     if(NULL == (oh = H5O_protect(loc, H5AC_ind_dxpl_id, H5AC_READ)))
438 	HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load object header")
439 
440     /* Locate "unknown" message  */
441     for(idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++)
442 	if(idx_msg->type->id == H5O_UNKNOWN_ID) {
443             /* Check for "unknown" message having the correct flags */
444             if(((idx_msg->flags & H5O_MSG_FLAG_WAS_UNKNOWN) > 0) != flag_val)
445                 HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "'unknown' message has incorrect 'was unknown' flag value")
446 
447             /* Break out of loop, to indicate that the "unknown" message was found */
448             break;
449         } /* end if */
450 
451     /* Check for not finding an "unknown" message */
452     if(idx == oh->nmesgs)
453         HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "'unknown' message type not found")
454 
455 done:
456     if(oh && H5O_unprotect(loc, H5AC_ind_dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
457 	HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
458 
459     FUNC_LEAVE_NOAPI(ret_value)
460 }   /* H5O_check_msg_marked_test() */
461 
462 
463 /*--------------------------------------------------------------------------
464  NAME
465     H5O_expunge_chunks_test
466  PURPOSE
467     Expunge all the chunks for an object header from the cache.
468  USAGE
469     herr_t H5O_expunge_chunks_test(f, dxpl_id, loc)
470         H5F_t *f;               IN: Pointer to file that object is within
471         hid_t dxpl_id;          IN: DXPL to use for operation
472         H5O_loc_t *loc;         IN: Object location for object header to expunge
473  RETURNS
474     Non-negative on success, negative on failure
475  DESCRIPTION
476     Iterates over all the chunks for an object header an expunges each from the
477     metadata cache.
478  GLOBAL VARIABLES
479  COMMENTS, BUGS, ASSUMPTIONS
480     DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
481  EXAMPLES
482  REVISION LOG
483 --------------------------------------------------------------------------*/
484 herr_t
H5O_expunge_chunks_test(const H5O_loc_t * loc,hid_t dxpl_id)485 H5O_expunge_chunks_test(const H5O_loc_t *loc, hid_t dxpl_id)
486 {
487     H5O_t *oh = NULL;           /* Object header */
488     haddr_t chk_addr[16];       /* Array of chunk addresses */
489     size_t nchunks;             /* Number of chunks in object header */
490     size_t u;                   /* Local index variable */
491     herr_t ret_value = SUCCEED; /* Return value */
492 
493     FUNC_ENTER_NOAPI(FAIL)
494 
495     /* Get the object header */
496     if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_WRITE)))
497 	HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
498 
499     /* Safety check */
500     nchunks = oh->nchunks;
501     HDassert(0 < nchunks && nchunks < NELMTS(chk_addr));
502 
503     /* Iterate over all the chunks, saving the chunk addresses */
504     for(u = 0; u < oh->nchunks; u++)
505         chk_addr[u] = oh->chunk[u].addr;
506 
507     /* Release the object header */
508     if(H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
509 	HGOTO_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header")
510 
511     /* Iterate over all the saved chunk addresses, evicting them from the cache */
512     /* (in reverse order, so that chunk #0 is unpinned) */
513     for(u = nchunks - 1; u < nchunks; u--)
514         if(H5AC_expunge_entry(loc->file, dxpl_id, (u == 0 ? H5AC_OHDR : H5AC_OHDR_CHK), chk_addr[u], H5AC__NO_FLAGS_SET) < 0)
515             HGOTO_ERROR(H5E_OHDR, H5E_CANTEXPUNGE, FAIL, "unable to expunge object header chunk")
516 
517 done:
518     FUNC_LEAVE_NOAPI(ret_value)
519 }   /* H5O_expunge_chunks_test() */
520 
521 
522 /*--------------------------------------------------------------------------
523  NAME
524     H5O_get_rc
525  PURPOSE
526     Retrieve the refcount for the object header
527  USAGE
528     herr_t H5O_expunge_chunks_test(loc, dxpl_id, rc)
529         const H5O_loc_t *loc;   IN: Object location for object header to query
530         hid_t dxpl_id;          IN: DXPL to use for operation
531         unsigned *rc;           OUT: Pointer to refcount for object header
532  RETURNS
533     Non-negative on success, negative on failure
534  DESCRIPTION
535     Protects object header, retrieves the object header's refcount, and
536     unprotects object header.
537  GLOBAL VARIABLES
538  COMMENTS, BUGS, ASSUMPTIONS
539     DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
540  EXAMPLES
541  REVISION LOG
542 --------------------------------------------------------------------------*/
543 herr_t
H5O_get_rc(const H5O_loc_t * loc,hid_t dxpl_id,unsigned * rc)544 H5O_get_rc(const H5O_loc_t *loc, hid_t dxpl_id, unsigned *rc)
545 {
546     H5O_t *oh = NULL;           /* Object header */
547     herr_t ret_value = SUCCEED; /* Return value */
548 
549     FUNC_ENTER_NOAPI(FAIL)
550 
551     /* Sanity check */
552     HDassert(loc);
553     HDassert(rc);
554 
555     /* Get the object header */
556     if(NULL == (oh = H5O_protect(loc, dxpl_id, H5AC_READ)))
557 	HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object header")
558 
559     /* Save the refcount for the object header */
560     *rc = oh->nlink;
561 
562 done:
563     /* Release the object header */
564     if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
565 	HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to unprotect object header")
566 
567     FUNC_LEAVE_NOAPI(ret_value)
568 }   /* H5O_expunge_chunks_test() */
569 
570