From 4c6cd1a9322ed3cf089f849751d74884b530f476 Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Thu, 23 Oct 2025 14:18:04 -0500 Subject: [PATCH 01/10] Fix overflow on long link names --- CMakeLists.txt | 3 - src/H5LS.c | 8 ++ src/H5LS.h | 4 +- src/H5VLcache_ext.c | 180 ++++++++++++++++++++++++++++++-------------- src/cache_utils.c | 51 +++++++++++++ src/cache_utils.h | 4 + 6 files changed, 189 insertions(+), 61 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d2e9ad..1be3af6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,9 +8,6 @@ include(CTest) enable_testing() find_package(MPI REQUIRED) -find_package(ASYNC REQUIRED) -find_package(HDF5 REQUIRED COMPONENTS C) - include_directories(${MPI_INCLUDE_PATH}) include_directories(${HDF5_INCLUDE_DIRS}) include_directories(${ASYNC_INCLUDE_DIRS}) diff --git a/src/H5LS.c b/src/H5LS.c index bc0cf41..215cfac 100644 --- a/src/H5LS.c +++ b/src/H5LS.c @@ -481,6 +481,10 @@ herr_t H5LSremove_cache(cache_storage_t *LS, cache_t *cache) { LOG_DEBUG(-1, "Cache storage space left: %lu bytes\n", LS->mspace_left); #endif + if (cache->path != NULL) { + free(cache->path); + cache->path = NULL; + } free(cache); cache = NULL; } @@ -511,6 +515,10 @@ herr_t H5LSremove_cache_all(cache_storage_t *LS) { while (head != NULL) { if (LS->io_node) { ret_value = LS->mmap_cls->removeCacheFolder(head->cache->path); + if (head->cache->path != NULL) { + free(head->cache->path); + head->cache->path = NULL; + } free(head->cache); head->cache = NULL; head = head->next; diff --git a/src/H5LS.h b/src/H5LS.h index ab359e6..f9b8103 100644 --- a/src/H5LS.h +++ b/src/H5LS.h @@ -50,7 +50,7 @@ typedef struct cache_t { hsize_t mspace_per_rank_total; // total space per process hsize_t mspace_per_rank_left; // space left per process hid_t fd; // the associate file - char path[255]; // path + char *path; // dynamically allocated path AccessHistory access_history; } cache_t; @@ -116,7 +116,7 @@ typedef struct _IO_THREAD { typedef struct _MMAP { // for write int fd; // file handle for write - char fname[255]; // full path of the memory mapped file + char *fname; // dynamically allocated full path of the memory mapped file void *obj; // this will be used for cache data on global storage layer void *buf; // pointer that map the file to the memory void *tmp_buf; // temporally buffer, used for parallel read: copy the read diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index 18695d4..d0089a2 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -3186,6 +3186,7 @@ static herr_t H5VL_cache_ext_dataset_close(void *dset, hid_t dxpl_id, H5VL_cache_ext_t *o = (H5VL_cache_ext_t *)dset; herr_t ret_value; H5VL_cache_ext_t *p = o; + while (p->parent != NULL) p = p->parent; @@ -5386,7 +5387,9 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DWMM->io->fusion_data_size = 0.0; file->H5DWMM->io->num_fusion_requests = 0; file->H5DWMM->cache = (cache_t *)malloc(sizeof(cache_t)); + file->H5DWMM->cache->path = NULL; file->H5DWMM->mmap = (MMAP *)malloc(sizeof(MMAP)); + file->H5DWMM->mmap->fname = NULL; } else { #ifndef NDEBUG LOG_WARN(-1, "file_cache_create: cache data already exist. " @@ -5415,6 +5418,7 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DWMM->io->num_request = 0; file->H5DWMM->cache = (cache_t *)malloc(sizeof(cache_t)); + file->H5DWMM->cache->path = NULL; file->H5DWMM->cache->mspace_total = file->H5LS->write_buffer_size * file->H5DWMM->mpi->ppn; if (file->H5LS->mspace_total < file->H5DWMM->cache->mspace_total) { @@ -5423,12 +5427,14 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, " Will turn off Cache effect." " Try to decrease HDF5_CACHE_WRITE_BUFFER_SIZE."); file->write_cache = false; + free(file->H5DWMM->cache); return FAIL; } else if (H5LSclaim_space(file->H5LS, file->H5DWMM->cache->mspace_total, HARD, file->H5LS->replacement_policy) == FAIL) { LOG_ERROR(-1, "Unable to claim space, turning off write " "cache"); file->write_cache = false; + free(file->H5DWMM->cache); return FAIL; } @@ -5441,19 +5447,26 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DWMM->cache->duration = PERMANENT; if (file->H5LS->path != NULL) { - strcpy(file->H5DWMM->cache->path, file->H5LS->path); - strcat(file->H5DWMM->cache->path, "/"); - strcat(file->H5DWMM->cache->path, basename((char *)name)); - strcat(file->H5DWMM->cache->path, "-cache/"); - // mkdir(file->H5DWMM->cache->path, 0755); // setup the folder with the - // name of the file, and put everything under it. - - strcpy(file->H5DWMM->mmap->fname, file->H5DWMM->cache->path); - strcat(file->H5DWMM->mmap->fname, "mmap-"); + // Build cache path: /-cache/ char rnd[255]; sprintf(rnd, "%d", file->H5DWMM->mpi->rank); - strcat(file->H5DWMM->mmap->fname, rnd); - strcat(file->H5DWMM->mmap->fname, ".dat"); + + file->H5DWMM->cache->path = cache_utils_build_path(file->H5LS->path, basename((char *)name), "-cache", NULL); + if (file->H5DWMM->cache->path == NULL) { + LOG_ERROR(-1, "Failed to allocate cache path"); + free(file->H5DWMM->cache); + return FAIL; + } + + // Build mmap fname: /mmap-.dat + file->H5DWMM->mmap->fname = cache_utils_build_path(file->H5DWMM->cache->path, "mmap-", rnd, ".dat", NULL); + if (file->H5DWMM->mmap->fname == NULL) { + LOG_ERROR(-1, "Failed to allocate mmap fname"); + free(file->H5DWMM->cache->path); + file->H5DWMM->cache->path = NULL; + free(file->H5DWMM->cache); + return FAIL; + } #ifndef NDEBUG LOG_DEBUG(-1, "**Using node local storage to cache the file"); LOG_DEBUG(-1, "**path: %s", file->H5DWMM->cache->path); @@ -5486,7 +5499,9 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DRMM->mpi = (MPI_INFO *)malloc(sizeof(MPI_INFO)); file->H5DRMM->io = (IO_THREAD *)malloc(sizeof(IO_THREAD)); file->H5DRMM->cache = (cache_t *)malloc(sizeof(cache_t)); + file->H5DRMM->cache->path = NULL; file->H5DRMM->mmap = (MMAP *)malloc(sizeof(MMAP)); + file->H5DRMM->mmap->fname = NULL; } else { #ifndef NDEBUG LOG_WARN(-1, "file cache create: cache data already exist. " @@ -5510,10 +5525,18 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, /* setting up cache within a folder */ if (file->H5LS->path != NULL) { - strcpy(file->H5DRMM->cache->path, file->H5LS->path); - strcat(file->H5DRMM->cache->path, "/"); - strcat(file->H5DRMM->cache->path, basename((char *)name)); - strcat(file->H5DRMM->cache->path, "/"); + // Build cache path: // + file->H5DRMM->cache->path = cache_utils_build_path(file->H5LS->path, basename((char *)name), "/", NULL); + if (file->H5DRMM->cache->path == NULL) { + LOG_ERROR(-1, "Failed to allocate file read cache path"); + free(file->H5DRMM->mmap); + free(file->H5DRMM->cache); + free(file->H5DRMM->io); + free(file->H5DRMM->mpi); + free(file->H5DRMM); + file->H5DRMM = NULL; + return FAIL; + } #ifndef NDEBUG LOG_DEBUG(-1, "file cache created: %s", file->H5DRMM->cache->path); @@ -5647,6 +5670,7 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, dset->H5DRMM->dset.size * dset->H5DRMM->mpi->ppn, HARD, dset->H5LS->replacement_policy) == SUCCEED) { dset->H5DRMM->cache = (cache_t *)malloc(sizeof(cache_t)); + dset->H5DRMM->cache->path = NULL; // set cache size @@ -5659,31 +5683,27 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, dset->H5DRMM->cache->mspace_left = dset->H5DRMM->cache->mspace_total; if (dset->H5LS->path != NULL) { - strcpy(dset->H5DRMM->cache->path, p->H5DRMM->cache->path); // create - strncat(dset->H5DRMM->cache->path, "/", - sizeof(dset->H5DRMM->cache->path) - - strlen(dset->H5DRMM->cache->path) - 1); - strncat(dset->H5DRMM->cache->path, name, - sizeof(dset->H5DRMM->cache->path) - - strlen(dset->H5DRMM->cache->path) - 1); - strncat(dset->H5DRMM->cache->path, "/", - sizeof(dset->H5DRMM->cache->path) - - strlen(dset->H5DRMM->cache->path) - 1); - strncpy(dset->H5DRMM->mmap->fname, dset->H5DRMM->cache->path, - sizeof(dset->H5DRMM->mmap->fname) - 1); - dset->H5DRMM->mmap->fname[sizeof(dset->H5DRMM->mmap->fname) - 1] = - '\0'; // Ensure null-termination - strncat(dset->H5DRMM->mmap->fname, "/dset-mmap-", - sizeof(dset->H5DRMM->mmap->fname) - - strlen(dset->H5DRMM->mmap->fname) - 1); + // Build cache path: // + dset->H5DRMM->cache->path = cache_utils_build_path(p->H5DRMM->cache->path, name, "/", NULL); + if (dset->H5DRMM->cache->path == NULL) { + LOG_ERROR(-1, "Failed to allocate dataset read cache path"); + free(dset->H5DRMM->cache); + dset->H5DRMM->cache = NULL; + return FAIL; + } + + // Build mmap fname: /dset-mmap-.dat char cc[255]; int2char(dset->H5DRMM->mpi->rank, cc); - strncat(dset->H5DRMM->mmap->fname, cc, - sizeof(dset->H5DRMM->mmap->fname) - - strlen(dset->H5DRMM->mmap->fname) - 1); - strncat(dset->H5DRMM->mmap->fname, ".dat", - sizeof(dset->H5DRMM->mmap->fname) - - strlen(dset->H5DRMM->mmap->fname) - 1); + dset->H5DRMM->mmap->fname = cache_utils_build_path(dset->H5DRMM->cache->path, "dset-mmap-", cc, ".dat", NULL); + if (dset->H5DRMM->mmap->fname == NULL) { + LOG_ERROR(-1, "Failed to allocate dataset read mmap fname"); + free(dset->H5DRMM->cache->path); + dset->H5DRMM->cache->path = NULL; + free(dset->H5DRMM->cache); + dset->H5DRMM->cache = NULL; + return FAIL; + } #ifndef NDEBUG LOG_DEBUG(-1, "Dataset read cache created: %s", @@ -5756,19 +5776,20 @@ static herr_t create_group_cache_on_local_storage(void *obj, void *group_args, if (group->read_cache) { group->H5DRMM = (io_handler_t *)malloc(sizeof(io_handler_t)); group->H5DRMM->cache = (cache_t *)malloc(sizeof(cache_t)); + group->H5DRMM->cache->path = NULL; group->H5DRMM->mpi = (MPI_INFO *)malloc(sizeof(MPI_INFO)); memcpy(group->H5DRMM->mpi, o->H5DRMM->mpi, sizeof(MPI_INFO)); if (group->H5LS->path != NULL) { - strcpy(group->H5DRMM->cache->path, o->H5DRMM->cache->path); // create - size_t remaining_size = sizeof(group->H5DRMM->cache->path) - - strlen(group->H5DRMM->cache->path) - 1; - strncat(group->H5DRMM->cache->path, "/", remaining_size); - remaining_size = sizeof(group->H5DRMM->cache->path) - - strlen(group->H5DRMM->cache->path) - 1; - strncat(group->H5DRMM->cache->path, name, remaining_size); - remaining_size = sizeof(group->H5DRMM->cache->path) - - strlen(group->H5DRMM->cache->path) - 1; - strncat(group->H5DRMM->cache->path, "/", remaining_size); + // Build cache path: // + group->H5DRMM->cache->path = cache_utils_build_path(o->H5DRMM->cache->path, name, "/", NULL); + if (group->H5DRMM->cache->path == NULL) { + LOG_ERROR(-1, "Failed to allocate group read cache path"); + free(group->H5DRMM->mpi); + free(group->H5DRMM->cache); + free(group->H5DRMM); + group->H5DRMM = NULL; + return FAIL; + } #ifndef NDEBUG LOG_DEBUG(-1, "group cache created: %s", group->H5DRMM->cache->path); #endif @@ -5793,6 +5814,8 @@ static herr_t create_group_cache_on_local_storage(void *obj, void *group_args, static herr_t remove_group_cache_on_local_storage(void *obj, void **req) { H5VL_cache_ext_t *group = (H5VL_cache_ext_t *)obj; if (group->read_cache) { + free(group->H5DRMM->cache->path); + group->H5DRMM->cache->path = NULL; free(group->H5DRMM->cache); free(group->H5DRMM->mpi); free(group->H5DRMM); @@ -6083,9 +6106,11 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, file->H5DWMM->mpi = (MPI_INFO *)malloc(sizeof(MPI_INFO)); file->H5DWMM->io = (IO_THREAD *)malloc(sizeof(IO_THREAD)); file->H5DWMM->mmap = (MMAP *)malloc(sizeof(MMAP)); + file->H5DWMM->mmap->fname = NULL; file->H5DWMM->io->fusion_data_size = 0.0; file->H5DWMM->io->num_fusion_requests = 0; file->H5DWMM->cache = (cache_t *)malloc(sizeof(cache_t)); + file->H5DWMM->cache->path = NULL; } else { LOG_ERROR(-1, "file_cache_create: cache data already exist. " "Remove first!"); @@ -6101,15 +6126,36 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, file->H5LS->io_node = (file->H5DWMM->mpi->rank == 0); // set up I/O node file->H5DWMM->io->num_request = 0; if (file->H5LS->path != NULL) { - strcpy(file->H5DWMM->cache->path, file->H5LS->path); - strcat(file->H5DWMM->cache->path, "/"); - strcat(file->H5DWMM->cache->path, basename((char *)name)); - strcat(file->H5DWMM->cache->path, "-global-cache/"); + // Build cache path: /-global-cache/ + file->H5DWMM->cache->path = cache_utils_build_path(file->H5LS->path, basename((char *)name), "-global-cache/", NULL); + if (file->H5DWMM->cache->path == NULL) { + LOG_ERROR(-1, "Failed to allocate file GLOBAL cache path"); + free(file->H5DWMM->mmap); + free(file->H5DWMM->cache); + free(file->H5DWMM->io); + free(file->H5DWMM->mpi); + free(file->H5DWMM); + file->H5DWMM = NULL; + return FAIL; + } mkdir(file->H5DWMM->cache->path, 0755); // setup the folder with the name of the file, and put // everything under it. - strcpy(file->H5DWMM->mmap->fname, file->H5DWMM->cache->path); - strcat(file->H5DWMM->mmap->fname, basename((char *)name)); + + // Build mmap fname: / + file->H5DWMM->mmap->fname = cache_utils_build_path(file->H5DWMM->cache->path, basename((char *)name), NULL); + if (file->H5DWMM->mmap->fname == NULL) { + LOG_ERROR(-1, "Failed to allocate file GLOBAL mmap fname"); + free(file->H5DWMM->cache->path); + file->H5DWMM->cache->path = NULL; + free(file->H5DWMM->mmap); + free(file->H5DWMM->cache); + free(file->H5DWMM->io); + free(file->H5DWMM->mpi); + free(file->H5DWMM); + file->H5DWMM = NULL; + return FAIL; + } #ifndef NDEBUG LOG_INFO(-1, "Using global storage as a cache"); @@ -6256,6 +6302,7 @@ static herr_t create_dataset_cache_on_global_storage(void *obj, void *dset_args, dset->H5DWMM->dset.size * dset->H5DWMM->mpi->nproc, HARD, dset->H5LS->replacement_policy) == SUCCEED) { dset->H5DWMM->cache = (cache_t *)malloc(sizeof(cache_t)); + dset->H5DWMM->cache->path = NULL; dset->H5DWMM->cache->mspace_per_rank_total = dset->H5DWMM->dset.size; dset->H5DWMM->cache->mspace_per_rank_left = @@ -6266,8 +6313,25 @@ static herr_t create_dataset_cache_on_global_storage(void *obj, void *dset_args, dset->H5DWMM->cache->mspace_left = dset->H5DWMM->cache->mspace_total; if (dset->H5LS->path != NULL) { - strcpy(dset->H5DWMM->cache->path, o->H5DWMM->cache->path); // create - strcpy(dset->H5DWMM->mmap->fname, args->name); + // Copy parent cache path + dset->H5DWMM->cache->path = strdup(o->H5DWMM->cache->path); + if (dset->H5DWMM->cache->path == NULL) { + LOG_ERROR(-1, "Failed to allocate dataset GLOBAL cache path"); + free(dset->H5DWMM->cache); + dset->H5DWMM->cache = NULL; + return FAIL; + } + + // Copy dataset name to mmap fname + dset->H5DWMM->mmap->fname = strdup(args->name); + if (dset->H5DWMM->mmap->fname == NULL) { + LOG_ERROR(-1, "Failed to allocate dataset GLOBAL mmap fname"); + free(dset->H5DWMM->cache->path); + dset->H5DWMM->cache->path = NULL; + free(dset->H5DWMM->cache); + dset->H5DWMM->cache = NULL; + return FAIL; + } #ifndef NDEBUG LOG_DEBUG(-1, "Dataset cache created: %s", dset->H5DWMM->mmap->fname); @@ -6482,7 +6546,11 @@ static herr_t remove_dataset_cache_on_global_storage(void *dset, void **req) { H5VL_cache_ext_dataset_wait(dset); if (o->write_cache || o->read_cache) { H5Dclose_async(o->hd_glob, H5ES_NONE); + free(o->H5DWMM->cache->path); + o->H5DWMM->cache->path = NULL; free(o->H5DWMM->cache); + free(o->H5DWMM->mmap->fname); + o->H5DWMM->mmap->fname = NULL; free(o->H5DWMM->mmap); free(o->H5DWMM); o->H5DWMM = NULL; diff --git a/src/cache_utils.c b/src/cache_utils.c index da5286e..4a908cd 100644 --- a/src/cache_utils.c +++ b/src/cache_utils.c @@ -12,6 +12,7 @@ #include "stdlib.h" #include "string.h" #include "unistd.h" +#include #include // POSIX I/O #include "cache_utils.h" @@ -164,3 +165,53 @@ herr_t rmdirRecursive(const char *path) { ret = rmdir(path); return ret; } + +/*------------------------------------------------------------------------- + * Function: cache_utils_build_path + * + * Purpose: Build a path from multiple components (varargs, NULL-terminated) + * + * Return: Pointer to newly allocated path string, or NULL on failure + * + * Example: cache_utils_build_path("/tmp", "file.h5", "group", NULL) + * Returns: "/tmp/file.h5/group" + * + *------------------------------------------------------------------------- + */ +char *cache_utils_build_path(const char *base, ...) { + if (base == NULL) + return NULL; + + va_list args; + const char *component; + size_t total_len = strlen(base); + int num_components = 0; + + // First pass: calculate total length + va_start(args, base); + while ((component = va_arg(args, const char *)) != NULL) { + total_len += strlen(component); + num_components++; + } + va_end(args); + + // Allocate buffer (base + components + separators + null terminator) + char *result = (char *)malloc(total_len + num_components + 1); + if (result == NULL) + return NULL; + + // Second pass: build the path + strcpy(result, base); + + va_start(args, base); + while ((component = va_arg(args, const char *)) != NULL) { + // Add separator if needed (avoid double slashes) + size_t current_len = strlen(result); + if (current_len > 0 && result[current_len - 1] != '/' && component[0] != '/') + strcat(result, "/"); + strcat(result, component); + } + va_end(args); + + return result; +} diff --git a/src/cache_utils.h b/src/cache_utils.h index 2208917..762c1cf 100644 --- a/src/cache_utils.h +++ b/src/cache_utils.h @@ -45,6 +45,10 @@ void parallel_dist(size_t dim, int nproc, int rank, size_t *ldim, void int2char(int a, char str[255]); void mkdirRecursive(const char *path, mode_t mode); herr_t rmdirRecursive(const char *path); + +// Helper functions for dynamic string allocation +char *cache_utils_build_path(const char *base, ...); // NULL-terminated varargs + #ifdef __cplusplus } #endif From f1a7ab9b93ff00581ca9f147539a37112fef5a8a Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Fri, 24 Oct 2025 10:45:41 -0500 Subject: [PATCH 02/10] Reference count cache objects --- CMakeLists.txt | 3 ++ src/H5VLcache_ext.c | 85 +++++++++++++++++++++++++++++++++++---------- src/H5VLcache_ext.h | 10 ++++-- src/cache_utils.c | 51 --------------------------- src/cache_utils.h | 4 --- 5 files changed, 77 insertions(+), 76 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1be3af6..9d2e9ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,9 @@ include(CTest) enable_testing() find_package(MPI REQUIRED) +find_package(ASYNC REQUIRED) +find_package(HDF5 REQUIRED COMPONENTS C) + include_directories(${MPI_INCLUDE_PATH}) include_directories(${HDF5_INCLUDE_DIRS}) include_directories(${ASYNC_INCLUDE_DIRS}) diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index d0089a2..37acc3b 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -875,6 +875,7 @@ static H5VL_cache_ext_t *H5VL_cache_ext_new_obj(void *under_obj, new_obj = (H5VL_cache_ext_t *)calloc(1, sizeof(H5VL_cache_ext_t)); new_obj->under_object = under_obj; new_obj->under_vol_id = under_vol_id; + new_obj->ref_count = 1; H5Iinc_ref(new_obj->under_vol_id); return new_obj; @@ -897,17 +898,34 @@ static H5VL_cache_ext_t *H5VL_cache_ext_new_obj(void *under_obj, *------------------------------------------------------------------------- */ static herr_t H5VL_cache_ext_free_obj(H5VL_cache_ext_t *obj) { - hid_t err_id; + hid_t err_id = H5I_INVALID_HID; err_id = H5Eget_current_stack(); - H5Idec_ref(obj->under_vol_id); + assert(obj->ref_count > 0); + obj->ref_count--; - H5Eset_current_stack(err_id); + if (obj->ref_count == 0) { + if (H5Idec_ref(obj->under_vol_id) < 0) { + LOG_ERROR(-1, "H5Idec_ref failed on underlying VOL ID"); + goto error; + } + /* Close this object's reference to its parent object (if any) */ + if (obj->parent) + if (H5VL_cache_ext_free_obj(obj->parent) < 0) { + LOG_ERROR(-1, "can't free parent object"); + goto error; + } - free(obj); + free(obj); + } + H5Eset_current_stack(err_id); return 0; + +error: + H5Eset_current_stack(err_id); + return -1; } /* end H5VL_cache_extfree_obj() */ /*------------------------------------------------------------------------- @@ -1990,7 +2008,8 @@ static void *H5VL_cache_ext_dataset_create(void *obj, if (under) { dset = H5VL_cache_ext_new_obj(under, o->under_vol_id); /* inherit cache information from loc */ - dset->parent = obj; + dset->parent = o; + o->ref_count++; // inherit variables from parent object dset->H5DWMM = o->H5DWMM; dset->write_cache = o->write_cache; @@ -2179,7 +2198,8 @@ static void *H5VL_cache_ext_dataset_open(void *obj, if (under) { dset = H5VL_cache_ext_new_obj(under, o->under_vol_id); /* Inherit Cache information from obj */ - dset->parent = obj; + dset->parent = o; + o->ref_count++; dset->H5DWMM = o->H5DWMM; dset->write_cache = o->write_cache; dset->read_cache = o->read_cache; @@ -3545,6 +3565,11 @@ static herr_t set_file_cache(void *obj, void *file_args, void **req) { file->write_cache = false; file->read_cache = false; + if (file->parent != NULL) { + assert(file->parent->ref_count > 0); + H5VL_cache_ext_free_obj(file->parent); + } + file->parent = NULL; file->H5DRMM = NULL; @@ -4163,7 +4188,8 @@ static void *H5VL_cache_ext_group_create(void *obj, /* passing the cache information on from file to group */ group->write_cache = o->write_cache; group->read_cache = o->read_cache; - group->parent = obj; + group->parent = o; + o->ref_count++; group->H5LS = o->H5LS; group->async_pause = o->async_pause; if (group->write_cache || group->read_cache) { @@ -4221,7 +4247,8 @@ static void *H5VL_cache_ext_group_open(void *obj, group->H5DWMM = o->H5DWMM; group->read_cache = o->read_cache; group->H5DRMM = o->H5DRMM; - group->parent = obj; + group->parent = o; + o->ref_count++; group->H5LS = o->H5LS; group->async_pause = o->async_pause; if (group->write_cache || group->read_cache) { @@ -4707,7 +4734,8 @@ static void *H5VL_cache_ext_object_open(void *obj, new_obj->write_cache = o->write_cache; new_obj->H5DWMM = o->H5DWMM; new_obj->H5DRMM = o->H5DRMM; - new_obj->parent = obj; + new_obj->parent = o; + o->ref_count++; new_obj->H5LS = o->H5LS; new_obj->async_close = o->async_close; #ifndef NDEBUG @@ -4739,7 +4767,8 @@ static void *H5VL_cache_ext_object_open(void *obj, new_obj->async_close = p->async_close; new_obj->H5DRMM = o->H5DRMM; new_obj->H5DWMM = o->H5DWMM; - new_obj->parent = obj; + new_obj->parent = o; + o->ref_count++; new_obj->H5LS = o->H5LS; new_obj->es_id = H5EScreate(); int called = 0; @@ -5450,16 +5479,20 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, // Build cache path: /-cache/ char rnd[255]; sprintf(rnd, "%d", file->H5DWMM->mpi->rank); + char *base = basename((char *)name); - file->H5DWMM->cache->path = cache_utils_build_path(file->H5LS->path, basename((char *)name), "-cache", NULL); + size_t path_len = strlen(file->H5LS->path) + strlen(base) + strlen("-cache") + 2; + file->H5DWMM->cache->path = (char *)malloc(path_len); if (file->H5DWMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate cache path"); free(file->H5DWMM->cache); return FAIL; } + snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-cache", file->H5LS->path, base); // Build mmap fname: /mmap-.dat - file->H5DWMM->mmap->fname = cache_utils_build_path(file->H5DWMM->cache->path, "mmap-", rnd, ".dat", NULL); + size_t fname_len = strlen(file->H5DWMM->cache->path) + strlen("mmap-") + strlen(rnd) + strlen(".dat") + 2; + file->H5DWMM->mmap->fname = (char *)malloc(fname_len); if (file->H5DWMM->mmap->fname == NULL) { LOG_ERROR(-1, "Failed to allocate mmap fname"); free(file->H5DWMM->cache->path); @@ -5467,6 +5500,7 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, free(file->H5DWMM->cache); return FAIL; } + snprintf(file->H5DWMM->mmap->fname, fname_len, "%s/mmap-%s.dat", file->H5DWMM->cache->path, rnd); #ifndef NDEBUG LOG_DEBUG(-1, "**Using node local storage to cache the file"); LOG_DEBUG(-1, "**path: %s", file->H5DWMM->cache->path); @@ -5526,7 +5560,9 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, if (file->H5LS->path != NULL) { // Build cache path: // - file->H5DRMM->cache->path = cache_utils_build_path(file->H5LS->path, basename((char *)name), "/", NULL); + char *base = basename((char *)name); + size_t path_len = strlen(file->H5LS->path) + strlen(base) + 2; + file->H5DRMM->cache->path = (char *)malloc(path_len); if (file->H5DRMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate file read cache path"); free(file->H5DRMM->mmap); @@ -5537,6 +5573,7 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DRMM = NULL; return FAIL; } + snprintf(file->H5DRMM->cache->path, path_len, "%s/%s", file->H5LS->path, base); #ifndef NDEBUG LOG_DEBUG(-1, "file cache created: %s", file->H5DRMM->cache->path); @@ -5628,6 +5665,7 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, H5P_DATASET_XFER_DEFAULT, NULL); o->read_cache = true; + // TODO - May create persistent ref that needs ref counting? o->H5LS->cache_io_cls->create_cache((void *)o, &file_args, req); } int np; @@ -5684,18 +5722,21 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, if (dset->H5LS->path != NULL) { // Build cache path: // - dset->H5DRMM->cache->path = cache_utils_build_path(p->H5DRMM->cache->path, name, "/", NULL); + size_t path_len = strlen(p->H5DRMM->cache->path) + strlen(name) + 2; + dset->H5DRMM->cache->path = (char *)malloc(path_len); if (dset->H5DRMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate dataset read cache path"); free(dset->H5DRMM->cache); dset->H5DRMM->cache = NULL; return FAIL; } + snprintf(dset->H5DRMM->cache->path, path_len, "%s/%s", p->H5DRMM->cache->path, name); // Build mmap fname: /dset-mmap-.dat char cc[255]; int2char(dset->H5DRMM->mpi->rank, cc); - dset->H5DRMM->mmap->fname = cache_utils_build_path(dset->H5DRMM->cache->path, "dset-mmap-", cc, ".dat", NULL); + size_t fname_len = strlen(dset->H5DRMM->cache->path) + strlen("dset-mmap-") + strlen(cc) + strlen(".dat") + 2; + dset->H5DRMM->mmap->fname = (char *)malloc(fname_len); if (dset->H5DRMM->mmap->fname == NULL) { LOG_ERROR(-1, "Failed to allocate dataset read mmap fname"); free(dset->H5DRMM->cache->path); @@ -5704,6 +5745,7 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, dset->H5DRMM->cache = NULL; return FAIL; } + snprintf(dset->H5DRMM->mmap->fname, fname_len, "%s/dset-mmap-%s.dat", dset->H5DRMM->cache->path, cc); #ifndef NDEBUG LOG_DEBUG(-1, "Dataset read cache created: %s", @@ -5781,7 +5823,8 @@ static herr_t create_group_cache_on_local_storage(void *obj, void *group_args, memcpy(group->H5DRMM->mpi, o->H5DRMM->mpi, sizeof(MPI_INFO)); if (group->H5LS->path != NULL) { // Build cache path: // - group->H5DRMM->cache->path = cache_utils_build_path(o->H5DRMM->cache->path, name, "/", NULL); + size_t path_len = strlen(o->H5DRMM->cache->path) + strlen(name) + 2; + group->H5DRMM->cache->path = (char *)malloc(path_len); if (group->H5DRMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate group read cache path"); free(group->H5DRMM->mpi); @@ -5790,6 +5833,7 @@ static herr_t create_group_cache_on_local_storage(void *obj, void *group_args, group->H5DRMM = NULL; return FAIL; } + snprintf(group->H5DRMM->cache->path, path_len, "%s/%s", o->H5DRMM->cache->path, name); #ifndef NDEBUG LOG_DEBUG(-1, "group cache created: %s", group->H5DRMM->cache->path); #endif @@ -6127,7 +6171,9 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, file->H5DWMM->io->num_request = 0; if (file->H5LS->path != NULL) { // Build cache path: /-global-cache/ - file->H5DWMM->cache->path = cache_utils_build_path(file->H5LS->path, basename((char *)name), "-global-cache/", NULL); + char *base = basename((char *)name); + size_t path_len = strlen(file->H5LS->path) + strlen(base) + strlen("-global-cache/") + 2; + file->H5DWMM->cache->path = (char *)malloc(path_len); if (file->H5DWMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate file GLOBAL cache path"); free(file->H5DWMM->mmap); @@ -6138,12 +6184,14 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, file->H5DWMM = NULL; return FAIL; } + snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-global-cache/", file->H5LS->path, base); mkdir(file->H5DWMM->cache->path, 0755); // setup the folder with the name of the file, and put // everything under it. // Build mmap fname: / - file->H5DWMM->mmap->fname = cache_utils_build_path(file->H5DWMM->cache->path, basename((char *)name), NULL); + size_t fname_len = strlen(file->H5DWMM->cache->path) + strlen(base) + 1; + file->H5DWMM->mmap->fname = (char *)malloc(fname_len); if (file->H5DWMM->mmap->fname == NULL) { LOG_ERROR(-1, "Failed to allocate file GLOBAL mmap fname"); free(file->H5DWMM->cache->path); @@ -6156,6 +6204,7 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, file->H5DWMM = NULL; return FAIL; } + snprintf(file->H5DWMM->mmap->fname, fname_len, "%s%s", file->H5DWMM->cache->path, base); #ifndef NDEBUG LOG_INFO(-1, "Using global storage as a cache"); diff --git a/src/H5VLcache_ext.h b/src/H5VLcache_ext.h index cd1bb61..fafd0ea 100644 --- a/src/H5VLcache_ext.h +++ b/src/H5VLcache_ext.h @@ -36,8 +36,11 @@ typedef struct H5VL_cache_ext_info_t { char fconfig[255]; /* file name for config, this is specific to caching VOL */ } H5VL_cache_ext_info_t; +/* Forward declaration for self-referential struct */ +typedef struct H5VL_cache_ext_t H5VL_cache_ext_t; + /* The Cache VOL info object */ -typedef struct H5VL_cache_ext_t { +struct H5VL_cache_ext_t { hid_t under_vol_id; /* ID for underlying VOL connector */ void *under_object; /* Info object for underlying VOL connector */ // the following are specific to caching vol. @@ -55,10 +58,11 @@ typedef struct H5VL_cache_ext_t { object_close_task_t *async_close_task_list, *async_close_task_current, *async_close_task_head; hid_t es_id; // event set id associated to all - void *parent; // parent object, file->group->dataset + H5VL_cache_ext_t *parent; // parent object, file->group->dataset cache_storage_t *H5LS; H5I_type_t obj_type; -} H5VL_cache_ext_t; + size_t ref_count; +}; #ifdef __cplusplus extern "C" { diff --git a/src/cache_utils.c b/src/cache_utils.c index 4a908cd..da5286e 100644 --- a/src/cache_utils.c +++ b/src/cache_utils.c @@ -12,7 +12,6 @@ #include "stdlib.h" #include "string.h" #include "unistd.h" -#include #include // POSIX I/O #include "cache_utils.h" @@ -165,53 +164,3 @@ herr_t rmdirRecursive(const char *path) { ret = rmdir(path); return ret; } - -/*------------------------------------------------------------------------- - * Function: cache_utils_build_path - * - * Purpose: Build a path from multiple components (varargs, NULL-terminated) - * - * Return: Pointer to newly allocated path string, or NULL on failure - * - * Example: cache_utils_build_path("/tmp", "file.h5", "group", NULL) - * Returns: "/tmp/file.h5/group" - * - *------------------------------------------------------------------------- - */ -char *cache_utils_build_path(const char *base, ...) { - if (base == NULL) - return NULL; - - va_list args; - const char *component; - size_t total_len = strlen(base); - int num_components = 0; - - // First pass: calculate total length - va_start(args, base); - while ((component = va_arg(args, const char *)) != NULL) { - total_len += strlen(component); - num_components++; - } - va_end(args); - - // Allocate buffer (base + components + separators + null terminator) - char *result = (char *)malloc(total_len + num_components + 1); - if (result == NULL) - return NULL; - - // Second pass: build the path - strcpy(result, base); - - va_start(args, base); - while ((component = va_arg(args, const char *)) != NULL) { - // Add separator if needed (avoid double slashes) - size_t current_len = strlen(result); - if (current_len > 0 && result[current_len - 1] != '/' && component[0] != '/') - strcat(result, "/"); - strcat(result, component); - } - va_end(args); - - return result; -} diff --git a/src/cache_utils.h b/src/cache_utils.h index 762c1cf..2208917 100644 --- a/src/cache_utils.h +++ b/src/cache_utils.h @@ -45,10 +45,6 @@ void parallel_dist(size_t dim, int nproc, int rank, size_t *ldim, void int2char(int a, char str[255]); void mkdirRecursive(const char *path, mode_t mode); herr_t rmdirRecursive(const char *path); - -// Helper functions for dynamic string allocation -char *cache_utils_build_path(const char *base, ...); // NULL-terminated varargs - #ifdef __cplusplus } #endif From 9ffc2254d9c35ebed7e9938097c0a1cff51b0edb Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Fri, 24 Oct 2025 11:16:01 -0500 Subject: [PATCH 03/10] Clang-format --- src/H5LS.h | 16 ++++++++-------- src/H5VLcache_ext.c | 45 +++++++++++++++++++++++++++++---------------- src/H5VLcache_ext.h | 2 +- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/H5LS.h b/src/H5LS.h index f9b8103..1d7cb32 100644 --- a/src/H5LS.h +++ b/src/H5LS.h @@ -115,14 +115,14 @@ typedef struct _IO_THREAD { // Memory mapped files typedef struct _MMAP { // for write - int fd; // file handle for write - char *fname; // dynamically allocated full path of the memory mapped file - void *obj; // this will be used for cache data on global storage layer - void *buf; // pointer that map the file to the memory - void *tmp_buf; // temporally buffer, used for parallel read: copy the read - // buffer, return the H5Dread_to_cache function, the back - // ground thread write the data to the SSD. - hsize_t offset; // the offset of the memory map + int fd; // file handle for write + char *fname; // dynamically allocated full path of the memory mapped file + void *obj; // this will be used for cache data on global storage layer + void *buf; // pointer that map the file to the memory + void *tmp_buf; // temporally buffer, used for parallel read: copy the read + // buffer, return the H5Dread_to_cache function, the back + // ground thread write the data to the SSD. + hsize_t offset; // the offset of the memory map } MMAP; // Dataset diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index 37acc3b..7154d29 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -5481,17 +5481,20 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, sprintf(rnd, "%d", file->H5DWMM->mpi->rank); char *base = basename((char *)name); - size_t path_len = strlen(file->H5LS->path) + strlen(base) + strlen("-cache") + 2; + size_t path_len = + strlen(file->H5LS->path) + strlen(base) + strlen("-cache") + 2; file->H5DWMM->cache->path = (char *)malloc(path_len); if (file->H5DWMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate cache path"); free(file->H5DWMM->cache); return FAIL; } - snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-cache", file->H5LS->path, base); + snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-cache", + file->H5LS->path, base); // Build mmap fname: /mmap-.dat - size_t fname_len = strlen(file->H5DWMM->cache->path) + strlen("mmap-") + strlen(rnd) + strlen(".dat") + 2; + size_t fname_len = strlen(file->H5DWMM->cache->path) + strlen("mmap-") + + strlen(rnd) + strlen(".dat") + 2; file->H5DWMM->mmap->fname = (char *)malloc(fname_len); if (file->H5DWMM->mmap->fname == NULL) { LOG_ERROR(-1, "Failed to allocate mmap fname"); @@ -5500,7 +5503,8 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, free(file->H5DWMM->cache); return FAIL; } - snprintf(file->H5DWMM->mmap->fname, fname_len, "%s/mmap-%s.dat", file->H5DWMM->cache->path, rnd); + snprintf(file->H5DWMM->mmap->fname, fname_len, "%s/mmap-%s.dat", + file->H5DWMM->cache->path, rnd); #ifndef NDEBUG LOG_DEBUG(-1, "**Using node local storage to cache the file"); LOG_DEBUG(-1, "**path: %s", file->H5DWMM->cache->path); @@ -5573,7 +5577,8 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DRMM = NULL; return FAIL; } - snprintf(file->H5DRMM->cache->path, path_len, "%s/%s", file->H5LS->path, base); + snprintf(file->H5DRMM->cache->path, path_len, "%s/%s", file->H5LS->path, + base); #ifndef NDEBUG LOG_DEBUG(-1, "file cache created: %s", file->H5DRMM->cache->path); @@ -5730,12 +5735,15 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, dset->H5DRMM->cache = NULL; return FAIL; } - snprintf(dset->H5DRMM->cache->path, path_len, "%s/%s", p->H5DRMM->cache->path, name); + snprintf(dset->H5DRMM->cache->path, path_len, "%s/%s", + p->H5DRMM->cache->path, name); // Build mmap fname: /dset-mmap-.dat char cc[255]; int2char(dset->H5DRMM->mpi->rank, cc); - size_t fname_len = strlen(dset->H5DRMM->cache->path) + strlen("dset-mmap-") + strlen(cc) + strlen(".dat") + 2; + size_t fname_len = strlen(dset->H5DRMM->cache->path) + + strlen("dset-mmap-") + strlen(cc) + strlen(".dat") + + 2; dset->H5DRMM->mmap->fname = (char *)malloc(fname_len); if (dset->H5DRMM->mmap->fname == NULL) { LOG_ERROR(-1, "Failed to allocate dataset read mmap fname"); @@ -5745,7 +5753,8 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, dset->H5DRMM->cache = NULL; return FAIL; } - snprintf(dset->H5DRMM->mmap->fname, fname_len, "%s/dset-mmap-%s.dat", dset->H5DRMM->cache->path, cc); + snprintf(dset->H5DRMM->mmap->fname, fname_len, "%s/dset-mmap-%s.dat", + dset->H5DRMM->cache->path, cc); #ifndef NDEBUG LOG_DEBUG(-1, "Dataset read cache created: %s", @@ -5833,7 +5842,8 @@ static herr_t create_group_cache_on_local_storage(void *obj, void *group_args, group->H5DRMM = NULL; return FAIL; } - snprintf(group->H5DRMM->cache->path, path_len, "%s/%s", o->H5DRMM->cache->path, name); + snprintf(group->H5DRMM->cache->path, path_len, "%s/%s", + o->H5DRMM->cache->path, name); #ifndef NDEBUG LOG_DEBUG(-1, "group cache created: %s", group->H5DRMM->cache->path); #endif @@ -5859,7 +5869,7 @@ static herr_t remove_group_cache_on_local_storage(void *obj, void **req) { H5VL_cache_ext_t *group = (H5VL_cache_ext_t *)obj; if (group->read_cache) { free(group->H5DRMM->cache->path); - group->H5DRMM->cache->path = NULL; + group->H5DRMM->cache->path = NULL; free(group->H5DRMM->cache); free(group->H5DRMM->mpi); free(group->H5DRMM); @@ -6172,7 +6182,8 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, if (file->H5LS->path != NULL) { // Build cache path: /-global-cache/ char *base = basename((char *)name); - size_t path_len = strlen(file->H5LS->path) + strlen(base) + strlen("-global-cache/") + 2; + size_t path_len = strlen(file->H5LS->path) + strlen(base) + + strlen("-global-cache/") + 2; file->H5DWMM->cache->path = (char *)malloc(path_len); if (file->H5DWMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate file GLOBAL cache path"); @@ -6184,7 +6195,8 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, file->H5DWMM = NULL; return FAIL; } - snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-global-cache/", file->H5LS->path, base); + snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-global-cache/", + file->H5LS->path, base); mkdir(file->H5DWMM->cache->path, 0755); // setup the folder with the name of the file, and put // everything under it. @@ -6195,7 +6207,7 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, if (file->H5DWMM->mmap->fname == NULL) { LOG_ERROR(-1, "Failed to allocate file GLOBAL mmap fname"); free(file->H5DWMM->cache->path); - file->H5DWMM->cache->path = NULL; + file->H5DWMM->cache->path = NULL; free(file->H5DWMM->mmap); free(file->H5DWMM->cache); free(file->H5DWMM->io); @@ -6204,7 +6216,8 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, file->H5DWMM = NULL; return FAIL; } - snprintf(file->H5DWMM->mmap->fname, fname_len, "%s%s", file->H5DWMM->cache->path, base); + snprintf(file->H5DWMM->mmap->fname, fname_len, "%s%s", + file->H5DWMM->cache->path, base); #ifndef NDEBUG LOG_INFO(-1, "Using global storage as a cache"); @@ -6596,10 +6609,10 @@ static herr_t remove_dataset_cache_on_global_storage(void *dset, void **req) { if (o->write_cache || o->read_cache) { H5Dclose_async(o->hd_glob, H5ES_NONE); free(o->H5DWMM->cache->path); - o->H5DWMM->cache->path = NULL; + o->H5DWMM->cache->path = NULL; free(o->H5DWMM->cache); free(o->H5DWMM->mmap->fname); - o->H5DWMM->mmap->fname = NULL; + o->H5DWMM->mmap->fname = NULL; free(o->H5DWMM->mmap); free(o->H5DWMM); o->H5DWMM = NULL; diff --git a/src/H5VLcache_ext.h b/src/H5VLcache_ext.h index fafd0ea..e4abffe 100644 --- a/src/H5VLcache_ext.h +++ b/src/H5VLcache_ext.h @@ -57,7 +57,7 @@ struct H5VL_cache_ext_t { hid_t hd_glob; object_close_task_t *async_close_task_list, *async_close_task_current, *async_close_task_head; - hid_t es_id; // event set id associated to all + hid_t es_id; // event set id associated to all H5VL_cache_ext_t *parent; // parent object, file->group->dataset cache_storage_t *H5LS; H5I_type_t obj_type; From ce9b9b316bbffd2e92f3e801c81add71e021ac94 Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Fri, 24 Oct 2025 14:31:02 -0500 Subject: [PATCH 04/10] Fix bad arg memory access --- src/H5VLcache_ext.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index 7154d29..b8b7b25 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -3761,12 +3761,12 @@ static void *H5VL_cache_ext_file_open(const char *name, unsigned flags, file->async_pause = false; set_file_cache((void *)file, (void *)args, req); } - free(args); /* Close underlying FAPL */ H5Pclose(under_fapl_id); H5Pclose(args->fapl_id); H5Pclose(args->fcpl_id); H5Pclose(args->dxpl_id); + free(args); H5VL_cache_ext_info_free(info); return (void *)file; } /* end H5VL_cache_ext_file_open() */ @@ -5670,7 +5670,6 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, H5P_DATASET_XFER_DEFAULT, NULL); o->read_cache = true; - // TODO - May create persistent ref that needs ref counting? o->H5LS->cache_io_cls->create_cache((void *)o, &file_args, req); } int np; From 4864c74ab0f02bc70b1cec7339dbd260c067df7b Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Mon, 3 Nov 2025 11:58:49 -0600 Subject: [PATCH 05/10] Address comments --- src/H5VLcache_ext.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index b8b7b25..8eeff81 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -902,7 +902,11 @@ static herr_t H5VL_cache_ext_free_obj(H5VL_cache_ext_t *obj) { err_id = H5Eget_current_stack(); - assert(obj->ref_count > 0); + if (obj->ref_count == 0) { + LOG_ERROR(-1, "Attempting to decrement ref_count that is already 0"); + return FAIL; + } + obj->ref_count--; if (obj->ref_count == 0) { @@ -3508,12 +3512,6 @@ static herr_t H5VL_cache_ext_datatype_close(void *dt, hid_t dxpl_id, return ret_value; } /* end H5VL_cache_ext_datatype_close() */ -char *get_fname(const char *path) { - char tmp[255]; - strcpy(tmp, path); - return basename(tmp); -} - static ssize_t file_get_name(void *file, hid_t driver_id, size_t buf_size, char *buf, hid_t dxpl_id, void **req) { H5VL_file_get_args_t vol_cb_args; @@ -3566,7 +3564,10 @@ static herr_t set_file_cache(void *obj, void *file_args, void **req) { file->write_cache = false; file->read_cache = false; if (file->parent != NULL) { - assert(file->parent->ref_count > 0); + if (file->parent->ref_count == 0) { + LOG_ERROR(-1, "Parent ref count is zero!"); + return FAIL; + } H5VL_cache_ext_free_obj(file->parent); } @@ -5415,8 +5416,6 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DWMM->io = (IO_THREAD *)malloc(sizeof(IO_THREAD)); file->H5DWMM->io->fusion_data_size = 0.0; file->H5DWMM->io->num_fusion_requests = 0; - file->H5DWMM->cache = (cache_t *)malloc(sizeof(cache_t)); - file->H5DWMM->cache->path = NULL; file->H5DWMM->mmap = (MMAP *)malloc(sizeof(MMAP)); file->H5DWMM->mmap->fname = NULL; } else { @@ -5457,6 +5456,10 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, " Try to decrease HDF5_CACHE_WRITE_BUFFER_SIZE."); file->write_cache = false; free(file->H5DWMM->cache); + free(file->H5DWMM->mpi); + free(file->H5DWMM->io); + free(file->H5DWMM); + file->H5DWMM = NULL; return FAIL; } else if (H5LSclaim_space(file->H5LS, file->H5DWMM->cache->mspace_total, HARD, file->H5LS->replacement_policy) == FAIL) { @@ -5464,6 +5467,10 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, "cache"); file->write_cache = false; free(file->H5DWMM->cache); + free(file->H5DWMM->mpi); + free(file->H5DWMM->io); + free(file->H5DWMM); + file->H5DWMM = NULL; return FAIL; } @@ -5479,7 +5486,10 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, // Build cache path: /-cache/ char rnd[255]; sprintf(rnd, "%d", file->H5DWMM->mpi->rank); - char *base = basename((char *)name); + char name_buf[4096]; + strncpy(name_buf, name, sizeof(name_buf) - 1); + name_buf[sizeof(name_buf) - 1] = '\0'; + char *base = basename(name_buf); size_t path_len = strlen(file->H5LS->path) + strlen(base) + strlen("-cache") + 2; @@ -5564,7 +5574,10 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, if (file->H5LS->path != NULL) { // Build cache path: // - char *base = basename((char *)name); + char name_buf[4096]; + strncpy(name_buf, name, sizeof(name_buf) - 1); + name_buf[sizeof(name_buf) - 1] = '\0'; + char *base = basename(name_buf); size_t path_len = strlen(file->H5LS->path) + strlen(base) + 2; file->H5DRMM->cache->path = (char *)malloc(path_len); if (file->H5DRMM->cache->path == NULL) { @@ -6180,7 +6193,10 @@ static herr_t create_file_cache_on_global_storage(void *obj, void *file_args, file->H5DWMM->io->num_request = 0; if (file->H5LS->path != NULL) { // Build cache path: /-global-cache/ - char *base = basename((char *)name); + char name_buf[4096]; + strncpy(name_buf, name, sizeof(name_buf) - 1); + name_buf[sizeof(name_buf) - 1] = '\0'; + char *base = basename(name_buf); size_t path_len = strlen(file->H5LS->path) + strlen(base) + strlen("-global-cache/") + 2; file->H5DWMM->cache->path = (char *)malloc(path_len); From caf929ccf6e4d4aacd7e1ac60ed2c44aa9a6f0ae Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Mon, 10 Nov 2025 11:49:05 -0600 Subject: [PATCH 06/10] Correct early return --- src/H5VLcache_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index 8eeff81..89e7c1e 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -904,7 +904,7 @@ static herr_t H5VL_cache_ext_free_obj(H5VL_cache_ext_t *obj) { if (obj->ref_count == 0) { LOG_ERROR(-1, "Attempting to decrement ref_count that is already 0"); - return FAIL; + goto error; } obj->ref_count--; From a560b8a5853c14945540122757a535d3ef1cb50c Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Mon, 10 Nov 2025 11:49:52 -0600 Subject: [PATCH 07/10] Remove redundant check --- src/H5VLcache_ext.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index 89e7c1e..f73cb6b 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -3563,13 +3563,8 @@ static herr_t set_file_cache(void *obj, void *file_args, void **req) { file->write_cache = false; file->read_cache = false; - if (file->parent != NULL) { - if (file->parent->ref_count == 0) { - LOG_ERROR(-1, "Parent ref count is zero!"); - return FAIL; - } + if (file->parent != NULL) H5VL_cache_ext_free_obj(file->parent); - } file->parent = NULL; From 1cb0d94f35ce39979f19131c95543abf14e0821a Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Mon, 10 Nov 2025 12:15:47 -0600 Subject: [PATCH 08/10] Consolidate cleanup --- src/H5VLcache_ext.c | 55 ++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index f73cb6b..971330e 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -5399,6 +5399,8 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file_args_t *args = (file_args_t *)file_args; const char *name = args->name; H5VL_cache_ext_t *file = (H5VL_cache_ext_t *)obj; + bool write_fail = false; + bool read_fail = false; H5VL_cache_ext_info_t *info; /* Get copy of our VOL info from FAPL */ @@ -5450,23 +5452,15 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, " Will turn off Cache effect." " Try to decrease HDF5_CACHE_WRITE_BUFFER_SIZE."); file->write_cache = false; - free(file->H5DWMM->cache); - free(file->H5DWMM->mpi); - free(file->H5DWMM->io); - free(file->H5DWMM); - file->H5DWMM = NULL; - return FAIL; + write_fail = true; + goto error; } else if (H5LSclaim_space(file->H5LS, file->H5DWMM->cache->mspace_total, HARD, file->H5LS->replacement_policy) == FAIL) { LOG_ERROR(-1, "Unable to claim space, turning off write " "cache"); file->write_cache = false; - free(file->H5DWMM->cache); - free(file->H5DWMM->mpi); - free(file->H5DWMM->io); - free(file->H5DWMM); - file->H5DWMM = NULL; - return FAIL; + write_fail = true; + goto error; } file->H5DWMM->cache->mspace_left = file->H5DWMM->cache->mspace_total; @@ -5491,8 +5485,8 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DWMM->cache->path = (char *)malloc(path_len); if (file->H5DWMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate cache path"); - free(file->H5DWMM->cache); - return FAIL; + write_fail = true; + goto error; } snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-cache", file->H5LS->path, base); @@ -5503,10 +5497,8 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DWMM->mmap->fname = (char *)malloc(fname_len); if (file->H5DWMM->mmap->fname == NULL) { LOG_ERROR(-1, "Failed to allocate mmap fname"); - free(file->H5DWMM->cache->path); - file->H5DWMM->cache->path = NULL; - free(file->H5DWMM->cache); - return FAIL; + write_fail = true; + goto error; } snprintf(file->H5DWMM->mmap->fname, fname_len, "%s/mmap-%s.dat", file->H5DWMM->cache->path, rnd); @@ -5577,13 +5569,8 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, file->H5DRMM->cache->path = (char *)malloc(path_len); if (file->H5DRMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate file read cache path"); - free(file->H5DRMM->mmap); - free(file->H5DRMM->cache); - free(file->H5DRMM->io); - free(file->H5DRMM->mpi); - free(file->H5DRMM); - file->H5DRMM = NULL; - return FAIL; + read_fail = true; + goto error; } snprintf(file->H5DRMM->cache->path, path_len, "%s/%s", file->H5LS->path, base); @@ -5596,6 +5583,24 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, // mkdir(file->H5DRMM->cache->path, 0755); } return SUCCEED; + +error: + if (write_fail) { + free(file->H5DWMM->cache); + free(file->H5DWMM->mpi); + free(file->H5DWMM->io); + free(file->H5DWMM); + file->H5DWMM = NULL; + } + if (read_fail) { + free(file->H5DRMM->mmap); + free(file->H5DRMM->cache); + free(file->H5DRMM->io); + free(file->H5DRMM->mpi); + free(file->H5DRMM); + file->H5DRMM = NULL; + } + return FAIL; } static herr_t remove_file_cache_on_local_storage(void *file, void **req) { From 0a0ad899df7b98f73cb392359e6baff7a74a21ee Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Mon, 10 Nov 2025 14:13:38 -0600 Subject: [PATCH 09/10] Re-add trailing slashes to paths --- src/H5VLcache_ext.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index 971330e..ea2f76f 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -5488,7 +5488,7 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, write_fail = true; goto error; } - snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-cache", + snprintf(file->H5DWMM->cache->path, path_len, "%s/%s-cache/", file->H5LS->path, base); // Build mmap fname: /mmap-.dat @@ -5572,7 +5572,7 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, read_fail = true; goto error; } - snprintf(file->H5DRMM->cache->path, path_len, "%s/%s", file->H5LS->path, + snprintf(file->H5DRMM->cache->path, path_len, "%s/%s/", file->H5LS->path, base); #ifndef NDEBUG @@ -5747,7 +5747,7 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, dset->H5DRMM->cache = NULL; return FAIL; } - snprintf(dset->H5DRMM->cache->path, path_len, "%s/%s", + snprintf(dset->H5DRMM->cache->path, path_len, "%s/%s/", p->H5DRMM->cache->path, name); // Build mmap fname: /dset-mmap-.dat @@ -5854,7 +5854,7 @@ static herr_t create_group_cache_on_local_storage(void *obj, void *group_args, group->H5DRMM = NULL; return FAIL; } - snprintf(group->H5DRMM->cache->path, path_len, "%s/%s", + snprintf(group->H5DRMM->cache->path, path_len, "%s/%s/", o->H5DRMM->cache->path, name); #ifndef NDEBUG LOG_DEBUG(-1, "group cache created: %s", group->H5DRMM->cache->path); From 93dfb3a85361644728fb626042f6d35253ade03a Mon Sep 17 00:00:00 2001 From: Matthew Larson Date: Tue, 11 Nov 2025 11:22:39 -0600 Subject: [PATCH 10/10] Update path buffer sizes to hold slashes --- src/H5VLcache_ext.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/H5VLcache_ext.c b/src/H5VLcache_ext.c index ea2f76f..6b34701 100644 --- a/src/H5VLcache_ext.c +++ b/src/H5VLcache_ext.c @@ -5481,7 +5481,7 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, char *base = basename(name_buf); size_t path_len = - strlen(file->H5LS->path) + strlen(base) + strlen("-cache") + 2; + strlen(file->H5LS->path) + strlen(base) + strlen("-cache/") + 2; file->H5DWMM->cache->path = (char *)malloc(path_len); if (file->H5DWMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate cache path"); @@ -5565,7 +5565,8 @@ static herr_t create_file_cache_on_local_storage(void *obj, void *file_args, strncpy(name_buf, name, sizeof(name_buf) - 1); name_buf[sizeof(name_buf) - 1] = '\0'; char *base = basename(name_buf); - size_t path_len = strlen(file->H5LS->path) + strlen(base) + 2; + size_t path_len = strlen(file->H5LS->path) + strlen(base) + + 3; // 3 for two slashes and null file->H5DRMM->cache->path = (char *)malloc(path_len); if (file->H5DRMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate file read cache path"); @@ -5739,7 +5740,8 @@ static herr_t create_dataset_cache_on_local_storage(void *obj, void *dset_args, if (dset->H5LS->path != NULL) { // Build cache path: // - size_t path_len = strlen(p->H5DRMM->cache->path) + strlen(name) + 2; + size_t path_len = strlen(p->H5DRMM->cache->path) + strlen(name) + + 3; // 3 for two slashes and null dset->H5DRMM->cache->path = (char *)malloc(path_len); if (dset->H5DRMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate dataset read cache path"); @@ -5844,7 +5846,8 @@ static herr_t create_group_cache_on_local_storage(void *obj, void *group_args, memcpy(group->H5DRMM->mpi, o->H5DRMM->mpi, sizeof(MPI_INFO)); if (group->H5LS->path != NULL) { // Build cache path: // - size_t path_len = strlen(o->H5DRMM->cache->path) + strlen(name) + 2; + size_t path_len = strlen(o->H5DRMM->cache->path) + strlen(name) + + 3; // 3 for two slashes and null group->H5DRMM->cache->path = (char *)malloc(path_len); if (group->H5DRMM->cache->path == NULL) { LOG_ERROR(-1, "Failed to allocate group read cache path");