hdf5/src/H5VLnative.c
Dana Robinson 60dd8526d7
Fix bad private FUNC_ENTER macros (#5020)
The name check in the FUNC_ENTER checks for private FUNC_ENTER macros
(which have NOAPI in the name) only checked for not having the
public form (H5Xfoo), so they could be inappropriately applied to
package-level functions (H5X__foo).

This PR fixes the bug and updates the inappropriate macros.
2024-10-28 07:35:33 -07:00

618 lines
22 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 LICENSE file, which can be found at the root of the source code *
* distribution tree, or in https://www.hdfgroup.org/licenses. *
* 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.
*/
/****************/
/* Module Setup */
/****************/
#define H5VL_FRIEND /* Suppress error about including H5VLpkg */
/***********/
/* Headers */
/***********/
#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 "H5VLpkg.h" /* Virtual Object Layer */
#include "H5VLnative_private.h" /* Native VOL connector */
/* The native VOL connector */
hid_t H5VL_NATIVE_g = H5I_INVALID_HID;
H5VL_connector_t *H5VL_NATIVE_conn_g = NULL;
#define H5VL_NATIVE_CAP_FLAGS \
(H5VL_CAP_FLAG_NATIVE_FILES | H5VL_CAP_FLAG_ATTR_BASIC | H5VL_CAP_FLAG_ATTR_MORE | \
H5VL_CAP_FLAG_DATASET_BASIC | H5VL_CAP_FLAG_DATASET_MORE | H5VL_CAP_FLAG_FILE_BASIC | \
H5VL_CAP_FLAG_FILE_MORE | H5VL_CAP_FLAG_GROUP_BASIC | H5VL_CAP_FLAG_GROUP_MORE | \
H5VL_CAP_FLAG_LINK_BASIC | H5VL_CAP_FLAG_LINK_MORE | H5VL_CAP_FLAG_OBJECT_BASIC | \
H5VL_CAP_FLAG_OBJECT_MORE | H5VL_CAP_FLAG_REF_BASIC | H5VL_CAP_FLAG_REF_MORE | H5VL_CAP_FLAG_OBJ_REF | \
H5VL_CAP_FLAG_REG_REF | H5VL_CAP_FLAG_ATTR_REF | H5VL_CAP_FLAG_STORED_DATATYPES | \
H5VL_CAP_FLAG_CREATION_ORDER | H5VL_CAP_FLAG_ITERATE | H5VL_CAP_FLAG_STORAGE_SIZE | \
H5VL_CAP_FLAG_BY_IDX | H5VL_CAP_FLAG_GET_PLIST | H5VL_CAP_FLAG_FLUSH_REFRESH | \
H5VL_CAP_FLAG_EXTERNAL_LINKS | H5VL_CAP_FLAG_HARD_LINKS | H5VL_CAP_FLAG_SOFT_LINKS | \
H5VL_CAP_FLAG_UD_LINKS | H5VL_CAP_FLAG_TRACK_TIMES | H5VL_CAP_FLAG_MOUNT | H5VL_CAP_FLAG_FILTERS | \
H5VL_CAP_FLAG_FILL_VALUES)
/* Native VOL connector class struct */
static const H5VL_class_t H5VL_native_cls_g = {
H5VL_VERSION, /* VOL class struct version */
H5VL_NATIVE_VALUE, /* value */
H5VL_NATIVE_NAME, /* name */
H5VL_NATIVE_VERSION, /* connector version */
H5VL_NATIVE_CAP_FLAGS, /* capability flags */
NULL, /* initialize */
NULL, /* 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_get_cap_flags, /* get_cap_flags */
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 set up an ID for it.
*
* Return: SUCCEED/FAIL
*
*-------------------------------------------------------------------------
*/
herr_t
H5VL__native_register(void)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Register the native VOL connector, if it isn't already */
if (NULL == H5VL_NATIVE_conn_g)
if (NULL ==
(H5VL_NATIVE_conn_g = H5VL__register_connector(&H5VL_native_cls_g, H5P_VOL_INITIALIZE_DEFAULT)))
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't register native VOL connector");
/* Get ID for connector */
if (H5I_VOL != H5I_get_type(H5VL_NATIVE_g)) {
if ((H5VL_NATIVE_g = H5I_register(H5I_VOL, H5VL_NATIVE_conn_g, false)) < 0)
HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't create ID for native VOL connector");
/* ID is holding a reference to the connector */
H5VL_conn_inc_rc(H5VL_NATIVE_conn_g);
}
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL__native_register() */
/*---------------------------------------------------------------------------
* Function: H5VL__native_unregister
*
* Purpose: Shut down the native VOL
*
* Returns: SUCCEED (Can't fail)
*
*---------------------------------------------------------------------------
*/
herr_t
H5VL__native_unregister(void)
{
FUNC_ENTER_PACKAGE_NOERR
/* Reset VOL connector info */
H5VL_NATIVE_g = H5I_INVALID_HID;
H5VL_NATIVE_conn_g = NULL;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5VL__native_unregister() */
/*---------------------------------------------------------------------------
* 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 statically 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 */
assert(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_introspect_get_cap_flags
*
* Purpose: Query the capability flags for this connector.
*
* Note: This routine is in this file so that it can return the field
* from the statically declared class struct.
*
* Returns: SUCCEED (Can't fail)
*
*---------------------------------------------------------------------------
*/
herr_t
H5VL__native_introspect_get_cap_flags(const void H5_ATTR_UNUSED *info, uint64_t *cap_flags)
{
FUNC_ENTER_PACKAGE_NOERR
/* Sanity check */
assert(cap_flags);
/* Set the flags from the connector's field */
*cap_flags = H5VL_native_cls_g.cap_flags;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5VL__native_introspect_get_cap_flags() */
/*-------------------------------------------------------------------------
* 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 */
assert(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 struct pointer */
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
/* check arguments */
assert(obj);
assert(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)
/* 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;
bool is_native_vol_obj;
/* Get the location object */
if (NULL == (vol_obj_container = H5VL_vol_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");
assert(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 */
assert(obj);
assert(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 */
memset(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)
/* 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;
bool is_native_vol_obj;
/* Get the location object */
if (NULL == (vol_obj_container = H5VL_vol_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");
assert(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 */
assert(obj);
assert(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_EVENTSET:
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 */