1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*
15 * Programmer: Quincey Koziol <koziol@hdfgroup.org>
16 * Tuesday, January 8, 2008
17 *
18 * Purpose: Free space section callbacks for file.
19 *
20 */
21
22 /****************/
23 /* Module Setup */
24 /****************/
25
26 #define H5F_FRIEND /*suppress error about including H5Fpkg */
27 #include "H5MFmodule.h" /* This source code file is part of the H5MF module */
28
29
30 /***********/
31 /* Headers */
32 /***********/
33 #include "H5private.h" /* Generic Functions */
34 #include "H5Eprivate.h" /* Error handling */
35 #include "H5Fpkg.h" /* File access */
36 #include "H5MFpkg.h" /* File memory management */
37
38
39 /****************/
40 /* Local Macros */
41 /****************/
42
43
44 /******************/
45 /* Local Typedefs */
46 /******************/
47
48
49 /********************/
50 /* Package Typedefs */
51 /********************/
52
53
54 /********************/
55 /* Local Prototypes */
56 /********************/
57
58 /* 'simple/small/large' section callbacks */
59 static H5FS_section_info_t *H5MF_sect_deserialize(const H5FS_section_class_t *cls,
60 hid_t dxpl_id, const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size,
61 unsigned *des_flags);
62 static herr_t H5MF_sect_valid(const H5FS_section_class_t *cls,
63 const H5FS_section_info_t *sect, hid_t dxpl_id);
64 static H5FS_section_info_t *H5MF_sect_split(H5FS_section_info_t *sect,
65 hsize_t frag_size);
66
67
68 /* 'simple' section callbacks */
69 static htri_t H5MF_sect_simple_can_merge(const H5FS_section_info_t *sect1,
70 const H5FS_section_info_t *sect2, void *udata);
71 static herr_t H5MF_sect_simple_merge(H5FS_section_info_t **sect1,
72 H5FS_section_info_t *sect2, void *udata);
73 static htri_t H5MF_sect_simple_can_shrink(const H5FS_section_info_t *_sect,
74 void *udata);
75 static herr_t H5MF_sect_simple_shrink(H5FS_section_info_t **_sect,
76 void *udata);
77
78
79 /* 'small' section callbacks */
80 static herr_t H5MF_sect_small_add(H5FS_section_info_t **_sect, unsigned *flags, void *_udata);
81 static htri_t H5MF_sect_small_can_merge(const H5FS_section_info_t *sect1,
82 const H5FS_section_info_t *sect2, void *udata);
83 static herr_t H5MF_sect_small_merge(H5FS_section_info_t **sect1,
84 H5FS_section_info_t *sect2, void *udata);
85 static htri_t H5MF_sect_small_can_shrink(const H5FS_section_info_t *_sect,
86 void *udata);
87 static herr_t H5MF_sect_small_shrink(H5FS_section_info_t **_sect,
88 void *udata);
89
90 /* 'large' section callbacks */
91 static htri_t H5MF_sect_large_can_merge(const H5FS_section_info_t *sect1,
92 const H5FS_section_info_t *sect2, void *udata);
93 static herr_t H5MF_sect_large_merge(H5FS_section_info_t **sect1,
94 H5FS_section_info_t *sect2, void *udata);
95 static htri_t H5MF_sect_large_can_shrink(const H5FS_section_info_t *_sect,
96 void *udata);
97 static herr_t H5MF_sect_large_shrink(H5FS_section_info_t **_sect,
98 void *udata);
99
100 /*********************/
101 /* Package Variables */
102 /*********************/
103
104 /* Class info for "simple" free space sections */
105 H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SIMPLE[1] = {{
106 /* Class variables */
107 H5MF_FSPACE_SECT_SIMPLE, /* Section type */
108 0, /* Extra serialized size */
109 H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
110 NULL, /* Class private info */
111
112 /* Class methods */
113 NULL, /* Initialize section class */
114 NULL, /* Terminate section class */
115
116 /* Object methods */
117 NULL, /* Add section */
118 NULL, /* Serialize section */
119 H5MF_sect_deserialize, /* Deserialize section */
120 H5MF_sect_simple_can_merge, /* Can sections merge? */
121 H5MF_sect_simple_merge, /* Merge sections */
122 H5MF_sect_simple_can_shrink, /* Can section shrink container?*/
123 H5MF_sect_simple_shrink, /* Shrink container w/section */
124 H5MF_sect_free, /* Free section */
125 H5MF_sect_valid, /* Check validity of section */
126 H5MF_sect_split, /* Split section node for alignment */
127 NULL, /* Dump debugging for section */
128 }};
129
130 /* Class info for "small" free space sections */
131 H5FS_section_class_t H5MF_FSPACE_SECT_CLS_SMALL[1] = {{
132 /* Class variables */
133 H5MF_FSPACE_SECT_SMALL, /* Section type */
134 0, /* Extra serialized size */
135 H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
136 NULL, /* Class private info */
137
138 /* Class methods */
139 NULL, /* Initialize section class */
140 NULL, /* Terminate section class */
141
142 /* Object methods */
143 H5MF_sect_small_add, /* Add section */
144 NULL, /* Serialize section */
145 H5MF_sect_deserialize, /* Deserialize section */
146 H5MF_sect_small_can_merge, /* Can sections merge? */
147 H5MF_sect_small_merge, /* Merge sections */
148 H5MF_sect_small_can_shrink, /* Can section shrink container?*/
149 H5MF_sect_small_shrink, /* Shrink container w/section */
150 H5MF_sect_free, /* Free section */
151 H5MF_sect_valid, /* Check validity of section */
152 H5MF_sect_split, /* Split section node for alignment */
153 NULL, /* Dump debugging for section */
154 }};
155
156 /* Class info for "large" free space sections */
157 H5FS_section_class_t H5MF_FSPACE_SECT_CLS_LARGE[1] = {{
158 /* Class variables */
159 H5MF_FSPACE_SECT_LARGE, /* Section type */
160 0, /* Extra serialized size */
161 H5FS_CLS_MERGE_SYM | H5FS_CLS_ADJUST_OK, /* Class flags */
162 NULL, /* Class private info */
163
164 /* Class methods */
165 NULL, /* Initialize section class */
166 NULL, /* Terminate section class */
167
168 /* Object methods */
169 NULL, /* Add section */
170 NULL, /* Serialize section */
171 H5MF_sect_deserialize, /* Deserialize section */
172 H5MF_sect_large_can_merge, /* Can sections merge? */
173 H5MF_sect_large_merge, /* Merge sections */
174 H5MF_sect_large_can_shrink, /* Can section shrink container?*/
175 H5MF_sect_large_shrink, /* Shrink container w/section */
176 H5MF_sect_free, /* Free section */
177 H5MF_sect_valid, /* Check validity of section */
178 H5MF_sect_split, /* Split section node for alignment */
179 NULL, /* Dump debugging for section */
180 }};
181
182 /*****************************/
183 /* Library Private Variables */
184 /*****************************/
185
186
187 /*******************/
188 /* Local Variables */
189 /*******************/
190
191 /* Declare a free list to manage the H5MF_free_section_t struct */
192 H5FL_DEFINE(H5MF_free_section_t);
193
194 /*
195 * "simple/small/large" section callbacks
196 */
197
198
199 /*-------------------------------------------------------------------------
200 * Function: H5MF_sect_new
201 *
202 * Purpose: Create a new section of "ctype" and return it to the caller
203 *
204 * Return: Pointer to new section on success/NULL on failure
205 *
206 * Programmer: Quincey Koziol
207 * koziol@hdfgroup.org
208 * January 8 2008
209 *
210 *-------------------------------------------------------------------------
211 */
212 H5MF_free_section_t *
H5MF_sect_new(unsigned ctype,haddr_t sect_off,hsize_t sect_size)213 H5MF_sect_new(unsigned ctype, haddr_t sect_off, hsize_t sect_size)
214 {
215 H5MF_free_section_t *sect; /* 'Simple' free space section to add */
216 H5MF_free_section_t *ret_value = NULL; /* Return value */
217
218 FUNC_ENTER_NOAPI_NOINIT
219
220 /* Check arguments. */
221 HDassert(sect_size);
222
223 /* Create free space section node */
224 if(NULL == (sect = H5FL_MALLOC(H5MF_free_section_t)))
225 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct block free list section")
226
227 /* Set the information passed in */
228 sect->sect_info.addr = sect_off;
229 sect->sect_info.size = sect_size;
230
231 /* Set the section's class & state */
232 sect->sect_info.type = ctype;
233 sect->sect_info.state = H5FS_SECT_LIVE;
234
235 /* Set return value */
236 ret_value = sect;
237
238 done:
239 FUNC_LEAVE_NOAPI(ret_value)
240 } /* end H5MF_sect_new() */
241
242
243 /*-------------------------------------------------------------------------
244 * Function: H5MF_sect_free
245 *
246 * Purpose: Free a 'simple/small/large' section node
247 *
248 * Return: Success: non-negative
249 * Failure: negative
250 *
251 * Programmer: Quincey Koziol
252 * Tuesday, January 8, 2008
253 *
254 *-------------------------------------------------------------------------
255 */
256 herr_t
H5MF_sect_free(H5FS_section_info_t * _sect)257 H5MF_sect_free(H5FS_section_info_t *_sect)
258 {
259 H5MF_free_section_t *sect = (H5MF_free_section_t *)_sect; /* File free section */
260
261 FUNC_ENTER_NOAPI_NOINIT_NOERR
262
263 /* Check arguments. */
264 HDassert(sect);
265
266 /* Release the section */
267 sect = H5FL_FREE(H5MF_free_section_t, sect);
268
269 FUNC_LEAVE_NOAPI(SUCCEED)
270 } /* H5MF_sect_free() */
271
272
273 /*-------------------------------------------------------------------------
274 * Function: H5MF_sect_deserialize
275 *
276 * Purpose: Deserialize a buffer into a "live" section
277 *
278 * Return: Success: non-negative
279 * Failure: negative
280 *
281 * Programmer: Quincey Koziol
282 * Tuesday, January 8, 2008
283 *
284 *-------------------------------------------------------------------------
285 */
286 static H5FS_section_info_t *
H5MF_sect_deserialize(const H5FS_section_class_t * cls,hid_t H5_ATTR_UNUSED dxpl_id,const uint8_t H5_ATTR_UNUSED * buf,haddr_t sect_addr,hsize_t sect_size,unsigned H5_ATTR_UNUSED * des_flags)287 H5MF_sect_deserialize(const H5FS_section_class_t *cls,
288 hid_t H5_ATTR_UNUSED dxpl_id, const uint8_t H5_ATTR_UNUSED *buf, haddr_t sect_addr,
289 hsize_t sect_size, unsigned H5_ATTR_UNUSED *des_flags)
290 {
291 H5MF_free_section_t *sect; /* New section */
292 H5FS_section_info_t *ret_value = NULL; /* Return value */
293
294 FUNC_ENTER_NOAPI_NOINIT
295
296 /* Check arguments. */
297 HDassert(cls);
298 HDassert(H5F_addr_defined(sect_addr));
299 HDassert(sect_size);
300
301 /* Create free space section for block */
302 if(NULL == (sect = H5MF_sect_new(cls->type, sect_addr, sect_size)))
303 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't initialize free space section")
304
305 /* Set return value */
306 ret_value = (H5FS_section_info_t *)sect;
307
308 done:
309 FUNC_LEAVE_NOAPI(ret_value)
310 } /* H5MF_sect_deserialize() */
311
312
313 /*-------------------------------------------------------------------------
314 * Function: H5MF_sect_valid
315 *
316 * Purpose: Check the validity of a section
317 *
318 * Return: Success: non-negative
319 * Failure: negative
320 *
321 * Programmer: Quincey Koziol
322 * Tuesday, January 8, 2008
323 *
324 *-------------------------------------------------------------------------
325 */
326 static herr_t
H5MF_sect_valid(const H5FS_section_class_t H5_ATTR_UNUSED * cls,const H5FS_section_info_t H5_ATTR_UNUSED * _sect,hid_t H5_ATTR_UNUSED dxpl_id)327 H5MF_sect_valid(const H5FS_section_class_t H5_ATTR_UNUSED *cls,
328 const H5FS_section_info_t
329 #ifdef NDEBUG
330 H5_ATTR_UNUSED
331 #endif /* NDEBUG */
332 *_sect, hid_t H5_ATTR_UNUSED dxpl_id)
333 {
334 #ifndef NDEBUG
335 const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* File free section */
336 #endif /* NDEBUG */
337
338 FUNC_ENTER_NOAPI_NOINIT_NOERR
339
340 /* Check arguments. */
341 HDassert(sect);
342
343 FUNC_LEAVE_NOAPI(SUCCEED)
344 } /* H5MF_sect_valid() */
345
346
347 /*-------------------------------------------------------------------------
348 * Function: H5MF_sect_split
349 *
350 * Purpose: Split SECT into 2 sections: fragment for alignment & the aligned section
351 * SECT's addr and size are updated to point to the aligned section
352 *
353 * Return: Success: the fragment for aligning sect
354 * Failure: null
355 *
356 * Programmer: Vailin Choi, July 29, 2008
357 *
358 *-------------------------------------------------------------------------
359 */
360 static H5FS_section_info_t *
H5MF_sect_split(H5FS_section_info_t * sect,hsize_t frag_size)361 H5MF_sect_split(H5FS_section_info_t *sect, hsize_t frag_size)
362 {
363 H5MF_free_section_t *ret_value; /* Return value */
364
365 FUNC_ENTER_NOAPI_NOINIT
366
367 /* Allocate space for new section */
368 if(NULL == (ret_value = H5MF_sect_new(sect->type, sect->addr, frag_size)))
369 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't initialize free space section")
370
371 /* Set new section's info */
372 sect->addr += frag_size;
373 sect->size -= frag_size;
374
375 done:
376 FUNC_LEAVE_NOAPI((H5FS_section_info_t *)ret_value)
377 } /* end H5MF_sect_split() */
378
379 /*
380 * "simple" section callbacks
381 */
382
383 /*-------------------------------------------------------------------------
384 * Function: H5MF_sect_simple_can_merge
385 *
386 * Purpose: Can two sections of this type merge?
387 *
388 * Note: Second section must be "after" first section
389 *
390 * Return: Success: non-negative (TRUE/FALSE)
391 * Failure: negative
392 *
393 * Programmer: Quincey Koziol
394 * Tuesday, January 8, 2008
395 *
396 *-------------------------------------------------------------------------
397 */
398 static htri_t
H5MF_sect_simple_can_merge(const H5FS_section_info_t * _sect1,const H5FS_section_info_t * _sect2,void H5_ATTR_UNUSED * _udata)399 H5MF_sect_simple_can_merge(const H5FS_section_info_t *_sect1,
400 const H5FS_section_info_t *_sect2, void H5_ATTR_UNUSED *_udata)
401 {
402 const H5MF_free_section_t *sect1 = (const H5MF_free_section_t *)_sect1; /* File free section */
403 const H5MF_free_section_t *sect2 = (const H5MF_free_section_t *)_sect2; /* File free section */
404 htri_t ret_value = FAIL; /* Return value */
405
406 FUNC_ENTER_NOAPI_NOINIT_NOERR
407
408 /* Check arguments. */
409 HDassert(sect1);
410 HDassert(sect2);
411 HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
412 HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
413
414 /* Check if second section adjoins first section */
415 ret_value = H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
416
417 FUNC_LEAVE_NOAPI(ret_value)
418 } /* H5MF_sect_simple_can_merge() */
419
420
421 /*-------------------------------------------------------------------------
422 * Function: H5MF_sect_simple_merge
423 *
424 * Purpose: Merge two sections of this type
425 *
426 * Note: Second section always merges into first node
427 *
428 * Return: Success: non-negative
429 * Failure: negative
430 *
431 * Programmer: Quincey Koziol
432 * Tuesday, January 8, 2008
433 *
434 *-------------------------------------------------------------------------
435 */
436 static herr_t
H5MF_sect_simple_merge(H5FS_section_info_t ** _sect1,H5FS_section_info_t * _sect2,void H5_ATTR_UNUSED * _udata)437 H5MF_sect_simple_merge(H5FS_section_info_t **_sect1, H5FS_section_info_t *_sect2,
438 void H5_ATTR_UNUSED *_udata)
439 {
440 H5MF_free_section_t **sect1 = (H5MF_free_section_t **)_sect1; /* File free section */
441 H5MF_free_section_t *sect2 = (H5MF_free_section_t *)_sect2; /* File free section */
442 herr_t ret_value = SUCCEED; /* Return value */
443
444 FUNC_ENTER_NOAPI_NOINIT
445
446 /* Check arguments. */
447 HDassert(sect1);
448 HDassert((*sect1)->sect_info.type == H5MF_FSPACE_SECT_SIMPLE);
449 HDassert(sect2);
450 HDassert(sect2->sect_info.type == H5MF_FSPACE_SECT_SIMPLE);
451 HDassert(H5F_addr_eq((*sect1)->sect_info.addr + (*sect1)->sect_info.size, sect2->sect_info.addr));
452
453 /* Add second section's size to first section */
454 (*sect1)->sect_info.size += sect2->sect_info.size;
455
456 /* Get rid of second section */
457 if(H5MF_sect_free((H5FS_section_info_t *)sect2) < 0)
458 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free section node")
459
460 done:
461 FUNC_LEAVE_NOAPI(ret_value)
462 } /* H5MF_sect_simple_merge() */
463
464
465 /*-------------------------------------------------------------------------
466 * Function: H5MF_sect_simple_can_shrink
467 *
468 * Purpose: Can this section shrink the container?
469 *
470 * Return: Success: non-negative (TRUE/FALSE)
471 * Failure: negative
472 *
473 * Programmer: Quincey Koziol
474 * Tuesday, January 8, 2008
475 *
476 *-------------------------------------------------------------------------
477 */
478 static htri_t
H5MF_sect_simple_can_shrink(const H5FS_section_info_t * _sect,void * _udata)479 H5MF_sect_simple_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
480 {
481 const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* File free section */
482 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
483 haddr_t eoa; /* End of address space in the file */
484 haddr_t end; /* End of section to extend */
485 htri_t ret_value = FAIL; /* Return value */
486
487 FUNC_ENTER_NOAPI_NOINIT
488
489 /* Check arguments. */
490 HDassert(sect);
491 HDassert(udata);
492 HDassert(udata->f);
493
494 /* Retrieve the end of the file's address space */
495 if(HADDR_UNDEF == (eoa = H5F_get_eoa(udata->f, udata->alloc_type)))
496 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
497
498 /* Compute address of end of section to check */
499 end = sect->sect_info.addr + sect->sect_info.size;
500
501 /* Check if the section is exactly at the end of the allocated space in the file */
502 if(H5F_addr_eq(end, eoa)) {
503 /* Set the shrinking type */
504 udata->shrink = H5MF_SHRINK_EOA;
505 #ifdef H5MF_ALLOC_DEBUG_MORE
506 HDfprintf(stderr, "%s: section {%a, %Hu}, shrinks file, eoa = %a\n", FUNC, sect->sect_info.addr, sect->sect_info.size, eoa);
507 #endif /* H5MF_ALLOC_DEBUG_MORE */
508
509 /* Indicate shrinking can occur */
510 HGOTO_DONE(TRUE)
511 } /* end if */
512 else {
513 /* Shrinking can't occur if the 'eoa_shrink_only' flag is set and we're not shrinking the EOA */
514 if(udata->allow_eoa_shrink_only)
515 HGOTO_DONE(FALSE)
516
517 /* Check if this section is allowed to merge with metadata aggregation block */
518 if(udata->f->shared->fs_aggr_merge[udata->alloc_type] & H5F_FS_MERGE_METADATA) {
519 htri_t status; /* Status from aggregator adjoin */
520
521 /* See if section can absorb the aggregator & vice versa */
522 if((status = H5MF_aggr_can_absorb(udata->f, &(udata->f->shared->meta_aggr), sect, &(udata->shrink))) < 0)
523 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "error merging section with aggregation block")
524 else if(status > 0) {
525 /* Set the aggregator to operate on */
526 udata->aggr = &(udata->f->shared->meta_aggr);
527 #ifdef H5MF_ALLOC_DEBUG_MORE
528 HDfprintf(stderr, "%s: section {%a, %Hu}, adjoins metadata aggregator\n", FUNC, sect->sect_info.addr, sect->sect_info.size);
529 #endif /* H5MF_ALLOC_DEBUG_MORE */
530
531 /* Indicate shrinking can occur */
532 HGOTO_DONE(TRUE)
533 } /* end if */
534 } /* end if */
535
536 /* Check if this section is allowed to merge with small 'raw' aggregation block */
537 if(udata->f->shared->fs_aggr_merge[udata->alloc_type] & H5F_FS_MERGE_RAWDATA) {
538 htri_t status; /* Status from aggregator adjoin */
539
540 /* See if section can absorb the aggregator & vice versa */
541 if((status = H5MF_aggr_can_absorb(udata->f, &(udata->f->shared->sdata_aggr), sect, &(udata->shrink))) < 0)
542 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "error merging section with aggregation block")
543 else if(status > 0) {
544 /* Set the aggregator to operate on */
545 udata->aggr = &(udata->f->shared->sdata_aggr);
546 #ifdef H5MF_ALLOC_DEBUG_MORE
547 HDfprintf(stderr, "%s: section {%a, %Hu}, adjoins small data aggregator\n", FUNC, sect->sect_info.addr, sect->sect_info.size);
548 #endif /* H5MF_ALLOC_DEBUG_MORE */
549
550 /* Indicate shrinking can occur */
551 HGOTO_DONE(TRUE)
552 } /* end if */
553 } /* end if */
554 } /* end else */
555
556 /* Set return value */
557 ret_value = FALSE;
558
559 done:
560 FUNC_LEAVE_NOAPI(ret_value)
561 } /* H5MF_sect_simple_can_shrink() */
562
563
564 /*-------------------------------------------------------------------------
565 * Function: H5MF_sect_simple_shrink
566 *
567 * Purpose: Shrink container with section
568 *
569 * Return: Success: non-negative
570 * Failure: negative
571 *
572 * Programmer: Quincey Koziol
573 * Tuesday, January 8, 2008
574 *
575 *-------------------------------------------------------------------------
576 */
577 static herr_t
H5MF_sect_simple_shrink(H5FS_section_info_t ** _sect,void * _udata)578 H5MF_sect_simple_shrink(H5FS_section_info_t **_sect, void *_udata)
579 {
580 H5MF_free_section_t **sect = (H5MF_free_section_t **)_sect; /* File free section */
581 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
582 herr_t ret_value = SUCCEED; /* Return value */
583
584 FUNC_ENTER_NOAPI_NOINIT
585
586 /* Check arguments. */
587 HDassert(sect);
588 HDassert(udata);
589 HDassert(udata->f);
590
591 /* Check for shrinking file */
592 if(H5MF_SHRINK_EOA == udata->shrink) {
593 /* Sanity check */
594 HDassert(H5F_INTENT(udata->f) & H5F_ACC_RDWR);
595
596 /* Release section's space at EOA */
597 if(H5F_free(udata->f, udata->dxpl_id, udata->alloc_type, (*sect)->sect_info.addr, (*sect)->sect_info.size) < 0)
598 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "driver free request failed")
599 } /* end if */
600 else {
601 /* Sanity check */
602 HDassert(udata->aggr);
603
604 /* Absorb the section into the aggregator or vice versa */
605 if(H5MF_aggr_absorb(udata->f, udata->aggr, *sect, udata->allow_sect_absorb) < 0)
606 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTMERGE, FAIL, "can't absorb section into aggregator or vice versa")
607 } /* end else */
608
609 /* Check for freeing section */
610 if(udata->shrink != H5MF_SHRINK_SECT_ABSORB_AGGR) {
611 /* Free section */
612 if(H5MF_sect_free((H5FS_section_info_t *)*sect) < 0)
613 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
614
615 /* Mark section as freed, for free space manager */
616 *sect = NULL;
617 } /* end if */
618
619 done:
620 FUNC_LEAVE_NOAPI(ret_value)
621 } /* H5MF_sect_simple_shrink() */
622
623 /*
624 * "small" section callbacks
625 */
626
627
628 /*-------------------------------------------------------------------------
629 * Function: H5MF_sect_small_add
630 *
631 * Purpose: Perform actions on a small "meta" action before adding it to the free space manager:
632 * 1) Drop the section if it is at page end and its size <= page end threshold
633 * 2) Adjust section size to include page end threshold if
634 * (section size + threshold) is at page end
635 *
636 * Return: Success: non-negative
637 * Failure: negative
638 *
639 * Programmer: Vailin Choi; Dec 2012
640 *
641 *-------------------------------------------------------------------------
642 */
643 static herr_t
H5MF_sect_small_add(H5FS_section_info_t ** _sect,unsigned * flags,void * _udata)644 H5MF_sect_small_add(H5FS_section_info_t **_sect, unsigned *flags, void *_udata)
645 {
646 H5MF_free_section_t **sect = (H5MF_free_section_t **)_sect; /* Fractal heap free section */
647 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
648 haddr_t sect_end;
649 hsize_t rem, prem;
650 herr_t ret_value = SUCCEED; /* Return value */
651
652 FUNC_ENTER_NOAPI_NOINIT
653
654 #ifdef H5MF_ALLOC_DEBUG_MORE
655 HDfprintf(stderr, "%s: Entering, section {%a, %Hu}\n", FUNC, (*sect)->sect_info.addr, (*sect)->sect_info.size);
656 #endif /* H5MF_ALLOC_DEBUG_MORE */
657
658 /* Do not adjust the section raw data or global heap data */
659 if(udata->alloc_type == H5FD_MEM_DRAW || udata->alloc_type == H5FD_MEM_GHEAP)
660 HGOTO_DONE(ret_value);
661
662 sect_end = (*sect)->sect_info.addr + (*sect)->sect_info.size;
663 rem = sect_end % udata->f->shared->fs_page_size;
664 prem = udata->f->shared->fs_page_size - rem;
665
666 /* Drop the section if it is at page end and its size is <= pgend threshold */
667 if(!rem && (*sect)->sect_info.size <= H5F_PGEND_META_THRES(udata->f) && (*flags & H5FS_ADD_RETURNED_SPACE)) {
668 if(H5MF_sect_free((H5FS_section_info_t *)(*sect)) < 0)
669 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free section node")
670 *sect = NULL;
671 *flags &= (unsigned)~H5FS_ADD_RETURNED_SPACE;
672 *flags |= H5FS_PAGE_END_NO_ADD;
673 #ifdef H5MF_ALLOC_DEBUG_MORE
674 HDfprintf(stderr, "%s: section is dropped\n", FUNC);
675 #endif /* H5MF_ALLOC_DEBUG_MORE */
676 } /* end if */
677 /* Adjust the section if it is not at page end but its size + pgend threshold is at page end */
678 else
679 if(prem <= H5F_PGEND_META_THRES(udata->f)) {
680 (*sect)->sect_info.size += prem;
681 #ifdef H5MF_ALLOC_DEBUG_MORE
682 HDfprintf(stderr, "%s: section is adjusted {%a, %Hu}\n", FUNC, (*sect)->sect_info.addr, (*sect)->sect_info.size);
683 #endif /* H5MF_ALLOC_DEBUG_MORE */
684 } /* end if */
685
686 done:
687 FUNC_LEAVE_NOAPI(ret_value)
688 } /* H5MF_sect_small_add() */
689
690
691 /*-------------------------------------------------------------------------
692 * Function: H5MF_sect_small_can_shrink
693 *
694 * Purpose: Can this section shrink the container?
695 *
696 * Note: A small section is allowed to shrink only at closing.
697 *
698 * Return: Success: non-negative (TRUE/FALSE)
699 * Failure: negative
700 *
701 * Programmer: Vailin Choi; Dec 2012
702 *
703 *-------------------------------------------------------------------------
704 */
705 static htri_t
H5MF_sect_small_can_shrink(const H5FS_section_info_t * _sect,void * _udata)706 H5MF_sect_small_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
707 {
708 const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* File free section */
709 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
710 haddr_t eoa; /* End of address space in the file */
711 haddr_t end; /* End of section to extend */
712 htri_t ret_value = FALSE; /* Return value */
713
714 FUNC_ENTER_NOAPI_NOINIT
715
716 /* Check arguments. */
717 HDassert(sect);
718 HDassert(udata);
719 HDassert(udata->f);
720
721 /* Retrieve the end of the file's address space */
722 if(HADDR_UNDEF == (eoa = H5FD_get_eoa(udata->f->shared->lf, udata->alloc_type)))
723 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
724
725 /* Compute address of end of section to check */
726 end = sect->sect_info.addr + sect->sect_info.size;
727
728 /* Check if the section is exactly at the end of the allocated space in the file */
729 if(H5F_addr_eq(end, eoa) && sect->sect_info.size == udata->f->shared->fs_page_size) {
730 udata->shrink = H5MF_SHRINK_EOA;
731
732 #ifdef H5MF_ALLOC_DEBUG_MORE
733 HDfprintf(stderr, "%s: section {%a, %Hu}, shrinks file, eoa = %a\n", FUNC, sect->sect_info.addr, sect->sect_info.size, eoa);
734 #endif /* H5MF_ALLOC_DEBUG_MORE */
735
736 /* Indicate shrinking can occur */
737 HGOTO_DONE(TRUE)
738 } /* end if */
739
740 done:
741 FUNC_LEAVE_NOAPI(ret_value)
742 } /* H5MF_sect_small_can_shrink() */
743
744
745 /*-------------------------------------------------------------------------
746 * Function: H5MF_sect_small_shrink
747 *
748 * Purpose: Shrink container with section
749 *
750 * Return: Success: non-negative
751 * Failure: negative
752 *
753 * Programmer: Vailin Choi; Dec 2012
754 *
755 *-------------------------------------------------------------------------
756 */
757 static herr_t
H5MF_sect_small_shrink(H5FS_section_info_t ** _sect,void * _udata)758 H5MF_sect_small_shrink(H5FS_section_info_t **_sect, void *_udata)
759 {
760 H5MF_free_section_t **sect = (H5MF_free_section_t **)_sect; /* File free section */
761 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
762 herr_t ret_value = SUCCEED; /* Return value */
763
764 FUNC_ENTER_NOAPI_NOINIT
765
766 /* Check arguments. */
767 HDassert(sect);
768 HDassert((*sect)->sect_info.type == H5MF_FSPACE_SECT_SMALL);
769 HDassert(udata);
770 HDassert(udata->f);
771 HDassert(udata->shrink == H5MF_SHRINK_EOA);
772 HDassert(H5F_INTENT(udata->f) & H5F_ACC_RDWR);
773
774 /* Release section's space at EOA */
775 if(H5F_free(udata->f, udata->dxpl_id, udata->alloc_type, (*sect)->sect_info.addr, (*sect)->sect_info.size) < 0)
776 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "driver free request failed")
777
778 /* Free section */
779 if(H5MF_sect_free((H5FS_section_info_t *)*sect) < 0)
780 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
781
782 /* Mark section as freed, for free space manager */
783 *sect = NULL;
784
785 done:
786 FUNC_LEAVE_NOAPI(ret_value)
787 } /* H5MF_sect_small_shrink() */
788
789
790 /*-------------------------------------------------------------------------
791 * Function: H5MF_sect_small_can_merge
792 *
793 * Purpose: Can two sections of this type merge?
794 *
795 * Note: Second section must be "after" first section
796 * The "merged" section cannot cross page boundary.
797 *
798 * Return: Success: non-negative (TRUE/FALSE)
799 * Failure: negative
800 *
801 * Programmer: Vailin Choi; Dec 2012
802 *
803 *-------------------------------------------------------------------------
804 */
805 static htri_t
H5MF_sect_small_can_merge(const H5FS_section_info_t * _sect1,const H5FS_section_info_t * _sect2,void * _udata)806 H5MF_sect_small_can_merge(const H5FS_section_info_t *_sect1,
807 const H5FS_section_info_t *_sect2, void *_udata)
808 {
809 const H5MF_free_section_t *sect1 = (const H5MF_free_section_t *)_sect1; /* File free section */
810 const H5MF_free_section_t *sect2 = (const H5MF_free_section_t *)_sect2; /* File free section */
811 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
812 htri_t ret_value = FALSE; /* Return value */
813
814 FUNC_ENTER_NOAPI_NOINIT_NOERR
815
816 /* Check arguments. */
817 HDassert(sect1);
818 HDassert(sect2);
819 HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
820 HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
821
822 /* Check if second section adjoins first section */
823 ret_value = H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
824 if(ret_value > 0)
825 /* If they are on different pages, couldn't merge */
826 if((sect1->sect_info.addr / udata->f->shared->fs_page_size) != (((sect2->sect_info.addr + sect2->sect_info.size - 1) / udata->f->shared->fs_page_size)))
827 ret_value = FALSE;
828
829 #ifdef H5MF_ALLOC_DEBUG_MORE
830 HDfprintf(stderr, "%s: Leaving: ret_value = %t\n", FUNC, ret_value);
831 #endif /* H5MF_ALLOC_DEBUG_MORE */
832
833 FUNC_LEAVE_NOAPI(ret_value)
834 } /* H5MF_sect_small_can_merge() */
835
836
837 /*-------------------------------------------------------------------------
838 * Function: H5MF_sect_small_merge
839 *
840 * Purpose: Merge two sections of this type
841 *
842 * Note: Second section always merges into first node.
843 * If the size of the "merged" section is equal to file space page size,
844 * free the section.
845 *
846 * Return: Success: non-negative
847 * Failure: negative
848 *
849 * Programmer: Vailin Choi; Dec 2012
850 *
851 *-------------------------------------------------------------------------
852 */
853 static herr_t
H5MF_sect_small_merge(H5FS_section_info_t ** _sect1,H5FS_section_info_t * _sect2,void * _udata)854 H5MF_sect_small_merge(H5FS_section_info_t **_sect1, H5FS_section_info_t *_sect2,
855 void *_udata)
856 {
857 H5MF_free_section_t **sect1 = (H5MF_free_section_t **)_sect1; /* File free section */
858 H5MF_free_section_t *sect2 = (H5MF_free_section_t *)_sect2; /* File free section */
859 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
860 herr_t ret_value = SUCCEED; /* Return value */
861
862 FUNC_ENTER_NOAPI_NOINIT
863
864 /* Check arguments. */
865 HDassert(sect1);
866 HDassert((*sect1)->sect_info.type == H5MF_FSPACE_SECT_SMALL);
867 HDassert(sect2);
868 HDassert(sect2->sect_info.type == H5MF_FSPACE_SECT_SMALL);
869 HDassert(H5F_addr_eq((*sect1)->sect_info.addr + (*sect1)->sect_info.size, sect2->sect_info.addr));
870
871 /* Add second section's size to first section */
872 (*sect1)->sect_info.size += sect2->sect_info.size;
873
874 if((*sect1)->sect_info.size == udata->f->shared->fs_page_size) {
875 if(H5MF_xfree(udata->f, udata->alloc_type, udata->dxpl_id, (*sect1)->sect_info.addr, (*sect1)->sect_info.size) < 0)
876 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't free merged section")
877
878 /* Need to free possible metadata page in the PB cache */
879 /* This is in response to the data corruption bug from fheap.c with page buffering + page strategy */
880 /* Note: Large metadata page bypasses the PB cache */
881 /* Note: Update of raw data page (large or small sized) is handled by the PB cache */
882 if(udata->f->shared->page_buf != NULL && udata->alloc_type != H5FD_MEM_DRAW)
883 if(H5PB_remove_entry(udata->f, (*sect1)->sect_info.addr) < 0)
884 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't free merged section")
885
886 if(H5MF_sect_free((H5FS_section_info_t *)(*sect1)) < 0)
887 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free section node")
888 *sect1 = NULL;
889 } /* end if */
890
891 /* Get rid of second section */
892 if(H5MF_sect_free((H5FS_section_info_t *)sect2) < 0)
893 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free section node")
894
895 done:
896 FUNC_LEAVE_NOAPI(ret_value)
897 } /* H5MF_sect_small_merge() */
898
899 /*
900 * "Large" section callbacks
901 */
902
903
904 /*-------------------------------------------------------------------------
905 * Function: H5MF_sect_large_can_merge (same as H5MF_sect_simple_can_merge)
906 *
907 * Purpose: Can two sections of this type merge?
908 *
909 * Note: Second section must be "after" first section
910 *
911 * Return: Success: non-negative (TRUE/FALSE)
912 * Failure: negative
913 *
914 * Programmer: Vailin Choi; Dec 2012
915 *
916 *-------------------------------------------------------------------------
917 */
918 static htri_t
H5MF_sect_large_can_merge(const H5FS_section_info_t * _sect1,const H5FS_section_info_t * _sect2,void H5_ATTR_UNUSED * _udata)919 H5MF_sect_large_can_merge(const H5FS_section_info_t *_sect1,
920 const H5FS_section_info_t *_sect2, void H5_ATTR_UNUSED *_udata)
921 {
922 const H5MF_free_section_t *sect1 = (const H5MF_free_section_t *)_sect1; /* File free section */
923 const H5MF_free_section_t *sect2 = (const H5MF_free_section_t *)_sect2; /* File free section */
924 htri_t ret_value = FALSE; /* Return value */
925
926 FUNC_ENTER_NOAPI_NOINIT_NOERR
927
928 /* Check arguments. */
929 HDassert(sect1);
930 HDassert(sect2);
931 HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
932 HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
933
934 ret_value = H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr);
935
936 #ifdef H5MF_ALLOC_DEBUG_MORE
937 HDfprintf(stderr, "%s: Leaving: ret_value = %t\n", FUNC, ret_value);
938 #endif /* H5MF_ALLOC_DEBUG_MORE */
939
940 FUNC_LEAVE_NOAPI(ret_value)
941 } /* H5MF_sect_large_can_merge() */
942
943
944 /*-------------------------------------------------------------------------
945 * Function: H5MF_sect_large_merge (same as H5MF_sect_simple_merge)
946 *
947 * Purpose: Merge two sections of this type
948 *
949 * Note: Second section always merges into first node
950 *
951 * Return: Success: non-negative
952 * Failure: negative
953 *
954 * Programmer: Vailin Choi; Dec 2012
955 *
956 *-------------------------------------------------------------------------
957 */
958 static herr_t
H5MF_sect_large_merge(H5FS_section_info_t ** _sect1,H5FS_section_info_t * _sect2,void H5_ATTR_UNUSED * _udata)959 H5MF_sect_large_merge(H5FS_section_info_t **_sect1, H5FS_section_info_t *_sect2,
960 void H5_ATTR_UNUSED *_udata)
961 {
962 H5MF_free_section_t **sect1 = (H5MF_free_section_t **)_sect1; /* File free section */
963 H5MF_free_section_t *sect2 = (H5MF_free_section_t *)_sect2; /* File free section */
964 herr_t ret_value = SUCCEED; /* Return value */
965
966 FUNC_ENTER_NOAPI_NOINIT
967
968 /* Check arguments. */
969 HDassert(sect1);
970 HDassert((*sect1)->sect_info.type == H5MF_FSPACE_SECT_LARGE);
971 HDassert(sect2);
972 HDassert(sect2->sect_info.type == H5MF_FSPACE_SECT_LARGE);
973 HDassert(H5F_addr_eq((*sect1)->sect_info.addr + (*sect1)->sect_info.size, sect2->sect_info.addr));
974
975 /* Add second section's size to first section */
976 (*sect1)->sect_info.size += sect2->sect_info.size;
977
978 /* Get rid of second section */
979 if(H5MF_sect_free((H5FS_section_info_t *)sect2) < 0)
980 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free section node")
981
982 done:
983 FUNC_LEAVE_NOAPI(ret_value)
984 } /* H5MF_sect_large_merge() */
985
986
987 /*-------------------------------------------------------------------------
988 * Function: H5MF_sect_large_can_shrink
989 *
990 * Purpose: Can this section shrink the container?
991 *
992 * Return: Success: non-negative (TRUE/FALSE)
993 * Failure: negative
994 *
995 * Programmer: Vailin Choi; Dec 2012
996 *
997 *-------------------------------------------------------------------------
998 */
999 static htri_t
H5MF_sect_large_can_shrink(const H5FS_section_info_t * _sect,void * _udata)1000 H5MF_sect_large_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
1001 {
1002 const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* File free section */
1003 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
1004 haddr_t eoa; /* End of address space in the file */
1005 haddr_t end; /* End of section to extend */
1006 htri_t ret_value = FALSE; /* Return value */
1007
1008 FUNC_ENTER_NOAPI_NOINIT
1009
1010 /* Check arguments. */
1011 HDassert(sect);
1012 HDassert(sect->sect_info.type == H5MF_FSPACE_SECT_LARGE);
1013 HDassert(udata);
1014 HDassert(udata->f);
1015
1016 /* Retrieve the end of the file's address space */
1017 if(HADDR_UNDEF == (eoa = H5FD_get_eoa(udata->f->shared->lf, udata->alloc_type)))
1018 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "driver get_eoa request failed")
1019
1020 /* Compute address of end of section to check */
1021 end = sect->sect_info.addr + sect->sect_info.size;
1022
1023 /* Check if the section is exactly at the end of the allocated space in the file */
1024 if(H5F_addr_eq(end, eoa) && sect->sect_info.size >= udata->f->shared->fs_page_size) {
1025 /* Set the shrinking type */
1026 udata->shrink = H5MF_SHRINK_EOA;
1027 #ifdef H5MF_ALLOC_DEBUG_MORE
1028 HDfprintf(stderr, "%s: section {%a, %Hu}, shrinks file, eoa = %a\n", FUNC, sect->sect_info.addr, sect->sect_info.size, eoa);
1029 #endif /* H5MF_ALLOC_DEBUG_MORE */
1030
1031 /* Indicate shrinking can occur */
1032 HGOTO_DONE(TRUE)
1033 } /* end if */
1034
1035 done:
1036 FUNC_LEAVE_NOAPI(ret_value)
1037 } /* H5MF_sect_large_can_shrink() */
1038
1039
1040 /*-------------------------------------------------------------------------
1041 * Function: H5MF_sect_large_shrink
1042 *
1043 * Purpose: Shrink a large-sized section
1044 *
1045 * Return: Success: non-negative
1046 * Failure: negative
1047 *
1048 * Programmer: Vailin Choi; Dec 2012
1049 *
1050 *-------------------------------------------------------------------------
1051 */
1052 static herr_t
H5MF_sect_large_shrink(H5FS_section_info_t ** _sect,void * _udata)1053 H5MF_sect_large_shrink(H5FS_section_info_t **_sect, void *_udata)
1054 {
1055 H5MF_free_section_t **sect = (H5MF_free_section_t **)_sect; /* File free section */
1056 H5MF_sect_ud_t *udata = (H5MF_sect_ud_t *)_udata; /* User data for callback */
1057 hsize_t frag_size = 0; /* Fragment size */
1058 herr_t ret_value = SUCCEED; /* Return value */
1059
1060 FUNC_ENTER_NOAPI_NOINIT
1061
1062 /* Check arguments. */
1063 HDassert(sect);
1064 HDassert((*sect)->sect_info.type == H5MF_FSPACE_SECT_LARGE);
1065 HDassert(udata);
1066 HDassert(udata->f);
1067 HDassert(udata->shrink == H5MF_SHRINK_EOA);
1068 HDassert(H5F_INTENT(udata->f) & H5F_ACC_RDWR);
1069 HDassert(H5F_PAGED_AGGR(udata->f));
1070
1071 /* Calculate possible mis-aligned fragment */
1072 H5MF_EOA_MISALIGN(udata->f, (*sect)->sect_info.addr, udata->f->shared->fs_page_size, frag_size);
1073
1074 /* Free full pages from EOA */
1075 /* Retain partial page in the free-space manager so as to keep EOA at page boundary */
1076 if(H5F_free(udata->f, udata->dxpl_id, udata->alloc_type, (*sect)->sect_info.addr+frag_size, (*sect)->sect_info.size-frag_size) < 0)
1077 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "driver free request failed")
1078
1079 if(frag_size) /* Adjust section size for the partial page */
1080 (*sect)->sect_info.size = frag_size;
1081 else {
1082 /* Free section */
1083 if(H5MF_sect_free((H5FS_section_info_t *)*sect) < 0)
1084 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't free simple section node")
1085
1086 /* Mark section as freed, for free space manager */
1087 *sect = NULL;
1088 } /* end else */
1089
1090 done:
1091 FUNC_LEAVE_NOAPI(ret_value)
1092 } /* H5MF_sect_large_shrink() */
1093
1094