summaryrefslogtreecommitdiffstats
path: root/src/H5Fint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Fint.c')
-rw-r--r--src/H5Fint.c207
1 files changed, 205 insertions, 2 deletions
diff --git a/src/H5Fint.c b/src/H5Fint.c
index abc638a..6448027 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -79,6 +79,9 @@ static char *H5F__getenv_prefix_name(char **env_prefix/*in,out*/);
static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, char ** /*out*/ actual_name);
static herr_t H5F__flush_phase1(H5F_t *f);
static herr_t H5F__flush_phase2(H5F_t *f, hbool_t closing);
+static herr_t H5F__init_vfd_swmr(H5F_t *f, hbool_t file_create);
+static herr_t H5F__init_vfd_swmr_info(H5F_t *f);
+static herr_t H5F__init_vfd_swmr_md(H5F_t *f, hbool_t file_create);
/*********************/
@@ -184,6 +187,10 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
if(H5P_set(new_plist, H5F_ACS_PAGE_BUFFER_MIN_RAW_PERC_NAME, &(f->shared->page_buf->min_raw_perc)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set minimum raw data fraction of page buffer")
} /* end if */
+
+ if(H5P_set(new_plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, &(f->shared->vfd_swmr_config)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.")
+
#ifdef H5_HAVE_PARALLEL
if(H5P_set(new_plist, H5_COLL_MD_READ_FLAG_NAME, &(f->coll_md_read)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set collective metadata read flag")
@@ -1033,6 +1040,10 @@ H5F__new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_
if(H5P_get(plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &(f->shared->object_flush)) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get object flush cb info")
+ /* Get VFD SWMR configuration */
+ if(H5P_get(plist, H5F_ACS_VFD_SWMR_CONFIG_NAME, &(f->shared->vfd_swmr_config)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get VFD SWMR config info")
+
/* Create a metadata cache with the specified number of elements.
* The cache might be created with a different number of elements and
* the access property list should be updated to reflect that.
@@ -1497,7 +1508,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
hbool_t use_file_locking; /*read from env var */
hbool_t ci_load = FALSE; /* whether MDC ci load requested */
hbool_t ci_write = FALSE; /* whether MDC CI write requested */
- H5F_t *ret_value = NULL; /*actual return value */
+ hbool_t file_create = FALSE; /* creating a new file or not */
+ H5F_t *ret_value = NULL; /*actual return value */
FUNC_ENTER_NOAPI(NULL)
@@ -1667,6 +1679,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get minimum raw data fraction of page buffer")
} /* end if */
+
/*
* Read or write the file superblock, depending on whether the file is
* empty or not.
@@ -1693,6 +1706,9 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
*/
if(H5G_mkroot(file, TRUE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group")
+
+ file_create = TRUE;
+
} /* end if */
else if (1 == shared->nrefs) {
/* Read the superblock if it hasn't been read before. */
@@ -1707,8 +1723,19 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Open the root group */
if(H5G_mkroot(file, FALSE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group")
+
} /* end if */
+ if(H5F_VFD_SWMR_CONFIG(file)) {
+ /* Page buffering and page allocation strategy have to be enabled */
+ if(!page_buf_size || !H5F_PAGED_AGGR(file))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "file open fail with VFD SWMR writer")
+ if(1 == shared->nrefs && H5F_INTENT(file) & H5F_ACC_RDWR) {
+ if(H5F__init_vfd_swmr(file, file_create) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "file open fail with initialization for VFD SWMR writer")
+ }
+ }
+
/*
* Decide the file close degree. If it's the first time to open the
* file, set the degree to access property list value; if it's the
@@ -1812,9 +1839,15 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
ret_value = file;
done:
- if((NULL == ret_value) && file)
+ if((NULL == ret_value) && file) {
+ if(file->shared->root_grp && file->shared->nrefs == 1) {
+ if(H5AC_expunge_tag_type_metadata(file, H5G_oloc(file->shared->root_grp)->addr, H5AC_OHDR_ID, H5AC__NO_FLAGS_SET, FALSE) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTEXPUNGE, NULL, "unable to expunge root group tagged entries")
+ }
+
if(H5F__dest(file, FALSE) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file")
+ }
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_open() */
@@ -3685,3 +3718,173 @@ done:
FUNC_LEAVE_NOAPI_VOL(ret_value)
} /* H5F__format_convert() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__init_vfd_swmr
+ *
+ * Purpose: Intitialize info and the metadata file for VFD SWMR writer.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__init_vfd_swmr(H5F_t *f, hbool_t file_create)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Initialize info */
+ if(H5F__init_vfd_swmr_info(f) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "error in initializing info for VFD SWMR writer")
+
+ /* Initialize the metadata file */
+ if(H5F__init_vfd_swmr_md(f, file_create) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "error in creating metadata file for VFD SWMR writer")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__init_vfd_swmr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__init_vfd_swmr_info
+ *
+ * Purpose: Initialize globals and the corresponding fields in f
+ * for VFD SWMR writer:
+ * --set vfd_swmr_g to TRUE
+ * --set vfd_swmr_writer_g to TRUE
+ * --set tick_num_g to 0
+ * --set end_of_tick_g to the current time + tick length
+ * --set vfd_swmr_file_g to f->shared
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__init_vfd_swmr_info(H5F_t *f)
+{
+ struct timespec tmp_end_of_tick;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ HDassert(f->shared->vfd_swmr_config.vfd_swmr_writer);
+
+ vfd_swmr_g = f->shared->vfd_swmr = TRUE;
+ vfd_swmr_writer_g = f->shared->vfd_swmr_writer = TRUE;
+ tick_num_g = f->shared->tick_num = 0;
+
+ /* Get current time */
+ if(HDclock_gettime(CLOCK_MONOTONIC, &tmp_end_of_tick) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time via clock_gettime")
+
+ /* Increment by tick length */
+ tmp_end_of_tick.tv_nsec += f->shared->vfd_swmr_config.tick_len * 100000000;
+ tmp_end_of_tick.tv_sec += tmp_end_of_tick.tv_nsec / 1000000000;
+ tmp_end_of_tick.tv_nsec = tmp_end_of_tick.tv_nsec % 1000000000;
+ HDmemcpy(&end_of_tick_g, &tmp_end_of_tick, sizeof(struct timespec));
+ HDmemcpy(&f->shared->end_of_tick, &tmp_end_of_tick, sizeof(struct timespec));
+
+ vfd_swmr_file_g = f->shared;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__init_vfd_swmr_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__init_vfd_swmr_md
+ *
+ * Purpose: Open the metadata file for VFD SMWR and allocate md_pages_reserved
+ * in the file.
+ * If not creating a new file, write header and an empty index
+ * to the file.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__init_vfd_swmr_md(H5F_t *f, hbool_t file_create)
+{
+ uint8_t image[H5FD_MD_HEADER_SIZE]; /* Buffer for element data */
+ uint8_t image_empty_idx[H5FD_MD_INDEX_SIZE(0)]; /* Buffer for element data */
+ uint8_t *p = NULL; /* Pointer to buffer */
+ uint32_t metadata_chksum; /* Computed metadata checksum value */
+ int fd; /* File descriptor */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Open the metadata file */
+ if((fd = HDopen(f->shared->vfd_swmr_config.md_file_path, O_CREAT|O_RDWR, H5_POSIX_CREATE_MODE_RW)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open metadata file")
+
+ /* Set the file to md_pages_reserved */
+ if(HDftruncate(fd, (HDoff_t)f->shared->vfd_swmr_config.md_pages_reserved * f->shared->fs_page_size) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_SEEKERROR, FAIL, "unable to extend file properly")
+
+ if(!file_create) {
+ /*
+ * Encode metadata file header
+ */
+ p = &image[0];
+
+ /* Magic for header */
+ HDmemcpy(p, H5FD_MD_HEADER_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ UINT32ENCODE(p, f->shared->fs_page_size);
+ UINT64ENCODE(p, f->shared->tick_num);
+ UINT64ENCODE(p, H5FD_MD_HEADER_SIZE);
+ UINT64ENCODE(p, H5FD_MD_INDEX_SIZE(0));
+
+ metadata_chksum = H5_checksum_metadata((uint8_t *)p, (size_t)(p - &image[0]), 0);
+
+ /* Checksum for header */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* Sanity checks */
+ HDassert((size_t)(p - &image[0] == H5FD_MD_HEADER_SIZE));
+
+ /* Write header to the metadata file */
+ if(HDwrite(fd, &image[0], H5FD_MD_HEADER_SIZE) != H5FD_MD_HEADER_SIZE)
+ HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing header to metadata file")
+
+ /*
+ * Encode metadata file index
+ */
+ p = &image_empty_idx[0];
+
+ /* Magic for index */
+ HDmemcpy(p, H5FD_MD_INDEX_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ p += H5_SIZEOF_MAGIC;
+
+ UINT64ENCODE(p, f->shared->tick_num);
+
+ /* No entry in index */
+ UINT32ENCODE(p, 0);
+
+ metadata_chksum = H5_checksum_metadata((uint8_t *)p, (size_t)(p - &image_empty_idx[0]), 0);
+
+ /* Checksum for index */
+ UINT32ENCODE(p, metadata_chksum);
+
+ /* sanity checks */
+ HDassert((size_t)(p - &image_empty_idx[0] == H5FD_MD_INDEX_SIZE(0)));
+
+ /* Write index to the metadata file */
+ if(HDwrite(fd, &image_empty_idx[0], H5FD_MD_INDEX_SIZE(0)) != H5FD_MD_INDEX_SIZE(0))
+ HGOTO_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "error in writing index to metadata file")
+ }
+ f->shared->vfd_swmr_md_fd = fd;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F__init_vfd_swmr_md() */