summaryrefslogtreecommitdiffstats
path: root/src/H5Fint.c
diff options
context:
space:
mode:
authorDana Robinson <43805+derobins@users.noreply.github.com>2020-11-17 13:47:52 (GMT)
committerGitHub <noreply@github.com>2020-11-17 13:47:52 (GMT)
commit5d0be1b196570ac2c08ffe0b61ac6a45b6ab7f3f (patch)
treedbe8a76bcb211babe9900647eb1f515d8623ad9b /src/H5Fint.c
parentec48fb8dfdb4f2f59f22a5efb6b950aafcac449d (diff)
downloadhdf5-5d0be1b196570ac2c08ffe0b61ac6a45b6ab7f3f.zip
hdf5-5d0be1b196570ac2c08ffe0b61ac6a45b6ab7f3f.tar.gz
hdf5-5d0be1b196570ac2c08ffe0b61ac6a45b6ab7f3f.tar.bz2
Manual sync with develop (#95)
Brings all features from develop. Note that RELEASE.txt has not been updated (will be done in a future PR).
Diffstat (limited to 'src/H5Fint.c')
-rw-r--r--src/H5Fint.c140
1 files changed, 120 insertions, 20 deletions
diff --git a/src/H5Fint.c b/src/H5Fint.c
index d364a04..1d7a86f 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -80,6 +80,7 @@ static int H5F__get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
static herr_t H5F__build_name(const char *prefix, const char *file_name, char **full_name /*out*/);
static char * H5F__getenv_prefix_name(char **env_prefix /*in,out*/);
static H5F_t *H5F__new(H5F_shared_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf);
+static herr_t H5F__check_if_using_file_locks(H5P_genplist_t *fapl, hbool_t *use_file_locking);
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);
@@ -92,6 +93,12 @@ static herr_t H5F__flush_phase2(H5F_t *f, hbool_t closing);
/* Package initialization variable */
hbool_t H5_PKG_INIT_VAR = FALSE;
+/* Based on the value of the HDF5_USE_FILE_LOCKING environment variable.
+ * TRUE/FALSE have obvious meanings. FAIL means the environment variable was
+ * not set, so the code should ignore it and use the fapl value instead.
+ */
+htri_t use_locks_env_g = FAIL;
+
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -160,6 +167,10 @@ H5F__init_package(void)
if (H5I_register_type(H5I_FILE_CLS) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface")
+ /* Check the file locking environment variable */
+ if (H5F__parse_file_lock_env_var(&use_locks_env_g) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to parse file locking environment variable")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5F__init_package() */
@@ -247,6 +258,38 @@ done:
} /* end H5F__close_cb() */
/*-------------------------------------------------------------------------
+ * Function: H5F__parse_file_lock_env_var
+ *
+ * Purpose: Parses the HDF5_USE_FILE_LOCKING environment variable.
+ *
+ * NOTE: This is done in a separate function so we can call it from
+ * the test code.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F__parse_file_lock_env_var(htri_t *use_locks)
+{
+ char *lock_env_var = NULL; /* Environment variable pointer */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Check the file locking environment variable */
+ lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
+ if (lock_env_var && (!HDstrcmp(lock_env_var, "FALSE") || !HDstrcmp(lock_env_var, "0")))
+ *use_locks = FALSE; /* Override: Never use locks */
+ else if (lock_env_var && (!HDstrcmp(lock_env_var, "TRUE") || !HDstrcmp(lock_env_var, "BEST_EFFORT") ||
+ !HDstrcmp(lock_env_var, "1")))
+ *use_locks = TRUE; /* Override: Always use locks */
+ else
+ *use_locks = FAIL; /* Environment variable not set, or not set correctly */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5F__parse_file_lock_env_var() */
+
+/*-------------------------------------------------------------------------
* Function: H5F__set_vol_conn
*
* Purpose: Set the VOL connector ID and info for a file.
@@ -1573,6 +1616,51 @@ H5F__dest(H5F_t *f, hbool_t flush)
} /* end H5F__dest() */
/*-------------------------------------------------------------------------
+ * Function: H5F__check_if_using_file_locks
+ *
+ * Purpose: Determines if this file will use file locks.
+ *
+ * There are three ways that file locking can be controlled:
+ *
+ * 1) The configure/cmake option that sets the H5_USE_FILE_LOCKING
+ * symbol (which is used as the default fapl value).
+ *
+ * 2) The H5Pset_file_locking() API call, which will override
+ * the configuration default.
+ *
+ * 3) The HDF5_USE_FILE_LOCKING environment variable, which overrides
+ * everything above.
+ *
+ * The main reason to disable file locking is to prevent errors on file
+ * systems where locking is not supported or has been disabled (as is
+ * often the case in parallel file systems).
+ *
+ * Return: SUCCEED/FAIL
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__check_if_using_file_locks(H5P_genplist_t *fapl, hbool_t *use_file_locking)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Make sure the out parameter has a value */
+ *use_file_locking = TRUE;
+
+ /* Check the fapl property */
+ if (H5P_get(fapl, H5F_ACS_USE_FILE_LOCKING_NAME, use_file_locking) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get use file locking flag")
+
+ /* Check the environment variable */
+ if (use_locks_env_g != FAIL)
+ *use_file_locking = (use_locks_env_g == TRUE) ? TRUE : FALSE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__check_if_using_file_locks() */
+
+/*-------------------------------------------------------------------------
* Function: H5F_open
*
* Purpose: Opens (or creates) a file. This function understands the
@@ -1661,11 +1749,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
hbool_t set_flag = FALSE; /*set the status_flags in the superblock */
hbool_t clear = FALSE; /*clear the status_flags */
hbool_t evict_on_close; /* evict on close value from plist */
- char * lock_env_var = NULL; /*env var pointer */
- 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 use_file_locking = TRUE; /* Using file locks? */
+ hbool_t ci_load = FALSE; /* whether MDC ci load requested */
+ hbool_t ci_write = FALSE; /* whether MDC CI write requested */
+ H5F_t * ret_value = NULL; /*actual return value */
FUNC_ENTER_NOAPI(NULL)
@@ -1680,15 +1767,13 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
if (NULL == (drvr = H5FD_get_class(fapl_id)))
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class")
- /* Check the environment variable that determines if we care
- * about file locking. File locking should be used unless explicitly
- * disabled.
- */
- lock_env_var = HDgetenv("HDF5_USE_FILE_LOCKING");
- if (lock_env_var && !HDstrcmp(lock_env_var, "FALSE"))
- use_file_locking = FALSE;
- else
- use_file_locking = TRUE;
+ /* Get the file access property list, for future queries */
+ if (NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
+
+ /* Check if we are using file locking */
+ if (H5F__check_if_using_file_locks(a_plist, &use_file_locking) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get file locking flag")
/*
* Opening a file is a two step process. First we try to open the
@@ -1771,8 +1856,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
if (H5FD_lock(lf, (hbool_t)((flags & H5F_ACC_RDWR) ? TRUE : FALSE)) < 0) {
/* Locking failed - Closing will remove the lock */
if (H5FD_close(lf) < 0)
- HDONE_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info")
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to lock the file")
+ HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "unable to close low-level file info")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTLOCKFILE, NULL, "unable to lock the file")
} /* end if */
/* Create the 'top' file structure */
@@ -1804,9 +1889,14 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
shared = file->shared;
lf = shared->lf;
- /* Get the file access property list, for future queries */
- if (NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
+ /* Set the file locking flag. If the file is already open, the file
+ * requested file locking flag must match that of the open file.
+ */
+ if (shared->nrefs == 1)
+ file->shared->use_file_locking = use_file_locking;
+ else if (shared->nrefs > 1)
+ if (file->shared->use_file_locking != use_file_locking)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file locking flag values don't match")
/* Check if page buffering is enabled */
if (H5P_get(a_plist, H5F_ACS_PAGE_BUFFER_SIZE_NAME, &page_buf_size) < 0)
@@ -1952,7 +2042,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Remove the file lock for SWMR_WRITE */
if (use_file_locking && (H5F_INTENT(file) & H5F_ACC_SWMR_WRITE)) {
if (H5FD_unlock(file->shared->lf) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to unlock the file")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTUNLOCKFILE, NULL, "unable to unlock the file")
} /* end if */
} /* end if */
else { /* H5F_ACC_RDONLY: check consistency of status_flags */
@@ -2070,6 +2160,11 @@ H5F__flush_phase2(H5F_t *f, hbool_t closing)
/* Sanity check arguments */
HDassert(f);
+ /* Inform the metadata cache that we are about to flush */
+ if (H5AC_prep_for_file_flush(f) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "prep for MDC flush failed")
+
/* Flush the entire metadata cache */
if (H5AC_flush(f) < 0)
/* Push error, but keep going*/
@@ -2102,6 +2197,11 @@ H5F__flush_phase2(H5F_t *f, hbool_t closing)
H5CX_set_mpi_file_flushing(FALSE);
#endif /* H5_HAVE_PARALLEL */
+ /* Inform the metadata cache that we are done with the flush */
+ if (H5AC_secure_from_file_flush(f) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "secure from MDC flush failed")
+
/* Flush out the metadata accumulator */
if (H5F__accum_flush(f->shared) < 0)
/* Push error, but keep going*/