summaryrefslogtreecommitdiffstats
path: root/src/H5Fint.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2017-01-05 05:36:14 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2017-01-05 05:36:14 (GMT)
commitafd7e5b476d65960d0e309f35fa2df3235731564 (patch)
treef92049d856d85402a334c00df4c98b12accf7a41 /src/H5Fint.c
parent6232dd6d62e5a58a6185b9502b6d8719cf0ce676 (diff)
downloadhdf5-afd7e5b476d65960d0e309f35fa2df3235731564.zip
hdf5-afd7e5b476d65960d0e309f35fa2df3235731564.tar.gz
hdf5-afd7e5b476d65960d0e309f35fa2df3235731564.tar.bz2
Bring file shutdown code from cache image branch
Diffstat (limited to 'src/H5Fint.c')
-rw-r--r--src/H5Fint.c180
1 files changed, 158 insertions, 22 deletions
diff --git a/src/H5Fint.c b/src/H5Fint.c
index f1e9fb5..8ad97a8 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -76,6 +76,8 @@ typedef struct H5F_olist_t {
static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key);
static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl,
const char *name, char ** /*out*/ actual_name);/* Declare a free list to manage the H5F_t struct */
+static herr_t H5F__flush_phase1(H5F_t *f, hid_t dxpl_id);
+static herr_t H5F__flush_phase2(H5F_t *f, hid_t dxpl_id, hbool_t closing);
/*********************/
@@ -820,15 +822,40 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush)
int actype; /* metadata cache type (enum value) */
H5F_io_info_t fio_info; /* I/O info for operation */
- /* Flush at this point since the file will be closed.
+ /* Flush at this point since the file will be closed (phase 1).
* Only try to flush the file if it was opened with write access, and if
* the caller requested a flush.
*/
if((H5F_ACC_RDWR & H5F_INTENT(f)) && flush)
- if(H5F_flush(f, dxpl_id, TRUE) < 0)
+ if(H5F__flush_phase1(f, dxpl_id) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
+ /* Notify the metadata cache that the file is about to be closed.
+ * This allows the cache to set up for creating a metadata cache
+ * image if this has been requested.
+ */
+ if(H5AC_prep_for_file_close(f, dxpl_id) < 0)
+ /* Push error, but keep going */
+ HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "metadata cache prep for close failed")
+
+ /* Flush at this point since the file will be closed (phase 2).
+ * Only try to flush the file if it was opened with write access, and if
+ * the caller requested a flush.
+ */
+ if((H5F_ACC_RDWR & H5F_INTENT(f)) && flush)
+ if(H5F__flush_phase2(f, dxpl_id, TRUE) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
+
+ /* With the shutdown modifications, the contents of the metadata cache
+ * should be clean at this point, with the possible exception of the
+ * the superblock and superblock extension.
+ *
+ * Verify this.
+ */
+ HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
+
/* Release the external file cache */
if(f->shared->efc) {
if(H5F_efc_destroy(f->shared->efc) < 0)
@@ -837,36 +864,72 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush)
f->shared->efc = NULL;
} /* end if */
+ /* With the shutdown modifications, the contents of the metadata cache
+ * should be clean at this point, with the possible exception of the
+ * the superblock and superblock extension.
+ *
+ * Verify this.
+ */
+ HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
+
/* Release objects that depend on the superblock being initialized */
if(f->shared->sblock) {
/* Shutdown file free space manager(s) */
- /* (We should release the free space information now (before truncating
- * the file and before the metadata cache is shut down) since the
- * free space manager is holding some data structures in memory
- * and also because releasing free space can shrink the file's
- * 'eoa' value)
+ /* (We should release the free space information now (before
+ * truncating the file and before the metadata cache is shut
+ * down) since the free space manager is holding some data
+ * structures in memory and also because releasing free space
+ * can shrink the file's 'eoa' value)
+ *
+ * Update 11/1/16:
+ *
+ * With recent library shutdown modifications, the free space
+ * managers should be settled and written to file at this point
+ * (assuming they are persistent). In this case, closing the
+ * free space managers should have no effect on EOA.
+ *
+ * -- JRM
*/
if(H5F_ACC_RDWR & H5F_INTENT(f)) {
if(H5MF_close(f, dxpl_id) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info")
- /* Flush the file again (if requested), as shutting down the
- * free space manager may dirty some data structures again.
+ /* at this point, only the superblock and superblock
+ * extension should be dirty.
*/
+ HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
+
if(flush) {
/* Clear status_flags */
f->shared->sblock->status_flags &= (uint8_t)(~H5F_SUPER_WRITE_ACCESS);
f->shared->sblock->status_flags &= (uint8_t)(~H5F_SUPER_SWMR_WRITE_ACCESS);
- /* Mark superblock dirty in cache, so change will get encoded */
- if(H5F_super_dirty(f) < 0)
+ /* Mark EOA info dirty in cache, so change will get encoded */
+ if(H5F_eoa_dirty(f, dxpl_id) < 0)
/* Push error, but keep going*/
HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
- if(H5F_flush(f, dxpl_id, TRUE) < 0)
+ /* Release any space allocated to space aggregators,
+ * so that the eoa value corresponds to the end of the
+ * space written to in the file.
+ *
+ * At most, this should change the superblock or the
+ * superblock extension messages.
+ */
+ if(H5MF_free_aggrs(f, dxpl_id) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space")
+
+ /* Truncate the file to the current allocated size */
+ if(H5FD_truncate(f->shared->lf, dxpl_id, TRUE) < 0)
/* Push error, but keep going*/
- HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
+ HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed")
+
+ /* at this point, only the superblock and superblock
+ * extension should be dirty.
+ */
+ HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
} /* end if */
} /* end if */
@@ -884,6 +947,13 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush)
HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock")
f->shared->sblock = NULL;
} /* end if */
+
+ /* with the possible exception of the superblock and superblock
+ * extension, the metadata cache should be clean at this point.
+ *
+ * Verify this.
+ */
+ HDassert(H5AC_cache_is_clean(f, H5AC_RING_MDFSM));
/* Remove shared file struct from list of open files */
if(H5F_sfile_remove(f->shared) < 0)
@@ -1358,25 +1428,24 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_flush
+ * Function: H5F_flush_phase1
*
- * Purpose: Flushes cached data.
+ * Purpose: First phase of flushing cached data.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 29 1997
+ * Programmer: Quincey Koziol
+ * koziol@lbl.gov
+ * Jan 1 2017
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing)
+static herr_t
+H5F__flush_phase1(H5F_t *f, hid_t dxpl_id)
{
- H5F_io_info_t fio_info; /* I/O info for operation */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Sanity check arguments */
HDassert(f);
@@ -1396,6 +1465,34 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing)
/* Push error, but keep going*/
HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__flush_phase1() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F__flush_phase2
+ *
+ * Purpose: Second phase of flushing cached data.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@lbl.gov
+ * Jan 1 2017
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5F__flush_phase2(H5F_t *f, hid_t dxpl_id, hbool_t closing)
+{
+ H5F_io_info_t fio_info; /* I/O info for operation */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check arguments */
+ HDassert(f);
+
/* Flush the entire metadata cache */
if(H5AC_flush(f, dxpl_id) < 0)
/* Push error, but keep going*/
@@ -1403,6 +1500,7 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing)
/* Truncate the file to the current allocated size */
if(H5FD_truncate(f->shared->lf, dxpl_id, closing) < 0)
+ /* Push error, but keep going*/
HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed")
/* Flush the entire metadata cache again since the EOA could have changed in the truncate call. */
@@ -1413,6 +1511,7 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing)
/* Set up I/O info for operation */
fio_info.f = f;
if(NULL == (fio_info.dxpl = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ /* Push error, but keep going*/
HDONE_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
/* Flush out the metadata accumulator */
@@ -1425,6 +1524,43 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing)
/* Push error, but keep going*/
HDONE_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed")
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5F__flush_phase2() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_flush
+ *
+ * Purpose: Flushes cached data.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 29 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check arguments */
+ HDassert(f);
+
+ /* First phase of flushing data */
+ if(H5F__flush_phase1(f, dxpl_id) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush file data")
+
+ /* Second phase of flushing data */
+ if(H5F__flush_phase2(f, dxpl_id, closing) < 0)
+ /* Push error, but keep going*/
+ HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush file data")
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_flush() */