2006-05-15 12:35:53 +08:00
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
2007-02-07 22:56:24 +08:00
|
|
|
|
* Copyright by The HDF Group. *
|
2006-05-15 12:35:53 +08:00
|
|
|
|
* Copyright by the Board of Trustees of the University of Illinois. *
|
|
|
|
|
* All rights reserved. *
|
|
|
|
|
* *
|
|
|
|
|
* This file is part of HDF5. The full HDF5 copyright notice, including *
|
|
|
|
|
* terms governing use, modification, and redistribution, is contained in *
|
|
|
|
|
* the files COPYING and Copyright.html. COPYING can be found at the root *
|
|
|
|
|
* of the source code distribution tree; Copyright.html can be found at the *
|
|
|
|
|
* root level of an installed copy of the electronic HDF5 document set and *
|
|
|
|
|
* is linked from the top-level documents page. It can also be found at *
|
2007-02-07 22:56:24 +08:00
|
|
|
|
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
|
|
|
|
|
* access to either file, you may request a copy from help@hdfgroup.org. *
|
2006-05-15 12:35:53 +08:00
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
|
|
|
|
|
2006-07-22 09:55:14 +08:00
|
|
|
|
/*
|
|
|
|
|
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
|
2006-05-15 12:35:53 +08:00
|
|
|
|
* Tuesday, May 2, 2006
|
|
|
|
|
*
|
2006-07-01 21:58:14 +08:00
|
|
|
|
* Purpose: Free space tracking functions.
|
2006-05-15 12:35:53 +08:00
|
|
|
|
*
|
|
|
|
|
* Note: (Used to be in the H5HFflist.c file, prior to the date above)
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/****************/
|
|
|
|
|
/* Module Setup */
|
|
|
|
|
/****************/
|
|
|
|
|
|
|
|
|
|
#define H5FS_PACKAGE /*suppress error about including H5FSpkg */
|
|
|
|
|
|
|
|
|
|
/***********/
|
|
|
|
|
/* Headers */
|
|
|
|
|
/***********/
|
|
|
|
|
#include "H5private.h" /* Generic Functions */
|
|
|
|
|
#include "H5Eprivate.h" /* Error handling */
|
|
|
|
|
#include "H5FSpkg.h" /* File free space */
|
|
|
|
|
#include "H5MFprivate.h" /* File memory management */
|
|
|
|
|
|
|
|
|
|
/****************/
|
|
|
|
|
/* Local Macros */
|
|
|
|
|
/****************/
|
|
|
|
|
|
2006-07-22 09:55:14 +08:00
|
|
|
|
|
2006-05-15 12:35:53 +08:00
|
|
|
|
/******************/
|
|
|
|
|
/* Local Typedefs */
|
|
|
|
|
/******************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/********************/
|
|
|
|
|
/* Package Typedefs */
|
|
|
|
|
/********************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/********************/
|
|
|
|
|
/* Local Prototypes */
|
|
|
|
|
/********************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*********************/
|
|
|
|
|
/* Package Variables */
|
|
|
|
|
/*********************/
|
|
|
|
|
|
|
|
|
|
/* Declare a free list to manage the H5FS_section_class_t sequence information */
|
|
|
|
|
H5FL_SEQ_DEFINE(H5FS_section_class_t);
|
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Declare a free list to manage the H5FS_t struct */
|
|
|
|
|
H5FL_DEFINE(H5FS_t);
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************/
|
|
|
|
|
/* Library Private Variables */
|
|
|
|
|
/*****************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************/
|
|
|
|
|
/* Local Variables */
|
|
|
|
|
/*******************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: H5FS_create
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Allocate & initialize file free space info
|
|
|
|
|
*
|
|
|
|
|
* Return: Success: Pointer to free space structure
|
|
|
|
|
*
|
|
|
|
|
* Failure: NULL
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Quincey Koziol
|
|
|
|
|
* Tuesday, March 7, 2006
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
H5FS_t *
|
|
|
|
|
H5FS_create(H5F_t *f, hid_t dxpl_id, haddr_t *fs_addr, const H5FS_create_t *fs_create,
|
2006-07-22 09:55:14 +08:00
|
|
|
|
size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata)
|
2006-05-15 12:35:53 +08:00
|
|
|
|
{
|
|
|
|
|
H5FS_t *fspace = NULL; /* New free space structure */
|
|
|
|
|
H5FS_t *ret_value; /* Return value */
|
|
|
|
|
|
|
|
|
|
FUNC_ENTER_NOAPI(H5FS_create, NULL)
|
[svn-r14353] Description:
- Add hash value for skip list string types, to reduce # of string
comparisons.
- Fixed bug with metadata/small data block aggregator adding size == 0
block into file free space list.
- Refactored metadata/small data block aggregator code into single set of
common routines.
- Changed block aggregator code to be smarter about releasing space in the
'other' block when the 'other' block has aggregated enough data.
Tested on:
FreeBSD/32 6.2 (duty) in debug mode
FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN,
in production mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
Mac OS X/32 10.4.10 (amazon) in debug mode
Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
2007-12-21 04:36:08 +08:00
|
|
|
|
#ifdef QAK
|
|
|
|
|
HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, nclasses);
|
|
|
|
|
#endif /* QAK */
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
|
|
|
|
/* Check arguments. */
|
|
|
|
|
HDassert(fs_addr);
|
|
|
|
|
HDassert(fs_create->shrink_percent);
|
|
|
|
|
HDassert(fs_create->shrink_percent < fs_create->expand_percent);
|
|
|
|
|
HDassert(fs_create->max_sect_size);
|
|
|
|
|
HDassert(nclasses == 0 || classes);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Allocate free space structure
|
|
|
|
|
*/
|
2006-08-03 00:44:44 +08:00
|
|
|
|
if(NULL == (fspace = H5FS_new(nclasses, classes, cls_init_udata)))
|
2006-05-15 12:35:53 +08:00
|
|
|
|
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space free list")
|
|
|
|
|
|
|
|
|
|
/* Allocate space for the free space header */
|
|
|
|
|
if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)H5FS_HEADER_SIZE(f))))
|
|
|
|
|
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for free space header")
|
|
|
|
|
*fs_addr = fspace->addr;
|
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Initialize creation information for free space manager */
|
|
|
|
|
fspace->client = fs_create->client;
|
|
|
|
|
fspace->shrink_percent = fs_create->shrink_percent;
|
|
|
|
|
fspace->expand_percent = fs_create->expand_percent;
|
|
|
|
|
fspace->max_sect_addr = fs_create->max_sect_addr;
|
|
|
|
|
fspace->max_sect_size = fs_create->max_sect_size;
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
2006-08-19 10:38:03 +08:00
|
|
|
|
/* Cache the new free space header (pinned) */
|
|
|
|
|
if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0)
|
2006-05-15 12:35:53 +08:00
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space header to cache")
|
|
|
|
|
|
2006-08-19 10:38:03 +08:00
|
|
|
|
/* Set the return value */
|
|
|
|
|
ret_value = fspace;
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
|
|
|
|
done:
|
2006-08-03 00:44:44 +08:00
|
|
|
|
if(!ret_value && fspace)
|
|
|
|
|
(void)H5FS_cache_hdr_dest(f, fspace);
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
|
|
|
} /* H5FS_create() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: H5FS_open
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Open an existing file free space info structure on disk
|
|
|
|
|
*
|
|
|
|
|
* Return: Success: Pointer to free space structure
|
|
|
|
|
*
|
|
|
|
|
* Failure: NULL
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Quincey Koziol
|
|
|
|
|
* Tuesday, May 2, 2006
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
H5FS_t *
|
2006-05-23 00:43:45 +08:00
|
|
|
|
H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr, size_t nclasses,
|
2006-07-22 09:55:14 +08:00
|
|
|
|
const H5FS_section_class_t *classes[], void *cls_init_udata)
|
2006-05-15 12:35:53 +08:00
|
|
|
|
{
|
2006-08-19 10:38:03 +08:00
|
|
|
|
H5FS_t *fspace = NULL; /* New free space structure */
|
|
|
|
|
H5FS_prot_t fs_prot; /* Information for protecting free space manager */
|
|
|
|
|
unsigned fspace_status = 0; /* Free space header's status in the metadata cache */
|
2006-05-15 12:35:53 +08:00
|
|
|
|
H5FS_t *ret_value; /* Return value */
|
|
|
|
|
|
|
|
|
|
FUNC_ENTER_NOAPI(H5FS_open, NULL)
|
|
|
|
|
#ifdef QAK
|
2007-08-14 21:33:14 +08:00
|
|
|
|
HDfprintf(stderr, "%s: Opening free space manager, nclasses = %Zu\n", FUNC, nclasses);
|
2006-05-15 12:35:53 +08:00
|
|
|
|
#endif /* QAK */
|
|
|
|
|
|
|
|
|
|
/* Check arguments. */
|
|
|
|
|
HDassert(H5F_addr_defined(fs_addr));
|
2006-08-03 00:44:44 +08:00
|
|
|
|
HDassert(nclasses);
|
|
|
|
|
HDassert(classes);
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
2006-08-19 10:38:03 +08:00
|
|
|
|
/* Initialize user data for protecting the free space manager */
|
|
|
|
|
fs_prot.nclasses = nclasses;
|
|
|
|
|
fs_prot.classes = classes;
|
|
|
|
|
fs_prot.cls_init_udata = cls_init_udata;
|
|
|
|
|
|
|
|
|
|
/* Protect the free space header */
|
2008-08-22 04:30:19 +08:00
|
|
|
|
if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_READ)))
|
2006-08-19 10:38:03 +08:00
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, NULL, "unable to load free space header")
|
2006-08-21 22:48:21 +08:00
|
|
|
|
#ifdef QAK
|
|
|
|
|
HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
|
|
|
|
|
HDfprintf(stderr, "%s: fspace->sect_size = %Hu\n", FUNC, fspace->sect_size);
|
|
|
|
|
HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu\n", FUNC, fspace->alloc_sect_size);
|
|
|
|
|
HDfprintf(stderr, "%s: fspace->sinfo = %p\n", FUNC, fspace->sinfo);
|
|
|
|
|
#endif /* QAK */
|
2006-08-19 10:38:03 +08:00
|
|
|
|
|
|
|
|
|
/* Check the free space header's status in the metadata cache */
|
|
|
|
|
if(H5AC_get_entry_status(f, fs_addr, &fspace_status) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, NULL, "unable to check metadata cache status for free space header")
|
|
|
|
|
|
|
|
|
|
/* If the free space header isn't already pinned, pin it now */
|
|
|
|
|
/* (could still be pinned from it's section info still hanging around in the cache) */
|
|
|
|
|
if(!(fspace_status & H5AC_ES__IS_PINNED)) {
|
|
|
|
|
/* Pin free space header in the cache */
|
|
|
|
|
if(H5AC_pin_protected_entry(f, fspace) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPIN, NULL, "unable to pin free space header")
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Unlock free space header, now pinned */
|
|
|
|
|
if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__NO_FLAGS_SET) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, NULL, "unable to release free space header")
|
|
|
|
|
|
|
|
|
|
/* Set return value */
|
|
|
|
|
ret_value = fspace;
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
|
|
|
|
} /* H5FS_open() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Function: H5FS_delete
|
2006-05-15 12:35:53 +08:00
|
|
|
|
*
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Purpose: Delete a free space manager on disk
|
2006-05-15 12:35:53 +08:00
|
|
|
|
*
|
|
|
|
|
* Return: Success: non-negative
|
|
|
|
|
*
|
|
|
|
|
* Failure: negative
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Quincey Koziol
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Tuesday, May 30, 2006
|
2006-05-15 12:35:53 +08:00
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
2006-08-03 00:44:44 +08:00
|
|
|
|
herr_t
|
|
|
|
|
H5FS_delete(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr)
|
2006-05-15 12:35:53 +08:00
|
|
|
|
{
|
2006-08-03 00:44:44 +08:00
|
|
|
|
H5FS_t *fspace = NULL; /* Free space header loaded from file */
|
2006-10-02 18:24:03 +08:00
|
|
|
|
H5FS_prot_t fs_prot; /* Temporary information for protecting free space header */
|
2006-05-15 12:35:53 +08:00
|
|
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
FUNC_ENTER_NOAPI(H5FS_delete, FAIL)
|
|
|
|
|
#ifdef QAK
|
|
|
|
|
HDfprintf(stderr, "%s: Deleting free space manager\n", FUNC);
|
|
|
|
|
#endif /* QAK */
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
|
|
|
|
/* Check arguments. */
|
2006-08-03 00:44:44 +08:00
|
|
|
|
HDassert(f);
|
|
|
|
|
HDassert(H5F_addr_defined(fs_addr));
|
|
|
|
|
|
2006-10-02 18:24:03 +08:00
|
|
|
|
/* Initialize user data for protecting the free space manager */
|
|
|
|
|
/* (no class information necessary for delete) */
|
|
|
|
|
fs_prot.nclasses = 0;
|
|
|
|
|
fs_prot.classes = NULL;
|
|
|
|
|
fs_prot.cls_init_udata = NULL;
|
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Protect the free space header */
|
2008-08-22 04:30:19 +08:00
|
|
|
|
if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_WRITE)))
|
2006-08-03 00:44:44 +08:00
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, FAIL, "unable to protect free space header")
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Delete serialized section storage, if there are any */
|
|
|
|
|
#ifdef QAK
|
2006-08-08 00:49:18 +08:00
|
|
|
|
HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
|
2006-08-03 00:44:44 +08:00
|
|
|
|
#endif /* QAK */
|
|
|
|
|
if(fspace->serial_sect_count > 0) {
|
2006-08-08 00:49:18 +08:00
|
|
|
|
unsigned sinfo_status = 0; /* Free space section info's status in the metadata cache */
|
|
|
|
|
|
|
|
|
|
/* Sanity check */
|
2006-08-03 00:44:44 +08:00
|
|
|
|
HDassert(H5F_addr_defined(fspace->sect_addr));
|
|
|
|
|
HDassert(fspace->sect_size > 0);
|
2006-08-08 00:49:18 +08:00
|
|
|
|
|
|
|
|
|
/* Check the free space section info's status in the metadata cache */
|
|
|
|
|
if(H5AC_get_entry_status(f, fspace->sect_addr, &sinfo_status) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space section info")
|
|
|
|
|
|
|
|
|
|
/* If the free space section info is in the cache, expunge it now */
|
|
|
|
|
if(sinfo_status & H5AC_ES__IN_CACHE) {
|
|
|
|
|
/* Sanity checks on direct block */
|
|
|
|
|
HDassert(!(sinfo_status & H5AC_ES__IS_PINNED));
|
|
|
|
|
HDassert(!(sinfo_status & H5AC_ES__IS_PROTECTED));
|
|
|
|
|
|
|
|
|
|
#ifdef QAK
|
|
|
|
|
HDfprintf(stderr, "%s: Expunging free space section info from cache\n", FUNC);
|
|
|
|
|
#endif /* QAK */
|
|
|
|
|
/* Evict the free space section info from the metadata cache */
|
|
|
|
|
if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove free space section info from cache")
|
|
|
|
|
#ifdef QAK
|
|
|
|
|
HDfprintf(stderr, "%s: Done expunging free space section info from cache\n", FUNC);
|
|
|
|
|
#endif /* QAK */
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Release the space in the file */
|
|
|
|
|
if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0)
|
2006-08-03 00:44:44 +08:00
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
|
2006-05-23 00:43:45 +08:00
|
|
|
|
} /* end if */
|
2006-08-03 00:44:44 +08:00
|
|
|
|
|
|
|
|
|
/* Release header's disk space */
|
|
|
|
|
if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, dxpl_id, fs_addr, (hsize_t)H5FS_HEADER_SIZE(f))<0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space header")
|
|
|
|
|
|
|
|
|
|
/* Release the free space header */
|
|
|
|
|
if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__DELETED_FLAG) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPROTECT, FAIL, "unable to release free space header")
|
|
|
|
|
fspace = NULL;
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
2006-08-03 00:44:44 +08:00
|
|
|
|
} /* H5FS_delete() */
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Function: H5FS_close
|
2006-05-23 00:43:45 +08:00
|
|
|
|
*
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Purpose: Destroy & deallocate free list structure, serializing sections
|
|
|
|
|
* in the bins
|
2006-05-23 00:43:45 +08:00
|
|
|
|
*
|
|
|
|
|
* Return: Success: non-negative
|
|
|
|
|
*
|
|
|
|
|
* Failure: negative
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Quincey Koziol
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Tuesday, March 7, 2006
|
2006-05-23 00:43:45 +08:00
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
2006-08-03 00:44:44 +08:00
|
|
|
|
herr_t
|
|
|
|
|
H5FS_close(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
|
2006-05-23 00:43:45 +08:00
|
|
|
|
{
|
|
|
|
|
herr_t ret_value = SUCCEED; /* Return value */
|
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
FUNC_ENTER_NOAPI(H5FS_close, FAIL)
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
|
|
|
|
/* Check arguments. */
|
2006-08-03 00:44:44 +08:00
|
|
|
|
HDassert(f);
|
2006-05-23 00:43:45 +08:00
|
|
|
|
HDassert(fspace);
|
2006-07-22 09:55:14 +08:00
|
|
|
|
#ifdef QAK
|
2007-08-15 02:41:40 +08:00
|
|
|
|
HDfprintf(stderr, "%s: Entering, fspace = %p, fspace->sinfo = %p\n", FUNC, fspace, fspace->sinfo);
|
2006-07-22 09:55:14 +08:00
|
|
|
|
#endif /* QAK */
|
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Check if section info is valid */
|
|
|
|
|
if(fspace->sinfo) {
|
|
|
|
|
HDassert(H5F_addr_defined(fspace->sect_addr));
|
2006-07-22 09:55:14 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Unpin the free space section info in the cache */
|
|
|
|
|
if(H5AC_unpin_entry(f, fspace->sinfo) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space section info")
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* If there aren't any sections being managed, free the space for the sections */
|
|
|
|
|
#ifdef QAK
|
|
|
|
|
HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_count);
|
|
|
|
|
#endif /* QAK */
|
|
|
|
|
if(fspace->tot_sect_count == 0) {
|
|
|
|
|
haddr_t old_addr; /* Old section info address */
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
HDassert(fspace->serial_sect_count == 0);
|
|
|
|
|
HDassert(fspace->ghost_sect_count == 0);
|
2006-07-22 09:55:14 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Free previous serialized sections disk space */
|
|
|
|
|
old_addr = fspace->sect_addr;
|
|
|
|
|
if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, old_addr, fspace->alloc_sect_size) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Reset section info */
|
|
|
|
|
fspace->sect_addr = HADDR_UNDEF;
|
|
|
|
|
fspace->alloc_sect_size = fspace->sect_size = 0;
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Mark free space header as dirty */
|
|
|
|
|
if(H5AC_mark_pinned_or_protected_entry_dirty(f, fspace) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Evict the section info from the metadata cache */
|
|
|
|
|
if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, old_addr) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTREMOVE, FAIL, "unable to remove free space section info from cache")
|
|
|
|
|
} /* end if */
|
2006-05-23 00:43:45 +08:00
|
|
|
|
} /* end if */
|
2006-08-03 00:44:44 +08:00
|
|
|
|
else {
|
2007-08-15 02:41:40 +08:00
|
|
|
|
unsigned sect_status = 0; /* Free space section's status in the metadata cache */
|
|
|
|
|
|
[svn-r14353] Description:
- Add hash value for skip list string types, to reduce # of string
comparisons.
- Fixed bug with metadata/small data block aggregator adding size == 0
block into file free space list.
- Refactored metadata/small data block aggregator code into single set of
common routines.
- Changed block aggregator code to be smarter about releasing space in the
'other' block when the 'other' block has aggregated enough data.
Tested on:
FreeBSD/32 6.2 (duty) in debug mode
FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN,
in production mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
Mac OS X/32 10.4.10 (amazon) in debug mode
Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
2007-12-21 04:36:08 +08:00
|
|
|
|
/* Check if we've allocated any section info in the file & if it's still in the cache */
|
|
|
|
|
if(H5F_addr_defined(fspace->sect_addr) && H5AC_get_entry_status(f, fspace->sect_addr, §_status) < 0)
|
2007-08-15 02:41:40 +08:00
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space header")
|
|
|
|
|
|
[svn-r14353] Description:
- Add hash value for skip list string types, to reduce # of string
comparisons.
- Fixed bug with metadata/small data block aggregator adding size == 0
block into file free space list.
- Refactored metadata/small data block aggregator code into single set of
common routines.
- Changed block aggregator code to be smarter about releasing space in the
'other' block when the 'other' block has aggregated enough data.
Tested on:
FreeBSD/32 6.2 (duty) in debug mode
FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN,
in production mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
Mac OS X/32 10.4.10 (amazon) in debug mode
Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
2007-12-21 04:36:08 +08:00
|
|
|
|
/* If this free list header's section info exists and is still in the
|
|
|
|
|
* cache, don't unpin the header - let the section info do it,
|
|
|
|
|
* when the section info is evicted from the cache. -QAK
|
2007-08-15 02:41:40 +08:00
|
|
|
|
*/
|
|
|
|
|
if(!(sect_status & H5AC_ES__IN_CACHE)) {
|
|
|
|
|
/* Unpin the free space header in the cache */
|
|
|
|
|
/* (the section info destructor would unpin it if the section info existed) */
|
|
|
|
|
if(H5AC_unpin_entry(f, fspace) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header")
|
|
|
|
|
} /* end if */
|
2006-08-03 00:44:44 +08:00
|
|
|
|
} /* end else */
|
|
|
|
|
|
|
|
|
|
/* Reset the header's pointer to the section info, so it will get pinned again
|
|
|
|
|
* if the free space header is still in the metadata cache when the free
|
|
|
|
|
* space manager is re-opened.
|
|
|
|
|
*/
|
|
|
|
|
fspace->sinfo = NULL;
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
2006-08-03 00:44:44 +08:00
|
|
|
|
} /* H5FS_close() */
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Function: H5FS_new
|
2006-05-23 00:43:45 +08:00
|
|
|
|
*
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Purpose: Create new free space manager structure
|
2006-05-23 00:43:45 +08:00
|
|
|
|
*
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Return: Success: non-NULL, pointer to new free space manager struct
|
|
|
|
|
* Failure: NULL
|
2006-05-23 00:43:45 +08:00
|
|
|
|
*
|
|
|
|
|
* Programmer: Quincey Koziol
|
2006-08-03 00:44:44 +08:00
|
|
|
|
* Monday, July 31, 2006
|
2006-05-23 00:43:45 +08:00
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
2006-08-03 00:44:44 +08:00
|
|
|
|
H5FS_t *
|
|
|
|
|
H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[],
|
|
|
|
|
void *cls_init_udata)
|
2006-05-23 00:43:45 +08:00
|
|
|
|
{
|
2006-08-03 00:44:44 +08:00
|
|
|
|
H5FS_t *fspace; /* Free space manager */
|
|
|
|
|
size_t u; /* Local index variable */
|
|
|
|
|
H5FS_t *ret_value; /* Return value */
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
FUNC_ENTER_NOAPI_NOINIT(H5FS_new)
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
|
|
|
|
/* Check arguments. */
|
2006-10-02 18:24:03 +08:00
|
|
|
|
HDassert(nclasses == 0 || (nclasses > 0 && classes));
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/*
|
|
|
|
|
* Allocate free space structure
|
|
|
|
|
*/
|
|
|
|
|
if(NULL == (fspace = H5FL_CALLOC(H5FS_t)))
|
|
|
|
|
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space free list")
|
2006-05-23 00:43:45 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Set immutable free list parameters */
|
|
|
|
|
fspace->nclasses = nclasses;
|
|
|
|
|
if(nclasses > 0) {
|
|
|
|
|
if(NULL == (fspace->sect_cls = H5FL_SEQ_MALLOC(H5FS_section_class_t, nclasses)))
|
|
|
|
|
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space section class array")
|
|
|
|
|
|
|
|
|
|
/* Initialize the section classes for this free space list */
|
|
|
|
|
for(u = 0; u < nclasses; u++) {
|
|
|
|
|
/* Make certain that section class type can be used as an array index into this array */
|
|
|
|
|
HDassert(u == classes[u]->type);
|
|
|
|
|
|
|
|
|
|
/* Copy the class information into the free space manager */
|
|
|
|
|
HDmemcpy(&fspace->sect_cls[u], classes[u], sizeof(H5FS_section_class_t));
|
|
|
|
|
|
|
|
|
|
/* Call the class initialization routine, if there is one */
|
|
|
|
|
if(fspace->sect_cls[u].init_cls)
|
|
|
|
|
if((fspace->sect_cls[u].init_cls)(&fspace->sect_cls[u], cls_init_udata) < 0)
|
|
|
|
|
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "unable to initialize section class")
|
|
|
|
|
} /* end for */
|
2006-05-15 12:35:53 +08:00
|
|
|
|
} /* end if */
|
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Initialize non-zero information for new free space manager */
|
|
|
|
|
fspace->addr = HADDR_UNDEF;
|
|
|
|
|
fspace->sect_addr = HADDR_UNDEF;
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
2006-08-03 00:44:44 +08:00
|
|
|
|
/* Set return value */
|
|
|
|
|
ret_value = fspace;
|
2006-05-15 12:35:53 +08:00
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value)
|
2006-08-03 00:44:44 +08:00
|
|
|
|
} /* H5FS_new() */
|
2006-07-01 21:58:14 +08:00
|
|
|
|
|
2006-07-22 09:55:14 +08:00
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
2007-07-18 03:35:09 +08:00
|
|
|
|
* Function: H5FS_size
|
2007-07-14 05:12:25 +08:00
|
|
|
|
*
|
|
|
|
|
* Purpose: Collect meta storage info used by the free space manager
|
|
|
|
|
*
|
|
|
|
|
* Return: Success: non-negative
|
|
|
|
|
* Failure: negative
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Vailin Choi
|
|
|
|
|
* June 19, 2007
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
2007-08-14 21:33:14 +08:00
|
|
|
|
H5FS_size(const H5F_t *f, const H5FS_t *fspace, hsize_t *meta_size)
|
2007-07-14 05:12:25 +08:00
|
|
|
|
{
|
2007-08-14 21:33:14 +08:00
|
|
|
|
FUNC_ENTER_NOAPI_NOFUNC(H5FS_size)
|
2007-07-18 03:35:09 +08:00
|
|
|
|
|
2007-07-14 05:12:25 +08:00
|
|
|
|
/*
|
|
|
|
|
* Check arguments.
|
|
|
|
|
*/
|
|
|
|
|
HDassert(f);
|
2007-08-14 21:33:14 +08:00
|
|
|
|
HDassert(fspace);
|
2007-07-14 05:12:25 +08:00
|
|
|
|
HDassert(meta_size);
|
|
|
|
|
|
2007-07-18 03:35:09 +08:00
|
|
|
|
/* Get the free space size info */
|
|
|
|
|
*meta_size += H5FS_HEADER_SIZE(f) + fspace->alloc_sect_size;
|
2007-07-14 05:12:25 +08:00
|
|
|
|
|
2007-08-14 21:33:14 +08:00
|
|
|
|
FUNC_LEAVE_NOAPI(SUCCEED)
|
2007-07-18 03:35:09 +08:00
|
|
|
|
} /* end H5FS_size() */
|
|
|
|
|
|
|
|
|
|
#ifdef H5FS_DEBUG
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
|
* Function: H5FS_assert
|
|
|
|
|
*
|
|
|
|
|
* Purpose: Verify that the free space manager is mostly sane
|
|
|
|
|
*
|
|
|
|
|
* Return: Non-negative on success, negative on failure
|
|
|
|
|
*
|
|
|
|
|
* Programmer: Quincey Koziol
|
|
|
|
|
* koziol@hdfgroup.org
|
|
|
|
|
* Jul 17 2006
|
|
|
|
|
*
|
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
herr_t
|
|
|
|
|
H5FS_assert(const H5FS_t *fspace)
|
|
|
|
|
{
|
|
|
|
|
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_assert)
|
|
|
|
|
#ifdef QAK
|
|
|
|
|
HDfprintf(stderr, "%s: fspace->hdr->tot_sect_count = %Hu\n", "H5FS_assert", fspace->hdr->tot_sect_count);
|
|
|
|
|
#endif /* QAK */
|
|
|
|
|
|
|
|
|
|
/* Sanity check sections */
|
|
|
|
|
H5FS_sect_assert(fspace);
|
|
|
|
|
|
|
|
|
|
/* General assumptions about the section size counts */
|
|
|
|
|
HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->serial_size_count);
|
|
|
|
|
HDassert(fspace->sinfo->tot_size_count >= fspace->sinfo->ghost_size_count);
|
|
|
|
|
|
|
|
|
|
/* General assumptions about the section counts */
|
|
|
|
|
HDassert(fspace->tot_sect_count >= fspace->serial_sect_count);
|
|
|
|
|
HDassert(fspace->tot_sect_count >= fspace->ghost_sect_count);
|
|
|
|
|
HDassert(fspace->tot_sect_count == (fspace->serial_sect_count + fspace->ghost_sect_count));
|
|
|
|
|
#ifdef QAK
|
|
|
|
|
HDassert(fspace->serial_sect_count > 0 || fspace->ghost_sect_count == 0);
|
|
|
|
|
#endif /* QAK */
|
|
|
|
|
|
|
|
|
|
FUNC_LEAVE_NOAPI(SUCCEED)
|
|
|
|
|
} /* end H5FS_assert() */
|
|
|
|
|
#endif /* H5FS_DEBUG */
|
|
|
|
|
|