Пример #1
0
/*-------------------------------------------------------------------------
 * Function:	H5O_chunk_protect
 *
 * Purpose:	Protect an object header chunk for modifications
 *
 * Return:	Success:	Non-negative
 *		Failure:	Negative
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Jul 17 2008
 *
 *-------------------------------------------------------------------------
 */
H5O_chunk_proxy_t *
H5O_chunk_protect(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx)
{
    H5O_chunk_proxy_t *chk_proxy = NULL;        /* Proxy for protected chunk */
    H5O_chunk_proxy_t *ret_value;               /* Return value */

    FUNC_ENTER_NOAPI_TAG(dxpl_id, oh->cache_info.addr, NULL)

    /* check args */
    HDassert(f);
    HDassert(oh);
    HDassert(idx < oh->nchunks);

    /* Check for protecting first chunk */
    if(0 == idx) {
        /* Create new "fake" chunk proxy for first chunk */
        /* (since the first chunk is already handled by the H5O_t object) */
        if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t)))
            HGOTO_ERROR(H5E_OHDR, H5E_CANTALLOC, NULL, "memory allocation failed")

        /* Increment reference count on object header */
        if(H5O_inc_rc(oh) < 0)
            HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, NULL, "can't increment reference count on object header")

        /* Set chunk proxy fields */
        chk_proxy->oh = oh;
        chk_proxy->chunkno = idx;
    } /* end if */
    else {
Пример #2
0
/*-------------------------------------------------------------------------
 * 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
 *
 * Modfications:
 *
 *	Vailin Choi, July 29th, 2008
 *	  Add two more parameters for handling alignment: alignment & threshhold
 *
 *-------------------------------------------------------------------------
 */
H5FS_t *
H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr, size_t nclasses,
    const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, hsize_t threshold)
{
    H5FS_t *fspace = NULL;      /* New free space structure */
    H5FS_hdr_cache_ud_t cache_udata; /* User-data for metadata cache callback */
    H5FS_t *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_TAG(dxpl_id, H5AC__FREESPACE_TAG, NULL)
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Opening free space manager, fs_addr = %a, nclasses = %Zu\n", FUNC, fs_addr, nclasses);
#endif /* H5FS_DEBUG */

    /* Check arguments. */
    HDassert(H5F_addr_defined(fs_addr));
    HDassert(nclasses);
    HDassert(classes);

    /* Initialize user data for protecting the free space manager */
    cache_udata.f = f;
    cache_udata.nclasses = nclasses;
    cache_udata.classes = classes;
    cache_udata.cls_init_udata = cls_init_udata;
    cache_udata.addr = fs_addr;

    /* Protect the free space header */
    if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &cache_udata, H5AC_READ)))
        HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, NULL, "unable to load free space header")
#ifdef H5FS_DEBUG
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);
HDfprintf(stderr, "%s: fspace->rc = %u\n", FUNC, fspace->rc);
#endif /* H5FS_DEBUG */

    /* Increment the reference count on the free space manager header */
    HDassert(fspace->rc <= 1);
    if(H5FS_incr(fspace) < 0)
        HGOTO_ERROR(H5E_FSPACE, H5E_CANTINC, NULL, "unable to increment ref. count on free space header")

    fspace->alignment = alignment;
    fspace->threshold = threshold;

    /* Unlock free space header */
    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;

done:
    FUNC_LEAVE_NOAPI_TAG(ret_value, NULL)
} /* H5FS_open() */
Пример #3
0
/*-------------------------------------------------------------------------
 * Function:	H5FS_close
 *
 * Purpose:	Destroy & deallocate free list structure, serializing sections
 *              in the bins
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Quincey Koziol
 *              Tuesday, March  7, 2006
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5FS_close(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
{
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_NOAPI_TAG(dxpl_id, H5AC__FREESPACE_TAG, FAIL)

    /* Check arguments. */
    HDassert(f);
    HDassert(fspace);
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Entering, fspace = %p, fspace->addr = %a, fspace->sinfo = %p\n", FUNC, fspace, fspace->addr, fspace->sinfo);
#endif /* H5FS_DEBUG */

    /* Check if section info is valid */
    /* (i.e. the header "owns" the section info and it's not in the cache) */
    if(fspace->sinfo) {
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu, fspace->serial_sect_count = %Hu, fspace->sect_addr = %a, fspace->rc = %u\n", FUNC, fspace->tot_sect_count, fspace->serial_sect_count, fspace->sect_addr, fspace->rc);
HDfprintf(stderr, "%s: fspace->alloc_sect_size = %Hu, fspace->sect_size = %Hu\n", FUNC, fspace->alloc_sect_size, fspace->sect_size);
#endif /* H5FS_DEBUG */
        /* If there are sections to serialize, update them */
        /* (if the free space manager is persistant) */
        if(fspace->serial_sect_count > 0 && H5F_addr_defined(fspace->addr)) {
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Real sections to store in file\n", FUNC);
#endif /* H5FS_DEBUG */
            if(fspace->sinfo->dirty) {
                /* Check if the section info is "floating" */
                if(!H5F_addr_defined(fspace->sect_addr)) {
                    /* Sanity check */
                    HDassert(fspace->sect_size > 0);

                    /* Allocate space for the section info in file */
                    if(H5F_USE_TMP_SPACE(f)) {
                        if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc_tmp(f, fspace->sect_size)))
                            HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
                    } /* end if */
                    else {
                        if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_size)))
                            HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "file allocation failed for free space sections")
                    } /* end if */
                    fspace->alloc_sect_size = (size_t)fspace->sect_size;

                    /* Mark free space header as dirty */
                    if(H5AC_mark_entry_dirty(fspace) < 0)
                        HGOTO_ERROR(H5E_FSPACE, H5E_CANTMARKDIRTY, FAIL, "unable to mark free space header as dirty")
                } /* end if */
Пример #4
0
/*-------------------------------------------------------------------------
 * Function:	H5O_chunk_add
 *
 * Purpose:	Add new chunk for object header to metadata cache
 *
 * Return:	Success:	Non-negative
 *		Failure:	Negative
 *
 * Programmer:	Quincey Koziol
 *		[email protected]
 *		Jul 13 2008
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx,
    unsigned cont_chunkno)
{
    H5O_chunk_proxy_t *chk_proxy = NULL;        /* Proxy for chunk, to mark it dirty in the cache */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_NOAPI_TAG(dxpl_id, oh->cache_info.addr, FAIL)

    /* check args */
    HDassert(f);
    HDassert(oh);
    HDassert(idx < oh->nchunks);
    HDassert(idx > 0);

    /* Allocate space for the object header data structure */
    if(NULL == (chk_proxy = H5FL_CALLOC(H5O_chunk_proxy_t)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")

    /* Set the values in the chunk proxy */
    chk_proxy->f = f;
    chk_proxy->oh = oh;
    chk_proxy->chunkno = idx;
    chk_proxy->cont_chunkno = cont_chunkno;

    chk_proxy->fd_parent_addr = HADDR_UNDEF;
    chk_proxy->fd_parent_ptr = NULL;

    /* Increment reference count on object header */
    if(H5O_inc_rc(oh) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "can't increment reference count on object header")

    /* Insert the chunk proxy into the cache */
    if(H5AC_insert_entry(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0)
        HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header chunk")

    chk_proxy = NULL;

done:
    if(ret_value < 0)
        if(chk_proxy)
            chk_proxy = H5FL_FREE(H5O_chunk_proxy_t, chk_proxy);

    FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5O_chunk_add() */
Пример #5
0
/*-------------------------------------------------------------------------
 * Function:	H5FS_delete
 *
 * Purpose:	Delete a free space manager on disk
 *
 * Return:	Success:	non-negative
 *
 *		Failure:	negative
 *
 * Programmer:	Quincey Koziol
 *              Tuesday, May 30, 2006
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5FS_delete(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr)
{
    H5FS_t *fspace = NULL;              /* Free space header loaded from file */
    H5FS_hdr_cache_ud_t cache_udata; /* User-data for metadata cache callback */
    herr_t ret_value = SUCCEED;         /* Return value */

    FUNC_ENTER_NOAPI_TAG(dxpl_id, H5AC__FREESPACE_TAG, FAIL)
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Deleting free space manager, fs_addr = %a\n", FUNC, fs_addr);
#endif /* H5FS_DEBUG */

    /* Check arguments. */
    HDassert(f);
    HDassert(H5F_addr_defined(fs_addr));

    /* Initialize user data for protecting the free space manager */
    /* (no class information necessary for delete) */
    cache_udata.f = f;
    cache_udata.nclasses = 0;
    cache_udata.classes = NULL;
    cache_udata.cls_init_udata = NULL;
    cache_udata.addr = fs_addr;

#ifdef H5FS_DEBUG
{
    unsigned fspace_status = 0;      /* Free space section info's status in the metadata cache */

    /* Sanity check */
    HDassert(H5F_addr_defined(fs_addr));

    /* Check the free space section info's status in the metadata cache */
    if(H5AC_get_entry_status(f, fs_addr, &fspace_status) < 0)
        HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space section info")

    HDfprintf(stderr, "%s: fspace_status = %0x: ", FUNC, fspace_status);
    if(fspace_status) {
        hbool_t printed = FALSE;

        if(fspace_status & H5AC_ES__IN_CACHE) {
            HDfprintf(stderr, "H5AC_ES__IN_CACHE");
            printed = TRUE;
        } /* end if */
        if(fspace_status & H5AC_ES__IS_DIRTY) {
            HDfprintf(stderr, "%sH5AC_ES__IS_DIRTY", (printed ? " | " : ""));
            printed = TRUE;
        } /* end if */
        if(fspace_status & H5AC_ES__IS_PROTECTED) {
            HDfprintf(stderr, "%sH5AC_ES__IS_PROTECTED", (printed ? " | " : ""));
            printed = TRUE;
        } /* end if */
        if(fspace_status & H5AC_ES__IS_PINNED) {
            HDfprintf(stderr, "%sH5AC_ES__IS_PINNED", (printed ? " | " : ""));
            printed = TRUE;
        } /* end if */
        if(fspace_status & H5AC_ES__IS_FLUSH_DEP_PARENT) {
            HDfprintf(stderr, "%sH5AC_ES__IS_FLUSH_DEP_PARENT", (printed ? " | " : ""));
            printed = TRUE;
        } /* end if */
        if(fspace_status & H5AC_ES__IS_FLUSH_DEP_CHILD) {
            HDfprintf(stderr, "%sH5AC_ES__IS_FLUSH_DEP_CHILD", (printed ? " | " : ""));
            printed = TRUE;
        } /* end if */
    } /* end if */
    HDfprintf(stderr, "\n");
}
#endif /* H5FS_DEBUG */

    /* Protect the free space header */
    if(NULL == (fspace = (H5FS_t *)H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &cache_udata, H5AC_WRITE)))
        HGOTO_ERROR(H5E_FSPACE, H5E_CANTPROTECT, FAIL, "unable to protect free space header")

    /* Sanity check */
    HDassert(fspace->sinfo == NULL);

    /* Delete serialized section storage, if there are any */
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
#endif /* H5FS_DEBUG */
    if(fspace->serial_sect_count > 0) {
        unsigned sinfo_status = 0;      /* Free space section info's status in the metadata cache */

        /* Sanity check */
        HDassert(H5F_addr_defined(fspace->sect_addr));
        HDassert(fspace->alloc_sect_size > 0);

        /* 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 H5FS_DEBUG
HDfprintf(stderr, "%s: Expunging free space section info from cache\n", FUNC);
#endif /* H5FS_DEBUG */
            /* Evict the free space section info from the metadata cache */
            /* (Free file space) */
            if(H5AC_expunge_entry(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
                HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove free space section info from cache")
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Done expunging free space section info from cache\n", FUNC);
#endif /* H5FS_DEBUG */
        } /* end if */
        else {
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Deleting free space section info from file\n", FUNC);
#endif /* H5FS_DEBUG */
            /* Release the space in the file */
            if(!H5F_IS_TMP_ADDR(f, fspace->sect_addr)) {
                if(H5MF_xfree(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->sect_addr, fspace->alloc_sect_size) < 0)
                    HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space sections")
            } /* end if */
        } /* end else */
    } /* end if */
Пример #6
0
/*-------------------------------------------------------------------------
 * 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
 *
 * Modifications:
 *	Vailin Choi, July 29th, 2008
 *	  Add two more parameters for handling alignment: alignment & threshhold
 *
 *-------------------------------------------------------------------------
 */
H5FS_t *
H5FS_create(H5F_t *f, hid_t dxpl_id, haddr_t *fs_addr, const H5FS_create_t *fs_create,
    size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata, hsize_t alignment, hsize_t threshold)
{
    H5FS_t *fspace = NULL;      /* New free space structure */
    H5FS_t *ret_value;          /* Return value */

    FUNC_ENTER_NOAPI_TAG(dxpl_id, H5AC__FREESPACE_TAG, NULL)
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, nclasses);
#endif /* H5FS_DEBUG */

    /* Check arguments. */
    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
     */
    if(NULL == (fspace = H5FS_new(f, nclasses, classes, cls_init_udata)))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space free list")

    /* 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;

    fspace->alignment = alignment;
    fspace->threshold = threshold;

    /* Check if the free space tracker is supposed to be persistant */
    if(fs_addr) {
        /* Allocate space for the free space header */
        if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)fspace->hdr_size)))
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for free space header")

        /* Cache the new free space header (pinned) */
        if(H5AC_insert_entry(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0)
            HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space header to cache")

        /* Return free space header address to caller, if desired */
        *fs_addr = fspace->addr;
    } /* end if */

    /* Set the reference count to 1, since we inserted the entry in the cache pinned */
    fspace->rc = 1;

    /* Set the return value */
    ret_value = fspace;
#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: fspace = %p, fspace->addr = %a\n", FUNC, fspace, fspace->addr);
#endif /* H5FS_DEBUG */

done:
    if(!ret_value && fspace)
        if(H5FS_hdr_dest(fspace) < 0)
            HDONE_ERROR(H5E_FSPACE, H5E_CANTFREE, NULL, "unable to destroy free space header")

#ifdef H5FS_DEBUG
HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
#endif /* H5FS_DEBUG */
    FUNC_LEAVE_NOAPI_TAG(ret_value, NULL)
} /* H5FS_create() */