diff --git a/src/H5FDsubfiling/H5FDioc.c b/src/H5FDsubfiling/H5FDioc.c index f43f638ff0c..8ec066a0a68 100644 --- a/src/H5FDsubfiling/H5FDioc.c +++ b/src/H5FDsubfiling/H5FDioc.c @@ -88,16 +88,6 @@ typedef struct H5FD_ioc_t { #define REGION_OVERFLOW(A, Z) \ (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || HADDR_UNDEF == (A) + (Z) || (HDoff_t)((A) + (Z)) < (HDoff_t)(A)) -#ifdef H5FD_IOC_DEBUG -#define H5FD_IOC_LOG_CALL(name) \ - do { \ - printf("called %s()\n", (name)); \ - fflush(stdout); \ - } while (0) -#else -#define H5FD_IOC_LOG_CALL(name) /* no-op */ -#endif - /* Private functions */ /* Prototypes */ static herr_t H5FD__ioc_term(void); @@ -111,13 +101,9 @@ static H5FD_t *H5FD__ioc_open(const char *name, unsigned flags, hid_t fapl_id, h static herr_t H5FD__ioc_close(H5FD_t *_file); static int H5FD__ioc_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD__ioc_query(const H5FD_t *_file, unsigned long *flags /* out */); -static herr_t H5FD__ioc_get_type_map(const H5FD_t *_file, H5FD_mem_t *type_map); -static haddr_t H5FD__ioc_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); -static herr_t H5FD__ioc_free(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t size); static haddr_t H5FD__ioc_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type); static herr_t H5FD__ioc_set_eoa(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr); static haddr_t H5FD__ioc_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type); -static herr_t H5FD__ioc_get_handle(H5FD_t *_file, hid_t H5_ATTR_UNUSED fapl, void **file_handle); static herr_t H5FD__ioc_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, void *buf); static herr_t H5FD__ioc_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t size, @@ -126,26 +112,22 @@ static herr_t H5FD__ioc_read_vector(H5FD_t *file, hid_t dxpl_id, uint32_t count haddr_t addrs[], size_t sizes[], void *bufs[] /* out */); static herr_t H5FD__ioc_write_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 */); -static herr_t H5FD__ioc_flush(H5FD_t *_file, hid_t dxpl_id, bool closing); static herr_t H5FD__ioc_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing); -static herr_t H5FD__ioc_lock(H5FD_t *_file, bool rw); -static herr_t H5FD__ioc_unlock(H5FD_t *_file); static herr_t H5FD__ioc_del(const char *name, hid_t fapl); /* static herr_t H5FD__ioc_ctl(H5FD_t *file, uint64_t op_code, uint64_t flags, const void *input, void **result); */ -static herr_t H5FD__ioc_get_default_config(H5FD_ioc_config_t *config_out); static herr_t H5FD__ioc_validate_config(const H5FD_ioc_config_t *fa); -static herr_t H5FD__ioc_close_int(H5FD_ioc_t *file_ptr); +static herr_t H5FD__ioc_close_int(H5FD_ioc_t *file); -static herr_t H5FD__ioc_write_vector_internal(H5FD_t *_file, uint32_t count, H5FD_mem_t types[], +static herr_t H5FD__ioc_write_vector_internal(H5FD_ioc_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* data_in */); -static herr_t H5FD__ioc_read_vector_internal(H5FD_t *_file, uint32_t count, haddr_t addrs[], size_t sizes[], - void *bufs[] /* data_out */); +static herr_t H5FD__ioc_read_vector_internal(H5FD_ioc_t *file, uint32_t count, haddr_t addrs[], + size_t sizes[], void *bufs[] /* data_out */); static const H5FD_class_t H5FD_ioc_g = { H5FD_CLASS_VERSION, /* VFD interface version */ @@ -168,23 +150,23 @@ static const H5FD_class_t H5FD_ioc_g = { H5FD__ioc_close, /* close */ H5FD__ioc_cmp, /* cmp */ H5FD__ioc_query, /* query */ - H5FD__ioc_get_type_map, /* get_type_map */ - H5FD__ioc_alloc, /* alloc */ - H5FD__ioc_free, /* free */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ H5FD__ioc_get_eoa, /* get_eoa */ H5FD__ioc_set_eoa, /* set_eoa */ H5FD__ioc_get_eof, /* get_eof */ - H5FD__ioc_get_handle, /* get_handle */ + NULL, /* get_handle */ H5FD__ioc_read, /* read */ H5FD__ioc_write, /* write */ H5FD__ioc_read_vector, /* read_vector */ H5FD__ioc_write_vector, /* write_vector */ NULL, /* read_selection */ NULL, /* write_selection */ - H5FD__ioc_flush, /* flush */ + NULL, /* flush */ H5FD__ioc_truncate, /* truncate */ - H5FD__ioc_lock, /* lock */ - H5FD__ioc_unlock, /* unlock */ + NULL, /* lock */ + NULL, /* unlock */ H5FD__ioc_del, /* del */ NULL, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ @@ -211,7 +193,7 @@ H5FD_ioc_init(void) { hid_t ret_value = H5I_INVALID_HID; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_NOAPI(H5I_INVALID_HID) /* Register the IOC VFD, if it isn't already registered */ if (H5I_VFL != H5I_get_type(H5FD_IOC_g)) { @@ -220,7 +202,7 @@ H5FD_ioc_init(void) int mpi_code; if ((H5FD_IOC_g = H5FD_register(&H5FD_ioc_g, sizeof(H5FD_class_t), false)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register IOC VFD"); + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register IOC VFD"); /* Check if IOC VFD has been loaded dynamically */ env_var = getenv(HDF5_DRIVER); @@ -230,45 +212,43 @@ H5FD_ioc_init(void) /* Initialize MPI if not already initialized */ if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_initialized))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); if (mpi_initialized) { /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ if (MPI_SUCCESS != (mpi_code = MPI_Query_thread(&provided))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); if (provided != MPI_THREAD_MULTIPLE) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "IOC VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "IOC VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); } else { int required = MPI_THREAD_MULTIPLE; /* Otherwise, initialize MPI */ if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(NULL, NULL, required, &provided))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); H5FD_mpi_self_initialized = true; if (provided != required) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); } } /* Retrieve upper bound for MPI message tag value */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_TAG_UB, &H5FD_IOC_tag_ub_val_ptr, &key_val_retrieved))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Comm_get_attr failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Comm_get_attr failed", mpi_code); if (!key_val_retrieved) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "couldn't retrieve value for MPI_TAG_UB"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "couldn't retrieve value for MPI_TAG_UB"); } ret_value = H5FD_IOC_g; done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_ioc_init() */ /*--------------------------------------------------------------------------- @@ -276,7 +256,7 @@ H5FD_ioc_init(void) * * Purpose: Shut down the IOC VFD. * - * Returns: SUCCEED (Can't fail) + * Return: SUCCEED/FAIL *--------------------------------------------------------------------------- */ static herr_t @@ -284,7 +264,7 @@ H5FD__ioc_term(void) { herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE if (H5FD_IOC_g >= 0) { /* Terminate MPI if the driver initialized it */ @@ -293,11 +273,10 @@ H5FD__ioc_term(void) int mpi_code; if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); - if (!mpi_finalized) { + HMPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + if (!mpi_finalized) if (MPI_SUCCESS != (mpi_code = MPI_Finalize())) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalize failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Finalize failed", mpi_code); H5FD_mpi_self_initialized = false; } @@ -307,7 +286,7 @@ H5FD__ioc_term(void) /* Reset VFL ID */ H5FD_IOC_g = H5I_INVALID_HID; - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_term() */ /*------------------------------------------------------------------------- @@ -322,38 +301,30 @@ H5FD__ioc_term(void) herr_t H5Pset_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *vfd_config) { - H5FD_ioc_config_t *ioc_conf = NULL; - H5P_genplist_t *plist_ptr = NULL; - herr_t ret_value = SUCCEED; + H5FD_ioc_config_t ioc_conf; + H5P_genplist_t *plist = NULL; + herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_API(FAIL) - if (NULL == (plist_ptr = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); if (vfd_config == NULL) { - if (NULL == (ioc_conf = H5FL_CALLOC(H5FD_ioc_config_t))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate IOC VFD configuration"); - /* Get IOC VFD defaults */ - if (H5FD__ioc_get_default_config(ioc_conf) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't get default IOC VFD configuration"); + if (H5FD__subfiling_get_default_ioc_config(&ioc_conf) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't get default IOC VFD configuration"); - vfd_config = ioc_conf; + vfd_config = &ioc_conf; } if (H5FD__ioc_validate_config(vfd_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC VFD configuration"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC VFD configuration"); - ret_value = H5P_set_driver(plist_ptr, H5FD_IOC, vfd_config, NULL); + ret_value = H5P_set_driver(plist, H5FD_IOC, vfd_config, NULL); done: - if (ioc_conf) { - H5FL_FREE(H5FD_ioc_config_t, ioc_conf); - } - - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_API(ret_value) } /* end H5Pset_fapl_ioc() */ /*------------------------------------------------------------------------- @@ -371,68 +342,39 @@ H5Pset_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *vfd_config) herr_t H5Pget_fapl_ioc(hid_t fapl_id, H5FD_ioc_config_t *config_out) { - const H5FD_ioc_config_t *config_ptr = NULL; - H5P_genplist_t *plist_ptr = NULL; + const H5FD_ioc_config_t *config = NULL; + H5P_genplist_t *plist = NULL; bool use_default_config = false; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_API(FAIL) /* Check arguments */ if (config_out == NULL) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_out is NULL"); - - if (NULL == (plist_ptr = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_out is NULL"); + if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); - if (H5FD_IOC != H5P_peek_driver(plist_ptr)) + if (H5FD_IOC != H5P_peek_driver(plist)) use_default_config = true; else { - config_ptr = H5P_peek_driver_info(plist_ptr); - if (NULL == config_ptr) + config = H5P_peek_driver_info(plist); + if (NULL == config) use_default_config = true; } if (use_default_config) { - if (H5FD__ioc_get_default_config(config_out) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get default IOC VFD configuration"); + if (H5FD__subfiling_get_default_ioc_config(config_out) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default IOC VFD configuration"); } - else { + else /* Copy the IOC fapl data out */ - H5MM_memcpy(config_out, config_ptr, sizeof(H5FD_ioc_config_t)); - } + H5MM_memcpy(config_out, config, sizeof(H5FD_ioc_config_t)); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_API(ret_value) } /* end H5Pget_fapl_ioc() */ -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_get_default_config - * - * Purpose: This is called by H5Pset/get_fapl_ioc when called with no - * established configuration info. This simply fills in - * the basics. This avoids the necessity of having the - * user write code to initialize the config structure. - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_get_default_config(H5FD_ioc_config_t *config_out) -{ - herr_t ret_value = SUCCEED; - - assert(config_out); - - memset(config_out, 0, sizeof(*config_out)); - - config_out->magic = H5FD_IOC_FAPL_MAGIC; - config_out->version = H5FD_IOC_CURR_FAPL_VERSION; - config_out->thread_pool_size = H5FD_IOC_DEFAULT_THREAD_POOL_SIZE; - - H5_SUBFILING_FUNC_LEAVE; -} - /*------------------------------------------------------------------------- * Function: H5FD__ioc_validate_config() * @@ -455,16 +397,17 @@ H5FD__ioc_validate_config(const H5FD_ioc_config_t *fa) { herr_t ret_value = SUCCEED; - assert(fa != NULL); + FUNC_ENTER_PACKAGE - if (fa->version != H5FD_IOC_CURR_FAPL_VERSION) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown H5FD_ioc_config_t version"); + assert(fa != NULL); if (fa->magic != H5FD_IOC_FAPL_MAGIC) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5FD_ioc_config_t magic value"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5FD_ioc_config_t magic value"); + if (fa->version != H5FD_IOC_CURR_FAPL_VERSION) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown H5FD_ioc_config_t version"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_validate_config() */ /*------------------------------------------------------------------------- @@ -485,7 +428,7 @@ H5FD__ioc_sb_size(H5FD_t H5_ATTR_UNUSED *_file) { hsize_t ret_value = 0; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Configuration structure magic number */ ret_value += sizeof(uint32_t); @@ -502,7 +445,7 @@ H5FD__ioc_sb_size(H5FD_t H5_ATTR_UNUSED *_file) /* Subfiling stripe count (encoded as int64_t for future) */ ret_value += sizeof(int64_t); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_sb_size */ /*------------------------------------------------------------------------- @@ -522,10 +465,10 @@ H5FD__ioc_sb_encode(H5FD_t *_file, char *name, unsigned char *buf) int64_t tmp64; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); /* Encode driver name */ strncpy(name, "IOC", 9); @@ -548,7 +491,7 @@ H5FD__ioc_sb_encode(H5FD_t *_file, char *name, unsigned char *buf) INT64ENCODE(p, tmp64); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_sb_encode */ /*------------------------------------------------------------------------- @@ -568,13 +511,13 @@ H5FD__ioc_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) int64_t tmp64; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); if (strncmp(name, "IOC", 9)) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver name in superblock"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver name in superblock"); /* Decode configuration structure magic number */ UINT32DECODE(p, file->fa.magic); @@ -595,26 +538,24 @@ H5FD__ioc_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) /* Validate the decoded configuration */ if (H5FD__ioc_validate_config(&file->fa) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "decoded IOC VFD configuration info is invalid"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "decoded IOC VFD configuration info is invalid"); - if (H5_subfiling_validate_config(&file->subf_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "decoded subfiling configuration parameters are invalid"); + if (H5FD__subfiling_validate_config_params(&file->subf_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "decoded subfiling configuration parameters are invalid"); if (file->subf_config.stripe_size != sf_context->sf_stripe_size) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "specified subfiling stripe size (%" PRId64 - ") doesn't match value stored in file (%" PRId64 ")", - sf_context->sf_stripe_size, file->subf_config.stripe_size); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "specified subfiling stripe size (%" PRId64 + ") doesn't match value stored in file (%" PRId64 ")", + sf_context->sf_stripe_size, file->subf_config.stripe_size); if (file->subf_config.stripe_count != sf_context->sf_num_subfiles) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_BADVALUE, FAIL, - "specified subfiling stripe count (%d) doesn't match value stored in file (%" PRId32 ")", - sf_context->sf_num_subfiles, file->subf_config.stripe_count); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "specified subfiling stripe count (%d) doesn't match value stored in file (%" PRId32 ")", + sf_context->sf_num_subfiles, file->subf_config.stripe_count); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_sb_decode */ /*------------------------------------------------------------------------- @@ -635,11 +576,13 @@ H5FD__ioc_fapl_get(H5FD_t *_file) H5FD_ioc_t *file = (H5FD_ioc_t *)_file; void *ret_value = NULL; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE - ret_value = H5FD__ioc_fapl_copy(&(file->fa)); + if (NULL == (ret_value = H5FD__ioc_fapl_copy(&file->fa))) + HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, NULL, "can't copy IOC fapl"); - H5_SUBFILING_FUNC_LEAVE; +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_fapl_get() */ /*------------------------------------------------------------------------- @@ -658,13 +601,12 @@ H5FD__ioc_fapl_copy(const void *_old_fa) H5FD_ioc_config_t *new_fa_ptr = NULL; void *ret_value = NULL; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE assert(old_fa_ptr); - new_fa_ptr = H5FL_CALLOC(H5FD_ioc_config_t); - if (NULL == new_fa_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate log file FAPL"); + if (NULL == (new_fa_ptr = H5FL_CALLOC(H5FD_ioc_config_t))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate log file FAPL"); H5MM_memcpy(new_fa_ptr, old_fa_ptr, sizeof(H5FD_ioc_config_t)); @@ -675,7 +617,7 @@ H5FD__ioc_fapl_copy(const void *_old_fa) if (new_fa_ptr) new_fa_ptr = H5FL_FREE(H5FD_ioc_config_t, new_fa_ptr); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_fapl_copy() */ /*-------------------------------------------------------------------------- @@ -692,7 +634,7 @@ H5FD__ioc_fapl_free(void *_fapl) H5FD_ioc_config_t *fapl = (H5FD_ioc_config_t *)_fapl; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Check arguments */ assert(fapl); @@ -700,7 +642,7 @@ H5FD__ioc_fapl_free(void *_fapl) /* Free the property list */ fapl = H5FL_FREE(H5FD_ioc_config_t, fapl); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_fapl_free() */ /*------------------------------------------------------------------------- @@ -717,86 +659,86 @@ H5FD__ioc_fapl_free(void *_fapl) static H5FD_t * H5FD__ioc_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_ioc_t *file_ptr = NULL; /* Ioc VFD info */ + H5FD_ioc_t *file = NULL; /* Ioc VFD info */ const H5FD_ioc_config_t *config_ptr = NULL; /* Driver-specific property list */ subfiling_context_t *sf_context = NULL; H5FD_ioc_config_t default_config; - H5P_genplist_t *plist_ptr = NULL; + H5P_genplist_t *plist = NULL; int ioc_flags; int mpi_inited = 0; int mpi_code; /* MPI return code */ H5FD_t *ret_value = NULL; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE /* Check arguments */ if (!name || !*name) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); if (0 == maxaddr || HADDR_UNDEF == maxaddr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); if (ADDR_OVERFLOW(maxaddr)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); - if (NULL == (file_ptr = (H5FD_ioc_t *)H5FL_CALLOC(H5FD_ioc_t))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); - file_ptr->comm = MPI_COMM_NULL; - file_ptr->info = MPI_INFO_NULL; - file_ptr->file_id = UINT64_MAX; - file_ptr->context_id = -1; + if (NULL == (file = (H5FD_ioc_t *)H5FL_CALLOC(H5FD_ioc_t))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); + file->comm = MPI_COMM_NULL; + file->info = MPI_INFO_NULL; + file->file_id = UINT64_MAX; + file->context_id = -1; /* Initialize file pointer's subfiling parameters */ - file_ptr->subf_config.ioc_selection = SELECT_IOC_ONE_PER_NODE; - file_ptr->subf_config.stripe_size = H5FD_SUBFILING_DEFAULT_STRIPE_SIZE; - file_ptr->subf_config.stripe_count = H5FD_SUBFILING_DEFAULT_STRIPE_COUNT; + file->subf_config.ioc_selection = SELECT_IOC_ONE_PER_NODE; + file->subf_config.stripe_size = H5FD_SUBFILING_DEFAULT_STRIPE_SIZE; + file->subf_config.stripe_count = H5FD_SUBFILING_DEFAULT_STRIPE_COUNT; /* Get the driver-specific file access properties */ - if (NULL == (plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a 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"); if (H5FD_mpi_self_initialized) { - file_ptr->comm = MPI_COMM_WORLD; - file_ptr->info = MPI_INFO_NULL; + file->comm = MPI_COMM_WORLD; + file->info = MPI_INFO_NULL; mpi_inited = 1; } else { /* Get the MPI communicator and info object from the property list */ - if (H5P_get(plist_ptr, H5F_ACS_MPI_PARAMS_COMM_NAME, &file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator"); - if (H5P_get(plist_ptr, H5F_ACS_MPI_PARAMS_INFO_NAME, &file_ptr->info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &file->comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &file->info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object"); - if (file_ptr->comm == MPI_COMM_NULL) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid or unset MPI communicator in FAPL"); + if (file->comm == MPI_COMM_NULL) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid or unset MPI communicator in FAPL"); /* Get the status of MPI initialization */ if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_inited))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Initialized failed", mpi_code); + HMPI_GOTO_ERROR(NULL, "MPI_Initialized failed", mpi_code); if (!mpi_inited) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, NULL, "MPI has not been initialized"); + HGOTO_ERROR(H5E_VFL, H5E_UNINITIALIZED, NULL, "MPI has not been initialized"); } /* Get the MPI rank of this process and the total number of processes */ - if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_ptr->comm, &file_ptr->mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_ptr->comm, &file_ptr->mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file->comm, &file->mpi_rank))) + HMPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file->comm, &file->mpi_size))) + HMPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code); - config_ptr = H5P_peek_driver_info(plist_ptr); + config_ptr = H5P_peek_driver_info(plist); if (!config_ptr || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) { - if (H5FD__ioc_get_default_config(&default_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get default IOC VFD configuration"); + if (H5FD__subfiling_get_default_ioc_config(&default_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default IOC VFD configuration"); config_ptr = &default_config; } /* Fill in the file config values */ - H5MM_memcpy(&file_ptr->fa, config_ptr, sizeof(H5FD_ioc_config_t)); + H5MM_memcpy(&file->fa, config_ptr, sizeof(H5FD_ioc_config_t)); /* Fully resolve the given filepath and get its dirname */ - if (H5_resolve_pathname(name, file_ptr->comm, &file_ptr->file_path) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't resolve filepath"); - if (H5_dirname(file_ptr->file_path, &file_ptr->file_dir) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get filepath dirname"); + if (H5FD__subfiling_resolve_pathname(name, file->comm, &file->file_path) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't resolve filepath"); + if (H5_dirname(file->file_path, &file->file_dir) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get filepath dirname"); /* Translate the HDF5 file open flags into standard POSIX open flags */ ioc_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; @@ -807,158 +749,130 @@ H5FD__ioc_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (H5F_ACC_EXCL & flags) ioc_flags |= O_EXCL; - if (NULL == (plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); - /* Retrieve the subfiling configuration for the current file */ - if (H5_subfiling_get_config_prop(plist_ptr, &file_ptr->subf_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get subfiling configuration from FAPL"); - if (H5_subfiling_validate_config(&file_ptr->subf_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "invalid subfiling configuration"); + if (H5FD__subfiling_get_config_prop(plist, &file->subf_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get subfiling configuration from FAPL"); + if (H5FD__subfiling_validate_config_params(&file->subf_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid subfiling configuration"); /* Retrieve the HDF5 stub file ID for the current file */ - if (H5_subfiling_get_file_id_prop(plist_ptr, &file_ptr->file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get stub file ID from FAPL"); - if (file_ptr->file_id == UINT64_MAX) { - /* Since this VFD does no displaying of error stacks itself - * (it relies on the Subfiling VFD to do this), we must print - * the error stack here if we know it wasn't stacked under the - * Subfiling VFD. - */ - H5_SUBFILING_DONE_ERROR( - H5E_PLIST, H5E_BADVALUE, NULL, - "subfiling stub file ID property was missing from FAPL - IOC VFD wasn't correctly stacked under " - "the Subfiling VFD and cannot currently be used alone"); - PRINT_ERROR_STACK; - goto done; - } + if (H5FD__subfiling_get_file_id_prop(plist, &file->file_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get stub file ID from FAPL"); + if (file->file_id == UINT64_MAX) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, + "subfiling stub file ID property was missing from FAPL - IOC VFD wasn't correctly " + "stacked under the subfiling VFD and cannot currently be used alone"); /* - * Open the subfiles for this HDF5 file. A subfiling - * context ID will be returned, which is used for - * further interactions with this file's subfiles. + * Open the subfiles for this HDF5 file. A subfiling context ID will be + * returned, which is used for further interactions with this file's subfiles. */ - if (H5_open_subfiles(file_ptr->file_path, file_ptr->file_id, &file_ptr->subf_config, ioc_flags, - file_ptr->comm, &file_ptr->context_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open subfiles for file '%s'", - name); + if (H5FD__subfiling_open_subfiles(file->file_path, file->file_id, &file->subf_config, ioc_flags, + file->comm, &file->context_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open subfiles for file '%s'", name); /* * Initialize I/O concentrator threads if this MPI rank is an I/O * concentrator and the threads haven't already been initialized by * a different open of this file */ - sf_context = H5_get_subfiling_object(file_ptr->context_id); + sf_context = H5FD__subfiling_get_object(file->context_id); if (sf_context && sf_context->topology->rank_is_ioc && !sf_context->threads_inited) { - if (initialize_ioc_threads(sf_context) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, - "unable to initialize I/O concentrator threads"); + if (H5FD__ioc_init_threads(sf_context) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to initialize I/O concentrator threads"); sf_context->threads_inited = true; } - ret_value = (H5FD_t *)file_ptr; + ret_value = (H5FD_t *)file; done: /* - * Check if any ranks failed before exit. The objective - * here is twofold: + * Check if any ranks failed before exit. The objective here is twofold: * - * - prevent possible hangs caused by ranks sending - * messages to I/O concentrators that failed and - * didn't spin up - * - use the barrier semantics of MPI_Allreduce to - * ensure that the I/O concentrators are fully up - * and running before proceeding. + * - prevent possible hangs caused by ranks sending messages to I/O + * concentrators that failed and didn't spin up + * - use the barrier semantics of MPI_Allreduce to ensure that the I/O + * concentrators are fully up and running before proceeding. */ if (mpi_inited) { MPI_Comm reduce_comm = MPI_COMM_WORLD; int mpi_size = -1; int err_result = (ret_value == NULL); - if (file_ptr && (file_ptr->comm != MPI_COMM_NULL)) - reduce_comm = file_ptr->comm; + if (file && (file->comm != MPI_COMM_NULL)) + reduce_comm = file->comm; if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(reduce_comm, &mpi_size))) - H5_SUBFILING_MPI_DONE_ERROR(NULL, "MPI_Comm_size failed", mpi_code); + HMPI_DONE_ERROR(NULL, "MPI_Comm_size failed", mpi_code); - if (mpi_size > 1) { + if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Allreduce(MPI_IN_PLACE, &err_result, 1, MPI_INT, MPI_MAX, reduce_comm))) - H5_SUBFILING_MPI_DONE_ERROR(NULL, "MPI_Allreduce failed", mpi_code); - } + HMPI_DONE_ERROR(NULL, "MPI_Allreduce failed", mpi_code); if (err_result) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "one or more MPI ranks were unable to open file '%s'", name); + HDONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "one or more MPI ranks were unable to open file '%s'", name); } - if (NULL == ret_value) { - if (file_ptr) { - if (H5FD__ioc_close_int(file_ptr) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "can't close IOC file"); - } - } /* end if error */ + if (NULL == ret_value) + if (file) + if (H5FD__ioc_close_int(file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "can't close IOC file"); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_open() */ static herr_t -H5FD__ioc_close_int(H5FD_ioc_t *file_ptr) +H5FD__ioc_close_int(H5FD_ioc_t *file) { int mpi_finalized; int mpi_code; herr_t ret_value = SUCCEED; - assert(file_ptr); + FUNC_ENTER_PACKAGE + + assert(file); if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); - if (file_ptr->context_id >= 0) { - subfiling_context_t *sf_context = H5_get_subfiling_object(file_ptr->context_id); + if (file->context_id >= 0) { + subfiling_context_t *sf_context = H5FD__subfiling_get_object(file->context_id); /* Don't allow IOC threads to be finalized until everyone gets here */ - if (!mpi_finalized && (file_ptr->mpi_size > 1)) - if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file_ptr->comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + if (!mpi_finalized && file->mpi_size > 1) + if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file->comm))) + HMPI_DONE_ERROR(FAIL, "MPI_Barrier failed", mpi_code); - /* Only finalize IOC threads and close subfiles if this is - * the last file holding a reference to the context + /* Only finalize IOC threads and close subfiles if this is the last file + * holding a reference to the context */ if (sf_context && sf_context->file_ref == 1) { - if (sf_context->topology->rank_is_ioc && sf_context->threads_inited) { - if (finalize_ioc_threads(sf_context) < 0) - /* Note that closing of subfiles is collective */ - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, - "unable to finalize IOC threads"); - } + if (sf_context->topology->rank_is_ioc && sf_context->threads_inited) + if (H5FD__ioc_finalize_threads(sf_context) < 0) + /* Fall through: closing of subfiles is collective */ + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to finalize IOC threads"); - if (H5_close_subfiles(file_ptr->context_id, file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, - "unable to close subfiling file(s)"); + if (H5FD__subfiling_close_subfiles(file->context_id, file->comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close subfiling file(s)"); } - - file_ptr->context_id = -1; } if (!mpi_finalized) { - if (H5_mpi_comm_free(&file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Communicator"); - if (H5_mpi_info_free(&file_ptr->info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Info object"); + if (H5_mpi_comm_free(&file->comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Communicator"); + if (H5_mpi_info_free(&file->info) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Info object"); } -done: - free(file_ptr->file_path); - file_ptr->file_path = NULL; - - H5MM_free(file_ptr->file_dir); - file_ptr->file_dir = NULL; + H5MM_free(file->file_path); + H5MM_free(file->file_dir); /* Release the file info */ - file_ptr = H5FL_FREE(H5FD_ioc_t, file_ptr); + H5FL_FREE(H5FD_ioc_t, file); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -976,13 +890,13 @@ H5FD__ioc_close(H5FD_t *_file) H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE if (H5FD__ioc_close_int(file) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close IOC file"); + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close IOC file"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_close() */ /*------------------------------------------------------------------------- @@ -1001,14 +915,14 @@ H5FD__ioc_cmp(const H5FD_t *_f1, const H5FD_t *_f2) const H5FD_ioc_t *f2 = (const H5FD_ioc_t *)_f2; herr_t ret_value = 0; /* Return value */ - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR assert(f1); assert(f2); ret_value = (f1->file_id > f2->file_id) - (f1->file_id < f2->file_id); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_cmp */ /*------------------------------------------------------------------------- @@ -1025,7 +939,7 @@ H5FD__ioc_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* out { herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Set the VFL feature flags that this driver supports */ if (flags) { @@ -1035,71 +949,9 @@ H5FD__ioc_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* out *flags |= H5FD_FEAT_HAS_MPI; /* This driver uses MPI */ } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_query() */ -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_get_type_map - * - * Purpose: Retrieve the memory type mapping for this file - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_get_type_map(const H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED *type_map) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_get_type_map() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_alloc - * - * Purpose: Allocate file memory. - * - * Return: Address of allocated space (HADDR_UNDEF if error). - *------------------------------------------------------------------------- - */ -static haddr_t -H5FD__ioc_alloc(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED dxpl_id, - hsize_t H5_ATTR_UNUSED size) -{ - haddr_t ret_value = HADDR_UNDEF; /* Return value */ - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_alloc() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_free - * - * Purpose: Free the resources for the ioc VFD. - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_free(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, hsize_t H5_ATTR_UNUSED size) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_free() */ - /*------------------------------------------------------------------------- * Function: H5FD__ioc_get_eoa * @@ -1115,17 +967,14 @@ H5FD__ioc_free(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid static haddr_t H5FD__ioc_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) { - const H5FD_ioc_t *file = (const H5FD_ioc_t *)_file; - haddr_t ret_value = HADDR_UNDEF; + const H5FD_ioc_t *file = (const H5FD_ioc_t *)_file; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Sanity check */ assert(file); - ret_value = file->eoa; - - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(file->eoa) } /* end H5FD__ioc_get_eoa */ /*------------------------------------------------------------------------- @@ -1144,14 +993,14 @@ H5FD__ioc_set_eoa(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr) H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Sanity check */ assert(file); file->eoa = addr; - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_set_eoa() */ /*------------------------------------------------------------------------- @@ -1170,48 +1019,23 @@ static haddr_t H5FD__ioc_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) { const H5FD_ioc_t *file = (const H5FD_ioc_t *)_file; - haddr_t ret_value = HADDR_UNDEF; /* Return value */ subfiling_context_t *sf_context = NULL; + haddr_t ret_value = HADDR_UNDEF; /* Return value */ - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR /* Sanity check */ assert(file); - sf_context = H5_get_subfiling_object(file->context_id); - if (sf_context) { + sf_context = H5FD__subfiling_get_object(file->context_id); + if (sf_context) ret_value = sf_context->sf_eof; - goto done; - } else ret_value = file->eof; -done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_get_eof */ -/*-------------------------------------------------------------------------- - * Function: H5FD__ioc_get_handle - * - * Purpose: Returns a pointer to the file handle of low-level virtual - * file driver. - * - * Return: SUCCEED/FAIL - *-------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_get_handle(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED fapl, - void H5_ATTR_UNUSED **file_handle) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_get_handle */ - /*------------------------------------------------------------------------- * Function: H5FD__ioc_read * @@ -1220,36 +1044,32 @@ H5FD__ioc_get_handle(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED fapl, * properties in DXPL_ID. * * Return: Success: SUCCEED - * The read result is written into the BUF buffer - * which should be allocated by the caller. * Failure: FAIL - * The contents of BUF are undefined. *------------------------------------------------------------------------- */ static herr_t H5FD__ioc_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, void *buf) { -#ifndef NDEBUG - H5FD_ioc_t *file = (H5FD_ioc_t *)_file; -#endif - herr_t ret_value = SUCCEED; + H5FD_ioc_t *file = (H5FD_ioc_t *)_file; + herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE assert(file && file->pub.cls); assert(buf); /* Check for overflow conditions */ if (!H5_addr_defined(addr)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %" PRIuHADDR, addr); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %" PRIuHADDR, addr); if (REGION_OVERFLOW(addr, size)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %" PRIuHADDR, addr); + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %" PRIuHADDR, addr); - ret_value = H5FD__ioc_read_vector_internal(_file, 1, &addr, &size, &buf); + if (H5FD__ioc_read_vector_internal(file, 1, &addr, &size, &buf) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't read data"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_read() */ /*------------------------------------------------------------------------- @@ -1266,56 +1086,51 @@ static herr_t H5FD__ioc_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf) { - herr_t ret_value = SUCCEED; + H5FD_ioc_t *file = (H5FD_ioc_t *)_file; + herr_t ret_value = SUCCEED; - addr += _file->base_addr; + FUNC_ENTER_PACKAGE - ret_value = H5FD__ioc_write_vector_internal(_file, 1, &type, &addr, &size, &buf); + addr += file->pub.base_addr; + if (H5FD__ioc_write_vector_internal(file, 1, &type, &addr, &size, &buf) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "can't write data"); - H5_SUBFILING_FUNC_LEAVE; +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_write() */ static herr_t H5FD__ioc_read_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], void *bufs[] /* out */) { - H5FD_ioc_t *file_ptr = (H5FD_ioc_t *)_file; + H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ - /* Check arguments */ - if (!file_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL"); - - if ((!types) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "types parameter can't be NULL if count is positive"); + FUNC_ENTER_PACKAGE - if ((!addrs) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "addrs parameter can't be NULL if count is positive"); - - if ((!sizes) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "sizes parameter can't be NULL if count is positive"); - - if ((!bufs) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "bufs parameter can't be NULL if count is positive"); - - /* Get the default dataset transfer property list if the user didn't provide - * one */ - if (H5P_DEFAULT == dxpl_id) { + /* Check arguments */ + if (!file) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file 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"); + + /* 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)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - } + else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - ret_value = H5FD__ioc_read_vector_internal(_file, count, addrs, sizes, bufs); + if (H5FD__ioc_read_vector_internal(file, count, addrs, sizes, bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't read vector of data"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } static herr_t @@ -1325,61 +1140,32 @@ H5FD__ioc_write_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_mem_t H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + /* Check arguments */ if (!file) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file pointer cannot be NULL"); - - if ((!types) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "types parameter can't be NULL if count is positive"); - - if ((!addrs) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "addrs parameter can't be NULL if count is positive"); - - if ((!sizes) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "sizes parameter can't be NULL if count is positive"); - - if ((!bufs) && (count > 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "bufs parameter can't be NULL if count is positive"); - - /* Get the default dataset transfer property list if the user didn't provide - * one */ - if (H5P_DEFAULT == dxpl_id) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file 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"); + + /* 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)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - } + else if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - ret_value = H5FD__ioc_write_vector_internal(_file, count, types, addrs, sizes, bufs); + if (H5FD__ioc_write_vector_internal(file, count, types, addrs, sizes, bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "can't write vector of data"); done: - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FDioc__write_vector() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__ioc_flush - * - * Purpose: Flushes all data to disk for underlying VFD. - * - * Return: SUCCEED/FAIL - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_flush(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_ATTR_UNUSED closing) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_flush() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ioc__write_vector() */ /*------------------------------------------------------------------------- * Function: H5FD__ioc_truncate @@ -1395,63 +1181,21 @@ H5FD__ioc_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_ATTR_UNU H5FD_ioc_t *file = (H5FD_ioc_t *)_file; herr_t ret_value = SUCCEED; - H5FD_IOC_LOG_CALL(__func__); + FUNC_ENTER_PACKAGE_NOERR assert(file); - /* TODO: placeholder for now since Subfiling does the truncation */ - if (!H5_addr_eq(file->eoa, file->last_eoa)) { + /* TODO: placeholder for now since subfiling does the truncation */ + if (!H5_addr_eq(file->eoa, file->last_eoa)) file->last_eoa = file->eoa; - } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__ioc_truncate */ -/*-------------------------------------------------------------------------- - * Function: H5FD__ioc_lock - * - * Purpose: Sets a file lock. - * - * Return: SUCCEED/FAIL - *-------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_lock(H5FD_t H5_ATTR_UNUSED *_file, bool H5_ATTR_UNUSED rw) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_lock */ - -/*-------------------------------------------------------------------------- - * Function: H5FD__ioc_unlock - * - * Purpose: Removes a file lock. - * - * Return: SUCCEED/FAIL - *-------------------------------------------------------------------------- - */ -static herr_t -H5FD__ioc_unlock(H5FD_t H5_ATTR_UNUSED *_file) -{ - herr_t ret_value = SUCCEED; - - H5FD_IOC_LOG_CALL(__func__); - - /* TODO: placeholder for now */ - - H5_SUBFILING_FUNC_LEAVE; -} /* end H5FD__ioc_unlock */ - static herr_t H5FD__ioc_del(const char *name, hid_t fapl) { H5P_genplist_t *plist; - h5_stat_t st; MPI_Comm comm = MPI_COMM_NULL; MPI_Info info = MPI_INFO_NULL; FILE *config_file = NULL; @@ -1462,49 +1206,45 @@ H5FD__ioc_del(const char *name, hid_t fapl) int mpi_code; herr_t ret_value = SUCCEED; - /* TODO: Eventually this routine should share common code - * with H5_subfiling_common's routines so it doesn't get - * out of sync - */ + FUNC_ENTER_PACKAGE if (NULL == (plist = H5P_object_verify(fapl, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); assert(H5FD_IOC == H5P_peek_driver(plist)); - if (H5FD_mpi_self_initialized) { + if (H5FD_mpi_self_initialized) comm = MPI_COMM_WORLD; - } else { /* Get the MPI communicator and info from the fapl */ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI info object"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI info object"); if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI communicator"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator"); } /* Get the MPI rank of this process */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (mpi_rank == 0) { - int64_t read_n_subfiles = 0; - int32_t n_subfiles = 0; - char *prefix_env = NULL; - int num_digits = 0; + int64_t read_n_subfiles = 0; + int32_t n_subfiles = 0; + char *prefix_env = NULL; + int num_digits = 0; + h5_stat_t st; memset(&st, 0, sizeof(h5_stat_t)); if (HDstat(name, &st) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SYSERRSTR, FAIL, "HDstat failed"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_SYSERRSTR, FAIL, "HDstat failed"); if (H5_basename(name, &base_filename) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file basename"); + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file basename"); if (H5_dirname(name, &file_dirname) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file dirname"); + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file dirname"); /* Try to open the subfiling configuration file and get the number of IOCs */ - if (NULL == (tmp_filename = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate config file name buffer"); + if (NULL == (tmp_filename = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate config file name buffer"); /* Check if a prefix has been set for the configuration file name */ prefix_env = getenv(H5FD_SUBFILING_CONFIG_FILE_PREFIX); @@ -1516,20 +1256,14 @@ H5FD__ioc_del(const char *name, hid_t fapl) (uint64_t)st.st_ino); if (NULL == (config_file = fopen(tmp_filename, "r"))) { - if (ENOENT == errno) { -#ifdef H5FD_IOC_DEBUG - printf("** WARNING: couldn't delete Subfiling configuration file '%s'\n", tmp_filename); -#endif - - H5_SUBFILING_GOTO_DONE(SUCCEED); - } + if (ENOENT == errno) + HGOTO_DONE(SUCCEED); else - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "can't open subfiling config file"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "can't open subfiling config file"); } - if (H5_get_subfiling_config_from_file(config_file, NULL, &read_n_subfiles) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "can't read subfiling config file"); + if (H5FD__subfiling_get_config_from_file(config_file, NULL, &read_n_subfiles) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "can't read subfiling config file"); H5_CHECK_OVERFLOW(read_n_subfiles, int64_t, int32_t); n_subfiles = (int32_t)read_n_subfiles; @@ -1537,15 +1271,13 @@ H5FD__ioc_del(const char *name, hid_t fapl) /* Delete the Subfiling configuration file */ if (EOF == fclose(config_file)) { config_file = NULL; - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "can't close subfiling config file"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close subfiling config file"); } config_file = NULL; if (HDremove(tmp_filename) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "can't delete subfiling config file"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't delete subfiling config file"); /* Try to delete each of the subfiles */ num_digits = (int)(log10(n_subfiles) + 1); @@ -1555,49 +1287,46 @@ H5FD__ioc_del(const char *name, hid_t fapl) snprintf(tmp_filename, PATH_MAX, "%s/" H5FD_SUBFILING_FILENAME_TEMPLATE, file_dirname, base_filename, (uint64_t)st.st_ino, num_digits, i + 1, n_subfiles); - if (HDremove(tmp_filename) < 0) { -#ifdef H5FD_IOC_DEBUG - printf("** WARNING: couldn't delete subfile '%s'\n", tmp_filename); -#endif - + if (HDremove(tmp_filename) < 0) if (ENOENT != errno) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "can't delete subfile"); - } + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "can't delete subfile"); } /* Delete the HDF5 stub file */ if (HDremove(name) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "can't delete HDF5 file"); + HSYS_GOTO_ERROR(H5E_FILE, H5E_CANTDELETEFILE, FAIL, "can't delete HDF5 file"); } done: if (config_file) if (EOF == fclose(config_file)) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close subfiling config file"); + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close subfiling config file"); /* Set up a barrier (don't want processes to run ahead of the delete) */ if (comm != MPI_COMM_NULL) { int comm_size = -1; if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &comm_size))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); if (comm_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Barrier failed", mpi_code); } - /* Free duplicated MPI Communicator and Info objects */ - if (H5_mpi_comm_free(&comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI communicator"); - if (H5_mpi_info_free(&info) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI info object"); + if (!H5FD_mpi_self_initialized) { + /* Free duplicated MPI Communicator and Info objects */ + if (H5_mpi_comm_free(&comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI communicator"); + if (H5_mpi_info_free(&info) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI info object"); + } - free(tmp_filename); + H5MM_free(tmp_filename); H5MM_free(file_dirname); H5MM_free(base_filename); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*-------------------------------------------------------------------------- @@ -1617,30 +1346,31 @@ H5FD__ioc_del(const char *name, hid_t fapl) *-------------------------------------------------------------------------- */ static herr_t -H5FD__ioc_write_vector_internal(H5FD_t *_file, uint32_t count, H5FD_mem_t H5_ATTR_UNUSED types[], +H5FD__ioc_write_vector_internal(H5FD_ioc_t *file, uint32_t count, H5FD_mem_t H5_ATTR_UNUSED types[], haddr_t addrs[], size_t sizes[], const void *bufs[] /* in */) { subfiling_context_t *sf_context = NULL; MPI_Request *mpi_reqs = NULL; - H5FD_ioc_t *file_ptr = (H5FD_ioc_t *)_file; io_req_t **sf_io_reqs = NULL; int64_t sf_context_id = -1; size_t io_size = 0; bool extend_sizes = false; herr_t ret_value = SUCCEED; - assert(_file); - assert((addrs) || (count == 0)); - assert((sizes) || (count == 0)); - assert((bufs) || (count == 0)); + FUNC_ENTER_PACKAGE if (count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); - sf_context_id = file_ptr->context_id; + assert(file); + assert(addrs); + assert(sizes); + assert(bufs); + + sf_context_id = file->context_id; - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get subfiling context from ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) + HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get subfiling context from ID"); assert(sf_context->topology); /* @@ -1652,88 +1382,81 @@ H5FD__ioc_write_vector_internal(H5FD_t *_file, uint32_t count, H5FD_mem_t H5_ATT * that blocking write calls do not return early before the data is * actually written. */ - if (NULL == (sf_io_reqs = calloc((size_t)count, sizeof(*sf_io_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate I/O request array"); - if (NULL == (mpi_reqs = malloc(2 * (size_t)count * sizeof(*mpi_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate MPI request array"); - - /* Each pass thru the following should queue an MPI write - * to a new IOC. Both the IOC selection and offset within the - * particular subfile are based on the combination of striping - * factors and the virtual file offset (addrs[i]). + if (NULL == (sf_io_reqs = H5MM_calloc((size_t)count * sizeof(*sf_io_reqs)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate I/O request array"); + if (NULL == (mpi_reqs = H5MM_malloc(2 * (size_t)count * sizeof(*mpi_reqs)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate MPI request array"); + + /* Each pass thru the following should queue an MPI write to a new IOC. Both + * the IOC selection and offset within the particular subfile are based on + * the combination of striping factors and the virtual file offset (addrs[i]). */ for (size_t i = 0; i < (size_t)count; i++) { - herr_t write_status; - if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - io_size = sizes[i - 1]; - } - else { + else io_size = sizes[i]; - } } if (io_size == 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "invalid size argument of 0"); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "invalid size argument of 0"); H5_CHECK_OVERFLOW(addrs[i], haddr_t, int64_t); H5_CHECK_OVERFLOW(io_size, size_t, int64_t); - write_status = ioc__write_independent_async(sf_context_id, (int64_t)addrs[i], (int64_t)io_size, - bufs[i], &sf_io_reqs[i]); - - if (write_status < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't queue write operation"); + if (H5FD__ioc_write_independent_async(sf_context_id, (int64_t)addrs[i], (int64_t)io_size, bufs[i], + &sf_io_reqs[i]) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't queue write operation"); mpi_reqs[(2 * i)] = sf_io_reqs[i]->io_transfer_req; mpi_reqs[(2 * i) + 1] = sf_io_reqs[i]->io_comp_req; } - /* Here, we should have queued 'count' async requests. - * We can can now try to complete those before returning - * to the caller for the next set of IO operations. + /* Here, we should have queued 'count' async requests. We can can now try to + * complete those before returning to the caller for the next set of IO + * operations. */ - if (ioc__async_completion(mpi_reqs, 2 * (size_t)count) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't complete I/O requests"); + if (H5FD__ioc_async_completion(mpi_reqs, 2 * (size_t)count) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't complete I/O requests"); done: - free(mpi_reqs); + H5MM_free(mpi_reqs); if (sf_io_reqs) { for (size_t i = 0; i < count; i++) - free(sf_io_reqs[i]); - free(sf_io_reqs); + H5MM_free(sf_io_reqs[i]); + H5MM_free(sf_io_reqs); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } static herr_t -H5FD__ioc_read_vector_internal(H5FD_t *_file, uint32_t count, haddr_t addrs[], size_t sizes[], +H5FD__ioc_read_vector_internal(H5FD_ioc_t *file, uint32_t count, haddr_t addrs[], size_t sizes[], void *bufs[] /* out */) { subfiling_context_t *sf_context = NULL; MPI_Request *mpi_reqs = NULL; - H5FD_ioc_t *file_ptr = (H5FD_ioc_t *)_file; io_req_t **sf_io_reqs = NULL; int64_t sf_context_id = -1; size_t io_size = 0; bool extend_sizes = false; herr_t ret_value = SUCCEED; - assert(_file); - assert((addrs) || (count == 0)); - assert((sizes) || (count == 0)); - assert((bufs) || (count == 0)); + FUNC_ENTER_PACKAGE if (count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); + + assert(file); + assert(addrs); + assert(sizes); + assert(bufs); - sf_context_id = file_ptr->context_id; + sf_context_id = file->context_id; - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get subfiling context from ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) + HGOTO_ERROR(H5E_IO, H5E_CANTGET, FAIL, "can't get subfiling context from ID"); assert(sf_context->topology); /* @@ -1743,52 +1466,43 @@ H5FD__ioc_read_vector_internal(H5FD_t *_file, uint32_t count, haddr_t addrs[], s * that the actual I/O call (currently, HDpread) has completed and * the data read from the file has been transferred to the caller. */ - if (NULL == (sf_io_reqs = calloc((size_t)count, sizeof(*sf_io_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate I/O request array"); - if (NULL == (mpi_reqs = malloc((size_t)count * sizeof(*mpi_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate MPI request array"); + if (NULL == (sf_io_reqs = H5MM_calloc((size_t)count * sizeof(*sf_io_reqs)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate I/O request array"); + if (NULL == (mpi_reqs = H5MM_malloc((size_t)count * sizeof(*mpi_reqs)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate MPI request array"); for (size_t i = 0; i < (size_t)count; i++) { - herr_t read_status; - if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - io_size = sizes[i - 1]; - } - else { + else io_size = sizes[i]; - } } H5_CHECK_OVERFLOW(addrs[i], haddr_t, int64_t); H5_CHECK_OVERFLOW(io_size, size_t, int64_t); - read_status = ioc__read_independent_async(sf_context_id, (int64_t)addrs[i], (int64_t)io_size, bufs[i], - &sf_io_reqs[i]); - - if (read_status < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't queue read operation"); + if (H5FD__ioc_read_independent_async(sf_context_id, (int64_t)addrs[i], (int64_t)io_size, bufs[i], + &sf_io_reqs[i]) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't queue read operation"); mpi_reqs[i] = sf_io_reqs[i]->io_transfer_req; } - /* Here, we should have queued 'count' async requests - * (one to each required IOC). - * - * We can can now try to complete those before returning - * to the caller for the next set of IO operations. + /* Here, we should have queued 'count' async requests, one to each required + * IOC. We can can now try to complete those before returning to the caller + * for the next set of IO operations. */ - if (ioc__async_completion(mpi_reqs, (size_t)count) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't complete I/O requests"); + if (H5FD__ioc_async_completion(mpi_reqs, (size_t)count) < 0) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't complete I/O requests"); done: - free(mpi_reqs); + H5MM_free(mpi_reqs); if (sf_io_reqs) { for (size_t i = 0; i < count; i++) - free(sf_io_reqs[i]); - free(sf_io_reqs); + H5MM_free(sf_io_reqs[i]); + H5MM_free(sf_io_reqs); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } diff --git a/src/H5FDsubfiling/H5FDioc_int.c b/src/H5FDsubfiling/H5FDioc_int.c index 75a36d0cb04..e528a362f80 100644 --- a/src/H5FDsubfiling/H5FDioc_int.c +++ b/src/H5FDsubfiling/H5FDioc_int.c @@ -17,21 +17,21 @@ #include "H5FDioc_priv.h" /* - * Given a file offset, the stripe size, the - * number of IOCs and the number of subfiles, - * calculate the target IOC for I/O, the index - * of the target subfile out of the subfiles - * that the IOC controls and the file offset - * into that subfile + * Given a file offset, the stripe size, the number of IOCs and the number of + * subfiles, calculate the target IOC for I/O, the index of the target subfile + * out of the subfiles that the IOC controls and the file offset into that subfile */ static inline void -calculate_target_ioc(int64_t file_offset, int64_t stripe_size, int num_io_concentrators, int num_subfiles, - int64_t *target_ioc, int64_t *ioc_file_offset, int64_t *ioc_subfile_idx) +H5FD__ioc_calculate_target_ioc(int64_t file_offset, int64_t stripe_size, int num_io_concentrators, + int num_subfiles, int64_t *target_ioc, int64_t *ioc_file_offset, + int64_t *ioc_subfile_idx) { int64_t stripe_idx; int64_t subfile_row; int64_t subfile_idx; + FUNC_ENTER_PACKAGE_NOERR + assert(stripe_size > 0); assert(num_io_concentrators > 0); assert(num_subfiles > 0); @@ -46,24 +46,12 @@ calculate_target_ioc(int64_t file_offset, int64_t stripe_size, int num_io_concen *target_ioc = (stripe_idx % num_subfiles) % num_io_concentrators; *ioc_file_offset = (subfile_row * stripe_size) + (file_offset % stripe_size); *ioc_subfile_idx = subfile_idx; -} -/* - * Utility routine to hack around casting away const - */ -static inline void * -cast_to_void(const void *data) -{ - union { - const void *const_ptr_to_data; - void *ptr_to_data; - } eliminate_const_warning; - eliminate_const_warning.const_ptr_to_data = data; - return eliminate_const_warning.ptr_to_data; + FUNC_LEAVE_NOAPI_VOID } /*------------------------------------------------------------------------- - * Function: ioc__write_independent_async + * Function: H5FD__ioc_write_independent_async * * Purpose: The IO operations can be striped across a selection of * IO concentrators. The read and write independent calls @@ -75,24 +63,22 @@ cast_to_void(const void *data) * zero and all offsets that reside within modulo range of * the subfiling stripe_size. * - * We cycle through all 'n_io_conentrators' and send a - * descriptor to each IOC that has a non-zero sized IO - * request to fulfill. + * We cycle through all 'n_io_conentrators' and send a descriptor + * to each IOC that has a non-zero sized IO request to fulfill. * - * Sending descriptors to an IOC usually gets an ACK or - * NACK in response. For the write operations, we post - * asynch READs to receive ACKs from IOC ranks that have - * allocated memory receive the data to write to the - * subfile. Upon receiving an ACK, we send the actual - * user data to the IOC. + * Sending descriptors to an IOC usually gets an ACK or NACK in + * response. For the write operations, we post asynch READs to + * receive ACKs from IOC ranks that have allocated memory receive + * the data to write to the subfile. Upon receiving an ACK, we + * send the actual user data to the IOC. * * Return: Non-negative on success/Negative on failure * *------------------------------------------------------------------------- */ herr_t -ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t elements, const void *data, - io_req_t **io_req) +H5FD__ioc_write_independent_async(int64_t context_id, int64_t offset, int64_t elements, const void *data, + io_req_t **io_req) { subfiling_context_t *sf_context = NULL; MPI_Request ack_request = MPI_REQUEST_NULL; @@ -108,10 +94,12 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(io_req); - if (NULL == (sf_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't get subfiling context from ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "can't get subfiling context from ID"); assert(sf_context->topology); assert(sf_context->topology->io_concentrators); @@ -120,59 +108,51 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element num_subfiles = sf_context->sf_num_subfiles; /* - * Calculate the IOC that we'll send the I/O request to - * and the offset within that IOC's subfile + * Calculate the IOC that we'll send the I/O request to and the offset within + * that IOC's subfile */ - calculate_target_ioc(offset, sf_context->sf_stripe_size, num_io_concentrators, num_subfiles, &ioc_start, - &ioc_offset, &ioc_subfile_idx); + H5FD__ioc_calculate_target_ioc(offset, sf_context->sf_stripe_size, num_io_concentrators, num_subfiles, + &ioc_start, &ioc_offset, &ioc_subfile_idx); /* - * Wait for memory to be allocated on the target IOC before - * beginning send of user data. Once that memory has been - * allocated, we will receive an ACK (or NACK) message from - * the IOC to allow us to proceed. + * Wait for memory to be allocated on the target IOC before beginning send of + * user data. Once that memory has been allocated, we will receive an ACK (or + * NACK) message from the IOC to allow us to proceed. * - * On ACK, the IOC will send the tag to be used for sending - * data. This allows us to distinguish between multiple - * concurrent writes from a single rank. + * On ACK, the IOC will send the tag to be used for sending data. This allows + * us to distinguish between multiple concurrent writes from a single rank. * * Post an early non-blocking receive for the MPI tag here. */ if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&data_tag, 1, MPI_INT, io_concentrators[ioc_start], WRITE_INDEP_ACK, sf_context->sf_data_comm, &ack_request))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); - /* - * Prepare and send an I/O request to the IOC identified - * by the file offset - */ + /* Prepare and send an I/O request to the IOC identified by the file offset */ msg[0] = elements; msg[1] = ioc_offset; msg[2] = ioc_subfile_idx; if (MPI_SUCCESS != (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, io_concentrators[ioc_start], WRITE_INDEP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); /* Wait to receive the data tag from the IOC */ if (MPI_SUCCESS != (mpi_code = MPI_Wait(&ack_request, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Wait failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Wait failed", mpi_code); if (data_tag == 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "received NACK from IOC"); + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "received NACK from IOC"); - /* - * Allocate the I/O request object that will - * be returned to the caller - */ - if (NULL == (sf_io_request = malloc(sizeof(io_req_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "couldn't allocate I/O request"); + /* Allocate the I/O request object that will be returned to the caller */ + if (NULL == (sf_io_request = H5MM_malloc(sizeof(io_req_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_WRITEERROR, FAIL, "couldn't allocate I/O request"); H5_CHECK_OVERFLOW(ioc_start, int64_t, int); sf_io_request->ioc = (int)ioc_start; sf_io_request->context_id = context_id; sf_io_request->offset = offset; sf_io_request->elements = elements; - sf_io_request->data = cast_to_void(data); + sf_io_request->data = H5FD__subfiling_cast_to_void(data); sf_io_request->io_transfer_req = MPI_REQUEST_NULL; sf_io_request->io_comp_req = MPI_REQUEST_NULL; sf_io_request->io_comp_tag = -1; @@ -184,7 +164,7 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&sf_io_request->io_comp_tag, 1, MPI_INT, io_concentrators[ioc_start], WRITE_DATA_DONE, sf_context->sf_data_comm, &sf_io_request->io_comp_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); /* * Start the actual data transfer using the ack received @@ -194,46 +174,40 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element if (MPI_SUCCESS != (mpi_code = MPI_Isend(data, (int)elements, MPI_BYTE, io_concentrators[ioc_start], data_tag, sf_context->sf_data_comm, &sf_io_request->io_transfer_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Isend failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Isend failed", mpi_code); /* - * NOTE: When we actually have the async I/O support, - * the request should be queued before we return to - * the caller. Having queued the I/O operation, we - * might want to get additional work started before - * allowing the queued I/O requests to make further - * progress and/or to complete, so we just return + * NOTE: When we actually have the async I/O support, the request should be + * queued before we return to the caller. Having queued the I/O operation, we + * might want to get additional work started before allowing the queued I/O + * requests to make further progress and/or to complete, so we just return * to the caller. */ - *io_req = sf_io_request; done: if (ret_value < 0) { - if (ack_request != MPI_REQUEST_NULL) { + if (ack_request != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&ack_request, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); if (sf_io_request) { - if (sf_io_request->io_transfer_req != MPI_REQUEST_NULL) { + if (sf_io_request->io_transfer_req != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&sf_io_request->io_transfer_req, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } - if (sf_io_request->io_comp_req != MPI_REQUEST_NULL) { + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); + if (sf_io_request->io_comp_req != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&sf_io_request->io_comp_req, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); } - free(sf_io_request); + H5MM_free(sf_io_request); *io_req = NULL; } - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc__write_independent_async() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ioc_write_independent_async() */ /*------------------------------------------------------------------------- - * Function: Internal ioc__read_independent_async + * Function: Internal H5FD__ioc_read_independent_async * * Purpose: The IO operations can be striped across a selection of * IO concentrators. The read and write independent calls @@ -259,8 +233,8 @@ ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t element *------------------------------------------------------------------------- */ herr_t -ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements, void *data, - io_req_t **io_req) +H5FD__ioc_read_independent_async(int64_t context_id, int64_t offset, int64_t elements, void *data, + io_req_t **io_req) { subfiling_context_t *sf_context = NULL; MPI_Request ack_request = MPI_REQUEST_NULL; @@ -277,12 +251,14 @@ ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(io_req); H5_CHECK_OVERFLOW(elements, int64_t, int); - if (NULL == (sf_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't get subfiling context from ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "can't get subfiling context from ID"); assert(sf_context->topology); assert(sf_context->topology->io_concentrators); @@ -291,35 +267,30 @@ ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements num_subfiles = sf_context->sf_num_subfiles; /* - * If we are using 1 subfile per IOC, we can optimize reads - * a little since each read will go to a separate IOC and we - * won't be in danger of data being received in an - * unpredictable order. However, if some IOCs own more than - * 1 subfile, we need to associate each read with a unique - * message tag to make sure the data is received in the - * correct order. We also need a unique message tag in the - * case where only 1 subfile is used in total. In this case, - * vector I/O calls are passed directly down to this VFD without - * being split up into multiple I/O requests, so we need the - * tag to distinguish each I/O request. + * If we are using 1 subfile per IOC, we can optimize reads a little since + * each read will go to a separate IOC and we won't be in danger of data + * being received in an unpredictable order. However, if some IOCs own more + * than 1 subfile, we need to associate each read with a unique message tag + * to make sure the data is received in the correct order. We also need a + * unique message tag in the case where only 1 subfile is used in total. In + * this case, vector I/O calls are passed directly down to this VFD without + * being split up into multiple I/O requests, so we need the tag to + * distinguish each I/O request. */ need_data_tag = (num_subfiles == 1) || (num_subfiles != num_io_concentrators); if (!need_data_tag) data_tag = READ_INDEP_DATA; /* - * Calculate the IOC that we'll send the I/O request to - * and the offset within that IOC's subfile + * Calculate the IOC that we'll send the I/O request to and the offset within + * that IOC's subfile */ - calculate_target_ioc(offset, sf_context->sf_stripe_size, num_io_concentrators, num_subfiles, &ioc_start, - &ioc_offset, &ioc_subfile_idx); + H5FD__ioc_calculate_target_ioc(offset, sf_context->sf_stripe_size, num_io_concentrators, num_subfiles, + &ioc_start, &ioc_offset, &ioc_subfile_idx); - /* - * Allocate the I/O request object that will - * be returned to the caller - */ - if (NULL == (sf_io_request = malloc(sizeof(io_req_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_READERROR, FAIL, "couldn't allocate I/O request"); + /* Allocate the I/O request object that will be returned to the caller */ + if (NULL == (sf_io_request = H5MM_malloc(sizeof(io_req_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_READERROR, FAIL, "couldn't allocate I/O request"); H5_CHECK_OVERFLOW(ioc_start, int64_t, int); sf_io_request->ioc = (int)ioc_start; @@ -333,82 +304,72 @@ ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements if (need_data_tag) { /* - * Post an early non-blocking receive for IOC to send an ACK - * (or NACK) message with a data tag that we will use for - * receiving data + * Post an early non-blocking receive for IOC to send an ACK (or NACK) + * message with a data tag that we will use for receiving data */ if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&data_tag, 1, MPI_INT, io_concentrators[ioc_start], READ_INDEP_ACK, sf_context->sf_data_comm, &ack_request))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); - /* - * Prepare and send an I/O request to the IOC identified - * by the file offset - */ + /* Prepare and send an I/O request to the IOC identified by the file offset */ msg[0] = elements; msg[1] = ioc_offset; msg[2] = ioc_subfile_idx; if (MPI_SUCCESS != (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, io_concentrators[ioc_start], READ_INDEP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); /* Wait to receive the data tag from the IOC */ if (MPI_SUCCESS != (mpi_code = MPI_Wait(&ack_request, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Wait failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Wait failed", mpi_code); if (data_tag == 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "received NACK from IOC"); + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "received NACK from IOC"); } /* - * Post a non-blocking receive for the data from the IOC - * using the selected data tag (either the one received - * from the IOC or the static READ_INDEP_DATA tag) + * Post a non-blocking receive for the data from the IOC using the selected + * data tag (either the one received from the IOC or the static + * READ_INDEP_DATA tag) */ if (MPI_SUCCESS != (mpi_code = MPI_Irecv(data, (int)elements, MPI_BYTE, io_concentrators[ioc_start], data_tag, sf_context->sf_data_comm, &sf_io_request->io_transfer_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); if (!need_data_tag) { - /* - * Prepare and send an I/O request to the IOC identified - * by the file offset - */ + /* Prepare and send an I/O request to the IOC identified by the file offset */ msg[0] = elements; msg[1] = ioc_offset; msg[2] = ioc_subfile_idx; if (MPI_SUCCESS != (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, io_concentrators[ioc_start], READ_INDEP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); } *io_req = sf_io_request; done: if (ret_value < 0) { - if (ack_request != MPI_REQUEST_NULL) { + if (ack_request != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&ack_request, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } - if (sf_io_request) { - if (sf_io_request->io_transfer_req != MPI_REQUEST_NULL) { + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); + if (sf_io_request) + if (sf_io_request->io_transfer_req != MPI_REQUEST_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Wait(&sf_io_request->io_transfer_req, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - } - } + HMPI_DONE_ERROR(FAIL, "MPI_Wait failed", mpi_code); - free(sf_io_request); + H5MM_free(sf_io_request); *io_req = NULL; } - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc__read_independent_async() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__ioc_read_independent_async() */ /*------------------------------------------------------------------------- - * Function: ioc__async_completion + * Function: H5FD__ioc_async_completion * * Purpose: IOC function to complete outstanding I/O requests. * Currently just a wrapper around MPI_Waitall on the given @@ -419,11 +380,13 @@ ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements *------------------------------------------------------------------------- */ herr_t -ioc__async_completion(MPI_Request *mpi_reqs, size_t num_reqs) +H5FD__ioc_async_completion(MPI_Request *mpi_reqs, size_t num_reqs) { herr_t ret_value = SUCCEED; int mpi_code; + FUNC_ENTER_PACKAGE + assert(mpi_reqs); H5_CHECK_OVERFLOW(num_reqs, size_t, int); @@ -433,9 +396,9 @@ ioc__async_completion(MPI_Request *mpi_reqs, size_t num_reqs) */ H5_GCC_DIAG_OFF("stringop-overflow") if (MPI_SUCCESS != (mpi_code = MPI_Waitall((int)num_reqs, mpi_reqs, MPI_STATUSES_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Waitall failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Waitall failed", mpi_code); H5_GCC_DIAG_ON("stringop-overflow") done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } diff --git a/src/H5FDsubfiling/H5FDioc_priv.h b/src/H5FDsubfiling/H5FDioc_priv.h index b7e0c7350cb..eeaeb6a955e 100644 --- a/src/H5FDsubfiling/H5FDioc_priv.h +++ b/src/H5FDsubfiling/H5FDioc_priv.h @@ -37,7 +37,6 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5subfiling_common.h" -#include "H5subfiling_err.h" #include "mercury_thread.h" #include "mercury_thread_mutex.h" @@ -411,17 +410,13 @@ extern int *H5FD_IOC_tag_ub_val_ptr; extern "C" { #endif -H5_DLL int initialize_ioc_threads(void *_sf_context); -H5_DLL int finalize_ioc_threads(void *_sf_context); - -H5_DLL herr_t ioc__write_independent_async(int64_t context_id, int64_t offset, int64_t elements, - const void *data, io_req_t **io_req); -H5_DLL herr_t ioc__read_independent_async(int64_t context_id, int64_t offset, int64_t elements, void *data, - io_req_t **io_req); - -H5_DLL herr_t ioc__async_completion(MPI_Request *mpi_reqs, size_t num_reqs); - -H5_DLL int wait_for_thread_main(void); +H5_DLL herr_t H5FD__ioc_init_threads(void *_sf_context); +H5_DLL herr_t H5FD__ioc_finalize_threads(void *_sf_context); +H5_DLL herr_t H5FD__ioc_write_independent_async(int64_t context_id, int64_t offset, int64_t elements, + const void *data, io_req_t **io_req); +H5_DLL herr_t H5FD__ioc_read_independent_async(int64_t context_id, int64_t offset, int64_t elements, + void *data, io_req_t **io_req); +H5_DLL herr_t H5FD__ioc_async_completion(MPI_Request *mpi_reqs, size_t num_reqs); #ifdef __cplusplus } diff --git a/src/H5FDsubfiling/H5FDioc_threads.c b/src/H5FDsubfiling/H5FDioc_threads.c index fea1add0a31..2f6bed7ebc2 100644 --- a/src/H5FDsubfiling/H5FDioc_threads.c +++ b/src/H5FDsubfiling/H5FDioc_threads.c @@ -64,33 +64,31 @@ static int sf_read_ops = 0; static double sf_pwrite_time = 0.0; static double sf_pread_time = 0.0; static double sf_write_wait_time = 0.0; -static double sf_read_wait_time = 0.0; static double sf_queue_delay_time = 0.0; #endif /* Prototypes */ -static HG_THREAD_RETURN_TYPE ioc_thread_main(void *arg); -static int ioc_main(ioc_data_t *ioc_data); - -static int ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, - uint32_t counter); -static int ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, - uint32_t counter); - -static int ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, - int ioc_idx); -static int ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx); -static int ioc_file_truncate(sf_work_request_t *msg); -static int ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm); - -static ioc_io_queue_entry_t *ioc_io_queue_alloc_entry(void); -static void ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_ptr); -static void ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock); -static void ioc_io_queue_free_entry(ioc_io_queue_entry_t *q_entry_ptr); -static void ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr); +static HG_THREAD_RETURN_TYPE H5FD__ioc_thread_main(void *arg); + +static int H5FD__ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, + uint32_t counter); +static int H5FD__ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, + uint32_t counter); + +static int H5FD__ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, + int ioc_idx); +static int H5FD__ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, + int ioc_idx); +static int H5FD__ioc_file_truncate(sf_work_request_t *msg); +static int H5FD__ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm); + +static ioc_io_queue_entry_t *H5FD__ioc_io_queue_alloc_entry(void); +static void H5FD__ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_ptr); +static void H5FD__ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock); +static void H5FD__ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr); /*------------------------------------------------------------------------- - * Function: initialize_ioc_threads + * Function: H5FD__ioc_init_threads * * Purpose: The principal entry point to initialize the execution * context for an I/O Concentrator (IOC). The main thread @@ -104,27 +102,25 @@ static void ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_r * *------------------------------------------------------------------------- */ -int -initialize_ioc_threads(void *_sf_context) +herr_t +H5FD__ioc_init_threads(void *_sf_context) { subfiling_context_t *sf_context = _sf_context; ioc_data_t *ioc_data = NULL; unsigned thread_pool_size = H5FD_IOC_DEFAULT_THREAD_POOL_SIZE; char *env_value; - int ret_value = 0; + herr_t ret_value = SUCCEED; #ifdef H5FD_IOC_COLLECT_STATS double t_start = 0.0, t_end = 0.0; #endif + FUNC_ENTER_PACKAGE + assert(sf_context); - /* - * Allocate and initialize IOC data that will be passed - * to the IOC main thread - */ - if (NULL == (ioc_data = malloc(sizeof(*ioc_data)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, (-1), - "can't allocate IOC data for IOC main thread"); + /* Allocate and initialize IOC data that will be passed to the IOC main thread */ + if (NULL == (ioc_data = H5MM_malloc(sizeof(*ioc_data)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate IOC data for IOC main thread"); ioc_data->sf_context_id = sf_context->sf_context_id; ioc_data->io_thread_pool = NULL; ioc_data->io_queue = (ioc_io_queue_t){/* magic = */ H5FD_IOC__IO_Q_MAGIC, @@ -164,28 +160,26 @@ initialize_ioc_threads(void *_sf_context) #endif if (hg_thread_mutex_init(&ioc_data->io_queue.q_mutex) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, (-1), "can't initialize IOC thread queue mutex"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize IOC thread queue mutex"); /* Allow experimentation with the number of helper threads */ if ((env_value = getenv(H5FD_IOC_THREAD_POOL_SIZE)) != NULL) { int value_check = atoi(env_value); - if (value_check > 0) { + if (value_check > 0) thread_pool_size = (unsigned int)value_check; - } } /* Initialize a thread pool for the I/O concentrator's worker threads */ if (hg_thread_pool_init(thread_pool_size, &ioc_data->io_thread_pool) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, (-1), "can't initialize IOC worker thread pool"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize IOC worker thread pool"); /* Create the main IOC thread that will receive and dispatch I/O requests */ - if (hg_thread_create(&ioc_data->ioc_main_thread, ioc_thread_main, ioc_data) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, (-1), "can't create IOC main thread"); + if (hg_thread_create(&ioc_data->ioc_main_thread, H5FD__ioc_thread_main, ioc_data) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't create IOC main thread"); - /* Wait until ioc_main() reports that it is ready */ - while (atomic_load(&ioc_data->sf_ioc_ready) != 1) { + /* Wait until H5FD__ioc_thread_main() reports that it is ready */ + while (atomic_load(&ioc_data->sf_ioc_ready) != 1) usleep(20); - } #ifdef H5FD_IOC_COLLECT_STATS t_end = MPI_Wtime(); @@ -200,15 +194,17 @@ initialize_ioc_threads(void *_sf_context) #endif done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } -int -finalize_ioc_threads(void *_sf_context) +herr_t +H5FD__ioc_finalize_threads(void *_sf_context) { subfiling_context_t *sf_context = _sf_context; ioc_data_t *ioc_data = NULL; - int ret_value = 0; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE assert(sf_context); assert(sf_context->topology->rank_is_ioc); @@ -220,7 +216,7 @@ finalize_ioc_threads(void *_sf_context) /* Shutdown the main IOC thread */ atomic_store(&ioc_data->sf_shutdown_flag, 1); - /* Allow ioc_main to exit.*/ + /* Allow H5FD__ioc_thread_main to exit.*/ do { usleep(20); } while (0 != atomic_load(&ioc_data->sf_shutdown_flag)); @@ -236,42 +232,17 @@ finalize_ioc_threads(void *_sf_context) } if (ioc_data->io_queue.num_failed > 0) - H5_SUBFILING_DONE_ERROR(H5E_IO, H5E_CLOSEERROR, -1, "%" PRId32 " I/O requests failed", - ioc_data->io_queue.num_failed); + HDONE_ERROR(H5E_VFL, H5E_CLOSEERROR, FAIL, "%" PRId32 " I/O requests failed", + ioc_data->io_queue.num_failed); - free(ioc_data); + H5MM_free(ioc_data); sf_context->ioc_data = NULL; - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: ioc_thread_main - * - * Purpose: An IO Concentrator instance is initialized with the - * specified subfiling context. - * - * Return: The IO concentrator thread executes as long as the HDF5 - * file associated with this context is open. At file close, - * the thread will return from 'ioc_main' and the thread - * exit status will be checked by the main program. - * - *------------------------------------------------------------------------- - */ -static HG_THREAD_RETURN_TYPE -ioc_thread_main(void *arg) -{ - hg_thread_ret_t thread_ret = (hg_thread_ret_t)0; - ioc_data_t *ioc_data = (ioc_data_t *)arg; - - /* Pass along the ioc_data_t */ - ioc_main(ioc_data); - - return thread_ret; -} - -/*------------------------------------------------------------------------- - * Function: ioc_main + * Function: H5FD__ioc_thread_main * * Purpose: This is the principal function run by the I/O Concentrator * main thread. It remains within a loop until allowed to @@ -286,8 +257,8 @@ ioc_thread_main(void *arg) * As each incoming message is received, it gets added to * a queue for processing by a thread_pool thread. The * message handlers are dispatched via the - * "handle_work_request" routine. - + * "H5FD__ioc_handle_work_request" routine. + * * Subfiling is effectively a software RAID-0 implementation * where having multiple I/O Concentrators and independent * subfiles is equated to the multiple disks and a true @@ -328,17 +299,18 @@ ioc_thread_main(void *arg) * *------------------------------------------------------------------------- */ -static int -ioc_main(ioc_data_t *ioc_data) +static HG_THREAD_RETURN_TYPE +H5FD__ioc_thread_main(void *arg) { - subfiling_context_t *context = NULL; + ioc_data_t *ioc_data = (ioc_data_t *)arg; + subfiling_context_t *context = NULL; sf_work_request_t wk_req; int shutdown_requested; - int ret_value = 0; + hg_thread_ret_t ret_value = (hg_thread_ret_t)SUCCEED; assert(ioc_data); - context = H5_get_subfiling_object(ioc_data->sf_context_id); + context = H5FD__subfiling_get_object(ioc_data->sf_context_id); assert(context); /* We can't have opened any files at this point.. @@ -348,7 +320,7 @@ ioc_main(ioc_data_t *ioc_data) * represent an open file). */ - /* tell initialize_ioc_threads() that ioc_main() is ready to enter its main loop */ + /* tell H5FD__ioc_init_threads() that ioc_main() is ready to enter its main loop */ atomic_store(&ioc_data->sf_ioc_ready, 1); shutdown_requested = 0; @@ -362,50 +334,44 @@ ioc_main(ioc_data_t *ioc_data) /* Probe for incoming work requests */ if (MPI_SUCCESS != (mpi_code = (MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, context->sf_msg_comm, &flag, &status)))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Iprobe failed", mpi_code); + HGOTO_DONE((hg_thread_ret_t)FAIL); if (flag) { - double queue_start_time; - int count; - int source = status.MPI_SOURCE; - int tag = status.MPI_TAG; + int count; + int source = status.MPI_SOURCE; + int tag = status.MPI_TAG; - if ((tag != READ_INDEP) && (tag != WRITE_INDEP) && (tag != TRUNC_OP) && (tag != GET_EOF_OP)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, -1, "invalid work request operation (%d)", - tag); + if (tag != READ_INDEP && tag != WRITE_INDEP && tag != TRUNC_OP && tag != GET_EOF_OP) + HGOTO_DONE((hg_thread_ret_t)FAIL); if (MPI_SUCCESS != (mpi_code = MPI_Get_count(&status, MPI_BYTE, &count))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Get_count failed", mpi_code); + HGOTO_DONE((hg_thread_ret_t)FAIL); if (count < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, -1, "invalid work request message size (%d)", - count); - + HGOTO_DONE((hg_thread_ret_t)FAIL); if ((size_t)count > sizeof(sf_work_request_t)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, -1, "work request message is too large (%d)", - count); + HGOTO_DONE((hg_thread_ret_t)FAIL); /* * Zero out work request, since the received message should * be smaller than sizeof(sf_work_request_t) */ memset(&wk_req, 0, sizeof(sf_work_request_t)); - if (MPI_SUCCESS != (mpi_code = MPI_Recv(&wk_req, count, MPI_BYTE, source, tag, context->sf_msg_comm, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Recv failed", mpi_code); + HGOTO_DONE((hg_thread_ret_t)FAIL); /* Dispatch work request to worker threads in thread pool */ - queue_start_time = MPI_Wtime(); - wk_req.tag = tag; wk_req.source = source; wk_req.ioc_idx = context->topology->ioc_idx; wk_req.context_id = ioc_data->sf_context_id; - wk_req.start_time = queue_start_time; +#ifdef H5FD_IOC_COLLECT_STATS + wk_req.start_time = MPI_Wtime(); +#endif - ioc_io_queue_add_entry(ioc_data, &wk_req); + H5FD__ioc_io_queue_add_entry(ioc_data, &wk_req); assert(atomic_load(&ioc_data->sf_io_ops_pending) >= 0); } @@ -415,7 +381,7 @@ ioc_main(ioc_data_t *ioc_data) HDnanosleep(&sleep_spec, NULL); } - ioc_io_queue_dispatch_eligible_entries(ioc_data, flag ? 0 : 1); + H5FD__ioc_io_queue_dispatch_eligible_entries(ioc_data, flag ? 0 : 1); shutdown_requested = atomic_load(&ioc_data->sf_shutdown_flag); } @@ -424,8 +390,8 @@ ioc_main(ioc_data_t *ioc_data) atomic_store(&ioc_data->sf_shutdown_flag, 0); done: - H5_SUBFILING_FUNC_LEAVE; -} /* ioc_main() */ + return ret_value; +} /* H5FD__ioc_thread_main() */ #ifdef H5_SUBFILING_DEBUG static const char * @@ -463,7 +429,7 @@ translate_opcode(io_op_t op) #endif /*------------------------------------------------------------------------- - * Function: handle_work_request + * Function: H5FD__ioc_handle_work_request * * Purpose: Handle a work request from the thread pool work queue. * We dispatch the specific function as indicated by the @@ -480,7 +446,7 @@ translate_opcode(io_op_t op) *------------------------------------------------------------------------- */ static HG_THREAD_RETURN_TYPE -handle_work_request(void *arg) +H5FD__ioc_handle_work_request(void *arg) { ioc_io_queue_entry_t *q_entry_ptr = (ioc_io_queue_entry_t *)arg; subfiling_context_t *sf_context = NULL; @@ -494,7 +460,7 @@ handle_work_request(void *arg) assert(q_entry_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); assert(q_entry_ptr->in_progress); - sf_context = H5_get_subfiling_object(file_context_id); + sf_context = H5FD__subfiling_get_object(file_context_id); assert(sf_context); ioc_data = sf_context->ioc_data; @@ -504,27 +470,28 @@ handle_work_request(void *arg) switch (msg->tag) { case WRITE_INDEP: - op_ret = ioc_file_queue_write_indep(msg, msg->ioc_idx, msg->source, sf_context->sf_data_comm, - q_entry_ptr->counter); + op_ret = H5FD__ioc_file_queue_write_indep(msg, msg->ioc_idx, msg->source, + sf_context->sf_data_comm, q_entry_ptr->counter); break; case READ_INDEP: - op_ret = ioc_file_queue_read_indep(msg, msg->ioc_idx, msg->source, sf_context->sf_data_comm, - q_entry_ptr->counter); + op_ret = H5FD__ioc_file_queue_read_indep(msg, msg->ioc_idx, msg->source, sf_context->sf_data_comm, + q_entry_ptr->counter); break; case TRUNC_OP: - op_ret = ioc_file_truncate(msg); + op_ret = H5FD__ioc_file_truncate(msg); break; case GET_EOF_OP: - op_ret = ioc_file_report_eof(msg, sf_context->sf_eof_comm); + op_ret = H5FD__ioc_file_report_eof(msg, sf_context->sf_eof_comm); break; default: #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, "%s: IOC %d received unknown message with tag %x from rank %d", - __func__, msg->ioc_idx, msg->tag, msg->source); + H5FD__subfiling_log(file_context_id, + "%s: IOC %d received unknown message with tag %x from rank %d", __func__, + msg->ioc_idx, msg->tag, msg->source); #endif op_ret = -1; @@ -535,11 +502,11 @@ handle_work_request(void *arg) if (op_ret < 0) { #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, - "%s: IOC %d request(%s) from rank(%d), (%" PRId64 ", %" PRId64 ", %" PRId64 - ") FAILED with ret %d", - __func__, msg->ioc_idx, translate_opcode((io_op_t)msg->tag), msg->source, - msg->header[0], msg->header[1], msg->header[2], op_ret); + H5FD__subfiling_log(file_context_id, + "%s: IOC %d request(%s) from rank(%d), (%" PRId64 ", %" PRId64 ", %" PRId64 + ") FAILED with ret %d", + __func__, msg->ioc_idx, translate_opcode((io_op_t)msg->tag), msg->source, + msg->header[0], msg->header[1], msg->header[2], op_ret); #endif q_entry_ptr->wk_ret = op_ret; @@ -553,14 +520,14 @@ handle_work_request(void *arg) #endif /* complete the I/O request */ - ioc_io_queue_complete_entry(ioc_data, q_entry_ptr); + H5FD__ioc_io_queue_complete_entry(ioc_data, q_entry_ptr); assert(atomic_load(&ioc_data->sf_io_ops_pending) >= 0); /* Check the I/O Queue to see if there are any dispatchable entries */ - ioc_io_queue_dispatch_eligible_entries(ioc_data, 1); + H5FD__ioc_io_queue_dispatch_eligible_entries(ioc_data, 1); - H5_SUBFILING_FUNC_LEAVE; + return ret_value; } /*------------------------------------------------------------------------- @@ -595,36 +562,25 @@ H5FD_ioc_end_thread_exclusive(void) } static herr_t -send_ack_to_client(int ack_val, int dest_rank, int source_rank, int msg_tag, MPI_Comm comm) +H5FD__ioc_send_ack_to_client(int ack_val, int dest_rank, int msg_tag, MPI_Comm comm) { - int mpi_code; - herr_t ret_value = SUCCEED; - assert(ack_val > 0); - (void)source_rank; - - if (MPI_SUCCESS != (mpi_code = MPI_Send(&ack_val, 1, MPI_INT, dest_rank, msg_tag, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send", mpi_code); + if (MPI_SUCCESS != MPI_Send(&ack_val, 1, MPI_INT, dest_rank, msg_tag, comm)) + return FAIL; -done: - H5_SUBFILING_FUNC_LEAVE; + return SUCCEED; } static herr_t -send_nack_to_client(int dest_rank, int source_rank, int msg_tag, MPI_Comm comm) +H5FD__ioc_send_nack_to_client(int dest_rank, int msg_tag, MPI_Comm comm) { - int nack = 0; - int mpi_code; - herr_t ret_value = SUCCEED; - - (void)source_rank; + int nack = 0; - if (MPI_SUCCESS != (mpi_code = MPI_Send(&nack, 1, MPI_INT, dest_rank, msg_tag, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send", mpi_code); + if (MPI_SUCCESS != MPI_Send(&nack, 1, MPI_INT, dest_rank, msg_tag, comm)) + return FAIL; -done: - H5_SUBFILING_FUNC_LEAVE; + return SUCCEED; } /* @@ -635,7 +591,7 @@ from the thread pool threads... */ /*------------------------------------------------------------------------- - * Function: ioc_file_queue_write_indep + * Function: H5FD__ioc_file_queue_write_indep * * Purpose: Implement the IOC independent write function. The * function is invoked as a result of the IOC receiving the @@ -644,14 +600,15 @@ from the thread pool threads... * subfile. We utilize pwrite for the actual file writing. * File flushing is done at file close. * - * Return: The integer status returned by the Internal read_independent + * Return: The integer status returned by the internal read_independent * function. Successful operations will return 0. * Errors: An MPI related error value. * *------------------------------------------------------------------------- */ static int -ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, uint32_t counter) +H5FD__ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, + uint32_t counter) { subfiling_context_t *sf_context = NULL; MPI_Status msg_status; @@ -673,7 +630,6 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ int rcv_tag; int sf_fid; int data_bytes_received; - int write_ret; int mpi_code; int ret_value = 0; @@ -688,10 +644,10 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ if (data_size < 0) { send_nack = true; - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_BADVALUE, -1, "invalid data size for write"); + HGOTO_DONE(FAIL); } - sf_context = H5_get_subfiling_object(file_context_id); + sf_context = H5FD__subfiling_get_object(file_context_id); assert(sf_context); stripe_id = file_offset + data_size; @@ -711,17 +667,17 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ t_queue_delay = t_start - msg->start_time; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, - "[ioc(%d) %s]: msg from %d: datasize=%ld\toffset=%ld, queue_delay = %lf seconds\n", - ioc_idx, __func__, source, data_size, file_offset, t_queue_delay); + H5FD__subfiling_log(file_context_id, + "[ioc(%d) %s]: msg from %d: datasize=%ld\toffset=%ld, queue_delay = %lf seconds\n", + ioc_idx, __func__, source, data_size, file_offset, t_queue_delay); #endif #endif /* Allocate space to receive data sent from the client */ - if (NULL == (recv_buf = malloc((size_t)data_size))) { + if (NULL == (recv_buf = H5MM_malloc((size_t)data_size))) { send_nack = true; - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, -1, "couldn't allocate receive buffer for data"); + HGOTO_DONE(FAIL); } /* @@ -736,22 +692,20 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ rcv_tag %= (*H5FD_IOC_tag_ub_val_ptr - IO_TAG_BASE); rcv_tag += IO_TAG_BASE; - if (send_ack_to_client(rcv_tag, source, ioc_idx, WRITE_INDEP_ACK, comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, -1, "couldn't send ACK to client"); + if (H5FD__ioc_send_ack_to_client(rcv_tag, source, WRITE_INDEP_ACK, comm) < 0) + HGOTO_DONE(FAIL); /* Receive data from client */ H5_CHECK_OVERFLOW(data_size, int64_t, int); if (MPI_SUCCESS != (mpi_code = MPI_Recv(recv_buf, (int)data_size, MPI_BYTE, source, rcv_tag, comm, &msg_status))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Recv failed", mpi_code); + HGOTO_DONE(FAIL); if (MPI_SUCCESS != (mpi_code = MPI_Get_count(&msg_status, MPI_BYTE, &data_bytes_received))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Get_count failed", mpi_code); + HGOTO_DONE(FAIL); if (data_bytes_received != data_size) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, -1, - "message size mismatch -- expected = %" PRId64 ", actual = %d", data_size, - data_bytes_received); + HGOTO_DONE(FAIL); #ifdef H5FD_IOC_COLLECT_STATS t_end = MPI_Wtime(); @@ -761,8 +715,8 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ t_start = t_end; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, "[ioc(%d) %s] MPI_Recv(%ld bytes, from = %d) status = %d\n", ioc_idx, - __func__, data_size, source, mpi_code); + H5FD__subfiling_log(file_context_id, "[ioc(%d) %s] MPI_Recv(%ld bytes, from = %d) status = %d\n", ioc_idx, + __func__, data_size, source, mpi_code); #endif #endif @@ -772,16 +726,14 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ #ifdef H5_SUBFILING_DEBUG if (sf_fid < 0) - H5_subfiling_log(file_context_id, "%s: WARNING: attempt to write data to closed subfile FID %d", - __func__, sf_fid); + H5FD__subfiling_log(file_context_id, "%s: WARNING: attempt to write data to closed subfile FID %d", + __func__, sf_fid); #endif if (sf_fid >= 0) { /* Actually write data received from client into subfile */ - if ((write_ret = ioc_file_write_data(sf_fid, file_offset, recv_buf, data_size, ioc_idx)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, -1, - "write function(FID=%d, Source=%d) returned an error (%d)", sf_fid, - source, write_ret); + if (H5FD__ioc_file_write_data(sf_fid, file_offset, recv_buf, data_size, ioc_idx) < 0) + HGOTO_DONE(FAIL); #ifdef H5FD_IOC_COLLECT_STATS t_end = MPI_Wtime(); @@ -807,22 +759,21 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ * completed and it is safe to return from the write call */ if (MPI_SUCCESS != (mpi_code = MPI_Send(&rcv_tag, 1, MPI_INT, source, WRITE_DATA_DONE, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Send failed", mpi_code); + HGOTO_DONE(FAIL); done: - if (send_nack) { + if (send_nack) /* Send NACK back to client so client can handle failure gracefully */ - if (send_nack_to_client(source, ioc_idx, WRITE_INDEP_ACK, comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_IO, H5E_WRITEERROR, -1, "couldn't send NACK to client"); - } + if (H5FD__ioc_send_nack_to_client(source, WRITE_INDEP_ACK, comm) < 0) + ret_value = FAIL; - free(recv_buf); + H5MM_free(recv_buf); - H5_SUBFILING_FUNC_LEAVE; -} /* ioc_file_queue_write_indep() */ + return ret_value; +} /* H5FD__ioc_file_queue_write_indep() */ /*------------------------------------------------------------------------- - * Function: ioc_file_queue_read_indep + * Function: H5FD__ioc_file_queue_read_indep * * Purpose: Implement the IOC independent read function. The * function is invoked as a result of the IOC receiving the @@ -837,7 +788,8 @@ ioc_file_queue_write_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_ *------------------------------------------------------------------------- */ static int -ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, uint32_t counter) +H5FD__ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_Comm comm, + uint32_t counter) { subfiling_context_t *sf_context = NULL; bool send_empty_buf = true; @@ -856,29 +808,25 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C char *send_buf = NULL; int send_tag; int sf_fid; - int read_ret; - int mpi_code; int ret_value = 0; assert(msg); file_context_id = msg->context_id; - sf_context = H5_get_subfiling_object(file_context_id); + sf_context = H5FD__subfiling_get_object(file_context_id); assert(sf_context); /* - * If we are using 1 subfile per IOC, we can optimize reads - * a little since each read will go to a separate IOC and we - * won't be in danger of data being received in an - * unpredictable order. However, if some IOCs own more than - * 1 subfile, we need to associate each read with a unique - * message tag to make sure the data is received in the - * correct order. We also need a unique message tag in the - * case where only 1 subfile is used in total. In this case, - * vector I/O calls are passed directly down to this VFD without - * being split up into multiple I/O requests, so we need the - * tag to distinguish each I/O request. + * If we are using 1 subfile per IOC, we can optimize reads a little since + * each read will go to a separate IOC and we won't be in danger of data + * being received in an unpredictable order. However, if some IOCs own more + * than 1 subfile, we need to associate each read with a unique message tag + * to make sure the data is received in the correct order. We also need a + * unique message tag in the case where only 1 subfile is used in total. In + * this case, vector I/O calls are passed directly down to this VFD without + * being split up into multiple I/O requests, so we need the tag to + * distinguish each I/O request. */ need_data_tag = (sf_context->sf_num_subfiles == 1) || (sf_context->sf_num_subfiles != sf_context->topology->n_io_concentrators); @@ -895,7 +843,7 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C send_nack = true; send_empty_buf = false; } - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_BADVALUE, -1, "invalid data size for read"); + HGOTO_DONE(FAIL); } /* Flag that we've attempted to read data from the file */ @@ -909,20 +857,20 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C t_queue_delay = t_start - msg->start_time; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, - "[ioc(%d) %s] msg from %d: datasize=%ld\toffset=%ld queue_delay=%lf seconds\n", ioc_idx, - __func__, source, data_size, file_offset, t_queue_delay); + H5FD__subfiling_log(file_context_id, + "[ioc(%d) %s] msg from %d: datasize=%ld\toffset=%ld queue_delay=%lf seconds\n", + ioc_idx, __func__, source, data_size, file_offset, t_queue_delay); #endif #endif /* Allocate space to send data read from file to client */ - if (NULL == (send_buf = malloc((size_t)data_size))) { + if (NULL == (send_buf = H5MM_malloc((size_t)data_size))) { if (need_data_tag) { send_nack = true; send_empty_buf = false; } - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, -1, "couldn't allocate send buffer for data"); + HGOTO_DONE(FAIL); } if (need_data_tag) { @@ -939,9 +887,9 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C send_tag %= (*H5FD_IOC_tag_ub_val_ptr - IO_TAG_BASE); send_tag += IO_TAG_BASE; - if (send_ack_to_client(send_tag, source, ioc_idx, READ_INDEP_ACK, comm) < 0) { + if (H5FD__ioc_send_ack_to_client(send_tag, source, READ_INDEP_ACK, comm) < 0) { send_empty_buf = false; - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, -1, "couldn't send ACK to client"); + HGOTO_DONE(FAIL); } } @@ -949,20 +897,17 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C assert(subfile_idx < sf_context->sf_num_fids); sf_fid = sf_context->sf_fids[subfile_idx]; if (sf_fid < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_BADVALUE, -1, "subfile file descriptor %d is invalid", sf_fid); + HGOTO_DONE(FAIL); - if ((read_ret = ioc_file_read_data(sf_fid, file_offset, send_buf, data_size, ioc_idx)) < 0) { - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, read_ret, - "read function(FID=%d, Source=%d) returned an error (%d)", sf_fid, source, - read_ret); - } + if (H5FD__ioc_file_read_data(sf_fid, file_offset, send_buf, data_size, ioc_idx) < 0) + HGOTO_DONE(FAIL); send_empty_buf = false; /* Send read data to the client */ H5_CHECK_OVERFLOW(data_size, int64_t, int); - if (MPI_SUCCESS != (mpi_code = MPI_Send(send_buf, (int)data_size, MPI_BYTE, source, send_tag, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Send failed", mpi_code); + if (MPI_SUCCESS != MPI_Send(send_buf, (int)data_size, MPI_BYTE, source, send_tag, comm)) + HGOTO_DONE(FAIL); #ifdef H5FD_IOC_COLLECT_STATS t_end = MPI_Wtime(); @@ -971,31 +916,29 @@ ioc_file_queue_read_indep(sf_work_request_t *msg, int ioc_idx, int source, MPI_C sf_queue_delay_time += t_queue_delay; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, "[ioc(%d)] MPI_Send to source(%d) completed\n", ioc_idx, - source); + H5FD__subfiling_log(sf_context->sf_context_id, "[ioc(%d)] MPI_Send to source(%d) completed\n", ioc_idx, + source); #endif #endif done: - if (need_data_tag && send_nack) { + if (need_data_tag && send_nack) /* Send NACK back to client so client can handle failure gracefully */ - if (send_nack_to_client(source, ioc_idx, READ_INDEP_ACK, comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_IO, H5E_READERROR, -1, "couldn't send NACK to client"); - } - if (send_empty_buf) { + if (H5FD__ioc_send_nack_to_client(source, READ_INDEP_ACK, comm) < 0) + ret_value = FAIL; + if (send_empty_buf) /* * Send an empty message back to client on failure. The client will * likely get a message truncation error, but at least shouldn't hang. */ - if (MPI_SUCCESS != (mpi_code = MPI_Send(NULL, 0, MPI_BYTE, source, send_tag, comm))) - H5_SUBFILING_MPI_DONE_ERROR(-1, "MPI_Send failed", mpi_code); - } + if (MPI_SUCCESS != MPI_Send(NULL, 0, MPI_BYTE, source, send_tag, comm)) + ret_value = FAIL; - free(send_buf); + H5MM_free(send_buf); return ret_value; -} /* end ioc_file_queue_read_indep() */ +} /* end H5FD__ioc_file_queue_read_indep() */ /* ====================================================== @@ -1007,7 +950,7 @@ being thread safe. */ static int -ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx) +H5FD__ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx) { ssize_t bytes_remaining = (ssize_t)data_size; ssize_t bytes_written = 0; @@ -1036,9 +979,8 @@ ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data this_data += bytes_written; file_offset += bytes_written; } - else { - H5_SUBFILING_SYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, -1, "HDpwrite failed"); - } + else + HGOTO_DONE(FAIL); } /* We don't usually use this for each file write. We usually do the file @@ -1049,11 +991,11 @@ ioc_file_write_data(int fd, int64_t file_offset, void *data_buffer, int64_t data #endif done: - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc_file_write_data() */ + return ret_value; +} /* end H5FD__ioc_file_write_data() */ static int -ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx) +H5FD__ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_size, int ioc_idx) { useconds_t delay = 100; ssize_t bytes_remaining = (ssize_t)data_size; @@ -1098,11 +1040,11 @@ ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_ else { if (retries == 0) { #ifdef H5FD_IOC_DEBUG - printf("[ioc(%d) %s]: TIMEOUT: file_offset=%" PRId64 ", data_size=%ld\n", ioc_idx, __func__, - file_offset, data_size); + printf("[ioc(%d) %s]: TIMEOUT: file_offset=%" PRId64 ", data_size=%" PRId64 "\n", ioc_idx, + __func__, file_offset, data_size); #endif - H5_SUBFILING_SYS_GOTO_ERROR(H5E_IO, H5E_READERROR, -1, "HDpread failed"); + HGOTO_DONE(FAIL); } retries--; @@ -1112,11 +1054,11 @@ ioc_file_read_data(int fd, int64_t file_offset, void *data_buffer, int64_t data_ } done: - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc_file_read_data() */ + return ret_value; +} /* end H5FD__ioc_file_read_data() */ static int -ioc_file_truncate(sf_work_request_t *msg) +H5FD__ioc_file_truncate(sf_work_request_t *msg) { subfiling_context_t *sf_context = NULL; int64_t file_context_id; @@ -1124,7 +1066,6 @@ ioc_file_truncate(sf_work_request_t *msg) int64_t subfile_idx; int fd; int ioc_idx; - int mpi_code; int ret_value = 0; assert(msg); @@ -1139,23 +1080,23 @@ ioc_file_truncate(sf_work_request_t *msg) (void)ioc_idx; #endif - if (NULL == (sf_context = H5_get_subfiling_object(file_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, -1, "couldn't retrieve subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file_context_id))) + HGOTO_DONE(FAIL); assert(subfile_idx < sf_context->sf_num_fids); fd = sf_context->sf_fids[subfile_idx]; if (HDftruncate(fd, (HDoff_t)length) != 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SEEKERROR, -1, "HDftruncate failed"); + HGOTO_DONE(FAIL); /* * Send a completion message back to the source that * requested the truncation operation */ - if (MPI_SUCCESS != (mpi_code = MPI_Send(msg->header, 1, H5_subfiling_rpc_msg_type, msg->source, - TRUNC_COMPLETED, sf_context->sf_eof_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + if (MPI_SUCCESS != MPI_Send(msg->header, 1, H5_subfiling_rpc_msg_type, msg->source, TRUNC_COMPLETED, + sf_context->sf_eof_comm)) + HGOTO_DONE(FAIL); #ifdef H5FD_IOC_DEBUG printf("[ioc(%d) %s]: truncated subfile to %lld bytes. ret = %d\n", ioc_idx, __func__, (long long)length, @@ -1164,11 +1105,11 @@ ioc_file_truncate(sf_work_request_t *msg) #endif done: - H5_SUBFILING_FUNC_LEAVE; -} /* end ioc_file_truncate() */ + return ret_value; +} /* end H5FD__ioc_file_truncate() */ /*------------------------------------------------------------------------- - * Function: ioc_file_report_eof + * Function: H5FD__ioc_file_report_eof * * Purpose: Determine the target subfile's eof and report this value * to the requesting rank. @@ -1183,9 +1124,8 @@ ioc_file_truncate(sf_work_request_t *msg) * *------------------------------------------------------------------------- */ - static int -ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) +H5FD__ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) { subfiling_context_t *sf_context = NULL; h5_stat_t sb; @@ -1195,7 +1135,6 @@ ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) int fd; int source; int ioc_idx; - int mpi_code; int ret_value = 0; assert(msg); @@ -1206,8 +1145,8 @@ ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) subfile_idx = msg->header[0]; - if (NULL == (sf_context = H5_get_subfiling_object(file_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, -1, "couldn't retrieve subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file_context_id))) + HGOTO_DONE(FAIL); assert(subfile_idx < sf_context->sf_num_fids); @@ -1215,27 +1154,27 @@ ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) memset(&sb, 0, sizeof(h5_stat_t)); if (HDfstat(fd, &sb) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SYSERRSTR, -1, "HDfstat failed"); + HGOTO_DONE(FAIL); eof_req_reply[0] = (int64_t)ioc_idx; eof_req_reply[1] = (int64_t)(sb.st_size); eof_req_reply[2] = subfile_idx; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(file_context_id, "%s: reporting file EOF as %" PRId64 ".", __func__, eof_req_reply[1]); + H5FD__subfiling_log(file_context_id, "%s: reporting file EOF as %" PRId64 ".", __func__, + eof_req_reply[1]); #endif /* return the subfile EOF to the querying rank */ - if (MPI_SUCCESS != - (mpi_code = MPI_Send(eof_req_reply, 1, H5_subfiling_rpc_msg_type, source, GET_EOF_COMPLETED, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(-1, "MPI_Send", mpi_code); + if (MPI_SUCCESS != MPI_Send(eof_req_reply, 1, H5_subfiling_rpc_msg_type, source, GET_EOF_COMPLETED, comm)) + HGOTO_DONE(FAIL); done: - H5_SUBFILING_FUNC_LEAVE; -} /* ioc_file_report_eof() */ + return ret_value; +} /* H5FD__ioc_file_report_eof() */ /*------------------------------------------------------------------------- - * Function: ioc_io_queue_alloc_entry + * Function: H5FD__ioc_io_queue_alloc_entry * * Purpose: Allocate and initialize an instance of * ioc_io_queue_entry_t. Return pointer to the new @@ -1247,36 +1186,19 @@ ioc_file_report_eof(sf_work_request_t *msg, MPI_Comm comm) *------------------------------------------------------------------------- */ static ioc_io_queue_entry_t * -ioc_io_queue_alloc_entry(void) +H5FD__ioc_io_queue_alloc_entry(void) { ioc_io_queue_entry_t *q_entry_ptr = NULL; - q_entry_ptr = (ioc_io_queue_entry_t *)malloc(sizeof(ioc_io_queue_entry_t)); - - if (q_entry_ptr) { - - q_entry_ptr->magic = H5FD_IOC__IO_Q_ENTRY_MAGIC; - q_entry_ptr->next = NULL; - q_entry_ptr->prev = NULL; - q_entry_ptr->in_progress = false; - q_entry_ptr->counter = 0; - - /* will memcpy the wk_req field, so don't bother to initialize */ - /* will initialize thread_wk field before use */ - - q_entry_ptr->wk_ret = 0; - -#ifdef H5FD_IOC_COLLECT_STATS - q_entry_ptr->q_time = 0; - q_entry_ptr->dispatch_time = 0; -#endif - } + q_entry_ptr = (ioc_io_queue_entry_t *)H5MM_calloc(sizeof(ioc_io_queue_entry_t)); + if (q_entry_ptr) + q_entry_ptr->magic = H5FD_IOC__IO_Q_ENTRY_MAGIC; return q_entry_ptr; -} /* ioc_io_queue_alloc_entry() */ +} /* H5FD__ioc_io_queue_alloc_entry() */ /*------------------------------------------------------------------------- - * Function: ioc_io_queue_add_entry + * Function: H5FD__ioc_io_queue_add_entry * * Purpose: Add an I/O request to the tail of the IOC I/O Queue. * @@ -1291,14 +1213,14 @@ ioc_io_queue_alloc_entry(void) * * Note that this does not dispatch the request even if it * is eligible for immediate dispatch. This is done with - * a call to ioc_io_queue_dispatch_eligible_entries(). + * a call to H5FD__ioc_io_queue_dispatch_eligible_entries(). * * Return: void. * *------------------------------------------------------------------------- */ static void -ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) +H5FD__ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) { ioc_io_queue_entry_t *entry_ptr = NULL; @@ -1306,7 +1228,7 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) assert(ioc_data->io_queue.magic == H5FD_IOC__IO_Q_MAGIC); assert(wk_req_ptr); - entry_ptr = ioc_io_queue_alloc_entry(); + entry_ptr = H5FD__ioc_io_queue_alloc_entry(); assert(entry_ptr); assert(entry_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); @@ -1327,7 +1249,7 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) atomic_fetch_add(&ioc_data->sf_io_ops_pending, 1); #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log( + H5FD__subfiling_log( wk_req_ptr->context_id, "%s: request %d queued. op = %d, req = (%lld, %lld, %lld), q-ed/disp/ops_pend = %d/%d/%d.", __func__, entry_ptr->counter, (entry_ptr->wk_req.tag), (long long)(entry_ptr->wk_req.header[0]), @@ -1341,33 +1263,27 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) #ifdef H5FD_IOC_COLLECT_STATS entry_ptr->q_time = H5_now_usec(); - if (ioc_data->io_queue.q_len > ioc_data->io_queue.max_q_len) { + if (ioc_data->io_queue.q_len > ioc_data->io_queue.max_q_len) ioc_data->io_queue.max_q_len = ioc_data->io_queue.q_len; - } - if (ioc_data->io_queue.num_pending > ioc_data->io_queue.max_num_pending) { + if (ioc_data->io_queue.num_pending > ioc_data->io_queue.max_num_pending) ioc_data->io_queue.max_num_pending = ioc_data->io_queue.num_pending; - } - if (entry_ptr->wk_req.tag == READ_INDEP) { + if (entry_ptr->wk_req.tag == READ_INDEP) ioc_data->io_queue.ind_read_requests++; - } - else if (entry_ptr->wk_req.tag == WRITE_INDEP) { + else if (entry_ptr->wk_req.tag == WRITE_INDEP) ioc_data->io_queue.ind_write_requests++; - } - else if (entry_ptr->wk_req.tag == TRUNC_OP) { + else if (entry_ptr->wk_req.tag == TRUNC_OP) ioc_data->io_queue.truncate_requests++; - } - else if (entry_ptr->wk_req.tag == GET_EOF_OP) { + else if (entry_ptr->wk_req.tag == GET_EOF_OP) ioc_data->io_queue.get_eof_requests++; - } ioc_data->io_queue.requests_queued++; #endif #ifdef H5_SUBFILING_DEBUG if (ioc_data->io_queue.q_len != atomic_load(&ioc_data->sf_io_ops_pending)) { - H5_subfiling_log( + H5FD__subfiling_log( wk_req_ptr->context_id, "%s: ioc_data->io_queue->q_len = %d != %d = atomic_load(&ioc_data->sf_io_ops_pending).", __func__, ioc_data->io_queue.q_len, atomic_load(&ioc_data->sf_io_ops_pending)); @@ -1379,10 +1295,10 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) hg_thread_mutex_unlock(&ioc_data->io_queue.q_mutex); return; -} /* ioc_io_queue_add_entry() */ +} /* H5FD__ioc_io_queue_add_entry() */ /*------------------------------------------------------------------------- - * Function: ioc_io_queue_dispatch_eligible_entries + * Function: H5FD__ioc_io_queue_dispatch_eligible_entries * * Purpose: Scan the IOC I/O Queue for dispatchable entries, and * dispatch any such entries found. @@ -1421,7 +1337,7 @@ ioc_io_queue_add_entry(ioc_data_t *ioc_data, sf_work_request_t *wk_req_ptr) * can become O(N**2) in the worst case. */ static void -ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) +H5FD__ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) { bool conflict_detected; int64_t entry_offset; @@ -1445,24 +1361,18 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) /* sanity check on first element in the I/O queue */ assert((entry_ptr == NULL) || (entry_ptr->prev == NULL)); - - while ((entry_ptr) && (ioc_data->io_queue.num_pending > 0)) { - + while (entry_ptr && ioc_data->io_queue.num_pending > 0) { assert(entry_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); /* Check for a get EOF or truncate operation at head of queue */ - if (ioc_data->io_queue.q_head->in_progress) { - if ((ioc_data->io_queue.q_head->wk_req.tag == TRUNC_OP) || - (ioc_data->io_queue.q_head->wk_req.tag == GET_EOF_OP)) { - - /* we have a truncate or get eof operation in progress -- thus no other operations - * can be dispatched until the truncate or get eof operation completes. Just break - * out of the loop. - */ - + if (ioc_data->io_queue.q_head->in_progress) + /* We have a truncate or get eof operation in progress -- thus no other operations + * can be dispatched until the truncate or get eof operation completes. Just break + * out of the loop. + */ + if (ioc_data->io_queue.q_head->wk_req.tag == TRUNC_OP || + ioc_data->io_queue.q_head->wk_req.tag == GET_EOF_OP) break; - } - } if (!entry_ptr->in_progress) { @@ -1473,46 +1383,30 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) scan_ptr = entry_ptr->prev; - assert((scan_ptr == NULL) || (scan_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC)); - - if ((entry_ptr->wk_req.tag == TRUNC_OP) || (entry_ptr->wk_req.tag == GET_EOF_OP)) { - - if (scan_ptr != NULL) { - - /* the TRUNC_OP or GET_EOF_OP is not at the head of the queue, and thus cannot - * be dispatched. Further, no operation can be dispatched if a truncate request - * appears before it in the queue. Thus we have done all we can and will break - * out of the loop. - */ + assert(scan_ptr == NULL || scan_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); + if (entry_ptr->wk_req.tag == TRUNC_OP || entry_ptr->wk_req.tag == GET_EOF_OP) + /* the TRUNC_OP or GET_EOF_OP is not at the head of the queue, and thus cannot + * be dispatched. Further, no operation can be dispatched if a truncate request + * appears before it in the queue. Thus we have done all we can and will break + * out of the loop. + */ + if (scan_ptr != NULL) break; - } - } - - while ((scan_ptr) && (!conflict_detected)) { + while (scan_ptr && !conflict_detected) { /* check for overlaps */ scan_offset = scan_ptr->wk_req.header[1]; scan_len = scan_ptr->wk_req.header[0]; - /* at present, I/O requests are scalar -- i.e. single blocks specified by offset and length. - * when this changes, this if statement will have to be updated accordingly. - */ - if (((scan_offset + scan_len) > entry_offset) && ((entry_offset + entry_len) > scan_offset)) { - + if ((scan_offset + scan_len) > entry_offset && (entry_offset + entry_len) > scan_offset) /* the two request overlap -- unless they are both reads, we have detected a conflict */ - - /* TODO: update this if statement when we add collective I/O */ - if ((entry_ptr->wk_req.tag != READ_INDEP) || (scan_ptr->wk_req.tag != READ_INDEP)) { - + if (entry_ptr->wk_req.tag != READ_INDEP || scan_ptr->wk_req.tag != READ_INDEP) conflict_detected = true; - } - } scan_ptr = scan_ptr->prev; } if (!conflict_detected) { /* dispatch I/O request */ - assert(scan_ptr == NULL); assert(!entry_ptr->in_progress); @@ -1526,11 +1420,11 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) assert(ioc_data->io_queue.num_pending + ioc_data->io_queue.num_in_progress == ioc_data->io_queue.q_len); - entry_ptr->thread_wk.func = handle_work_request; + entry_ptr->thread_wk.func = H5FD__ioc_handle_work_request; entry_ptr->thread_wk.args = entry_ptr; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log( + H5FD__subfiling_log( entry_ptr->wk_req.context_id, "%s: request %d dispatched. op = %d, req = (%lld, %lld, %lld), " "q-ed/disp/ops_pend = %d/%d/%d.", @@ -1541,9 +1435,8 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) #endif #ifdef H5FD_IOC_COLLECT_STATS - if (ioc_data->io_queue.num_in_progress > ioc_data->io_queue.max_num_in_progress) { + if (ioc_data->io_queue.num_in_progress > ioc_data->io_queue.max_num_in_progress) ioc_data->io_queue.max_num_in_progress = ioc_data->io_queue.num_in_progress; - } ioc_data->io_queue.requests_dispatched++; @@ -1560,10 +1453,10 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) assert(ioc_data->io_queue.q_len == atomic_load(&ioc_data->sf_io_ops_pending)); hg_thread_mutex_unlock(&ioc_data->io_queue.q_mutex); -} /* ioc_io_queue_dispatch_eligible_entries() */ +} /* H5FD__ioc_io_queue_dispatch_eligible_entries() */ /*------------------------------------------------------------------------- - * Function: ioc_io_queue_complete_entry + * Function: H5FD__ioc_io_queue_complete_entry * * Purpose: Update the IOC I/O Queue for the completion of an I/O * request. @@ -1581,13 +1474,8 @@ ioc_io_queue_dispatch_eligible_entries(ioc_data_t *ioc_data, bool try_lock) *------------------------------------------------------------------------- */ static void -ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_ptr) +H5FD__ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_ptr) { -#ifdef H5FD_IOC_COLLECT_STATS - uint64_t queued_time; - uint64_t execution_time; -#endif - assert(ioc_data); assert(ioc_data->io_queue.magic == H5FD_IOC__IO_Q_MAGIC); assert(entry_ptr); @@ -1611,13 +1499,13 @@ ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_pt atomic_fetch_sub(&ioc_data->sf_io_ops_pending, 1); #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(entry_ptr->wk_req.context_id, - "%s: request %d completed with ret %d. op = %d, req = (%lld, %lld, %lld), " - "q-ed/disp/ops_pend = %d/%d/%d.", - __func__, entry_ptr->counter, entry_ptr->wk_ret, (entry_ptr->wk_req.tag), - (long long)(entry_ptr->wk_req.header[0]), (long long)(entry_ptr->wk_req.header[1]), - (long long)(entry_ptr->wk_req.header[2]), ioc_data->io_queue.num_pending, - ioc_data->io_queue.num_in_progress, atomic_load(&ioc_data->sf_io_ops_pending)); + H5FD__subfiling_log(entry_ptr->wk_req.context_id, + "%s: request %d completed with ret %d. op = %d, req = (%lld, %lld, %lld), " + "q-ed/disp/ops_pend = %d/%d/%d.", + __func__, entry_ptr->counter, entry_ptr->wk_ret, (entry_ptr->wk_req.tag), + (long long)(entry_ptr->wk_req.header[0]), (long long)(entry_ptr->wk_req.header[1]), + (long long)(entry_ptr->wk_req.header[2]), ioc_data->io_queue.num_pending, + ioc_data->io_queue.num_in_progress, atomic_load(&ioc_data->sf_io_ops_pending)); /* * If this I/O request is a truncate or "get eof" op, make sure @@ -1630,52 +1518,14 @@ ioc_io_queue_complete_entry(ioc_data_t *ioc_data, ioc_io_queue_entry_t *entry_pt assert(ioc_data->io_queue.q_len == atomic_load(&ioc_data->sf_io_ops_pending)); #ifdef H5FD_IOC_COLLECT_STATS - /* Compute the queued and execution time */ - queued_time = entry_ptr->dispatch_time - entry_ptr->q_time; - execution_time = H5_now_usec() - entry_ptr->dispatch_time; - ioc_data->io_queue.requests_completed++; entry_ptr->q_time = H5_now_usec(); - #endif hg_thread_mutex_unlock(&ioc_data->io_queue.q_mutex); - ioc_io_queue_free_entry(entry_ptr); - - entry_ptr = NULL; - - return; -} /* ioc_io_queue_complete_entry() */ - -/*------------------------------------------------------------------------- - * Function: ioc_io_queue_free_entry - * - * Purpose: Free the supplied instance of ioc_io_queue_entry_t. - * - * Verify that magic field is set to - * H5FD_IOC__IO_Q_ENTRY_MAGIC, and that the next and prev - * fields are NULL. - * - * Return: void. - * - *------------------------------------------------------------------------- - */ -static void -ioc_io_queue_free_entry(ioc_io_queue_entry_t *q_entry_ptr) -{ - /* use assertions for error checking, since the following should never fail. */ - assert(q_entry_ptr); - assert(q_entry_ptr->magic == H5FD_IOC__IO_Q_ENTRY_MAGIC); - assert(q_entry_ptr->next == NULL); - assert(q_entry_ptr->prev == NULL); - - q_entry_ptr->magic = 0; - - free(q_entry_ptr); - - q_entry_ptr = NULL; + H5MM_free(entry_ptr); return; -} /* H5FD_ioc__free_c_io_q_entry() */ +} /* H5FD__ioc_io_queue_complete_entry() */ diff --git a/src/H5FDsubfiling/H5FDsubfile_int.c b/src/H5FDsubfiling/H5FDsubfile_int.c index a7dd86455cb..bf01fc0a2e4 100644 --- a/src/H5FDsubfiling/H5FDsubfile_int.c +++ b/src/H5FDsubfiling/H5FDsubfile_int.c @@ -73,16 +73,18 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); /* Barrier on entry */ if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); - if (NULL == (sf_context = (subfiling_context_t *)H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "can't get subfile context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't get subfile context"); if (sf_context->topology->rank_is_ioc) { int64_t num_full_stripes; @@ -96,24 +98,22 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, num_subfiles_owned = sf_context->sf_num_fids; - if (NULL == (recv_reqs = malloc((size_t)num_subfiles_owned * sizeof(*recv_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate receive requests array"); - if (NULL == (recv_msgs = malloc((size_t)num_subfiles_owned * 3 * sizeof(*recv_msgs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate message array"); + if (NULL == (recv_reqs = H5MM_malloc((size_t)num_subfiles_owned * sizeof(*recv_reqs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate receive requests array"); + if (NULL == (recv_msgs = H5MM_malloc((size_t)num_subfiles_owned * 3 * sizeof(*recv_msgs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate message array"); /* * Post early receives for messages from the IOC main * thread that will signal completion of the truncate * operation */ - for (int i = 0; i < num_subfiles_owned; i++) { + for (int i = 0; i < num_subfiles_owned; i++) if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&recv_msgs[3 * i], 1, H5_subfiling_rpc_msg_type, sf_context->topology->io_concentrators[sf_context->topology->ioc_idx], TRUNC_COMPLETED, sf_context->sf_eof_comm, &recv_reqs[i]))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv failed", mpi_code); /* Compute the EOF for each subfile this IOC owns */ for (int i = 0; i < num_subfiles_owned; i++) { @@ -123,12 +123,10 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, global_subfile_idx = (i * sf_context->topology->n_io_concentrators) + sf_context->topology->ioc_idx; - if (global_subfile_idx < num_leftover_stripes) { + if (global_subfile_idx < num_leftover_stripes) subfile_eof += sf_context->sf_stripe_size; - } - else if (global_subfile_idx == num_leftover_stripes) { + else if (global_subfile_idx == num_leftover_stripes) subfile_eof += partial_stripe_len % sf_context->sf_stripe_size; - } /* Direct the IOC to truncate this subfile to the correct EOF */ msg[0] = subfile_eof; @@ -139,54 +137,26 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, sf_context->topology->io_concentrators[sf_context->topology->ioc_idx], TRUNC_OP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send failed", mpi_code); } /* Wait for truncate operations to complete */ H5_GCC_DIAG_OFF("stringop-overflow") if (MPI_SUCCESS != (mpi_code = MPI_Waitall(num_subfiles_owned, recv_reqs, MPI_STATUSES_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); H5_GCC_DIAG_ON("stringop-overflow") - - /* sanity check -- compute the file eof using the same mechanism used to - * compute the subfile eof. Assert that the computed value and the - * actual value match. - * - * Do this only for debug builds -- probably delete this before release. - * - * JRM -- 12/15/21 - */ - -#ifndef NDEBUG - { - int64_t test_file_eof = 0; - - for (int i = 0; i < sf_context->sf_num_subfiles; i++) { - test_file_eof += num_full_stripes * sf_context->sf_stripe_size; - - if (i < num_leftover_stripes) { - test_file_eof += sf_context->sf_stripe_size; - } - else if (i == num_leftover_stripes) { - test_file_eof += partial_stripe_len % sf_context->sf_stripe_size; - } - } - - assert(test_file_eof == logical_file_eof); - } -#endif /* NDEBUG */ } /* Barrier on exit */ if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Barrier(comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); done: - free(recv_msgs); - free(recv_reqs); + H5MM_free(recv_msgs); + H5MM_free(recv_reqs); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* H5FD__subfiling__truncate_sub_files() */ /*------------------------------------------------------------------------- @@ -207,43 +177,42 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, * subfile's EOF. * * 3) Await reply from each IOC, storing the reply in - * the appropriate entry in the array allocated in 1. + * the appropriate entry in the array allocated in 1). * - * 4) After all IOCs have replied, compute the offset of - * each subfile in the logical file. Take the maximum - * of these values, and report this value as the overall - * EOF. + * 4) After all IOCs have replied, compute the offset of each + * subfile in the logical file. Take the maximum of these + * values, and report this value as the overall EOF. * * Note that this operation is not collective, and can return * invalid data if other ranks perform writes while this * operation is in progress. * - * SUBFILING NOTE: + * NOTE: * The EOF calculation for subfiling is somewhat different * than for the more traditional HDF5 file implementations. * This statement derives from the fact that unlike "normal" * HDF5 files, subfiling introduces a multi-file representation - * of a single HDF5 file. The plurality of subfiles represents + * of a single HDF5 file. This set of subfiles represents * a software RAID-0 based HDF5 file. As such, each subfile * contains a designated portion of the address space of the * virtual HDF5 storage. We have no notion of HDF5 datatypes, - * datasets, metadata, or other HDF5 structures; only BYTES. + * datasets, metadata, or other HDF5 structures; only bytes. * * The organization of the bytes within subfiles is consistent - * with the RAID-0 striping, i.e. there are IO Concentrators - * (IOCs) which correspond to a stripe-count (in Lustre) as - * well as a stripe_size. The combination of these two - * variables determines the "address" (a combination of IOC - * and a file offset) of any storage operation. - * - * Having a defined storage layout, the virtual file EOF - * calculation should be the MAXIMUM value returned by the - * collection of IOCs. Every MPI rank which hosts an IOC - * maintains its own EOF by updating that value for each - * WRITE operation that completes, i.e. if a new local EOF - * is greater than the existing local EOF, the new EOF - * will replace the old. The local EOF calculation is as - * follows. + * with the RAID-0 striping, i.e. there are IO Concentrators (IOCs) + * which correspond to a stripe-count (as in Lustre) as well as a + * stripe_size. The combination of these two variables determines + * the "address" (a combination of IOC and a file offset) of any + * storage operation. + * + * Having a defined storage layout, the virtual file EOF calculation + * should be the maximum value returned by the collection of IOCs. + * Every MPI rank which hosts an IOC maintains its own EOF by + * updating that value for each write operation that completes, i.e. + * if a new local EOF is greater than the existing local EOF, the + * new EOF will replace the old. The local EOF calculation is as + * follows: + * * 1. At file creation, each IOC is assigned a rank value * (0 to N-1, where N is the total number of IOCs) and * a 'sf_base_addr' = 'ioc_idx' * 'sf_stripe_size') @@ -251,10 +220,11 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, * is simply the 'sf_stripe_size' * 'n_ioc_concentrators' * * 2. For every write operation, the IOC receives a message - * containing a file_offset and the data_size. + * containing a file_offset and data_size. * * 3. The file_offset + data_size are in turn used to * create a stripe_id: + * * IOC-(ioc_rank) IOC-(ioc_rank+1) * |<- sf_base_address |<- sf_base_address | * ID +--------------------+--------------------+ @@ -266,6 +236,7 @@ H5FD__subfiling__truncate_sub_files(hid_t context_id, int64_t logical_file_eof, * * The new 'stripe_id' is then used to calculate a * potential new EOF: + * * sf_eof = (stripe_id * sf_blocksize_per_stripe) + sf_base_addr * + ((file_offset + data_size) % sf_stripe_size) * @@ -290,10 +261,12 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) int mpi_code; /* MPI return code */ herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + assert(logical_eof_ptr); - if (NULL == (sf_context = (subfiling_context_t *)H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "can't get subfile context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't get subfile context"); assert(sf_context->topology); @@ -303,12 +276,12 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) assert(n_io_concentrators > 0); assert(num_subfiles >= n_io_concentrators); - if (NULL == (sf_eofs = malloc((size_t)num_subfiles * sizeof(int64_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate subfile EOFs array"); - if (NULL == (recv_reqs = malloc((size_t)num_subfiles * sizeof(*recv_reqs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate receive requests array"); - if (NULL == (recv_msg = malloc((size_t)num_subfiles * sizeof(msg)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate message array"); + if (NULL == (sf_eofs = H5MM_malloc((size_t)num_subfiles * sizeof(int64_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile EOFs array"); + if (NULL == (recv_reqs = H5MM_malloc((size_t)num_subfiles * sizeof(*recv_reqs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate receive requests array"); + if (NULL == (recv_msg = H5MM_malloc((size_t)num_subfiles * sizeof(msg)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate message array"); for (int i = 0; i < num_subfiles; i++) { sf_eofs[i] = -1; @@ -321,7 +294,7 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) if (MPI_SUCCESS != (mpi_code = MPI_Irecv(&recv_msg[3 * i], 1, H5_subfiling_rpc_msg_type, ioc_rank, GET_EOF_COMPLETED, sf_context->sf_eof_comm, &recv_reqs[i]))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Irecv", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Irecv", mpi_code); } /* Send each subfile's IOC a message requesting that subfile's EOF */ @@ -337,13 +310,13 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) if (MPI_SUCCESS != (mpi_code = MPI_Send(msg, 1, H5_subfiling_rpc_msg_type, ioc_rank, GET_EOF_OP, sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Send", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Send", mpi_code); } /* Wait for EOF communication to complete */ H5_GCC_DIAG_OFF("stringop-overflow") if (MPI_SUCCESS != (mpi_code = MPI_Waitall(num_subfiles, recv_reqs, MPI_STATUSES_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Waitall", mpi_code); H5_GCC_DIAG_ON("stringop-overflow") for (int i = 0; i < num_subfiles; i++) { @@ -358,55 +331,47 @@ H5FD__subfiling__get_real_eof(hid_t context_id, int64_t *logical_eof_ptr) sf_eofs[i] = recv_msg[(3 * i) + 1]; } - /* 4) After all IOCs have replied, compute the offset of - * each subfile in the logical file. Take the maximum - * of these values, and report this value as the overall - * EOF. + /* After all IOCs have replied, compute the offset of each subfile in the + * logical file. Take the maximum of these values, and report this value + * as the overall EOF. */ for (int i = 0; i < num_subfiles; i++) { - - /* compute number of complete stripes */ + /* Compute number of complete stripes */ sf_logical_eof = sf_eofs[i] / sf_context->sf_stripe_size; - /* multiply by stripe size */ + /* Multiply by stripe size */ sf_logical_eof *= sf_context->sf_stripe_size * num_subfiles; - /* if the subfile doesn't end on a stripe size boundary, must add in a partial stripe */ + /* If the subfile doesn't end on a stripe size boundary, must add in a partial stripe */ if (sf_eofs[i] % sf_context->sf_stripe_size > 0) { - - /* add in the size of the partial stripe up to but not including this subfile */ + /* Add in the size of the partial stripe up to but not including this subfile */ sf_logical_eof += i * sf_context->sf_stripe_size; - /* finally, add in the number of bytes in the last partial stripe depth in the subfile */ + /* Finally, add in the number of bytes in the last partial stripe depth in the subfile */ sf_logical_eof += sf_eofs[i] % sf_context->sf_stripe_size; } - if (sf_logical_eof > logical_eof) { - + if (sf_logical_eof > logical_eof) logical_eof = sf_logical_eof; - } } #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(context_id, "%s: calculated logical EOF = %" PRId64 ".", __func__, logical_eof); + H5FD__subfiling_log(context_id, "%s: calculated logical EOF = %" PRId64 ".", __func__, logical_eof); #endif *logical_eof_ptr = logical_eof; done: - if (ret_value < 0) { - for (int i = 0; i < num_subfiles; i++) { - if (recv_reqs && (recv_reqs[i] != MPI_REQUEST_NULL)) { + if (ret_value < 0) + for (int i = 0; i < num_subfiles; i++) + if (recv_reqs && (recv_reqs[i] != MPI_REQUEST_NULL)) if (MPI_SUCCESS != (mpi_code = MPI_Cancel(&recv_reqs[i]))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Cancel", mpi_code); - } - } - } + HMPI_DONE_ERROR(FAIL, "MPI_Cancel", mpi_code); - free(recv_msg); - free(recv_reqs); - free(sf_eofs); + H5MM_free(recv_msg); + H5MM_free(recv_reqs); + H5MM_free(sf_eofs); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* H5FD__subfiling__get_real_eof() */ diff --git a/src/H5FDsubfiling/H5FDsubfiling.c b/src/H5FDsubfiling/H5FDsubfiling.c index 6fbd3696200..affcfcbe94a 100644 --- a/src/H5FDsubfiling/H5FDsubfiling.c +++ b/src/H5FDsubfiling/H5FDsubfiling.c @@ -79,7 +79,7 @@ static bool H5FD_mpi_self_initialized = false; * Document additional subfiling fields here. * * Recall that the existing fields are inherited from the sec2 driver - * and should be kept or not as appropriate for the sub-filing VFD. + * and should be kept or not as appropriate for the subfiling VFD. * * ***************************************************************************/ @@ -178,110 +178,109 @@ static herr_t H5FD__subfiling_read_vector(H5FD_t *file, hid_t dxpl_id, uint32_t static herr_t H5FD__subfiling_write_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 */); static herr_t H5FD__subfiling_truncate(H5FD_t *_file, hid_t dxpl_id, bool closing); -#if 0 -static herr_t H5FD__subfiling_lock(H5FD_t *_file, bool rw); -static herr_t H5FD__subfiling_unlock(H5FD_t *_file); -#endif -static herr_t H5FD__subfiling_del(const char *name, hid_t fapl); -static herr_t H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, - void **output); +static herr_t H5FD__subfiling_del(const char *name, hid_t fapl); +static herr_t H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *input, + void **output); static herr_t H5FD__subfiling_get_default_config(hid_t fapl_id, H5FD_subfiling_config_t *config_out); static herr_t H5FD__subfiling_validate_config(const H5FD_subfiling_config_t *fa); -static int H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr); +static herr_t H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr); -static herr_t H5FD__subfiling_close_int(H5FD_subfiling_t *file_ptr); +static herr_t H5FD__subfiling_close_int(H5FD_subfiling_t *file); -static herr_t H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_t types[], +static herr_t H5FD__subfiling_io_helper(H5FD_subfiling_t *file, size_t io_count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], H5_flexible_const_ptr_t bufs[], H5FD_subfiling_io_type_t io_type); -static herr_t H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count, +static herr_t H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[]); -static herr_t generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t types[], - haddr_t file_offsets[], size_t nelemts[], H5_flexible_const_ptr_t bufs[], - size_t dtype_extent, H5FD_subfiling_io_type_t io_type, size_t *ioreq_count, - uint32_t *iovec_len, H5FD_mem_t **io_types, haddr_t **io_addrs, - size_t **io_sizes, H5_flexible_const_ptr_t **io_bufs); -static void get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_offsets[], - size_t nelemts[], size_t dtype_extent, size_t *max_iovec_depth, - size_t *max_num_subfiles); -static herr_t translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, size_t iovec_len, - size_t iovec_count, H5FD_mem_t type, haddr_t addr, size_t io_size, - H5_flexible_const_ptr_t io_buf, H5FD_subfiling_io_type_t io_type, - H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, - H5_flexible_const_ptr_t *io_bufs); -static herr_t iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t first_io_len, H5_flexible_const_ptr_t buf, - H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, - H5_flexible_const_ptr_t *io_bufs_ptr); -static herr_t iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t last_io_len, H5_flexible_const_ptr_t buf, - H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, - H5_flexible_const_ptr_t *io_bufs_ptr); -static herr_t iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, - int64_t cur_iovec_depth, int64_t target_datasize, - int64_t start_mem_offset, int64_t start_file_offset, int64_t first_io_len, - int64_t last_io_len, H5_flexible_const_ptr_t buf, - H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, - size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); -static herr_t iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, - haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, - H5_flexible_const_ptr_t *io_bufs_ptr); +static herr_t H5FD__subfiling_generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, + H5FD_mem_t types[], haddr_t file_offsets[], + size_t nelemts[], H5_flexible_const_ptr_t bufs[], + H5FD_subfiling_io_type_t io_type, size_t *ioreq_count, + uint32_t *iovec_len, H5FD_mem_t **io_types, + haddr_t **io_addrs, size_t **io_sizes, + H5_flexible_const_ptr_t **io_bufs); +static void H5FD__subfiling_get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, + haddr_t file_offsets[], size_t nelemts[], size_t *max_iovec_depth, + size_t *max_num_subfiles); +static herr_t H5FD__subfiling_translate_io_req_to_iovec( + subfiling_context_t *sf_context, size_t iovec_idx, size_t iovec_len, size_t iovec_count, H5FD_mem_t type, + haddr_t addr, size_t io_size, H5_flexible_const_ptr_t io_buf, H5FD_subfiling_io_type_t io_type, + H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs); +static herr_t H5FD__subfiling_iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, + int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, + int64_t first_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); +static herr_t H5FD__subfiling_iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, + int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, + int64_t last_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); +static herr_t H5FD__subfiling_iovec_fill_first_last( + subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, int64_t first_io_len, int64_t last_io_len, + H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); +static herr_t H5FD__subfiling_iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, + int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, + H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr); #ifdef H5_SUBFILING_DEBUG -void H5_subfiling_dump_iovecs(subfiling_context_t *sf_context, size_t ioreq_count, size_t iovec_len, - H5FD_subfiling_io_type_t io_type, H5FD_mem_t *io_types, haddr_t *io_addrs, - size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs); +static void H5_subfiling_dump_iovecs(subfiling_context_t *sf_context, size_t ioreq_count, size_t iovec_len, + H5FD_subfiling_io_type_t io_type, H5FD_mem_t *io_types, + haddr_t *io_addrs, size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs); #endif void H5FD__subfiling_mpi_finalize(void); static const H5FD_class_t H5FD_subfiling_g = { - H5FD_CLASS_VERSION, /* VFD interface version */ - H5_VFD_SUBFILING, /* value */ - H5FD_SUBFILING_NAME, /* name */ - MAXADDR, /* maxaddr */ - H5F_CLOSE_WEAK, /* fc_degree */ - H5FD__subfiling_term, /* terminate */ - H5FD__subfiling_sb_size, /* sb_size */ - H5FD__subfiling_sb_encode, /* sb_encode */ - H5FD__subfiling_sb_decode, /* sb_decode */ - sizeof(H5FD_subfiling_config_t), /* fapl_size */ - H5FD__subfiling_fapl_get, /* fapl_get */ - H5FD__subfiling_fapl_copy, /* fapl_copy */ - H5FD__subfiling_fapl_free, /* fapl_free */ - 0, /* dxpl_size */ - NULL, /* dxpl_copy */ - NULL, /* dxpl_free */ - H5FD__subfiling_open, /* open */ - H5FD__subfiling_close, /* close */ - H5FD__subfiling_cmp, /* cmp */ - H5FD__subfiling_query, /* query */ - NULL, /* get_type_map */ - NULL, /* alloc */ - NULL, /* free */ - H5FD__subfiling_get_eoa, /* get_eoa */ - H5FD__subfiling_set_eoa, /* set_eoa */ - H5FD__subfiling_get_eof, /* get_eof */ - H5FD__subfiling_get_handle, /* get_handle */ - H5FD__subfiling_read, /* read */ - H5FD__subfiling_write, /* write */ - H5FD__subfiling_read_vector, /* read_vector */ - H5FD__subfiling_write_vector, /* write_vector */ - NULL, /* read_selection */ - NULL, /* write_selection */ - NULL, /* flush */ - H5FD__subfiling_truncate, /* truncate */ - NULL /* H5FD__subfiling_lock */, /* lock */ - NULL /* H5FD__subfiling_unlock */, /* unlock */ - H5FD__subfiling_del, /* del */ - H5FD__subfiling_ctl, /* ctl */ - H5FD_FLMAP_DICHOTOMY /* fl_map */ + H5FD_CLASS_VERSION, /* VFD interface version */ + H5_VFD_SUBFILING, /* value */ + H5FD_SUBFILING_NAME, /* name */ + MAXADDR, /* maxaddr */ + H5F_CLOSE_WEAK, /* fc_degree */ + H5FD__subfiling_term, /* terminate */ + H5FD__subfiling_sb_size, /* sb_size */ + H5FD__subfiling_sb_encode, /* sb_encode */ + H5FD__subfiling_sb_decode, /* sb_decode */ + sizeof(H5FD_subfiling_config_t), /* fapl_size */ + H5FD__subfiling_fapl_get, /* fapl_get */ + H5FD__subfiling_fapl_copy, /* fapl_copy */ + H5FD__subfiling_fapl_free, /* fapl_free */ + 0, /* dxpl_size */ + NULL, /* dxpl_copy */ + NULL, /* dxpl_free */ + H5FD__subfiling_open, /* open */ + H5FD__subfiling_close, /* close */ + H5FD__subfiling_cmp, /* cmp */ + H5FD__subfiling_query, /* query */ + NULL, /* get_type_map */ + NULL, /* alloc */ + NULL, /* free */ + H5FD__subfiling_get_eoa, /* get_eoa */ + H5FD__subfiling_set_eoa, /* set_eoa */ + H5FD__subfiling_get_eof, /* get_eof */ + H5FD__subfiling_get_handle, /* get_handle */ + H5FD__subfiling_read, /* read */ + H5FD__subfiling_write, /* write */ + H5FD__subfiling_read_vector, /* read_vector */ + H5FD__subfiling_write_vector, /* write_vector */ + NULL, /* read_selection */ + NULL, /* write_selection */ + NULL, /* flush */ + H5FD__subfiling_truncate, /* truncate */ + NULL, /* lock */ + NULL, /* unlock */ + H5FD__subfiling_del, /* del */ + H5FD__subfiling_ctl, /* ctl */ + H5FD_FLMAP_DICHOTOMY /* fl_map */ }; /* Declare a free list to manage the H5FD_subfiling_t struct */ @@ -295,8 +294,17 @@ H5FL_DEFINE_STATIC(H5FD_subfiling_t); void H5FD__subfiling_mpi_finalize(void) { - H5close(); + /* + * Don't call normal FUNC_ENTER() since we don't want to initialize the + * whole library just to release it all right away. It is safe to call + * this function for an uninitialized library. + */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + H5_term_library(); MPI_Finalize(); + + FUNC_LEAVE_NOAPI_VOID } /*------------------------------------------------------------------------- @@ -315,6 +323,8 @@ H5FD_subfiling_init(void) { hid_t ret_value = H5I_INVALID_HID; /* Return value */ + FUNC_ENTER_NOAPI(H5I_INVALID_HID) + /* Register the Subfiling VFD, if it isn't already registered */ if (H5I_VFL != H5I_get_type(H5FD_SUBFILING_g)) { int mpi_initialized = 0; @@ -322,44 +332,34 @@ H5FD_subfiling_init(void) int mpi_code; if ((H5FD_SUBFILING_g = H5FD_register(&H5FD_subfiling_g, sizeof(H5FD_class_t), false)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, - "can't register subfiling VFD"); - - /* Initialize error reporting */ - if ((H5subfiling_err_stack_g = H5Ecreate_stack()) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, "can't create HDF5 error stack"); - if ((H5subfiling_err_class_g = H5Eregister_class(H5SUBFILING_ERR_CLS_NAME, H5SUBFILING_ERR_LIB_NAME, - H5SUBFILING_ERR_VER)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "can't register error class with HDF5 error API"); + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register subfiling VFD"); /* Initialize MPI if not already initialized */ if (MPI_SUCCESS != (mpi_code = MPI_Initialized(&mpi_initialized))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Initialized failed", mpi_code); if (mpi_initialized) { /* If MPI is initialized, validate that it was initialized with MPI_THREAD_MULTIPLE */ if (MPI_SUCCESS != (mpi_code = MPI_Query_thread(&provided))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Query_thread failed", mpi_code); if (provided != MPI_THREAD_MULTIPLE) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "Subfiling VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "Subfiling VFD requires the use of MPI_Init_thread with MPI_THREAD_MULTIPLE"); } else { int required = MPI_THREAD_MULTIPLE; if (MPI_SUCCESS != (mpi_code = MPI_Init_thread(NULL, NULL, required, &provided))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Init_thread failed", mpi_code); H5FD_mpi_self_initialized = true; if (provided != required) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "MPI doesn't support MPI_Init_thread with MPI_THREAD_MULTIPLE"); if (atexit(H5FD__subfiling_mpi_finalize) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, - "can't register atexit handler for MPI_Finalize"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, H5I_INVALID_HID, + "can't register atexit handler for MPI_Finalize"); } /* @@ -369,9 +369,9 @@ H5FD_subfiling_init(void) HDcompile_assert(sizeof(((sf_work_request_t *)NULL)->header) == 3 * sizeof(int64_t)); if (H5_subfiling_rpc_msg_type == MPI_DATATYPE_NULL) { if (MPI_SUCCESS != (mpi_code = MPI_Type_contiguous(3, MPI_INT64_T, &H5_subfiling_rpc_msg_type))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_contiguous failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_contiguous failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Type_commit(&H5_subfiling_rpc_msg_type))) - H5_SUBFILING_MPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_commit failed", mpi_code); + HMPI_GOTO_ERROR(H5I_INVALID_HID, "MPI_Type_commit failed", mpi_code); } } @@ -379,7 +379,7 @@ H5FD_subfiling_init(void) ret_value = H5FD_SUBFILING_g; done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_subfiling_init() */ /*--------------------------------------------------------------------------- @@ -396,6 +396,8 @@ H5FD__subfiling_term(void) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (H5FD_SUBFILING_g >= 0) { int mpi_finalized; int mpi_code; @@ -406,52 +408,31 @@ H5FD__subfiling_term(void) * shuts down after MPI_Finalize() is called in an application. */ if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); /* Free RPC message MPI Datatype */ if (H5_subfiling_rpc_msg_type != MPI_DATATYPE_NULL) { if (!mpi_finalized) { if (MPI_SUCCESS != (mpi_code = MPI_Type_free(&H5_subfiling_rpc_msg_type))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Type_free failed", mpi_code); } #ifdef H5_SUBFILING_DEBUG else - printf("** WARNING **: HDF5 is terminating the Subfiling VFD after MPI_Finalize() was " - "called - an HDF5 ID was probably left unclosed\n"); + printf("** WARNING **: HDF5 is terminating the Subfiling VFD after MPI_Finalize() was called " + "- an HDF5 ID was probably left unclosed\n"); #endif } /* Clean up resources */ - if (H5_subfiling_terminate() < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "can't cleanup internal subfiling resources"); - - /* Unregister from HDF5 error API */ - if (H5subfiling_err_class_g >= 0) { - if (H5Eunregister_class(H5subfiling_err_class_g) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CLOSEERROR, FAIL, - "can't unregister error class from HDF5 error API"); - } - if (H5subfiling_err_stack_g >= 0) { - /* Print the current error stack before destroying it */ - PRINT_ERROR_STACK; - - /* Destroy the error stack */ - if (H5Eclose_stack(H5subfiling_err_stack_g) < 0) { - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CLOSEERROR, FAIL, "can't close HDF5 error stack"); - PRINT_ERROR_STACK; - } /* end if */ - - H5subfiling_err_stack_g = H5I_INVALID_HID; - H5subfiling_err_class_g = H5I_INVALID_HID; - } + if (H5FD__subfiling_terminate() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't cleanup internal subfiling resources"); } done: /* Reset VFL ID */ H5FD_SUBFILING_g = H5I_INVALID_HID; - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_term() */ /*------------------------------------------------------------------------- @@ -478,66 +459,64 @@ H5Pset_fapl_subfiling(hid_t fapl_id, const H5FD_subfiling_config_t *vfd_config) MPI_Info info = MPI_INFO_NULL; herr_t ret_value = SUCCEED; + FUNC_ENTER_API(FAIL) + /* Ensure Subfiling (and therefore MPI) is initialized before doing anything */ if (H5FD_subfiling_init() < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize subfiling VFD"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize subfiling VFD"); if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); if (vfd_config == NULL) { - if (NULL == (subfiling_conf = calloc(1, sizeof(*subfiling_conf)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate subfiling VFD configuration"); - subfiling_conf->ioc_fapl_id = H5I_INVALID_HID; + if (NULL == (subfiling_conf = H5MM_calloc(sizeof(*subfiling_conf)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfiling VFD configuration"); /* Get subfiling VFD defaults */ if (H5FD__subfiling_get_default_config(fapl_id, subfiling_conf) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, - "can't get default subfiling VFD configuration"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't get default subfiling VFD configuration"); vfd_config = subfiling_conf; } /* Check if any MPI parameters were set on the FAPL */ if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI communicator from plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI communicator from plist"); if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI info from plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI info from plist"); if (comm == MPI_COMM_NULL) comm = MPI_COMM_WORLD; /* Set MPI parameters on IOC FAPL */ if (NULL == (ioc_plist = H5P_object_verify(vfd_config->ioc_fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, FAIL, "not a file access property list"); if (H5P_set(ioc_plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI communicator on plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI communicator on plist"); if (H5P_set(ioc_plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI info on plist"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI info on plist"); if (H5FD__subfiling_validate_config(vfd_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling VFD configuration"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling VFD configuration"); /* Set Subfiling configuration on IOC FAPL */ - if (H5_subfiling_set_config_prop(ioc_plist, &vfd_config->shared_cfg) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, - "can't set subfiling configuration on IOC FAPL"); + if (H5FD__subfiling_set_config_prop(ioc_plist, &vfd_config->shared_cfg) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set subfiling configuration on IOC FAPL"); ret_value = H5P_set_driver(plist, H5FD_SUBFILING, vfd_config, NULL); done: if (H5_mpi_comm_free(&comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Communicator"); if (H5_mpi_info_free(&info) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Info object"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Info object"); if (subfiling_conf) { if (subfiling_conf->ioc_fapl_id >= 0 && H5I_dec_ref(subfiling_conf->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); - free(subfiling_conf); + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); + H5MM_free(subfiling_conf); } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_API(ret_value) } /* end H5Pset_fapl_subfiling() */ /*------------------------------------------------------------------------- @@ -553,50 +532,52 @@ H5Pset_fapl_subfiling(hid_t fapl_id, const H5FD_subfiling_config_t *vfd_config) herr_t H5Pget_fapl_subfiling(hid_t fapl_id, H5FD_subfiling_config_t *config_out) { - const H5FD_subfiling_config_t *config_ptr = NULL; + const H5FD_subfiling_config_t *config = NULL; H5P_genplist_t *plist = NULL; bool use_default_config = false; herr_t ret_value = SUCCEED; - if (config_out == NULL) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_out is NULL"); + FUNC_ENTER_API(FAIL) + if (config_out == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "config_out is NULL"); if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); if (H5FD_SUBFILING != H5P_peek_driver(plist)) use_default_config = true; else { - config_ptr = H5P_peek_driver_info(plist); - if (NULL == config_ptr) + if (NULL == (config = H5P_peek_driver_info(plist))) use_default_config = true; } if (use_default_config) { if (H5FD__subfiling_get_default_config(fapl_id, config_out) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't get default Subfiling VFD configuration"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default Subfiling VFD configuration"); } else { /* Copy the subfiling fapl data out */ - H5MM_memcpy(config_out, config_ptr, sizeof(H5FD_subfiling_config_t)); + H5MM_memcpy(config_out, config, sizeof(H5FD_subfiling_config_t)); /* Copy the driver info value */ - if (H5FD__copy_plist(config_ptr->ioc_fapl_id, &(config_out->ioc_fapl_id)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't copy IOC FAPL"); + if (H5FD__copy_plist(config->ioc_fapl_id, &(config_out->ioc_fapl_id)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "can't copy IOC FAPL"); } done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_API(ret_value) } /* end H5Pget_fapl_subfiling() */ static herr_t H5FD__subfiling_get_default_config(hid_t fapl_id, H5FD_subfiling_config_t *config_out) { - MPI_Comm comm = MPI_COMM_NULL; - MPI_Info info = MPI_INFO_NULL; - char *h5_require_ioc; - herr_t ret_value = SUCCEED; + H5P_genplist_t *plist; /* Property list pointer */ + MPI_Comm comm = MPI_COMM_NULL; + MPI_Info info = MPI_INFO_NULL; + char *h5_require_ioc; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE assert(config_out); @@ -618,45 +599,59 @@ H5FD__subfiling_get_default_config(hid_t fapl_id, H5FD_subfiling_config_t *confi } /* Check if any MPI parameters were set on the FAPL */ - if (H5Pget_mpi_params(fapl_id, &comm, &info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI Comm/Info"); + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADID, FAIL, "can't find object for ID"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI communicator from plist"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get MPI info from plist"); if (comm == MPI_COMM_NULL) { comm = MPI_COMM_WORLD; /* Set MPI_COMM_WORLD on FAPL if no MPI parameters were set */ - if (H5Pset_mpi_params(fapl_id, comm, info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI Comm/Info"); + if (H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI communicator"); + if (H5P_set(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI info object"); } /* Create a default FAPL and choose an appropriate underlying driver */ - if ((config_out->ioc_fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "can't create default FAPL"); + if (H5FD__copy_plist(H5P_FILE_ACCESS_DEFAULT, &config_out->ioc_fapl_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTCREATE, FAIL, "can't create default FAPL"); + if (NULL == (plist = (H5P_genplist_t *)H5I_object(config_out->ioc_fapl_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADID, FAIL, "can't find object for ID"); if (config_out->require_ioc) { - if (H5Pset_mpi_params(config_out->ioc_fapl_id, comm, info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't get MPI Comm/Info on IOC FAPL"); + H5FD_ioc_config_t ioc_config; - if (H5Pset_fapl_ioc(config_out->ioc_fapl_id, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set IOC VFD on IOC FAPL"); + if (H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI communicator"); + if (H5P_set(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI info object"); + + if (H5FD__subfiling_get_default_ioc_config(&ioc_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default IOC config"); + if (H5P_set_driver(plist, H5FD_IOC, &ioc_config, NULL) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set IOC VFD on IOC FAPL"); } else { - if (H5Pset_fapl_sec2(config_out->ioc_fapl_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set Sec2 VFD on IOC FAPL"); + if (H5P_set_driver(plist, H5FD_SEC2, NULL, NULL) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set sec2 VFD on IOC FAPL"); } done: if (H5_mpi_comm_free(&comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Communicator"); if (H5_mpi_info_free(&info) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Info object"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI Info object"); if (ret_value < 0) { - if (config_out->ioc_fapl_id >= 0 && H5Pclose(config_out->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "can't close FAPL"); + if (config_out->ioc_fapl_id >= 0 && H5I_dec_ref(config_out->ioc_fapl_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close FAPL"); config_out->ioc_fapl_id = H5I_INVALID_HID; } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -681,26 +676,24 @@ H5FD__subfiling_validate_config(const H5FD_subfiling_config_t *fa) { herr_t ret_value = SUCCEED; - assert(fa != NULL); + FUNC_ENTER_PACKAGE - if (fa->version != H5FD_SUBFILING_CURR_FAPL_VERSION) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown H5FD_subfiling_config_t version"); + assert(fa != NULL); if (fa->magic != H5FD_SUBFILING_FAPL_MAGIC) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5FD_subfiling_config_t magic value"); - + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5FD_subfiling_config_t magic value"); + if (fa->version != H5FD_SUBFILING_CURR_FAPL_VERSION) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown H5FD_subfiling_config_t version"); if (fa->ioc_fapl_id < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC FAPL ID"); - + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC FAPL ID"); if (!fa->require_ioc) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "Subfiling VFD currently always requires IOC VFD to be used"); - - if (H5_subfiling_validate_config(&fa->shared_cfg) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration parameters"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "Subfiling VFD currently always requires IOC VFD to be used"); + if (H5FD__subfiling_validate_config_params(&fa->shared_cfg) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration parameters"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_validate_config() */ /*------------------------------------------------------------------------- @@ -719,6 +712,8 @@ H5FD__subfiling_sb_size(H5FD_t *_file) H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; hsize_t ret_value = 0; + FUNC_ENTER_PACKAGE_NOERR + assert(file); /* Configuration structure magic number */ @@ -745,13 +740,11 @@ H5FD__subfiling_sb_size(H5FD_t *_file) * to retrieve the context object here so we can check for * errors later. */ - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) { + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) file->fail_to_encode = true; - } else { - if (sf_context->config_file_prefix) { + if (sf_context->config_file_prefix) ret_value += strlen(sf_context->config_file_prefix) + 1; - } } /* Add superblock information from IOC file if necessary */ @@ -772,7 +765,7 @@ H5FD__subfiling_sb_size(H5FD_t *_file) if (ret_value > H5FD_SUBFILING_MAX_DRV_INFO_SIZE) file->fail_to_encode = true; - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_sb_size() */ /*------------------------------------------------------------------------- @@ -796,14 +789,16 @@ H5FD__subfiling_sb_encode(H5FD_t *_file, char *name, unsigned char *buf) size_t prefix_len = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + /* Check if the "fail to encode flag" is set */ if (file->fail_to_encode) - H5_SUBFILING_GOTO_ERROR( + HGOTO_ERROR( H5E_VFL, H5E_CANTENCODE, FAIL, "can't encode subfiling driver info message - message was too large or internal error occurred"); - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); /* Encode driver name */ strncpy(name, "Subfilin", 9); @@ -842,21 +837,12 @@ H5FD__subfiling_sb_encode(H5FD_t *_file, char *name, unsigned char *buf) } /* Encode IOC VFD configuration information if necessary */ - if (file->sf_file) { - char ioc_name[9]; - - memset(ioc_name, 0, sizeof(ioc_name)); - - if (H5FD_sb_encode(file->sf_file, ioc_name, p + 9) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTENCODE, FAIL, - "unable to encode IOC VFD's superblock information"); - - /* Copy the IOC VFD's name into our buffer */ - H5MM_memcpy(p, ioc_name, 9); - } + if (file->sf_file) + if (H5FD_sb_encode(file->sf_file, (char *)p, p + 9) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTENCODE, FAIL, "unable to encode IOC VFD's superblock information"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_sb_encode() */ /*------------------------------------------------------------------------- @@ -879,17 +865,19 @@ H5FD__subfiling_sb_decode(H5FD_t *_file, const char *name, const unsigned char * int32_t tmp32; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + /* Check if we previously failed to encode the info */ if (file->fail_to_encode) - H5_SUBFILING_GOTO_ERROR( + HGOTO_ERROR( H5E_VFL, H5E_CANTDECODE, FAIL, "can't decode subfiling driver info message - message wasn't encoded (or encoded improperly)"); - if (NULL == (sf_context = H5_get_subfiling_object(file->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); + if (NULL == (sf_context = H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling context object"); if (strncmp(name, "Subfilin", 9)) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver name in superblock"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid driver name in superblock"); /* Decode configuration structure magic number */ UINT32DECODE(p, file->fa.magic); @@ -915,9 +903,9 @@ H5FD__subfiling_sb_decode(H5FD_t *_file, const char *name, const unsigned char * /* Decode config file prefix string */ if (tmpu64 > 0) { if (!sf_context->config_file_prefix) { - if (NULL == (sf_context->config_file_prefix = malloc(tmpu64))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate space for config file prefix string"); + if (NULL == (sf_context->config_file_prefix = H5MM_malloc(tmpu64))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "can't allocate space for config file prefix string"); H5MM_memcpy(sf_context->config_file_prefix, p, tmpu64); @@ -928,36 +916,27 @@ H5FD__subfiling_sb_decode(H5FD_t *_file, const char *name, const unsigned char * p += tmpu64; } - if (file->sf_file) { - char ioc_name[9]; - - H5MM_memcpy(ioc_name, p, 9); - p += 9; - - if (H5FD_sb_load(file->sf_file, ioc_name, p) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTDECODE, FAIL, - "unable to decode IOC VFD's superblock information"); - } + if (file->sf_file) + if (H5FD_sb_load(file->sf_file, (const char *)p, p + 9) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTDECODE, FAIL, "unable to decode IOC VFD's superblock information"); /* Validate the decoded configuration */ if (H5FD__subfiling_validate_config(&file->fa) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "decoded subfiling configuration info is invalid"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "decoded subfiling configuration info is invalid"); if (file->fa.shared_cfg.stripe_size != sf_context->sf_stripe_size) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "specified subfiling stripe size (%" PRId64 - ") doesn't match value stored in file (%" PRId64 ")", - sf_context->sf_stripe_size, file->fa.shared_cfg.stripe_size); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "specified subfiling stripe size (%" PRId64 + ") doesn't match value stored in file (%" PRId64 ")", + sf_context->sf_stripe_size, file->fa.shared_cfg.stripe_size); if (file->fa.shared_cfg.stripe_count != sf_context->sf_num_subfiles) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_BADVALUE, FAIL, - "specified subfiling stripe count (%d) doesn't match value stored in file (%" PRId32 ")", - sf_context->sf_num_subfiles, file->fa.shared_cfg.stripe_count); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "specified subfiling stripe count (%d) doesn't match value stored in file (%" PRId32 ")", + sf_context->sf_num_subfiles, file->fa.shared_cfg.stripe_count); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_sb_decode() */ /*------------------------------------------------------------------------- @@ -967,7 +946,6 @@ H5FD__subfiling_sb_decode(H5FD_t *_file, const char *name, const unsigned char * * create an identical file. * * Return: Success: Ptr to new file access property list value. - * * Failure: NULL * *------------------------------------------------------------------------- @@ -979,31 +957,27 @@ H5FD__subfiling_fapl_get(H5FD_t *_file) H5FD_subfiling_config_t *fa = NULL; void *ret_value = NULL; - fa = (H5FD_subfiling_config_t *)H5MM_calloc(sizeof(H5FD_subfiling_config_t)); + FUNC_ENTER_PACKAGE - if (fa == NULL) { - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - } + if (NULL == (fa = H5MM_calloc(sizeof(H5FD_subfiling_config_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "memory allocation failed"); /* Copy the fields of the structure */ - H5MM_memcpy(fa, &(file->fa), sizeof(H5FD_subfiling_config_t)); + H5MM_memcpy(fa, &file->fa, sizeof(H5FD_subfiling_config_t)); /* Copy the driver info value */ - if (H5FD__copy_plist(file->fa.ioc_fapl_id, &(fa->ioc_fapl_id)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy IOC FAPL"); + if (H5FD__copy_plist(file->fa.ioc_fapl_id, &fa->ioc_fapl_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy IOC FAPL"); /* Set return value */ ret_value = fa; done: - if (ret_value == NULL) { - - if (fa != NULL) { + if (ret_value == NULL) + if (fa != NULL) H5MM_xfree(fa); - } - } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_fapl_get() */ /*------------------------------------------------------------------------- @@ -1012,31 +986,30 @@ H5FD__subfiling_fapl_get(H5FD_t *_file) * Purpose: Sanity-wrapped H5P_copy_plist() for each channel. * Utility function for operation in multiple locations. * - * Return: 0 on success, -1 on error. + * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- */ -/* TODO: no need for this function */ -static int -H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr) +static herr_t +H5FD__copy_plist(hid_t fapl_id, hid_t *id) { - int ret_value = 0; - H5P_genplist_t *plist_ptr = NULL; + H5P_genplist_t *plist = NULL; + int ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE - assert(id_out_ptr != NULL); + assert(id != NULL); if (false == H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, -1, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); - plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id); - if (NULL == plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, -1, "unable to get property list"); + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to get property list"); - *id_out_ptr = H5P_copy_plist(plist_ptr, false); - if (H5I_INVALID_HID == *id_out_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADTYPE, -1, "unable to copy file access property list"); + if (H5I_INVALID_HID == (*id = H5P_copy_plist(plist, false))) + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, FAIL, "unable to copy file access property list"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__copy_plist() */ /*------------------------------------------------------------------------- @@ -1045,7 +1018,6 @@ H5FD__copy_plist(hid_t fapl_id, hid_t *id_out_ptr) * Purpose: Copies the subfiling-specific file access properties. * * Return: Success: Ptr to a new property list - * * Failure: NULL * *------------------------------------------------------------------------- @@ -1057,27 +1029,24 @@ H5FD__subfiling_fapl_copy(const void *_old_fa) H5FD_subfiling_config_t *new_fa = NULL; void *ret_value = NULL; - new_fa = (H5FD_subfiling_config_t *)H5MM_malloc(sizeof(H5FD_subfiling_config_t)); - if (new_fa == NULL) { - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - } + FUNC_ENTER_PACKAGE + + if (NULL == (new_fa = H5MM_malloc(sizeof(H5FD_subfiling_config_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "memory allocation failed"); H5MM_memcpy(new_fa, old_fa, sizeof(H5FD_subfiling_config_t)); - if (H5FD__copy_plist(old_fa->ioc_fapl_id, &(new_fa->ioc_fapl_id)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy the IOC FAPL"); + if (H5FD__copy_plist(old_fa->ioc_fapl_id, &new_fa->ioc_fapl_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy the IOC FAPL"); ret_value = new_fa; done: - if (ret_value == NULL) { - - if (new_fa != NULL) { + if (ret_value == NULL) + if (new_fa != NULL) H5MM_xfree(new_fa); - } - } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_fapl_copy() */ /*------------------------------------------------------------------------- @@ -1095,15 +1064,17 @@ H5FD__subfiling_fapl_free(void *_fa) H5FD_subfiling_config_t *fa = (H5FD_subfiling_config_t *)_fa; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(fa != NULL); /* sanity check */ if (fa->ioc_fapl_id >= 0 && H5I_dec_ref(fa->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); fa->ioc_fapl_id = H5I_INVALID_HID; H5MM_xfree(fa); - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_fapl_free() */ /*------------------------------------------------------------------------- @@ -1121,248 +1092,207 @@ H5FD__subfiling_fapl_free(void *_fa) static H5FD_t * H5FD__subfiling_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - H5FD_subfiling_t *file_ptr = NULL; /* Subfiling VFD info */ - const H5FD_subfiling_config_t *config_ptr = NULL; /* Driver-specific property list */ + H5FD_subfiling_t *file = NULL; /* Subfiling VFD info */ + const H5FD_subfiling_config_t *config = NULL; /* Driver-specific property list */ H5FD_subfiling_config_t default_config; - H5FD_class_t *driver = NULL; /* VFD for file */ - H5P_genplist_t *plist_ptr = NULL; + H5FD_class_t *driver = NULL; /* VFD for file */ + H5P_genplist_t *plist = NULL; H5FD_driver_prop_t driver_prop; /* Property for driver ID & info */ bool bcasted_eof = false; int64_t sf_eof = -1; int mpi_code; /* MPI return code */ H5FD_t *ret_value = NULL; + FUNC_ENTER_PACKAGE + /* Check arguments */ if (!name || !*name) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name"); if (0 == maxaddr || HADDR_UNDEF == maxaddr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr"); if (ADDR_OVERFLOW(maxaddr)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); - - if (NULL == (file_ptr = (H5FD_subfiling_t *)H5FL_CALLOC(H5FD_subfiling_t))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); - file_ptr->comm = MPI_COMM_NULL; - file_ptr->info = MPI_INFO_NULL; - file_ptr->file_id = UINT64_MAX; - file_ptr->context_id = -1; - file_ptr->fa.ioc_fapl_id = H5I_INVALID_HID; - file_ptr->ext_comm = MPI_COMM_NULL; - file_ptr->fail_to_encode = false; + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "bogus maxaddr"); + + if (NULL == (file = (H5FD_subfiling_t *)H5FL_CALLOC(H5FD_subfiling_t))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "unable to allocate file struct"); + file->comm = MPI_COMM_NULL; + file->info = MPI_INFO_NULL; + file->file_id = UINT64_MAX; + file->context_id = -1; + file->fa.ioc_fapl_id = H5I_INVALID_HID; + file->ext_comm = MPI_COMM_NULL; + file->fail_to_encode = false; /* Get the driver-specific file access properties */ - if (NULL == (plist_ptr = (H5P_genplist_t *)H5I_object(fapl_id))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a 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"); if (H5FD_mpi_self_initialized) { - file_ptr->comm = MPI_COMM_WORLD; - file_ptr->info = MPI_INFO_NULL; + file->comm = MPI_COMM_WORLD; + file->info = MPI_INFO_NULL; } else { /* Get the MPI communicator and info object from the property list */ - if (H5P_get(plist_ptr, H5F_ACS_MPI_PARAMS_COMM_NAME, &file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator"); - if (H5P_get(plist_ptr, H5F_ACS_MPI_PARAMS_INFO_NAME, &file_ptr->info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &file->comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI communicator"); + if (H5P_get(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &file->info) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get MPI info object"); - if (file_ptr->comm == MPI_COMM_NULL) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid or unset MPI communicator in FAPL"); + if (file->comm == MPI_COMM_NULL) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid or unset MPI communicator in FAPL"); } /* Get the MPI rank of this process and the total number of processes */ - if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_ptr->comm, &file_ptr->mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_ptr->comm, &file_ptr->mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file->comm, &file->mpi_rank))) + HMPI_GOTO_ERROR(NULL, "MPI_Comm_rank failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file->comm, &file->mpi_size))) + HMPI_GOTO_ERROR(NULL, "MPI_Comm_size failed", mpi_code); /* Work around an HDF5 metadata cache bug with distributed metadata writes when MPI size == 1 */ - if (file_ptr->mpi_size == 1) { + if (file->mpi_size == 1) { H5AC_cache_config_t mdc_config; /* Get the current initial metadata cache resize configuration */ - if (H5P_get(plist_ptr, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &mdc_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache initial config"); + if (H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &mdc_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get metadata cache initial config"); mdc_config.metadata_write_strategy = H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY; - if (H5P_set(plist_ptr, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &mdc_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set metadata cache initial config"); + if (H5P_set(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &mdc_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't set metadata cache initial config"); } - config_ptr = H5P_peek_driver_info(plist_ptr); - if (!config_ptr || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) { + config = H5P_peek_driver_info(plist); + if (!config || (H5P_FILE_ACCESS_DEFAULT == fapl_id)) { if (H5FD__subfiling_get_default_config(fapl_id, &default_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, - "can't get default subfiling VFD configuration"); - config_ptr = &default_config; + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default subfiling VFD configuration"); + config = &default_config; } - H5MM_memcpy(&file_ptr->fa, config_ptr, sizeof(H5FD_subfiling_config_t)); - if (H5FD__copy_plist(config_ptr->ioc_fapl_id, &(file_ptr->fa.ioc_fapl_id)) < 0) { - file_ptr->fa.ioc_fapl_id = H5I_INVALID_HID; - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy FAPL"); + H5MM_memcpy(&file->fa, config, sizeof(H5FD_subfiling_config_t)); + if (H5FD__copy_plist(config->ioc_fapl_id, &file->fa.ioc_fapl_id) < 0) { + file->fa.ioc_fapl_id = H5I_INVALID_HID; + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "can't copy FAPL"); } /* Check the "native" driver (IOC/sec2/etc.) */ - if (NULL == (plist_ptr = H5I_object(file_ptr->fa.ioc_fapl_id))) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "invalid IOC FAPL"); + if (NULL == (plist = H5I_object(file->fa.ioc_fapl_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid IOC FAPL"); - if (H5P_peek(plist_ptr, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get driver ID & info"); + if (H5P_peek(plist, H5F_ACS_FILE_DRV_NAME, &driver_prop) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get driver ID & info"); if (NULL == (driver = (H5FD_class_t *)H5I_object(driver_prop.driver_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, - "invalid driver ID in file access property list"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid driver ID in file access property list"); if (driver->value != H5_VFD_IOC) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, - "unable to open file '%s' - only IOC VFD is currently supported for subfiles", - name); + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, + "unable to open file '%s' - only IOC VFD is currently supported for subfiles", name); /* Fully resolve the given filepath and get its dirname */ - if (H5_resolve_pathname(name, file_ptr->comm, &file_ptr->file_path) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't resolve filepath"); - if (H5_dirname(file_ptr->file_path, &file_ptr->file_dir) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get filepath dirname"); + if (H5FD__subfiling_resolve_pathname(name, file->comm, &file->file_path) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't resolve filepath"); + if (H5_dirname(file->file_path, &file->file_dir) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get filepath dirname"); /* * Create/open the HDF5 stub file and get its inode value for * the internal mapping from file inode to subfiling context. */ - if (H5_open_subfiling_stub_file(file_ptr->file_path, flags, file_ptr->comm, &file_ptr->stub_file, - &file_ptr->file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open HDF5 stub file"); + if (H5FD__subfiling_open_stub_file(file->file_path, flags, file->comm, &file->stub_file, &file->file_id) < + 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "can't open HDF5 stub file"); /* Set stub file ID on IOC fapl so it can reuse on open */ - if (H5_subfiling_set_file_id_prop(plist_ptr, file_ptr->file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set stub file ID on FAPL"); + if (H5FD__subfiling_set_file_id_prop(plist, file->file_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, NULL, "can't set stub file ID on FAPL"); /* Open the HDF5 file's subfiles */ - if (H5FD_open(false, &file_ptr->sf_file, name, flags, file_ptr->fa.ioc_fapl_id, HADDR_UNDEF) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open IOC file"); - - if (driver->value == H5_VFD_IOC) { - /* Get a copy of the context ID for later use */ - if (H5_subfile_fid_to_context(file_ptr->file_id, &file_ptr->context_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, - "unable to retrieve subfiling context ID for this file"); - file_ptr->fa.require_ioc = true; - } - else if (driver->value == H5_VFD_SEC2) { - int ioc_flags; - - /* Translate the HDF5 file open flags into standard POSIX open flags */ - ioc_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; - if (H5F_ACC_TRUNC & flags) - ioc_flags |= O_TRUNC; - if (H5F_ACC_CREAT & flags) - ioc_flags |= O_CREAT; - if (H5F_ACC_EXCL & flags) - ioc_flags |= O_EXCL; + if (H5FD_open(false, &file->sf_file, name, flags, file->fa.ioc_fapl_id, HADDR_UNDEF) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "unable to open IOC file"); - /* - * Open the subfiles for this HDF5 file. A subfiling - * context ID will be returned, which is used for - * further interactions with this file's subfiles. - */ - if (H5_open_subfiles(file_ptr->file_path, file_ptr->file_id, &file_ptr->fa.shared_cfg, ioc_flags, - file_ptr->comm, &file_ptr->context_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open subfiling files = %s\n", - name); - } + /* Get a copy of the context ID for later use */ + if (H5FD__subfile_fid_to_context(file->file_id, &file->context_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "unable to retrieve subfiling context ID for this file"); + file->fa.require_ioc = true; - if (file_ptr->mpi_rank == 0) { - if (H5FD__subfiling__get_real_eof(file_ptr->context_id, &sf_eof) < 0) + if (file->mpi_rank == 0) + if (H5FD__subfiling__get_real_eof(file->context_id, &sf_eof) < 0) sf_eof = -1; - } - - if (file_ptr->mpi_size > 1) { - if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file_ptr->comm))) - H5_SUBFILING_MPI_GOTO_ERROR(NULL, "MPI_Bcast", mpi_code); - } - + if (file->mpi_size > 1) + if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file->comm))) + HMPI_GOTO_ERROR(NULL, "MPI_Bcast", mpi_code); bcasted_eof = true; - if (sf_eof < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "lead MPI process failed to get file EOF"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "lead MPI process failed to get file EOF"); - file_ptr->eof = (haddr_t)sf_eof; - file_ptr->local_eof = file_ptr->eof; + file->eof = (haddr_t)sf_eof; + file->local_eof = file->eof; - ret_value = (H5FD_t *)file_ptr; + ret_value = (H5FD_t *)file; done: - if (config_ptr == &default_config) - if (H5I_dec_ref(config_ptr->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, NULL, "can't close IOC FAPL"); + if (config == &default_config) + if (H5I_dec_ref(config->ioc_fapl_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEOBJ, NULL, "can't close IOC FAPL"); - if (NULL == ret_value) { - if (file_ptr) { + if (NULL == ret_value) + if (file) { /* Participate in possible MPI collectives on failure */ - if (file_ptr->comm != MPI_COMM_NULL) { + if (file->comm != MPI_COMM_NULL) if (!bcasted_eof) { sf_eof = -1; - if (file_ptr->mpi_size > 1) { - if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file_ptr->comm))) - H5_SUBFILING_MPI_DONE_ERROR(NULL, "MPI_Bcast failed", mpi_code); - } + if (file->mpi_size > 1) + if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file->comm))) + HMPI_DONE_ERROR(NULL, "MPI_Bcast failed", mpi_code); } - } - if (H5FD__subfiling_close_int(file_ptr) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CLOSEERROR, NULL, "couldn't close file"); + if (H5FD__subfiling_close_int(file) < 0) + HDONE_ERROR(H5E_VFL, H5E_CLOSEERROR, NULL, "couldn't close file"); } - } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_open() */ static herr_t -H5FD__subfiling_close_int(H5FD_subfiling_t *file_ptr) +H5FD__subfiling_close_int(H5FD_subfiling_t *file) { int mpi_finalized; int mpi_code; herr_t ret_value = SUCCEED; - assert(file_ptr); + FUNC_ENTER_PACKAGE - if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + assert(file); - if (file_ptr->sf_file && H5FD_close(file_ptr->sf_file) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close subfile"); - if (file_ptr->stub_file && H5FD_close(file_ptr->stub_file) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close HDF5 stub file"); + if (file->sf_file && H5FD_close(file->sf_file) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close subfile"); + if (file->stub_file && H5FD_close(file->stub_file) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close HDF5 stub file"); - /* if set, close the copy of the plist for the underlying VFD. */ - if ((file_ptr->fa.ioc_fapl_id >= 0) && (H5I_dec_ref(file_ptr->fa.ioc_fapl_id) < 0)) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_ARGS, FAIL, "can't close IOC FAPL"); - file_ptr->fa.ioc_fapl_id = H5I_INVALID_HID; + /* If set, close the copy of the plist for the underlying VFD. */ + if (file->fa.ioc_fapl_id >= 0 && H5I_dec_ref(file->fa.ioc_fapl_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close IOC FAPL"); + if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) + HMPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); if (!mpi_finalized) { - if (H5_mpi_comm_free(&file_ptr->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Communicator"); - if (H5_mpi_info_free(&file_ptr->info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Info object"); - - if (H5_mpi_comm_free(&file_ptr->ext_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&file->comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Communicator"); + if (H5_mpi_info_free(&file->info) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to free MPI Info object"); + if (H5_mpi_comm_free(&file->ext_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); } - file_ptr->fail_to_encode = false; + H5MM_free(file->file_path); + H5MM_free(file->file_dir); -done: - free(file_ptr->file_path); - file_ptr->file_path = NULL; - - H5MM_free(file_ptr->file_dir); - file_ptr->file_dir = NULL; - - if (file_ptr->context_id >= 0 && H5_free_subfiling_object(file_ptr->context_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't free subfiling context object"); + if (file->context_id >= 0 && H5FD__subfiling_free_object(file->context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free subfiling context object"); /* Release the file info */ - file_ptr = H5FL_FREE(H5FD_subfiling_t, file_ptr); + H5FL_FREE(H5FD_subfiling_t, file); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -1378,14 +1308,16 @@ H5FD__subfiling_close_int(H5FD_subfiling_t *file_ptr) static herr_t H5FD__subfiling_close(H5FD_t *_file) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - if (H5FD__subfiling_close_int(file_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file"); + FUNC_ENTER_PACKAGE + + if (H5FD__subfiling_close_int(file) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close file"); done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_close() */ /*------------------------------------------------------------------------- @@ -1395,8 +1327,7 @@ H5FD__subfiling_close(H5FD_t *_file) * arbitrary (but consistent) ordering. * * Return: Success: A value like strcmp() - * Failure: never fails (arguments were checked by the - * caller). + * Failure: never fails (arguments were checked by the caller). * *------------------------------------------------------------------------- */ @@ -1407,12 +1338,14 @@ H5FD__subfiling_cmp(const H5FD_t *_f1, const H5FD_t *_f2) const H5FD_subfiling_t *f2 = (const H5FD_subfiling_t *)_f2; int ret_value = 0; + FUNC_ENTER_PACKAGE_NOERR + assert(f1); assert(f2); ret_value = H5FD_cmp(f1->sf_file, f2->sf_file); - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_cmp() */ /*------------------------------------------------------------------------- @@ -1432,7 +1365,7 @@ H5FD__subfiling_cmp(const H5FD_t *_f1, const H5FD_t *_f2) static herr_t H5FD__subfiling_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* out */) { - herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE_NOERR /* Set the VFL feature flags that this driver supports */ if (flags) { @@ -1442,7 +1375,7 @@ H5FD__subfiling_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags / *flags |= H5FD_FEAT_HAS_MPI; /* This driver uses MPI */ } - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FD__subfiling_query() */ /*------------------------------------------------------------------------- @@ -1459,12 +1392,11 @@ H5FD__subfiling_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags / static haddr_t H5FD__subfiling_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) { - const H5FD_subfiling_t *file = (const H5FD_subfiling_t *)_file; - haddr_t ret_value = HADDR_UNDEF; + const H5FD_subfiling_t *file = (const H5FD_subfiling_t *)_file; - ret_value = file->eoa; + FUNC_ENTER_PACKAGE_NOERR - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(file->eoa) } /* end H5FD__subfiling_get_eoa() */ /*------------------------------------------------------------------------- @@ -1481,21 +1413,23 @@ H5FD__subfiling_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) static herr_t H5FD__subfiling_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - file_ptr->eoa = addr; + FUNC_ENTER_PACKAGE + + file->eoa = addr; /* Set EOA for HDF5 stub file */ - if (file_ptr->mpi_rank == 0) { - if (H5FD_set_eoa(file_ptr->stub_file, type, addr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set HDF5 stub file EOA"); - } + if (file->mpi_rank == 0) + if (H5FD_set_eoa(file->stub_file, type, addr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set HDF5 stub file EOA"); - ret_value = H5FD_set_eoa(file_ptr->sf_file, type, addr); + if (H5FD_set_eoa(file->sf_file, type, addr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set subfile EOA"); done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_set_eoa() */ /*------------------------------------------------------------------------- @@ -1517,12 +1451,11 @@ H5FD__subfiling_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) static haddr_t H5FD__subfiling_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) { - const H5FD_subfiling_t *file = (const H5FD_subfiling_t *)_file; - haddr_t ret_value = HADDR_UNDEF; + const H5FD_subfiling_t *file = (const H5FD_subfiling_t *)_file; - ret_value = file->eof; + FUNC_ENTER_PACKAGE_NOERR - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(file->eof) } /* end H5FD__subfiling_get_eof() */ /*------------------------------------------------------------------------- @@ -1540,13 +1473,16 @@ H5FD__subfiling_get_handle(H5FD_t *_file, hid_t H5_ATTR_UNUSED fapl, void **file H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!file_handle) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid"); - H5FD_get_vfd_handle(file->sf_file, file->fa.ioc_fapl_id, file_handle); + if (H5FD_get_vfd_handle(file->sf_file, file->fa.ioc_fapl_id, file_handle) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfile handle"); done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_get_handle() */ /*------------------------------------------------------------------------- @@ -1566,32 +1502,33 @@ static herr_t H5FD__subfiling_read(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, void *buf /*out*/) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - assert(file_ptr); - assert(file_ptr->pub.driver_id == H5FD_SUBFILING); + FUNC_ENTER_PACKAGE + + assert(file); assert(buf); - if (H5FD__subfiling_io_helper(file_ptr, 1, &type, &addr, &size, (H5_flexible_const_ptr_t *)&buf, + if (H5FD__subfiling_io_helper(file, 1, &type, &addr, &size, (H5_flexible_const_ptr_t *)&buf, IO_TYPE_READ) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from subfiles failed"); + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read from subfiles failed"); /* Point to the end of the current I/O */ addr += (haddr_t)size; /* Update current file position and EOF */ - file_ptr->pos = addr; - file_ptr->op = OP_READ; + file->pos = addr; + file->op = OP_READ; done: if (ret_value < 0) { /* Reset last file I/O information */ - file_ptr->pos = HADDR_UNDEF; - file_ptr->op = OP_UNKNOWN; + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; } /* end if */ - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_read() */ /*------------------------------------------------------------------------- @@ -1609,44 +1546,45 @@ static herr_t H5FD__subfiling_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf /*in*/) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - assert(file_ptr); - assert(file_ptr->pub.driver_id == H5FD_SUBFILING); + FUNC_ENTER_PACKAGE + + assert(file); assert(buf); - if (H5FD__subfiling_io_helper(file_ptr, 1, &type, &addr, &size, (H5_flexible_const_ptr_t *)&buf, + if (H5FD__subfiling_io_helper(file, 1, &type, &addr, &size, (H5_flexible_const_ptr_t *)&buf, IO_TYPE_WRITE) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to subfiles failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write to subfiles failed"); /* Point to the end of the current I/O */ addr += (haddr_t)size; /* Update current file position and EOF */ - file_ptr->pos = addr; - file_ptr->op = OP_WRITE; + file->pos = addr; + file->op = OP_WRITE; /* Mimic the MPI I/O VFD */ - file_ptr->eof = HADDR_UNDEF; + file->eof = HADDR_UNDEF; - if (file_ptr->pos > file_ptr->local_eof) - file_ptr->local_eof = file_ptr->pos; + if (file->pos > file->local_eof) + file->local_eof = file->pos; done: if (ret_value < 0) { /* Reset last file I/O information */ - file_ptr->pos = HADDR_UNDEF; - file_ptr->op = OP_UNKNOWN; + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; } /* end if */ - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_write() */ /*------------------------------------------------------------------------- - * Function: H5FD__subfile_read_vector (internal function) + * Function: H5FD__subfile_read_vector * - * Purpose: Vector Read function for the sub-filing VFD. + * Purpose: Vector Read function for the subfiling VFD. * * Perform count reads from the specified file at the offsets * provided in the addrs array, with the lengths and memory @@ -1657,23 +1595,7 @@ H5FD__subfiling_write(H5FD_t *_file, H5FD_mem_t type, hid_t H5_ATTR_UNUSED dxpl_ * 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. - * - * Notes: Thus function doesn't actually implement vector read. - * Instead, it converts the vector read call into a series - * of scalar read calls. Fix this when time permits. - * - * Also, it didn't support the sizes and types optimization. - * I implemented a version of this which is more generous - * than that currently defined in the RFC. This is good - * enough for now, but the final version should follow - * the RFC. - * JRM -- 10/5/21 * *------------------------------------------------------------------------- */ @@ -1681,47 +1603,36 @@ static herr_t H5FD__subfiling_read_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], void *bufs[] /* out */) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - assert(file_ptr); - assert(file_ptr->pub.driver_id == H5FD_SUBFILING); - assert((types) || (count == 0)); - assert((addrs) || (count == 0)); - assert((sizes) || (count == 0)); - assert((bufs) || (count == 0)); + FUNC_ENTER_PACKAGE - /* - * Verify that the first elements of the sizes and - * types arrays are valid. - */ - assert((count == 0) || (sizes[0] != 0)); - assert((count == 0) || (types[0] != H5FD_MEM_NOLIST)); + assert(file); + assert(count == 0 || types); + assert(count == 0 || addrs); + assert(count == 0 || sizes); + assert(count == 0 || bufs); + + /* Verify that the first elements of the sizes and types arrays are valid */ + assert(count == 0 || sizes[0] != 0); + assert(count == 0 || types[0] != H5FD_MEM_NOLIST); /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) { + if (H5P_DEFAULT == dxpl_id) dxpl_id = H5P_DATASET_XFER_DEFAULT; - } - else { - if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - } + 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); - if (file_ptr->fa.require_ioc) { - if (H5FD__subfiling_io_helper(file_ptr, (size_t)count, types, addrs, sizes, - (H5_flexible_const_ptr_t *)bufs, IO_TYPE_READ) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't read data"); - } - else { - if (H5FD_read_vector(_file, count, types, addrs, sizes, bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "couldn't read data"); - } + if (H5FD__subfiling_io_helper(file, (size_t)count, types, addrs, sizes, (H5_flexible_const_ptr_t *)bufs, + IO_TYPE_READ) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "couldn't read data"); done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_read_vector() */ /*------------------------------------------------------------------------- @@ -1736,12 +1647,7 @@ H5FD__subfiling_read_vector(H5FD_t *_file, hid_t dxpl_id, uint32_t count, H5FD_m * list dxpl_id (which may be the constant H5P_DEFAULT). * * Return: Success: SUCCEED - * All writes have completed successfully. - * * Failure: FAIL - * An internal error was encountered, e.g the - * input arguments are not valid, or the actual - * subfiling writes have failed for some reason. * *------------------------------------------------------------------------- */ @@ -1749,48 +1655,37 @@ static herr_t H5FD__subfiling_write_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 */) { - H5FD_subfiling_t *file_ptr = (H5FD_subfiling_t *)_file; + H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; - assert(file_ptr); - assert(file_ptr->pub.driver_id == H5FD_SUBFILING); - assert((types) || (count == 0)); - assert((addrs) || (count == 0)); - assert((sizes) || (count == 0)); - assert((bufs) || (count == 0)); + FUNC_ENTER_PACKAGE - /* - * Verify that the first elements of the sizes and - * types arrays are valid. - */ - assert((count == 0) || (sizes[0] != 0)); - assert((count == 0) || (types[0] != H5FD_MEM_NOLIST)); + assert(file); + assert(count == 0 || types); + assert(count == 0 || addrs); + assert(count == 0 || sizes); + assert(count == 0 || bufs); + + /* Verify that the first elements of the sizes and types arrays are valid */ + assert(count == 0 || sizes[0] != 0); + assert(count == 0 || types[0] != H5FD_MEM_NOLIST); /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == dxpl_id) { + if (H5P_DEFAULT == dxpl_id) dxpl_id = H5P_DATASET_XFER_DEFAULT; - } - else { - if (true != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data transfer property list"); - } + 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); - if (file_ptr->fa.require_ioc) { - if (H5FD__subfiling_io_helper(file_ptr, (size_t)count, types, addrs, sizes, - (H5_flexible_const_ptr_t *)bufs, IO_TYPE_WRITE) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't write data"); - } - else { - if (H5FD_write_vector(_file, count, types, addrs, sizes, bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "couldn't write data"); - } + if (H5FD__subfiling_io_helper(file, (size_t)count, types, addrs, sizes, (H5_flexible_const_ptr_t *)bufs, + IO_TYPE_WRITE) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "couldn't write data"); done: - H5_SUBFILING_FUNC_LEAVE_API; -} /* end H5FDsubfile__write_vector() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__subfile__write_vector() */ /*------------------------------------------------------------------------- * Function: H5FD__subfiling_truncate @@ -1808,6 +1703,8 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + assert(file); /* Extend the file to make sure it's large enough */ @@ -1816,24 +1713,21 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT int64_t eoa; int mpi_code; - if (!H5CX_get_mpi_file_flushing()) { + if (!H5CX_get_mpi_file_flushing()) if (file->mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file->comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); - if (0 == file->mpi_rank) { + if (0 == file->mpi_rank) if (H5FD__subfiling__get_real_eof(file->context_id, &sf_eof) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get EOF"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get EOF"); - if (file->mpi_size > 1) { + if (file->mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&sf_eof, 1, MPI_INT64_T, 0, file->comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); if (sf_eof < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "invalid EOF"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid EOF"); H5_CHECKED_ASSIGN(eoa, int64_t, file->eoa, haddr_t); @@ -1844,14 +1738,13 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT * JRM -- 12/18/21 */ if (H5FD__subfiling__truncate_sub_files(file->context_id, eoa, file->comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "subfile truncate request failed"); + HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "subfile truncate request failed"); #if 0 /* TODO: Should be truncated only to size of superblock metadata */ /* Truncate the HDF5 stub file */ - if (file->mpi_rank == 0) { + if (file->mpi_rank == 0) if (H5FD_truncate(file->stub_file, closing) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "stub file truncate request failed"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "stub file truncate request failed"); #endif /* Reset last file I/O information */ @@ -1863,69 +1756,9 @@ H5FD__subfiling_truncate(H5FD_t *_file, hid_t H5_ATTR_UNUSED dxpl_id, bool H5_AT } done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_truncate() */ -/*------------------------------------------------------------------------- - * Function: H5FD__subfiling_lock - * - * Purpose: To place an advisory lock on a file. - * The lock type to apply depends on the parameter "rw": - * true--opens for write: an exclusive lock - * false--opens for read: a shared lock - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -#if 0 -static herr_t -H5FD__subfiling_lock(H5FD_t *_file, bool rw) -{ - H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; /* VFD file struct */ - herr_t ret_value = SUCCEED; /* Return value */ - - assert(file); - - if (file->fa.require_ioc) { -#ifdef VERBOSE - puts("Subfiling driver doesn't support file locking"); -#endif - } - else { - if (H5FD_lock(file->sf_file, rw) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to lock file"); - } /* end if */ - -done: - H5_SUBFILING_FUNC_LEAVE_API; -} /* end H5FD__subfiling_lock() */ - -/*------------------------------------------------------------------------- - * Function: H5FD__subfiling_unlock - * - * Purpose: To remove the existing lock on the file - * - * Return: SUCCEED/FAIL - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD__subfiling_unlock(H5FD_t *_file) -{ - H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; /* VFD file struct */ - herr_t ret_value = SUCCEED; /* Return value */ - - assert(file); - - if (H5FD_unlock(file->sf_file) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to lock file"); - -done: - H5_SUBFILING_FUNC_LEAVE_API; -} /* end H5FD__subfiling_unlock() */ -#endif - static herr_t H5FD__subfiling_del(const char *name, hid_t fapl) { @@ -1934,28 +1767,29 @@ H5FD__subfiling_del(const char *name, hid_t fapl) H5P_genplist_t *plist = NULL; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (NULL == (plist = H5P_object_verify(fapl, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); if (H5FD_SUBFILING != H5P_peek_driver(plist)) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect driver set on FAPL"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "incorrect driver set on FAPL"); if (NULL == (subfiling_config = H5P_peek_driver_info(plist))) { if (H5FD__subfiling_get_default_config(fapl, &default_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't get default Subfiling VFD configuration"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default Subfiling VFD configuration"); subfiling_config = &default_config; } if (H5FD_delete(name, subfiling_config->ioc_fapl_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTDELETE, FAIL, "unable to delete file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTDELETE, FAIL, "unable to delete file"); done: if (subfiling_config == &default_config) if (H5I_dec_ref(subfiling_config->ioc_fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close IOC FAPL"); + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEOBJ, FAIL, "unable to close IOC FAPL"); - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -1992,24 +1826,20 @@ H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void H5FD_subfiling_t *file = (H5FD_subfiling_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_PACKAGE + /* Sanity checks */ assert(file); - assert(H5FD_SUBFILING == file->pub.driver_id); switch (op_code) { - case H5FD_CTL_GET_MPI_COMMUNICATOR_OPCODE: assert(output); assert(*output); - /* - * Return a separate MPI communicator to the caller so - * that our own MPI calls won't have a chance to conflict - */ - if (file->ext_comm == MPI_COMM_NULL) { + /* Return a new MPI communicator so that our MPI calls are isolated */ + if (file->ext_comm == MPI_COMM_NULL) if (H5_mpi_comm_dup(file->comm, &file->ext_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't duplicate MPI communicator"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't duplicate MPI communicator"); **((MPI_Comm **)output) = file->ext_comm; break; @@ -2033,14 +1863,13 @@ H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void break; default: /* unknown op code */ - if (flags & H5FD_CTL_FAIL_IF_UNKNOWN_FLAG) { - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown"); - } + if (flags & H5FD_CTL_FAIL_IF_UNKNOWN_FLAG) + HGOTO_ERROR(H5E_VFL, H5E_FCNTL, FAIL, "unknown op_code and fail if unknown"); break; } done: - H5_SUBFILING_FUNC_LEAVE_API; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__subfiling_ctl() */ /*------------------------------------------------------------------------- @@ -2054,7 +1883,7 @@ H5FD__subfiling_ctl(H5FD_t *_file, uint64_t op_code, uint64_t flags, const void *------------------------------------------------------------------------- */ static herr_t -H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_t types[], haddr_t addrs[], +H5FD__subfiling_io_helper(H5FD_subfiling_t *file, size_t io_count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], H5_flexible_const_ptr_t bufs[], H5FD_subfiling_io_type_t io_type) { H5_flexible_const_ptr_t *io_bufs = NULL; @@ -2070,36 +1899,32 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ int num_subfiles; herr_t ret_value = SUCCEED; - assert(file_ptr); + FUNC_ENTER_PACKAGE + + assert(file); - if (HADDR_UNDEF == (file_eoa = H5FD__subfiling_get_eoa((const H5FD_t *)file_ptr, H5FD_MEM_DEFAULT))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get file EOA"); + if (HADDR_UNDEF == (file_eoa = H5FD__subfiling_get_eoa((const H5FD_t *)file, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get file EOA"); /* Perform some sanity checking on the given (address, size) pairs */ extend_sizes = false; for (size_t i = 0; i < io_count; i++) { if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - io_size = sizes[i - 1]; - } - else { + else io_size = sizes[i]; - } } if (!H5_addr_defined(addrs[i])) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr[%zu] undefined, addr = %" PRIuHADDR, - i, addrs[i]); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr[%zu] undefined, addr = %" PRIuHADDR, i, addrs[i]); if (REGION_OVERFLOW(addrs[i], io_size)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, - "addr[%zu] overflow, addr = %" PRIuHADDR ", size = %zu", i, addrs[i], - io_size); + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr[%zu] overflow, addr = %" PRIuHADDR ", size = %zu", + i, addrs[i], io_size); if ((addrs[i] + io_size) > file_eoa) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, - "addr overflow, addrs[%zu] = %" PRIuHADDR - ", sizes[%zu] = %zu, eoa = %" PRIuHADDR, - i, addrs[i], i, io_size, file_eoa); + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, + "addr overflow, addrs[%zu] = %" PRIuHADDR ", sizes[%zu] = %zu, eoa = %" PRIuHADDR, i, + addrs[i], i, io_size, file_eoa); } /* @@ -2108,15 +1933,15 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ * can be properly handled here. */ if (H5CX_get_io_xfer_mode(&xfer_mode) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't determine I/O collectivity setting"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't determine I/O collectivity setting"); if (xfer_mode == H5FD_MPIO_COLLECTIVE) { MPI_Datatype btype, ftype; if (H5CX_get_mpi_coll_datatypes(&btype, &ftype) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't get MPI-I/O datatypes"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get MPI-I/O datatypes"); if (MPI_BYTE != btype || MPI_BYTE != ftype) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "collective I/O is currently unsupported"); + HGOTO_ERROR(H5E_VFL, H5E_UNSUPPORTED, FAIL, "collective I/O is currently unsupported"); } /* @@ -2141,14 +1966,12 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ * to size the vectors that will be used to invoke the * underlying I/O operations. */ - if (NULL == (sf_context = (subfiling_context_t *)H5_get_subfiling_object(file_ptr->context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, - "invalid or missing subfiling context object"); + if (NULL == (sf_context = (subfiling_context_t *)H5FD__subfiling_get_object(file->context_id))) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid or missing subfiling context object"); assert(sf_context->topology); if ((num_subfiles = sf_context->sf_num_subfiles) <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, FAIL, "invalid number of subfiles (%d)", - num_subfiles); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid number of subfiles (%d)", num_subfiles); if (num_subfiles == 1) { uint32_t u32_io_count; @@ -2166,24 +1989,21 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ if (io_type == IO_TYPE_WRITE) { /* Make vector write call to VFD controlling subfiles */ - if (H5FD_write_vector(file_ptr->sf_file, u32_io_count, types, addrs, sizes, (const void **)bufs) < - 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to subfile failed"); + if (H5FD_write_vector(file->sf_file, u32_io_count, types, addrs, sizes, (const void **)bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write to subfile failed"); /* - * Mirror superblock writes to the stub file so that - * legacy HDF5 applications can check what type of - * file they are reading + * Mirror superblock writes to the stub file so that legacy HDF5 + * applications can check what type of file they are reading */ - if (H5FD__subfiling_mirror_writes_to_stub(file_ptr, u32_io_count, types, addrs, sizes, + if (H5FD__subfiling_mirror_writes_to_stub(file, u32_io_count, types, addrs, sizes, (const void **)bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "mirrored write to stub file failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "mirrored write to stub file failed"); } - else { + else /* Make vector read call to VFD controlling subfiles */ - if (H5FD_read_vector(file_ptr->sf_file, u32_io_count, types, addrs, sizes, (void **)bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from subfile failed"); - } + if (H5FD_read_vector(file->sf_file, u32_io_count, types, addrs, sizes, (void **)bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read from subfile failed"); } else { uint32_t iovec_len; @@ -2198,14 +2018,13 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ * Generate the types, addrs, sizes and bufs I/O vectors for * this I/O request. */ - status = generate_io_vectors( + status = H5FD__subfiling_generate_io_vectors( sf_context, /* IN: Subfiling context used to look up config info */ io_count, /* IN: Number of entries in `types`, `addrs`, `sizes` and `bufs` */ types, /* IN: Array of memory types */ addrs, /* IN: Array of starting file offsets */ sizes, /* IN: Array of I/O sizes (in terms of elements) */ bufs, /* IN: Array of I/O buffers */ - 1, /* IN: Data extent of the 'type'; byte is assumed currently */ io_type, /* IN: Type of I/O being performed (IO_TYPE_WRITE or IO_TYPE_READ) */ &ioreq_count, /* OUT: Number of I/O requests to be made */ &iovec_len, /* OUT: Number of elements in I/O vector for a single I/O request */ @@ -2215,17 +2034,17 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ &io_bufs); /* OUT: I/O vector of buffers for each I/O entry */ if (status < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't initialize I/O vectors"); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't initialize I/O vectors"); /* Nothing to do * - * TODO: Note that this does not let the sub-filing VFD participate in + * TODO: Note that this does not let the subfiling VFD participate in * collective calls when there is no data to write. This is not an issue * now, as we don't do anything special with collective operations. * However, this needs to be fixed. */ if (ioreq_count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); #ifdef H5_SUBFILING_DEBUG H5_subfiling_dump_iovecs(sf_context, ioreq_count, iovec_len, io_type, io_types, io_addrs, io_sizes, @@ -2282,50 +2101,44 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ if (io_type == IO_TYPE_WRITE) { /* Make vector write call to VFD controlling subfiles */ - if (H5FD_write_vector(file_ptr->sf_file, final_vec_len, io_types_ptr, io_addrs_ptr, - io_sizes_ptr, (const void **)io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to subfile failed"); + if (H5FD_write_vector(file->sf_file, final_vec_len, io_types_ptr, io_addrs_ptr, io_sizes_ptr, + (const void **)io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "write to subfile failed"); /* - * Mirror superblock writes to the stub file so that - * legacy HDF5 applications can check what type of - * file they are reading + * Mirror superblock writes to the stub file so that legacy HDF5 + * applications can check what type of file they are reading */ - if (H5FD__subfiling_mirror_writes_to_stub(file_ptr, final_vec_len, io_types_ptr, io_addrs_ptr, + if (H5FD__subfiling_mirror_writes_to_stub(file, final_vec_len, io_types_ptr, io_addrs_ptr, io_sizes_ptr, (const void **)io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "mirrored write to stub file failed"); + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "mirrored write to stub file failed"); } else { - if (!rank0_bcast || (file_ptr->mpi_rank == 0)) { + if (!rank0_bcast || (file->mpi_rank == 0)) /* Make vector read call to VFD controlling subfiles */ - if (H5FD_read_vector(file_ptr->sf_file, final_vec_len, io_types_ptr, io_addrs_ptr, + if (H5FD_read_vector(file->sf_file, final_vec_len, io_types_ptr, io_addrs_ptr, io_sizes_ptr, (void **)io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from subfile failed"); - } + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "read from subfile failed"); } } - if (rank0_bcast && (file_ptr->mpi_size > 1)) { - size_t size; + if (rank0_bcast && (file->mpi_size > 1)) { + size_t size = 0; assert(io_type == IO_TYPE_READ); extend_sizes = false; for (size_t i = 0; i < io_count; i++) { if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - size = sizes[i - 1]; - } - else { + else size = sizes[i]; - } } H5_CHECK_OVERFLOW(size, size_t, int); - if (MPI_SUCCESS != MPI_Bcast(bufs[i].vp, (int)size, MPI_BYTE, 0, file_ptr->comm)) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't broadcast data from rank 0"); + if (MPI_SUCCESS != MPI_Bcast(bufs[i].vp, (int)size, MPI_BYTE, 0, file->comm)) + HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "can't broadcast data from rank 0"); } } } @@ -2334,14 +2147,14 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ /* Restore original transfer mode if we changed it */ if (xfer_mode != H5FD_MPIO_INDEPENDENT) if (H5CX_set_io_xfer_mode(xfer_mode) < 0) - H5_SUBFILING_DONE_ERROR(H5E_CONTEXT, H5E_CANTSET, FAIL, "can't set I/O collectivity setting"); + HDONE_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set I/O collectivity setting"); - free(io_bufs); - free(io_sizes); - free(io_addrs); - free(io_types); + H5MM_free(io_bufs); + H5MM_free(io_sizes); + H5MM_free(io_addrs); + H5MM_free(io_types); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- @@ -2362,7 +2175,7 @@ H5FD__subfiling_io_helper(H5FD_subfiling_t *file_ptr, size_t io_count, H5FD_mem_ *------------------------------------------------------------------------- */ static herr_t -H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count, H5FD_mem_t types[], +H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file, uint32_t count, H5FD_mem_t types[], haddr_t addrs[], size_t sizes[], const void *bufs[]) { const void **copied_bufs = NULL; @@ -2373,91 +2186,83 @@ H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count size_t io_size = 0; bool all_super_writes = true; bool some_super_writes = false; + uint32_t super_count = 0; bool extend_types = false; bool extend_sizes = false; herr_t ret_value = SUCCEED; - assert(file_ptr); + FUNC_ENTER_PACKAGE + + assert(file); /* Only mirror I/O from MPI rank 0 */ - if (file_ptr->mpi_rank != 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + if (file->mpi_rank != 0) + HGOTO_DONE(SUCCEED); if (count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); for (size_t i = 0; i < count; i++) { if (!extend_types) { - if ((i > 0) && (types[i] == H5FD_MEM_NOLIST)) { + if (i > 0 && types[i] == H5FD_MEM_NOLIST) extend_types = true; - type = types[i - 1]; - } - else { + else type = types[i]; - } } - if (type == H5FD_MEM_SUPER) + if (type == H5FD_MEM_SUPER) { some_super_writes = true; + super_count++; + } else all_super_writes = false; - /* - * If we find H5FD_MEM_NOLIST, we don't need to - * keep looking through the array entries - */ - if (extend_types) + /* If we find H5FD_MEM_NOLIST, we can stop looking at array entries */ + if (extend_types) { + if (type == H5FD_MEM_SUPER) + super_count += (count - (uint32_t)i) - 1; /* Account for remaining elements */ break; + } } if (all_super_writes) { - if (H5FD_write_vector(file_ptr->stub_file, count, types, addrs, sizes, bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "couldn't write superblock information to stub file"); + if (H5FD_write_vector(file->stub_file, count, types, addrs, sizes, bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "couldn't write superblock information to stub file"); } else if (some_super_writes) { uint32_t vec_len = 0; /* Copy I/O vectors and strip out non-superblock I/O */ - if (NULL == (copied_types = malloc(count * sizeof(*copied_types)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate copy of I/O types array"); - if (NULL == (copied_addrs = malloc(count * sizeof(*copied_addrs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate copy of I/O addresses array"); - if (NULL == (copied_sizes = malloc(count * sizeof(*copied_sizes)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate copy of I/O sizes array"); - if (NULL == (copied_bufs = malloc(count * sizeof(*copied_bufs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate copy of I/O buffers array"); + if (NULL == (copied_types = H5MM_malloc(super_count * sizeof(*copied_types)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate copy of I/O types array"); + if (NULL == (copied_addrs = H5MM_malloc(super_count * sizeof(*copied_addrs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate copy of I/O addresses array"); + if (NULL == (copied_sizes = H5MM_malloc(super_count * sizeof(*copied_sizes)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate copy of I/O sizes array"); + if (NULL == (copied_bufs = H5MM_malloc(super_count * sizeof(*copied_bufs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate copy of I/O buffers array"); extend_types = false; extend_sizes = false; for (size_t i = 0; i < count; i++) { if (!extend_types) { - if ((i > 0) && (types[i] == H5FD_MEM_NOLIST)) { + if (i > 0 && types[i] == H5FD_MEM_NOLIST) { extend_types = true; - type = types[i - 1]; /* End early if none of the remaining memory types are H5FD_MEM_SUPER */ if (type != H5FD_MEM_SUPER) break; } - else { + else type = types[i]; - } } if (!extend_sizes) { - if ((i > 0) && (sizes[i] == 0)) { + if (i > 0 && sizes[i] == 0) extend_sizes = true; - io_size = sizes[i - 1]; - } - else { + else io_size = sizes[i]; - } } if (type != H5FD_MEM_SUPER) @@ -2470,24 +2275,24 @@ H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count vec_len++; } + assert(vec_len > 0); - if ((vec_len > 0) && (H5FD_write_vector(file_ptr->stub_file, vec_len, copied_types, copied_addrs, - copied_sizes, copied_bufs) < 0)) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "couldn't write superblock information to stub file"); + if (H5FD_write_vector(file->stub_file, vec_len, copied_types, copied_addrs, copied_sizes, + copied_bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "couldn't write superblock information to stub file"); } done: - free(copied_bufs); - free(copied_sizes); - free(copied_addrs); - free(copied_types); + H5MM_free(copied_bufs); + H5MM_free(copied_sizes); + H5MM_free(copied_addrs); + H5MM_free(copied_types); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: generate_io_vectors + * Function: H5FD__subfiling_generate_io_vectors * * Purpose: Given an array of memory types, an array of file offsets, * an array of the number of I/O elements for each file @@ -2526,12 +2331,6 @@ H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count * bufs (IN) * - array of the I/O buffers to use for each I/O entry * - * dtype_extent (IN) - * - the extent of the datatype of each data element for - * the I/O operation (currently assumed to be 1, meaning - * entries in `nelemts` are expressed in terms of - * bytes) - * * io_type (IN) * - the type of I/O being performed (IO_TYPE_WRITE or * IO_TYPE_READ) @@ -2568,11 +2367,11 @@ H5FD__subfiling_mirror_writes_to_stub(H5FD_subfiling_t *file_ptr, uint32_t count * */ static herr_t -generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t types[], - haddr_t file_offsets[], size_t nelemts[], H5_flexible_const_ptr_t bufs[], - size_t dtype_extent, H5FD_subfiling_io_type_t io_type, size_t *ioreq_count, - uint32_t *iovec_len, H5FD_mem_t **io_types, haddr_t **io_addrs, size_t **io_sizes, - H5_flexible_const_ptr_t **io_bufs) +H5FD__subfiling_generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t types[], + haddr_t file_offsets[], size_t nelemts[], H5_flexible_const_ptr_t bufs[], + H5FD_subfiling_io_type_t io_type, size_t *ioreq_count, + uint32_t *iovec_len, H5FD_mem_t **io_types, haddr_t **io_addrs, + size_t **io_sizes, H5_flexible_const_ptr_t **io_bufs) { H5_flexible_const_ptr_t *loc_io_bufs = NULL; H5FD_mem_t *loc_io_types = NULL; @@ -2587,16 +2386,17 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t bool extend_types = false; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(sf_context->sf_stripe_size > 0); assert(sf_context->sf_blocksize_per_stripe > 0); assert(sf_context->sf_num_subfiles > 0); assert(sf_context->topology); - assert((types) || (in_count == 0)); - assert((file_offsets) || (in_count == 0)); - assert((nelemts) || (in_count == 0)); - assert((bufs) || (in_count == 0)); - assert(dtype_extent == 1); /* For now, assume 'byte'-sized elements */ + assert(types || in_count == 0); + assert(file_offsets || in_count == 0); + assert(nelemts || in_count == 0); + assert(bufs || in_count == 0); assert(ioreq_count); assert(iovec_len); assert(io_types); @@ -2610,36 +2410,33 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t /* Nothing to do */ if (in_count == 0) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); /* - * Do some initial pre-processing to determine how large of - * I/O vectors we will need to allocate to satisfy the - * entire I/O request + * Do some initial pre-processing to determine how large of I/O vectors we + * will need to allocate to satisfy the entire I/O request */ - get_iovec_sizes(sf_context, in_count, file_offsets, nelemts, dtype_extent, &max_iovec_depth, - &max_num_subfiles_touched); + H5FD__subfiling_get_iovec_sizes(sf_context, in_count, file_offsets, nelemts, &max_iovec_depth, + &max_num_subfiles_touched); tot_iovec_len = in_count * max_iovec_depth * max_num_subfiles_touched; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log( + H5FD__subfiling_log( sf_context->sf_context_id, "%s: I/O count: %zu, max_iovec_depth = %zu, max_num_subfiles_touched = %zu, iovec_len = %zu", __func__, in_count, max_iovec_depth, max_num_subfiles_touched, tot_iovec_len); #endif /* Allocate I/O vectors that will be returned to the caller */ - if (NULL == (loc_io_types = calloc(1, tot_iovec_len * sizeof(*loc_io_types)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O types vector"); - if (NULL == (loc_io_addrs = calloc(1, tot_iovec_len * sizeof(*loc_io_addrs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate subfile I/O addresses vector"); - if (NULL == (loc_io_sizes = calloc(1, tot_iovec_len * sizeof(*loc_io_sizes)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O sizes vector"); - if (NULL == (loc_io_bufs = calloc(1, tot_iovec_len * sizeof(*loc_io_bufs)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate subfile I/O buffers vector"); + if (NULL == (loc_io_types = H5MM_calloc(tot_iovec_len * sizeof(*loc_io_types)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O types vector"); + if (NULL == (loc_io_addrs = H5MM_calloc(tot_iovec_len * sizeof(*loc_io_addrs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O addresses vector"); + if (NULL == (loc_io_sizes = H5MM_calloc(tot_iovec_len * sizeof(*loc_io_sizes)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O sizes vector"); + if (NULL == (loc_io_bufs = H5MM_calloc(tot_iovec_len * sizeof(*loc_io_bufs)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate subfile I/O buffers vector"); /* * Populate the I/O vectors by looping through each @@ -2652,29 +2449,24 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t assert(iovec_idx < tot_iovec_len); if (!extend_types) { - if ((io_idx > 0) && (types[io_idx] == H5FD_MEM_NOLIST)) { + if (io_idx > 0 && types[io_idx] == H5FD_MEM_NOLIST) extend_types = true; - mem_type = types[io_idx - 1]; - } - else { + else mem_type = types[io_idx]; - } } if (!extend_sizes) { - if ((io_idx > 0) && (nelemts[io_idx] == 0)) { + if (io_idx > 0 && nelemts[io_idx] == 0) extend_sizes = true; - io_size = nelemts[io_idx - 1] * dtype_extent; - } - else { - io_size = nelemts[io_idx] * dtype_extent; - } + else + io_size = nelemts[io_idx]; } - if (translate_io_req_to_iovec(sf_context, iovec_idx, max_num_subfiles_touched, max_iovec_depth, - mem_type, file_offsets[io_idx], io_size, bufs[io_idx], io_type, - loc_io_types, loc_io_addrs, loc_io_sizes, loc_io_bufs) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't translate I/O request to I/O vectors"); + if (H5FD__subfiling_translate_io_req_to_iovec(sf_context, iovec_idx, max_num_subfiles_touched, + max_iovec_depth, mem_type, file_offsets[io_idx], + io_size, bufs[io_idx], io_type, loc_io_types, + loc_io_addrs, loc_io_sizes, loc_io_bufs) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't translate I/O request to I/O vectors"); } *ioreq_count = in_count * max_iovec_depth; @@ -2687,17 +2479,17 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t done: if (ret_value < 0) { - free(loc_io_bufs); - free(loc_io_sizes); - free(loc_io_addrs); - free(loc_io_types); + H5MM_free(loc_io_bufs); + H5MM_free(loc_io_sizes); + H5MM_free(loc_io_addrs); + H5MM_free(loc_io_types); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: get_iovec_sizes + * Function: H5FD__subfiling_get_iovec_sizes * * Purpose: Helper routine to determine the maximum I/O vector depth * (in terms of array elements) and maximum number of subfiles @@ -2711,8 +2503,8 @@ generate_io_vectors(subfiling_context_t *sf_context, size_t in_count, H5FD_mem_t *------------------------------------------------------------------------- */ static void -get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_offsets[], size_t nelemts[], - size_t dtype_extent, size_t *max_iovec_depth, size_t *max_num_subfiles) +H5FD__subfiling_get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_offsets[], + size_t nelemts[], size_t *max_iovec_depth, size_t *max_num_subfiles) { int64_t stripe_size = 0; int64_t block_size = 0; @@ -2720,6 +2512,8 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o size_t loc_max_num_subfiles = 0; int num_subfiles = 0; + FUNC_ENTER_PACKAGE_NOERR + assert(sf_context); assert(file_offsets); assert(nelemts); @@ -2744,7 +2538,7 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o size_t cur_iovec_depth; H5_CHECKED_ASSIGN(cur_file_offset, int64_t, file_offsets[io_idx], haddr_t); - H5_CHECKED_ASSIGN(data_size, int64_t, (nelemts[io_idx] * dtype_extent), size_t); + H5_CHECKED_ASSIGN(data_size, int64_t, nelemts[io_idx], size_t); /* * Calculate the following from the starting file offset: @@ -2759,8 +2553,7 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o * (offsets 0-1023) * final_offset * - the last offset in the virtual file covered by this I/O - * operation. Simply the I/O size added to the starting file - * offset. + * operation. Simply the I/O size added to the starting file offset. */ stripe_idx = cur_file_offset / stripe_size; final_offset = cur_file_offset + data_size; @@ -2769,28 +2562,26 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o first_subfile = stripe_idx % num_subfiles; /* - * Determine the stripe "index" of the last offset in the - * virtual file and, from that, determine the subfile that - * the I/O request ends in. + * Determine the stripe "index" of the last offset in the virtual file + * and the subfile that the I/O request ends in. */ final_stripe_idx = final_offset / stripe_size; last_subfile = final_stripe_idx % num_subfiles; /* - * Determine how "deep" the resulting I/O vectors are at - * most by calculating the maximum number of "rows" spanned - * for any particular subfile; e.g. the maximum number of - * I/O requests for any particular subfile + * Determine how "deep" the resulting I/O vectors are at most by + * calculating the maximum number of "rows" spanned for any particular + * subfile; i.e. the maximum number of I/O requests for any particular + * subfile */ row_stripe_idx_start = stripe_idx - first_subfile; row_stripe_idx_final = final_stripe_idx - last_subfile; cur_iovec_depth = (size_t)((row_stripe_idx_final - row_stripe_idx_start) / num_subfiles) + 1; /* - * If the I/O request "wrapped around" and ends in a subfile - * less than the subfile we started in, subtract one from the - * I/O vector length to account for "empty space". This can be - * visualized as follows: + * If the I/O request "wrapped around" and ends in a subfile less than + * the subfile we started in, subtract one from the I/O vector length to + * account for "empty space". This can be visualized as follows: * * SUBFILE 0 SUBFILE 1 SUBFILE 2 SUBFILE 3 * _______________________________________________ @@ -2803,16 +2594,15 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o * | | | | | * |___________|___________|___________|___________| * - * Here, `stripe_idx` would be calculated as 2 (I/O begins in - * the 3rd stripe, or subfile index 2), `first_subfile` would be - * calculated as 2 and the starting "row" (row_stripe_idx_start) - * would be calculated as "row" index 0. `final_stripe_idx` would - * be calculated as 9, `last_subfile` would be calculated as - * (9 % 4) = 1 and the ending "row" (row_stripe_idx_final) would - * be calculated as (9 - 1) = 8. Thus, the calculated I/O vector - * length would be ((8 - 0) / 4) + 1 = 3. However, since there is - * no I/O to stripe indices 0 and 1 (residing in "row" 0 of subfile - * index 0 and 1, respectively), it can be seen that the real I/O + * Here, `stripe_idx` would be calculated as 2 (I/O begins in the 3rd + * stripe, or subfile index 2), `first_subfile` would be calculated as 2 + * and the starting "row" (row_stripe_idx_start) would be calculated as + * "row" index 0. `final_stripe_idx` would be calculated as 9, + * `last_subfile` would be calculated as (9 % 4) = 1 and the ending "row" + * (row_stripe_idx_final) would be calculated as (9 - 1) = 8. Thus, the + * calculated I/O vector length would be ((8 - 0) / 4) + 1 = 3. However, + * since there is no I/O to stripe indices 0 and 1 (residing in "row" 0 of + * subfile index 0 and 1, respectively), it can be seen that the real I/O * vector length is 2. */ if (last_subfile < first_subfile) @@ -2854,13 +2644,15 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o *max_iovec_depth = loc_max_iovec_depth; *max_num_subfiles = loc_max_num_subfiles; + + FUNC_LEAVE_NOAPI_VOID } /*------------------------------------------------------------------------- - * Function: translate_io_req_to_iovec + * Function: H5FD__subfiling_translate_io_req_to_iovec * * Purpose: Helper routine to perform the translation between an I/O - * request (type, addr, size, buf tuple) and a set of I/O + * request [i.e. an (type, addr, size, buf) tuple] and a set of I/O * vectors that spans all the subfiles touched by that I/O * request. Once finished, this function will have generated * at most `iovec_count` sets of I/O vectors, each containing @@ -2880,7 +2672,7 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o * * iovec_count (IN) * - the maximum number of I/O vectors to be generated, as - * calculated in generate_io_vectors() + * calculated in H5FD__subfiling_generate_io_vectors() * * type (IN) * - the memory type to use for each component of the I/O @@ -2919,11 +2711,11 @@ get_iovec_sizes(subfiling_context_t *sf_context, size_t in_count, haddr_t file_o *------------------------------------------------------------------------- */ static herr_t -translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, size_t iovec_len, - size_t iovec_count, H5FD_mem_t type, haddr_t addr, size_t io_size, - H5_flexible_const_ptr_t io_buf, H5FD_subfiling_io_type_t io_type, - H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, - H5_flexible_const_ptr_t *io_bufs) +H5FD__subfiling_translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, size_t iovec_len, + size_t iovec_count, H5FD_mem_t type, haddr_t addr, size_t io_size, + H5_flexible_const_ptr_t io_buf, H5FD_subfiling_io_type_t io_type, + H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, + H5_flexible_const_ptr_t *io_bufs) { int64_t stripe_idx = 0; int64_t final_stripe_idx = 0; @@ -2947,6 +2739,8 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz int num_subfiles = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(io_types); assert(io_addrs); @@ -2960,11 +2754,9 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * - the size of the data striping across the file's subfiles * block_size * - the size of a "block" across the IOCs, as calculated - * by the stripe size multiplied by the number of - * subfiles + * by the stripe size multiplied by the number of subfiles * num_subfiles - * - the total number of subfiles for the logical - * HDF5 file + * - the total number of subfiles for the logical HDF5 file */ stripe_size = sf_context->sf_stripe_size; block_size = sf_context->sf_blocksize_per_stripe; @@ -2988,8 +2780,7 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * - the relative offset in the stripe that the starting file * offset resides in * offset_in_block - * - the relative offset in the "block" of stripes across the - * subfiles + * - the relative offset in the "block" of stripes across the subfiles * final_offset * - the last offset in the virtual file covered by this I/O * request. Simply the I/O size minus one byte added to the @@ -3012,14 +2803,12 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz assert(final_length <= stripe_size); /* - * Determine which subfile the I/O request begins in and which - * "row" the I/O request begins in within the "block" of stripes - * across the subfiles. Note that "row" here is just a conceptual - * way to think of how a block of data stripes is laid out across - * the subfiles. A block's "column" size in bytes is equal to the - * stripe size multiplied by the number of subfiles. Therefore, - * file offsets that are multiples of the block size begin a new - * "row". + * Determine which subfile the I/O request begins in and which "row" the I/O + * request begins in within the "block" of stripes across the subfiles. Note + * that "row" here is just a conceptual way to think of how a block of data + * stripes is laid out across the subfiles. A block's "column" size in bytes + * is equal to the stripe size multiplied by the number of subfiles. Therefore, + * file offsets that are multiples of the block size begin a new "row". */ start_row = stripe_idx / num_subfiles; first_subfile_idx = stripe_idx % num_subfiles; @@ -3050,10 +2839,9 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz max_iovec_depth = ((row_stripe_idx_final - row_stripe_idx_start) / num_subfiles) + 1; /* - * If the I/O request "wrapped around" and ends in a subfile - * less than the subfile we started in, subtract one from the - * I/O vector length to account for "empty space". This can be - * visualized as follows: + * If the I/O request "wrapped around" and ends in a subfile less than the + * subfile we started in, subtract one from the I/O vector length to account + * for "empty space". This can be visualized as follows: * * SUBFILE 0 SUBFILE 1 SUBFILE 2 SUBFILE 3 * _______________________________________________ @@ -3066,23 +2854,21 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * | | | | | * |___________|___________|___________|___________| * - * Here, `stripe_idx` would be calculated as 2 (I/O begins in - * the 3rd stripe, or subfile index 2), `first_subfile` would be - * calculated as 2 and the starting "row" (row_stripe_idx_start) - * would be calculated as "row" index 0. `final_stripe_idx` would - * be calculated as 9, `last_subfile` would be calculated as - * (9 % 4) = 1 and the ending "row" (row_stripe_idx_final) would - * be calculated as (9 - 1) = 8. Thus, the calculated I/O vector - * length would be ((8 - 0) / 4) + 1 = 3. However, since there is - * no I/O to stripe indices 0 and 1 (residing in "row" 0 of subfile - * index 0 and 1, respectively), it can be seen that the real I/O - * vector length is 2. + * Here, `stripe_idx` would be calculated as 2 (I/O begins in the 3rd stripe, + * or subfile index 2), `first_subfile` would be calculated as 2 and the + * starting "row" (row_stripe_idx_start) would be calculated as "row" index 0. + * `final_stripe_idx` would be calculated as 9, `last_subfile` would be + * calculated as (9 % 4) = 1 and the ending "row" (row_stripe_idx_final) would + * be calculated as (9 - 1) = 8. Thus, the calculated I/O vector length would + * be ((8 - 0) / 4) + 1 = 3. However, since there is no I/O to stripe indices + * 0 and 1 (residing in "row" 0 of subfile index 0 and 1, respectively), it + * can be seen that the real I/O vector length is 2. */ if (last_subfile_idx < first_subfile_idx) max_iovec_depth--; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log( + H5FD__subfiling_log( sf_context->sf_context_id, "%s: TRANSLATING I/O REQUEST (MEMORY TYPE: %d, ADDR: %" PRIuHADDR ", I/O SIZE: %zu, BUF: %p)\n" "STRIPE SIZE: %" PRId64 ", BLOCK SIZE: %" PRId64 ", NUM SUBFILES: %d\n" @@ -3096,9 +2882,9 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz #endif /* - * Loop through the set of subfiles to determine the various - * vector components for each. Subfiles whose data size is - * zero will not have I/O requests passed to them. + * Loop through the set of subfiles to determine the various vector components + * for each. Subfiles whose data size is zero will not have I/O requests + * passed to them. */ for (int i = 0, subfile_idx = (int)first_subfile_idx; i < num_subfiles; i++) { H5_flexible_const_ptr_t *_io_bufs_ptr; @@ -3120,10 +2906,7 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz if (subfile_idx == first_subfile_idx) { is_first = true; - /* - * Add partial segment length if not - * starting on a stripe boundary - */ + /* Add partial segment length if not starting on a stripe boundary */ if (start_length < stripe_size) { subfile_bytes += start_length; num_full_stripes--; @@ -3133,10 +2916,7 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz if (subfile_idx == last_subfile_idx) { is_last = true; - /* - * Add partial segment length if not - * ending on a stripe boundary - */ + /* Add partial segment length if not ending on a stripe boundary */ if (final_length < stripe_size) { subfile_bytes += final_length; if (num_full_stripes) @@ -3150,15 +2930,13 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz if (last_subfile_idx >= first_subfile_idx) { /* - * In the case where the subfile with the final data - * segment has an index value greater than or equal - * to the subfile with the first data segment, I/O - * vectors directed to a subfile with an index value - * that is greater than the last subfile or less than - * the first subfile will be "thin", or rather will - * have a vector depth of 1 less than normal, which - * will be accounted for below. This can be visualized - * with the following I/O pattern: + * In the case where the subfile with the final data segment has + * an index value greater than or equal to the subfile with the + * first data segment, I/O vectors directed to a subfile with an + * index value that is greater than the last subfile or less than + * the first subfile will be "thin", or rather will have a vector + * depth of 1 less than normal, which will be accounted for below. + * This can be visualized with the following I/O pattern: * * SUBFILE 0 SUBFILE 1 SUBFILE 2 SUBFILE 3 * _______________________________________________ @@ -3176,10 +2954,10 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz } else { /* last_subfile_idx < first_subfile_idx */ /* - * This can also happen when the subfile with the final - * data segment has a smaller subfile index than the - * subfile with the first data segment and the current - * subfile index falls between the two. + * This can also happen when the subfile with the final data + * segment has a smaller subfile index than the subfile with the + * first data segment and the current subfile index falls between + * the two. */ thin_uniform_section = ((last_subfile_idx < subfile_idx) && (subfile_idx < first_subfile_idx)); @@ -3203,10 +2981,7 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz subfile_bytes += num_full_stripes * stripe_size; total_bytes += (size_t)subfile_bytes; - /* - * Setup the pointers to the next set of I/O vectors - * in the output arrays - */ + /* Set up the pointers to the next I/O vector in the output arrays */ _io_types_ptr = &io_types[iovec_idx + (size_t)i]; _io_addrs_ptr = &io_addrs[iovec_idx + (size_t)i]; _io_sizes_ptr = &io_sizes[iovec_idx + (size_t)i]; @@ -3240,23 +3015,24 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * I/O. In this case, we may have to deal with partial * stripe I/O in the first and last I/O segments. */ - if (iovec_fill_first_last(sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, - cur_file_offset, start_length, final_length, io_buf, io_type, - _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); + if (H5FD__subfiling_iovec_fill_first_last(sf_context, iovec_len, iovec_depth, + subfile_bytes, mem_offset, cur_file_offset, + start_length, final_length, io_buf, io_type, + _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); } else { /* - * The current subfile being processed is the first - * subfile touched by I/O. In this case, we may have - * to deal with partial stripe I/O in the first I/O - * segment. + * The current subfile being processed is the first subfile + * touched by I/O. In this case, we may have to deal with + * partial stripe I/O in the first I/O segment. */ - if (iovec_fill_first(sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, - cur_file_offset, start_length, io_buf, io_type, _io_addrs_ptr, - _io_sizes_ptr, _io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); + if (H5FD__subfiling_iovec_fill_first( + sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, cur_file_offset, + start_length, io_buf, io_type, _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); } + /* Move the memory pointer to the starting location * for next subfile I/O request. */ @@ -3268,10 +3044,10 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * touched by I/O. In this case, we may have to deal with * partial stripe I/O in the last I/O segment. */ - if (iovec_fill_last(sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, - cur_file_offset, final_length, io_buf, io_type, _io_addrs_ptr, - _io_sizes_ptr, _io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); + if (H5FD__subfiling_iovec_fill_last(sf_context, iovec_len, iovec_depth, subfile_bytes, + mem_offset, cur_file_offset, final_length, io_buf, + io_type, _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); mem_offset += stripe_size; } @@ -3282,10 +3058,10 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz * partial stripe I/O will need to be dealt with; all I/O * segments will cover a full I/O stripe. */ - if (iovec_fill_uniform(sf_context, iovec_len, iovec_depth, subfile_bytes, mem_offset, - cur_file_offset, io_buf, io_type, _io_addrs_ptr, _io_sizes_ptr, - _io_bufs_ptr) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); + if (H5FD__subfiling_iovec_fill_uniform(sf_context, iovec_len, iovec_depth, subfile_bytes, + mem_offset, cur_file_offset, io_buf, io_type, + _io_addrs_ptr, _io_sizes_ptr, _io_bufs_ptr) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't fill I/O vectors"); mem_offset += stripe_size; } @@ -3306,15 +3082,15 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz } if (total_bytes != io_size) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "total bytes (%zu) didn't match data size (%zu)!", - total_bytes, io_size); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "total bytes (%zu) didn't match data size (%zu)!", + total_bytes, io_size); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: iovec_fill_first + * Function: H5FD__subfiling_iovec_fill_first * * Purpose: Fills I/O vectors for the case where the IOC has the first * data segment of the I/O operation. @@ -3333,16 +3109,19 @@ translate_io_req_to_iovec(subfiling_context_t *sf_context, size_t iovec_idx, siz *------------------------------------------------------------------------- */ static herr_t -iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t first_io_len, H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, - haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) +H5FD__subfiling_iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, + int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, + int64_t first_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) { int64_t stripe_size; int64_t block_size; int64_t total_bytes = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(cur_iovec_depth > 0); assert(io_addrs_ptr); @@ -3353,10 +3132,10 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ block_size = sf_context->sf_blocksize_per_stripe; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 - ", first_io_len = %" PRId64, - __func__, start_mem_offset, start_file_offset, first_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 + ", first_io_len = %" PRId64, + __func__, start_mem_offset, start_file_offset, first_io_len); #endif *io_addrs_ptr = (haddr_t)start_file_offset; @@ -3368,7 +3147,7 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ io_bufs_ptr->vp = (char *)(buf.vp) + start_mem_offset; if (first_io_len == target_datasize) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); if (first_io_len > 0) { int64_t offset_in_stripe = start_file_offset % stripe_size; @@ -3387,10 +3166,10 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); #endif next_mem_offset += block_size; @@ -3399,17 +3178,17 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ } if (total_bytes != target_datasize) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", - total_bytes, target_datasize); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", total_bytes, + target_datasize); } done: - return ret_value; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: iovec_fill_last + * Function: H5FD__subfiling_iovec_fill_last * * Purpose: Fills I/O vectors for the case where the IOC has the last * data segment of the I/O operation. @@ -3430,15 +3209,21 @@ iovec_fill_first(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_ *------------------------------------------------------------------------- */ static herr_t -iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t last_io_len, H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, - haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) +H5FD__subfiling_iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, + int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, + int64_t last_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, + H5_flexible_const_ptr_t *io_bufs_ptr) { int64_t stripe_size; int64_t block_size; int64_t total_bytes = 0; - herr_t ret_value = SUCCEED; + int64_t next_mem_offset; + int64_t next_file_offset; + size_t i; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_PACKAGE assert(sf_context); assert(cur_iovec_depth > 0); @@ -3450,10 +3235,10 @@ iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_i block_size = sf_context->sf_blocksize_per_stripe; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 - ", last_io_len = %" PRId64, - __func__, start_mem_offset, start_file_offset, last_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 + ", last_io_len = %" PRId64, + __func__, start_mem_offset, start_file_offset, last_io_len); #endif *io_addrs_ptr = (haddr_t)start_file_offset; @@ -3465,79 +3250,72 @@ iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_i io_bufs_ptr->vp = (char *)(buf.vp) + start_mem_offset; if (last_io_len == target_datasize) - H5_SUBFILING_GOTO_DONE(SUCCEED); - - { - int64_t next_mem_offset = start_mem_offset + block_size; - int64_t next_file_offset = start_file_offset + block_size; - size_t i; - - /* - * If the last I/O size doesn't cover the target data - * size, there is at least one full stripe preceding - * the last I/O block - */ - *io_sizes_ptr = (size_t)stripe_size; + HGOTO_DONE(SUCCEED); - total_bytes = stripe_size; + /* + * If the last I/O size doesn't cover the target data + * size, there is at least one full stripe preceding + * the last I/O block + */ + *io_sizes_ptr = (size_t)stripe_size; - for (i = 1; i < (size_t)cur_iovec_depth - 1;) { - *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; - *(io_sizes_ptr + (i * iovec_len)) = (size_t)stripe_size; + next_mem_offset = start_mem_offset + block_size; + next_file_offset = start_file_offset + block_size; + total_bytes = stripe_size; + for (i = 1; i < (size_t)cur_iovec_depth - 1; i++) { + *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; + *(io_sizes_ptr + (i * iovec_len)) = (size_t)stripe_size; - if (io_type == IO_TYPE_WRITE) - (io_bufs_ptr + (i * iovec_len))->cvp = (const char *)(buf.cvp) + next_mem_offset; - else - (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; + if (io_type == IO_TYPE_WRITE) + (io_bufs_ptr + (i * iovec_len))->cvp = (const char *)(buf.cvp) + next_mem_offset; + else + (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); #endif - next_mem_offset += block_size; - next_file_offset += block_size; - total_bytes += stripe_size; - - i++; - } + next_mem_offset += block_size; + next_file_offset += block_size; + total_bytes += stripe_size; + } - *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; - *(io_sizes_ptr + (i * iovec_len)) = (size_t)last_io_len; + *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; + *(io_sizes_ptr + (i * iovec_len)) = (size_t)last_io_len; - if (io_type == IO_TYPE_WRITE) - (io_bufs_ptr + (i * iovec_len))->cvp = (const char *)(buf.cvp) + next_mem_offset; - else - (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; + if (io_type == IO_TYPE_WRITE) + (io_bufs_ptr + (i * iovec_len))->cvp = (const char *)(buf.cvp) + next_mem_offset; + else + (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, last_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, last_io_len); #endif - total_bytes += last_io_len; + total_bytes += last_io_len; - if (total_bytes != target_datasize) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", - total_bytes, target_datasize); - } + if (total_bytes != target_datasize) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", total_bytes, + target_datasize); done: - return ret_value; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: iovec_fill_first_last + * Function: H5FD__subfiling_iovec_fill_first_last * * Purpose: Fills I/O vectors for the case where the IOC has the first * and last data segments of the I/O operation. This function - * is essentially a merge of the iovec_fill_first and - * iovec_fill_last functions. + * is essentially a merge of the H5FD__subfiling_iovec_fill_first and + * H5FD__subfiling_iovec_fill_last functions. * * If the 'first_io_len' is sufficient to complete the I/O to * the IOC, then the first entry in the I/O vectors is simply @@ -3555,17 +3333,20 @@ iovec_fill_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_i *------------------------------------------------------------------------- */ static herr_t -iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - int64_t first_io_len, int64_t last_io_len, H5_flexible_const_ptr_t buf, - H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, size_t *io_sizes_ptr, - H5_flexible_const_ptr_t *io_bufs_ptr) +H5FD__subfiling_iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, + int64_t cur_iovec_depth, int64_t target_datasize, + int64_t start_mem_offset, int64_t start_file_offset, + int64_t first_io_len, int64_t last_io_len, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) { int64_t stripe_size; int64_t block_size; int64_t total_bytes = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(cur_iovec_depth > 0); assert(io_addrs_ptr); @@ -3576,10 +3357,10 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t block_size = sf_context->sf_blocksize_per_stripe; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 - ", first_io_len = %" PRId64 ", last_io_len = %" PRId64, - __func__, start_mem_offset, start_file_offset, first_io_len, last_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 + ", first_io_len = %" PRId64 ", last_io_len = %" PRId64, + __func__, start_mem_offset, start_file_offset, first_io_len, last_io_len); #endif *io_addrs_ptr = (haddr_t)start_file_offset; @@ -3591,7 +3372,7 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t io_bufs_ptr->vp = (char *)(buf.vp) + start_mem_offset; if (first_io_len == target_datasize) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); if (first_io_len > 0) { int64_t offset_in_stripe = start_file_offset % stripe_size; @@ -3601,7 +3382,7 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t total_bytes = first_io_len; - for (i = 1; i < (size_t)cur_iovec_depth - 1;) { + for (i = 1; i < (size_t)cur_iovec_depth - 1; i++) { *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; *(io_sizes_ptr + (i * iovec_len)) = (size_t)stripe_size; @@ -3611,17 +3392,15 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); #endif next_mem_offset += block_size; next_file_offset += block_size; total_bytes += stripe_size; - - i++; } *(io_addrs_ptr + (i * iovec_len)) = (haddr_t)next_file_offset; @@ -3633,26 +3412,26 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, last_io_len); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, last_io_len); #endif total_bytes += last_io_len; if (total_bytes != target_datasize) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", - total_bytes, target_datasize); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", total_bytes, + target_datasize); } done: - return ret_value; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: iovec_fill_uniform + * Function: H5FD__subfiling_iovec_fill_uniform * * Purpose: Fills I/O vectors for the typical I/O operation when * reading data from or writing data to an I/O Concentrator @@ -3667,18 +3446,21 @@ iovec_fill_first_last(subfiling_context_t *sf_context, size_t iovec_len, int64_t *------------------------------------------------------------------------- */ static herr_t -iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, - int64_t target_datasize, int64_t start_mem_offset, int64_t start_file_offset, - H5_flexible_const_ptr_t buf, H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, - size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) +H5FD__subfiling_iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cur_iovec_depth, + int64_t target_datasize, int64_t start_mem_offset, + int64_t start_file_offset, H5_flexible_const_ptr_t buf, + H5FD_subfiling_io_type_t io_type, haddr_t *io_addrs_ptr, + size_t *io_sizes_ptr, H5_flexible_const_ptr_t *io_bufs_ptr) { int64_t stripe_size; int64_t block_size; int64_t total_bytes = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); - assert((cur_iovec_depth > 0) || (target_datasize == 0)); + assert(cur_iovec_depth > 0 || target_datasize == 0); assert(io_addrs_ptr); assert(io_sizes_ptr); assert(io_bufs_ptr); @@ -3687,10 +3469,10 @@ iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cu block_size = sf_context->sf_blocksize_per_stripe; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 - ", segment size = %" PRId64, - __func__, start_mem_offset, start_file_offset, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: start_mem_offset = %" PRId64 ", start_file_offset = %" PRId64 + ", segment size = %" PRId64, + __func__, start_mem_offset, start_file_offset, stripe_size); #endif *io_addrs_ptr = (haddr_t)start_file_offset; @@ -3703,11 +3485,11 @@ iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cu if (target_datasize == 0) { #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, "%s: target_datasize = 0", __func__); + H5FD__subfiling_log(sf_context->sf_context_id, "%s: target_datasize = 0", __func__); #endif *io_sizes_ptr = (size_t)0; - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); } if (target_datasize > stripe_size) { @@ -3726,10 +3508,10 @@ iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cu (io_bufs_ptr + (i * iovec_len))->vp = (char *)(buf.vp) + next_mem_offset; #ifdef H5_SUBFILING_DEBUG - H5_subfiling_log(sf_context->sf_context_id, - "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 - ", io_block_len[%zu] = %" PRId64, - __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: mem_offset[%zu] = %" PRId64 ", file_offset[%zu] = %" PRId64 + ", io_block_len[%zu] = %" PRId64, + __func__, i, next_mem_offset, i, next_file_offset, i, stripe_size); #endif next_mem_offset += block_size; @@ -3738,46 +3520,50 @@ iovec_fill_uniform(subfiling_context_t *sf_context, size_t iovec_len, int64_t cu } if (total_bytes != target_datasize) - H5_SUBFILING_GOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", - total_bytes, target_datasize); + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "total bytes (%" PRId64 ") didn't match target data size (%" PRId64 ")!", total_bytes, + target_datasize); } done: - return ret_value; + FUNC_LEAVE_NOAPI(ret_value) } #ifdef H5_SUBFILING_DEBUG -void +static void H5_subfiling_dump_iovecs(subfiling_context_t *sf_context, size_t ioreq_count, size_t iovec_len, H5FD_subfiling_io_type_t io_type, H5FD_mem_t *io_types, haddr_t *io_addrs, size_t *io_sizes, H5_flexible_const_ptr_t *io_bufs) { + FUNC_ENTER_PACKAGE_NOERR + assert(sf_context); assert(io_types); assert(io_addrs); assert(io_sizes); assert(io_bufs); - H5_subfiling_log(sf_context->sf_context_id, - "%s: I/O REQUEST VECTORS (mem type, addr, size, buf):", __func__); + H5FD__subfiling_log(sf_context->sf_context_id, + "%s: I/O REQUEST VECTORS (mem type, addr, size, buf):", __func__); for (size_t ioreq_idx = 0; ioreq_idx < ioreq_count; ioreq_idx++) { - H5_subfiling_log_nonewline(sf_context->sf_context_id, " -> I/O REQUEST %zu: ", ioreq_idx); + H5FD__subfiling_log_nonewline(sf_context->sf_context_id, " -> I/O REQUEST %zu: ", ioreq_idx); - H5_subfiling_log_nonewline(sf_context->sf_context_id, "["); + H5FD__subfiling_log_nonewline(sf_context->sf_context_id, "["); for (size_t i = 0; i < iovec_len; i++) { if (i > 0) - H5_subfiling_log_nonewline(sf_context->sf_context_id, ", "); + H5FD__subfiling_log_nonewline(sf_context->sf_context_id, ", "); - H5_subfiling_log_nonewline( + H5FD__subfiling_log_nonewline( sf_context->sf_context_id, "(%d, %" PRIuHADDR ", %zu, %p)", *(io_types + (ioreq_idx * iovec_len) + i), *(io_addrs + (ioreq_idx * iovec_len) + i), *(io_sizes + (ioreq_idx * iovec_len) + i), (io_type == IO_TYPE_WRITE) ? (const void *)(io_bufs + (ioreq_idx * iovec_len) + i)->cvp : (void *)(io_bufs + (ioreq_idx * iovec_len) + i)->vp); } - H5_subfiling_log_nonewline(sf_context->sf_context_id, "]\n"); + H5FD__subfiling_log_nonewline(sf_context->sf_context_id, "]\n"); } + + FUNC_LEAVE_NOAPI_VOID } #endif diff --git a/src/H5FDsubfiling/H5FDsubfiling_priv.h b/src/H5FDsubfiling/H5FDsubfiling_priv.h index 08fef7d1a01..cef71e15b84 100644 --- a/src/H5FDsubfiling/H5FDsubfiling_priv.h +++ b/src/H5FDsubfiling/H5FDsubfiling_priv.h @@ -38,7 +38,6 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5subfiling_common.h" -#include "H5subfiling_err.h" #define DRIVER_INFO_MESSAGE_MAX_INFO 65536 #define DRIVER_INFO_MESSAGE_MAX_LENGTH 65552 /* MAX_INFO + sizeof(info_header_t) */ diff --git a/src/H5FDsubfiling/H5subfiling_common.c b/src/H5FDsubfiling/H5subfiling_common.c index 53fb0ce3c4c..0b7dea833a4 100644 --- a/src/H5FDsubfiling/H5subfiling_common.c +++ b/src/H5FDsubfiling/H5subfiling_common.c @@ -15,8 +15,8 @@ */ #include "H5subfiling_common.h" -#include "H5subfiling_err.h" +#include "H5Eprivate.h" #include "H5MMprivate.h" typedef struct { /* Format of a context map entry */ @@ -24,12 +24,6 @@ typedef struct { /* Format of a context map entry */ int64_t sf_context_id; /* The return value if matching file_handle */ } file_map_to_context_t; -/* Identifiers for HDF5's error API */ -hid_t H5subfiling_err_stack_g = H5I_INVALID_HID; -hid_t H5subfiling_err_class_g = H5I_INVALID_HID; -char H5subfiling_mpi_error_str[MPI_MAX_ERROR_STRING]; -int H5subfiling_mpi_error_str_len; - /* MPI Datatype used to send/receive an RPC message */ MPI_Datatype H5_subfiling_rpc_msg_type = MPI_DATATYPE_NULL; @@ -48,36 +42,45 @@ static int sf_file_map_size = 0; #define DEFAULT_TOPOLOGY_CACHE_SIZE 4 #define DEFAULT_FILE_MAP_ENTRIES 8 -static herr_t H5_free_subfiling_object_int(subfiling_context_t *sf_context); -static herr_t H5_free_subfiling_topology(sf_topology_t *topology); - -static herr_t init_subfiling(const char *base_filename, uint64_t file_id, - H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, MPI_Comm comm, - int64_t *context_id_out); -static herr_t init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_config, - MPI_Comm comm, MPI_Comm node_comm, sf_topology_t **app_topology_out); -static herr_t get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_type, - char **ioc_sel_info_str); -static herr_t find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, - long iocs_per_node, sf_topology_t **app_topology); -static herr_t init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm); -static herr_t gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_comm); -static int compare_layout_nodelocal(const void *layout1, const void *layout2); -static herr_t identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_stride); -static herr_t init_subfiling_context(subfiling_context_t *sf_context, const char *base_filename, - uint64_t file_id, H5FD_subfiling_params_t *subfiling_config, - sf_topology_t *app_topology, MPI_Comm file_comm); -static herr_t init_open_file_map(void); -static herr_t record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_index); -static herr_t clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id); -static herr_t ioc_open_files(int64_t file_context_id, int file_acc_flags); -static herr_t create_config_file(subfiling_context_t *sf_context, const char *base_filename, - const char *config_dir, const char *subfile_dir, bool truncate_if_exists); -static herr_t open_config_file(const char *base_filename, const char *config_dir, uint64_t file_id, - const char *mode, FILE **config_file_out); +static int64_t H5FD__subfiling_new_object_id(sf_obj_type_t obj_type); +static herr_t H5FD__subfiling_free_context(subfiling_context_t *sf_context); +static herr_t H5FD__subfiling_free_topology(sf_topology_t *topology); + +static herr_t H5FD__subfiling_setup_context(const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, + MPI_Comm comm, int64_t *context_id_out); +static herr_t H5FD__subfiling_init_app_topology(int64_t sf_context_id, + H5FD_subfiling_params_t *subfiling_config, MPI_Comm comm, + MPI_Comm node_comm, sf_topology_t **app_topology_out); +static herr_t H5FD__subfiling_init_context(int64_t context_id, const char *prefix_env, + const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, + sf_topology_t *app_topology, MPI_Comm file_comm, + MPI_Comm node_comm, subfiling_context_t **context); +static herr_t +H5FD__subfiling_get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_type, + char **ioc_sel_info_str); +static herr_t H5FD__subfiling_find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, + long iocs_per_node, sf_topology_t **app_topology); +static herr_t H5FD__subfiling_init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm); +static herr_t H5FD__subfiling_gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, + MPI_Comm intra_comm); +static int H5FD__subfiling_compare_layout_nodelocal(const void *layout1, const void *layout2); +static herr_t H5FD__subfiling_identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, + int rank_stride); +static herr_t H5FD__subfiling_init_open_file_map(void); +static herr_t H5FD__subfiling_record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, + int *next_index); +static herr_t H5FD__subfiling_clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id); +static herr_t H5FD__subfiling_ioc_open_files(int64_t file_context_id, int file_acc_flags); +static herr_t H5FD__subfiling_create_config_file(subfiling_context_t *sf_context, const char *base_filename, + const char *config_dir, const char *subfile_dir, + bool truncate_if_exists); +static herr_t H5FD__subfiling_open_config_file(const char *base_filename, const char *config_dir, + uint64_t file_id, const char *mode, FILE **config_file_out); /*------------------------------------------------------------------------- - * Function: H5_new_subfiling_object_id + * Function: H5FD__subfiling_new_object_id * * Purpose: Given a subfiling object type and an index value, generates * a new subfiling object ID. @@ -86,28 +89,32 @@ static herr_t open_config_file(const char *base_filename, const char *config_dir * *------------------------------------------------------------------------- */ -int64_t -H5_new_subfiling_object_id(sf_obj_type_t obj_type) +static int64_t +H5FD__subfiling_new_object_id(sf_obj_type_t obj_type) { int64_t index_val = 0; + int64_t ret_value; - if (obj_type == SF_CONTEXT) { + FUNC_ENTER_PACKAGE + + if (obj_type == SF_CONTEXT) index_val = (int64_t)sf_context_cache_next_index; - } - else if (obj_type == SF_TOPOLOGY) { + else if (obj_type == SF_TOPOLOGY) index_val = (int64_t)sf_topology_cache_num_entries; - } else - return -1; + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid object type"); if (index_val < 0) - return -1; + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "invalid object index"); + + ret_value = ((int64_t)obj_type << 32) | index_val; - return (((int64_t)obj_type << 32) | index_val); +done: + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_get_subfiling_object + * Function: H5FD__subfiling_get_object * * Purpose: Given a subfiling object ID, returns a pointer to the * underlying object, which can be either a subfiling context @@ -130,32 +137,33 @@ H5_new_subfiling_object_id(sf_obj_type_t obj_type) *------------------------------------------------------------------------- */ void * -H5_get_subfiling_object(int64_t object_id) +H5FD__subfiling_get_object(int64_t object_id) { int64_t obj_type = (object_id >> 32) & 0x0FFFF; int64_t obj_index = object_id & 0x0FFFF; void *ret_value = NULL; + FUNC_ENTER_PACKAGE + if (obj_index < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, - "invalid object index for subfiling object ID %" PRId64, object_id); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid object index for subfiling object ID %" PRId64, + object_id); if (obj_type == SF_CONTEXT) { - /* Contexts provide information principally about - * the application and how the data layout is managed - * over some number of subfiles. The important - * parameters are the number of subfiles (or in the - * context of IOCs, the MPI ranks and counts of the - * processes which host an I/O Concentrator. We - * also provide a map of IOC rank to MPI rank - * to facilitate the communication of I/O requests. + /* Contexts provide information principally about the application and how + * the data layout is managed over some number of subfiles. The important + * parameters are the number of subfiles (or in the context of IOCs, the + * MPI ranks and counts of the processes which host an I/O Concentrator. + * We also provide a map of IOC rank to MPI rank to facilitate the + * communication of I/O requests. */ /* Create subfiling context cache if it doesn't exist */ if (!sf_context_cache) { - if (NULL == (sf_context_cache = calloc(DEFAULT_CONTEXT_CACHE_SIZE, sizeof(*sf_context_cache)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate space for subfiling context cache"); + if (NULL == + (sf_context_cache = H5MM_calloc(DEFAULT_CONTEXT_CACHE_SIZE * sizeof(*sf_context_cache)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, + "couldn't allocate space for subfiling context cache"); sf_context_cache_size = DEFAULT_CONTEXT_CACHE_SIZE; sf_context_cache_next_index = 0; } @@ -170,9 +178,9 @@ H5_get_subfiling_object(int64_t object_id) new_size = (sf_context_cache_size * 3) / 2; - if (NULL == (tmp_realloc = realloc(sf_context_cache, new_size * sizeof(*sf_context_cache)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate space for subfiling context cache"); + if (NULL == (tmp_realloc = H5MM_realloc(sf_context_cache, new_size * sizeof(*sf_context_cache)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, + "couldn't allocate space for subfiling context cache"); sf_context_cache = tmp_realloc; sf_context_cache_size = new_size; @@ -193,9 +201,8 @@ H5_get_subfiling_object(int64_t object_id) size_t next_idx; /* Allocate a new subfiling context object */ - if (NULL == (sf_context_cache[obj_index] = calloc(1, sizeof(subfiling_context_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate subfiling context object"); + if (NULL == (sf_context_cache[obj_index] = H5MM_calloc(sizeof(subfiling_context_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "couldn't allocate subfiling context object"); ret_value = sf_context_cache[obj_index]; @@ -214,9 +221,10 @@ H5_get_subfiling_object(int64_t object_id) else if (obj_type == SF_TOPOLOGY) { /* Create subfiling topology cache if it doesn't exist */ if (!sf_topology_cache) { - if (NULL == (sf_topology_cache = calloc(DEFAULT_TOPOLOGY_CACHE_SIZE, sizeof(*sf_topology_cache)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate space for subfiling topology cache"); + if (NULL == + (sf_topology_cache = H5MM_calloc(DEFAULT_TOPOLOGY_CACHE_SIZE * sizeof(*sf_topology_cache)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, + "couldn't allocate space for subfiling topology cache"); sf_topology_cache_size = DEFAULT_TOPOLOGY_CACHE_SIZE; sf_topology_cache_num_entries = 0; } @@ -231,9 +239,10 @@ H5_get_subfiling_object(int64_t object_id) new_size = (sf_topology_cache_size * 3) / 2; - if (NULL == (tmp_realloc = realloc(sf_topology_cache, new_size * sizeof(*sf_topology_cache)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate space for subfiling topology cache"); + if (NULL == + (tmp_realloc = H5MM_realloc(sf_topology_cache, new_size * sizeof(*sf_topology_cache)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, + "couldn't allocate space for subfiling topology cache"); sf_topology_cache = tmp_realloc; sf_topology_cache_size = new_size; @@ -261,24 +270,21 @@ H5_get_subfiling_object(int64_t object_id) assert(!sf_topology_cache[sf_topology_cache_num_entries]); /* Allocate a new subfiling topology object */ - if (NULL == (ret_value = malloc(sizeof(sf_topology_t)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, - "couldn't allocate subfiling topology object"); + if (NULL == (ret_value = H5MM_malloc(sizeof(sf_topology_t)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "couldn't allocate subfiling topology object"); sf_topology_cache[sf_topology_cache_num_entries++] = ret_value; } } -#ifdef H5_SUBFILING_DEBUG else - printf("%s: Unknown subfiling object type for ID %" PRId64 "\n", __func__, object_id); -#endif + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "unknown subfiling object type for ID %" PRId64, object_id); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_free_subfiling_object + * Function: H5FD__subfiling_free_object * * Purpose: Frees the underlying subfiling object for a given subfiling * object ID. @@ -302,22 +308,22 @@ H5_get_subfiling_object(int64_t object_id) *------------------------------------------------------------------------- */ herr_t -H5_free_subfiling_object(int64_t object_id) +H5FD__subfiling_free_object(int64_t object_id) { int64_t obj_type = (object_id >> 32) & 0x0FFFF; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (obj_type == SF_CONTEXT) { subfiling_context_t *sf_context; - if (NULL == (sf_context = H5_get_subfiling_object(object_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get subfiling context for subfiling object ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(object_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context for subfiling object ID"); if (sf_context->file_ref == 0 || --sf_context->file_ref == 0) { - if (H5_free_subfiling_object_int(sf_context) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "couldn't free subfiling context object"); + if (H5FD__subfiling_free_context(sf_context) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling context object"); for (size_t idx = 0; idx < sf_context_cache_size; idx++) { if (sf_context != sf_context_cache[idx]) @@ -333,12 +339,11 @@ H5_free_subfiling_object(int64_t object_id) else if (obj_type == SF_TOPOLOGY) { sf_topology_t *sf_topology; - if (NULL == (sf_topology = H5_get_subfiling_object(object_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get subfiling context for subfiling object ID"); + if (NULL == (sf_topology = H5FD__subfiling_get_object(object_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context for subfiling object ID"); - if (H5_free_subfiling_topology(sf_topology) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology object"); + if (H5FD__subfiling_free_topology(sf_topology) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology object"); assert(sf_topology_cache_num_entries > 0); assert(sf_topology == sf_topology_cache[sf_topology_cache_num_entries - 1]); @@ -346,91 +351,46 @@ H5_free_subfiling_object(int64_t object_id) sf_topology_cache_num_entries--; } else - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "couldn't free subfiling object - invalid object type"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "couldn't free subfiling object - invalid object type"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } static herr_t -H5_free_subfiling_object_int(subfiling_context_t *sf_context) +H5FD__subfiling_free_context(subfiling_context_t *sf_context) { int mpi_finalized; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) { - /* Assume MPI is finalized or worse, and try to clean up what we can */ - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + /* Assume MPI is finalized and try to clean up what we can */ + HMPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); mpi_finalized = 1; } - sf_context->sf_context_id = -1; - sf_context->h5_file_id = UINT64_MAX; - sf_context->threads_inited = false; - sf_context->file_ref = 0; - sf_context->sf_num_fids = 0; - sf_context->sf_num_subfiles = -1; - sf_context->sf_write_count = 0; - sf_context->sf_read_count = 0; - sf_context->sf_eof = HADDR_UNDEF; - sf_context->sf_stripe_size = -1; - sf_context->sf_blocksize_per_stripe = -1; - sf_context->sf_base_addr = -1; - - if (sf_context->sf_msg_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_msg_comm) < 0) - return FAIL; - } - sf_context->sf_msg_comm = MPI_COMM_NULL; - } - if (sf_context->sf_data_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_data_comm) < 0) - return FAIL; - } - sf_context->sf_data_comm = MPI_COMM_NULL; - } - if (sf_context->sf_eof_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_eof_comm) < 0) - return FAIL; - } - sf_context->sf_eof_comm = MPI_COMM_NULL; - } - if (sf_context->sf_node_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_node_comm) < 0) - return FAIL; - } - sf_context->sf_node_comm = MPI_COMM_NULL; + if (!mpi_finalized) { + if (H5_mpi_comm_free(&sf_context->sf_msg_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&sf_context->sf_data_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&sf_context->sf_eof_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&sf_context->sf_node_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + if (H5_mpi_comm_free(&sf_context->sf_group_comm) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); } - if (sf_context->sf_group_comm != MPI_COMM_NULL) { - if (!mpi_finalized) { - if (H5_mpi_comm_free(&sf_context->sf_group_comm) < 0) - return FAIL; - } - sf_context->sf_group_comm = MPI_COMM_NULL; - } - - sf_context->sf_group_size = -1; - sf_context->sf_group_rank = -1; - - free(sf_context->subfile_prefix); - sf_context->subfile_prefix = NULL; - free(sf_context->config_file_prefix); - sf_context->config_file_prefix = NULL; - - free(sf_context->h5_filename); - sf_context->h5_filename = NULL; - - free(sf_context->sf_fids); - sf_context->sf_fids = NULL; + H5MM_free(sf_context->subfile_prefix); + H5MM_free(sf_context->config_file_prefix); + H5MM_free(sf_context->h5_filename); + H5MM_free(sf_context->sf_fids); /* * Currently we assume that all created application topology @@ -438,25 +398,27 @@ H5_free_subfiling_object_int(subfiling_context_t *sf_context) * among multiple subfiling contexts, so we free them separately * from here to avoid issues with stale pointers. */ - sf_context->topology = NULL; + /* sf_context->topology = NULL; */ - free(sf_context); + H5MM_free(sf_context); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } static herr_t -H5_free_subfiling_topology(sf_topology_t *topology) +H5FD__subfiling_free_topology(sf_topology_t *topology) { int mpi_finalized; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(topology); if (MPI_SUCCESS != (mpi_code = MPI_Finalized(&mpi_finalized))) { - /* Assume MPI is finalized or worse, but clean up what we can */ - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); + /* Assume MPI is finalized, but clean up what we can */ + HMPI_DONE_ERROR(FAIL, "MPI_Finalized failed", mpi_code); mpi_finalized = 1; } @@ -472,41 +434,30 @@ H5_free_subfiling_topology(sf_topology_t *topology) } #endif - topology->ioc_idx = -1; - topology->n_io_concentrators = 0; - if (topology->app_layout) { - free(topology->app_layout->layout); - topology->app_layout->layout = NULL; - - free(topology->app_layout->node_ranks); - topology->app_layout->node_ranks = NULL; - - free(topology->app_layout); + H5MM_free(topology->app_layout->layout); + H5MM_free(topology->app_layout->node_ranks); + H5MM_free(topology->app_layout); } - topology->app_layout = NULL; - - free(topology->io_concentrators); - topology->io_concentrators = NULL; + H5MM_free(topology->io_concentrators); if (!mpi_finalized) if (H5_mpi_comm_free(&topology->app_comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); - free(topology); + H5MM_free(topology); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_open_subfiling_stub_file + * Function: H5FD__subfiling_open_stub_file * - * Purpose: Opens the stub file for an HDF5 file created with the - * Subfiling VFD. This stub file only contains some superblock - * metadata that can allow HDF5 applications to determine that - * the file is an HDF5 file and was created with the Subfiling - * VFD. + * Purpose: Opens the stub file for an HDF5 file created with the subfiling + * VFD. This stub file only contains some superblock metadata that + * can allow HDF5 applications to determine that the file is an HDF5 + * file and was created with the subfiling VFD. * * This routine is collective across `file_comm`; once the * stub file has been opened, the inode value for the file is @@ -517,17 +468,16 @@ H5_free_subfiling_topology(sf_topology_t *topology) * this stub file is currently only opened on MPI rank 0. Note * that this assumes that all the relevant metadata will be * written from MPI rank 0. This should be fine for now since - * the HDF file signature and Subfiling driver info is really + * the HDF file signature and subfiling driver info is really * all that's needed, but this should be revisited since the - * file metadata can and will come from other MPI ranks as - * well. + * file metadata can and will come from other MPI ranks as well. * * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- */ herr_t -H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm, H5FD_t **file_ptr, - uint64_t *file_id) +H5FD__subfiling_open_stub_file(const char *name, unsigned flags, MPI_Comm file_comm, H5FD_t **file_ptr, + uint64_t *file_id) { H5P_genplist_t *plist = NULL; uint64_t stub_file_id = UINT64_MAX; @@ -539,20 +489,22 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!name) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling stub file name"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling stub file name"); if (file_comm == MPI_COMM_NULL) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid MPI communicator"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid MPI communicator"); if (!file_id) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file ID pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file ID pointer"); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - if (!file_ptr && (mpi_rank == 0)) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL stub file pointer"); + if (!file_ptr && mpi_rank == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL stub file pointer"); /* Open stub file on MPI rank 0 only */ if (mpi_rank == 0) { @@ -561,44 +513,39 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm MPI_Info stub_info = MPI_INFO_NULL; if ((fapl_id = H5P_create_id(H5P_CLS_FILE_ACCESS_g, false)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't create FAPL for stub file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "can't create FAPL for stub file"); if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a file access property list"); + HGOTO_ERROR(H5E_VFL, H5E_BADTYPE, FAIL, "not a file access property list"); /* Use MPI I/O driver for stub file to allow access to vector I/O */ if (H5P_set(plist, H5F_ACS_MPI_PARAMS_COMM_NAME, &stub_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI communicator"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI communicator"); if (H5P_set(plist, H5F_ACS_MPI_PARAMS_INFO_NAME, &stub_info) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI info object"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI info object"); if (H5P_set_driver(plist, H5FD_MPIO, NULL, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set MPI I/O driver on FAPL"); + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set MPI I/O driver on FAPL"); if (H5FD_open(false, &stub_file, name, flags, fapl_id, HADDR_UNDEF) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "couldn't open HDF5 stub file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "couldn't open HDF5 stub file"); HDcompile_assert(sizeof(uint64_t) >= sizeof(ino_t)); /* Retrieve Inode value for stub file */ memset(&st, 0, sizeof(h5_stat_t)); - if (HDstat(name, &st) < 0) { - stub_file_id = UINT64_MAX; - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't stat HDF5 stub file, errno = %d, error message = '%s'", errno, - strerror(errno)); - } - else - stub_file_id = (uint64_t)st.st_ino; + if (HDstat(name, &st) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "couldn't stat HDF5 stub file, errno = %d, error message = '%s'", errno, + strerror(errno)); + stub_file_id = (uint64_t)st.st_ino; } - bcasted_inode = true; - - if (mpi_size > 1) { + if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&stub_file_id, 1, MPI_UINT64_T, 0, file_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + bcasted_inode = true; if (stub_file_id == UINT64_MAX) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "couldn't get inode value for HDF5 stub file"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get inode value for HDF5 stub file"); if (file_ptr) *file_ptr = stub_file; @@ -606,24 +553,22 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm done: if (fapl_id >= 0 && H5I_dec_ref(fapl_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_ID, H5E_CANTDEC, FAIL, "can't close FAPL ID"); + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't close FAPL ID"); if (ret_value < 0) { - if (!bcasted_inode && (mpi_size > 1)) { + if (!bcasted_inode && (mpi_size > 1)) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&stub_file_id, 1, MPI_UINT64_T, 0, file_comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } - if (stub_file) { + HMPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + if (stub_file) if (H5FD_close(stub_file) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "couldn't close HDF5 stub file"); - } + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close HDF5 stub file"); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_open_subfiles + * Function: H5FD__subfiling_open_subfiles * * Purpose: Initializes a subfiling context object for a file with the * given filename and file ID (inode) and opens the associated @@ -641,61 +586,59 @@ H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm *------------------------------------------------------------------------- */ herr_t -H5_open_subfiles(const char *base_filename, uint64_t file_id, H5FD_subfiling_params_t *subfiling_config, - int file_acc_flags, MPI_Comm file_comm, int64_t *context_id_out) +H5FD__subfiling_open_subfiles(const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, + MPI_Comm file_comm, int64_t *context_id_out) { - subfiling_context_t *sf_context = NULL; - int64_t context_id = -1; + subfiling_context_t *sf_context = NULL; + int64_t context_id = -1; + int mpi_size; + int err_result; bool recorded_fid = false; int mpi_code; herr_t ret_value = SUCCEED; - if (!base_filename) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "invalid subfiling base filename"); + FUNC_ENTER_PACKAGE + if (!base_filename) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "invalid subfiling base filename"); if (!subfiling_config) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "invalid subfiling configuration"); - + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "invalid subfiling configuration"); if (!context_id_out) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "invalid subfiling context ID pointer"); + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "invalid subfiling context ID pointer"); /* Make sure open file mapping is initialized in case this * is the first file open call with the VFD */ - if (init_open_file_map() < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize open file mapping"); + if (H5FD__subfiling_init_open_file_map() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize open file mapping"); /* Check if this file is already open */ - if (H5_subfile_fid_to_context(file_id, &context_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't retrieve context ID from open file mapping"); + if (H5FD__subfile_fid_to_context(file_id, &context_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't retrieve context ID from open file mapping"); if (context_id >= 0) { /* Retrieve the subfiling object for the cached context ID */ - if (NULL == (sf_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get subfiling object from context ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling object from context ID"); } else { - /* Initialize new subfiling context ID based on configuration information */ - if (init_subfiling(base_filename, file_id, subfiling_config, file_acc_flags, file_comm, &context_id) < - 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize subfiling context"); + /* Set up new subfiling context based on configuration information */ + if (H5FD__subfiling_setup_context(base_filename, file_id, subfiling_config, file_acc_flags, file_comm, + &context_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize subfiling context"); /* Retrieve the subfiling object for the newly-created context ID */ - if (NULL == (sf_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get subfiling object from context ID"); + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling object from context ID"); /* - * If this rank is an I/O concentrator, actually open - * the subfiles belonging to this IOC rank and start - * the I/O service threads + * If this rank is an I/O concentrator, actually open the subfiles + * belonging to this IOC rank and start the I/O service threads */ - if (sf_context->topology->rank_is_ioc) { - if (ioc_open_files(sf_context->sf_context_id, file_acc_flags) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "IOC couldn't open subfile"); - } + if (sf_context->topology->rank_is_ioc) + if (H5FD__subfiling_ioc_open_files(sf_context->sf_context_id, file_acc_flags) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "IOC couldn't open subfile"); } #ifdef H5_SUBFILING_DEBUG @@ -707,18 +650,17 @@ H5_open_subfiles(const char *base_filename, uint64_t file_id, H5FD_subfiling_par /* Open debugging logfile */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); snprintf(sf_context->sf_logfile_name, PATH_MAX, "%s.log.%d", sf_context->h5_filename, mpi_rank); if (NULL == (sf_context->sf_logfile = fopen(sf_context->sf_logfile_name, "a"))) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't open subfiling debug logfile"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "couldn't open subfiling debug logfile"); cur_time = time(NULL); tm = localtime(&cur_time); - H5_subfiling_log(context_id, "-- LOGGING BEGIN - %s", asctime(tm)); + H5FD__subfiling_log(context_id, "-- LOGGING BEGIN - %s", asctime(tm)); } #endif @@ -727,48 +669,35 @@ H5_open_subfiles(const char *base_filename, uint64_t file_id, H5FD_subfiling_par * There shouldn't be any issue, but check the status and * return if there was a problem. */ - if (record_fid_map_entry(sf_context->h5_file_id, sf_context->sf_context_id, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, - "couldn't record HDF5 file ID to subfile context mapping"); + if (H5FD__subfiling_record_fid_map_entry(sf_context->h5_file_id, sf_context->sf_context_id, NULL) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't record HDF5 file ID to subfile context mapping"); recorded_fid = true; *context_id_out = context_id; done: - /* - * Form consensus on whether opening subfiles was - * successful - */ - { - int mpi_size = -1; - int err_result = (ret_value < 0); - - if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_comm, &mpi_size))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - - if (mpi_size > 1) { - if (MPI_SUCCESS != - (mpi_code = MPI_Allreduce(MPI_IN_PLACE, &err_result, 1, MPI_INT, MPI_MAX, file_comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Allreduce failed", mpi_code); - } - - if (err_result) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, - "one or more IOC ranks couldn't open subfiles"); - } + /* Form consensus on whether opening subfiles was successful */ + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_comm, &mpi_size))) + HMPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + err_result = (ret_value < 0); + if (mpi_size > 1) + if (MPI_SUCCESS != + (mpi_code = MPI_Allreduce(MPI_IN_PLACE, &err_result, 1, MPI_INT, MPI_MAX, file_comm))) + HMPI_DONE_ERROR(FAIL, "MPI_Allreduce failed", mpi_code); + if (err_result) + HDONE_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "one or more IOC ranks couldn't open subfiles"); if (ret_value < 0) { - if (recorded_fid && clear_fid_map_entry(file_id, context_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "unable to clear entry from file ID to context mapping"); + if (recorded_fid && H5FD__subfiling_clear_fid_map_entry(file_id, context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "unable to clear entry from file ID to context mapping"); - if (context_id >= 0 && H5_free_subfiling_object(context_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); + if (context_id >= 0 && H5FD__subfiling_free_object(context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); *context_id_out = -1; } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* @@ -786,14 +715,14 @@ H5_open_subfiles(const char *base_filename, uint64_t file_id, H5FD_subfiling_par including malloc failures or any resource allocation problems. - Revision History -- Initial implementation ------------------------------------------------------------------------- */ static herr_t -init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_params_t *subfiling_config, - int file_acc_flags, MPI_Comm comm, int64_t *context_id_out) +H5FD__subfiling_setup_context(const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, MPI_Comm comm, + int64_t *context_id_out) { - subfiling_context_t *new_context = NULL; + subfiling_context_t *context = NULL; sf_topology_t *app_topology = NULL; MPI_Comm node_comm = MPI_COMM_NULL; int64_t context_id = -1; @@ -801,44 +730,27 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param char *file_basename = NULL; char *subfile_dir = NULL; char *prefix_env = NULL; + char *env_value = NULL; int mpi_rank; int mpi_size; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(context_id_out); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - - /* Use the file's index to create a new subfiling context ID */ - if ((context_id = H5_new_subfiling_object_id(SF_CONTEXT)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't create new subfiling context ID"); - - /* Create a new subfiling context object with the created context ID */ - if (NULL == (new_context = H5_get_subfiling_object(context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't create new subfiling object"); - new_context->sf_context_id = -1; - new_context->topology = NULL; - new_context->sf_msg_comm = MPI_COMM_NULL; - new_context->sf_data_comm = MPI_COMM_NULL; - new_context->sf_eof_comm = MPI_COMM_NULL; - new_context->sf_node_comm = MPI_COMM_NULL; - new_context->sf_group_comm = MPI_COMM_NULL; + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); /* Check if a prefix has been set for the configuration file name */ prefix_env = getenv(H5FD_SUBFILING_CONFIG_FILE_PREFIX); - if (prefix_env && (strlen(prefix_env) > 0)) { - if (NULL == (new_context->config_file_prefix = strdup(prefix_env))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "couldn't copy config file prefix string"); - } /* - * If there's an existing subfiling configuration file for - * this file, read the stripe size and number of subfiles - * from it + * If there's an existing subfiling configuration file for this file, read the + * stripe size and number of subfiles from it */ if (0 == (file_acc_flags & O_CREAT)) { int64_t config[2] = {0, 0}; /* {stripe size, num subfiles} */ @@ -848,20 +760,18 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param if (H5_dirname(base_filename, &subfile_dir) < 0) config[0] = -1; - if (config[0] >= 0) { + if (config[0] >= 0) if (H5_basename(base_filename, &file_basename) < 0) config[0] = -1; - } - if (config[0] >= 0) { + if (config[0] >= 0) /* * If a prefix has been specified, try to read the config file * from there, otherwise look for it next to the generated subfiles. */ - if (open_config_file(file_basename, prefix_env ? prefix_env : subfile_dir, file_id, "r", - &config_file) < 0) + if (H5FD__subfiling_open_config_file(file_basename, prefix_env ? prefix_env : subfile_dir, + file_id, "r", &config_file) < 0) config[0] = -1; - } if (config[0] >= 0) { if (!config_file) @@ -871,25 +781,24 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param * If a subfiling configuration file exists and we aren't truncating * it, read the number of subfiles used at file creation time. */ - if (H5_get_subfiling_config_from_file(config_file, &config[0], &config[1]) < 0) + if (H5FD__subfiling_get_config_from_file(config_file, &config[0], &config[1]) < 0) config[0] = -1; } } } - if (mpi_size > 1) { + if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(config, 2, MPI_INT64_T, 0, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); /* - * Override the stripe size and stripe count settings in the - * application's subfiling configuration if we read values - * from an existing subfiling configuration file + * Override the stripe size and stripe count settings in the application's + * subfiling configuration if we read values from an existing subfiling + * configuration file */ if (config[0] == -1) - H5_SUBFILING_GOTO_ERROR( - H5E_FILE, H5E_CANTOPENFILE, FAIL, + HGOTO_ERROR( + H5E_VFL, H5E_CANTOPENFILE, FAIL, "lead process couldn't read the number of subfiles from subfiling configuration file"); else { if (config[0] > 0) @@ -901,85 +810,83 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param } } else { - char *env_value = NULL; - /* Check for a subfiling stripe size setting from the environment */ env_value = getenv(H5FD_SUBFILING_STRIPE_SIZE); if (env_value && (strlen(env_value) > 0)) { long long stripe_size = -1; - errno = 0; - + errno = 0; stripe_size = strtoll(env_value, NULL, 0); if (ERANGE == errno) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, - "invalid stripe size setting for " H5FD_SUBFILING_STRIPE_SIZE); + HSYS_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "invalid stripe size setting for " H5FD_SUBFILING_STRIPE_SIZE); - if (stripe_size > 0) { + if (stripe_size > 0) subfiling_config->stripe_size = (int64_t)stripe_size; - } } } #if H5_CHECK_MPI_VERSION(3, 0) if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); /* Create an MPI sub-communicator for intra-node communications */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_split_type(comm, MPI_COMM_TYPE_SHARED, mpi_rank, MPI_INFO_NULL, &node_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_split_type failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_split_type failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(node_comm, MPI_ERRORS_RETURN))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); #else #error "MPI-3 required for MPI_Comm_split_type" #endif + /* Use the file's index to create a new subfiling context ID */ + if ((context_id = H5FD__subfiling_new_object_id(SF_CONTEXT)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't create new subfiling context ID"); + /* - * Setup the application topology information, including the computed + * Initialize the application topology information, including the computed * number and distribution map of the set of I/O concentrators */ - if (init_app_topology(context_id, subfiling_config, comm, node_comm, &app_topology) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize application topology"); - - new_context->sf_context_id = context_id; + if (H5FD__subfiling_init_app_topology(context_id, subfiling_config, comm, node_comm, &app_topology) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize application topology"); - if (init_subfiling_context(new_context, base_filename, file_id, subfiling_config, app_topology, comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, - "couldn't initialize subfiling application topology object"); - new_context->sf_node_comm = node_comm; + /* Initialize the subfiling context */ + if (H5FD__subfiling_init_context(context_id, prefix_env, base_filename, file_id, subfiling_config, + app_topology, comm, node_comm, &context) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize subfiling context"); + assert(context); + node_comm = MPI_COMM_NULL; /* New context takes ownership of node_comm */ *context_id_out = context_id; done: - if (config_file && (EOF == fclose(config_file))) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "couldn't close subfiling configuration file"); + if (config_file && EOF == fclose(config_file)) + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfiling configuration file"); H5MM_free(file_basename); H5MM_free(subfile_dir); if (ret_value < 0) { - if (app_topology) { - if (H5_free_subfiling_topology(app_topology) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology"); - } + if (app_topology) + if (H5FD__subfiling_free_topology(app_topology) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology"); if (H5_mpi_comm_free(&node_comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free MPI communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free MPI communicator"); - if (context_id >= 0 && H5_free_subfiling_object(context_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); + if (context_id >= 0 && context) + if (H5FD__subfiling_free_object(context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); *context_id_out = -1; } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: init_app_topology + * Function: H5FD__subfiling_init_app_topology * * Purpose: Determine the topology of the application so that MPI ranks * can be assigned as I/O concentrators. The default is to use @@ -992,8 +899,8 @@ init_subfiling(const char *base_filename, uint64_t file_id, H5FD_subfiling_param *------------------------------------------------------------------------- */ static herr_t -init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_config, MPI_Comm comm, - MPI_Comm node_comm, sf_topology_t **app_topology_out) +H5FD__subfiling_init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_config, + MPI_Comm comm, MPI_Comm node_comm, sf_topology_t **app_topology_out) { H5FD_subfiling_ioc_select_t ioc_selection_type; sf_topology_t *app_topology = NULL; @@ -1009,6 +916,8 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(subfiling_config); assert(MPI_COMM_NULL != comm); assert(MPI_COMM_NULL != node_comm); @@ -1016,16 +925,15 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf assert(!*app_topology_out); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &comm_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &comm_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); ioc_selection_type = subfiling_config->ioc_selection; /* Check if an IOC selection type was specified by environment variable */ - if (get_ioc_selection_criteria_from_env(&ioc_selection_type, &ioc_sel_str) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't get IOC selection type from environment"); + if (H5FD__subfiling_get_ioc_selection_criteria_from_env(&ioc_selection_type, &ioc_sel_str) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get IOC selection type from environment"); /* * Check parameters for the specified IOC selection strategy @@ -1039,10 +947,8 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf if (env_value && (strlen(env_value) > 0)) { errno = 0; ioc_select_val = strtol(env_value, NULL, 0); - if ((ERANGE == errno)) { - printf("invalid value '%s' for " H5FD_SUBFILING_IOC_PER_NODE "\n", env_value); + if (ERANGE == errno) ioc_select_val = 1; - } if (ioc_select_val > 0) iocs_per_node = ioc_select_val; @@ -1066,11 +972,7 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf if (ioc_sel_str) { errno = 0; ioc_select_val = strtol(ioc_sel_str, NULL, 0); - if ((ERANGE == errno) || (ioc_select_val <= 0)) { - printf("invalid IOC selection strategy string '%s' for strategy " - "SELECT_IOC_EVERY_NTH_RANK; defaulting to SELECT_IOC_ONE_PER_NODE\n", - ioc_sel_str); - + if (ERANGE == errno || ioc_select_val <= 0) { ioc_select_val = 1; ioc_selection_type = SELECT_IOC_ONE_PER_NODE; @@ -1102,11 +1004,7 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf if (ioc_sel_str) { errno = 0; ioc_select_val = strtol(ioc_sel_str, NULL, 0); - if ((ERANGE == errno) || (ioc_select_val <= 0)) { - printf("invalid IOC selection strategy string '%s' for strategy SELECT_IOC_TOTAL; " - "defaulting to SELECT_IOC_ONE_PER_NODE\n", - ioc_sel_str); - + if (ERANGE == errno || ioc_select_val <= 0) { ioc_select_val = 1; ioc_selection_type = SELECT_IOC_ONE_PER_NODE; @@ -1134,7 +1032,7 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf case SELECT_IOC_WITH_CONFIG: case ioc_selection_options: default: - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid IOC selection strategy"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid IOC selection strategy"); break; } @@ -1146,19 +1044,18 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf * eventually. */ /* Check the subfiling topology cache to see if there's a matching object */ - if (find_cached_topology_info(comm, subfiling_config, iocs_per_node, &app_topology) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "can't check for cached subfiling topology object"); + if (H5FD__subfiling_find_cached_topology_info(comm, subfiling_config, iocs_per_node, &app_topology) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check for cached subfiling topology object"); assert(!app_topology || (app_topology->selection_type == ioc_selection_type)); - if (!app_topology) { + if (NULL == app_topology) { /* Generate an ID for the application topology object */ - if ((topology_id = H5_new_subfiling_object_id(SF_TOPOLOGY)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get ID for subfiling topology object"); + if ((topology_id = H5FD__subfiling_new_object_id(SF_TOPOLOGY)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get ID for subfiling topology object"); /* Get a new application topology object from the cache */ - if (NULL == (app_topology = H5_get_subfiling_object(topology_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling topology object"); + if (NULL == (app_topology = H5FD__subfiling_get_object(topology_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling topology object"); app_topology->app_layout = NULL; app_topology->app_comm = MPI_COMM_NULL; app_topology->rank_is_ioc = false; @@ -1168,10 +1065,10 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf app_topology->selection_type = ioc_selection_type; if (H5_mpi_comm_dup(comm, &app_topology->app_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTCOPY, FAIL, "can't duplicate MPI communicator"); + HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't duplicate MPI communicator"); - if (init_app_layout(app_topology, comm, node_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize application layout"); + if (H5FD__subfiling_init_app_layout(app_topology, comm, node_comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize application layout"); assert(app_topology->app_layout); assert(app_topology->app_layout->layout); assert(app_topology->app_layout->node_ranks); @@ -1188,31 +1085,28 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf * Make sure the number of I/O concentrators doesn't * exceed the specified number of subfiles */ - if (subfiling_config->stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) { + if (subfiling_config->stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) if (app_topology->n_io_concentrators > subfiling_config->stripe_count) app_topology->n_io_concentrators = subfiling_config->stripe_count; - } /* * Determine which ranks are I/O concentrator ranks, based on the * given IOC selection strategy and MPI information. */ - if (identify_ioc_ranks(sf_context_id, app_topology, rank_multiple) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, - "couldn't determine which MPI ranks are I/O concentrators"); + if (H5FD__subfiling_identify_ioc_ranks(sf_context_id, app_topology, rank_multiple) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "couldn't determine which MPI ranks are I/O concentrators"); } *app_topology_out = app_topology; done: - if (ret_value < 0) { - if (app_topology && (topology_id >= 0)) { - if (H5_free_subfiling_object(topology_id) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free subfiling topology object"); - } - } + if (ret_value < 0) + if (app_topology && (topology_id >= 0)) + if (H5FD__subfiling_free_object(topology_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free subfiling topology object"); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /* @@ -1230,32 +1124,34 @@ init_app_topology(int64_t sf_context_id, H5FD_subfiling_params_t *subfiling_conf ------------------------------------------------------------------------- */ static herr_t -get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_type, char **ioc_sel_info_str) +H5FD__subfiling_get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_type, + char **ioc_sel_info_str) { char *opt_value = NULL; - char *env_value = getenv(H5FD_SUBFILING_IOC_SELECTION_CRITERIA); + char *env_value; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(ioc_selection_type); assert(ioc_sel_info_str); *ioc_sel_info_str = NULL; + env_value = getenv(H5FD_SUBFILING_IOC_SELECTION_CRITERIA); if (env_value && (strlen(env_value) > 0)) { /* - * Parse I/O Concentrator selection strategy criteria as - * either a single value or two colon-separated values of - * the form 'integer:[integer|string]'. If two values are - * given, the first value specifies the I/O Concentrator - * selection strategy to use (given as the integer value - * corresponding to the H5FD_subfiling_ioc_select_t enum - * value for that strategy) and the second value specifies - * the criteria for that strategy. + * Parse I/O Concentrator selection strategy criteria as either a single + * value or two colon-separated values of the form + * 'integer:[integer|string]'. If two values are given, the first value + * specifies the I/O Concentrator selection strategy to use (given as the + * integer value corresponding to the H5FD_subfiling_ioc_select_t enum + * value for that strategy) and the second value specifies the criteria + * for that strategy. * - * For example, to assign every 64th MPI rank as an I/O - * Concentrator, the criteria string should have the format - * '1:64' to specify the "every Nth rank" strategy with a - * criteria of '64'. + * For example, to assign every 64th MPI rank as an I/O Concentrator, the + * criteria string should have the format '1:64' to specify the "every + * Nth rank" strategy with a criteria of '64'. */ opt_value = strchr(env_value, ':'); if (opt_value) { @@ -1265,36 +1161,32 @@ get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_t errno = 0; check_value = strtol(env_value, NULL, 0); - if (errno == ERANGE) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "couldn't parse value from " H5FD_SUBFILING_IOC_SELECTION_CRITERIA - " environment variable"); - - if ((check_value < 0) || (check_value >= ioc_selection_options)) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_BADVALUE, FAIL, - "invalid IOC selection type value %ld from " H5FD_SUBFILING_IOC_SELECTION_CRITERIA - " environment variable", - check_value); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "couldn't parse value from " H5FD_SUBFILING_IOC_SELECTION_CRITERIA + " environment variable"); + if (check_value < 0 || check_value >= ioc_selection_options) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "invalid IOC selection type value %ld from " H5FD_SUBFILING_IOC_SELECTION_CRITERIA + " environment variable", + check_value); *ioc_selection_type = (H5FD_subfiling_ioc_select_t)check_value; *ioc_sel_info_str = opt_value; } - else { + else *ioc_sel_info_str = env_value; - } } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: find_cached_topology_info + * Function: H5FD__subfiling_find_cached_topology_info * * Purpose: Given an MPI communicator and IOC selection strategy, - * checks the subfiling topology cached to see if any matching + * checks the subfiling topology cache to see if any matching * topology objects have been cached. * * Return: Non-negative on success/Negative on failure @@ -1302,13 +1194,15 @@ get_ioc_selection_criteria_from_env(H5FD_subfiling_ioc_select_t *ioc_selection_t *------------------------------------------------------------------------- */ static herr_t -find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, long iocs_per_node, - sf_topology_t **app_topology) +H5FD__subfiling_find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, + long iocs_per_node, sf_topology_t **app_topology) { H5FD_subfiling_ioc_select_t ioc_selection_type; int32_t stripe_count; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(subf_config); ioc_selection_type = subf_config->ioc_selection; @@ -1333,10 +1227,9 @@ find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, l * is greater than the specified target number of subfiles, * reject the cached topology */ - if (stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) { + if (stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) if (stripe_count < cached_topology->n_io_concentrators) continue; - } if (cached_topology->selection_type == SELECT_IOC_ONE_PER_NODE) { assert(iocs_per_node >= 1); @@ -1353,7 +1246,7 @@ find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, l } if (MPI_SUCCESS != (mpi_code = MPI_Comm_compare(comm, cached_topology->app_comm, &result))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_compare failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_compare failed", mpi_code); if (MPI_IDENT == result || MPI_CONGRUENT == result) { *app_topology = cached_topology; @@ -1362,11 +1255,11 @@ find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, l } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: init_app_layout + * Function: H5FD__subfiling_init_app_layout * * Purpose: Determines the layout of MPI ranks across nodes in order to * figure out the final application topology @@ -1376,40 +1269,42 @@ find_cached_topology_info(MPI_Comm comm, H5FD_subfiling_params_t *subf_config, l *------------------------------------------------------------------------- */ static herr_t -init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm) +H5FD__subfiling_init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm) { app_layout_t *app_layout = NULL; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(app_topology); assert(!app_topology->app_layout); assert(MPI_COMM_NULL != comm); assert(MPI_COMM_NULL != node_comm); - if (NULL == (app_layout = calloc(1, sizeof(*app_layout)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate application layout structure"); + if (NULL == (app_layout = H5MM_calloc(sizeof(*app_layout)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate application layout structure"); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &app_layout->world_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &app_layout->world_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(node_comm, &app_layout->node_local_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(node_comm, &app_layout->node_local_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - if (NULL == (app_layout->layout = malloc((size_t)app_layout->world_size * sizeof(*app_layout->layout)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate application layout array"); + if (NULL == + (app_layout->layout = H5MM_malloc((size_t)app_layout->world_size * sizeof(*app_layout->layout)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate application layout array"); /* Gather the list of layout_t pairs to all ranks */ - if (gather_topology_info(app_layout, comm, node_comm) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't gather application topology info"); + if (H5FD__subfiling_gather_topology_info(app_layout, comm, node_comm) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't gather application topology info"); /* Sort the list according to the node local lead rank values */ - qsort(app_layout->layout, (size_t)app_layout->world_size, sizeof(layout_t), compare_layout_nodelocal); + qsort(app_layout->layout, (size_t)app_layout->world_size, sizeof(layout_t), + H5FD__subfiling_compare_layout_nodelocal); /* * Count the number of nodes by checking how many @@ -1421,40 +1316,32 @@ init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm) app_layout->node_count++; if (app_layout->node_count <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "node count less than or equal to zero"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "node count less than or equal to zero"); - if (NULL == - (app_layout->node_ranks = malloc((size_t)app_layout->node_count * sizeof(*app_layout->node_ranks)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate application layout node rank array"); + if (NULL == (app_layout->node_ranks = + H5MM_malloc((size_t)app_layout->node_count * sizeof(*app_layout->node_ranks)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate application layout node rank array"); - /* - * Record the rank value of the "lead" - * MPI rank on each node for later use - */ - for (size_t i = 0, node_rank_index = 0; i < (size_t)app_layout->world_size; i++) { - if (app_layout->layout[i].node_local_rank == 0) { - assert(node_rank_index < (size_t)app_layout->node_count); + /* Record the rank value of the "lead" MPI rank on each node for later use */ + for (size_t i = 0, node_rank_index = 0; i < (size_t)app_layout->world_size; i++) + if (app_layout->layout[i].node_local_rank == 0) app_layout->node_ranks[node_rank_index++] = app_layout->layout[i].rank; - } - } app_topology->app_layout = app_layout; done: - if (ret_value < 0) { + if (ret_value < 0) if (app_layout) { - free(app_layout->layout); - free(app_layout->node_ranks); - free(app_layout); + H5MM_free(app_layout->layout); + H5MM_free(app_layout->node_ranks); + H5MM_free(app_layout); } - } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: gather_topology_info + * Function: H5FD__subfiling_gather_topology_info * * Purpose: Collectively generate a list of layout_t structures * @@ -1463,7 +1350,7 @@ init_app_layout(sf_topology_t *app_topology, MPI_Comm comm, MPI_Comm node_comm) *------------------------------------------------------------------------- */ static herr_t -gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_comm) +H5FD__subfiling_gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_comm) { MPI_Group file_group = MPI_GROUP_NULL; MPI_Group node_group = MPI_GROUP_NULL; @@ -1476,9 +1363,13 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com int sf_world_rank; int node_local_rank; int node_local_size; + const int local_lead = 0; + int lead_rank; int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(app_layout); assert(app_layout->layout); assert(MPI_COMM_NULL != comm); @@ -1493,32 +1384,25 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com my_layout_info.node_local_size = node_local_size; /* - * Get the rank value for the "lead" rank on this - * rank's node so that we can group the layout_t - * information for all node-local ranks together + * Get the rank value for the "lead" rank on this rank's node so that we can + * group the layout_t information for all node-local ranks together */ - { - const int local_lead = 0; - int lead_rank; - - if (MPI_SUCCESS != (mpi_code = MPI_Comm_group(comm, &file_group))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_group failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Comm_group(intra_comm, &node_group))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_group failed", mpi_code); - if (MPI_SUCCESS != - (mpi_code = MPI_Group_translate_ranks(node_group, 1, &local_lead, file_group, &lead_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Group_translate_ranks failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_group(comm, &file_group))) + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_group failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Comm_group(intra_comm, &node_group))) + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_group failed", mpi_code); + if (MPI_SUCCESS != + (mpi_code = MPI_Group_translate_ranks(node_group, 1, &local_lead, file_group, &lead_rank))) + HMPI_GOTO_ERROR(FAIL, "MPI_Group_translate_ranks failed", mpi_code); + if (MPI_UNDEFINED == lead_rank) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't determine lead rank on node"); - if (MPI_UNDEFINED == lead_rank) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't determine lead rank on node"); + my_layout_info.node_lead_rank = lead_rank; - my_layout_info.node_lead_rank = lead_rank; - - if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&node_group))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Group_free failed", mpi_code); - if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&file_group))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Group_free failed", mpi_code); - } + if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&node_group))) + HMPI_GOTO_ERROR(FAIL, "MPI_Group_free failed", mpi_code); + if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&file_group))) + HMPI_GOTO_ERROR(FAIL, "MPI_Group_free failed", mpi_code); app_layout->layout[sf_world_rank] = my_layout_info; @@ -1528,47 +1412,42 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com if (MPI_SUCCESS != (mpi_code = MPI_Allgather(&my_layout_info, 4, MPI_INT, app_layout->layout, 4, MPI_INT, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code); #else - int aggr_comm_size = 0; - assert(MPI_COMM_NULL != intra_comm); /* Split the file communicator into a sub-group of one rank per node */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_split(comm, node_local_rank, sf_world_rank, &aggr_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_split failed", mpi_code); - - if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(aggr_comm, &aggr_comm_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_split failed", mpi_code); /* Allocate a partial layout info array to aggregate into from node-local ranks */ - if (node_local_rank == 0) { + if (node_local_rank == 0) if (NULL == - (layout_info_partial = malloc((size_t)node_local_size * sizeof(*layout_info_partial)))) + (layout_info_partial = H5MM_malloc((size_t)node_local_size * sizeof(*layout_info_partial)))) /* Push error, but participate in gather operation */ - H5_SUBFILING_DONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate layout info array"); - } + HDONE_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate layout info array"); - /* Gather node-local layout info to single master rank on each node */ + /* Gather node-local layout info to single leader rank on each node */ if (MPI_SUCCESS != (mpi_code = MPI_Gather(&my_layout_info, 4, MPI_INT, layout_info_partial, 4, MPI_INT, 0, intra_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Gather failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Gather failed", mpi_code); - /* Gather total layout info from/to each master rank on each node */ + /* Gather total layout info from/to each leader rank on each node */ if (node_local_rank == 0) { - int send_size = 4 * node_local_size; + int aggr_comm_size = 0; + int send_size = 4 * node_local_size; + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(aggr_comm, &aggr_comm_size))) + HMPI_DONE_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - if (NULL == (recv_counts = malloc((size_t)aggr_comm_size * sizeof(*recv_counts)))) - H5_SUBFILING_DONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate receive counts array"); - if (NULL == (recv_displs = malloc((size_t)aggr_comm_size * sizeof(*recv_displs)))) - H5_SUBFILING_DONE_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate receive displacements array"); + if (NULL == (recv_counts = H5MM_malloc((size_t)aggr_comm_size * sizeof(*recv_counts)))) + HDONE_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate receive counts array"); + if (NULL == (recv_displs = H5MM_malloc((size_t)aggr_comm_size * sizeof(*recv_displs)))) + HDONE_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate receive displacements array"); if (MPI_SUCCESS != (mpi_code = MPI_Allgather(&send_size, 1, MPI_INT, recv_counts, 1, MPI_INT, aggr_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Allgather failed", mpi_code); recv_displs[0] = 0; for (int i = 1; i < aggr_comm_size; i++) @@ -1577,44 +1456,39 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com if (MPI_SUCCESS != (mpi_code = MPI_Allgatherv(layout_info_partial, send_size, MPI_INT, app_layout->layout, recv_counts, recv_displs, MPI_INT, aggr_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Allgatherv failed", mpi_code); - - free(recv_displs); - free(recv_counts); - recv_displs = NULL; - recv_counts = NULL; + HMPI_GOTO_ERROR(FAIL, "MPI_Allgatherv failed", mpi_code); } /* - * Each master rank on each node distributes the total + * Each leader rank on each node distributes the total * layout info back to other node-local ranks */ if (MPI_SUCCESS != (mpi_code = MPI_Bcast(app_layout->layout, 4 * sf_world_size, MPI_INT, 0, intra_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); #endif } done: - free(recv_displs); - free(recv_counts); - free(layout_info_partial); + H5MM_free(recv_displs); + H5MM_free(recv_counts); + H5MM_free(layout_info_partial); if (H5_mpi_comm_free(&aggr_comm) < 0) - H5_SUBFILING_DONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free MPI communicator"); if (node_group != MPI_GROUP_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&node_group))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Group_free failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Group_free failed", mpi_code); if (file_group != MPI_GROUP_NULL) if (MPI_SUCCESS != (mpi_code = MPI_Group_free(&file_group))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Group_free failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Group_free failed", mpi_code); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: compare_layout_nodelocal + * Function: H5FD__subfiling_compare_layout_nodelocal * * Purpose: Qsort sorting callback that sorts layout_t structures * according to their node local lead MPI rank values. Ties @@ -1624,30 +1498,28 @@ gather_topology_info(app_layout_t *app_layout, MPI_Comm comm, MPI_Comm intra_com *------------------------------------------------------------------------- */ static int -compare_layout_nodelocal(const void *layout1, const void *layout2) +H5FD__subfiling_compare_layout_nodelocal(const void *layout1, const void *layout2) { const layout_t *l1 = (const layout_t *)layout1; const layout_t *l2 = (const layout_t *)layout2; - if (l1->node_lead_rank == l2->node_lead_rank) { + if (l1->node_lead_rank == l2->node_lead_rank) return (l1->node_local_rank > l2->node_local_rank) - (l1->node_local_rank < l2->node_local_rank); - } else return (l1->node_lead_rank > l2->node_lead_rank) - (l1->node_lead_rank < l2->node_lead_rank); } /*------------------------------------------------------------------------- - * Function: identify_ioc_ranks - * - * Purpose: We've already identified the number of unique nodes and - * have a sorted list of layout_t structures. Under normal - * conditions, we only utilize a single IOC per node. Under - * that circumstance, we only need to fill the - * io_concentrators vector from the node_ranks array (which - * contains the index into the layout array of lowest MPI rank - * on each node) into the io_concentrators vector; Otherwise, - * while determining the number of local ranks per node, we - * can also select one or more additional IOCs. + * Function: H5FD__subfiling_identify_ioc_ranks + * + * Purpose: We've already identified the number of unique nodes and have a + * sorted list of layout_t structures. Under normal conditions, we + * only utilize a single IOC per node. Under that circumstance, we + * only need to fill the io_concentrators vector from the node_ranks + * array (which contains the index into the layout array of lowest + * MPI rank on each node) into the io_concentrators vector; Otherwise, + * while determining the number of local ranks per node, we can also + * select one or more additional IOCs. * * As a side effect, we fill the 'io_concentrators' vector * and set the 'rank_is_ioc' flag to true if our rank is @@ -1656,13 +1528,15 @@ compare_layout_nodelocal(const void *layout1, const void *layout2) *------------------------------------------------------------------------- */ static herr_t -identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_stride) +H5FD__subfiling_identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_stride) { app_layout_t *app_layout = NULL; int *io_concentrators = NULL; int max_iocs = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(app_topology); assert(!app_topology->io_concentrators); assert(app_topology->n_io_concentrators > 0); @@ -1678,11 +1552,9 @@ identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_ app_layout = app_topology->app_layout; max_iocs = app_topology->n_io_concentrators; - - if (NULL == - (app_topology->io_concentrators = malloc((size_t)max_iocs * sizeof(*app_topology->io_concentrators)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate array of I/O concentrator ranks"); + if (NULL == (app_topology->io_concentrators = + H5MM_malloc((size_t)max_iocs * sizeof(*app_topology->io_concentrators)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate array of I/O concentrator ranks"); io_concentrators = app_topology->io_concentrators; @@ -1759,9 +1631,9 @@ identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_ #ifdef H5_SUBFILING_DEBUG if (app_topology->n_io_concentrators != total_ioc_count) - H5_subfiling_log(sf_context_id, - "%s: **WARN** Number of I/O concentrators adjusted from %d to %d", __func__, - app_topology->n_io_concentrators, total_ioc_count); + H5FD__subfiling_log(sf_context_id, + "%s: **WARN** Number of I/O concentrators adjusted from %d to %d", + __func__, app_topology->n_io_concentrators, total_ioc_count); #endif /* Set final number of I/O concentrators after adjustments */ @@ -1802,21 +1674,20 @@ identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_ case SELECT_IOC_WITH_CONFIG: case ioc_selection_options: default: - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid IOC selection strategy"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid IOC selection strategy"); break; } done: - if (ret_value < 0) { + if (ret_value < 0) if (app_topology) - free(app_topology->io_concentrators); - } + H5MM_free(app_topology->io_concentrators); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: init_subfile_context + * Function: H5FD__subfiling_init_context * * Purpose: Called as part of the HDF5 file + subfiling opening. * This initializes the subfiling context and associates @@ -1827,81 +1698,64 @@ identify_ioc_ranks(int64_t sf_context_id, sf_topology_t *app_topology, int rank_ *------------------------------------------------------------------------- */ static herr_t -init_subfiling_context(subfiling_context_t *sf_context, const char *base_filename, uint64_t file_id, - H5FD_subfiling_params_t *subfiling_config, sf_topology_t *app_topology, - MPI_Comm file_comm) +H5FD__subfiling_init_context(int64_t context_id, const char *prefix_env, const char *base_filename, + uint64_t file_id, H5FD_subfiling_params_t *subfiling_config, + sf_topology_t *app_topology, MPI_Comm file_comm, MPI_Comm node_comm, + subfiling_context_t **context) { - char *env_value = NULL; - int mpi_rank; - int mpi_code; - herr_t ret_value = SUCCEED; + subfiling_context_t *sf_context = NULL; + char *env_value = NULL; + int mpi_code; + herr_t ret_value = SUCCEED; - assert(sf_context); - assert(sf_context->topology == NULL); - assert(sf_context->sf_context_id >= 0); - assert(base_filename); - assert(file_id != UINT64_MAX); - assert(subfiling_config); - assert(app_topology); - assert(app_topology->n_io_concentrators > 0); - assert(MPI_COMM_NULL != file_comm); + FUNC_ENTER_PACKAGE + + /* Create a new subfiling context object with the created context ID */ + if (NULL == (sf_context = H5FD__subfiling_get_object(context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't create new subfiling object"); + /* Set non-zero fields */ sf_context->h5_file_id = file_id; - sf_context->threads_inited = false; - sf_context->file_ref = 0; - sf_context->sf_fids = NULL; - sf_context->sf_num_fids = 0; + sf_context->sf_context_id = context_id; sf_context->sf_num_subfiles = subfiling_config->stripe_count; - sf_context->sf_write_count = 0; - sf_context->sf_read_count = 0; sf_context->sf_eof = HADDR_UNDEF; sf_context->sf_stripe_size = H5FD_SUBFILING_DEFAULT_STRIPE_SIZE; - sf_context->sf_base_addr = 0; sf_context->sf_msg_comm = MPI_COMM_NULL; sf_context->sf_data_comm = MPI_COMM_NULL; sf_context->sf_eof_comm = MPI_COMM_NULL; - sf_context->sf_node_comm = MPI_COMM_NULL; + sf_context->sf_node_comm = node_comm; sf_context->sf_group_comm = MPI_COMM_NULL; sf_context->sf_group_size = 1; - sf_context->sf_group_rank = 0; - sf_context->subfile_prefix = NULL; - sf_context->h5_filename = NULL; - sf_context->ioc_data = NULL; sf_context->topology = app_topology; -#ifdef H5_SUBFILING_DEBUG - sf_context->sf_logfile = NULL; -#endif + /* Check if a prefix has been set for the configuration file name */ + if (prefix_env && (strlen(prefix_env) > 0)) + if (NULL == (sf_context->config_file_prefix = strdup(prefix_env))) + HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "couldn't copy config file prefix string"); if (NULL == (sf_context->h5_filename = strdup(base_filename))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for subfiling filename"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate space for subfiling filename"); /* Check for a subfile name prefix setting in the environment */ env_value = getenv(H5FD_SUBFILING_SUBFILE_PREFIX); - if (env_value && (strlen(env_value) > 0)) { + if (env_value && (strlen(env_value) > 0)) if (NULL == (sf_context->subfile_prefix = strdup(env_value))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't copy subfile prefix value"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't copy subfile prefix value"); - /* - * Set IOC stripe size from subfiling configuration - */ + /* Set IOC stripe size from subfiling configuration */ if (subfiling_config->stripe_size > 0) sf_context->sf_stripe_size = subfiling_config->stripe_size; /* - * If still set to the default, set the number of subfiles - * according to the default mapping of 1 I/O concentrator - * -> 1 subfile + * If still set to the default, set the number of subfiles according to the + * default mapping of 1 I/O concentrator -> 1 subfile */ if (sf_context->sf_num_subfiles == H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) sf_context->sf_num_subfiles = app_topology->n_io_concentrators; /* - * Set blocksize per stripe value after possibly adjusting - * for user-specified subfile stripe size and number of - * subfiles + * Set blocksize per stripe value after possibly adjusting for user-specified + * subfile stripe size and number of subfiles */ sf_context->sf_blocksize_per_stripe = sf_context->sf_stripe_size * sf_context->sf_num_subfiles; @@ -1912,9 +1766,8 @@ init_subfiling_context(subfiling_context_t *sf_context, const char *base_filenam sf_context->sf_base_addr = (int64_t)(app_topology->ioc_idx * sf_context->sf_stripe_size); /* - * Calculate the number of subfiles this rank owns by - * round-robining them across the available IOCs and - * then allocate an array for the subfile IDs + * Calculate the number of subfiles this rank owns by round-robining them + * across the available IOCs and then allocate an array for the subfile IDs */ sf_context->sf_num_fids = sf_context->sf_num_subfiles / app_topology->n_io_concentrators; @@ -1922,70 +1775,70 @@ init_subfiling_context(subfiling_context_t *sf_context, const char *base_filenam if (leftover_subfiles && (leftover_subfiles > app_topology->ioc_idx)) sf_context->sf_num_fids++; - if (NULL == - (sf_context->sf_fids = malloc((size_t)sf_context->sf_num_fids * sizeof(*sf_context->sf_fids)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't allocate subfile IDs array"); + if (NULL == (sf_context->sf_fids = + H5MM_malloc((size_t)sf_context->sf_num_fids * sizeof(*sf_context->sf_fids)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate subfile IDs array"); for (int i = 0; i < sf_context->sf_num_fids; i++) sf_context->sf_fids[i] = -1; } - /* - * Set up various MPI sub-communicators for MPI operations - * to/from IOC ranks - */ - - if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + /* Set up various MPI sub-communicators for MPI operations to/from IOC ranks */ if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(file_comm, &sf_context->sf_msg_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(sf_context->sf_msg_comm, MPI_ERRORS_RETURN))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(file_comm, &sf_context->sf_data_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(sf_context->sf_data_comm, MPI_ERRORS_RETURN))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(file_comm, &sf_context->sf_eof_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_set_errhandler(sf_context->sf_eof_comm, MPI_ERRORS_RETURN))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_set_errhandler failed", mpi_code); /* Create an MPI sub-communicator for IOC ranks */ if (app_topology->n_io_concentrators > 1) { + int mpi_rank; + + if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(file_comm, &mpi_rank))) + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_split(file_comm, app_topology->rank_is_ioc, mpi_rank, &sf_context->sf_group_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_split failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_split failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(sf_context->sf_group_comm, &sf_context->sf_group_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); - + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(sf_context->sf_group_comm, &sf_context->sf_group_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); } /* Perform some final validation of subfiling configuration */ if (sf_context->sf_stripe_size <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid subfiling stripe size (%" PRId64 ")", - sf_context->sf_stripe_size); - + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid subfiling stripe size (%" PRId64 ")", + sf_context->sf_stripe_size); if (sf_context->sf_num_subfiles <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid subfiling stripe count (%d)", - sf_context->sf_num_subfiles); - + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid subfiling stripe count (%d)", + sf_context->sf_num_subfiles); assert(sf_context->sf_num_subfiles >= app_topology->n_io_concentrators); + *context = sf_context; + done: - H5_SUBFILING_FUNC_LEAVE; + if (ret_value < 0) { + if (context_id >= 0 && H5FD__subfiling_free_object(context_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling object"); + *context = NULL; + } + + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: init_open_file_map + * Function: H5FD__subfiling_init_open_file_map * * Purpose: Allocates and initializes an array that keeps a mapping * between a file's inode value (__ino_t st_ino) and the ID @@ -1996,13 +1849,16 @@ init_subfiling_context(subfiling_context_t *sf_context, const char *base_filenam *------------------------------------------------------------------------- */ static herr_t -init_open_file_map(void) +H5FD__subfiling_init_open_file_map(void) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!sf_open_file_map) { - if (NULL == (sf_open_file_map = malloc((size_t)DEFAULT_FILE_MAP_ENTRIES * sizeof(*sf_open_file_map)))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't allocate open file mapping"); + if (NULL == + (sf_open_file_map = H5MM_malloc((size_t)DEFAULT_FILE_MAP_ENTRIES * sizeof(*sf_open_file_map)))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate open file mapping"); sf_file_map_size = DEFAULT_FILE_MAP_ENTRIES; for (int i = 0; i < sf_file_map_size; i++) { @@ -2012,24 +1868,23 @@ init_open_file_map(void) } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: record_fid_map_entry + * Function: H5FD__subfiling_record_fid_map_entry * - * Purpose: Every opened HDF5 file will have (if utilizing subfiling) - * a subfiling context associated with it. It is important that - * the HDF5 file index is a constant rather than utilizing a - * posix file handle since files can be opened multiple times - * and with each file open, a new file handle will be assigned. - * Note that in such a case, the actual filesystem id will be - * retained. + * Purpose: Every opened HDF5 file that uses subfiling will have a subfiling + * context associated with it. It is important that the HDF5 file + * index is a constant rather than utilizing a POSIX file handle + * since files can be opened multiple times and with each file open, + * a new file handle will be assigned. Note that in such a case, the + * actual filesystem id will be retained. * - * We utilize that filesystem id (ino_t inode) so that - * irrespective of what process opens a common file, the - * subfiling system will generate a consistent context for this - * file across all parallel ranks. + * We use the filesystem id (ino_t inode) so that irrespective of + * what process opens a common file, the subfiling system will + * generate a consistent context for this file across all parallel + * ranks. * * This function simply records the filesystem handle to * subfiling context mapping. @@ -2039,19 +1894,21 @@ init_open_file_map(void) *------------------------------------------------------------------------- */ static herr_t -record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_index) +H5FD__subfiling_record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_index) { subfiling_context_t *sf_context = NULL; int index; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + for (index = 0; index < sf_file_map_size; index++) { if (sf_open_file_map[index].file_id == file_id) { /* Increment file ref. count for this context */ - if (NULL == (sf_context = H5_get_subfiling_object(sf_open_file_map[index].sf_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_open_file_map[index].sf_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); sf_context->file_ref++; - goto done; + HGOTO_DONE(SUCCEED); } if (sf_open_file_map[index].file_id == UINT64_MAX) { @@ -2059,52 +1916,48 @@ record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_ind sf_open_file_map[index].sf_context_id = subfile_context_id; /* First open of this file - set file ref. count to 1 for this context */ - if (NULL == (sf_context = H5_get_subfiling_object(subfile_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(subfile_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); sf_context->file_ref = 1; - if (next_index) { + if (next_index) *next_index = index; - } - goto done; + HGOTO_DONE(SUCCEED); } } if (index == sf_file_map_size) { void *tmp_realloc; - if (NULL == (tmp_realloc = realloc(sf_open_file_map, - ((size_t)(sf_file_map_size * 2) * sizeof(*sf_open_file_map))))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't reallocate open file mapping"); + if (NULL == (tmp_realloc = H5MM_realloc( + sf_open_file_map, ((size_t)(sf_file_map_size * 2) * sizeof(*sf_open_file_map))))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't reallocate open file mapping"); sf_open_file_map = tmp_realloc; sf_file_map_size *= 2; - for (int i = index; i < sf_file_map_size; i++) { + for (int i = index; i < sf_file_map_size; i++) sf_open_file_map[i].file_id = UINT64_MAX; - } - if (next_index) { + if (next_index) *next_index = index; - } sf_open_file_map[index].file_id = file_id; sf_open_file_map[index].sf_context_id = subfile_context_id; /* First open of this file - set file ref. count to 1 for this context */ - if (NULL == (sf_context = H5_get_subfiling_object(subfile_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); + if (NULL == (sf_context = H5FD__subfiling_get_object(subfile_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context"); sf_context->file_ref = 1; } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: clear_fid_map_entry + * Function: H5FD__subfiling_clear_fid_map_entry * * Purpose: Remove the map entry associated with the file->inode. * This is done at file close. @@ -2114,39 +1967,66 @@ record_fid_map_entry(uint64_t file_id, int64_t subfile_context_id, int *next_ind *------------------------------------------------------------------------- */ static herr_t -clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id) +H5FD__subfiling_clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!sf_open_file_map) - H5_SUBFILING_GOTO_DONE(SUCCEED); + HGOTO_DONE(SUCCEED); for (int i = 0; i < sf_file_map_size; i++) { - subfiling_context_t *sf_context = NULL; + if (sf_open_file_map[i].file_id == file_id && sf_open_file_map[i].sf_context_id == sf_context_id) { + subfiling_context_t *sf_context; - if ((sf_open_file_map[i].file_id != file_id) || (sf_open_file_map[i].sf_context_id != sf_context_id)) - continue; + /* Only clear map entry if this is the last file + * holding a reference to the context + */ + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context object"); - /* Only clear map entry if this is the last file - * holding a reference to the context - */ - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling context object"); + if (sf_context->file_ref == 0 || sf_context->file_ref == 1) { + sf_open_file_map[i].file_id = UINT64_MAX; + sf_open_file_map[i].sf_context_id = -1; + } - if (sf_context->file_ref == 0 || sf_context->file_ref == 1) { - sf_open_file_map[i].file_id = UINT64_MAX; - sf_open_file_map[i].sf_context_id = -1; + break; } - - break; } done: - return ret_value; -} /* end clear_fid_map_entry() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__subfiling_clear_fid_map_entry() */ /*------------------------------------------------------------------------- - * Function: ioc_open_files + * Function: H5FD__subfiling_get_default_ioc_config + * + * Purpose: This simply fills in + * the basics. This avoids the necessity of having the + * user write code to initialize the config structure. + * + * Return: SUCCEED/FAIL + *------------------------------------------------------------------------- + */ +herr_t +H5FD__subfiling_get_default_ioc_config(H5FD_ioc_config_t *config) +{ + FUNC_ENTER_PACKAGE_NOERR + + assert(config); + + memset(config, 0, sizeof(*config)); + + config->magic = H5FD_IOC_FAPL_MAGIC; + config->version = H5FD_IOC_CURR_FAPL_VERSION; + config->thread_pool_size = H5FD_IOC_DEFAULT_THREAD_POOL_SIZE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} + +/*------------------------------------------------------------------------- + * Function: H5FD__subfiling_ioc_open_files * * Purpose: This function is called by an I/O concentrator in order to * open the subfiles it is responsible for. @@ -2179,7 +2059,7 @@ clear_fid_map_entry(uint64_t file_id, int64_t sf_context_id) *------------------------------------------------------------------------- */ static herr_t -ioc_open_files(int64_t file_context_id, int file_acc_flags) +H5FD__subfiling_ioc_open_files(int64_t file_context_id, int file_acc_flags) { subfiling_context_t *sf_context = NULL; mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; @@ -2190,9 +2070,10 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) int num_digits = 0; herr_t ret_value = SUCCEED; - if (NULL == (sf_context = H5_get_subfiling_object(file_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, - "couldn't get subfiling object from context ID"); + FUNC_ENTER_PACKAGE + + if (NULL == (sf_context = H5FD__subfiling_get_object(file_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "couldn't get subfiling object from context ID"); assert(sf_context->h5_file_id != UINT64_MAX); assert(sf_context->h5_filename); @@ -2204,7 +2085,7 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) /* Get the basename of the full HDF5 filename */ if (H5_basename(sf_context->h5_filename, &base) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get HDF5 file basename"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't get HDF5 file basename"); /* * Get the directory prefix where subfiles will be placed. @@ -2214,16 +2095,13 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) */ if (sf_context->subfile_prefix) { if (NULL == (subfile_dir = H5MM_strdup(sf_context->subfile_prefix))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't copy subfile prefix"); - } - else { - if (H5_dirname(sf_context->h5_filename, &subfile_dir) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "couldn't get HDF5 file dirname"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't copy subfile prefix"); } + else if (H5_dirname(sf_context->h5_filename, &subfile_dir) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't get HDF5 file dirname"); - if (NULL == (filepath = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for subfile filename"); + if (NULL == (filepath = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "couldn't allocate space for subfile filename"); num_subfiles = sf_context->sf_num_subfiles; num_digits = (int)(log10(num_subfiles) + 1); @@ -2253,7 +2131,7 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) sf_context->h5_file_id, num_digits, subfile_idx, num_subfiles); if ((sf_context->sf_fids[i] = HDopen(filepath, file_acc_flags, mode)) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "failed to open subfile"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "failed to open subfile"); } if (file_acc_flags & O_CREAT) @@ -2276,31 +2154,29 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) else config_dir = subfile_dir; - if (create_config_file(sf_context, base, config_dir, subfile_dir, (file_acc_flags & O_TRUNC)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, - "couldn't create subfiling configuration file"); + if (H5FD__subfiling_create_config_file(sf_context, base, config_dir, subfile_dir, + (file_acc_flags & O_TRUNC)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTCREATE, FAIL, "couldn't create subfiling configuration file"); } done: - if (ret_value < 0) { - if (sf_context) { + if (ret_value < 0) + if (sf_context) for (int i = 0; i < sf_context->sf_num_fids; i++) { if (sf_context->sf_fids[i] >= 0 && HDclose(sf_context->sf_fids[i]) < 0) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "failed to close subfile"); + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "failed to close subfile"); sf_context->sf_fids[i] = -1; } - } - } H5MM_free(base); H5MM_free(subfile_dir); - free(filepath); + H5MM_free(filepath); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: create_config_file + * Function: H5FD__subfiling_create_config_file * * Purpose: Creates a configuration file that contains * subfiling-related information for a file. This file @@ -2317,8 +2193,8 @@ ioc_open_files(int64_t file_context_id, int file_acc_flags) *------------------------------------------------------------------------- */ static herr_t -create_config_file(subfiling_context_t *sf_context, const char *base_filename, const char *config_dir, - const char *subfile_dir, bool truncate_if_exists) +H5FD__subfiling_create_config_file(subfiling_context_t *sf_context, const char *base_filename, + const char *config_dir, const char *subfile_dir, bool truncate_if_exists) { bool config_file_exists = false; FILE *config_file = NULL; @@ -2327,25 +2203,25 @@ create_config_file(subfiling_context_t *sf_context, const char *base_filename, c int ret = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(sf_context); assert(base_filename); assert(config_dir); assert(subfile_dir); if (sf_context->h5_file_id == UINT64_MAX) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "invalid HDF5 file ID %" PRIu64, - sf_context->h5_file_id); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid HDF5 file ID %" PRIu64, sf_context->h5_file_id); if (*base_filename == '\0') - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "invalid base HDF5 filename '%s'", - base_filename); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid base HDF5 filename '%s'", base_filename); if (*config_dir == '\0') config_dir = "."; if (*subfile_dir == '\0') subfile_dir = "."; - if (NULL == (config_filename = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for subfiling configuration filename"); + if (NULL == (config_filename = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "couldn't allocate space for subfiling configuration filename"); snprintf(config_filename, PATH_MAX, "%s/" H5FD_SUBFILING_CONFIG_FILENAME_TEMPLATE, config_dir, base_filename, sf_context->h5_file_id); @@ -2356,57 +2232,51 @@ create_config_file(subfiling_context_t *sf_context, const char *base_filename, c config_file_exists = (ret == 0) || ((ret < 0) && (ENOENT != errno)); - if (config_file_exists && (ret != 0)) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't check existence of subfiling configuration file"); + if (config_file_exists && ret != 0) + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, + "couldn't check existence of subfiling configuration file"); /* - * If a config file doesn't exist, create one. If a - * config file does exist, don't touch it unless the - * O_TRUNC flag was specified. In this case, truncate - * the existing config file and create a new one. + * If a config file doesn't exist, create one. If a config file does exist, + * don't touch it unless the O_TRUNC flag was specified. In this case, + * truncate the existing config file and create a new one. */ if (!config_file_exists || truncate_if_exists) { int n_subfiles = sf_context->sf_num_subfiles; int num_digits; if (NULL == (config_file = fopen(config_filename, "w+"))) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't create/truncate subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, + "couldn't create/truncate subfiling configuration file"); - if (NULL == (line_buf = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate buffer for writing to subfiling configuration file"); + if (NULL == (line_buf = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "couldn't allocate buffer for writing to subfiling configuration file"); /* Write the subfiling stripe size to the configuration file */ snprintf(line_buf, PATH_MAX, "stripe_size=%" PRId64 "\n", sf_context->sf_stripe_size); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write the number of I/O concentrators to the configuration file */ snprintf(line_buf, PATH_MAX, "aggregator_count=%d\n", sf_context->topology->n_io_concentrators); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write the number of subfiles to the configuration file */ snprintf(line_buf, PATH_MAX, "subfile_count=%d\n", n_subfiles); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write the base HDF5 filename to the configuration file */ snprintf(line_buf, PATH_MAX, "hdf5_file=%s\n", sf_context->h5_filename); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write the optional subfile directory prefix to the configuration file */ snprintf(line_buf, PATH_MAX, "subfile_dir=%s\n", subfile_dir); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, "failed to write to subfiling configuration file"); /* Write out each subfile name to the configuration file */ num_digits = (int)(log10(n_subfiles) + 1); @@ -2415,41 +2285,38 @@ create_config_file(subfiling_context_t *sf_context, const char *base_filename, c sf_context->h5_file_id, num_digits, k + 1, n_subfiles); if (fwrite(line_buf, strlen(line_buf), 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, - "failed to write to subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_WRITEERROR, FAIL, + "failed to write to subfiling configuration file"); } } done: - if (config_file) { + if (config_file) if (EOF == fclose(config_file)) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "couldn't close subfiling configuration file"); - } + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfiling configuration file"); - free(line_buf); - free(config_filename); + H5MM_free(line_buf); + H5MM_free(config_filename); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: open_config_file + * Function: H5FD__subfiling_open_config_file * * Purpose: Opens the subfiling configuration file for a given HDF5 * file and sets `config_file_out`, if a configuration file * exists. Otherwise, `config_file_out` is set to NULL. * - * It is the caller's responsibility to check - * `config_file_out` on success and close an opened file as - * necessary. + * It is the caller's responsibility to check `config_file_out` + * on success and close an opened file as necessary. * * Return: Non-negative on success/Negative on failure *------------------------------------------------------------------------- */ static herr_t -open_config_file(const char *base_filename, const char *config_dir, uint64_t file_id, const char *mode, - FILE **config_file_out) +H5FD__subfiling_open_config_file(const char *base_filename, const char *config_dir, uint64_t file_id, + const char *mode, FILE **config_file_out) { bool config_file_exists = false; FILE *config_file = NULL; @@ -2457,6 +2324,8 @@ open_config_file(const char *base_filename, const char *config_dir, uint64_t fil int ret = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(base_filename); assert(config_dir); assert(file_id != UINT64_MAX); @@ -2466,14 +2335,13 @@ open_config_file(const char *base_filename, const char *config_dir, uint64_t fil *config_file_out = NULL; if (*base_filename == '\0') - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "invalid base HDF5 filename '%s'", - base_filename); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, "invalid base HDF5 filename '%s'", base_filename); if (*config_dir == '\0') config_dir = "."; - if (NULL == (config_filename = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for subfiling configuration filename"); + if (NULL == (config_filename = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "couldn't allocate space for subfiling configuration filename"); snprintf(config_filename, PATH_MAX, "%s/" H5FD_SUBFILING_CONFIG_FILENAME_TEMPLATE, config_dir, base_filename, file_id); @@ -2485,32 +2353,29 @@ open_config_file(const char *base_filename, const char *config_dir, uint64_t fil config_file_exists = (ret == 0) || ((ret < 0) && (ENOENT != errno)); if (!config_file_exists) - goto done; + HGOTO_DONE(SUCCEED); - if (config_file_exists && (ret != 0)) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't check existence of subfiling configuration file"); + if (config_file_exists && ret != 0) + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, + "couldn't check existence of subfiling configuration file"); if (NULL == (config_file = fopen(config_filename, mode))) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, - "couldn't open subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, FAIL, "couldn't open subfiling configuration file"); *config_file_out = config_file; done: - if (ret_value < 0) { + if (ret_value < 0) if (config_file && (EOF == fclose(config_file))) - H5_SUBFILING_DONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, - "couldn't close subfiling configuration file"); - } + HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfiling configuration file"); - free(config_filename); + H5MM_free(config_filename); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_get_subfiling_config_from_file + * Function: H5FD__subfiling_get_config_from_file * * Purpose: Reads a Subfiling configuration file to get the stripe size * and number of subfiles used for the logical HDF5 file. @@ -2520,7 +2385,7 @@ open_config_file(const char *base_filename, const char *config_dir, uint64_t fil *------------------------------------------------------------------------- */ herr_t -H5_get_subfiling_config_from_file(FILE *config_file, int64_t *stripe_size, int64_t *num_subfiles) +H5FD__subfiling_get_config_from_file(FILE *config_file, int64_t *stripe_size, int64_t *num_subfiles) { int64_t read_stripe_size = 0; int64_t read_num_subfiles = 0; @@ -2529,73 +2394,71 @@ H5_get_subfiling_config_from_file(FILE *config_file, int64_t *stripe_size, int64 long config_file_len = 0; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(config_file); if (HDfseek(config_file, 0, SEEK_END) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, - "couldn't seek to end of subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, "couldn't seek to end of subfiling configuration file"); if ((config_file_len = HDftell(config_file)) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, - "couldn't get size of subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get size of subfiling configuration file"); if (HDfseek(config_file, 0, SEEK_SET) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, - "couldn't seek to beginning of subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_SEEKERROR, FAIL, + "couldn't seek to beginning of subfiling configuration file"); - if (NULL == (config_buf = malloc((size_t)config_file_len + 1))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "couldn't allocate space for reading from subfiling configuration file"); + if (NULL == (config_buf = H5MM_malloc((size_t)config_file_len + 1))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, + "couldn't allocate space for reading from subfiling configuration file"); if (fread(config_buf, (size_t)config_file_len, 1, config_file) != 1) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, - "couldn't read from subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "couldn't read from subfiling configuration file"); config_buf[config_file_len] = '\0'; if (stripe_size) { if (NULL == (substr = strstr(config_buf, "stripe_size"))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, - "malformed subfiling configuration file - no stripe size entry"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "malformed subfiling configuration file - no stripe size entry"); if (EOF == sscanf(substr, "stripe_size=%" PRId64, &read_stripe_size)) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, - "couldn't get stripe size from subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "couldn't get stripe size from subfiling configuration file"); if (read_stripe_size <= 0) - H5_SUBFILING_GOTO_ERROR( - H5E_FILE, H5E_BADVALUE, FAIL, - "invalid stripe size (%" PRId64 ") read from subfiling configuration file", read_stripe_size); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "invalid stripe size (%" PRId64 ") read from subfiling configuration file", + read_stripe_size); *stripe_size = read_stripe_size; } if (num_subfiles) { if (NULL == (substr = strstr(config_buf, "subfile_count"))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, - "malformed subfiling configuration file - no subfile count entry"); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "malformed subfiling configuration file - no subfile count entry"); if (EOF == sscanf(substr, "subfile_count=%" PRId64, &read_num_subfiles)) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, - "couldn't get number of subfiles from subfiling configuration file"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "couldn't get number of subfiles from subfiling configuration file"); if (read_num_subfiles <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, - "invalid number of subfiles (%" PRId64 - ") read from subfiling configuration file", - read_num_subfiles); + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, FAIL, + "invalid number of subfiles (%" PRId64 ") read from subfiling configuration file", + read_num_subfiles); *num_subfiles = read_num_subfiles; } done: - free(config_buf); + H5MM_free(config_buf); - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_resolve_pathname + * Function: H5FD__subfiling_resolve_pathname * * Purpose: Simple wrapper routine around realpath(3) to fully resolve * a given filepath. Collective across the specified MPI @@ -2610,7 +2473,7 @@ H5_get_subfiling_config_from_file(FILE *config_file, int64_t *stripe_size, int64 *------------------------------------------------------------------------- */ herr_t -H5_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepath) +H5FD__subfiling_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepath) { hsize_t path_len = HSIZE_UNDEF; bool bcasted_path_len = false; @@ -2624,121 +2487,104 @@ H5_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepat int mpi_code; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(filepath); assert(resolved_filepath); if (MPI_SUCCESS != (mpi_code = MPI_Comm_rank(comm, &mpi_rank))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_rank failed", mpi_code); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); if (mpi_rank == 0) { + errno = 0; if (NULL == (resolved_path = HDrealpath(filepath, NULL))) { if (ENOENT == errno) { if (H5_dirname(filepath, &file_dirname) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file dirname"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't get file dirname"); /* If filepath is just the filename, set up path using CWD */ if (!strcmp(file_dirname, ".")) { - if (NULL == (resolved_path = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate buffer for filepath"); + if (NULL == (resolved_path = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate buffer for filepath"); if (H5_basename(filepath, &file_basename) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't get file basename"); - if (NULL == (cwd = malloc(PATH_MAX))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, - "can't allocate buffer for CWD"); + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't get file basename"); + if (NULL == (cwd = H5MM_malloc(PATH_MAX))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate buffer for CWD"); if (NULL == HDgetcwd(cwd, PATH_MAX)) - H5_SUBFILING_GOTO_ERROR( - H5E_VFL, H5E_CANTGET, FAIL, - "can't get current working directory, errno = %d, error message = '%s'", errno, - strerror(errno)); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "can't get current working directory, errno = %d, error message = '%s'", + errno, strerror(errno)); snprintf(resolved_path, PATH_MAX, "%s/%s", cwd, file_basename); } - else { + else /* Otherwise, just use what was given as the pathname */ if (NULL == (resolved_path = strdup(filepath))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't copy filename"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't copy filename"); } else - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, - "can't resolve subfile path, errno = %d, error message = '%s'", errno, - strerror(errno)); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "can't resolve subfile path, errno = %d, error message = '%s'", errno, + strerror(errno)); } - if (resolved_path) { + if (resolved_path) H5_CHECKED_ASSIGN(path_len, hsize_t, (strlen(resolved_path) + 1), size_t); - } else path_len = HSIZE_UNDEF; } /* Broadcast the size of the resolved filepath string to other ranks */ bcasted_path_len = true; - if (mpi_size > 1) { + if (mpi_size > 1) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&path_len, 1, HSIZE_AS_MPI_TYPE, 0, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); if (path_len == HSIZE_UNDEF) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't resolve filepath"); + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't resolve filepath"); - if (mpi_rank != 0) { - if (NULL == (resolved_path = malloc(path_len))) - H5_SUBFILING_GOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate file name buffer"); - } + if (mpi_rank != 0) + if (NULL == (resolved_path = H5MM_malloc(path_len))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, FAIL, "can't allocate file name buffer"); /* Broadcast the resolved filepath to other ranks */ bcasted_path = true; if (mpi_size > 1) { H5_CHECK_OVERFLOW(path_len, hsize_t, int); if (MPI_SUCCESS != (mpi_code = MPI_Bcast(resolved_path, (int)path_len, MPI_CHAR, 0, comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Bcast failed", mpi_code); } *resolved_filepath = resolved_path; done: - free(cwd); + H5MM_free(cwd); H5MM_free(file_basename); H5MM_free(file_dirname); if (ret_value < 0) { - if (!bcasted_path_len) { + if (!bcasted_path_len) if (MPI_SUCCESS != (mpi_code = MPI_Bcast(&path_len, 1, HSIZE_AS_MPI_TYPE, 0, comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); - } + HMPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); if (!bcasted_path && (path_len != HSIZE_UNDEF)) { H5_CHECK_OVERFLOW(path_len, hsize_t, int); if (MPI_SUCCESS != (mpi_code = MPI_Bcast(resolved_path, (int)path_len, MPI_CHAR, 0, comm))) - H5_SUBFILING_MPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); + HMPI_DONE_ERROR(FAIL, "MPI_Bcast failed", mpi_code); } - free(resolved_path); + H5MM_free(resolved_path); } - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_close_subfiles - * - * Purpose: This is a simple wrapper function for the internal version - * which actually manages all subfile closing via commands - * to the set of IO Concentrators. - * - * Return: Success (0) or Failure (non-zero) - * Errors: If MPI operations fail for some reason. - * - *------------------------------------------------------------------------- - */ -/*------------------------------------------------------------------------- - * Function: Internal close__subfiles + * Function: H5FD__subfiling_close_subfiles * - * Purpose: When closing and HDF5 file, we need to close any associated + * Purpose: When closing an HDF5 file, we need to close any associated * subfiles as well. This function cycles through all known * IO Concentrators to send a file CLOSE_OP command. * @@ -2757,7 +2603,7 @@ H5_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepat *------------------------------------------------------------------------- */ herr_t -H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) +H5FD__subfiling_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) { subfiling_context_t *sf_context = NULL; MPI_Request barrier_req = MPI_REQUEST_NULL; @@ -2765,84 +2611,78 @@ H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) int mpi_code; herr_t ret_value = SUCCEED; - if (NULL == (sf_context = H5_get_subfiling_object(subfiling_context_id))) - H5_SUBFILING_GOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "couldn't get subfiling object from context ID"); + FUNC_ENTER_PACKAGE + + if (NULL == (sf_context = H5FD__subfiling_get_object(subfiling_context_id))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "couldn't get subfiling object from context ID"); if (MPI_SUCCESS != (mpi_code = MPI_Comm_size(file_comm, &mpi_size))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Comm_size failed", mpi_code); - /* We make the subfile close operation collective. - * Otherwise, there may be a race condition between - * our closing the subfiles and the user application + /* We make the subfile close operation collective. Otherwise, there may be a + * race condition between our closing the subfiles and the user application * moving ahead and possibly re-opening a file. * - * If we can, we utilize an async barrier which gives - * us the opportunity to reduce the CPU load due to - * MPI spinning while waiting for the barrier to - * complete. This is especially important if there - * is heavy thread utilization due to subfiling - * activities, i.e. the thread pool might be - * extremely busy servicing I/O requests from all - * HDF5 application ranks. + * If we can, we utilize an async barrier which gives us the opportunity to + * reduce the CPU load due to MPI spinning while waiting for the barrier to + * complete. This is especially important if there is heavy thread + * utilization due to subfiling activities, i.e. the thread pool might be + * busy servicing I/O requests from all HDF5 application ranks. */ if (mpi_size > 1) { #if H5_CHECK_MPI_VERSION(3, 1) int barrier_complete = 0; if (MPI_SUCCESS != (mpi_code = MPI_Ibarrier(file_comm, &barrier_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code); while (!barrier_complete) { useconds_t t_delay = 5; usleep(t_delay); if (MPI_SUCCESS != (mpi_code = MPI_Test(&barrier_req, &barrier_complete, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code); } #else if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); #endif } /* The map from file handle to subfiling context can now be cleared */ - if (sf_context->h5_file_id != UINT64_MAX) { - clear_fid_map_entry(sf_context->h5_file_id, sf_context->sf_context_id); - } + if (sf_context->h5_file_id != UINT64_MAX) + H5FD__subfiling_clear_fid_map_entry(sf_context->h5_file_id, sf_context->sf_context_id); - if (sf_context->topology->rank_is_ioc) { - if (sf_context->sf_fids) { + if (sf_context->topology->rank_is_ioc) + if (sf_context->sf_fids) for (int i = 0; i < sf_context->sf_num_fids; i++) { errno = 0; if (sf_context->sf_fids[i] >= 0 && HDclose(sf_context->sf_fids[i]) < 0) - H5_SUBFILING_SYS_GOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfile"); + HSYS_GOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "couldn't close subfile"); sf_context->sf_fids[i] = -1; } - } - } /* - * Run another barrier to prevent some ranks from running ahead, - * and opening another file before this file is completely closed - * down. + * Run another barrier to prevent some ranks from running ahead, and opening + * another file before this file is completely closed down. */ if (mpi_size > 1) { #if H5_CHECK_MPI_VERSION(3, 1) int barrier_complete = 0; if (MPI_SUCCESS != (mpi_code = MPI_Ibarrier(file_comm, &barrier_req))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Ibarrier failed", mpi_code); while (!barrier_complete) { useconds_t t_delay = 5; usleep(t_delay); if (MPI_SUCCESS != (mpi_code = MPI_Test(&barrier_req, &barrier_complete, MPI_STATUS_IGNORE))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Test failed", mpi_code); } #else if (MPI_SUCCESS != (mpi_code = MPI_Barrier(file_comm))) - H5_SUBFILING_MPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); + HMPI_GOTO_ERROR(FAIL, "MPI_Barrier failed", mpi_code); #endif } @@ -2854,7 +2694,7 @@ H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) cur_time = time(NULL); tm = localtime(&cur_time); - H5_subfiling_log(sf_context->sf_context_id, "\n-- LOGGING FINISH - %s", asctime(tm)); + H5FD__subfiling_log(sf_context->sf_context_id, "\n-- LOGGING FINISH - %s", asctime(tm)); fclose(sf_context->sf_logfile); sf_context->sf_logfile = NULL; @@ -2862,11 +2702,11 @@ H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) #endif done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_set_config_prop + * Function: H5FD__subfiling_set_config_prop * * Purpose: Sets the specified Subfiling VFD configuration as a * property on the given FAPL pointer. The Subfiling VFD uses @@ -2879,50 +2719,43 @@ H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm) *------------------------------------------------------------------------- */ herr_t -H5_subfiling_set_config_prop(H5P_genplist_t *plist_ptr, const H5FD_subfiling_params_t *vfd_config) +H5FD__subfiling_set_config_prop(H5P_genplist_t *plist, const H5FD_subfiling_params_t *vfd_config) { htri_t prop_exists = FAIL; herr_t ret_value = SUCCEED; - if (!plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); + FUNC_ENTER_PACKAGE + + if (!plist) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); if (!vfd_config) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration pointer"); - if ((prop_exists = H5P_exist_plist(plist_ptr, H5FD_SUBFILING_CONFIG_PROP)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't check if subfiling configuration property exists in FAPL"); + if ((prop_exists = H5P_exist_plist(plist, H5FD_SUBFILING_CONFIG_PROP)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "can't check if subfiling configuration property exists in FAPL"); if (prop_exists) { - if (H5P_set(plist_ptr, H5FD_SUBFILING_CONFIG_PROP, vfd_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, - "can't set subfiling configuration property on FAPL"); + if (H5P_set(plist, H5FD_SUBFILING_CONFIG_PROP, vfd_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set subfiling configuration property on FAPL"); } - else { - union { - const void *const_ptr_to_data; - void *ptr_to_data; - } eliminate_const_warning; - + else /* * Cast away const since H5P_insert doesn't match the signature * for "value" as H5P_set */ - eliminate_const_warning.const_ptr_to_data = vfd_config; - - if (H5P_insert(plist_ptr, H5FD_SUBFILING_CONFIG_PROP, sizeof(H5FD_subfiling_params_t), - eliminate_const_warning.ptr_to_data, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + if (H5P_insert(plist, H5FD_SUBFILING_CONFIG_PROP, sizeof(H5FD_subfiling_params_t), + H5FD__subfiling_cast_to_void(vfd_config), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, - "unable to register subfiling configuration property in FAPL"); - } + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, + "unable to register subfiling configuration property in FAPL"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_get_config_prop + * Function: H5FD__subfiling_get_config_prop * * Purpose: Retrieves the Subfiling VFD configuration from the given * FAPL pointer. The Subfiling VFD uses this property to pass @@ -2934,24 +2767,25 @@ H5_subfiling_set_config_prop(H5P_genplist_t *plist_ptr, const H5FD_subfiling_par *------------------------------------------------------------------------- */ herr_t -H5_subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t *vfd_config) +H5FD__subfiling_get_config_prop(H5P_genplist_t *plist, H5FD_subfiling_params_t *vfd_config) { htri_t prop_exists = FAIL; herr_t ret_value = SUCCEED; - if (!plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); + FUNC_ENTER_PACKAGE + + if (!plist) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); if (!vfd_config) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid subfiling configuration pointer"); - if ((prop_exists = H5P_exist_plist(plist_ptr, H5FD_SUBFILING_CONFIG_PROP)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't check if subfiling configuration property exists in FAPL"); + if ((prop_exists = H5P_exist_plist(plist, H5FD_SUBFILING_CONFIG_PROP)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, + "can't check if subfiling configuration property exists in FAPL"); if (prop_exists) { - if (H5P_get(plist_ptr, H5FD_SUBFILING_CONFIG_PROP, vfd_config) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't get subfiling configuration property from FAPL"); + if (H5P_get(plist, H5FD_SUBFILING_CONFIG_PROP, vfd_config) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get subfiling configuration property from FAPL"); } else { vfd_config->ioc_selection = SELECT_IOC_ONE_PER_NODE; @@ -2960,11 +2794,11 @@ H5_subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t } done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_set_file_id_prop + * Function: H5FD__subfiling_set_file_id_prop * * Purpose: Sets the specified file ID (Inode) value as a property on * the given FAPL pointer. The Subfiling VFD uses this @@ -2976,37 +2810,35 @@ H5_subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t *------------------------------------------------------------------------- */ herr_t -H5_subfiling_set_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t file_id) +H5FD__subfiling_set_file_id_prop(H5P_genplist_t *plist, uint64_t file_id) { htri_t prop_exists = FAIL; herr_t ret_value = SUCCEED; - if (!plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); + FUNC_ENTER_PACKAGE + + if (!plist) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); if (file_id == UINT64_MAX) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID value"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID value"); - if ((prop_exists = H5P_exist_plist(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't check if file ID property exists in FAPL"); + if ((prop_exists = H5P_exist_plist(plist, H5FD_SUBFILING_STUB_FILE_ID)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if file ID property exists in FAPL"); if (prop_exists) { - if (H5P_set(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID, &file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file ID property on FAPL"); - } - else { - if (H5P_insert(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID, sizeof(uint64_t), &file_id, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, - "unable to register file ID property in FAPL"); + if (H5P_set(plist, H5FD_SUBFILING_STUB_FILE_ID, &file_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set file ID property on FAPL"); } + else if (H5P_insert(plist, H5FD_SUBFILING_STUB_FILE_ID, sizeof(uint64_t), &file_id, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTREGISTER, FAIL, "unable to register file ID property in FAPL"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_get_file_id_prop + * Function: H5FD__subfiling_get_file_id_prop * * Purpose: Retrieves the file ID (Inode) value from the given FAPL * pointer. The Subfiling VFD uses this property to pass the @@ -3017,33 +2849,34 @@ H5_subfiling_set_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t file_id) *------------------------------------------------------------------------- */ herr_t -H5_subfiling_get_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t *file_id) +H5FD__subfiling_get_file_id_prop(H5P_genplist_t *plist, uint64_t *file_id) { htri_t prop_exists = FAIL; herr_t ret_value = SUCCEED; - if (!plist_ptr) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); + FUNC_ENTER_PACKAGE + + if (!plist) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL FAPL pointer"); if (!file_id) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file ID pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL file ID pointer"); - if ((prop_exists = H5P_exist_plist(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID)) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, - "can't check if file ID property exists in FAPL"); + if ((prop_exists = H5P_exist_plist(plist, H5FD_SUBFILING_STUB_FILE_ID)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't check if file ID property exists in FAPL"); if (prop_exists) { - if (H5P_get(plist_ptr, H5FD_SUBFILING_STUB_FILE_ID, file_id) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file ID property from FAPL"); + if (H5P_get(plist, H5FD_SUBFILING_STUB_FILE_ID, file_id) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get file ID property from FAPL"); } else *file_id = UINT64_MAX; done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfile_fid_to_context + * Function: H5FD__subfile_fid_to_context * * Purpose: This is a basic lookup function which returns the subfiling * context ID associated with the specified file ID. If no @@ -3055,27 +2888,29 @@ H5_subfiling_get_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t *file_id) *------------------------------------------------------------------------- */ herr_t -H5_subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out) +H5FD__subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + assert(context_id_out); *context_id_out = -1; - if (init_open_file_map() < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize open file mapping"); + if (H5FD__subfiling_init_open_file_map() < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "couldn't initialize open file mapping"); for (int i = 0; i < sf_file_map_size; i++) if (sf_open_file_map[i].file_id == file_id) *context_id_out = sf_open_file_map[i].sf_context_id; done: - H5_SUBFILING_FUNC_LEAVE; -} /* end H5_subfile_fid_to_context() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__subfile_fid_to_context() */ /*------------------------------------------------------------------------- - * Function: H5_subfiling_validate_config + * Function: H5FD__subfiling_validate_config_params * * Purpose: Checks that the given subfiling configuration parameters * are valid @@ -3084,13 +2919,15 @@ H5_subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out) *------------------------------------------------------------------------- */ herr_t -H5_subfiling_validate_config(const H5FD_subfiling_params_t *subf_config) +H5FD__subfiling_validate_config_params(const H5FD_subfiling_params_t *subf_config) { H5FD_subfiling_ioc_select_t ioc_sel_type; herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + if (!subf_config) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL subfiling configuration pointer"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL subfiling configuration pointer"); /* * Compare against each IOC selection value directly since @@ -3100,20 +2937,20 @@ H5_subfiling_validate_config(const H5FD_subfiling_params_t *subf_config) ioc_sel_type = subf_config->ioc_selection; if (ioc_sel_type != SELECT_IOC_ONE_PER_NODE && ioc_sel_type != SELECT_IOC_EVERY_NTH_RANK && ioc_sel_type != SELECT_IOC_WITH_CONFIG && ioc_sel_type != SELECT_IOC_TOTAL) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC selection method"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid IOC selection method"); if (subf_config->stripe_size <= 0) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stripe size"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stripe size"); if (subf_config->stripe_count <= 0 && subf_config->stripe_count != H5FD_SUBFILING_DEFAULT_STRIPE_COUNT) - H5_SUBFILING_GOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stripe count"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stripe count"); done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } /*------------------------------------------------------------------------- - * Function: H5_subfiling_terminate + * Function: H5FD__subfiling_terminate * * Purpose: A cleanup routine to be called by the Subfiling VFD when * it is terminating. Cleans up internal resources such as the @@ -3124,62 +2961,63 @@ H5_subfiling_validate_config(const H5FD_subfiling_params_t *subf_config) *------------------------------------------------------------------------- */ herr_t -H5_subfiling_terminate(void) +H5FD__subfiling_terminate(void) { herr_t ret_value = SUCCEED; + FUNC_ENTER_PACKAGE + /* Clean up subfiling context and topology caches */ if (sf_context_cache) { - for (size_t i = 0; i < sf_context_cache_size; i++) { + for (size_t i = 0; i < sf_context_cache_size; i++) if (sf_context_cache[i]) { - if (H5_free_subfiling_object_int(sf_context_cache[i]) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "couldn't free subfiling context object"); + if (H5FD__subfiling_free_context(sf_context_cache[i]) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling context object"); sf_context_cache[i] = NULL; } - } sf_context_cache_size = 0; sf_context_cache_next_index = 0; - free(sf_context_cache); + H5MM_free(sf_context_cache); sf_context_cache = NULL; } if (sf_topology_cache) { for (size_t i = 0; i < sf_topology_cache_num_entries; i++) { - if (H5_free_subfiling_topology(sf_topology_cache[i]) < 0) - H5_SUBFILING_GOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, - "couldn't free subfiling topology object"); + if (H5FD__subfiling_free_topology(sf_topology_cache[i]) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "couldn't free subfiling topology object"); sf_topology_cache[i] = NULL; } sf_topology_cache_size = 0; sf_topology_cache_num_entries = 0; - free(sf_topology_cache); + H5MM_free(sf_topology_cache); sf_topology_cache = NULL; } /* Clean up the file ID to context object mapping */ sf_file_map_size = 0; - free(sf_open_file_map); + H5MM_free(sf_open_file_map); sf_open_file_map = NULL; done: - H5_SUBFILING_FUNC_LEAVE; + FUNC_LEAVE_NOAPI(ret_value) } #ifdef H5_SUBFILING_DEBUG void -H5_subfiling_log(int64_t sf_context_id, const char *fmt, ...) +H5FD__subfiling_log(int64_t sf_context_id, const char *fmt, ...) { subfiling_context_t *sf_context = NULL; va_list log_args; + FUNC_ENTER_PACKAGE_NOERR + va_start(log_args, fmt); /* Retrieve the subfiling object for the newly-created context ID */ - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) { + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) { printf("%s: couldn't get subfiling object from context ID\n", __func__); goto done; } @@ -3202,19 +3040,21 @@ H5_subfiling_log(int64_t sf_context_id, const char *fmt, ...) done: va_end(log_args); - return; + FUNC_LEAVE_NOAPI_VOID } void -H5_subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...) +H5FD__subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...) { subfiling_context_t *sf_context = NULL; va_list log_args; + FUNC_ENTER_PACKAGE_NOERR + va_start(log_args, fmt); /* Retrieve the subfiling object for the newly-created context ID */ - if (NULL == (sf_context = H5_get_subfiling_object(sf_context_id))) { + if (NULL == (sf_context = H5FD__subfiling_get_object(sf_context_id))) { printf("%s: couldn't get subfiling object from context ID\n", __func__); goto done; } @@ -3235,6 +3075,6 @@ H5_subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...) done: va_end(log_args); - return; + FUNC_LEAVE_NOAPI_VOID } #endif diff --git a/src/H5FDsubfiling/H5subfiling_common.h b/src/H5FDsubfiling/H5subfiling_common.h index 2c614cc6803..cef396b9e42 100644 --- a/src/H5FDsubfiling/H5subfiling_common.h +++ b/src/H5FDsubfiling/H5subfiling_common.h @@ -258,38 +258,52 @@ typedef struct { /* MPI Datatype used to send/receive an RPC message */ extern MPI_Datatype H5_subfiling_rpc_msg_type; +/* + * Utility routine to hack around casting away const + */ +static inline void * +H5FD__subfiling_cast_to_void(const void *data) +{ + union { + const void *const_ptr_to_data; + void *ptr_to_data; + } eliminate_const_warning; + eliminate_const_warning.const_ptr_to_data = data; + return eliminate_const_warning.ptr_to_data; +} + #ifdef __cplusplus extern "C" { #endif -H5_DLL herr_t H5_open_subfiling_stub_file(const char *name, unsigned flags, MPI_Comm file_comm, - H5FD_t **file_ptr, uint64_t *file_id); -H5_DLL herr_t H5_open_subfiles(const char *base_filename, uint64_t file_id, - H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, - MPI_Comm file_comm, int64_t *context_id_out); -H5_DLL herr_t H5_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm); +H5_DLL herr_t H5FD__subfiling_open_stub_file(const char *name, unsigned flags, MPI_Comm file_comm, + H5FD_t **file_ptr, uint64_t *file_id); +H5_DLL herr_t H5FD__subfiling_open_subfiles(const char *base_filename, uint64_t file_id, + H5FD_subfiling_params_t *subfiling_config, int file_acc_flags, + MPI_Comm file_comm, int64_t *context_id_out); +H5_DLL herr_t H5FD__subfiling_close_subfiles(int64_t subfiling_context_id, MPI_Comm file_comm); -H5_DLL int64_t H5_new_subfiling_object_id(sf_obj_type_t obj_type); -H5_DLL void *H5_get_subfiling_object(int64_t object_id); -H5_DLL herr_t H5_free_subfiling_object(int64_t object_id); -H5_DLL herr_t H5_get_subfiling_config_from_file(FILE *config_file, int64_t *stripe_size, - int64_t *num_subfiles); -H5_DLL herr_t H5_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepath); +H5_DLL void *H5FD__subfiling_get_object(int64_t object_id); +H5_DLL herr_t H5FD__subfiling_free_object(int64_t object_id); +H5_DLL herr_t H5FD__subfiling_get_config_from_file(FILE *config_file, int64_t *stripe_size, + int64_t *num_subfiles); +H5_DLL herr_t H5FD__subfiling_resolve_pathname(const char *filepath, MPI_Comm comm, char **resolved_filepath); -H5_DLL herr_t H5_subfiling_set_config_prop(H5P_genplist_t *plist_ptr, - const H5FD_subfiling_params_t *vfd_config); -H5_DLL herr_t H5_subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t *vfd_config); -H5_DLL herr_t H5_subfiling_set_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t file_id); -H5_DLL herr_t H5_subfiling_get_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t *file_id); -H5_DLL herr_t H5_subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out); +H5_DLL herr_t H5FD__subfiling_set_config_prop(H5P_genplist_t *plist_ptr, + const H5FD_subfiling_params_t *vfd_config); +H5_DLL herr_t H5FD__subfiling_get_config_prop(H5P_genplist_t *plist_ptr, H5FD_subfiling_params_t *vfd_config); +H5_DLL herr_t H5FD__subfiling_set_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t file_id); +H5_DLL herr_t H5FD__subfiling_get_file_id_prop(H5P_genplist_t *plist_ptr, uint64_t *file_id); +H5_DLL herr_t H5FD__subfile_fid_to_context(uint64_t file_id, int64_t *context_id_out); -H5_DLL herr_t H5_subfiling_validate_config(const H5FD_subfiling_params_t *subf_config); +H5_DLL herr_t H5FD__subfiling_validate_config_params(const H5FD_subfiling_params_t *subf_config); +H5_DLL herr_t H5FD__subfiling_get_default_ioc_config(H5FD_ioc_config_t *config); -H5_DLL herr_t H5_subfiling_terminate(void); +H5_DLL herr_t H5FD__subfiling_terminate(void); #ifdef H5_SUBFILING_DEBUG -H5_DLL void H5_subfiling_log(int64_t sf_context_id, const char *fmt, ...); -H5_DLL void H5_subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...); +H5_DLL void H5FD__subfiling_log(int64_t sf_context_id, const char *fmt, ...); +H5_DLL void H5FD__subfiling_log_nonewline(int64_t sf_context_id, const char *fmt, ...); #endif #ifdef __cplusplus diff --git a/src/H5FDsubfiling/H5subfiling_err.h b/src/H5FDsubfiling/H5subfiling_err.h deleted file mode 100644 index efdfaab0d6c..00000000000 --- a/src/H5FDsubfiling/H5subfiling_err.h +++ /dev/null @@ -1,272 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright by The HDF Group. * - * All rights reserved. * - * * - * This file is part of HDF5. The full HDF5 copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the root of the source code * - * distribution tree, or in https://www.hdfgroup.org/licenses. * - * If you do not have access to either file, you may request a copy from * - * help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/* - * Error handling for the HDF5 Subfiling feature - */ - -#ifndef H5SUBFILING_ERR_H -#define H5SUBFILING_ERR_H - -#include - -#include "H5Epublic.h" - -extern hid_t H5subfiling_err_stack_g; -extern hid_t H5subfiling_err_class_g; - -#define H5SUBFILING_ERR_CLS_NAME "HDF5 Subfiling" -#define H5SUBFILING_ERR_LIB_NAME "HDF5 Subfiling" -#define H5SUBFILING_ERR_VER "1.0.0" - -/* Error macros */ - -#ifdef H5_NO_DEPRECATED_SYMBOLS - -/* - * Macro to push the current function to the current error stack - * and then goto the "done" label, which should appear inside the - * function. (v2 errors only) - */ -#define H5_SUBFILING_GOTO_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - H5E_auto2_t err_func; \ - \ - /* Check whether automatic error reporting has been disabled */ \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); \ - if (err_func) { \ - if (H5subfiling_err_stack_g >= 0 && H5subfiling_err_class_g >= 0) { \ - H5Epush2(H5subfiling_err_stack_g, __FILE__, __func__, __LINE__, H5subfiling_err_class_g, \ - err_major, err_minor, __VA_ARGS__); \ - } \ - else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - goto done; \ - } while (0) - -/* - * Macro to push the current function to the current error stack - * without calling goto. This is used for handling the case where - * an error occurs during cleanup past the "done" label inside a - * function so that an infinite loop does not occur where goto - * continually branches back to the label. (v2 errors only) - */ -#define H5_SUBFILING_DONE_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - H5E_auto2_t err_func; \ - \ - /* Check whether automatic error reporting has been disabled */ \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); \ - if (err_func) { \ - if (H5subfiling_err_stack_g >= 0 && H5subfiling_err_class_g >= 0) \ - H5Epush2(H5subfiling_err_stack_g, __FILE__, __func__, __LINE__, H5subfiling_err_class_g, \ - err_major, err_minor, __VA_ARGS__); \ - else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - } while (0) - -/* - * Macro to print out the current error stack and then clear it - * for future use. (v2 errors only) - */ -#define PRINT_ERROR_STACK \ - do { \ - H5E_auto2_t err_func; \ - \ - /* Check whether automatic error reporting has been disabled */ \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func, NULL); \ - if (err_func) { \ - if ((H5subfiling_err_stack_g >= 0) && (H5Eget_num(H5subfiling_err_stack_g) > 0)) { \ - H5Eprint2(H5subfiling_err_stack_g, NULL); \ - H5Eclear2(H5subfiling_err_stack_g); \ - } \ - } \ - } while (0) - -#else /* H5_NO_DEPRECATED_SYMBOLS */ - -/* - * Macro to push the current function to the current error stack - * and then goto the "done" label, which should appear inside the - * function. (compatible with v1 and v2 errors) - */ -#define H5_SUBFILING_GOTO_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - else \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || (!is_v2_err && err_func.err_func_v1)) { \ - if (H5subfiling_err_stack_g >= 0 && H5subfiling_err_class_g >= 0) { \ - H5Epush2(H5subfiling_err_stack_g, __FILE__, __func__, __LINE__, H5subfiling_err_class_g, \ - err_major, err_minor, __VA_ARGS__); \ - } \ - else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - goto done; \ - } while (0) - -/* - * Macro to push the current function to the current error stack - * without calling goto. This is used for handling the case where - * an error occurs during cleanup past the "done" label inside a - * function so that an infinite loop does not occur where goto - * continually branches back to the label. (compatible with v1 - * and v2 errors) - */ -#define H5_SUBFILING_DONE_ERROR(err_major, err_minor, ret_val, ...) \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - else \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || (!is_v2_err && err_func.err_func_v1)) { \ - if (H5subfiling_err_stack_g >= 0 && H5subfiling_err_class_g >= 0) { \ - H5Epush2(H5subfiling_err_stack_g, __FILE__, __func__, __LINE__, H5subfiling_err_class_g, \ - err_major, err_minor, __VA_ARGS__); \ - } \ - else { \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } \ - } \ - \ - ret_value = ret_val; \ - } while (0) - -/* - * Macro to print out the current error stack and then clear it - * for future use. (compatible with v1 and v2 errors) - */ -#define PRINT_ERROR_STACK \ - do { \ - unsigned is_v2_err; \ - union { \ - H5E_auto1_t err_func_v1; \ - H5E_auto2_t err_func_v2; \ - } err_func; \ - \ - /* Determine version of error */ \ - (void)H5Eauto_is_v2(H5E_DEFAULT, &is_v2_err); \ - \ - if (is_v2_err) \ - (void)H5Eget_auto2(H5E_DEFAULT, &err_func.err_func_v2, NULL); \ - else \ - (void)H5Eget_auto1(&err_func.err_func_v1, NULL); \ - \ - /* Check whether automatic error reporting has been disabled */ \ - if ((is_v2_err && err_func.err_func_v2) || (!is_v2_err && err_func.err_func_v1)) { \ - if ((H5subfiling_err_stack_g >= 0) && (H5Eget_num(H5subfiling_err_stack_g) > 0)) { \ - H5Eprint2(H5subfiling_err_stack_g, NULL); \ - H5Eclear2(H5subfiling_err_stack_g); \ - } \ - } \ - } while (0) - -#endif /* H5_NO_DEPRECATED_SYMBOLS */ - -#define H5_SUBFILING_SYS_GOTO_ERROR(err_major, err_minor, ret_val, str) \ - do { \ - int myerrno = errno; \ - H5_SUBFILING_GOTO_ERROR(err_major, err_minor, ret_val, "%s, errno = %d, error message = '%s'", str, \ - myerrno, strerror(myerrno)); \ - } while (0) - -/* MPI error handling macros. */ - -extern char H5subfiling_mpi_error_str[MPI_MAX_ERROR_STRING]; -extern int H5subfiling_mpi_error_str_len; - -#define H5_SUBFILING_MPI_DONE_ERROR(retcode, str, mpierr) \ - do { \ - MPI_Error_string(mpierr, H5subfiling_mpi_error_str, &H5subfiling_mpi_error_str_len); \ - H5_SUBFILING_DONE_ERROR(H5E_INTERNAL, H5E_MPI, retcode, "%s: MPI error string is '%s'", str, \ - H5subfiling_mpi_error_str); \ - } while (0) -#define H5_SUBFILING_MPI_GOTO_ERROR(retcode, str, mpierr) \ - do { \ - MPI_Error_string(mpierr, H5subfiling_mpi_error_str, &H5subfiling_mpi_error_str_len); \ - H5_SUBFILING_GOTO_ERROR(H5E_INTERNAL, H5E_MPI, retcode, "%s: MPI error string is '%s'", str, \ - H5subfiling_mpi_error_str); \ - } while (0) - -/* - * Macro to simply jump to the "done" label inside the function, - * setting ret_value to the given value. This is often used for - * short circuiting in functions when certain conditions arise. - */ -#define H5_SUBFILING_GOTO_DONE(ret_val) \ - do { \ - ret_value = ret_val; \ - goto done; \ - } while (0) - -/* - * Macro to return from a top-level API function, printing - * out the error stack on the way out. - * It should be ensured that this macro is only called once - * per HDF5 operation. If it is called multiple times per - * operation (e.g. due to calling top-level API functions - * internally), the error stack will be inconsistent/incoherent. - */ -#define H5_SUBFILING_FUNC_LEAVE_API \ - do { \ - PRINT_ERROR_STACK; \ - return ret_value; \ - } while (0) - -/* - * Macro to return from internal functions. - */ -#define H5_SUBFILING_FUNC_LEAVE \ - do { \ - return ret_value; \ - } while (0) - -#endif /* H5SUBFILING_ERR_H */