diff options
author | vchoi-hdfgroup <55293060+vchoi-hdfgroup@users.noreply.github.com> | 2022-06-04 02:46:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-04 02:46:43 (GMT) |
commit | b34aa88f486e9d8e90a33fd1cf55d7e6033eb9a9 (patch) | |
tree | e3384c2e32187a8a872f18126c9186f5ccd382e8 | |
parent | cfdc7f262f1f5d1d58fd719b82c9580ad01f32d1 (diff) | |
parent | 86c725c319e14e60e7f3e34d9c93713db50fc6c4 (diff) | |
download | hdf5-b34aa88f486e9d8e90a33fd1cf55d7e6033eb9a9.zip hdf5-b34aa88f486e9d8e90a33fd1cf55d7e6033eb9a9.tar.gz hdf5-b34aa88f486e9d8e90a33fd1cf55d7e6033eb9a9.tar.bz2 |
Merge pull request #1800 from vchoi-hdfgroup/merge_john_tarball
Merge john tarball
-rw-r--r-- | src/H5.c | 1 | ||||
-rw-r--r-- | src/H5FD.c | 226 | ||||
-rw-r--r-- | src/H5FDcore.c | 60 | ||||
-rw-r--r-- | src/H5FDdevelop.h | 4 | ||||
-rw-r--r-- | src/H5FDdirect.c | 60 | ||||
-rw-r--r-- | src/H5FDfamily.c | 64 | ||||
-rw-r--r-- | src/H5FDlog.c | 61 | ||||
-rw-r--r-- | src/H5FDmpio.c | 8 | ||||
-rw-r--r-- | src/H5FDmulti.c | 15 | ||||
-rw-r--r-- | src/H5FDpublic.h | 1 | ||||
-rw-r--r-- | src/H5FDros3.c | 60 | ||||
-rw-r--r-- | src/H5FDsec2.c | 15 | ||||
-rw-r--r-- | src/H5FDstdio.c | 62 | ||||
-rw-r--r-- | src/H5FDvfd_swmr.c | 765 | ||||
-rw-r--r-- | src/H5FDvfd_swmr.h | 39 | ||||
-rw-r--r-- | src/H5Fint.c | 157 | ||||
-rw-r--r-- | src/H5Fprivate.h | 2 | ||||
-rw-r--r-- | src/H5Fvfd_swmr.c | 74 | ||||
-rw-r--r-- | src/H5Pfapl.c | 3 | ||||
-rw-r--r-- | test/vfd_swmr.c | 22 |
20 files changed, 1162 insertions, 537 deletions
@@ -463,6 +463,7 @@ H5_term_library(void) do { pending = 0; for (i = 0; i < NELMTS(terminator); i++) { + if (terminator[i].completed) continue; if (pending != 0 && terminator[i].await_prior) @@ -51,12 +51,6 @@ /* Package Typedefs */ /********************/ -/* H5FD wrapper for VFD SWMR. Allows use as a BSD TAILQ element. */ -typedef struct H5FD_wrap_t { - TAILQ_ENTRY(H5FD_wrap_t) link; /* Linkage for list of all VFDs. */ - H5FD_t *file; /* Pointer to wrapped VFD struct */ -} H5FD_wrap_t; - /********************/ /* Local Prototypes */ /********************/ @@ -89,8 +83,6 @@ static herr_t H5FD__query(const H5FD_t *f, unsigned long *flags /*out*/); */ static unsigned long H5FD_file_serial_no_g; -static TAILQ_HEAD(_all_vfds, H5FD_wrap_t) all_vfds = TAILQ_HEAD_INITIALIZER(all_vfds); - /* File driver ID class */ static const H5I_class_t H5I_VFL_CLS[1] = {{ H5I_VFL, /* ID class value */ @@ -714,104 +706,6 @@ done: } /*------------------------------------------------------------------------- - * Function: H5FD__dedup - * - * Purpose: Helper routine for H5FD_deduplicate - * - * Compares `self` and `other` using the dedup callback of - * `self` (if it has one); otherwise compares using `H5FDcmp()`. - * - * No `dedup' callback: - * - * If `self` has no de-duplication method, compare `self` and - * `other` using `H5FDcmp()` and return `self` if they're equal - * and `other` if unequal. - * - * `dedup' callback present: - * - * If `self` does have a de-duplication callback, invoke it and - * return the method's result: `other` if it duplicates `self`, - * `self` if `other` does NOT duplicate it, NULL if `other` - * conflicts with `self` or if there is an error. - * - * Return: Success: `self' or `other', as described above - * - * Failure: NULL - * - * Note: Unlike H5FD_deduplicate(), this routine does not free `self` - * under any circumstances. - * - *------------------------------------------------------------------------- - * - */ - -/*------------------------------------------------------------------------- - * Function: H5FD_deduplicate - * - * Purpose: Search the already-opened VFD instances for an instance - * similar to the instance `file` newly-opened using file access - * properties given by `fapl_id`. - * - * Return: It's complicated... - * - * If there is an already-open instance that is functionally - * identical to `file`, close `file` and return the already - * open instance. - * - * If there is an already open instance that conflicts with - * `file` because, for example, its file-access properties are - * incompatible with `fapl_id`'s or, for another example, it is - * under exclusive control by a third VFD instance, then close - * `file` and return `NULL`. - * - * Otherwise, return `file` to indicate that there are no - * identical or conflicting VFD instances already open. - *------------------------------------------------------------------------- - */ -H5FD_t * -H5FD_deduplicate(H5FD_t *file, hid_t fapl_id) -{ - H5FD_wrap_t *item; - H5FD_t * ret_value = file; - - FUNC_ENTER_NOAPI(NULL) - - TAILQ_FOREACH(item, &all_vfds, link) - { - /* Skip "self" */ - if (item->file == file) - continue; - - /* Skip files with exclusive owners, for now */ - if (item->file->exc_owner != NULL) - continue; - - if ((ret_value = H5FD_vfd_swmr_dedup(item->file, file, fapl_id)) != file) - goto done; - } - - /* If we reach this stage, then we identified neither a conflict nor a - * duplicate. If any lower VFD with an exclusive owner matches `file`, - * return NULL to indicate the conflict. - */ - TAILQ_FOREACH(item, &all_vfds, link) - { - if (item->file == file || item->file->exc_owner == NULL) - continue; - - if (H5FD_cmp(file, item->file) == 0) - HGOTO_ERROR(H5E_VFL, H5E_FILEOPEN, NULL, - "found a conflicting open file when searching for duplicates") - } - -done: - if (ret_value != file && H5FD_close(file) < 0) - HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, NULL, "could not close file") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5FD_deduplicate() */ - -/*------------------------------------------------------------------------- * Function: H5FD_open * * Purpose: Private version of H5FDopen() @@ -825,14 +719,13 @@ done: H5FD_t * H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_class_t * driver; /* VFD for file */ - H5FD_t * file = NULL; /* VFD file struct */ - H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ - H5P_genplist_t * plist; /* Property list pointer */ - unsigned long driver_flags = 0; /* File-inspecific driver feature flags */ - H5FD_file_image_info_t file_image_info; /* Initial file image */ - H5FD_wrap_t * swmr_wrapper = NULL; /* H5FD wrapper for SWMR queue */ - H5FD_t * ret_value = NULL; /* Return value */ + H5FD_class_t * driver; /* VFD for file */ + H5FD_t * file = NULL; /* VFD file struct */ + H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ + H5P_genplist_t * plist; /* Property list pointer */ + unsigned long driver_flags = 0; /* File-inspecific driver feature flags */ + H5FD_file_image_info_t file_image_info; /* Initial file image */ + H5FD_t * ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI(NULL) @@ -874,8 +767,6 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (NULL == (file = (driver->open)(name, flags, fapl_id, maxaddr))) HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "open failed") - file->exc_owner = NULL; - /* Set the file access flags */ file->access_flags = flags; @@ -907,12 +798,6 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) /* (This will be changed later, when the superblock is located) */ file->base_addr = 0; - /* Create and insert a SWMR wrapper for the file */ - if (NULL == (swmr_wrapper = H5MM_calloc(sizeof(H5FD_wrap_t)))) - HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, NULL, "unable to allocate file wrap struct") - swmr_wrapper->file = file; - TAILQ_INSERT_TAIL(&all_vfds, swmr_wrapper, link); - /* Set return value */ ret_value = file; @@ -969,8 +854,6 @@ herr_t H5FD_close(H5FD_t *file) { const H5FD_class_t *driver; - H5FD_wrap_t * item; - H5FD_wrap_t * temp = NULL; herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) @@ -984,18 +867,6 @@ H5FD_close(H5FD_t *file) if (H5I_dec_ref(file->driver_id) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close driver ID") - TAILQ_FOREACH(item, &all_vfds, link) - { - if (item->file->exc_owner == file) - item->file->exc_owner = NULL; - if (item->file == file) - temp = item; - } - - HDassert(temp); - TAILQ_REMOVE(&all_vfds, temp, link); - H5MM_xfree(temp); - /* Dispatch to the driver for actual close. If the driver fails to * close the file then the file will be in an unusable state. */ @@ -1050,37 +921,100 @@ done: * * Failure: Must never fail. * + * Changes: Re-worked function to use H5FD_ctl() to obtain the terminal + * VFDs for f1 and f2. Typically, these are the same thing, + * however, if there is an intervening pass through VFD + * (i.e. splitter of vfd swrmr reader vfd), using the terminal + * VFD for the comparison will avoid some false negatives. + * + * Note, however, that we will still fail to detect the + * case in which a give file is opened twice with different + * terminal VFDs. + * + * JRM -- 5/5/22 + * *------------------------------------------------------------------------- */ + int H5FD_cmp(const H5FD_t *f1, const H5FD_t *f2) { - int ret_value = -1; /* Return value */ + const H5FD_t *term_f1 = f1; + const H5FD_t *term_f2 = f2; + herr_t ctl_result; + int ret_value = -1; /* Return value */ FUNC_ENTER_NOAPI_NOERR; /* return value is arbitrary */ - if ((!f1 || !f1->cls) && (!f2 || !f2->cls)) + /* For each of f1 and f2, check to see if the ctl call is defined. If it is, + * use the ctl call to try to obtain the terminal VFD. Since this function + * is not allowed to fail, discard the error stack if either of the ctl call + * fail. + */ + if ((f1) && (f1->cls) && (f1->cls->ctl)) { + + H5E_BEGIN_TRY + { + ctl_result = H5FD_ctl(f1, H5FD_CTL__GET_TERMINAL_VFD, + H5FD_CTL__FAIL_IF_UNKNOWN_FLAG | H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG, NULL, + (void **)(&term_f1)); + } + H5E_END_TRY; + + /* if the ctl call failed, set term_f1 equal to f1. This will probably be + * wrong -- but it will be no worse than using the top level VFD unconditionally. + */ + if (ctl_result != SUCCEED) { + + H5E_clear_stack(NULL); + + term_f1 = f1; + } + } + + if ((f2) && (f2->cls) && (f2->cls->ctl)) { + + H5E_BEGIN_TRY + { + ctl_result = H5FD_ctl(f2, H5FD_CTL__GET_TERMINAL_VFD, + H5FD_CTL__FAIL_IF_UNKNOWN_FLAG | H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG, NULL, + (void **)(&term_f2)); + } + H5E_END_TRY; + + /* if the ctl call failed, set term_f1 equal to f1. This will probably be + * wrong -- but it will be no worse than using the top level VFD unconditionally. + */ + if (ctl_result != SUCCEED) { + + H5E_clear_stack(NULL); + + term_f2 = f2; + } + } + + if ((!term_f1 || !term_f1->cls) && (!term_f2 || !term_f2->cls)) HGOTO_DONE(0) - if (!f1 || !f1->cls) + if (!term_f1 || !term_f1->cls) HGOTO_DONE(-1) - if (!f2 || !f2->cls) + if (!term_f2 || !term_f2->cls) HGOTO_DONE(1) - if (f1->cls < f2->cls) + if (term_f1->cls < term_f2->cls) HGOTO_DONE(-1) - if (f1->cls > f2->cls) + if (term_f1->cls > term_f2->cls) HGOTO_DONE(1) /* Files are same driver; no cmp callback */ - if (!f1->cls->cmp) { - if (f1 < f2) + if (!term_f1->cls->cmp) { + if (term_f1 < term_f2) HGOTO_DONE(-1) - if (f1 > f2) + if (term_f1 > term_f2) HGOTO_DONE(1) HGOTO_DONE(0) } /* Dispatch to driver */ - ret_value = (f1->cls->cmp)(f1, f2); + ret_value = (term_f1->cls->cmp)(term_f1, term_f2); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5FDcore.c b/src/H5FDcore.c index a207e9e..e09e250 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -149,6 +149,8 @@ static herr_t H5FD__core_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing static herr_t H5FD__core_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__core_unlock(H5FD_t *_file); static herr_t H5FD__core_delete(const char *filename, hid_t fapl_id); +static herr_t H5FD__core_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); static inline const H5FD_core_fapl_t *H5FD__core_get_default_config(void); static const H5FD_class_t H5FD_core_g = { @@ -185,7 +187,7 @@ static const H5FD_class_t H5FD_core_g = { H5FD__core_lock, /* lock */ H5FD__core_unlock, /* unlock */ H5FD__core_delete, /* del */ - NULL, /* ctl */ + H5FD__core_ctl, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1755,3 +1757,59 @@ H5FD__core_delete(const char *filename, hid_t fapl_id) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__core_delete() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__core_ctl + * + * Purpose: Core VFD version of the ctl callback. + * + * 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 + * + * At present, the only op code supported is + * H5FD_CTL__GET_TERMINAL_VFD, which is used to obtain a + * pointer to the instance of H5FD_t associated with the + * terminal VFD. This allows comparison of files whose + * terminal VFD may have overlying pass through VFDs. + * + * Return: Non-negative on success/Negative on failure + * + * Changes: None. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__core_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_ATTR_UNUSED *input, + void **output) +{ + H5FD_core_t *file = (H5FD_core_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(file); + + switch (op_code) { + + case H5FD_CTL__GET_TERMINAL_VFD: + HDassert(output); + *output = (void *)(file); + break; + + /* Unknown op code */ + default: + if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown flag is set") + break; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__core_ctl() */ diff --git a/src/H5FDdevelop.h b/src/H5FDdevelop.h index 32cd36f..be3b545 100644 --- a/src/H5FDdevelop.h +++ b/src/H5FDdevelop.h @@ -217,10 +217,6 @@ struct H5FD_t { haddr_t maxaddr; /* For this file, overrides class */ haddr_t base_addr; /* Base address for HDF5 data w/in file */ - H5FD_t *exc_owner; /* Pointer to an exclusive owner - * or NULL if none. - */ - /* Space allocation management fields */ hsize_t threshold; /* Threshold for alignment */ hsize_t alignment; /* Allocation alignment */ diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index a6139da..66843e9 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -140,6 +140,8 @@ static herr_t H5FD__direct_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closi static herr_t H5FD__direct_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__direct_unlock(H5FD_t *_file); static herr_t H5FD__direct_delete(const char *filename, hid_t fapl_id); +static herr_t H5FD__direct_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); static const H5FD_class_t H5FD_direct_g = { H5FD_DIRECT_VALUE, /* value */ @@ -175,7 +177,7 @@ static const H5FD_class_t H5FD_direct_g = { H5FD__direct_lock, /* lock */ H5FD__direct_unlock, /* unlock */ H5FD__direct_delete, /* del */ - NULL, /* ctl */ + H5FD__direct_ctl, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1421,4 +1423,60 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__direct_delete() */ +/*------------------------------------------------------------------------- + * Function: H5FD__direct_ctl + * + * Purpose: Direct VFD version of the ctl callback. + * + * 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 + * + * At present, the only op code supported is + * H5FD_CTL__GET_TERMINAL_VFD, which is used to obtain the + * instance of H5FD_t associated with the terminal + * VFD. This allows comparison of files whose terminal + * VFD may have overlying pass through VFDs. + * + * Return: Non-negative on success/Negative on failure + * + * Changes: None. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__direct_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_ATTR_UNUSED *input, + void **output) +{ + H5FD_direct_t *file = (H5FD_direct_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(file); + + switch (op_code) { + + case H5FD_CTL__GET_TERMINAL_VFD: + HDassert(output); + *output = (void *)(file); + break; + + /* Unknown op code */ + default: + if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown flag is set") + break; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__direct_ctl() */ + #endif /* H5_HAVE_DIRECT */ diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index b4cf58e..185ca4e 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -109,6 +109,8 @@ static herr_t H5FD__family_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closi static herr_t H5FD__family_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__family_unlock(H5FD_t *_file); static herr_t H5FD__family_delete(const char *filename, hid_t fapl_id); +static herr_t H5FD__family_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); /* The class struct */ static const H5FD_class_t H5FD_family_g = { @@ -145,7 +147,7 @@ static const H5FD_class_t H5FD_family_g = { H5FD__family_lock, /* lock */ H5FD__family_unlock, /* unlock */ H5FD__family_delete, /* del */ - NULL, /* ctl */ + H5FD__family_ctl, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1580,3 +1582,63 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__family_delete() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__family_ctl + * + * Purpose: Family VFD version of the ctl callback. + * + * 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 + * + * At present, the only op code supported is + * H5FD_CTL__GET_TERMINAL_VFD, which is used to obtain the + * instance of H5FD_t associated with the terminal + * VFD. This allows comparison of files whose terminal + * VFD may have overlying pass through VFDs. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__family_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_ATTR_UNUSED *input, + void **output) +{ + H5FD_family_t *file = (H5FD_family_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(file); + + switch (op_code) { + + case H5FD_CTL__GET_TERMINAL_VFD: + /* On can argue as to whether the family VFD should be regarded as terminal. + * It is treated as such here, as it is the lowest VFD through which all I/O + * request pass. + * + * For now at least, this works as this is the level at which files are compared. + */ + HDassert(output); + *output = (void *)(file); + break; + + /* Unknown op code */ + default: + if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown flag is set") + break; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__sec2_ctl() */ diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 1c8ff7d..a920cd9 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -178,6 +178,8 @@ static herr_t H5FD__log_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing) static herr_t H5FD__log_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__log_unlock(H5FD_t *_file); static herr_t H5FD__log_delete(const char *filename, hid_t fapl_id); +static herr_t H5FD__log_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); static const H5FD_class_t H5FD_log_g = { H5FD_LOG_VALUE, /* value */ @@ -213,7 +215,7 @@ static const H5FD_class_t H5FD_log_g = { H5FD__log_lock, /* lock */ H5FD__log_unlock, /* unlock */ H5FD__log_delete, /* del */ - NULL, /* ctl */ + H5FD__log_ctl, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1789,3 +1791,60 @@ H5FD__log_delete(const char *filename, hid_t H5_ATTR_UNUSED fapl_id) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__log_delete() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__log_ctl + * + * Purpose: log VFD version of the ctl callback. + * + * 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 + * + * At present, the only op code supported is + * H5FD_CTL__GET_TERMINAL_VFD, which is used to obtain the + * instance of H5FD_t associated with the terminal + * VFD. This allows comparison of files whose terminal + * VFD may have overlying pass through VFDs. + * + * Return: Non-negative on success/Negative on failure + * + * Changes: Added support for H5FD_CTL__GET_TERMINAL_VFD. + * JRM -- 5/4/22 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__log_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_ATTR_UNUSED *input, + void **output) +{ + H5FD_log_t *file = (H5FD_log_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(file); + + switch (op_code) { + + case H5FD_CTL__GET_TERMINAL_VFD: + HDassert(output); + *output = (void *)(file); + break; + + /* Unknown op code */ + default: + if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown flag is set") + break; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__log_ctl() */ diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index 6a168c7..cd59285 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -1918,6 +1918,9 @@ done: * * Programmer: JRM -- 8/3/21 * + * Changes: Added support for H5FD_CTL__GET_TERMINAL_VFD. + * JRM -- 5/4/22 + * *------------------------------------------------------------------------- */ static herr_t @@ -1953,6 +1956,11 @@ H5FD__mpio_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_AT **((int **)output) = file->mpi_size; break; + case H5FD_CTL__GET_TERMINAL_VFD: + HDassert(output); + *output = (void *)(file); + break; + default: /* unknown op code */ if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) { diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c index d9a6ce9..faf4b87 100644 --- a/src/H5FDmulti.c +++ b/src/H5FDmulti.c @@ -2243,6 +2243,9 @@ H5_MULTI_GCC_DIAG_ON("format-nonliteral") * * Return: Non-negative on success/Negative on failure * + * Changes: Added support for H5FD_CTL__GET_TERMINAL_VFD. + * JRM -- 5/4/22 + * *------------------------------------------------------------------------- */ static herr_t @@ -2261,6 +2264,18 @@ H5FD_multi_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *inpu H5Eclear2(H5E_DEFAULT); switch (op_code) { + + case H5FD_CTL__GET_TERMINAL_VFD: + /* One can argue as to whether the multi VFD should be regarded as terminal. + * It is treated as such here, as it is the lowest VFD through which all I/O + * request pass. + * + * For now at least, this works as this is the level at which files are compared. + */ + assert(output); + *output = (void *)(file); + break; + /* Unknown op code */ default: if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index 9411874..94ab92b 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -203,6 +203,7 @@ #define H5FD_CTL__MEM_ALLOC 5 #define H5FD_CTL__MEM_FREE 6 #define H5FD_CTL__MEM_COPY 7 +#define H5FD_CTL__GET_TERMINAL_VFD 8 /* ctl function flags: */ diff --git a/src/H5FDros3.c b/src/H5FDros3.c index 4b15616..3aae108 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -233,6 +233,8 @@ static herr_t H5FD__ros3_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, ha static herr_t H5FD__ros3_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, size_t size, const void *buf); static herr_t H5FD__ros3_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); +static herr_t H5FD__ros3_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); static herr_t H5FD__ros3_validate_config(const H5FD_ros3_fapl_t *fa); @@ -270,7 +272,7 @@ static const H5FD_class_t H5FD_ros3_g = { NULL, /* lock */ NULL, /* unlock */ NULL, /* del */ - NULL, /* ctl */ + H5FD__ros3_ctl, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1563,4 +1565,60 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ros3_truncate() */ +/*------------------------------------------------------------------------- + * Function: H5FD__ros3_ctl + * + * Purpose: ROS3 VFD version of the ctl callback. + * + * 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 + * + * At present, the only op code supported is + * H5FD_CTL__GET_TERMINAL_VFD, which is used to obtain the + * instance of H5FD_t associated with the terminal + * VFD. This allows comparison of files whose terminal + * VFD may have overlying pass through VFDs. + * + * Return: Non-negative on success/Negative on failure + * + * Changes: None, + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__ros3_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_ATTR_UNUSED *input, + void **output) +{ + H5FD_ros3_t *file = (H5FD_ros3_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(file); + + switch (op_code) { + + case H5FD_CTL__GET_TERMINAL_VFD: + HDassert(output); + *output = (void *)(file); + break; + + /* Unknown op code */ + default: + if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown flag is set") + break; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ros3_ctl() */ + #endif /* H5_HAVE_ROS3_VFD */ diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index accacb6..b88605c 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -1064,15 +1064,20 @@ done: * The input and output parameters allow op_code specific * input and output * - * At present, no op codes are supported by this VFD. + * At present, the only op code supported is + * H5FD_CTL__GET_TERMINAL_VFD, which is used in the + * comparison of files under layers of pass through VFDs. * * Return: Non-negative on success/Negative on failure * + * Changes: Added support for H5FD_CTL__GET_TERMINAL_VFD. + * JRM -- 5/4/22 + * *------------------------------------------------------------------------- */ static herr_t H5FD__sec2_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_ATTR_UNUSED *input, - void H5_ATTR_UNUSED **output) + void **output) { H5FD_sec2_t *file = (H5FD_sec2_t *)_file; herr_t ret_value = SUCCEED; @@ -1083,6 +1088,12 @@ H5FD__sec2_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5_AT HDassert(file); switch (op_code) { + + case H5FD_CTL__GET_TERMINAL_VFD: + HDassert(output); + *output = (void *)(file); + break; + /* Unknown op code */ default: if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index b59aae3..ad59bc9 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -181,6 +181,8 @@ static herr_t H5FD_stdio_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing static herr_t H5FD_stdio_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD_stdio_unlock(H5FD_t *_file); static herr_t H5FD_stdio_delete(const char *filename, hid_t fapl_id); +static herr_t H5FD__stdio_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); static const H5FD_class_t H5FD_stdio_g = { H5_VFD_STDIO, /* value */ @@ -216,7 +218,7 @@ static const H5FD_class_t H5FD_stdio_g = { H5FD_stdio_lock, /* lock */ H5FD_stdio_unlock, /* unlock */ H5FD_stdio_delete, /* del */ - NULL, /* ctl */ + H5FD__stdio_ctl, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; @@ -1233,6 +1235,64 @@ H5FD_stdio_delete(const char *filename, hid_t /*UNUSED*/ fapl_id) return 0; } /* end H5FD_stdio_delete() */ +/*------------------------------------------------------------------------- + * Function: H5FD__stdio_ctl + * + * Purpose: Sec2 VFD version of the ctl callback. + * + * 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 + * + * At present, the only op code supported is + * H5FD_CTL__GET_TERMINAL_VFD, which is used to obtain the + * instance of H5FD_t associated with the terminal + * VFD. This allows comparison of files whose terminal + * VFD may have overlying pass through VFDs. + * + * Return: Non-negative on success/Negative on failure + * + * Changes: None. + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__stdio_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void /* UNUSED */ *input, + void **output) +{ + static const char *func = "H5FD__stdio_ctl"; /* Function Name for error reporting */ + H5FD_stdio_t * file = (H5FD_stdio_t *)_file; + + /* Clear the error stack */ + H5Eclear2(H5E_DEFAULT); + + /* Quiet compiler */ + (void)input; + + switch (op_code) { + + case H5FD_CTL__GET_TERMINAL_VFD: + assert(output); + *output = (void *)(file); + break; + + /* Unknown op code */ + default: + if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) + H5Epush_ret(func, H5E_ERR_CLS, H5E_VFL, H5E_FCNTL, + "unknown op_code and fail if unknown flag is set", -1); + break; + } + + return (0); /* SUCCEED */ + +} /* end H5FD__stdio_ctl() */ + #ifdef H5private_H /* * This is not related to the functionality of the driver code. diff --git a/src/H5FDvfd_swmr.c b/src/H5FDvfd_swmr.c index 892d084..a8f588d 100644 --- a/src/H5FDvfd_swmr.c +++ b/src/H5FDvfd_swmr.c @@ -34,6 +34,8 @@ static hid_t H5FD_VFD_SWMR_g = 0; typedef struct H5FD_vfd_swmr_t { H5FD_t pub; /* public stuff, must be first */ + H5FD_vfd_swmr_reader_fapl_t fa; /* driver-specific file access properties */ + /* HDF5 file */ char hdf5_filename[H5FD_MAX_FILENAME_LEN]; /* Name of the HDF5 file from open */ H5FD_t *hdf5_file_lf; /* Driver info for the HDF5 file */ @@ -56,11 +58,6 @@ typedef struct H5FD_vfd_swmr_t { hbool_t pb_configured; /* Sanity-checking flag set when page buffer is configured */ H5F_vfd_swmr_config_t config; /* VFD SWMR configuration */ - /* Flag set if the file is a SWMR writer. - * All methods on a write-mode SWMR VFD instance are passed - * to the lower VFD instance. - */ - hbool_t writer; /* * Indicate whether we are in make_believe state or not */ @@ -73,6 +70,9 @@ typedef struct H5FD_vfd_swmr_t { /* Prototypes */ static herr_t H5FD__vfd_swmr_term(void); +static void * H5FD__vfd_swmr_fapl_get(H5FD_t *_file); +static void * H5FD__vfd_swmr_fapl_copy(const void *_old_fa); +static herr_t H5FD__vfd_swmr_fapl_free(void *_fapl); static H5FD_t *H5FD__vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD__vfd_swmr_close(H5FD_t *_file); static int H5FD__vfd_swmr_cmp(const H5FD_t *_f1, const H5FD_t *_f2); @@ -88,6 +88,8 @@ static herr_t H5FD__vfd_swmr_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_i static herr_t H5FD__vfd_swmr_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); static herr_t H5FD__vfd_swmr_lock(H5FD_t *_file, hbool_t rw); static herr_t H5FD__vfd_swmr_unlock(H5FD_t *_file); +static herr_t H5FD__vfd_swmr_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); /* VFD SWMR */ static htri_t H5FD__vfd_swmr_header_deserialize(H5FD_vfd_swmr_t *, H5FD_vfd_swmr_md_header *); @@ -96,46 +98,49 @@ static htri_t H5FD__vfd_swmr_index_deserialize(const H5FD_vfd_swmr_t *file, H5FD static herr_t H5FD__vfd_swmr_load_hdr_and_idx(H5FD_vfd_swmr_t *, hbool_t); static const H5FD_class_t H5FD_vfd_swmr_g = { - H5FD_VFD_SWMR_VALUE, /* value */ - "vfd_swmr", /* name */ - MAXADDR, /* maxaddr */ - H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__vfd_swmr_term, /* terminate */ - NULL, /* sb_size */ - NULL, /* sb_encode */ - NULL, /* sb_decode */ - 0, /* fapl_size */ - NULL, /* fapl_get */ - NULL, /* fapl_copy */ - NULL, /* fapl_free */ - 0, /* dxpl_size */ - NULL, /* dxpl_copy */ - NULL, /* dxpl_free */ - H5FD__vfd_swmr_open, /* open */ - H5FD__vfd_swmr_close, /* close */ - H5FD__vfd_swmr_cmp, /* cmp */ - H5FD__vfd_swmr_query, /* query */ - NULL, /* get_type_map */ - NULL, /* alloc */ - NULL, /* free */ - H5FD__vfd_swmr_get_eoa, /* get_eoa */ - H5FD__vfd_swmr_set_eoa, /* set_eoa */ - H5FD__vfd_swmr_get_eof, /* get_eof */ - H5FD__vfd_swmr_get_handle, /* get_handle */ - H5FD__vfd_swmr_read, /* read */ - H5FD__vfd_swmr_write, /* write */ - NULL, /* flush */ - H5FD__vfd_swmr_truncate, /* truncate */ - H5FD__vfd_swmr_lock, /* lock */ - H5FD__vfd_swmr_unlock, /* unlock */ - NULL, /* del */ - NULL, /* ctl */ - H5FD_FLMAP_DICHOTOMY /* fl_map */ + H5FD_VFD_SWMR_VALUE, /* value */ + "vfd_swmr", /* name */ + MAXADDR, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + H5FD__vfd_swmr_term, /* terminate */ + NULL, /* sb_size */ + NULL, /* sb_encode */ + NULL, /* sb_decode */ + sizeof(H5FD_vfd_swmr_reader_fapl_t), /* fapl_size */ + H5FD__vfd_swmr_fapl_get, /* fapl_get */ + H5FD__vfd_swmr_fapl_copy, /* fapl_copy */ + H5FD__vfd_swmr_fapl_free, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD__vfd_swmr_open, /* open */ + H5FD__vfd_swmr_close, /* close */ + H5FD__vfd_swmr_cmp, /* cmp */ + H5FD__vfd_swmr_query, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + H5FD__vfd_swmr_get_eoa, /* get_eoa */ + H5FD__vfd_swmr_set_eoa, /* set_eoa */ + H5FD__vfd_swmr_get_eof, /* get_eof */ + H5FD__vfd_swmr_get_handle, /* get_handle */ + H5FD__vfd_swmr_read, /* read */ + H5FD__vfd_swmr_write, /* write */ + NULL, /* flush */ + H5FD__vfd_swmr_truncate, /* truncate */ + H5FD__vfd_swmr_lock, /* lock */ + H5FD__vfd_swmr_unlock, /* unlock */ + NULL, /* del */ + H5FD__vfd_swmr_ctl, /* ctl */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }; /* Declare a free list to manage the H5FD_vfd_swmr_t struct */ H5FL_DEFINE_STATIC(H5FD_vfd_swmr_t); +/* Declare a free list to manage the H5FD_vfd_swmr_reader_config_t struct */ +H5FL_DEFINE_STATIC(H5FD_vfd_swmr_reader_fapl_t); + /* Declare a free list to manage the H5FD_vfd_swmr_idx_entry_t sequence information */ H5FL_SEQ_DEFINE(H5FD_vfd_swmr_idx_entry_t); @@ -187,32 +192,301 @@ H5FD__vfd_swmr_term(void) } /* end H5FD__vfd_swmr_term() */ /*------------------------------------------------------------------------- - * Function: H5Pset_fapl_vfd_swmr (Not yet) + * Function: H5FD__vfd_swmr_fapl_get + * + * Purpose: Returns a file access property list which indicates how the + * specified file is being accessed. The return list could be + * used to access another file the same way. + * + * Return: Success: Ptr to new file access property list with all + * members copied from the file struct. + * Failure: NULL + *------------------------------------------------------------------------- + */ +static void * +H5FD__vfd_swmr_fapl_get(H5FD_t *_file) +{ + H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; + void * ret_value = NULL; + + FUNC_ENTER_PACKAGE_NOERR + + ret_value = H5FD__vfd_swmr_fapl_copy(&(file->fa)); + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5FD__vfd_swmr_fapl_get() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__vfd_swmr_fapl_copy + * + * Purpose: Copies the file access properties. + * + * Return: Success: Pointer to a new property list info structure. + * Failure: NULL + *------------------------------------------------------------------------- + */ +static void * +H5FD__vfd_swmr_fapl_copy(const void *_old_fa) +{ + const H5FD_vfd_swmr_reader_fapl_t *old_fa_ptr = (const H5FD_vfd_swmr_reader_fapl_t *)_old_fa; + H5FD_vfd_swmr_reader_fapl_t * new_fa_ptr = NULL; + void * ret_value = NULL; + + FUNC_ENTER_PACKAGE + + HDassert(old_fa_ptr); + HDassert(old_fa_ptr->magic == H5FD_VFD_SWMR_READER_MAGIC); + + new_fa_ptr = H5FL_CALLOC(H5FD_vfd_swmr_reader_fapl_t); + if (NULL == new_fa_ptr) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate vfd swmr FAPL") + + H5MM_memcpy(new_fa_ptr, old_fa_ptr, sizeof(H5FD_vfd_swmr_reader_fapl_t)); + + ret_value = (void *)new_fa_ptr; + +done: + if (NULL == ret_value) { + if (new_fa_ptr) { + new_fa_ptr->magic = 0; + new_fa_ptr = H5FL_FREE(H5FD_vfd_swmr_reader_fapl_t, new_fa_ptr); + } + } + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5FD__vfd_swmr_fapl_copy() */ + +/*-------------------------------------------------------------------------- + * Function: H5FD__vfd_swmr_fapl_free + * + * Purpose: Releases the file access lists + * + * Return: SUCCEED/FAIL + *-------------------------------------------------------------------------- + */ +static herr_t +H5FD__vfd_swmr_fapl_free(void *_fapl) +{ + H5FD_vfd_swmr_reader_fapl_t *fapl = (H5FD_vfd_swmr_reader_fapl_t *)_fapl; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Check arguments */ + if ((NULL == fapl) || (fapl->magic != H5FD_VFD_SWMR_READER_MAGIC)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL or invalid H5FD_vfd_swmr_reader_fapl_t *") + + /* Free the property list */ + fapl->magic = 0; + fapl = H5FL_FREE(H5FD_vfd_swmr_reader_fapl_t, fapl); + +done: + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5FD__vfd_swmr_fapl_free() */ + +/*------------------------------------------------------------------------- + * Function: H5P_pop_vfd_swmr_reader_vfd_off_fapl + * + * Purpose: After a file has been opened in VFD SWMR reader mode, we + * must pop the vfd swmr reader driver entry off the supplied + * fapl. If we don't, and the fapl is used to open a second + * file (i.e. via virtual data sets), we would have multiple + * vfd swmr reader driver entries pushed on the vfd stack. + * + * Do this as follows: * - * Purpose: Modify the file access property list to use the H5FD_SWMR - * driver + * 1) Read the file driver entry from the supplied fapl. Verify + * that it specifies the vfd swmr reader VFD. + * + * 2) Read the file driver entry from the sub fapl specified + * in the vfd swmr reader vfd fapl entry. Set the file + * driver entry on the supplied fapl equal to that on + * the sub-fapl. + * + * 3) Discard the sub-fapl? Not sure if this is necessary. * * Return: SUCCEED/FAIL * + * Programmer JRM -- 4/28/22 + * *------------------------------------------------------------------------- */ herr_t -H5Pset_fapl_vfd_swmr(hid_t fapl_id) +H5P_pop_vfd_swmr_reader_vfd_off_fapl(hid_t fapl_id) { - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value; + H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ + H5P_genplist_t * plist_ptr = NULL; + hid_t sub_fapl_id; + H5P_genplist_t * sub_plist_ptr = NULL; + herr_t ret_value = SUCCEED; - FUNC_ENTER_API(FAIL) - H5TRACE1("e", "i", fapl_id); + FUNC_ENTER_NOAPI(FAIL) - if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + /* sanity checks -- get ptr to plist in passing */ + if (NULL == (plist_ptr = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") - ret_value = H5P_set_driver(plist, H5FD_VFD_SWMR, NULL, NULL); + /* 1) Read the file driver entry from the supplied fapl. Verify + * that it specifies the vfd swmr reader VFD. + */ + + /* get the driver property from the supplied fapl */ + if (H5P_peek(plist_ptr, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file driver ID & info") + + /* verify that it specifies the vfd swrm reader vfd */ + if (driver_prop.driver_id != H5FD_VFD_SWMR) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "fapl driver prop not vfd swmr reader") + + if ((((const H5FD_vfd_swmr_reader_fapl_t *)(driver_prop.driver_info)) == NULL) || + (((const H5FD_vfd_swmr_reader_fapl_t *)(driver_prop.driver_info))->magic != + H5FD_VFD_SWMR_READER_MAGIC)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "fapl driver info invalid") + + sub_fapl_id = ((const H5FD_vfd_swmr_reader_fapl_t *)(driver_prop.driver_info))->fapl_id; + + /* 2) Read the file driver entry from the sub fapl specified + * in the vfd swmr reader vfd fapl entry. Set the file + * driver entry on the supplied fapl equal to that on + * the sub-fapl. + */ + /* get a pointer to the sub-fapl */ + if (NULL == (sub_plist_ptr = (H5P_genplist_t *)H5I_object(sub_fapl_id))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get sub-fapl pointer") + + /* get the driver property from the sub-fapl */ + if (H5P_peek(sub_plist_ptr, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get sub-fapl file driver ID & info") + + /* insert the driver info from the sub-fapl into the supplied fapl. There is + * some question in my mind as to whether I should be making a copy of the + * info and string obtained above. While I don't think it is necessary, + * if we get occult failures, this is a good place to look. + * + * Note that for now, the driver info on the sub-fapl should only specify the + * sec2 VFD -- which has NULL info and config string. Thus, if it is an + * issue, it may not appear immediately. + */ + if (H5P_set_driver(plist_ptr, driver_prop.driver_id, driver_prop.driver_info, + driver_prop.driver_config_str) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set driver on supplied fapl") + + /* 3) Discard the sub-fapl? Not sure if this is necessary. Will wait on this for now. */ done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pset_fapl_vfd_swmr() */ + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5P_pop_vfd_swmr_reader_vfd_off_fapl() */ + +/*------------------------------------------------------------------------- + * Function: H5P_push_vfd_swmr_reader_vfd_on_fapl + * + * Purpose: When a file is opened in VFD SWMR reader mode, we must + * adjust the fapl so as to push the VFD SWMR reader vfd on + * the VFD stack specified in the fapl. + * + * Do this as follows: + * + * 1) Copy the file driver from the supplied fapl. Note + * that due to potential VFD stacking, we can't verify + * that this VFD supports vfd swmr. This will have to + * wait until after the file is opened. + * + * 2) Create a new FAPL, and set the file driver obtained + * in 1) in the new FAPL. + * + * 3) Allocate a new instance of H5FD_vfd_swmr_reader_config_t, + * load it with the ID of the FAPL created in 2, and use + * it to overwrite the file driver entry in the supplied + * FAPL. + * + * Return: SUCCEED/FAIL + * + * Programmer JRM -- 4/28/22 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_push_vfd_swmr_reader_vfd_on_fapl(hid_t fapl_id) +{ + H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ + H5FD_vfd_swmr_reader_fapl_t *info = NULL; + H5P_genplist_t * plist_ptr = NULL; + hid_t sub_fapl_id; + H5P_genplist_t * sub_plist_ptr = NULL; + H5P_genclass_t * pclass = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* sanity checks -- get ptr to plist in passing */ + if (NULL == (plist_ptr = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + + /* 1) Copy the file driver from the supplied fapl. Note + * that due to potential VFD stacking, we can't verify + * that this VFD supports vfd swmr. This will have to + * wait until after the file is opened. + */ + + /* get the driver property from the supplied fapl */ + if (H5P_peek(plist_ptr, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get init driver ID & info") + + /* 2) Create a new FAPL, and set the file driver obtained in 1) in the new FAPL. */ + + /* create a new FAPL */ + if (NULL == (pclass = (H5P_genclass_t *)H5I_object_verify(H5P_FILE_ACCESS, H5I_GENPROP_CLS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a property list class"); + + if ((sub_fapl_id = H5P_create_id(pclass, TRUE)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, H5I_INVALID_HID, "unable to create fapl"); + + /* get a pointer to it */ + if (NULL == (sub_plist_ptr = (H5P_genplist_t *)H5I_object(sub_fapl_id))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get sub-fapl pointer") + + /* insert the driver info from the base fapl into the sub-fapl. There is + * some question in my mind as to whether I should be making a copy of the + * info and string obtained above. While I don't think it is necessary, + * if we get occult failures, this is a good place to look. + * + * Note that for now, the driver info being inserted in sub-fapl should only specify + * the sec2 VFD -- which has NULL info and config string. Thus, if it is an + * issue, it may not appear immediately. + */ + if (H5P_set_driver(sub_plist_ptr, driver_prop.driver_id, driver_prop.driver_info, + driver_prop.driver_config_str) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set driver on sub-fapl") + + /* 3) Allocate a new instance of H5FD_vfd_swmr_reader_config_t, + * load it with the ID of the FAPL created in 2, and use + * it to overwrite the file driver entry in the supplied + * FAPL. + */ + + info = H5FL_CALLOC(H5FD_vfd_swmr_reader_fapl_t); + if (NULL == info) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "unable to allocate vfd swmr fapl struct") + + /* initialize the vfd swmr reader vfd info */ + info->magic = H5FD_VFD_SWMR_READER_MAGIC; + info->fapl_id = sub_fapl_id; + + /* set the driver on the main fapl */ + ret_value = H5P_set_driver(plist_ptr, H5FD_VFD_SWMR, info, NULL); + +done: + if (info) + info = H5FL_FREE(H5FD_vfd_swmr_reader_fapl_t, info); + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5P_push_vfd_swmr_reader_vfd_on_fapl() */ /*------------------------------------------------------------------------- * Function: H5FD__swmr_reader_open @@ -271,60 +545,6 @@ done: } /* end H5FD__swmr_reader_open() */ /*------------------------------------------------------------------------- - * - * Function: H5FD__vfd_swmr_build_md_path_name - * - * Purpose: To construct the metadata file's full name based on config's - * md_file_path and md_file_name. See RFC for details. - * - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Vailin Choi -- 1/13/2022 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__vfd_swmr_build_md_path_name(H5F_vfd_swmr_config_t *config, const char *hdf5_filename, - char *name /*out*/) -{ - size_t tot_len = 0; - size_t tmp_len = 0; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - if ((tot_len = HDstrlen(config->md_file_path)) != 0) { - - /* md_file_path + '/' */ - if (++tot_len > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "md_file_path and md_file_name exceeds maximum"); - HDstrcat(name, config->md_file_path); - HDstrcat(name, "/"); - } - - if ((tmp_len = HDstrlen(config->md_file_name)) != 0) { - if ((tot_len += tmp_len) > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "md_file_path and md_file_name exceeds maximum"); - HDstrcat(name, config->md_file_name); - } - else { - /* Automatic generation of metadata file name based on hdf5_filename + '.md' */ - if ((tot_len += (HDstrlen(hdf5_filename) + 3)) > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "md_file_path and md_file_name maximum"); - - HDstrcat(name, hdf5_filename); - HDstrcat(name, VFD_SWMR_MD_SUFFIX); - } - -done: - - FUNC_LEAVE_NOAPI(ret_value) - -} /* H5FD__vfd_swmr_build_md_path_name() */ - -/*------------------------------------------------------------------------- * Function: H5FD__vfd_swmr_create_make_believe_data * * Purpose: Set up pretend data when make_believe is true @@ -377,15 +597,19 @@ H5FD__vfd_swmr_create_make_believe_data(H5FD_vfd_swmr_t *_file) static H5FD_t * H5FD__vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_vfd_swmr_t * file = NULL; - size_t page_buf_size; - H5P_genplist_t * plist; - H5F_vfd_swmr_config_t *vfd_swmr_config; - H5FD_t * ret_value = NULL; /* Return value */ - htri_t is_hdf5; + H5FD_vfd_swmr_t * file = NULL; + size_t page_buf_size; + H5P_genplist_t * plist; + H5F_vfd_swmr_config_t * vfd_swmr_config; + const H5FD_vfd_swmr_reader_fapl_t *fa_ptr = NULL; + H5FD_t * ret_value = NULL; /* Return value */ + htri_t is_hdf5; FUNC_ENTER_PACKAGE + /* VFD SWMR reader VFD should only be called to open a file read only */ + HDassert((H5F_ACC_RDWR & flags) == 0); + /* Get file access property list */ if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") @@ -404,12 +628,33 @@ H5FD__vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t max if (NULL == (file = H5FL_CALLOC(H5FD_vfd_swmr_t))) HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, NULL, "unable to allocate file struct") + /* get the vfd swrm reader fapl entry. */ + if (H5P_peek_driver(plist) != H5FD_VFD_SWMR) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "incorrect VFL driver"); + + fa_ptr = (const H5FD_vfd_swmr_reader_fapl_t *)H5P_peek_driver_info(plist); + if (NULL == fa_ptr) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info"); + + HDassert(fa_ptr->magic == H5FD_VFD_SWMR_READER_MAGIC); /* sanity check */ + + /* the fapl id stored in fa_ptr->fapl_id should contain a driver entry that + * specifies a VFD that supports VFD SWMR. Since there may be a stack of + * VFDs, we can't check this until after file open. Further, the vfd swmr + * reader vfd is currently hard coded to use the sec2 vfd as its underlying + * vfd. Thus we just save a copy of the H5FD_vfd_swmr_reader_fapl_t for + * now. + */ + H5MM_memcpy(&(file->fa), fa_ptr, sizeof(H5FD_vfd_swmr_reader_fapl_t)); + vfd_swmr_config = &file->config; /* Get VFD SWMR configuration */ if (H5P_get(plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, vfd_swmr_config) < 0) HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get VFD SWMR config info") + HDassert(!vfd_swmr_config->writer); + file->md_fd = -1; file->hdf5_file_lf = NULL; file->md_pages_reserved = vfd_swmr_config->md_pages_reserved; @@ -419,13 +664,11 @@ H5FD__vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t max file->hdf5_filename[sizeof(file->hdf5_filename) - 1] = '\0'; /* Retain a copy of the metadata file name */ - if (H5FD__vfd_swmr_build_md_path_name(vfd_swmr_config, name, file->md_file_path_name) < 0) + if (H5F_vfd_swmr_build_md_path_name(vfd_swmr_config, name, file->md_file_path_name) < 0) HGOTO_ERROR(H5E_VFL, H5E_OPENERROR, NULL, "building md_file_path and md_file_name failed") file->md_file_path_name[sizeof(file->md_file_path_name) - 1] = '\0'; - file->writer = vfd_swmr_config->writer; - /* Make sure the hdf5 file exists and is valid */ is_hdf5 = H5F__is_hdf5(name, H5P_FILE_ACCESS_DEFAULT); @@ -448,8 +691,6 @@ H5FD__vfd_swmr_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t max if ((file->hdf5_file_lf = H5FD_open(name, flags, H5P_FILE_ACCESS_DEFAULT, maxaddr)) == NULL) HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "can't set driver info"); - file->hdf5_file_lf->exc_owner = &file->pub; - /* set pb_configured to FALSE. This field should not exist, but * until we modify the file open procedure to create the page buffer * before there is any file I/O when opening a file VFD SWMR reader, @@ -474,40 +715,6 @@ done: } /* end H5FD__vfd_swmr_open() */ /*------------------------------------------------------------------------- - * Function: H5FD__swmr_reader_close - * - * Purpose: Perform the reader-only aspects of closing in VFD SWMR mode: - * optionally log and always release the histogram of ticks spent - * in API calls, close the shadow file, release the shadow index. - * - * Return: void - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__swmr_reader_close(H5FD_vfd_swmr_t *file) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_PACKAGE - - if (file->api_elapsed_ticks != NULL) - H5MM_xfree(file->api_elapsed_ticks); - - /* Close the metadata file */ - if (file->md_fd >= 0 && HDclose(file->md_fd) < 0) - /* Push error, but keep going */ - HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close the metadata file"); - - /* Free the index entries */ - if (file->md_index.num_entries && file->md_index.entries) - file->md_index.entries = H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, file->md_index.entries); - - FUNC_LEAVE_NOAPI(ret_value) - -} /* end H5FD__swmr_reader_close() */ - -/*------------------------------------------------------------------------- * Function: H5FD__vfd_swmr_close * * Purpose: Handle closing for VFD SWMR driver @@ -529,10 +736,6 @@ H5FD__vfd_swmr_close(H5FD_t *_file) FUNC_ENTER_PACKAGE if (file->hdf5_file_lf != NULL) { - if (file->hdf5_file_lf->exc_owner != NULL) { - HDassert(file->hdf5_file_lf->exc_owner == &file->pub); - file->hdf5_file_lf->exc_owner = NULL; - } /* Close the underlying file */ if (H5FD_close(file->hdf5_file_lf) < 0) @@ -540,8 +743,17 @@ H5FD__vfd_swmr_close(H5FD_t *_file) HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close the HDF5 file") } - if (!file->writer) - H5FD__swmr_reader_close(file); + if (file->api_elapsed_ticks != NULL) + H5MM_xfree(file->api_elapsed_ticks); + + /* Close the metadata file */ + if (file->md_fd >= 0 && HDclose(file->md_fd) < 0) + /* Push error, but keep going */ + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close the metadata file"); + + /* Free the index entries */ + if (file->md_index.num_entries && file->md_index.entries) + file->md_index.entries = H5FL_SEQ_FREE(H5FD_vfd_swmr_idx_entry_t, file->md_index.entries); /* Release the driver info */ file = H5FL_FREE(H5FD_vfd_swmr_t, file); @@ -577,141 +789,6 @@ H5FD__vfd_swmr_cmp(const H5FD_t *_f1, const H5FD_t *_f2) } /* end H5FD__vfd__swmr_cmp() */ /*------------------------------------------------------------------------- - * Function: H5FD_vfd_swmr_dedup (original description with H5P_FILE_ACCESS_ANY_VFD) - * - * Purpose: Compare the already-opened VFD instance `_self` with the - * VFD instance `_other` newly-opened with file-access properties - * `fapl_id` and indicate whether the instances duplicate each - * other, if they conflict with each other, or if they are - * dissimilar. - * - * If `_self` duplicates `_other`, return `_self`. - * - * Return NULL on error, or if `_other` and `_self` refer to the - * same file but the file-access properties, `fapl_id`, conflict - * with the properties of `_self`. - * - * If `_other` neither duplicates nor conflicts with `_self`, - * then return `_other`. - * - * NOTE: Judging duplicate/conflicting/dissimilar VFD instances - * - * `_self` DUPLICATES `_other` if `_other` is also an instance - * of SWMR class, the instances' lower files are equal under - * `H5FD_cmp()`, and the file-access properties of `_self` match - * `fapl_id`. The wildcard `fapl_id` value, - * `H5P_FILE_ACCESS_ANY_VFD`, matches all. - * - * `_self` also DUPLICATES `_other` if `_other` is not a SWMR - * instance, but it equals the lower file of `_self` under - * `H5FD_cmp()`, and `fapl_id` is `H5P_FILE_ACCESS_ANY_VFD`. - * - * `_self` and `_other` CONFLICT if both are SWMR instances - * referring to the same lower file, and their file-access - * properties differ. - * - * `_self` and `_other` CONFLICT if `_other` is not a SWMR - * instance, it equals the lower file of `_self`, and `fapl_id` - * is not equal to `H5P_FILE_ACCESS_ANY_VFD`. - * - * Return: Success: `_self' or `_other', as described above - * Failure: NULL - *------------------------------------------------------------------------- - */ -/*------------------------------------------------------------------------- - * Function: H5FD_vfd_swmr_dedup (modified version without H5P_FILE_ACCESS_ANY_VFD) - * - * Purpose: Compare the already-opened VFD instance `_self` with the - * VFD instance `_other` newly-opened with file-access properties - * `fapl_id` and indicate whether the instances duplicate each - * other, if they conflict with each other, or if they are - * dissimilar. - * - * If `_self` duplicates `_other`, return `_self`. - * - * Return NULL on error, or if `_other` and `_self` refer to the - * same file but the file-access properties, `fapl_id`, conflict - * with the properties of `_self`. - * - * If `_other` neither duplicates nor conflicts with `_self`, - * then return `_other`. - * - * NOTE: Judging duplicate/conflicting/dissimilar VFD instances - * - * `_self` DUPLICATES `_other` if `_other` is also an instance - * of SWMR class, the instances' lower files are equal under - * `H5FD_cmp()`, and the file-access properties of `_self` match - * `fapl_id`. - * - * `_self` and `_other` CONFLICT if both are SWMR instances - * referring to the same lower file, and their file-access - * properties differ. - * - * `_self` and `_other` CONFLICT if `_other` is not a SWMR - * instance, it equals the lower file of `_self`. - * - * Return: Success: `_self' or `_other', as described above - * Failure: NULL - *------------------------------------------------------------------------- - */ -H5FD_t * -H5FD_vfd_swmr_dedup(H5FD_t *_self, H5FD_t *_other, hid_t fapl_id) -{ - H5FD_vfd_swmr_t *self = (H5FD_vfd_swmr_t *)_self; - H5FD_t * ret_value = NULL; - - FUNC_ENTER_NOAPI(NULL); - - /* Not VFD SWMR */ - if (_self->driver_id != H5FD_VFD_SWMR_g) { - if (H5FD_cmp(_self, _other) == 0) - HGOTO_DONE(_self) - else - HGOTO_DONE(_other) - } - - /* VFD SWMR */ - if (_self->cls == _other->cls) { - H5FD_vfd_swmr_t * other = (H5FD_vfd_swmr_t *)_other; - H5P_genplist_t * plist; - H5F_vfd_swmr_config_t *config; - hbool_t equal_configs; - - if (H5FD_cmp(self->hdf5_file_lf, other->hdf5_file_lf) != 0) - HGOTO_DONE(_other) - - /* If fapl_id != _ANY_VFD, then we have either a duplicate or - * a conflict. If the VFD SWMR parameters match, then - * return `self` to indicate a duplicate. Otherwise, return - * NULL to indicate a mismatch. - */ - if (NULL == (plist = H5I_object(fapl_id))) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "could not get fapl") - - if ((config = H5MM_malloc(sizeof(*config))) == NULL) - HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, NULL, "could not allocate config") - if (H5P_get(plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, config) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "cannot get VFD SWMR config") - - equal_configs = HDmemcmp(&self->config, config, sizeof(*config)) == 0; - - H5MM_xfree(config); - - if (equal_configs) - HGOTO_DONE(_self) - - HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "inconsistent VFD SWMR config") - } - else if (H5FD_cmp(self->hdf5_file_lf, _other) == 0) - ret_value = NULL; - else - ret_value = _other; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5FD_vfd_swmr_dedup() */ - -/*------------------------------------------------------------------------- * Function: H5FD__vfd_swmr_query * * Purpose: Set the flags that this VFL driver is capable of supporting. @@ -924,9 +1001,6 @@ H5FD__vfd_swmr_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id herr_t ret_value = SUCCEED; char * p = buf; - if (file->writer) - return H5FD_read(file->hdf5_file_lf, type, addr, size, buf); - FUNC_ENTER_PACKAGE HDassert(file && file->pub.cls); @@ -1027,50 +1101,44 @@ done: /*------------------------------------------------------------------------- * Function: H5FD__vfd_swmr_write * - * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR - * from buffer BUF according to data transfer properties in - * DXPL_ID. + * Purpose: As the VFD SWMR reader VFD is only use on files that are + * opened read only, this function should be unreachable. * - * Return: SUCCEED/FAIL + * Return: FAIL *------------------------------------------------------------------------- */ static herr_t -H5FD__vfd_swmr_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, - const void *buf) +H5FD__vfd_swmr_write(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, + hid_t H5_ATTR_UNUSED dxpl_id, haddr_t H5_ATTR_UNUSED addr, size_t H5_ATTR_UNUSED size, + const void H5_ATTR_UNUSED *buf) { - H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; + FUNC_ENTER_PACKAGE_NOERR /* Yes, even though this pushes an error on the stack */ - /* This routine should only be called if the VFD instance is opened - * for writing. - */ - HDassert(file->writer); + HERROR(H5E_CACHE, H5E_SYSTEM, "called unreachable fcn."); + + FUNC_LEAVE_NOAPI(FAIL) - return H5FD_write(file->hdf5_file_lf, type, addr, size, buf); } /* end H5FD__vfd_swmr_write() */ /*------------------------------------------------------------------------- * Function: H5FD_vfd_swmr_truncate * - * Purpose: Makes sure that the true file size is the same (or larger) - * than the end-of-address for the underlying HDF5 file + * Purpose: As the VFD SWMR reader VFD is only use on files that are + * opened read only, this function should be unreachable. * - * Return: SUCCEED/FAIL + * Return: FAIL * *------------------------------------------------------------------------- */ static herr_t -H5FD__vfd_swmr_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, hbool_t closing) +H5FD__vfd_swmr_truncate(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED dxpl_id, + hbool_t H5_ATTR_UNUSED closing) { - H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; /* VFD SWMR file struct */ + FUNC_ENTER_PACKAGE_NOERR /* Yes, even though this pushes an error on the stack */ - FUNC_ENTER_PACKAGE_NOERR - - /* This routine should only be called if the VFD instance is opened - * for writing. - */ - HDassert(file->writer); + HERROR(H5E_CACHE, H5E_SYSTEM, "called unreachable fcn."); - FUNC_LEAVE_NOAPI(H5FD_truncate(file->hdf5_file_lf, closing)) + FUNC_LEAVE_NOAPI(FAIL) } /*------------------------------------------------------------------------- @@ -1128,6 +1196,65 @@ done: } /* end H5FD__vfd_swmr_unlock() */ /*------------------------------------------------------------------------- + * Function: H5FD__vfd_swmr_ctl + * + * Purpose: VFD SWMR reader VFD version of the ctl callback. + * + * 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 + * + * At present, this VFD supports no op codes of its own and + * simply passes ctl calls on to the underlying VFD. + * + * Return: Non-negative on success/Negative on failure + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD__vfd_swmr_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, void **output) +{ + H5FD_vfd_swmr_t *file = (H5FD_vfd_swmr_t *)_file; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(file); + + switch (op_code) { + + /* Unknown op code */ + default: + if (flags & H5FD_CTL__ROUTE_TO_TERMINAL_VFD_FLAG) { + /* Pass ctl call down to R/W channel VFD */ + if (H5FDctl(file->hdf5_file_lf, op_code, flags, input, output) < 0) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "VFD ctl request failed") + } + else { + /* If no valid VFD routing flag is specified, fail for unknown op code + * if H5FD_CTL__FAIL_IF_UNKNOWN_FLAG flag is set. + */ + if (flags & H5FD_CTL__FAIL_IF_UNKNOWN_FLAG) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, + "VFD ctl request failed (unknown op code and fail if unknown flag is set)") + } + + break; + } + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* end H5FD__vfd_swmr_ctl() */ + +/*------------------------------------------------------------------------- * Function: H5FD__vfd_swmr_load_hdr_and_idx() * * Purpose: Load and decode the header and index in the metadata file diff --git a/src/H5FDvfd_swmr.h b/src/H5FDvfd_swmr.h index dfd8d19..95e7979 100644 --- a/src/H5FDvfd_swmr.h +++ b/src/H5FDvfd_swmr.h @@ -19,12 +19,49 @@ #define H5FD_VFD_SWMR (H5FDperform_init(H5FD_vfd_swmr_init)) #define H5FD_VFD_SWMR_VALUE H5_VFD_SWMR +/* Semi-unique constant used to help identify structure pointers */ +#define H5FD_VFD_SWMR_READER_MAGIC 0xABC123 + +/* ---------------------------------------------------------------------------- + * Structure: H5FD_vfd_swmr_reader_fapl_t + * + * Structure for configuring the VFD SWMR reader VFD. This structure and the + * associated FAPL entry and get / set routines are for HDF5 library use only, + * and should never be seen by the user. + * + * When a file is opened in VFD SWMR mode, the VFD SWMR reader VFD is inserted + * at the top of the user supplied (or default) VFD stack. + * + * The fields of this structure are discussed indvidually below. Note that + * there is no version field, since this structure should not be accessible + * to the user. The set of fields is quite limited, as most of the necessary + * configuration data is taken from the VFD SWMR configuration FAPL entry + * + * magic (int32_t) + * Semi-unique number, used to sanity-check that a given pointer is + * likely (or not) to be this structure type. MUST be first. + * If magic is not H5FD_VFD_SWMR_READER_MAGIC, the structure (and/or + * pointer to) must be considered invalid. + * + * fapl_id (hid_t) + * Library-given identification number of the FAPL containing the user + * supplied VFD stack. Must be set to H5P_DEFAULT or contain a file + * driver entry specifying a VFD that supports VFD SWMR + * + * ---------------------------------------------------------------------------- + */ +typedef struct H5FD_vfd_swmr_reader_fapl_t { + int32_t magic; + hid_t fapl_id; +} H5FD_vfd_swmr_reader_fapl_t; + #ifdef __cplusplus extern "C" { #endif H5_DLL hid_t H5FD_vfd_swmr_init(void); -H5_DLL herr_t H5Pset_fapl_vfd_swmr(hid_t fapl_id); +H5_DLL herr_t H5P_pop_vfd_swmr_reader_vfd_off_fapl(hid_t fapl_id); +H5_DLL herr_t H5P_push_vfd_swmr_reader_vfd_on_fapl(hid_t fapl_id); #ifdef __cplusplus } diff --git a/src/H5Fint.c b/src/H5Fint.c index 9880126..2f384fc 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -38,6 +38,10 @@ #include "H5Tprivate.h" /* Datatypes */ #include "H5VLprivate.h" /* Virtual Object Layer */ +#if 1 /* JRM */ /* probably want to re-work this */ +#include "H5FDvfd_swmr.h" +#endif /* JRM */ + #include "H5VLnative_private.h" /* Native VOL connector */ /****************/ @@ -1803,49 +1807,48 @@ done: H5F_t * H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) { - H5F_t * file = NULL; /*the success return value */ - H5F_shared_t * shared = NULL; /*shared part of `file' */ - H5FD_t * lf = NULL; /*file driver part of `shared' */ - unsigned tent_flags; /*tentative flags */ - H5FD_class_t * drvr; /*file driver class info */ - H5P_genplist_t * a_plist; /*file access property list */ - H5F_close_degree_t fc_degree; /*file close degree */ - size_t page_buf_size; - unsigned page_buf_min_meta_perc = 0; - unsigned page_buf_min_raw_perc = 0; - hbool_t set_flag = FALSE; /* Set the status_flags in the superblock */ - hbool_t clear = FALSE; /* Clear the status_flags */ - hbool_t evict_on_close; /* Evict on close value from plist */ - hbool_t use_file_locking = TRUE; /* Using file locks? */ - hbool_t ci_load = FALSE; /* Whether MDC ci load requested */ - hbool_t ci_write = FALSE; /* Whether MDC ci write requested */ - hbool_t file_create = FALSE; /* Creating a new file or not */ - H5F_vfd_swmr_config_t * vfd_swmr_config_ptr = NULL; /* Points to VFD SMWR config info */ - H5F_generate_md_ck_cb_t cb_info = {NULL}; /* For VFD SWMR NFS testing: - initialize the callback to generate - checksums for metadata files */ - H5F_t *ret_value = NULL; /* Actual return value */ + H5F_t * file = NULL; /*the success return value */ + H5F_shared_t * shared = NULL; /*shared part of `file' */ + H5FD_t * lf = NULL; /*file driver part of `shared' */ + unsigned tent_flags; /*tentative flags */ + H5FD_class_t * drvr; /*file driver class info */ + H5P_genplist_t * a_plist; /*file access property list */ + H5F_close_degree_t fc_degree; /*file close degree */ + size_t page_buf_size; + unsigned page_buf_min_meta_perc = 0; + unsigned page_buf_min_raw_perc = 0; + hbool_t vfd_swmr = FALSE; /* TRUE iff opening file with VFD SWMR */ + hbool_t vfd_swmr_writer = FALSE; /* TRUE iff opening file as VFD SWMR */ + /* writer. */ + hbool_t pop_vfd_swmr_reader_vfd = FALSE; /* Flag set when the VFD SWMR reader VFD */ + /* has been pushed on the supplied fapl */ + /* and must be popped before return. */ + hbool_t set_flag = FALSE; /* Set the status_flags in the superblock */ + hbool_t clear = FALSE; /* Clear the status_flags */ + hbool_t evict_on_close; /* Evict on close value from plist */ + hbool_t use_file_locking = TRUE; /* Using file locks? */ + hbool_t ci_load = FALSE; /* Whether MDC ci load requested */ + hbool_t ci_write = FALSE; /* Whether MDC ci write requested */ + hbool_t file_create = FALSE; /* Creating a new file or not */ + H5F_vfd_swmr_config_t * vfd_swmr_config_ptr = NULL; /* Points to VFD SMWR config info */ + H5F_generate_md_ck_cb_t cb_info = {NULL}; /* For VFD SWMR NFS testing: + initialize the callback to generate + checksums for metadata files */ + H5F_t *ret_value = NULL; /* Actual return value */ FUNC_ENTER_NOAPI(NULL) - /* - * If the driver has a 'cmp' method then the driver is capable of - * determining when two file handles refer to the same file and the - * library can insure that when the application opens a file twice - * that the two handles coordinate their operations appropriately. - * Otherwise it is the application's responsibility to never open the - * same file more than once at a time. - */ - if (NULL == (drvr = H5FD_get_class(fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class") - /* Get the file access property list, for future queries */ if (NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") - /* Check if we are using file locking */ - if (H5F__check_if_using_file_locks(a_plist, &use_file_locking) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get file locking flag") + /* start by testing to see if we are opening the file VFD SWMR reader. If + * we are, we must "push" the vfd swrm reader vfd on the vfd "stack" supplied + * by the user in the fapl. Since the user may use the fapl elsewhere, we + * must "pop" the vfd swmr reader vfd off the vfd "stack" before we return. + * + * In passing, collect the VFD SWMR configuration info for later use. + */ /* Allocate space for VFD SWMR configuration info */ if (NULL == (vfd_swmr_config_ptr = H5MM_calloc(sizeof(H5F_vfd_swmr_config_t)))) @@ -1857,18 +1860,78 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* When configured with VFD SWMR */ if (vfd_swmr_config_ptr->version) { + + /* get the page buffer size and verify that it is greater than zero. Note + * that this get of the page buffer size is redundant -- we do it again + * below. + */ + if (H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_SIZE_NAME, &page_buf_size) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get page buffer size"); + + if (page_buf_size == 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "page buffering must be enabled") + + /* Paged allocation must also be enabled, but the page buffer + * initialization (H5PB_create) will detect a conflicting configuration + * and return an error. + */ + + /* Legacy SWMR and VFD SWMR are incompatible. Fail if the legacy SWMR flags are set */ + if ((flags & H5F_ACC_SWMR_WRITE) || (flags & H5F_ACC_SWMR_READ)) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "Legacy and VFD SWMR are incompatible") + /* Verify that file access flags are consistent with VFD SWMR configuration */ if ((flags & H5F_ACC_RDWR) && !vfd_swmr_config_ptr->writer) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "file access is writer but VFD SWMR config is reader") if ((flags & H5F_ACC_RDWR) == 0 && vfd_swmr_config_ptr->writer) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "file access is reader but VFD SWMR config is writer") + if (((flags & H5F_ACC_RDWR) == 0) && (!vfd_swmr_config_ptr->writer)) { + + vfd_swmr = TRUE; + + /* We are opening a file as a VFD SWMR reader. Push the vfd swrm reader vfd on the + * vfd stack specified in the fapl. Set the pop_vfd_swmr_reader flag to trigger a + * pop of the vfd swmr reader vfd on exit from this function. + */ + if (H5P_push_vfd_swmr_reader_vfd_on_fapl(fapl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't push VFD SWMR reader VFD on FAPL"); + + pop_vfd_swmr_reader_vfd = TRUE; + } + else if ((flags & H5F_ACC_RDWR) && (vfd_swmr_config_ptr->writer)) { + + vfd_swmr = TRUE; + vfd_swmr_writer = TRUE; + } + + /* if we get to this point, vfd_swmr must be TRUE. */ + HDassert(vfd_swmr); + /* Retrieve the private property for VFD SWMR testing */ if (H5P_get(a_plist, H5F_ACS_GENERATE_MD_CK_CB_NAME, &cb_info) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get generate_md_ck_cb info") + } - if (!vfd_swmr_config_ptr->writer) - use_file_locking = FALSE; + /* + * If the driver has a 'cmp' method then the driver is capable of + * determining when two file handles refer to the same file and the + * library can insure that when the application opens a file twice + * that the two handles coordinate their operations appropriately. + * Otherwise it is the application's responsibility to never open the + * same file more than once at a time. + */ + if (NULL == (drvr = H5FD_get_class(fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class") + + /* Check if we are using file locking */ + if (H5F__check_if_using_file_locks(a_plist, &use_file_locking) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get file locking flag") + + /* turn off file locking unconditionally if the file is being opened VFD SWMR reader */ + if ((vfd_swmr) && (!vfd_swmr_writer)) { + + use_file_locking = FALSE; } /* @@ -1901,8 +1964,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) /* Avoid reusing a virtual file opened exclusively by a second virtual * file, or opening the same file twice with different parameters. */ - if ((lf = H5FD_deduplicate(lf, fapl_id)) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "an already-open file conflicts with '%s'", name) /* Is the file already open? */ if ((shared = H5F__sfile_search(lf)) != NULL) { @@ -1916,6 +1977,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) * readers don't expect the file to change under them), or if the * SWMR write/read access flags don't agree. */ + if (H5FD_close(lf) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") if (flags & H5F_ACC_TRUNC) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open") if (flags & H5F_ACC_EXCL) @@ -1932,6 +1995,17 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "SWMR read access flag not the same for file that is already open") + /* fail if VFD SWMR configurations disagree */ + if (HDmemcmp(&(shared->vfd_swmr_config), vfd_swmr_config_ptr, sizeof(H5F_vfd_swmr_config_t))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "VFD SWMR configuration not the same for file that is already open") + + /* Arguably, we should fail if there is a page size mismatch. However, if I read + * the code correctly, the page size and page buffer configuration from the open file + * will domininate. Thus, there probably isn't a functional issue. That said, + * this should be thought about. + */ + /* Allocate new "high-level" file struct */ if ((file = H5F__new(shared, flags, fcpl_id, fapl_id, NULL)) == NULL) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") @@ -2220,6 +2294,9 @@ done: if (vfd_swmr_config_ptr) H5MM_free(vfd_swmr_config_ptr); + if ((pop_vfd_swmr_reader_vfd) && (H5P_pop_vfd_swmr_reader_vfd_off_fapl(fapl_id) < 0)) + HDONE_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't pop vfd swrm reader vfd off vfd stack") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_open() */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index c594ed8..e5d3339 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -1218,6 +1218,8 @@ H5_DLL herr_t H5F_get_vfd_handle(const H5F_t *file, hid_t fapl, void **file_han /* VFD SWMR functions */ H5_DLL hbool_t H5F_get_use_vfd_swmr(const H5F_t *f); H5_DLL herr_t H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create); +H5_DLL herr_t H5F_vfd_swmr_build_md_path_name(H5F_vfd_swmr_config_t *config, const char *hdf5_filename, + char *name /*out*/); H5_DLL herr_t H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing); H5_DLL herr_t H5F_update_vfd_swmr_metadata_file(H5F_t *f, uint32_t index_len, H5FD_vfd_swmr_idx_entry_t *index); diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c index 9c4360e..702c362 100644 --- a/src/H5Fvfd_swmr.c +++ b/src/H5Fvfd_swmr.c @@ -49,8 +49,9 @@ /* Local Macros */ /****************/ -#define NANOSECS_PER_SECOND 1000000000 /* nanoseconds per second */ -#define NANOSECS_PER_TENTH_SEC 100000000 /* nanoseconds per 0.1 second */ +#define VFD_SWMR_MD_FILE_SUFFIX ".md" +#define NANOSECS_PER_SECOND 1000000000 /* nanoseconds per second */ +#define NANOSECS_PER_TENTH_SEC 100000000 /* nanoseconds per 0.1 second */ /* Declare an array of string to identify the VFD SMWR Log tags. * Note this array is used to generate the entry tag by the log reporting macro @@ -186,8 +187,13 @@ H5F_vfd_swmr_init(H5F_t *f, hbool_t file_create) shared->vfd_swmr_writer = TRUE; shared->tick_num = 0; - /* Retrieve the metadata filename built with md_file_path and md_file_name */ - H5FD_vfd_swmr_get_md_path_name(f->shared->lf, &shared->md_file_path_name); + /* Allocate space for the (possibly constructed) metadata file name */ + if (NULL == (shared->md_file_path_name = H5MM_calloc((H5FD_MAX_FILENAME_LEN + 1) * sizeof(char)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate memory for mdc log file name") + + if (H5F_vfd_swmr_build_md_path_name(&(shared->vfd_swmr_config), f->open_name, + shared->md_file_path_name) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to build metadata file name") if (((shared->vfd_swmr_md_fd = HDopen(shared->md_file_path_name, O_CREAT | O_RDWR | O_TRUNC, H5_POSIX_CREATE_MODE_RW))) < 0) @@ -281,6 +287,66 @@ done: } /* H5F_vfd_swmr_init() */ /*------------------------------------------------------------------------- + * + * Function: H5F_vfd_swmr_build_md_path_name + * + * Purpose: To construct the metadata file's full name based on config's + * md_file_path and md_file_name. See RFC for details. + * + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Vailin Choi -- 1/13/2022 + * + * Changes: Moved to H5Fvfd_swmr.c from H5FDvfd_swmr.c, and renamed + * accordingly. Changed FUNC_ENTER_PACKAGE to + * FUNC_ENTER_NOAPI. Converted to a private function so + * that it can be called in H5FDvfd_swmr.c + * + * JRM -- 5/17/22 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_vfd_swmr_build_md_path_name(H5F_vfd_swmr_config_t *config, const char *hdf5_filename, char *name /*out*/) +{ + size_t tot_len = 0; + size_t tmp_len = 0; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + if ((tot_len = HDstrlen(config->md_file_path)) != 0) { + + /* md_file_path + '/' */ + if (++tot_len > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "md_file_path and md_file_name exceeds maximum"); + HDstrcat(name, config->md_file_path); + HDstrcat(name, "/"); + } + + if ((tmp_len = HDstrlen(config->md_file_name)) != 0) { + if ((tot_len += tmp_len) > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "md_file_path and md_file_name exceeds maximum"); + HDstrcat(name, config->md_file_name); + } + else { + /* Automatic generation of metadata file name based on hdf5_filename + '.md' */ + if ((tot_len += (HDstrlen(hdf5_filename) + 3)) > H5F__MAX_VFD_SWMR_FILE_NAME_LEN) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "md_file_path and md_file_name maximum"); + + HDstrcat(name, hdf5_filename); + HDstrcat(name, VFD_SWMR_MD_FILE_SUFFIX); + } + +done: + + FUNC_LEAVE_NOAPI(ret_value) + +} /* H5F_vfd_swmr_build_md_path_name() */ + +/*------------------------------------------------------------------------- * Function: H5F_vfd_swmr_close_or_flush * * Purpose: Used by the VFD SWMR writer when the HDF5 file is closed diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index f900965..d6beece 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -6283,9 +6283,6 @@ H5Pset_vfd_swmr_config(hid_t plist_id, H5F_vfd_swmr_config_t *config_ptr) if (H5P_set(plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, config_ptr) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache initial config") - if (H5P_set_driver(plist, H5FD_VFD_SWMR, NULL, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set VFD SWMR driver info"); - done: FUNC_LEAVE_API(ret_value) } /* H5Pset_vfd_swmr_config() */ diff --git a/test/vfd_swmr.c b/test/vfd_swmr.c index 924da07..e3149f2 100644 --- a/test/vfd_swmr.c +++ b/test/vfd_swmr.c @@ -5402,12 +5402,12 @@ test_vfds_same_file_opens(hid_t orig_fapl, const char *env_h5_drvr) if (H5Pclose(fapl) < 0) FAIL_STACK_ERROR; -#if 0 /* Use test cases #4 and #5 when John's changes are merged */ - /* - * Case #4 +#if 1 /* Use test cases #4 and #5 when John's changes are merged */ + /* + * Case #4 * --Open the file as writer with both legacy SWMR and VFD SWMR configured . * --NOTE: The open should fail when John's changes are merged but for now it succeeds. - */ + */ /* * Set up VFD SWMR configuration as writer in fapl @@ -5416,8 +5416,7 @@ test_vfds_same_file_opens(hid_t orig_fapl, const char *env_h5_drvr) /* config, tick_len, max_lag, presume_posix_semantics, writer, * maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, * md_file_path, md_file_name, updater_file_path */ - init_vfd_swmr_config(config, 4, 10, FALSE, TRUE, TRUE, FALSE, TRUE, 2, NULL, - MD_FILENAME, NULL); + init_vfd_swmr_config(config, 4, 10, FALSE, TRUE, TRUE, FALSE, TRUE, 2, NULL, MD_FILENAME, NULL); if ((fapl = H5Pcopy(orig_fapl)) < 0) FAIL_STACK_ERROR; @@ -5442,18 +5441,17 @@ test_vfds_same_file_opens(hid_t orig_fapl, const char *env_h5_drvr) if (H5Pclose(fapl) < 0) FAIL_STACK_ERROR; - /* + /* * Case #5: * --Open the file as reader with both legacy SWMR and VFD SWMR configured . * --NOTE: The open should fail when John's changes are merged but for now it succeeds. - */ + */ /* config, tick_len, max_lag, presume_posix_semantics, writer, * maintain_metadata_file, generate_updater_files, flush_raw_data, md_pages_reserved, * md_file_path, md_file_name, updater_file_path */ /* NOTE: Set "presume_posix_semantics" to TRUE and "writer" to FALSE */ - init_vfd_swmr_config(config, 4, 10, TRUE, FALSE, TRUE, FALSE, TRUE, 2, NULL, - MD_FILENAME, NULL); + init_vfd_swmr_config(config, 4, 10, TRUE, FALSE, TRUE, FALSE, TRUE, 2, NULL, MD_FILENAME, NULL); if ((fapl = H5Pcopy(orig_fapl)) < 0) FAIL_STACK_ERROR; @@ -5469,11 +5467,11 @@ test_vfds_same_file_opens(hid_t orig_fapl, const char *env_h5_drvr) } H5E_END_TRY; /* Change the section of code inside the "for loop" to TEST_ERROR when John's changes are merged */ - if(fid1 >= 0) { + if (fid1 >= 0) { printf("The reader open succeeds which shouldn't be\n"); if (H5Fclose(fid1) < 0) FAIL_STACK_ERROR; - } + } if (H5Pclose(fapl) < 0) FAIL_STACK_ERROR; |