diff options
Diffstat (limited to 'src/H5Oflush.c')
-rw-r--r-- | src/H5Oflush.c | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/src/H5Oflush.c b/src/H5Oflush.c index 0bec096..6484dfd 100644 --- a/src/H5Oflush.c +++ b/src/H5Oflush.c @@ -54,6 +54,53 @@ static herr_t H5O_oh_tag(const H5O_loc_t *oloc, hid_t dxpl_id, haddr_t *tag); /*------------------------------------------------------------------------- + * Function: H5Oflush + * + * Purpose: Flushes all buffers associated with an object to disk. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Mike McGreevy + * May 19, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oflush(hid_t obj_id) +{ + H5O_loc_t *oloc; /* object location */ + void *obj_ptr; /* Pointer to object */ + const H5O_obj_class_t *obj_class = NULL; /* Class of object */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", obj_id); + + /* Check args */ + if(NULL == (oloc = H5O_get_loc(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an object") + + /* Get the object pointer */ + if(NULL == (obj_ptr = H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Get the object class */ + if(NULL == (obj_class = H5O_obj_class(oloc, H5AC_ind_read_dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object class") + + /* Flush the object of this class */ + if(obj_class->flush && obj_class->flush(obj_ptr, H5AC_ind_read_dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object") + + /* Flush the object metadata and invoke flush callback */ + if(H5O_flush_common(oloc, obj_id, H5AC_ind_read_dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object and object flush callback") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Oflush() */ + +/*------------------------------------------------------------------------- * Function: H5O_flush_common * * Purpose: Flushes the object's metadata @@ -130,3 +177,211 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_oh_tag() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refresh_metadata + * + * Purpose: Refreshes all buffers associated with an object. + * + * Note: This is based on the original H5O_refresh_metadata() but + * is split into 2 routines. + * This is done so that H5Fstart_swmr_write() can use these + * 2 routines to refresh opened objects. This may be + * restored back to the original code when H5Fstart_swmr_write() + * uses a different approach to handle issues with opened objects. + * H5Fstart_swmr_write() no longer calls the 1st routine. (12/24/15) + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Mike McGreevy/Vailin Choi + * July 28, 2010/Feb 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_refresh_metadata(hid_t oid, H5O_loc_t oloc, hid_t dxpl_id) +{ + hbool_t objs_incr = FALSE; /* Whether the object count in the file was incremented */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* If the file is opened with write access, no need to perform refresh actions. */ + if(!(H5F_INTENT(oloc.file) & H5F_ACC_RDWR)) { + H5G_loc_t obj_loc; + H5O_loc_t obj_oloc; + H5G_name_t obj_path; + + /* Create empty object location */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* "Fake" another open object in the file, so that it doesn't get closed + * if this object is the only thing holding the file open. + */ + H5F_incr_nopen_objs(oloc.file); + objs_incr = TRUE; + + /* Close object & evict its metadata */ + if((H5O_refresh_metadata_close(oid, oloc, &obj_loc, dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") + + /* Re-open the object, re-fetching its metadata */ + if((H5O_refresh_metadata_reopen(oid, &obj_loc, dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to refresh object") + } /* end if */ + +done: + if(objs_incr) + H5F_decr_nopen_objs(oloc.file); + + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_refresh_metadata() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refresh_metadata_close + * + * Purpose: This is the first part of the original routine H5O_refresh_metadata(). + * (1) Save object location information. + * (2) Handle multiple dataset opens + * (3) Get object cork status + * (4) Close the object + * (5) Flush and evict object metadata + * (6) Re-cork the object if needed + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Mike McGreevy/Vailin Choi + * July 28, 2010/Feb 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_refresh_metadata_close(hid_t oid, H5O_loc_t oloc, H5G_loc_t *obj_loc, hid_t dxpl_id) +{ + haddr_t tag = 0; /* Tag for object */ + hbool_t corked = FALSE; /* Whether object's metadata is corked */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Make deep local copy of object's location information */ + if(obj_loc) { + H5G_loc_t tmp_loc; + + H5G_loc(oid, &tmp_loc); + H5G_loc_copy(obj_loc, &tmp_loc, H5_COPY_DEEP); + } /* end if */ + + /* Get object's type */ + if(H5I_get_type(oid) == H5I_DATASET) + if(H5D_mult_refresh_close(oid, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to prepare refresh for dataset") + + /* Retrieve tag for object */ + if(H5O_oh_tag(&oloc, dxpl_id, &tag) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to get object header address") + + /* Get cork status of the object with tag */ + if(H5AC_cork(oloc.file, tag, H5AC__GET_CORKED, &corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_SYSTEM, FAIL, "unable to retrieve an object's cork status") + + /* Close the object */ + if(H5I_dec_ref(oid) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to close object") + + /* Flush metadata based on tag value of the object */ + if(H5F_flush_tagged_metadata(oloc.file, tag, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata") + + /* Evict the object's tagged metadata */ + if(H5F_evict_tagged_metadata(oloc.file, tag, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to evict metadata") + + /* Re-cork object with tag */ + if(corked) + if(H5AC_cork(oloc.file, tag, H5AC__SET_CORK, &corked) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_SYSTEM, FAIL, "unable to cork the object") + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_refresh_metadata_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_refresh_metadata_reopen + * + * Purpose: This is the second part of the original routine H5O_refresh_metadata(). + * (1) Re-open object with the saved object location information. + * (2) Re-register object ID with the re-opened object. + * + * Return: SUCCEED/FAIL + * + * Programmer: Mike McGreevy/Vailin Choi + * July 28, 2010/Feb 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_refresh_metadata_reopen(hid_t oid, H5G_loc_t *obj_loc, hid_t dxpl_id) +{ + void *object = NULL; /* Dataset for this operation */ + H5I_type_t type; /* Type of object for the ID */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Get object's type */ + type = H5I_get_type(oid); + + switch(type) { + case(H5I_GROUP): + /* Re-open the group */ + if(NULL == (object = H5G_open(obj_loc, dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + break; + + case(H5I_DATATYPE): + /* Re-open the named datatype */ + if(NULL == (object = H5T_open(obj_loc, dxpl_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype") + break; + + case(H5I_DATASET): + /* Re-open the dataset */ + if(NULL == (object = H5D_open(obj_loc, H5P_DATASET_ACCESS_DEFAULT, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + if(H5D_mult_refresh_reopen((H5D_t *)object, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to finish refresh for dataset") + break; + + case(H5I_UNINIT): + case(H5I_BADID): + case(H5I_FILE): + case(H5I_DATASPACE): + case(H5I_ATTR): + case(H5I_REFERENCE): + case(H5I_VFL): + case(H5I_GENPROP_CLS): + case(H5I_GENPROP_LST): + case(H5I_ERROR_CLASS): + case(H5I_ERROR_MSG): + case(H5I_ERROR_STACK): + case(H5I_NTYPES): + default: + HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)") + break; + } /* end switch */ + + /* Re-register ID for the object */ + if((H5I_register_with_id(type, object, TRUE, oid)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to re-register object atom") + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_refresh_metadata_reopen() */ + |