Пример #1
0
/*-------------------------------------------------------------------------
 * Function:	H5L_extern_traverse
 *
 * Purpose:	Default traversal function for external links. This can
 *              be overridden using H5Lregister().
 *
 *              Given a filename and path packed into the link udata,
 *              attempts to open an object within an external file.
 *              If the H5L_ELINK_PREFIX_NAME property is set in the
 *              link access property list, appends that prefix to the
 *              filename being opened.
 *
 * Return:	ID of the opened object on success/Negative on failure
 *
 * Programmer:	James Laird
 *              Monday, July 10, 2006
 * Modifications:
 *		Vailin Choi, April 2, 2008
 *		Add handling to search for the target file
 *		See description in RM: H5Lcreate_external
 *
 *		Vailin Choi; Sept. 12th, 2008; bug #1247
 *		Retrieve the file access property list identifer that is set
 *		for link access property via H5Pget_elink_fapl().
 *		If the return value is H5P_DEFAULT, the parent's file access
 *		property is used to H5F_open() the target file;
 *		Otherwise, the file access property retrieved from H5Pget_elink_fapl()
 *		is used to H5F_open() the target file.
 *
 *		Vailin Choi; Nov 2010
 *		Free memory pointed to by tmp_env_prefix for HDF5_EXT_PREFIX case.
 *
 *-------------------------------------------------------------------------
 */
static hid_t
H5L_extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group,
    const void *_udata, size_t H5_ATTR_UNUSED udata_size, hid_t lapl_id)
{
    H5P_genplist_t *plist;              /* Property list pointer */
    char       *my_prefix;              /* Library's copy of the prefix */
    H5G_loc_t   root_loc;               /* Location of root group in external file */
    H5G_loc_t   loc;                    /* Location of object */
    H5F_t	*ext_file = NULL;	/* File struct for external file */
    const uint8_t *p = (const uint8_t *)_udata;  /* Pointer into external link buffer */
    const char *file_name;              /* Name of file containing external link's object */
    char *full_name = NULL;             /* File name with prefix */
    const char  *obj_name;              /* Name external link's object */
    size_t      fname_len;              /* Length of external link file name */
    unsigned    intent;                 /* File access permissions */
    H5L_elink_cb_t cb_info;             /* Callback info struct */
    hid_t       fapl_id = -1;           /* File access property list for external link's file */
    hid_t       ext_obj = -1;           /* ID for external link's object */
    char        *parent_group_name = NULL;/* Temporary pointer to group name */
    char        local_group_name[H5L_EXT_TRAVERSE_BUF_SIZE];  /* Local buffer to hold group name */
    char        *temp_file_name = NULL; /* Temporary pointer to file name */
    size_t      temp_file_name_len;     /* Length of temporary file name */
    char        *actual_file_name = NULL; /* Parent file's actual name */
    H5P_genplist_t  *fa_plist;          /* File access property list pointer */
    H5F_close_degree_t 	fc_degree = H5F_CLOSE_WEAK;  /* File close degree for target file */
    hid_t       ret_value;              /* Return value */

    FUNC_ENTER_NOAPI(FAIL)

    /* Sanity checks */
    HDassert(p);

    /* Check external link version & flags */
    if(((*p >> 4) & 0x0F) > H5L_EXT_VERSION)
        HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad version number for external link")
    if((*p & 0x0F) & ~H5L_EXT_FLAGS_ALL)
        HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad flags for external link")
    p++;

    /* Gather some information from the external link's user data */
    file_name = (const char *)p;
    fname_len = HDstrlen(file_name);
    obj_name = (const char *)p + fname_len + 1;

    /* Get the plist structure */
    if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
        HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")

    /* Get the fapl_id set for lapl_id if any */
    if(H5P_get(plist, H5L_ACS_ELINK_FAPL_NAME, &fapl_id) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fapl for links")

    /* Get the location for the group holding the external link */
    if(H5G_loc(cur_group, &loc) < 0)
        HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get object location")

    /* get the access flags set for lapl_id if any */
    if(H5P_get(plist, H5L_ACS_ELINK_FLAGS_NAME, &intent) < 0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink file access flags")

    /* get the file access mode flags for the parent file, if they were not set
     * on lapl_id */
    if(intent == H5F_ACC_DEFAULT)
        intent = H5F_INTENT(loc.oloc->file);

    if((fapl_id == H5P_DEFAULT) && ((fapl_id = H5F_get_access_plist(loc.oloc->file, FALSE)) < 0))
	HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get parent's file access property list")

    /* Get callback_info */
    if(H5P_get(plist, H5L_ACS_ELINK_CB_NAME, &cb_info)<0)
        HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink callback info")

    /* Get file access property list */
    if(NULL == (fa_plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
	HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")

    /* Make callback if it exists */
    if(cb_info.func) {
        const char  *parent_file_name;  /* Parent file name */
        ssize_t group_name_len;         /* Length of parent group name */

        /* Get parent file name */
        parent_file_name = H5F_OPEN_NAME(loc.oloc->file);

        /* Query length of parent group name */
        if((group_name_len = H5G_get_name(&loc, NULL, (size_t) 0, NULL, lapl_id, H5AC_ind_dxpl_id)) < 0)
            HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")

        /* Account for null terminator */
        group_name_len++;

        /* Check if we need to allocate larger buffer */
        if((size_t)group_name_len > sizeof(local_group_name)) {
            if(NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
                HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't allocate buffer to hold group name, group_name_len = %Zu", group_name_len)
        } /* end if */
        else
            parent_group_name = local_group_name;

        /* Get parent group name */
        if(H5G_get_name(&loc, parent_group_name, (size_t) group_name_len, NULL, lapl_id, H5AC_ind_dxpl_id) < 0)
            HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")

        /* Make callback */
        if((cb_info.func)(parent_file_name, parent_group_name, file_name, obj_name, &intent, fapl_id, cb_info.user_data) < 0)
            HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "traversal operator failed")

        /* Check access flags */
        if((intent & H5F_ACC_TRUNC) || (intent & H5F_ACC_EXCL))
            HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
    } /* end if */
Пример #2
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
 *
 *-------------------------------------------------------------------------
 */
H5FS_t *
H5FS_create(H5F_t *f, haddr_t *fs_addr, const H5FS_create_t *fs_create,
    uint16_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 = NULL;   /* Return value */

    FUNC_ENTER_NOAPI(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->swmr_write = (H5F_INTENT(f) & H5F_ACC_SWMR_WRITE) > 0;

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

    /* Check if the free space tracker is supposed to be persistent */
    if(fs_addr) {
        /* Allocate space for the free space header */
        if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, (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, 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(ret_value)
} /* H5FS_create() */