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 /*-------------------------------------------------------------------------
17  *
18  * Created:		H5HFspace.c
19  *			May  2 2006
20  *			Quincey Koziol <koziol@ncsa.uiuc.edu>
21  *
22  * Purpose:		Space allocation routines for fractal heaps.
23  *
24  *-------------------------------------------------------------------------
25  */
26 
27 /****************/
28 /* Module Setup */
29 /****************/
30 
31 #define H5HF_PACKAGE		/*suppress error about including H5HFpkg  */
32 
33 /***********/
34 /* Headers */
35 /***********/
36 #include "H5private.h"		/* Generic Functions			*/
37 #include "H5Eprivate.h"		/* Error handling		  	*/
38 #include "H5HFpkg.h"		/* Fractal heaps			*/
39 
40 
41 /****************/
42 /* Local Macros */
43 /****************/
44 
45 #define H5HF_FSPACE_SHRINK      80              /* Percent of "normal" size to shrink serialized free space size */
46 #define H5HF_FSPACE_EXPAND      120             /* Percent of "normal" size to expand serialized free space size */
47 #define H5HF_FSPACE_THRHD_DEF 	1             	/* Default: no alignment threshold */
48 #define H5HF_FSPACE_ALIGN_DEF   1             	/* Default: no alignment */
49 
50 /******************/
51 /* Local Typedefs */
52 /******************/
53 
54 
55 /********************/
56 /* Package Typedefs */
57 /********************/
58 
59 
60 /********************/
61 /* Local Prototypes */
62 /********************/
63 
64 
65 /*********************/
66 /* Package Variables */
67 /*********************/
68 
69 
70 /*****************************/
71 /* Library Private Variables */
72 /*****************************/
73 
74 
75 /*******************/
76 /* Local Variables */
77 /*******************/
78 
79 
80 
81 /*-------------------------------------------------------------------------
82  * Function:	H5HF_space_start
83  *
84  * Purpose:	"Start up" free space for heap - open existing free space
85  *              structure if one exists, otherwise create a new free space
86  *              structure
87  *
88  * Return:	Success:	non-negative
89  *
90  *		Failure:	negative
91  *
92  * Programmer:	Quincey Koziol
93  *		koziol@ncsa.uiuc.edu
94  *		May  2 2006
95  *
96  * Modifications:
97  *	Vailin Choi, July 29th, 2008
98  *	  Pass values of alignment and threshold to FS_create() and FS_open()
99  *	  for handling alignment.
100  *
101  *-------------------------------------------------------------------------
102  */
103 herr_t
H5HF_space_start(H5HF_hdr_t * hdr,hid_t dxpl_id,hbool_t may_create)104 H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id, hbool_t may_create)
105 {
106     const H5FS_section_class_t *classes[] = { /* Free space section classes implemented for fractal heap */
107         H5HF_FSPACE_SECT_CLS_SINGLE,
108         H5HF_FSPACE_SECT_CLS_FIRST_ROW,
109         H5HF_FSPACE_SECT_CLS_NORMAL_ROW,
110         H5HF_FSPACE_SECT_CLS_INDIRECT};
111     herr_t ret_value = SUCCEED;         /* Return value */
112 
113     FUNC_ENTER_NOAPI_NOINIT
114 
115     /*
116      * Check arguments.
117      */
118     HDassert(hdr);
119 
120     /* Check for creating free space info for the heap */
121     if(H5F_addr_defined(hdr->fs_addr)) {
122         /* Open an existing free space structure for the heap */
123         if(NULL == (hdr->fspace = H5FS_open(hdr->f, dxpl_id, hdr->fs_addr,
124                 NELMTS(classes), classes, hdr, H5HF_FSPACE_THRHD_DEF, H5HF_FSPACE_ALIGN_DEF)))
125             HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free space info")
126     } /* end if */
127     else {
128         /* Check if we are allowed to create the free space manager */
129         if(may_create) {
130             H5FS_create_t fs_create;        /* Free space creation parameters */
131 
132             /* Set the free space creation parameters */
133             fs_create.client = H5FS_CLIENT_FHEAP_ID;
134             fs_create.shrink_percent = H5HF_FSPACE_SHRINK;
135             fs_create.expand_percent = H5HF_FSPACE_EXPAND;
136             fs_create.max_sect_size = hdr->man_dtable.cparam.max_direct_size;
137             fs_create.max_sect_addr = hdr->man_dtable.cparam.max_index;
138 
139             /* Create the free space structure for the heap */
140             if(NULL == (hdr->fspace = H5FS_create(hdr->f, dxpl_id, &hdr->fs_addr,
141                     &fs_create, NELMTS(classes), classes, hdr, H5HF_FSPACE_THRHD_DEF, H5HF_FSPACE_ALIGN_DEF)))
142                 HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free space info")
143             HDassert(H5F_addr_defined(hdr->fs_addr));
144         } /* end if */
145     } /* end else */
146 
147 done:
148     FUNC_LEAVE_NOAPI(ret_value)
149 } /* end H5HF_space_start() */
150 
151 
152 /*-------------------------------------------------------------------------
153  * Function:	H5HF_space_add
154  *
155  * Purpose:	Add a section to the free space for the heap
156  *
157  * Return:	Success:	non-negative
158  *
159  *		Failure:	negative
160  *
161  * Programmer:	Quincey Koziol
162  *		koziol@ncsa.uiuc.edu
163  *		May 15 2006
164  *
165  *-------------------------------------------------------------------------
166  */
167 herr_t
H5HF_space_add(H5HF_hdr_t * hdr,hid_t dxpl_id,H5HF_free_section_t * node,unsigned flags)168 H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node,
169     unsigned flags)
170 {
171     H5HF_sect_add_ud_t udata;          /* User data for free space manager 'add' */
172     herr_t ret_value = SUCCEED;         /* Return value */
173 
174     FUNC_ENTER_NOAPI_NOINIT
175 
176     /*
177      * Check arguments.
178      */
179     HDassert(hdr);
180     HDassert(node);
181 
182     /* Check if the free space for the heap has been initialized */
183     if(!hdr->fspace)
184         if(H5HF_space_start(hdr, dxpl_id, TRUE) < 0)
185             HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
186 
187     /* Construct user data */
188     udata.hdr = hdr;
189     udata.dxpl_id = dxpl_id;
190 
191     /* Add to the free space for the heap */
192     if(H5FS_sect_add(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata) < 0)
193         HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't add section to heap free space")
194 
195 done:
196     FUNC_LEAVE_NOAPI(ret_value)
197 } /* end H5HF_space_add() */
198 
199 
200 /*-------------------------------------------------------------------------
201  * Function:	H5HF_space_find
202  *
203  * Purpose:	Attempt to find space in a fractal heap
204  *
205  * Return:	Success:	non-negative
206  *
207  *		Failure:	negative
208  *
209  * Programmer:	Quincey Koziol
210  *		koziol@ncsa.uiuc.edu
211  *		May  2 2006
212  *
213  *-------------------------------------------------------------------------
214  */
215 htri_t
H5HF_space_find(H5HF_hdr_t * hdr,hid_t dxpl_id,hsize_t request,H5HF_free_section_t ** node)216 H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request, H5HF_free_section_t **node)
217 {
218     htri_t node_found = FALSE;  /* Whether an existing free list node was found */
219     htri_t ret_value;           /* Return value */
220 
221     FUNC_ENTER_NOAPI_NOINIT
222 
223     /*
224      * Check arguments.
225      */
226     HDassert(hdr);
227     HDassert(request);
228     HDassert(node);
229 
230     /* Check if the free space for the heap has been initialized */
231     if(!hdr->fspace)
232         if(H5HF_space_start(hdr, dxpl_id, FALSE) < 0)
233             HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
234 
235     /* Search for free space in the heap */
236     if(hdr->fspace)
237         if((node_found = H5FS_sect_find(hdr->f, dxpl_id, hdr->fspace, request, (H5FS_section_info_t **)node)) < 0)
238             HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap")
239 
240     /* Set return value */
241     ret_value = node_found;
242 
243 done:
244     FUNC_LEAVE_NOAPI(ret_value)
245 } /* end H5HF_space_find() */
246 
247 
248 /*-------------------------------------------------------------------------
249  * Function:	H5HF_space_revert_root_cb
250  *
251  * Purpose:	Callback routine from iterator, to reset 'parent' pointers in
252  *		sections, when the heap is changing from having a root indirect
253  *		block to a direct block.
254  *
255  * Return:	Success:	non-negative
256  *		Failure:	negative
257  *
258  * Programmer:	Quincey Koziol
259  *		koziol@hdfgroup.org
260  *		Feb 24 2012
261  *
262  *-------------------------------------------------------------------------
263  */
264 static herr_t
H5HF_space_revert_root_cb(H5FS_section_info_t * _sect,void UNUSED * _udata)265 H5HF_space_revert_root_cb(H5FS_section_info_t *_sect, void UNUSED *_udata)
266 {
267     H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect;       /* Section to dump info */
268     herr_t      ret_value = SUCCEED;    /* Return value */
269 
270     FUNC_ENTER_NOAPI_NOINIT
271 
272     /*
273      * Check arguments.
274      */
275     HDassert(sect);
276 
277     /* Only modify "live" single blocks... */
278     if(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE && sect->sect_info.state == H5FS_SECT_LIVE) {
279         /* Release hold on previous indirect block (we must have one) */
280         HDassert(sect->u.single.parent);
281         if(H5HF_iblock_decr(sect->u.single.parent) < 0)
282             HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block")
283 
284         /* Reset parent information */
285         sect->u.single.parent = NULL;
286         sect->u.single.par_entry = 0;
287     } /* end if */
288 
289 done:
290     FUNC_LEAVE_NOAPI(ret_value)
291 } /* end H5HF_space_revert_root_cb() */
292 
293 
294 /*-------------------------------------------------------------------------
295  * Function:	H5HF_space_revert_root
296  *
297  * Purpose:	Reset 'parent' pointers in sections, when the heap is
298  *		changing from having a root indirect block to a direct block.
299  *
300  * Return:	Success:	non-negative
301  *		Failure:	negative
302  *
303  * Programmer:	Quincey Koziol
304  *		koziol@hdfgroup.org
305  *		Feb 23 2012
306  *
307  *-------------------------------------------------------------------------
308  */
309 herr_t
H5HF_space_revert_root(const H5HF_hdr_t * hdr,hid_t dxpl_id)310 H5HF_space_revert_root(const H5HF_hdr_t *hdr, hid_t dxpl_id)
311 {
312     herr_t ret_value = SUCCEED;         /* Return value */
313 
314     FUNC_ENTER_NOAPI_NOINIT
315 
316     /*
317      * Check arguments.
318      */
319     HDassert(hdr);
320 
321     /* Only need to scan the sections if the free space has been initialized */
322     if(hdr->fspace) {
323 	/* Iterate over all sections, reseting the parent pointers in 'single' sections */
324         if(H5FS_sect_iterate(hdr->f, dxpl_id, hdr->fspace, H5HF_space_revert_root_cb, NULL) < 0)
325             HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to reset parent pointers")
326     } /* end if */
327 
328 done:
329     FUNC_LEAVE_NOAPI(ret_value)
330 } /* end H5HF_space_revert_root() */
331 
332 
333 /*-------------------------------------------------------------------------
334  * Function:	H5HF_space_create_root_cb
335  *
336  * Purpose:	Callback routine from iterator, to set 'parent' pointers in
337  *		sections to newly created root indirect block, when the heap
338  *		is changing from having a root direct block to an indirect block.
339  *
340  * Return:	Success:	non-negative
341  *		Failure:	negative
342  *
343  * Programmer:	Quincey Koziol
344  *		koziol@hdfgroup.org
345  *		Feb 24 2012
346  *
347  *-------------------------------------------------------------------------
348  */
349 static herr_t
H5HF_space_create_root_cb(H5FS_section_info_t * _sect,void * _udata)350 H5HF_space_create_root_cb(H5FS_section_info_t *_sect, void *_udata)
351 {
352     H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect;       /* Section to dump info */
353     H5HF_indirect_t *root_iblock = (H5HF_indirect_t *)_udata;	/* User data for callback */
354     herr_t      ret_value = SUCCEED;    /* Return value */
355 
356     FUNC_ENTER_NOAPI_NOINIT
357 
358     /*
359      * Check arguments.
360      */
361     HDassert(sect);
362     HDassert(root_iblock);
363 
364     /* Sanity check sections */
365     /* (If we are switching from a direct block for the root block of the heap, */
366     /*	there should only be 'single' type sections. -QAK) */
367     HDassert(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE);
368 
369     /* Increment ref. count on new root indirect block */
370     if(H5HF_iblock_incr(root_iblock) < 0)
371         HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on section's indirect block")
372 
373     /* Set parent info ("live" section must _NOT_ have a parent right now) */
374     if(sect->sect_info.state == H5FS_SECT_SERIALIZED)
375         sect->sect_info.state = H5FS_SECT_LIVE;         /* Mark "live" now */
376     else
377          HDassert(!sect->u.single.parent);
378     sect->u.single.parent = root_iblock;
379     sect->u.single.par_entry = 0;
380 
381 done:
382     FUNC_LEAVE_NOAPI(ret_value)
383 } /* end H5HF_space_create_root_cb() */
384 
385 
386 /*-------------------------------------------------------------------------
387  * Function:	H5HF_space_create_root
388  *
389  * Purpose:	Set 'parent' pointers in sections to new indirect block, when
390  *		the heap is changing from having a root direct block to a
391  *		indirect block.
392  *
393  * Return:	Success:	non-negative
394  *		Failure:	negative
395  *
396  * Programmer:	Quincey Koziol
397  *		koziol@hdfgroup.org
398  *		Feb 24 2012
399  *
400  *-------------------------------------------------------------------------
401  */
402 herr_t
H5HF_space_create_root(const H5HF_hdr_t * hdr,hid_t dxpl_id,H5HF_indirect_t * root_iblock)403 H5HF_space_create_root(const H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *root_iblock)
404 {
405     herr_t ret_value = SUCCEED;         /* Return value */
406 
407     FUNC_ENTER_NOAPI_NOINIT
408 
409     /*
410      * Check arguments.
411      */
412     HDassert(hdr);
413     HDassert(root_iblock);
414 
415     /* Only need to scan the sections if the free space has been initialized */
416     if(hdr->fspace) {
417 	/* Iterate over all sections, seting the parent pointers in 'single' sections to the new indirect block */
418         if(H5FS_sect_iterate(hdr->f, dxpl_id, hdr->fspace, H5HF_space_create_root_cb, root_iblock) < 0)
419             HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to set parent pointers")
420     } /* end if */
421 
422 done:
423     FUNC_LEAVE_NOAPI(ret_value)
424 } /* end H5HF_space_create_root() */
425 
426 
427 /*-------------------------------------------------------------------------
428  * Function:	H5HF_space_size
429  *
430  * Purpose:	Query the size of the heap's free space info on disk
431  *
432  * Return:	Success:	non-negative
433  *		Failure:	negative
434  *
435  * Programmer:	Quincey Koziol
436  *		koziol@hdfgroup.org
437  *		August 14 2007
438  *
439  *-------------------------------------------------------------------------
440  */
441 herr_t
H5HF_space_size(H5HF_hdr_t * hdr,hid_t dxpl_id,hsize_t * fs_size)442 H5HF_space_size(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t *fs_size)
443 {
444     herr_t ret_value = SUCCEED;         /* Return value */
445 
446     FUNC_ENTER_NOAPI_NOINIT
447 
448     /*
449      * Check arguments.
450      */
451     HDassert(hdr);
452     HDassert(fs_size);
453 
454     /* Check if the free space for the heap has been initialized */
455     if(!hdr->fspace)
456         if(H5HF_space_start(hdr, dxpl_id, FALSE) < 0)
457             HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
458 
459     /* Get free space metadata size */
460     if(hdr->fspace) {
461         if(H5FS_size(hdr->f, hdr->fspace, fs_size) < 0)
462             HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "can't retrieve FS meta storage info")
463     } /* end if */
464     else
465         *fs_size = 0;
466 
467 done:
468     FUNC_LEAVE_NOAPI(ret_value)
469 } /* end H5HF_space_size() */
470 
471 
472 /*-------------------------------------------------------------------------
473  * Function:	H5HF_space_remove
474  *
475  * Purpose:	Remove a section from the free space for the heap
476  *
477  * Return:	Success:	non-negative
478  *		Failure:	negative
479  *
480  * Programmer:	Quincey Koziol
481  *		koziol@ncsa.uiuc.edu
482  *		July 24 2006
483  *
484  *-------------------------------------------------------------------------
485  */
486 herr_t
H5HF_space_remove(H5HF_hdr_t * hdr,hid_t dxpl_id,H5HF_free_section_t * node)487 H5HF_space_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node)
488 {
489     herr_t ret_value = SUCCEED;         /* Return value */
490 
491     FUNC_ENTER_NOAPI_NOINIT
492 
493     /*
494      * Check arguments.
495      */
496     HDassert(hdr);
497     HDassert(hdr->fspace);
498     HDassert(node);
499 
500     /* Remove from the free space for the heap */
501     if(H5FS_sect_remove(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node) < 0)
502         HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove section from heap free space")
503 
504 done:
505     FUNC_LEAVE_NOAPI(ret_value)
506 } /* end H5HF_space_remove() */
507 
508 
509 /*-------------------------------------------------------------------------
510  * Function:	H5HF_space_close
511  *
512  * Purpose:	Close the free space for the heap
513  *
514  * Return:	Success:	non-negative
515  *
516  *		Failure:	negative
517  *
518  * Programmer:	Quincey Koziol
519  *		koziol@ncsa.uiuc.edu
520  *		May  2 2006
521  *
522  *-------------------------------------------------------------------------
523  */
524 herr_t
H5HF_space_close(H5HF_hdr_t * hdr,hid_t dxpl_id)525 H5HF_space_close(H5HF_hdr_t *hdr, hid_t dxpl_id)
526 {
527     herr_t ret_value = SUCCEED;         /* Return value */
528 
529     FUNC_ENTER_NOAPI_NOINIT
530 
531     /*
532      * Check arguments.
533      */
534     HDassert(hdr);
535 
536     /* Check if the free space was ever opened */
537     if(hdr->fspace) {
538         hsize_t nsects;         /* Number of sections for this heap */
539 
540         /* Retrieve the number of sections for this heap */
541         if(H5FS_sect_stats(hdr->fspace, NULL, &nsects) < 0)
542             HGOTO_ERROR(H5E_HEAP, H5E_CANTCOUNT, FAIL, "can't query free space section count")
543 #ifdef QAK
544 HDfprintf(stderr, "%s: nsects = %Hu\n", FUNC, nsects);
545 #endif /* QAK */
546 
547         /* Close the free space for the heap */
548         if(H5FS_close(hdr->f, dxpl_id, hdr->fspace) < 0)
549             HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release free space info")
550         hdr->fspace = NULL;
551 
552         /* Check if we can delete the free space manager for this heap */
553         if(!nsects) {
554             if(H5FS_delete(hdr->f, dxpl_id, hdr->fs_addr) < 0)
555                 HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete free space info")
556             hdr->fs_addr = HADDR_UNDEF;
557         } /* end if */
558     } /* end if */
559 
560 done:
561     FUNC_LEAVE_NOAPI(ret_value)
562 } /* end H5HF_space_close() */
563 
564 
565 /*-------------------------------------------------------------------------
566  * Function:	H5HF_space_delete
567  *
568  * Purpose:	Delete the free space manager for the heap
569  *
570  * Return:	Success:	non-negative
571  *		Failure:	negative
572  *
573  * Programmer:	Quincey Koziol
574  *		koziol@ncsa.uiuc.edu
575  *		Aug  7 2006
576  *
577  *-------------------------------------------------------------------------
578  */
579 herr_t
H5HF_space_delete(H5HF_hdr_t * hdr,hid_t dxpl_id)580 H5HF_space_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
581 {
582     herr_t ret_value = SUCCEED;         /* Return value */
583 
584     FUNC_ENTER_NOAPI_NOINIT
585 
586     /*
587      * Check arguments.
588      */
589     HDassert(hdr);
590 
591     /* Delete the free space manager */
592     if(H5FS_delete(hdr->f, dxpl_id, hdr->fs_addr) < 0)
593         HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "can't delete to free space manager")
594 
595 done:
596     FUNC_LEAVE_NOAPI(ret_value)
597 } /* end H5HF_space_delete() */
598 
599 
600 /*-------------------------------------------------------------------------
601  * Function:	H5HF_space_change_sect_class
602  *
603  * Purpose:	Change a section's class
604  *
605  * Return:	Success:	non-negative
606  *
607  *		Failure:	negative
608  *
609  * Programmer:	Quincey Koziol
610  *		koziol@ncsa.uiuc.edu
611  *		July 10 2006
612  *
613  *-------------------------------------------------------------------------
614  */
615 herr_t
H5HF_space_sect_change_class(H5HF_hdr_t * hdr,hid_t dxpl_id,H5HF_free_section_t * sect,unsigned new_class)616 H5HF_space_sect_change_class(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sect, unsigned new_class)
617 {
618     herr_t ret_value = SUCCEED;         /* Return value */
619 
620     FUNC_ENTER_NOAPI_NOINIT
621 #ifdef QAK
622 HDfprintf(stderr, "%s: Called\n", FUNC);
623 #endif /* QAK */
624 
625     /*
626      * Check arguments.
627      */
628     HDassert(hdr);
629     HDassert(hdr->fspace);
630     HDassert(sect);
631 
632     /* Notify the free space manager that a section has changed class */
633     if(H5FS_sect_change_class(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)sect, new_class) < 0)
634         HGOTO_ERROR(H5E_HEAP, H5E_CANTMODIFY, FAIL, "can't modify class of free space section")
635 
636 done:
637     FUNC_LEAVE_NOAPI(ret_value)
638 } /* end H5HF_space_sect_change_class() */
639 
640