summaryrefslogtreecommitdiffstats
path: root/src/H5FD.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5FD.c')
-rw-r--r--src/H5FD.c581
1 files changed, 548 insertions, 33 deletions
diff --git a/src/H5FD.c b/src/H5FD.c
index abda921..1887e18 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -61,9 +61,6 @@ static herr_t H5FD__query(const H5FD_t *f, unsigned long *flags /*out*/);
/* Package Variables */
/*********************/
-/* Package initialization variable */
-hbool_t H5_PKG_INIT_VAR = FALSE;
-
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -95,20 +92,20 @@ static const H5I_class_t H5I_VFL_CLS[1] = {{
}};
/*-------------------------------------------------------------------------
- * Function: H5FD__init_package
- *
- * Purpose: Initialize the virtual file layer.
+ * Function: H5FD_init
*
- * Return: SUCCEED/FAIL
+ * Purpose: Initialize the interface from some other layer.
*
+ * Return: Success: non-negative
+ * Failure: negative
*-------------------------------------------------------------------------
*/
herr_t
-H5FD__init_package(void)
+H5FD_init(void)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_PACKAGE
+ FUNC_ENTER_NOAPI(FAIL)
if (H5I_register_type(H5I_VFL_CLS) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize interface")
@@ -118,7 +115,7 @@ H5FD__init_package(void)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD__init_package() */
+}
/*-------------------------------------------------------------------------
* Function: H5FD_term_package
@@ -142,20 +139,14 @@ H5FD_term_package(void)
FUNC_ENTER_NOAPI_NOINIT_NOERR
- if (H5_PKG_INIT_VAR) {
- if (H5I_nmembers(H5I_VFL) > 0) {
- (void)H5I_clear_type(H5I_VFL, FALSE, FALSE);
- n++; /*H5I*/
- } /* end if */
- else {
- /* Destroy the VFL driver ID group */
- n += (H5I_dec_type_ref(H5I_VFL) > 0);
-
- /* Mark closed */
- if (0 == n)
- H5_PKG_INIT_VAR = FALSE;
- } /* end else */
- } /* end if */
+ if (H5I_nmembers(H5I_VFL) > 0) {
+ (void)H5I_clear_type(H5I_VFL, FALSE, FALSE);
+ n++; /*H5I*/
+ } /* end if */
+ else {
+ /* Destroy the VFL driver ID group */
+ n += (H5I_dec_type_ref(H5I_VFL) > 0);
+ } /* end else */
FUNC_LEAVE_NOAPI(n)
} /* end H5FD_term_package() */
@@ -165,7 +156,7 @@ H5FD_term_package(void)
*
* Purpose: Frees a file driver class struct and returns an indication of
* success. This function is used as the free callback for the
- * virtual file layer object identifiers (cf H5FD__init_package).
+ * virtual file layer object identifiers (cf H5FD_init).
*
* Return: SUCCEED/FAIL
*
@@ -223,6 +214,8 @@ H5FDregister(const H5FD_class_t *cls)
/* Check arguments */
if (!cls)
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "null class pointer is disallowed")
+ if (cls->version != H5FD_CLASS_VERSION)
+ HGOTO_ERROR(H5E_ARGS, H5E_VERSION, H5I_INVALID_HID, "wrong file driver version #")
if (!cls->open || !cls->close)
HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID,
"'open' and/or 'close' methods are not defined")
@@ -301,6 +294,62 @@ done:
} /* end H5FD_register() */
/*-------------------------------------------------------------------------
+ * Function: H5FDis_driver_registered_by_name
+ *
+ * Purpose: Tests whether a VFD class has been registered or not
+ * according to a supplied driver name.
+ *
+ * Return: >0 if a VFD with that name has been registered
+ * 0 if a VFD with that name has NOT been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FDis_driver_registered_by_name(const char *driver_name)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("t", "*s", driver_name);
+
+ /* Check if driver with this name is registered */
+ if ((ret_value = H5FD_is_driver_registered_by_name(driver_name, NULL)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if VFD is registered")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDis_driver_registered_by_name() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FDis_driver_registered_by_value
+ *
+ * Purpose: Tests whether a VFD class has been registered or not
+ * according to a supplied driver value (ID).
+ *
+ * Return: >0 if a VFD with that value has been registered
+ * 0 if a VFD with that value hasn't been registered
+ * <0 on errors
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5FDis_driver_registered_by_value(H5FD_class_value_t driver_value)
+{
+ htri_t ret_value = FALSE;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("t", "DV", driver_value);
+
+ /* Check if driver with this value is registered */
+ if ((ret_value = H5FD_is_driver_registered_by_value(driver_value, NULL)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if VFD is registered")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDis_driver_registered_by_value() */
+
+/*-------------------------------------------------------------------------
* Function: H5FDunregister
*
* Purpose: Removes a driver ID from the library. This in no way affects
@@ -398,7 +447,7 @@ H5FD_sb_size(H5FD_t *file)
{
hsize_t ret_value = 0;
- FUNC_ENTER_NOAPI(0)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(file);
@@ -408,7 +457,6 @@ H5FD_sb_size(H5FD_t *file)
if (file->cls->sb_size)
ret_value = (file->cls->sb_size)(file);
-done:
FUNC_LEAVE_NOAPI(ret_value)
}
@@ -536,7 +584,7 @@ H5FD_fapl_get(H5FD_t *file)
{
void *ret_value = NULL;
- FUNC_ENTER_NOAPI(NULL)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(file);
@@ -546,7 +594,6 @@ H5FD_fapl_get(H5FD_t *file)
if (file->cls->fapl_get)
ret_value = (file->cls->fapl_get)(file);
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_fapl_get() */
@@ -883,7 +930,7 @@ H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2)
{
int ret_value = -1; /* Return value */
- FUNC_ENTER_NOAPI(-1) /* return value is arbitrary */
+ FUNC_ENTER_NOAPI_NOERR; /* return value is arbitrary */
if ((!f1 || !f1->cls) && (!f2 || !f2->cls))
HGOTO_DONE(0)
@@ -1244,7 +1291,7 @@ H5FD_get_maxaddr(const H5FD_t *file)
{
haddr_t ret_value = HADDR_UNDEF; /* Return value */
- FUNC_ENTER_NOAPI(HADDR_UNDEF)
+ FUNC_ENTER_NOAPI_NOERR
/* Sanity checks */
HDassert(file);
@@ -1252,7 +1299,6 @@ H5FD_get_maxaddr(const H5FD_t *file)
/* Set return value */
ret_value = file->maxaddr;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5FD_get_maxaddr() */
@@ -1324,7 +1370,7 @@ H5FD_get_fs_type_map(const H5FD_t *file, H5FD_mem_t *type_map)
HDassert(file->cls);
HDassert(type_map);
- /* Check for VFD class providing a type map retrieval rouine */
+ /* Check for VFD class providing a type map retrieval routine */
if (file->cls->get_type_map) {
/* Retrieve type mapping for this file */
if ((file->cls->get_type_map)(file, type_map) < 0)
@@ -1436,6 +1482,370 @@ done:
} /* end H5FDwrite() */
/*-------------------------------------------------------------------------
+ * Function: H5FDread_vector
+ *
+ * Purpose: Perform count reads from the specified file at the offsets
+ * provided in the addrs array, with the lengths and memory
+ * types provided in the sizes and types arrays. Data read
+ * is returned in the buffers provided in the bufs array.
+ *
+ * All reads are done according to the data transfer property
+ * list dxpl_id (which may be the constant H5P_DEFAULT).
+ *
+ * Return: Success: SUCCEED
+ * All reads have completed successfully, and
+ * the results havce been into the supplied
+ * buffers.
+ *
+ * Failure: FAIL
+ * The contents of supplied buffers are undefined.
+ *
+ * Programmer: JRM -- 6/10/20
+ *
+ * Changes: None.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FDread_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
+ size_t sizes[], void *bufs[] /* out */)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "*#iIu*Mt*a*zx", file, dxpl_id, count, types, addrs, sizes, bufs);
+
+ /* Check arguments */
+ if (!file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
+
+ if (!file->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
+
+ if ((!types) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "types parameter can't be NULL if count is positive")
+
+ if ((!addrs) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addrs parameter can't be NULL if count is positive")
+
+ if ((!sizes) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes parameter can't be NULL if count is positive")
+
+ if ((!bufs) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive")
+
+ if ((count > 0) && (sizes[0] == 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes[0] can't be 0")
+
+ if ((count > 0) && (types[0] == H5FD_MEM_NOLIST))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "count[0] can't be H5FD_MEM_NOLIST")
+
+ /* Get the default dataset transfer property list if the user
+ * didn't provide one
+ */
+ if (H5P_DEFAULT == dxpl_id) {
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
+ }
+ else {
+ if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
+ }
+
+ /* Set DXPL for operation */
+ H5CX_set_dxpl(dxpl_id);
+
+ /* Call private function */
+ /* (Note compensating for base addresses addition in internal routine) */
+ if (H5FD_read_vector(file, count, types, addrs, sizes, bufs) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file vector read request failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDread_vector() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FDwrite_vector
+ *
+ * Purpose: Perform count writes to the specified file at the offsets
+ * provided in the addrs array, with the lengths and memory
+ * types provided in the sizes and types arrays. Data to be
+ * written is in the buffers provided in the bufs array.
+ *
+ * All writes are done according to the data transfer property
+ * list dxpl_id (which may be the constant H5P_DEFAULT).
+ *
+ * Return: Success: SUCCEED
+ * All writes have completed successfully
+ *
+ * Failure: FAIL
+ * One or more of the writes failed.
+ *
+ * Programmer: JRM -- 6/10/20
+ *
+ * Changes: None.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FDwrite_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[],
+ size_t sizes[], const void *bufs[] /* in */)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE7("e", "*#iIu*Mt*a*z**x", file, dxpl_id, count, types, addrs, sizes, bufs);
+
+ /* Check arguments */
+ if (!file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
+
+ if (!file->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
+
+ if ((!types) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "types parameter can't be NULL if count is positive")
+
+ if ((!addrs) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addrs parameter can't be NULL if count is positive")
+
+ if ((!sizes) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes parameter can't be NULL if count is positive")
+
+ if ((!bufs) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive")
+
+ if ((count > 0) && (sizes[0] == 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes[0] can't be 0")
+
+ if ((count > 0) && (types[0] == H5FD_MEM_NOLIST))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "count[0] can't be H5FD_MEM_NOLIST")
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if (H5P_DEFAULT == dxpl_id) {
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
+ }
+ else {
+ if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
+ }
+
+ /* Set DXPL for operation */
+ H5CX_set_dxpl(dxpl_id);
+
+ /* Call private function */
+ /* (Note compensating for base address addition in internal routine) */
+ if (H5FD_write_vector(file, count, types, addrs, sizes, bufs) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file vector write request failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDwrite_vector() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FDread_selection
+ *
+ * Purpose: Perform count reads from the specified file at the
+ * locations selected in the dataspaces in the file_spaces
+ * array, with each of those dataspaces starting at the file
+ * address specified by the corresponding element of the
+ * offsets array, and with the size of each element in the
+ * dataspace specified by the corresponding element of the
+ * element_sizes array. The memory type provided by type is
+ * the same for all selections. Data read is returned in
+ * the locations selected in the dataspaces in the
+ * mem_spaces array, within the buffers provided in the
+ * corresponding elements of the bufs array.
+ *
+ * If i > 0 and element_sizes[i] == 0, presume
+ * element_sizes[n] = element_sizes[i-1] for all n >= i and
+ * < count.
+ *
+ * If the underlying VFD supports selection reads, pass the
+ * call through directly.
+ *
+ * If it doesn't, convert the selection read into a sequence
+ * of individual reads.
+ *
+ * All reads are done according to the data transfer property
+ * list dxpl_id (which may be the constant H5P_DEFAULT).
+ *
+ * Return: Success: SUCCEED
+ * All reads have completed successfully, and
+ * the results havce been into the supplied
+ * buffers.
+ *
+ * Failure: FAIL
+ * The contents of supplied buffers are undefined.
+ *
+ * Programmer: NAF -- 5/19/21
+ *
+ * Changes: None.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FDread_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, hid_t mem_space_ids[],
+ hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], void *bufs[] /* out */)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("e", "*#MtiIu*i*i*a*zx", file, type, dxpl_id, count, mem_space_ids, file_space_ids, offsets,
+ element_sizes, bufs);
+
+ /* Check arguments */
+ if (!file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
+
+ if (!file->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
+
+ if ((!mem_space_ids) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_spaces parameter can't be NULL if count is positive")
+
+ if ((!file_space_ids) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_spaces parameter can't be NULL if count is positive")
+
+ if ((!offsets) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offsets parameter can't be NULL if count is positive")
+
+ if ((!element_sizes) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "element_sizes parameter can't be NULL if count is positive")
+
+ if ((!bufs) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive")
+
+ if ((count > 0) && (element_sizes[0] == 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes[0] can't be 0")
+
+ if ((count > 0) && (bufs[0] == NULL))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs[0] can't be NULL")
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if (H5P_DEFAULT == dxpl_id) {
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
+ }
+ else {
+ if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
+ }
+
+ /* Set DXPL for operation */
+ H5CX_set_dxpl(dxpl_id);
+
+ /* Call private function */
+ /* (Note compensating for base address addition in internal routine) */
+ if (H5FD_read_selection_id(file, type, count, mem_space_ids, file_space_ids, offsets, element_sizes,
+ bufs) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "file selection read request failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDread_selection() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FDwrite_selection
+ *
+ * Purpose: Perform count writes to the specified file at the
+ * locations selected in the dataspaces in the file_spaces
+ * array, with each of those dataspaces starting at the file
+ * address specified by the corresponding element of the
+ * offsets array, and with the size of each element in the
+ * dataspace specified by the corresponding element of the
+ * element_sizes array. The memory type provided by type is
+ * the same for all selections. Data write is from
+ * the locations selected in the dataspaces in the
+ * mem_spaces array, within the buffers provided in the
+ * corresponding elements of the bufs array.
+ *
+ * If i > 0 and element_sizes[i] == 0, presume
+ * element_sizes[n] = element_sizes[i-1] for all n >= i and
+ * < count.
+ *
+ * If the underlying VFD supports selection writes, pass the
+ * call through directly.
+ *
+ * If it doesn't, convert the selection write into a sequence
+ * of individual writes.
+ *
+ * All writes are done according to the data transfer property
+ * list dxpl_id (which may be the constant H5P_DEFAULT).
+ *
+ * Return: Success: SUCCEED
+ * All writes have completed successfully
+ *
+ * Failure: FAIL
+ * One or more of the writes failed.
+ *
+ * Programmer: NAF -- 5/14/21
+ *
+ * Changes: None.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FDwrite_selection(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, uint32_t count, hid_t mem_space_ids[],
+ hid_t file_space_ids[], haddr_t offsets[], size_t element_sizes[], const void *bufs[])
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE9("e", "*#MtiIu*i*i*a*z**x", file, type, dxpl_id, count, mem_space_ids, file_space_ids, offsets,
+ element_sizes, bufs);
+
+ /* Check arguments */
+ if (!file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
+
+ if (!file->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
+
+ if ((!mem_space_ids) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "mem_spaces parameter can't be NULL if count is positive")
+
+ if ((!file_space_ids) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file_spaces parameter can't be NULL if count is positive")
+
+ if ((!offsets) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "offsets parameter can't be NULL if count is positive")
+
+ if ((!element_sizes) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "element_sizes parameter can't be NULL if count is positive")
+
+ if ((!bufs) && (count > 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs parameter can't be NULL if count is positive")
+
+ if ((count > 0) && (element_sizes[0] == 0))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "sizes[0] can't be 0")
+
+ if ((count > 0) && (bufs[0] == NULL))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bufs[0] can't be NULL")
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if (H5P_DEFAULT == dxpl_id) {
+ dxpl_id = H5P_DATASET_XFER_DEFAULT;
+ }
+ else {
+ if (TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list")
+ }
+
+ /* Set DXPL for operation */
+ H5CX_set_dxpl(dxpl_id);
+
+ /* Call private function */
+ /* (Note compensating for base address addition in internal routine) */
+ if (H5FD_write_selection_id(file, type, count, mem_space_ids, file_space_ids, offsets, element_sizes,
+ bufs) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "file selection write request failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5FDwrite_selection() */
+
+/*-------------------------------------------------------------------------
* Function: H5FDflush
*
* Purpose: Notify driver to flush all cached data. If the driver has no
@@ -1688,6 +2098,111 @@ done:
} /* end H5FD_unlock() */
/*-------------------------------------------------------------------------
+ * Function: H5FDctl
+ *
+ * Purpose: Perform a CTL operation.
+ *
+ * The desired operation is specified by the op_code
+ * parameter.
+ *
+ * The flags parameter controls management of op_codes that
+ * are unknown to the callback
+ *
+ * The input and output parameters allow op_code specific
+ * input and output
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: JRM -- 8/3/21
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FDctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **output)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "*#ULUL*x**x", file, op_code, flags, input, output);
+
+ /* Check arguments */
+ if (!file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL")
+
+ if (!file->cls)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file class pointer cannot be NULL")
+
+ /* Don't attempt to validate the op code. If appropriate, that will
+ * be done by the underlying VFD callback, along with the input and
+ * output parameters.
+ */
+
+ /* Call private function */
+ if (H5FD_ctl(file, op_code, flags, input, output) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "VFD ctl request failed")
+
+done:
+
+ FUNC_LEAVE_API(ret_value)
+
+} /* end H5FDctl() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_ctl
+ *
+ * Purpose: Private version of H5FDctl()
+ *
+ * The desired operation is specified by the op_code
+ * parameter.
+ *
+ * The flags parameter controls management of op_codes that
+ * are unknown to the callback
+ *
+ * The input and output parameters allow op_code specific
+ * input and output
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: JRM -- 8/3/21
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_ctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **output)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity checks */
+ HDassert(file);
+ HDassert(file->cls);
+
+ /* Dispatch to driver if the ctl function exists.
+ *
+ * If it doesn't, fail if the H5FD_CTL__FAIL_IF_UNKNOWN_FLAG is set.
+ *
+ * Otherwise, report success.
+ */
+ if (file->cls->ctl) {
+
+ if ((file->cls->ctl)(file, op_code, flags, input, output) < 0)
+
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "VFD ctl request failed")
+ }
+ else if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) {
+
+ HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL,
+ "VFD ctl request failed (no ctl and fail if unknown flag is set)")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* end H5FD_ctl() */
+
+/*-------------------------------------------------------------------------
* Function: H5FD_get_fileno
*
* Purpose: Quick and dirty routine to retrieve the file's 'fileno' value