560 lines
21 KiB
C
560 lines
21 KiB
C
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Copyright by The HDF Group. *
|
||
* 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 COPYING file, which can be found at the root of the source code *
|
||
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
|
||
* If you do not have access to either file, you may request a copy from *
|
||
* help@hdfgroup.org. *
|
||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||
|
||
/*
|
||
* Purpose: The native VOL connector where access is to a single HDF5 file
|
||
* using HDF5 VFDs.
|
||
*/
|
||
|
||
#include "H5private.h" /* Generic Functions */
|
||
#include "H5Aprivate.h" /* Attributes */
|
||
#include "H5Dprivate.h" /* Datasets */
|
||
#include "H5Eprivate.h" /* Error handling */
|
||
#include "H5Fprivate.h" /* Files */
|
||
#include "H5Gprivate.h" /* Groups */
|
||
#include "H5Iprivate.h" /* IDs */
|
||
#include "H5Oprivate.h" /* Object headers */
|
||
#include "H5Pprivate.h" /* Property lists */
|
||
#include "H5Tprivate.h" /* Datatypes */
|
||
#include "H5VLprivate.h" /* Virtual Object Layer */
|
||
|
||
#include "H5VLnative_private.h" /* Native VOL connector */
|
||
|
||
|
||
/* The VOL connector identification number */
|
||
static hid_t H5VL_NATIVE_ID_g = H5I_INVALID_HID;
|
||
|
||
/* Prototypes */
|
||
static herr_t H5VL__native_term(void);
|
||
|
||
/* Native VOL connector class struct */
|
||
static const H5VL_class_t H5VL_native_cls_g = {
|
||
H5VL_NATIVE_VERSION, /* version */
|
||
H5VL_NATIVE_VALUE, /* value */
|
||
H5VL_NATIVE_NAME, /* name */
|
||
0, /* capability flags */
|
||
NULL, /* initialize */
|
||
H5VL__native_term, /* terminate */
|
||
{ /* info_cls */
|
||
(size_t)0, /* info size */
|
||
NULL, /* info copy */
|
||
NULL, /* info compare */
|
||
NULL, /* info free */
|
||
NULL, /* info to str */
|
||
NULL /* str to info */
|
||
},
|
||
{ /* wrap_cls */
|
||
NULL, /* get_object */
|
||
NULL, /* get_wrap_ctx */
|
||
NULL, /* wrap_object */
|
||
NULL, /* unwrap_object */
|
||
NULL /* free_wrap_ctx */
|
||
},
|
||
{ /* attribute_cls */
|
||
H5VL__native_attr_create, /* create */
|
||
H5VL__native_attr_open, /* open */
|
||
H5VL__native_attr_read, /* read */
|
||
H5VL__native_attr_write, /* write */
|
||
H5VL__native_attr_get, /* get */
|
||
H5VL__native_attr_specific, /* specific */
|
||
H5VL__native_attr_optional, /* optional */
|
||
H5VL__native_attr_close /* close */
|
||
},
|
||
{ /* dataset_cls */
|
||
H5VL__native_dataset_create, /* create */
|
||
H5VL__native_dataset_open, /* open */
|
||
H5VL__native_dataset_read, /* read */
|
||
H5VL__native_dataset_write, /* write */
|
||
H5VL__native_dataset_get, /* get */
|
||
H5VL__native_dataset_specific, /* specific */
|
||
H5VL__native_dataset_optional, /* optional */
|
||
H5VL__native_dataset_close /* close */
|
||
},
|
||
{ /* datatype_cls */
|
||
H5VL__native_datatype_commit, /* commit */
|
||
H5VL__native_datatype_open, /* open */
|
||
H5VL__native_datatype_get, /* get */
|
||
H5VL__native_datatype_specific, /* specific */
|
||
NULL, /* optional */
|
||
H5VL__native_datatype_close /* close */
|
||
},
|
||
{ /* file_cls */
|
||
H5VL__native_file_create, /* create */
|
||
H5VL__native_file_open, /* open */
|
||
H5VL__native_file_get, /* get */
|
||
H5VL__native_file_specific, /* specific */
|
||
H5VL__native_file_optional, /* optional */
|
||
H5VL__native_file_close /* close */
|
||
},
|
||
{ /* group_cls */
|
||
H5VL__native_group_create, /* create */
|
||
H5VL__native_group_open, /* open */
|
||
H5VL__native_group_get, /* get */
|
||
H5VL__native_group_specific, /* specific */
|
||
H5VL__native_group_optional, /* optional */
|
||
H5VL__native_group_close /* close */
|
||
},
|
||
{ /* link_cls */
|
||
H5VL__native_link_create, /* create */
|
||
H5VL__native_link_copy, /* copy */
|
||
H5VL__native_link_move, /* move */
|
||
H5VL__native_link_get, /* get */
|
||
H5VL__native_link_specific, /* specific */
|
||
NULL /* optional */
|
||
},
|
||
{ /* object_cls */
|
||
H5VL__native_object_open, /* open */
|
||
H5VL__native_object_copy, /* copy */
|
||
H5VL__native_object_get, /* get */
|
||
H5VL__native_object_specific, /* specific */
|
||
H5VL__native_object_optional /* optional */
|
||
},
|
||
{ /* introspect_cls */
|
||
H5VL__native_introspect_get_conn_cls, /* get_conn_cls */
|
||
H5VL__native_introspect_opt_query, /* opt_query */
|
||
},
|
||
{ /* request_cls */
|
||
NULL, /* wait */
|
||
NULL, /* notify */
|
||
NULL, /* cancel */
|
||
NULL, /* specific */
|
||
NULL, /* optional */
|
||
NULL /* free */
|
||
},
|
||
{ /* blob_cls */
|
||
H5VL__native_blob_put, /* put */
|
||
H5VL__native_blob_get, /* get */
|
||
H5VL__native_blob_specific, /* specific */
|
||
NULL /* optional */
|
||
},
|
||
{ /* token_cls */
|
||
H5VL__native_token_cmp, /* cmp */
|
||
H5VL__native_token_to_str, /* to_str */
|
||
H5VL__native_str_to_token /* from_str */
|
||
},
|
||
NULL /* optional */
|
||
};
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5VL_native_register
|
||
*
|
||
* Purpose: Register the native VOL connector and retrieve an ID for it.
|
||
*
|
||
* Return: Success: The ID for the native connector
|
||
* Failure: H5I_INVALID_HID
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
hid_t
|
||
H5VL_native_register(void)
|
||
{
|
||
hid_t ret_value = H5I_INVALID_HID; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(H5I_INVALID_HID)
|
||
|
||
/* Register the native VOL connector, if it isn't already */
|
||
if(H5I_INVALID_HID == H5VL_NATIVE_ID_g)
|
||
if((H5VL_NATIVE_ID_g = H5VL_register_connector(&H5VL_native_cls_g, TRUE, H5P_VOL_INITIALIZE_DEFAULT)) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTINSERT, H5I_INVALID_HID, "can't create ID for native VOL connector")
|
||
|
||
/* Set return value */
|
||
ret_value = H5VL_NATIVE_ID_g;
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value)
|
||
} /* end H5VL_native_register() */
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
* Function: H5VL__native_term
|
||
*
|
||
* Purpose: Shut down the native VOL
|
||
*
|
||
* Returns: SUCCEED (Can't fail)
|
||
*
|
||
*---------------------------------------------------------------------------
|
||
*/
|
||
static herr_t
|
||
H5VL__native_term(void)
|
||
{
|
||
FUNC_ENTER_STATIC_NOERR
|
||
|
||
/* Reset VOL ID */
|
||
H5VL_NATIVE_ID_g = H5I_INVALID_HID;
|
||
|
||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||
} /* end H5VL__native_term() */
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
* Function: H5VL__native_introspect_get_conn_cls
|
||
*
|
||
* Purpose: Query the connector class.
|
||
*
|
||
* Note: This routine is in this file so that it can return the address
|
||
* of the staticly declared class struct.
|
||
*
|
||
* Returns: SUCCEED (Can't fail)
|
||
*
|
||
*---------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5VL__native_introspect_get_conn_cls(void H5_ATTR_UNUSED *obj,
|
||
H5VL_get_conn_lvl_t H5_ATTR_UNUSED lvl, const H5VL_class_t **conn_cls)
|
||
{
|
||
FUNC_ENTER_PACKAGE_NOERR
|
||
|
||
/* Sanity check */
|
||
HDassert(conn_cls);
|
||
|
||
/* Retrieve the native VOL connector class */
|
||
*conn_cls = &H5VL_native_cls_g;
|
||
|
||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||
} /* end H5VL__native_introspect_get_conn_cls() */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5VL_native_get_file_addr_len
|
||
*
|
||
* Purpose: Convenience function to get a file's address length from a
|
||
* location ID. Useful when you have to encode/decode addresses
|
||
* to/from tokens.
|
||
*
|
||
* Return: SUCCEED/FAIL
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5VL_native_get_file_addr_len(hid_t loc_id, size_t *addr_len)
|
||
{
|
||
H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */
|
||
void *vol_obj = NULL; /* VOL Object of loc_id */
|
||
herr_t ret_value = SUCCEED; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(FAIL)
|
||
|
||
/* check arguments */
|
||
HDassert(addr_len);
|
||
|
||
/* Get object type */
|
||
if((vol_obj_type = H5I_get_type(loc_id)) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier")
|
||
|
||
/* Retrieve underlying VOL object */
|
||
if(NULL == (vol_obj = H5VL_object(loc_id)))
|
||
HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier")
|
||
|
||
/* Retrieve file address length */
|
||
if(H5VL__native_get_file_addr_len(vol_obj, vol_obj_type, addr_len) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get file address length")
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value)
|
||
} /* end H5VL_native_get_file_addr_len() */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5VL__native_get_file_addr_len
|
||
*
|
||
* Purpose: Convenience function to get a file's address length from a
|
||
* VOL object. Useful when you have to encode/decode addresses
|
||
* to/from tokens.
|
||
*
|
||
* Return: SUCCEED/FAIL
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5VL__native_get_file_addr_len(void *obj, H5I_type_t obj_type, size_t *addr_len)
|
||
{
|
||
H5F_t *file = NULL; /* File stuct pointer */
|
||
herr_t ret_value = SUCCEED;
|
||
|
||
FUNC_ENTER_NOAPI(FAIL)
|
||
|
||
/* check arguments */
|
||
HDassert(obj);
|
||
HDassert(addr_len);
|
||
|
||
/* Retrieve file from the VOL object */
|
||
if(H5VL_native_get_file_struct(obj, obj_type, &file) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get file from VOL object")
|
||
|
||
/* Get the length of an address in this file */
|
||
*addr_len = H5F_SIZEOF_ADDR(file);
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value)
|
||
} /* end H5VL__native_get_file_addr_len() */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5VLnative_addr_to_token
|
||
*
|
||
* Purpose: Converts a native VOL haddr_t address to an abstract VOL token.
|
||
*
|
||
* Return: SUCCEED/FAIL
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5VLnative_addr_to_token(hid_t loc_id, haddr_t addr, H5O_token_t *token)
|
||
{
|
||
H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */
|
||
void *vol_obj = NULL; /* VOL Object of loc_id */
|
||
herr_t ret_value = SUCCEED; /* Return value */
|
||
|
||
FUNC_ENTER_API(FAIL)
|
||
H5TRACE3("e", "ia*k", loc_id, addr, token);
|
||
|
||
/* Check args */
|
||
if(NULL == token)
|
||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "token pointer can't be NULL")
|
||
|
||
/* Get object type */
|
||
if((vol_obj_type = H5I_get_type(loc_id)) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier")
|
||
|
||
/* Retrieve underlying VOL object */
|
||
if(NULL == (vol_obj = H5VL_object(loc_id)))
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object")
|
||
|
||
#ifndef NDEBUG
|
||
{
|
||
H5VL_object_t *vol_obj_container;
|
||
hbool_t is_native_vol_obj;
|
||
|
||
/* Get the location object */
|
||
if(NULL == (vol_obj_container = (H5VL_object_t *)H5I_object(loc_id)))
|
||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
|
||
|
||
/* Make sure that the VOL object is a native connector object */
|
||
if(H5VL_object_is_native(vol_obj_container, &is_native_vol_obj) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object")
|
||
|
||
HDassert(is_native_vol_obj && "not a native VOL connector object");
|
||
}
|
||
#endif
|
||
|
||
/* Convert the haddr_t to an object token */
|
||
if(H5VL_native_addr_to_token(vol_obj, vol_obj_type, addr, token) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTSERIALIZE, FAIL, "couldn't serialize haddr_t into object token")
|
||
|
||
done:
|
||
FUNC_LEAVE_API(ret_value)
|
||
} /* end H5VLnative_addr_to_token() */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5VL_native_addr_to_token
|
||
*
|
||
* Purpose: Converts a native VOL haddr_t address to an abstract VOL token.
|
||
*
|
||
* Return: SUCCEED/FAIL
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5VL_native_addr_to_token(void *obj, H5I_type_t obj_type, haddr_t addr, H5O_token_t *token)
|
||
{
|
||
uint8_t *p;
|
||
size_t addr_len = 0; /* Size of haddr_t */
|
||
herr_t ret_value = SUCCEED;
|
||
|
||
FUNC_ENTER_NOAPI(FAIL)
|
||
|
||
/* Check args */
|
||
HDassert(obj);
|
||
HDassert(token);
|
||
|
||
/* Get the length of an haddr_t in the file */
|
||
if(H5VL__native_get_file_addr_len(obj, obj_type, &addr_len) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get length of haddr_t from VOL object")
|
||
|
||
/* Ensure that token is initialized */
|
||
HDmemset(token, 0, sizeof(H5O_token_t));
|
||
|
||
/* Encode token */
|
||
p = (uint8_t *)token;
|
||
H5F_addr_encode_len(addr_len, &p, addr);
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value)
|
||
} /* end H5VL_native_addr_to_token() */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5VLnative_token_to_addr
|
||
*
|
||
* Purpose: Converts an abstract VOL token to a native VOL haddr_t address.
|
||
*
|
||
* Return: SUCCEED/FAIL
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5VLnative_token_to_addr(hid_t loc_id, H5O_token_t token, haddr_t *addr)
|
||
{
|
||
H5I_type_t vol_obj_type = H5I_BADID; /* Object type of loc_id */
|
||
void *vol_obj = NULL; /* VOL Object of loc_id */
|
||
herr_t ret_value = SUCCEED; /* Return value */
|
||
|
||
FUNC_ENTER_API(FAIL)
|
||
H5TRACE3("e", "ik*a", loc_id, token, addr);
|
||
|
||
/* Check args */
|
||
if(NULL == addr)
|
||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr pointer can't be NULL")
|
||
|
||
/* Get object type */
|
||
if((vol_obj_type = H5I_get_type(loc_id)) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "invalid location identifier")
|
||
|
||
/* Retrieve underlying VOL object */
|
||
if(NULL == (vol_obj = H5VL_object(loc_id)))
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get underlying VOL object")
|
||
|
||
#ifndef NDEBUG
|
||
{
|
||
H5VL_object_t *vol_obj_container;
|
||
hbool_t is_native_vol_obj;
|
||
|
||
/* Get the location object */
|
||
if(NULL == (vol_obj_container = (H5VL_object_t *)H5I_object(loc_id)))
|
||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
|
||
|
||
/* Make sure that the VOL object is a native connector object */
|
||
if(H5VL_object_is_native(vol_obj_container, &is_native_vol_obj) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if VOL object is native connector object")
|
||
|
||
HDassert(is_native_vol_obj && "not a native VOL connector object");
|
||
}
|
||
#endif
|
||
|
||
/* Convert the object token to an haddr_t */
|
||
if(H5VL_native_token_to_addr(vol_obj, vol_obj_type, token, addr) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTUNSERIALIZE, FAIL, "couldn't deserialize object token into haddr_t")
|
||
|
||
done:
|
||
FUNC_LEAVE_API(ret_value)
|
||
} /* end H5VLnative_token_to_addr() */
|
||
|
||
|
||
/*-------------------------------------------------------------------------
|
||
* Function: H5VL_native_token_to_addr
|
||
*
|
||
* Purpose: Converts an abstract VOL token to a native VOL haddr_t address.
|
||
*
|
||
* Return: SUCCEED/FAIL
|
||
*
|
||
*-------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5VL_native_token_to_addr(void *obj, H5I_type_t obj_type, H5O_token_t token, haddr_t *addr)
|
||
{
|
||
const uint8_t *p;
|
||
size_t addr_len = 0; /* Size of haddr_t */
|
||
herr_t ret_value = SUCCEED;
|
||
|
||
FUNC_ENTER_NOAPI(FAIL)
|
||
|
||
/* Check args */
|
||
HDassert(obj);
|
||
HDassert(addr);
|
||
|
||
/* Get the length of an haddr_t in the file */
|
||
if(H5VL__native_get_file_addr_len(obj, obj_type, &addr_len) < 0)
|
||
HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "couldn't get length of haddr_t from VOL object")
|
||
|
||
/* Decode token */
|
||
p = (const uint8_t *)&token;
|
||
H5F_addr_decode_len(addr_len, &p, addr);
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value)
|
||
} /* end H5VL_native_token_to_addr() */
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
* Function: H5VL_native_get_file_struct
|
||
*
|
||
* Purpose: Utility routine to get file struct for an object
|
||
*
|
||
* Returns: SUCCEED/FAIL
|
||
*
|
||
*---------------------------------------------------------------------------
|
||
*/
|
||
herr_t
|
||
H5VL_native_get_file_struct(void *obj, H5I_type_t type, H5F_t **file)
|
||
{
|
||
H5O_loc_t *oloc = NULL; /* Object location for ID */
|
||
herr_t ret_value = SUCCEED; /* Return value */
|
||
|
||
FUNC_ENTER_NOAPI(FAIL);
|
||
|
||
*file = NULL;
|
||
|
||
switch(type) {
|
||
case H5I_FILE:
|
||
*file = (H5F_t *)obj;
|
||
break;
|
||
|
||
case H5I_GROUP:
|
||
oloc = H5G_oloc((H5G_t *)obj);
|
||
break;
|
||
|
||
case H5I_DATATYPE:
|
||
oloc = H5T_oloc((H5T_t *)obj);
|
||
break;
|
||
|
||
case H5I_DATASET:
|
||
oloc = H5D_oloc((H5D_t *)obj);
|
||
break;
|
||
|
||
case H5I_ATTR:
|
||
oloc = H5A_oloc((H5A_t *)obj);
|
||
break;
|
||
|
||
case H5I_MAP:
|
||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "maps not supported in native VOL connector")
|
||
|
||
case H5I_UNINIT:
|
||
case H5I_BADID:
|
||
case H5I_DATASPACE:
|
||
case H5I_VFL:
|
||
case H5I_VOL:
|
||
case H5I_GENPROP_CLS:
|
||
case H5I_GENPROP_LST:
|
||
case H5I_ERROR_CLASS:
|
||
case H5I_ERROR_MSG:
|
||
case H5I_ERROR_STACK:
|
||
case H5I_SPACE_SEL_ITER:
|
||
case H5I_NTYPES:
|
||
default:
|
||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
|
||
} /* end switch */
|
||
|
||
/* Set return value for objects (not files) */
|
||
if(oloc)
|
||
*file = oloc->file;
|
||
|
||
/* Couldn't find a file struct */
|
||
if(!*file)
|
||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not associated with a file")
|
||
|
||
done:
|
||
FUNC_LEAVE_NOAPI(ret_value)
|
||
} /* H5VL_native_get_file_struct */
|
||
|