diff options
Diffstat (limited to 'src/H5F.c')
-rw-r--r-- | src/H5F.c | 178 |
1 files changed, 90 insertions, 88 deletions
@@ -77,8 +77,8 @@ typedef struct H5F_olist_t { /********************/ static herr_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr); static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key); -static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, - H5FD_t *lf); +static H5F_t *H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, H5FD_t *lf); 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_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush); @@ -337,7 +337,6 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) /* Make a copy of the default file access property list */ if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_FILE_ACCESS_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - if((ret_value = H5P_copy_plist(old_plist, app_ref)) < 0) HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy file access property list") if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(ret_value))) @@ -366,7 +365,7 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size") if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") - if(H5P_set(new_plist, H5F_ACS_METADATA_READ_ATTEMPTS_NAME, &(f->read_attempts)) < 0) + if(H5P_set(new_plist, H5F_ACS_METADATA_READ_ATTEMPTS_NAME, &(f->shared->read_attempts)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") if(f->shared->efc) efc_size = H5F_efc_max_nfiles(f->shared->efc); @@ -887,7 +886,7 @@ done: *------------------------------------------------------------------------- */ static H5F_t * -H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) +H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) { H5F_t *f = NULL, *ret_value; @@ -910,6 +909,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) if(NULL == (f->shared = H5FL_CALLOC(H5F_file_t))) HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure") + f->shared->flags = flags; f->shared->sohm_addr = HADDR_UNDEF; f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION; for(u = 0; u < NELMTS(f->shared->fs_addr); u++) @@ -942,7 +942,6 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) /* Get the FAPL values to cache */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") - if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config") if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) @@ -961,6 +960,12 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size") if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag") + /* Require the latest format to use SWMR */ + /* (Need to revisit this when the 1.10 release is made, and require + * 1.10 or later -QAK) + */ + if(!H5F_USE_LATEST_FORMAT(f) && (H5F_INTENT(f) & H5F_ACC_SWMR_WRITE)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "must use 'latest format' flag with SWMR write access") if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache size") f->shared->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA; @@ -973,13 +978,16 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) if(NULL == (f->shared->efc = H5F_efc_create(efc_size))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache") - /* Get the VFD values to cache */ f->shared->maxaddr = H5FD_get_maxaddr(lf); if(!H5F_addr_defined(f->shared->maxaddr)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD") if(H5FD_get_feature_flags(lf, &f->shared->feature_flags) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get feature flags from VFD") + /* Require a POSIX compatible VFD to use SWMR feature */ + /* (It's reasonable to try to expand this to other VFDs eventually -QAK) */ + if(!H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE) && (H5F_INTENT(f) & (H5F_ACC_SWMR_WRITE | H5F_ACC_SWMR_READ))) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "must use POSIX compatible VFD with SWMR write access") if(H5FD_get_fs_type_map(lf, f->shared->fs_type_map) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get free space type mapping from VFD") if(H5MF_init_merge_flags(f) < 0) @@ -996,6 +1004,37 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) */ f->shared->use_tmp_space = !H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI); + /* Retrieve the # of read attempts here so that sohm in superblock will get the correct # of attempts */ + if(H5P_get(plist, H5F_ACS_METADATA_READ_ATTEMPTS_NAME, &f->shared->read_attempts) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get the # of read attempts") + + /* When opening file with SWMR access, the # of read attempts is H5F_SWMR_METADATA_READ_ATTEMPTS if not set */ + /* When opening file without SWMR access, the # of read attempts is always H5F_METADATA_READ_ATTEMPTS (set or not set) */ + if(H5F_INTENT(f) & (H5F_ACC_SWMR_READ | H5F_ACC_SWMR_WRITE)) { + /* If no value for read attempts has been set, use the default */ + if(!f->shared->read_attempts) + f->shared->read_attempts = H5F_SWMR_METADATA_READ_ATTEMPTS; + + /* Turn off accumulator with SWMR */ + f->shared->feature_flags = lf->feature_flags & ~(unsigned)H5FD_FEAT_ACCUMULATE_METADATA; + if(H5FD_set_feature_flags(lf, f->shared->feature_flags) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set feature_flags in VFD") + } /* end if */ + else + f->shared->read_attempts = H5F_METADATA_READ_ATTEMPTS; + + /* Determine the # of bins for metdata read retries */ + f->shared->retries_nbins = 0; + if(f->shared->read_attempts > 1) { + double tmp; + + tmp = HDlog10((double)(f->shared->read_attempts - 1)); + f->shared->retries_nbins = (unsigned)tmp + 1; + } /* end if */ + + /* Initialize the tracking for metadata read retries */ + HDmemset(f->shared->retries, 0, sizeof(f->shared->retries)); + /* * Create a metadata cache with the specified number of elements. * The cache might be created with a different number of elements and @@ -1024,8 +1063,17 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) done: if(!ret_value && f) { - if(!shared) + if(!shared) { + /* Attempt to clean up some of the shared file structures */ + if(f->shared->efc) + if(H5F_efc_destroy(f->shared->efc) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, NULL, "can't destroy external file cache") + if(f->shared->fcpl_id > 0) + if(H5I_dec_ref(f->shared->fcpl_id) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, NULL, "can't close property list") + f->shared = H5FL_FREE(H5F_file_t, f->shared); + } /* end if */ f = H5FL_FREE(H5F_t, f); } /* end if */ @@ -1248,7 +1296,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_class_t *drvr; /*file driver class info */ H5P_genplist_t *a_plist; /*file access property list */ H5F_close_degree_t fc_degree; /*file close degree */ - unsigned i; /*local index variable */ H5F_t *ret_value; /*actual return value */ FUNC_ENTER_NOAPI(NULL) @@ -1331,7 +1378,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "SWMR read access flag not the same for file that is already open") /* Allocate new "high-level" file struct */ - if((file = H5F_new(shared, fcpl_id, fapl_id, NULL)) == NULL) + if((file = H5F_new(shared, flags, fcpl_id, fapl_id, NULL)) == NULL) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") } /* end if */ else { @@ -1352,57 +1399,18 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, } /* end if */ } /* end if */ - if(NULL == (file = H5F_new(NULL, fcpl_id, fapl_id, lf))) + if(NULL == (file = H5F_new(NULL, flags, fcpl_id, fapl_id, lf))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") - file->shared->flags = flags; } /* end else */ + /* Retain the name the file was opened with */ + file->open_name = H5MM_xstrdup(name); + /* Short cuts */ shared = file->shared; lf = shared->lf; /* - * The intent at the top level file struct are not necessarily the same as - * the flags at the bottom. The top level describes how the file can be - * accessed through the HDF5 library. The bottom level describes how the - * file can be accessed through the C library. - */ - file->intent = flags; - file->open_name = H5MM_xstrdup(name); - - /* 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") - - /* Retrieve the # of read attempts here so that sohm in superblock will get the correct # of attempts */ - if(H5P_get(a_plist, H5F_ACS_METADATA_READ_ATTEMPTS_NAME, &file->read_attempts) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get the # of read attempts") - - /* When opening file with SWMR access, the # of read attempts is H5F_SWMR_METADATA_READ_ATTEMPTS if not set */ - /* When opening file without SWMR access, the # of read attempts is always H5F_METADATA_READ_ATTEMPTS (set or not set) */ - if(file->intent & H5F_ACC_SWMR_READ || file->intent & H5F_ACC_SWMR_WRITE) { - if(!file->read_attempts) - file->read_attempts = H5F_SWMR_METADATA_READ_ATTEMPTS; - /* Turn off accumulator */ - shared->feature_flags = lf->feature_flags & ~(unsigned)H5FD_FEAT_ACCUMULATE_METADATA; - if(H5FD_set_feature_flags(lf, shared->feature_flags) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTSET, NULL, "can't set feature_flags in VFD") - } else - file->read_attempts = H5F_METADATA_READ_ATTEMPTS; - - /* Determine the # of bins for metdata read retries */ - file->retries_nbins = 0; - if(file->read_attempts > 1) { - double tmp; - tmp = HDlog10((double)(file->read_attempts - 1)); - file->retries_nbins = (unsigned)tmp + 1; - } - - /* Initialize the tracking for metadata read retries */ - for(i = 0; i < H5AC_NTYPES; i++) - file->retries[i] = NULL; - - /* * Read or write the file superblock, depending on whether the file is * empty or not. */ @@ -1434,6 +1442,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, } /* end if */ + /* 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") + /* * 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 @@ -2148,7 +2160,6 @@ H5Freopen(hid_t file_id) { H5F_t *old_file = NULL; H5F_t *new_file = NULL; - unsigned i; hid_t ret_value; FUNC_ENTER_API(FAIL) @@ -2159,20 +2170,9 @@ H5Freopen(hid_t file_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") /* Get a new "top level" file struct, sharing the same "low level" file struct */ - if(NULL == (new_file = H5F_new(old_file->shared, H5P_FILE_CREATE_DEFAULT, H5P_FILE_ACCESS_DEFAULT, NULL))) + if(NULL == (new_file = H5F_new(old_file->shared, 0, H5P_FILE_CREATE_DEFAULT, H5P_FILE_ACCESS_DEFAULT, NULL))) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") - /* Keep old file's read/write intent in new file */ - new_file->intent = old_file->intent; - - /* Keep old file's read attempts in new file */ - new_file->read_attempts = old_file->read_attempts; - - new_file->retries_nbins = old_file->retries_nbins; - for(i = 0; i < H5AC_NTYPES; i++) - new_file->retries[i] = NULL; - - /* Duplicate old file's names */ new_file->open_name = H5MM_xstrdup(old_file->open_name); new_file->actual_name = H5MM_xstrdup(old_file->actual_name); @@ -3186,7 +3186,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5Fget_metadata_read_retries_info + * Function: H5Fget_metadata_read_retry_info * * Purpose: To retrieve the collection of read retries for metadata items with checksum. * @@ -3198,7 +3198,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Fget_metadata_read_retries_info(hid_t file_id, H5F_retries_info_t *info) +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 */ @@ -3217,11 +3217,10 @@ H5Fget_metadata_read_retries_info(hid_t file_id, H5F_retries_info_t *info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") /* Copy the # of bins for "retries" array */ - info->nbins = file->retries_nbins; + info->nbins = file->shared->retries_nbins; /* Initialize the array of "retries" */ - for(i = 0; i < NUM_METADATA_READ_RETRIES; i++) - info->retries[i] = NULL; + HDmemset(info->retries, 0, sizeof(info->retries)); /* Return if there are no bins -- no retries */ if(!info->nbins) @@ -3255,14 +3254,17 @@ H5Fget_metadata_read_retries_info(hid_t file_id, H5F_retries_info_t *info) case H5AC_FARRAY_DBLOCK_ID: case H5AC_FARRAY_DBLK_PAGE_ID: case H5AC_SUPERBLOCK_ID: - HDassert(j < NUM_METADATA_READ_RETRIES); - if(file->retries[i] != NULL) { + HDassert(j < H5F_NUM_METADATA_READ_RETRY_TYPES); + if(file->shared->retries[i] != NULL) { /* Allocate memory for retries[i] */ - if((info->retries[j] = (uint32_t *)HDmalloc(tot_size)) == NULL) + if(NULL == (info->retries[j] = (uint32_t *)HDmalloc(tot_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + /* Copy the information */ - HDmemcpy(info->retries[j], file->retries[i], tot_size); - } + HDmemcpy(info->retries[j], file->shared->retries[i], tot_size); + } /* end if */ + + /* Increment location in info->retries[] array */ j++; break; @@ -3273,7 +3275,7 @@ H5Fget_metadata_read_retries_info(hid_t file_id, H5F_retries_info_t *info) done: FUNC_LEAVE_API(ret_value) -} /* end H5Fget_metadata_read_retries_info() */ +} /* end H5Fget_metadata_read_retry_info() */ /*------------------------------------------------------------------------- @@ -3498,7 +3500,6 @@ H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5F_set_store_msg_crt_idx() */ - /*------------------------------------------------------------------------- * Function: H5F_track_metadata_read_retries @@ -3506,8 +3507,8 @@ H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag) * Purpose: To track the # of a "retries" (log10) for a metadata item. * This routine should be used only when: * "retries" > 0 - * f->read_attempts > 1 (does not have retry when 1) - * f->retries_nbins > 0 (calculated based on f->read_attempts) + * f->shared->read_attempts > 1 (does not have retry when 1) + * f->shared->retries_nbins > 0 (calculated based on f->shared->read_attempts) * * Return: Success: SUCCEED * Failure: FAIL @@ -3520,32 +3521,33 @@ herr_t H5F_track_metadata_read_retries(H5F_t *f, unsigned actype, unsigned retries) { unsigned log_ind; /* Index to the array of retries based on log10 of retries */ - double tmp; + double tmp; /* Temporary value, to keep compiler quiet */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) /* Sanity check */ HDassert(f); - HDassert(f->read_attempts > 1); - HDassert(f->retries_nbins > 0); + HDassert(f->shared->read_attempts > 1); + HDassert(f->shared->retries_nbins > 0); HDassert(retries > 0); - HDassert(retries < f->read_attempts); + HDassert(retries < f->shared->read_attempts); HDassert(actype < H5AC_NTYPES); /* Allocate memory for retries */ - if(f->retries[actype] == NULL) - if((f->retries[actype] = (uint32_t *)HDcalloc((size_t)f->retries_nbins, sizeof(uint32_t))) == NULL) + if(NULL == f->shared->retries[actype]) + if(NULL == (f->shared->retries[actype] = (uint32_t *)HDcalloc((size_t)f->shared->retries_nbins, sizeof(uint32_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Index to retries based on log10 */ tmp = HDlog10((double)retries); log_ind = (unsigned)tmp; - HDassert(log_ind < f->retries_nbins); + HDassert(log_ind < f->shared->retries_nbins); /* Increment the # of the "retries" */ - f->retries[actype][log_ind]++; + f->shared->retries[actype][log_ind]++; done: FUNC_LEAVE_NOAPI(ret_value) } /* H5F_track_metadata_read_retries() */ + |