Esempio n. 1
0
/*
 *  Verify that object headers are held in the cache until they are linked
 *      to a location in the graph, or assigned an ID.  This is done by
 *      creating an object header, then forcing it out of the cache by creating
 *      local heaps until the object header is evicted from the cache, then
 *      modifying the object header.  The refcount on the object header is
 *      checked as verifying that the object header has remained in the cache.
 */
static herr_t
test_ohdr_cache(char *filename, hid_t fapl)
{
    hid_t	file = -1;              /* File ID */
    hid_t       my_fapl;                /* FAPL ID */
    hid_t       my_dxpl;                /* DXPL ID */
    H5AC_cache_config_t mdc_config;     /* Metadata cache configuration info */
    H5F_t	*f = NULL;              /* File handle */
    H5HL_t      *lheap, *lheap2, *lheap3; /* Pointer to local heaps */
    haddr_t     lheap_addr, lheap_addr2, lheap_addr3; /* Local heap addresses */
    H5O_loc_t	oh_loc;                 /* Object header location */
    time_t	time_new;               /* Time value for modification time message */
    unsigned    rc;                     /* Refcount for object */

    TESTING("object header creation in cache");

    /* Make a copy of the FAPL */
    if((my_fapl = H5Pcopy(fapl)) < 0)
        FAIL_STACK_ERROR

    /* Tweak down the size of the metadata cache to only 64K */
    mdc_config.version = H5AC__CURR_CACHE_CONFIG_VERSION;
    if(H5Pget_mdc_config(my_fapl, &mdc_config) < 0)
        FAIL_STACK_ERROR
    mdc_config.set_initial_size = TRUE;
    mdc_config.initial_size = 32 * 1024;
    mdc_config.max_size = 64 * 1024;
    mdc_config.min_size = 8 * 1024;
    if(H5Pset_mdc_config(my_fapl, &mdc_config) < 0)
        FAIL_STACK_ERROR

    /* Make a copy of the default DXPL */
    if((my_dxpl = H5Pcopy(H5P_DATASET_XFER_DEFAULT)) < 0)
        FAIL_STACK_ERROR

    /* Create the file to operate on */
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
        FAIL_STACK_ERROR
    if(H5Pclose(my_fapl) < 0)
	FAIL_STACK_ERROR
    if(NULL == (f = (H5F_t *)H5I_object(file)))
        FAIL_STACK_ERROR
    if(H5AC_ignore_tags(f) < 0)
        FAIL_STACK_ERROR

    /* Create object (local heap) that occupies most of cache */
    if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr) < 0)
        FAIL_STACK_ERROR

    /* Protect local heap (which actually pins it in the cache) */
    if(NULL == (lheap = H5HL_protect(f, my_dxpl, lheap_addr, H5AC__READ_ONLY_FLAG)))
        FAIL_STACK_ERROR

    /* Create an object header */
    HDmemset(&oh_loc, 0, sizeof(oh_loc));
    if(H5O_create(f, my_dxpl, (size_t)2048, (size_t)1, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
        FAIL_STACK_ERROR

    /* Query object header information */
    rc = 0;
    if(H5O_get_rc(&oh_loc, my_dxpl, &rc) < 0)
        FAIL_STACK_ERROR
    if(0 != rc)
        TEST_ERROR

    /* Create object (local heap) that occupies most of cache */
    if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr2) < 0)
        FAIL_STACK_ERROR

    /* Protect local heap (which actually pins it in the cache) */
    if(NULL == (lheap2 = H5HL_protect(f, my_dxpl, lheap_addr2, H5AC__READ_ONLY_FLAG)))
        FAIL_STACK_ERROR

    /* Unprotect local heap (which actually unpins it from the cache) */
    if(H5HL_unprotect(lheap2) < 0)
        FAIL_STACK_ERROR

    /* Create object header message in new object header */
    time_new = 11111111;
    if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, my_dxpl) < 0)
        FAIL_STACK_ERROR

    /* Create object (local heap) that occupies most of cache */
    if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr3) < 0)
        FAIL_STACK_ERROR

    /* Protect local heap (which actually pins it in the cache) */
    if(NULL == (lheap3 = H5HL_protect(f, my_dxpl, lheap_addr3, H5AC__READ_ONLY_FLAG)))
        FAIL_STACK_ERROR

    /* Unprotect local heap (which actually unpins it from the cache) */
    if(H5HL_unprotect(lheap3) < 0)
        FAIL_STACK_ERROR

    /* Query object header information */
    /* (Note that this is somewhat of a weak test, since it doesn't actually
     *  verify that the object header was evicted from the cache, but it's
     *  very difficult to verify when an entry is evicted from the cache in
     *  a non-invasive way -QAK)
     */
    rc = 0;
    if(H5O_get_rc(&oh_loc, my_dxpl, &rc) < 0)
        FAIL_STACK_ERROR
    if(0 != rc)
        TEST_ERROR

    /* Decrement reference count o object header */
    if(H5O_dec_rc_by_loc(&oh_loc, my_dxpl) < 0)
        FAIL_STACK_ERROR

    /* Close object header created */
    if(H5O_close(&oh_loc) < 0)
        FAIL_STACK_ERROR

    /* Unprotect local heap (which actually unpins it from the cache) */
    if(H5HL_unprotect(lheap) < 0)
        FAIL_STACK_ERROR

    if(H5Pclose(my_dxpl) < 0)
	FAIL_STACK_ERROR
    if(H5Fclose(file) < 0)
	FAIL_STACK_ERROR

    PASSED();

    return 0;

error:
    H5E_BEGIN_TRY {
        H5Fclose(file);
    } H5E_END_TRY;

    return -1;
} /* test_ohdr_cache() */
Esempio n. 2
0
/*-------------------------------------------------------------------------
 * Function:	H5G_traverse_slink
 *
 * Purpose:	Traverses symbolic link.  The link head appears in the group
 *		whose entry is GRP_ENT and the link head entry is OBJ_ENT.
 *
 * Return:	Success:	Non-negative, OBJ_ENT will contain information
 *				about the object to which the link points and
 *				GRP_ENT will contain the information about
 *				the group in which the link tail appears.
 *
 *		Failure:	Negative
 *
 * Programmer:	Robb Matzke
 *              Friday, April 10, 1998
 *
 * Modifications:
 *
 *      Pedro Vicente, <*****@*****.**> 22 Aug 2002
 *      Added `id to name' support.
 *
 *-------------------------------------------------------------------------
 */
static herr_t
H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
                    H5G_entry_t *obj_ent/*in,out*/,
                    int *nlinks/*in,out*/, hid_t dxpl_id)
{
    H5O_stab_t		stab_mesg;		/*info about local heap	*/
    const char		*clv = NULL;		/*cached link value	*/
    char		*linkval = NULL;	/*the copied link value	*/
    H5G_entry_t         tmp_grp_ent;            /* Temporary copy of group entry */
    H5RS_str_t          *tmp_full_path_r = NULL, *tmp_user_path_r = NULL; /* Temporary pointer to object's user path & canonical path */
    const H5HL_t        *heap;
    herr_t      ret_value=SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink);

    /* Portably initialize the temporary group entry */
    H5G_ent_reset(&tmp_grp_ent);

    /* Get the link value */
    if (NULL==H5O_read (grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
        HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");

    if (NULL == (heap = H5HL_protect(grp_ent->file, dxpl_id, stab_mesg.heap_addr)))
        HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value")

        clv = H5HL_offset_into(grp_ent->file, heap, obj_ent->cache.slink.lval_offset);

    linkval = H5MM_xstrdup (clv);
    assert(linkval);

    if (H5HL_unprotect(grp_ent->file, dxpl_id, heap, stab_mesg.heap_addr) < 0)
        HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value")

        /* Hold the entry's name (& old_name) to restore later */
        tmp_full_path_r = obj_ent->full_path_r;
    obj_ent->full_path_r = NULL;
    tmp_user_path_r = obj_ent->user_path_r;
    obj_ent->user_path_r = NULL;

    /* Free the names for the group entry */
    H5G_name_free(grp_ent);

    /* Clone the group entry, so we can track the names properly */
    H5G_ent_copy(&tmp_grp_ent,grp_ent,H5_COPY_DEEP);

    /* Traverse the link */
    if (H5G_namei (&tmp_grp_ent, linkval, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, nlinks, H5G_NAMEI_TRAVERSE, NULL, dxpl_id))
        HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link");

    /* Free the entry's names, we will use the original name for the object */
    H5G_name_free(obj_ent);

    /* Restore previous name for object */
    obj_ent->full_path_r = tmp_full_path_r;
    tmp_full_path_r = NULL;
    obj_ent->user_path_r = tmp_user_path_r;
    tmp_user_path_r = NULL;

done:
    /* Error cleanup */
    if(tmp_full_path_r)
        H5RS_decr(tmp_full_path_r);
    if(tmp_user_path_r)
        H5RS_decr(tmp_user_path_r);

    /* Release cloned copy of group entry */
    H5G_name_free(&tmp_grp_ent);

    H5MM_xfree (linkval);
    FUNC_LEAVE_NOAPI(ret_value);
}
Esempio n. 3
0
/*-------------------------------------------------------------------------
 * Function:	H5O_efl_decode
 *
 * Purpose:	Decode an external file list message and return a pointer to
 *		the message (and some other data).
 *
 * Return:	Success:	Ptr to a new message struct.
 *
 *		Failure:	NULL
 *
 * Programmer:	Robb Matzke
 *		Tuesday, November 25, 1997
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
    unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p)
{
    H5O_efl_t		*mesg = NULL;
    int			version;
    const char		*s = NULL;
    H5HL_t              *heap;
    size_t		u;      /* Local index variable */
    void *ret_value;            /* Return value */

    FUNC_ENTER_NOAPI_NOINIT(H5O_efl_decode)

    /* Check args */
    HDassert(f);
    HDassert(p);

    if(NULL == (mesg = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))))
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Version */
    version = *p++;
    if(version != H5O_EFL_VERSION)
	HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for external file list message")

    /* Reserved */
    p += 3;

    /* Number of slots */
    UINT16DECODE(p, mesg->nalloc);
    assert(mesg->nalloc>0);
    UINT16DECODE(p, mesg->nused);
    assert(mesg->nused <= mesg->nalloc);

    /* Heap address */
    H5F_addr_decode(f, &p, &(mesg->heap_addr));

#ifndef NDEBUG
    HDassert(H5F_addr_defined(mesg->heap_addr));

    if(NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr, H5AC_READ)))
        HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value")

    s = (const char *)H5HL_offset_into(f, heap, 0);

    HDassert(s && !*s);

    if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value")
    heap = NULL;
#endif

    /* Decode the file list */
    mesg->slot = (H5O_efl_entry_t *)H5MM_calloc(mesg->nalloc * sizeof(H5O_efl_entry_t));
    if(NULL == mesg->slot)
	HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    if(NULL == (heap = H5HL_protect(f, dxpl_id, mesg->heap_addr, H5AC_READ)))
        HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read protect link value")
    for(u = 0; u < mesg->nused; u++) {
	/* Name */
	H5F_DECODE_LENGTH (f, p, mesg->slot[u].name_offset);

        s = (const char *)H5HL_offset_into(f, heap, mesg->slot[u].name_offset);
	HDassert(s && *s);
	mesg->slot[u].name = H5MM_xstrdup (s);
        HDassert(mesg->slot[u].name);

	/* File offset */
	H5F_DECODE_LENGTH (f, p, mesg->slot[u].offset);

	/* Size */
	H5F_DECODE_LENGTH (f, p, mesg->slot[u].size);
	HDassert(mesg->slot[u].size > 0);
    } /* end for */

    if(H5HL_unprotect(f, dxpl_id, heap, mesg->heap_addr) < 0)
        HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "unable to read unprotect link value")
    heap = NULL;

    /* Set return value */
    ret_value = mesg;

done:
    if(ret_value == NULL)
        if(mesg != NULL)
            H5MM_xfree(mesg);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_efl_decode() */
Esempio n. 4
0
/*-------------------------------------------------------------------------
 * Function:	H5HL_debug
 *
 * Purpose:	Prints debugging information about a heap.
 *
 * Return:	Non-negative on success/Negative on failure
 *
 * Programmer:	Robb Matzke
 *		[email protected]
 *		Aug  1 1997
 *
 * Modifications:
 *		Robb Matzke, 1999-07-28
 *		The ADDR argument is passed by value.
 *
 *              John Mainzer, 6/17/05
 *              Modified the function to use the new dirtied parameter of
 *              of H5AC_unprotect() instead of modifying the is_dirty
 *              field of the cache info.
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth)
{
    H5HL_t		*h = NULL;
    int			i, overlap, free_block;
    H5HL_free_t		*freelist = NULL;
    uint8_t		*marker = NULL;
    size_t		amount_free = 0;
    herr_t              ret_value = SUCCEED;       /* Return value */

    FUNC_ENTER_NOAPI(H5HL_debug, FAIL)

    /* check arguments */
    HDassert(f);
    HDassert(H5F_addr_defined(addr));
    HDassert(stream);
    HDassert(indent >= 0);
    HDassert(fwidth >= 0);

    if(NULL == (h = (H5HL_t *)H5HL_protect(f, dxpl_id, addr, H5AC_READ)))
        HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")

    fprintf(stream, "%*sLocal Heap...\n", indent, "");
    fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
	    "Header size (in bytes):",
	    (unsigned long)h->prfx_size);
    HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
	      "Address of heap data:",
	      h->dblk_addr);
    HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
	    "Data bytes allocated for heap:",
            h->dblk_size);

    /*
     * Traverse the free list and check that all free blocks fall within
     * the heap and that no two free blocks point to the same region of
     * the heap.  */
    if(NULL == (marker = (uint8_t *)H5MM_calloc(h->dblk_size)))
	HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed")

    fprintf(stream, "%*sFree Blocks (offset, size):\n", indent, "");

    for(free_block = 0, freelist = h->freelist; freelist; freelist = freelist->next, free_block++) {
        char temp_str[32];

        sprintf(temp_str,"Block #%d:",free_block);
	HDfprintf(stream, "%*s%-*s %8Zu, %8Zu\n", indent+3, "", MAX(0,fwidth-9),
		temp_str,
		freelist->offset, freelist->size);
	if((freelist->offset + freelist->size) > h->dblk_size)
	    fprintf(stream, "***THAT FREE BLOCK IS OUT OF BOUNDS!\n");
	else {
	    for(i = overlap = 0; i < (int)(freelist->size); i++) {
		if(marker[freelist->offset + i])
		    overlap++;
		marker[freelist->offset + i] = 1;
	    } /* end for */
	    if(overlap)
		fprintf(stream, "***THAT FREE BLOCK OVERLAPPED A PREVIOUS ONE!\n");
	    else
		amount_free += freelist->size;
	} /* end for */
    } /* end for */

    if(h->dblk_size)
	fprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth,
		"Percent of heap used:",
		(100.0 * (double)(h->dblk_size - amount_free) / (double)h->dblk_size));

    /*
     * Print the data in a VMS-style octal dump.
     */
    H5_buffer_dump(stream, indent, h->dblk_image, marker, (size_t)0, h->dblk_size);

done:
    if(h && H5HL_unprotect(h) < 0)
	HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
    H5MM_xfree(marker);

    FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HL_debug() */
Esempio n. 5
0
/*-------------------------------------------------------------------------
 * Function:	main
 *
 * Purpose:	Create a file, create a local heap, write data into the local
 *		heap, close the file, open the file, read data out of the
 *		local heap, close the file.
 *
 * Return:	Success:	zero
 *
 *		Failure:	non-zero
 *
 * Programmer:	Robb Matzke
 *              Tuesday, November 24, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
int
main(void)
{
    hid_t	fapl=H5P_DEFAULT;	/*file access properties	*/
    hid_t	file=-1;		/*hdf5 file 			*/
    H5F_t	*f=NULL;		/*hdf5 file pointer		*/
    char	filename[1024];		/*file name			*/
    haddr_t	heap_addr;		/*local heap address		*/
    H5HL_t      *heap = NULL;           /*local heap			*/
    size_t	obj[NOBJS];		/*offsets within the heap	*/
    int		i, j;			/*miscellaneous counters	*/
    char	buf[1024];		/*the value to store		*/
    const char	*s;			/*value to read			*/

    /* Reset library */
    h5_reset();
    fapl = h5_fileaccess();


    /*
     * Test writing to the heap...
     */
    TESTING("local heap write");
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0)
	goto error;
    if(NULL == (f = H5I_object(file))) {
	H5_FAILED();
	H5Eprint2(H5E_DEFAULT, stdout);
	goto error;
    }
    if(H5HL_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)0, &heap_addr/*out*/) < 0) {
	H5_FAILED();
	H5Eprint2(H5E_DEFAULT, stdout);
	goto error;
    }
    if (NULL == (heap = H5HL_protect(f, H5P_DATASET_XFER_DEFAULT, heap_addr, H5AC_WRITE))) {
        H5_FAILED();
        H5Eprint2(H5E_DEFAULT, stdout);
        goto error;
    }
    for(i = 0; i < NOBJS; i++) {
        sprintf(buf, "%03d-", i);
        for (j=4; j<i; j++) buf[j] = '0' + j%10;
        if (j>4) buf[j] = '\0';

        if ((size_t)(-1)==(obj[i]=H5HL_insert(f, H5P_DATASET_XFER_DEFAULT, heap, strlen(buf)+1, buf))) {
	    H5_FAILED();
	    H5Eprint2(H5E_DEFAULT, stdout);
	    goto error;
	}
    }
    if (H5HL_unprotect(f, H5P_DATASET_XFER_DEFAULT, heap, heap_addr) < 0) {
        H5_FAILED();
        H5Eprint2(H5E_DEFAULT, stdout);
        goto error;
    }
    if (H5Fclose(file)<0) goto error;
    PASSED();

    /*
     * Test reading from the heap...
     */

    TESTING("local heap read");
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if ((file=H5Fopen(filename, H5F_ACC_RDONLY, fapl))<0) goto error;
    if (NULL==(f=H5I_object(file))) {
        H5_FAILED();
        H5Eprint2(H5E_DEFAULT, stdout);
        goto error;
    }
    for (i=0; i<NOBJS; i++) {
        sprintf(buf, "%03d-", i);
        for (j=4; j<i; j++) buf[j] = '0' + j%10;
        if (j>4) buf[j] = '\0';

        if (NULL == (heap = H5HL_protect(f, H5P_DATASET_XFER_DEFAULT, heap_addr, H5AC_READ))) {
            H5_FAILED();
            H5Eprint2(H5E_DEFAULT, stdout);
            goto error;
        }

        if (NULL == (s = H5HL_offset_into(f, heap, obj[i]))) {
            H5_FAILED();
            H5Eprint2(H5E_DEFAULT, stdout);
            goto error;
        }

        if (strcmp(s, buf)) {
            H5_FAILED();
            printf("    i=%d, heap offset=%lu\n", i, (unsigned long)(obj[i]));
            printf("    got: \"%s\"\n", s);
            printf("    ans: \"%s\"\n", buf);
            goto error;
        }

        if (H5HL_unprotect(f, H5P_DATASET_XFER_DEFAULT, heap, heap_addr) < 0) {
            H5_FAILED();
            H5Eprint2(H5E_DEFAULT, stdout);
            goto error;
        }
    }

    if (H5Fclose(file)<0) goto error;
    PASSED();
    puts("All local heap tests passed.");
    h5_cleanup(FILENAME, fapl);

    return 0;

 error:
    puts("*** TESTS FAILED ***");
    H5E_BEGIN_TRY {
	H5Fclose(file);
    } H5E_END_TRY;
    return 1;
}
Esempio n. 6
0
/*-------------------------------------------------------------------------
 * Function:    H5O_efl_copy_file
 *
 * Purpose:     Copies an efl message from _MESG to _DEST in file
 *
 * Return:      Success:        Ptr to _DEST
 *
 *              Failure:        NULL
 *
 * Programmer:  Peter Cao
 *              September 29, 2005
 *
 *-------------------------------------------------------------------------
 */
static void *
H5O_efl_copy_file(H5F_t H5_ATTR_UNUSED *file_src, void *mesg_src, H5F_t *file_dst,
    hbool_t H5_ATTR_UNUSED *recompute_size, unsigned H5_ATTR_UNUSED *mesg_flags,
    H5O_copy_t H5_ATTR_UNUSED *cpy_info, void H5_ATTR_UNUSED *_udata, hid_t dxpl_id)
{
    H5O_efl_t   *efl_src = (H5O_efl_t *) mesg_src;
    H5O_efl_t   *efl_dst = NULL;
    H5HL_t      *heap = NULL;                   /* Pointer to local heap for EFL file names */
    size_t      idx, size, name_offset, heap_size;
    void        *ret_value = NULL;              /* Return value */

    FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, H5AC__COPIED_TAG, NULL)

    /* check args */
    HDassert(efl_src);
    HDassert(file_dst);

    /* Allocate space for the destination efl */
    if(NULL == (efl_dst = (H5O_efl_t *)H5MM_calloc(sizeof(H5O_efl_t))))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

    /* Copy the "top level" information */
    HDmemcpy(efl_dst, efl_src, sizeof(H5O_efl_t));

    /* Determine size needed for destination heap */
    heap_size = H5HL_ALIGN(1);  /* "empty" name */
    for(idx = 0; idx < efl_src->nused; idx++)
        heap_size += H5HL_ALIGN(HDstrlen(efl_src->slot[idx].name) + 1);

    /* Create name heap */
    if(H5HL_create(file_dst, dxpl_id, heap_size, &efl_dst->heap_addr/*out*/) < 0)
        HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, NULL, "can't create heap")

    /* Pin the heap down in memory */
    if(NULL == (heap = H5HL_protect(file_dst, dxpl_id, efl_dst->heap_addr, H5AC__NO_FLAGS_SET)))
        HGOTO_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to protect EFL file name heap")

    /* Insert "empty" name first */
    if((size_t)(-1) == (name_offset = H5HL_insert(file_dst, dxpl_id, heap, (size_t)1, "")))
        HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap")
    HDassert(0 == name_offset);

    /* allocate array of external file entries */
    if(efl_src->nalloc > 0) {
        size = efl_src->nalloc * sizeof(H5O_efl_entry_t);
        if((efl_dst->slot = (H5O_efl_entry_t *)H5MM_calloc(size)) == NULL)
            HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")

        /* copy content from the source. Need to update later */
        HDmemcpy(efl_dst->slot, efl_src->slot, size);
    } /* end if */

    /* copy the name from the source */
    for(idx = 0; idx < efl_src->nused; idx++) {
        efl_dst->slot[idx].name = H5MM_xstrdup(efl_src->slot[idx].name);
        if((size_t)(-1) == (efl_dst->slot[idx].name_offset = H5HL_insert(file_dst, dxpl_id, heap,
                HDstrlen(efl_dst->slot[idx].name) + 1, efl_dst->slot[idx].name)))
            HGOTO_ERROR(H5E_EFL, H5E_CANTINSERT, NULL, "can't insert file name into heap")
    } /* end for */

    /* Set return value */
    ret_value = efl_dst;

done:
    /* Release resources */
    if(heap && H5HL_unprotect(heap) < 0)
        HDONE_ERROR(H5E_EFL, H5E_PROTECT, NULL, "unable to unprotect EFL file name heap")
    if(!ret_value)
        if(efl_dst)
            H5MM_xfree(efl_dst);

    FUNC_LEAVE_NOAPI_TAG(ret_value, NULL)
} /* end H5O_efl_copy_file() */