mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-12-27 08:01:04 +08:00
Created internal functions for a couple of H5F calls.
This commit is contained in:
parent
73acad2919
commit
b8f56d22df
262
src/H5F.c
262
src/H5F.c
@ -1260,82 +1260,23 @@ done:
|
||||
herr_t
|
||||
H5Fget_metadata_read_retry_info(hid_t file_id, H5F_retry_info_t *info)
|
||||
{
|
||||
H5F_t *file; /* File object for file ID */
|
||||
unsigned i, j; /* Local index variable */
|
||||
size_t tot_size; /* Size of each retries[i] */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5F_t *file; /* File object for file ID */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE2("e", "i*x", file_id, info);
|
||||
|
||||
/* Check args */
|
||||
if(!info)
|
||||
if (!info)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
|
||||
|
||||
/* Get the file pointer */
|
||||
if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
|
||||
if (NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
|
||||
|
||||
/* Copy the # of bins for "retries" array */
|
||||
info->nbins = file->shared->retries_nbins;
|
||||
|
||||
/* Initialize the array of "retries" */
|
||||
HDmemset(info->retries, 0, sizeof(info->retries));
|
||||
|
||||
/* Return if there are no bins -- no retries */
|
||||
if(!info->nbins)
|
||||
HGOTO_DONE(SUCCEED);
|
||||
|
||||
/* Calculate size for each retries[i] */
|
||||
tot_size = info->nbins * sizeof(uint32_t);
|
||||
|
||||
/* Map and copy information to info's retries for metadata items with tracking for read retries */
|
||||
j = 0;
|
||||
for(i = 0; i < H5AC_NTYPES; i++) {
|
||||
switch(i) {
|
||||
case H5AC_OHDR_ID:
|
||||
case H5AC_OHDR_CHK_ID:
|
||||
case H5AC_BT2_HDR_ID:
|
||||
case H5AC_BT2_INT_ID:
|
||||
case H5AC_BT2_LEAF_ID:
|
||||
case H5AC_FHEAP_HDR_ID:
|
||||
case H5AC_FHEAP_DBLOCK_ID:
|
||||
case H5AC_FHEAP_IBLOCK_ID:
|
||||
case H5AC_FSPACE_HDR_ID:
|
||||
case H5AC_FSPACE_SINFO_ID:
|
||||
case H5AC_SOHM_TABLE_ID:
|
||||
case H5AC_SOHM_LIST_ID:
|
||||
case H5AC_EARRAY_HDR_ID:
|
||||
case H5AC_EARRAY_IBLOCK_ID:
|
||||
case H5AC_EARRAY_SBLOCK_ID:
|
||||
case H5AC_EARRAY_DBLOCK_ID:
|
||||
case H5AC_EARRAY_DBLK_PAGE_ID:
|
||||
case H5AC_FARRAY_HDR_ID:
|
||||
case H5AC_FARRAY_DBLOCK_ID:
|
||||
case H5AC_FARRAY_DBLK_PAGE_ID:
|
||||
case H5AC_SUPERBLOCK_ID:
|
||||
HDassert(j < H5F_NUM_METADATA_READ_RETRY_TYPES);
|
||||
if(file->shared->retries[i] != NULL) {
|
||||
/* Allocate memory for retries[i]
|
||||
*
|
||||
* This memory should be released by the user with
|
||||
* the H5free_memory() call.
|
||||
*/
|
||||
if(NULL == (info->retries[j] = (uint32_t *)H5MM_malloc(tot_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
||||
|
||||
/* Copy the information */
|
||||
HDmemcpy(info->retries[j], file->shared->retries[i], tot_size);
|
||||
} /* end if */
|
||||
|
||||
/* Increment location in info->retries[] array */
|
||||
j++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
} /* end switch */
|
||||
} /* end for */
|
||||
/* Get the retry info */
|
||||
if (H5F_get_metadata_read_retry_info(file, info) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't get metadata read retry info")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
@ -1446,196 +1387,21 @@ done:
|
||||
herr_t
|
||||
H5Fstart_swmr_write(hid_t file_id)
|
||||
{
|
||||
hbool_t ci_load = FALSE; /* whether MDC ci load requested */
|
||||
hbool_t ci_write = FALSE; /* whether MDC CI write requested */
|
||||
H5F_t *file = NULL; /* File info */
|
||||
size_t grp_dset_count=0; /* # of open objects: groups & datasets */
|
||||
size_t nt_attr_count=0; /* # of opened named datatypes + opened attributes */
|
||||
hid_t *obj_ids=NULL; /* List of ids */
|
||||
H5G_loc_t *obj_glocs=NULL; /* Group location of the object */
|
||||
H5O_loc_t *obj_olocs=NULL; /* Object location */
|
||||
H5G_name_t *obj_paths=NULL; /* Group hierarchy path */
|
||||
size_t u; /* Local index variable */
|
||||
hbool_t setup = FALSE; /* Boolean flag to indicate whether SWMR setting is enabled */
|
||||
H5F_io_info2_t fio_info; /* I/O info for operation */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
H5F_t *file = NULL; /* File info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_API(FAIL)
|
||||
H5TRACE1("e", "i", file_id);
|
||||
|
||||
/* check args */
|
||||
if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
|
||||
if (NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hid_t identifier is not a file ID")
|
||||
|
||||
/* Should have write permission */
|
||||
if((H5F_INTENT(file) & H5F_ACC_RDWR) == 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "no write intent on file")
|
||||
|
||||
if(file->shared->sblock->super_vers < HDF5_SUPERBLOCK_VERSION_3)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file superblock version should be at least 3")
|
||||
|
||||
HDassert((file->shared->low_bound == H5F_LIBVER_V110) && (file->shared->high_bound == H5F_LIBVER_V110));
|
||||
|
||||
/* Should not be marked for SWMR writing mode already */
|
||||
if(file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file already in SWMR writing mode")
|
||||
|
||||
HDassert(file->shared->sblock->status_flags & H5F_SUPER_WRITE_ACCESS);
|
||||
|
||||
/* Check to see if cache image is enabled. Fail if so */
|
||||
if(H5C_cache_image_status(file, &ci_load, &ci_write) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MDC cache image status")
|
||||
if(ci_load || ci_write )
|
||||
HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL, "can't have both SWMR and MDC cache image")
|
||||
|
||||
/* Flush the superblock extension */
|
||||
if(H5F_flush_tagged_metadata(file, file->shared->sblock->ext_addr, H5AC_ind_read_dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock extension")
|
||||
|
||||
/* Flush data buffers */
|
||||
if(H5F__flush(file, H5AC_ind_read_dxpl_id, H5AC_rawdata_dxpl_id, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information")
|
||||
|
||||
/* Get the # of opened named datatypes and attributes */
|
||||
if(H5F_get_obj_count(file, H5F_OBJ_DATATYPE|H5F_OBJ_ATTR, FALSE, &nt_attr_count) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
|
||||
if(nt_attr_count)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "named datatypes and/or attributes opened in the file")
|
||||
|
||||
/* Get the # of opened datasets and groups */
|
||||
if(H5F_get_obj_count(file, H5F_OBJ_GROUP|H5F_OBJ_DATASET, FALSE, &grp_dset_count) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
|
||||
|
||||
if(grp_dset_count) {
|
||||
/* Allocate space for group and object locations */
|
||||
if((obj_ids = (hid_t *) H5MM_malloc(grp_dset_count * sizeof(hid_t))) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for hid_t")
|
||||
if((obj_glocs = (H5G_loc_t *) H5MM_malloc(grp_dset_count * sizeof(H5G_loc_t))) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_loc_t")
|
||||
if((obj_olocs = (H5O_loc_t *) H5MM_malloc(grp_dset_count * sizeof(H5O_loc_t))) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5O_loc_t")
|
||||
if((obj_paths = (H5G_name_t *) H5MM_malloc(grp_dset_count * sizeof(H5G_name_t))) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_name_t")
|
||||
|
||||
/* Get the list of opened object ids (groups & datasets) */
|
||||
if(H5F_get_obj_ids(file, H5F_OBJ_GROUP|H5F_OBJ_DATASET, grp_dset_count, obj_ids, FALSE, &grp_dset_count) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "H5F_get_obj_ids failed")
|
||||
|
||||
/* Refresh opened objects (groups, datasets) in the file */
|
||||
for(u = 0; u < grp_dset_count; u++) {
|
||||
H5O_loc_t *oloc; /* object location */
|
||||
H5G_loc_t tmp_loc;
|
||||
|
||||
/* Set up the id's group location */
|
||||
obj_glocs[u].oloc = &obj_olocs[u];
|
||||
obj_glocs[u].path = &obj_paths[u];
|
||||
H5G_loc_reset(&obj_glocs[u]);
|
||||
|
||||
/* get the id's object location */
|
||||
if((oloc = H5O_get_loc(obj_ids[u])) == NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object")
|
||||
|
||||
/* Make deep local copy of object's location information */
|
||||
H5G_loc(obj_ids[u], &tmp_loc);
|
||||
H5G_loc_copy(&obj_glocs[u], &tmp_loc, H5_COPY_DEEP);
|
||||
|
||||
/* Close the object */
|
||||
if(H5I_dec_ref(obj_ids[u]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEOBJ, FAIL, "decrementing object ID failed")
|
||||
} /* end for */
|
||||
} /* end if */
|
||||
|
||||
/* Set up I/O info for operation */
|
||||
fio_info.f = file;
|
||||
if(NULL == (fio_info.meta_dxpl = (H5P_genplist_t *)H5I_object(H5AC_ind_read_dxpl_id)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
|
||||
if(NULL == (fio_info.raw_dxpl = (H5P_genplist_t *)H5I_object(H5AC_rawdata_dxpl_id)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
|
||||
|
||||
/* Flush and reset the accumulator */
|
||||
if(H5F__accum_reset(&fio_info, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTRESET, FAIL, "can't reset accumulator")
|
||||
|
||||
/* Turn on SWMR write in shared file open flags */
|
||||
file->shared->flags |= H5F_ACC_SWMR_WRITE;
|
||||
|
||||
/* Mark the file in SWMR writing mode */
|
||||
file->shared->sblock->status_flags |= H5F_SUPER_SWMR_WRITE_ACCESS;
|
||||
|
||||
/* Set up metadata read attempts */
|
||||
file->shared->read_attempts = H5F_SWMR_METADATA_READ_ATTEMPTS;
|
||||
|
||||
/* Initialize "retries" and "retries_nbins" */
|
||||
if(H5F_set_retries(file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't set retries and retries_nbins")
|
||||
|
||||
/* Turn off usage of accumulator */
|
||||
file->shared->feature_flags &= ~(unsigned)H5FD_FEAT_ACCUMULATE_METADATA;
|
||||
if(H5FD_set_feature_flags(file->shared->lf, file->shared->feature_flags) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set feature_flags in VFD")
|
||||
|
||||
setup = TRUE;
|
||||
|
||||
/* Mark superblock as dirty */
|
||||
if(H5F_super_dirty(file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
|
||||
|
||||
/* Flush the superblock */
|
||||
if(H5F_flush_tagged_metadata(file, H5AC__SUPERBLOCK_TAG, H5AC_ind_read_dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock")
|
||||
|
||||
/* Evict all flushed entries in the cache except the pinned superblock */
|
||||
if(H5F__evict_cache_entries(file, H5AC_ind_read_dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to evict file's cached information")
|
||||
|
||||
/* Refresh (reopen) the objects (groups & datasets) in the file */
|
||||
for(u = 0; u < grp_dset_count; u++)
|
||||
if(H5O_refresh_metadata_reopen(obj_ids[u], &obj_glocs[u], H5AC_ind_read_dxpl_id, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't refresh-close object")
|
||||
|
||||
/* Unlock the file */
|
||||
if(H5FD_unlock(file->shared->lf) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to unlock the file")
|
||||
/* start SWMR writing */
|
||||
if (H5F_start_swmr_write(file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_SYSTEM, FAIL, "unable to start SWMR writing")
|
||||
|
||||
done:
|
||||
if(ret_value < 0 && setup) {
|
||||
HDassert(file);
|
||||
|
||||
/* Re-enable accumulator */
|
||||
file->shared->feature_flags |= (unsigned)H5FD_FEAT_ACCUMULATE_METADATA;
|
||||
if(H5FD_set_feature_flags(file->shared->lf, file->shared->feature_flags) < 0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set feature_flags in VFD")
|
||||
|
||||
/* Reset the # of read attempts */
|
||||
file->shared->read_attempts = H5F_METADATA_READ_ATTEMPTS;
|
||||
if(H5F_set_retries(file) < 0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't set retries and retries_nbins")
|
||||
|
||||
/* Un-set H5F_ACC_SWMR_WRITE in shared open flags */
|
||||
file->shared->flags &= ~H5F_ACC_SWMR_WRITE;
|
||||
|
||||
/* Unmark the file: not in SWMR writing mode */
|
||||
file->shared->sblock->status_flags &= (uint8_t)(~H5F_SUPER_SWMR_WRITE_ACCESS);
|
||||
|
||||
/* Mark superblock as dirty */
|
||||
if(H5F_super_dirty(file) < 0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
|
||||
|
||||
/* Flush the superblock */
|
||||
if(H5F_flush_tagged_metadata(file, H5AC__SUPERBLOCK_TAG, H5AC_ind_read_dxpl_id) < 0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock")
|
||||
} /* end if */
|
||||
|
||||
/* Free memory */
|
||||
if(obj_ids)
|
||||
H5MM_xfree(obj_ids);
|
||||
if(obj_glocs)
|
||||
H5MM_xfree(obj_glocs);
|
||||
if(obj_olocs)
|
||||
H5MM_xfree(obj_olocs);
|
||||
if(obj_paths)
|
||||
H5MM_xfree(obj_paths);
|
||||
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Fstart_swmr_write() */
|
||||
|
||||
|
318
src/H5Fint.c
318
src/H5Fint.c
@ -2981,3 +2981,321 @@ H5F_set_coll_md_read(H5F_t *f, H5P_coll_md_read_flag_t cmr)
|
||||
FUNC_LEAVE_NOAPI_VOID
|
||||
} /* H5F_set_coll_md_read() */
|
||||
#endif /* H5_HAVE_PARALLEL */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_get_metadata_read_retry_info
|
||||
*
|
||||
* Purpose: Private function to retrieve the collection of read retries
|
||||
* for metadata items with checksum.
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_get_metadata_read_retry_info(H5F_t *file, H5F_retry_info_t *info)
|
||||
{
|
||||
unsigned i, j; /* Local index variable */
|
||||
size_t tot_size; /* Size of each retries[i] */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* Check args */
|
||||
HDassert(file);
|
||||
HDassert(info);
|
||||
|
||||
/* Copy the # of bins for "retries" array */
|
||||
info->nbins = file->shared->retries_nbins;
|
||||
|
||||
/* Initialize the array of "retries" */
|
||||
HDmemset(info->retries, 0, sizeof(info->retries));
|
||||
|
||||
/* Return if there are no bins -- no retries */
|
||||
if (!info->nbins)
|
||||
HGOTO_DONE(SUCCEED);
|
||||
|
||||
/* Calculate size for each retries[i] */
|
||||
tot_size = info->nbins * sizeof(uint32_t);
|
||||
|
||||
/* Map and copy information to info's retries for metadata items with tracking for read retries */
|
||||
j = 0;
|
||||
for (i = 0; i < H5AC_NTYPES; i++) {
|
||||
switch (i) {
|
||||
case H5AC_OHDR_ID:
|
||||
case H5AC_OHDR_CHK_ID:
|
||||
case H5AC_BT2_HDR_ID:
|
||||
case H5AC_BT2_INT_ID:
|
||||
case H5AC_BT2_LEAF_ID:
|
||||
case H5AC_FHEAP_HDR_ID:
|
||||
case H5AC_FHEAP_DBLOCK_ID:
|
||||
case H5AC_FHEAP_IBLOCK_ID:
|
||||
case H5AC_FSPACE_HDR_ID:
|
||||
case H5AC_FSPACE_SINFO_ID:
|
||||
case H5AC_SOHM_TABLE_ID:
|
||||
case H5AC_SOHM_LIST_ID:
|
||||
case H5AC_EARRAY_HDR_ID:
|
||||
case H5AC_EARRAY_IBLOCK_ID:
|
||||
case H5AC_EARRAY_SBLOCK_ID:
|
||||
case H5AC_EARRAY_DBLOCK_ID:
|
||||
case H5AC_EARRAY_DBLK_PAGE_ID:
|
||||
case H5AC_FARRAY_HDR_ID:
|
||||
case H5AC_FARRAY_DBLOCK_ID:
|
||||
case H5AC_FARRAY_DBLK_PAGE_ID:
|
||||
case H5AC_SUPERBLOCK_ID:
|
||||
HDassert(j < H5F_NUM_METADATA_READ_RETRY_TYPES);
|
||||
if (file->shared->retries[i] != NULL) {
|
||||
/* Allocate memory for retries[i]
|
||||
*
|
||||
* This memory should be released by the user with
|
||||
* the H5free_memory() call.
|
||||
*/
|
||||
if (NULL == (info->retries[j] = (uint32_t *)H5MM_malloc(tot_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
||||
|
||||
/* Copy the information */
|
||||
HDmemcpy(info->retries[j], file->shared->retries[i], tot_size);
|
||||
}
|
||||
|
||||
/* Increment location in info->retries[] array */
|
||||
j++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_get_metadata_read_retry_info() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_start_swmr_write
|
||||
*
|
||||
* Purpose: To enable SWMR writing mode for the file
|
||||
*
|
||||
* 1) Refresh opened objects: part 1
|
||||
* 2) Flush & reset accumulator
|
||||
* 3) Mark the file in SWMR writing mode
|
||||
* 4) Set metadata read attempts and retries info
|
||||
* 5) Disable accumulator
|
||||
* 6) Evict all cache entries except the superblock
|
||||
* 7) Refresh opened objects (part 2)
|
||||
* 8) Unlock the file
|
||||
*
|
||||
* Pre-conditions:
|
||||
*
|
||||
* 1) The file being opened has v3 superblock
|
||||
* 2) The file is opened with H5F_ACC_RDWR
|
||||
* 3) The file is not already marked for SWMR writing
|
||||
* 4) Current implementaion for opened objects:
|
||||
* --only allow datasets and groups without attributes
|
||||
* --disallow named datatype with/without attributes
|
||||
* --disallow opened attributes attached to objects
|
||||
*
|
||||
* NOTE: Currently, only opened groups and datasets are allowed
|
||||
* when enabling SWMR via H5Fstart_swmr_write().
|
||||
* Will later implement a different approach--
|
||||
* set up flush dependency/proxy even for file opened without
|
||||
* SWMR to resolve issues with opened objects.
|
||||
*
|
||||
* Return: SUCCEED/FAIL
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_start_swmr_write(H5F_t *file)
|
||||
{
|
||||
hbool_t ci_load = FALSE; /* whether MDC ci load requested */
|
||||
hbool_t ci_write = FALSE; /* whether MDC CI write requested */
|
||||
size_t grp_dset_count=0; /* # of open objects: groups & datasets */
|
||||
size_t nt_attr_count=0; /* # of opened named datatypes + opened attributes */
|
||||
hid_t *obj_ids = NULL; /* List of ids */
|
||||
H5G_loc_t *obj_glocs = NULL; /* Group location of the object */
|
||||
H5O_loc_t *obj_olocs = NULL; /* Object location */
|
||||
H5G_name_t *obj_paths = NULL; /* Group hierarchy path */
|
||||
size_t u; /* Local index variable */
|
||||
hbool_t setup = FALSE; /* Boolean flag to indicate whether SWMR setting is enabled */
|
||||
H5F_io_info2_t fio_info; /* I/O info for operation */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(FAIL)
|
||||
|
||||
/* check args */
|
||||
HDassert(file);
|
||||
|
||||
/* Should have write permission */
|
||||
if ((H5F_INTENT(file) & H5F_ACC_RDWR) == 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "no write intent on file")
|
||||
|
||||
/* Check superblock version */
|
||||
if (file->shared->sblock->super_vers < HDF5_SUPERBLOCK_VERSION_3)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file superblock version - should be at least 3")
|
||||
|
||||
/* Check for correct file format version */
|
||||
if ((file->shared->low_bound != H5F_LIBVER_V110) || (file->shared->high_bound != H5F_LIBVER_V110))
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file format version does not support SWMR - needs to be 1.10 or greater")
|
||||
|
||||
/* Should not be marked for SWMR writing mode already */
|
||||
if (file->shared->sblock->status_flags & H5F_SUPER_SWMR_WRITE_ACCESS)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file already in SWMR writing mode")
|
||||
|
||||
/* Check to see if cache image is enabled. Fail if so */
|
||||
if (H5C_cache_image_status(file, &ci_load, &ci_write) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MDC cache image status")
|
||||
if (ci_load || ci_write )
|
||||
HGOTO_ERROR(H5E_FILE, H5E_UNSUPPORTED, FAIL, "can't have both SWMR and MDC cache image")
|
||||
|
||||
/* Flush the superblock extension */
|
||||
if (H5F_flush_tagged_metadata(file, file->shared->sblock->ext_addr, H5AC_ind_read_dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock extension")
|
||||
|
||||
/* Flush data buffers */
|
||||
if (H5F__flush(file, H5AC_ind_read_dxpl_id, H5AC_rawdata_dxpl_id, FALSE) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information")
|
||||
|
||||
/* Get the # of opened named datatypes and attributes */
|
||||
if (H5F_get_obj_count(file, H5F_OBJ_DATATYPE|H5F_OBJ_ATTR, FALSE, &nt_attr_count) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
|
||||
if (nt_attr_count)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "named datatypes and/or attributes opened in the file")
|
||||
|
||||
/* Get the # of opened datasets and groups */
|
||||
if (H5F_get_obj_count(file, H5F_OBJ_GROUP|H5F_OBJ_DATASET, FALSE, &grp_dset_count) < 0)
|
||||
HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed")
|
||||
|
||||
if (grp_dset_count) {
|
||||
/* Allocate space for group and object locations */
|
||||
if ((obj_ids = (hid_t *) H5MM_malloc(grp_dset_count * sizeof(hid_t))) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for hid_t")
|
||||
if ((obj_glocs = (H5G_loc_t *) H5MM_malloc(grp_dset_count * sizeof(H5G_loc_t))) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_loc_t")
|
||||
if ((obj_olocs = (H5O_loc_t *) H5MM_malloc(grp_dset_count * sizeof(H5O_loc_t))) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5O_loc_t")
|
||||
if ((obj_paths = (H5G_name_t *) H5MM_malloc(grp_dset_count * sizeof(H5G_name_t))) == NULL)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, FAIL, "can't allocate buffer for H5G_name_t")
|
||||
|
||||
/* Get the list of opened object ids (groups & datasets) */
|
||||
if (H5F_get_obj_ids(file, H5F_OBJ_GROUP|H5F_OBJ_DATASET, grp_dset_count, obj_ids, FALSE, &grp_dset_count) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "H5F_get_obj_ids failed")
|
||||
|
||||
/* Refresh opened objects (groups, datasets) in the file */
|
||||
for (u = 0; u < grp_dset_count; u++) {
|
||||
H5O_loc_t *oloc; /* object location */
|
||||
H5G_loc_t tmp_loc;
|
||||
|
||||
/* Set up the id's group location */
|
||||
obj_glocs[u].oloc = &obj_olocs[u];
|
||||
obj_glocs[u].path = &obj_paths[u];
|
||||
H5G_loc_reset(&obj_glocs[u]);
|
||||
|
||||
/* get the id's object location */
|
||||
if ((oloc = H5O_get_loc(obj_ids[u])) == NULL)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object")
|
||||
|
||||
/* Make deep local copy of object's location information */
|
||||
H5G_loc(obj_ids[u], &tmp_loc);
|
||||
H5G_loc_copy(&obj_glocs[u], &tmp_loc, H5_COPY_DEEP);
|
||||
|
||||
/* Close the object */
|
||||
if (H5I_dec_ref(obj_ids[u]) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEOBJ, FAIL, "decrementing object ID failed")
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up I/O info for operation */
|
||||
fio_info.f = file;
|
||||
if (NULL == (fio_info.meta_dxpl = (H5P_genplist_t *)H5I_object(H5AC_ind_read_dxpl_id)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
|
||||
if (NULL == (fio_info.raw_dxpl = (H5P_genplist_t *)H5I_object(H5AC_rawdata_dxpl_id)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
|
||||
|
||||
/* Flush and reset the accumulator */
|
||||
if (H5F__accum_reset(&fio_info, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_IO, H5E_CANTRESET, FAIL, "can't reset accumulator")
|
||||
|
||||
/* Turn on SWMR write in shared file open flags */
|
||||
file->shared->flags |= H5F_ACC_SWMR_WRITE;
|
||||
|
||||
/* Mark the file in SWMR writing mode */
|
||||
file->shared->sblock->status_flags |= H5F_SUPER_SWMR_WRITE_ACCESS;
|
||||
|
||||
/* Set up metadata read attempts */
|
||||
file->shared->read_attempts = H5F_SWMR_METADATA_READ_ATTEMPTS;
|
||||
|
||||
/* Initialize "retries" and "retries_nbins" */
|
||||
if (H5F_set_retries(file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't set retries and retries_nbins")
|
||||
|
||||
/* Turn off usage of accumulator */
|
||||
file->shared->feature_flags &= ~(unsigned)H5FD_FEAT_ACCUMULATE_METADATA;
|
||||
if (H5FD_set_feature_flags(file->shared->lf, file->shared->feature_flags) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set feature_flags in VFD")
|
||||
|
||||
setup = TRUE;
|
||||
|
||||
/* Mark superblock as dirty */
|
||||
if (H5F_super_dirty(file) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
|
||||
|
||||
/* Flush the superblock */
|
||||
if (H5F_flush_tagged_metadata(file, H5AC__SUPERBLOCK_TAG, H5AC_ind_read_dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock")
|
||||
|
||||
/* Evict all flushed entries in the cache except the pinned superblock */
|
||||
if (H5F__evict_cache_entries(file, H5AC_ind_read_dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to evict file's cached information")
|
||||
|
||||
/* Refresh (reopen) the objects (groups & datasets) in the file */
|
||||
for (u = 0; u < grp_dset_count; u++)
|
||||
if (H5O_refresh_metadata_reopen(obj_ids[u], &obj_glocs[u], H5AC_ind_read_dxpl_id, TRUE) < 0)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't refresh-close object")
|
||||
|
||||
/* Unlock the file */
|
||||
if (H5FD_unlock(file->shared->lf) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to unlock the file")
|
||||
|
||||
done:
|
||||
if(ret_value < 0 && setup) {
|
||||
|
||||
/* Re-enable accumulator */
|
||||
file->shared->feature_flags |= (unsigned)H5FD_FEAT_ACCUMULATE_METADATA;
|
||||
if (H5FD_set_feature_flags(file->shared->lf, file->shared->feature_flags) < 0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set feature_flags in VFD")
|
||||
|
||||
/* Reset the # of read attempts */
|
||||
file->shared->read_attempts = H5F_METADATA_READ_ATTEMPTS;
|
||||
if (H5F_set_retries(file) < 0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "can't set retries and retries_nbins")
|
||||
|
||||
/* Un-set H5F_ACC_SWMR_WRITE in shared open flags */
|
||||
file->shared->flags &= ~H5F_ACC_SWMR_WRITE;
|
||||
|
||||
/* Unmark the file: not in SWMR writing mode */
|
||||
file->shared->sblock->status_flags &= (uint8_t)(~H5F_SUPER_SWMR_WRITE_ACCESS);
|
||||
|
||||
/* Mark superblock as dirty */
|
||||
if (H5F_super_dirty(file) < 0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTMARKDIRTY, FAIL, "unable to mark superblock as dirty")
|
||||
|
||||
/* Flush the superblock */
|
||||
if (H5F_flush_tagged_metadata(file, H5AC__SUPERBLOCK_TAG, H5AC_ind_read_dxpl_id) < 0)
|
||||
HDONE_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush superblock")
|
||||
}
|
||||
|
||||
/* Free memory */
|
||||
if (obj_ids)
|
||||
H5MM_xfree(obj_ids);
|
||||
if (obj_glocs)
|
||||
H5MM_xfree(obj_glocs);
|
||||
if (obj_olocs)
|
||||
H5MM_xfree(obj_olocs);
|
||||
if (obj_paths)
|
||||
H5MM_xfree(obj_paths);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_start_swmr_write() */
|
||||
|
||||
|
@ -723,6 +723,7 @@ typedef enum H5F_mem_page_t {
|
||||
H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id,
|
||||
hid_t fapl_id, hid_t dxpl_id);
|
||||
H5_DLL herr_t H5F_try_close(H5F_t *f, hbool_t *was_closed/*out*/);
|
||||
H5_DLL herr_t H5F_start_swmr_write(H5F_t *file);
|
||||
|
||||
/* Functions that retrieve values from the file struct */
|
||||
H5_DLL H5F_libver_t H5F_get_low_bound(const H5F_t *f);
|
||||
@ -817,6 +818,7 @@ H5_DLL herr_t H5F_get_checksums(const uint8_t *buf, size_t chk_size, uint32_t *s
|
||||
/* Routine to track the # of retries */
|
||||
H5_DLL herr_t H5F_track_metadata_read_retries(H5F_t *f, unsigned actype, unsigned retries);
|
||||
H5_DLL herr_t H5F_set_retries(H5F_t *f);
|
||||
H5_DLL herr_t H5F_get_metadata_read_retry_info(H5F_t *file, H5F_retry_info_t *info);
|
||||
|
||||
/* Routine to invoke callback function upon object flush */
|
||||
H5_DLL herr_t H5F_object_flush_cb(H5F_t *f, hid_t obj_id);
|
||||
|
Loading…
Reference in New Issue
Block a user