diff options
Diffstat (limited to 'src/H5FDfamily.c')
-rw-r--r-- | src/H5FDfamily.c | 246 |
1 files changed, 195 insertions, 51 deletions
diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 8cf9f9e..3f0080e 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -47,6 +47,9 @@ /* The size of the member name buffers */ #define H5FD_FAM_MEMB_NAME_BUF_SIZE 4096 +/* Default member size - 100 MiB */ +#define H5FD_FAM_DEF_MEM_SIZE ((hsize_t)(100 * H5_MB)) + /* The driver identification number, initialized at runtime */ static hid_t H5FD_FAMILY_g = 0; @@ -77,6 +80,10 @@ typedef struct H5FD_family_fapl_t { hid_t memb_fapl_id; /*file access property list of each memb*/ } H5FD_family_fapl_t; +/* Private routines */ +static herr_t H5FD__family_get_default_config(H5FD_family_fapl_t *fa_out); +static char * H5FD__family_get_default_printf_filename(const char *old_filename); + /* Callback prototypes */ static herr_t H5FD__family_term(void); static void * H5FD__family_fapl_get(H5FD_t *_file); @@ -105,6 +112,7 @@ static herr_t H5FD__family_delete(const char *filename, hid_t fapl_id); /* The class struct */ static const H5FD_class_t H5FD_family_g = { + H5FD_FAMILY_VALUE, /* value */ "family", /* name */ HADDR_MAX, /* maxaddr */ H5F_CLOSE_WEAK, /* fc_degree */ @@ -137,34 +145,125 @@ static const H5FD_class_t H5FD_family_g = { H5FD__family_lock, /* lock */ H5FD__family_unlock, /* unlock */ H5FD__family_delete, /* del */ + NULL, /* ctl */ H5FD_FLMAP_DICHOTOMY /* fl_map */ }; -/*-------------------------------------------------------------------------- -NAME - H5FD__init_package -- Initialize interface-specific information -USAGE - herr_t H5FD__init_package() -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. (Just calls - H5FD_family_init currently). - ---------------------------------------------------------------------------*/ +/*------------------------------------------------------------------------- + * Function: H5FD__family_get_default_config + * + * Purpose: Populates a H5FD_family_fapl_t structure with default + * values. + * + * Return: Non-negative on Success/Negative on Failure + * + *------------------------------------------------------------------------- + */ static herr_t -H5FD__init_package(void) +H5FD__family_get_default_config(H5FD_family_fapl_t *fa_out) +{ + H5P_genplist_t *def_plist; + H5P_genplist_t *plist; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_STATIC + + HDassert(fa_out); + + fa_out->memb_size = H5FD_FAM_DEF_MEM_SIZE; + + /* Use copy of default file access property list for member FAPL ID. + * The Sec2 driver is explicitly set on the member FAPL ID, as the + * default driver might have been replaced with the Family VFD, which + * would cause recursion badness in the child members. + */ + if (NULL == (def_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + if ((fa_out->memb_fapl_id = H5P_copy_plist(def_plist, FALSE)) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTCOPY, FAIL, "can't copy property list") + if (NULL == (plist = (H5P_genplist_t *)H5I_object(fa_out->memb_fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + if (H5P_set_driver_by_value(plist, H5_VFD_SEC2, NULL, TRUE) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTSET, FAIL, "can't set default driver on member FAPL") + +done: + if (ret_value < 0 && fa_out->memb_fapl_id >= 0) { + if (H5I_dec_ref(fa_out->memb_fapl_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't decrement ref. count on member FAPL ID") + } + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD__family_get_default_config() */ + +/*------------------------------------------------------------------------- + * Function: H5FD__family_get_default_printf_filename + * + * Purpose: Given a filename, allocates and returns a new filename + * buffer that contains the given filename modified into this + * VFD's printf-style format. For example, the filename + * "file1.h5" would be modified to "file1-%06d.h5". This would + * allow for member filenames such as "file1-000000.h5", + * "file1-000001.h5", etc. The caller is responsible for + * freeing the returned buffer. + * + * Return: Non-negative on Success/Negative on Failure + * + *------------------------------------------------------------------------- + */ +static char * +H5FD__family_get_default_printf_filename(const char *old_filename) { - herr_t ret_value = SUCCEED; + const char *suffix = "-%06d"; + size_t old_filename_len = 0; + size_t new_filename_len = 0; + char * file_extension = NULL; + char * tmp_buffer = NULL; + char * ret_value = NULL; FUNC_ENTER_STATIC - if (H5FD_family_init() < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to initialize family VFD") + HDassert(old_filename); + + old_filename_len = HDstrlen(old_filename); + if (0 == old_filename_len) + HGOTO_ERROR(H5E_VFL, H5E_BADVALUE, NULL, "invalid filename") + + new_filename_len = old_filename_len + HDstrlen(suffix) + 1; + if (NULL == (tmp_buffer = H5MM_malloc(new_filename_len))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, NULL, "can't allocate new filename buffer") + + /* Determine if filename contains a ".h5" extension. */ + if ((file_extension = HDstrstr(old_filename, ".h5"))) { + /* Insert the printf format between the filename and ".h5" extension. */ + HDstrcpy(tmp_buffer, old_filename); + file_extension = HDstrstr(tmp_buffer, ".h5"); + HDsprintf(file_extension, "%s%s", suffix, ".h5"); + } + else if ((file_extension = HDstrrchr(old_filename, '.'))) { + char *new_extension_loc = NULL; + + /* If the filename doesn't contain a ".h5" extension, but contains + * AN extension, just insert the printf format before that extension. + */ + HDstrcpy(tmp_buffer, old_filename); + new_extension_loc = HDstrrchr(tmp_buffer, '.'); + HDsprintf(new_extension_loc, "%s%s", suffix, file_extension); + } + else { + /* If the filename doesn't contain an extension at all, just insert + * the printf format at the end of the filename. + */ + HDsnprintf(tmp_buffer, new_filename_len, "%s%s", old_filename, suffix); + } + + ret_value = tmp_buffer; done: + if (!ret_value) + H5MM_xfree(tmp_buffer); + FUNC_LEAVE_NOAPI(ret_value) -} /* H5FD__init_package() */ +} /* end H5FD__family_get_default_printf_filename() */ /*------------------------------------------------------------------------- * Function: H5FD_family_init @@ -183,9 +282,9 @@ done: hid_t H5FD_family_init(void) { - hid_t ret_value = H5I_INVALID_HID; /* Return value */ + hid_t ret_value = H5I_INVALID_HID; - FUNC_ENTER_NOAPI(H5I_INVALID_HID) + FUNC_ENTER_NOAPI_NOERR if (H5I_VFL != H5I_get_type(H5FD_FAMILY_g)) H5FD_FAMILY_g = H5FD_register(&H5FD_family_g, sizeof(H5FD_class_t), FALSE); @@ -193,7 +292,6 @@ H5FD_family_init(void) /* Set return value */ ret_value = H5FD_FAMILY_g; -done: FUNC_LEAVE_NOAPI(ret_value) } /* H5FD_family_init() */ @@ -242,7 +340,7 @@ herr_t H5Pset_fapl_family(hid_t fapl_id, hsize_t msize, hid_t memb_fapl_id) { herr_t ret_value; - H5FD_family_fapl_t fa = {0, -1}; + H5FD_family_fapl_t fa = {0, H5I_INVALID_HID}; H5P_genplist_t * plist; /* Property list pointer */ FUNC_ENTER_API(FAIL) @@ -251,18 +349,22 @@ H5Pset_fapl_family(hid_t fapl_id, hsize_t msize, hid_t memb_fapl_id) /* Check arguments */ if (TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") - if (H5P_DEFAULT == memb_fapl_id) - memb_fapl_id = H5P_FILE_ACCESS_DEFAULT; + if (H5P_DEFAULT == memb_fapl_id) { + /* Get default configuration for member FAPL */ + if (H5FD__family_get_default_config(&fa) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default driver configuration info") + } else if (TRUE != H5P_isa_class(memb_fapl_id, H5P_FILE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list") /* Initialize driver specific information. */ - fa.memb_size = msize; - fa.memb_fapl_id = memb_fapl_id; + fa.memb_size = msize; + if (H5P_DEFAULT != memb_fapl_id) + fa.memb_fapl_id = memb_fapl_id; if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") - ret_value = H5P_set_driver(plist, H5FD_FAMILY, &fa); + ret_value = H5P_set_driver(plist, H5FD_FAMILY, &fa, NULL); done: FUNC_LEAVE_API(ret_value) @@ -588,9 +690,10 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad { H5FD_family_t *file = NULL; char * memb_name = NULL, *temp = NULL; - hsize_t eof = HADDR_UNDEF; - unsigned t_flags = flags & ~H5F_ACC_CREAT; - H5FD_t * ret_value = NULL; + hsize_t eof = HADDR_UNDEF; + hbool_t default_config = FALSE; + unsigned t_flags = flags & ~H5F_ACC_CREAT; + H5FD_t * ret_value = NULL; FUNC_ENTER_STATIC @@ -604,21 +707,32 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad if (NULL == (file = (H5FD_family_t *)H5MM_calloc(sizeof(H5FD_family_t)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") if (H5P_FILE_ACCESS_DEFAULT == fapl_id) { - file->memb_fapl_id = H5P_FILE_ACCESS_DEFAULT; - if (H5I_inc_ref(file->memb_fapl_id, FALSE) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINC, NULL, "unable to increment ref count on VFL driver") - file->memb_size = 1024 * 1024 * 1024; /*1GB. Actual member size to be updated later */ - file->pmem_size = 1024 * 1024 * 1024; /*1GB. Member size passed in through property */ - file->mem_newsize = 0; /*New member size used by h5repart only */ - } /* end if */ + H5FD_family_fapl_t default_fa; + + /* Get default configuration */ + if (H5FD__family_get_default_config(&default_fa) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default driver configuration info") + + file->memb_fapl_id = default_fa.memb_fapl_id; + file->memb_size = H5FD_FAM_DEF_MEM_SIZE; /* Actual member size to be updated later */ + file->pmem_size = H5FD_FAM_DEF_MEM_SIZE; /* Member size passed in through property */ + file->mem_newsize = 0; /*New member size used by h5repart only */ + + default_config = TRUE; + } /* end if */ else { H5P_genplist_t * plist; /* Property list pointer */ const H5FD_family_fapl_t *fa; + H5FD_family_fapl_t default_fa; if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") - if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, NULL, "bad VFL driver info") + if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) { + if (H5FD__family_get_default_config(&default_fa) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default family VFD configuration") + fa = &default_fa; + default_config = TRUE; + } /* Check for new family file size. It's used by h5repart only. */ if (H5P_exist_plist(plist, H5F_ACS_FAMILY_NEWSIZE_NAME) > 0) { @@ -642,7 +756,10 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad } /* end else */ file->memb_size = fa->memb_size; /* Actual member size to be updated later */ file->pmem_size = fa->memb_size; /* Member size passed in through property */ - } /* end else */ + + if (default_config && H5I_dec_ref(fa->memb_fapl_id) < 0) + HGOTO_ERROR(H5E_ID, H5E_CANTDEC, NULL, "can't decrement ref. count on member FAPL") + } /* end else */ file->name = H5MM_strdup(name); file->flags = flags; @@ -655,8 +772,16 @@ H5FD__family_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxad /* Check that names are unique */ HDsnprintf(memb_name, H5FD_FAM_MEMB_NAME_BUF_SIZE, name, 0); HDsnprintf(temp, H5FD_FAM_MEMB_NAME_BUF_SIZE, name, 1); - if (!HDstrcmp(memb_name, temp)) - HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file names not unique") + if (!HDstrcmp(memb_name, temp)) { + if (default_config) { + temp = H5MM_xfree(temp); + if (NULL == (temp = H5FD__family_get_default_printf_filename(name))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get default printf-style filename") + name = temp; + } + else + HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file names not unique") + } /* Open all the family members */ while (1) { @@ -1360,7 +1485,9 @@ H5FD__family_delete(const char *filename, hid_t fapl_id) { H5P_genplist_t * plist; const H5FD_family_fapl_t *fa; - hid_t memb_fapl_id = H5I_INVALID_HID; + H5FD_family_fapl_t default_fa = {0, H5I_INVALID_HID}; + hbool_t default_config = FALSE; + hid_t memb_fapl_id = H5I_INVALID_HID; unsigned current_member; char * member_name = NULL; char * temp = NULL; @@ -1374,13 +1501,21 @@ H5FD__family_delete(const char *filename, hid_t fapl_id) /* Get the driver info (for the member fapl) * The family_open call accepts H5P_DEFAULT, so we'll accept that here, too. */ - if (H5P_FILE_ACCESS_DEFAULT == fapl_id) - memb_fapl_id = H5P_FILE_ACCESS_DEFAULT; + if (H5P_FILE_ACCESS_DEFAULT == fapl_id) { + if (H5FD__family_get_default_config(&default_fa) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default family VFD configuration") + memb_fapl_id = default_fa.memb_fapl_id; + default_config = TRUE; + } else { if (NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") - if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad family VFD driver info") + if (NULL == (fa = (const H5FD_family_fapl_t *)H5P_peek_driver_info(plist))) { + if (H5FD__family_get_default_config(&default_fa) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default family VFD configuration") + fa = &default_fa; + default_config = TRUE; + } memb_fapl_id = fa->memb_fapl_id; } @@ -1393,8 +1528,17 @@ H5FD__family_delete(const char *filename, hid_t fapl_id) /* Sanity check to make sure that generated names are unique */ HDsnprintf(member_name, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, 0); HDsnprintf(temp, H5FD_FAM_MEMB_NAME_BUF_SIZE, filename, 1); - if (!HDstrcmp(member_name, temp)) - HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, "provided file name cannot generate unique sub-files") + if (!HDstrcmp(member_name, temp)) { + if (default_config) { + temp = H5MM_xfree(temp); + if (NULL == (temp = H5FD__family_get_default_printf_filename(filename))) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, FAIL, "can't get default printf-style filename") + filename = temp; + } + else + HGOTO_ERROR(H5E_VFL, H5E_CANTDELETEFILE, FAIL, + "provided file name cannot generate unique sub-files") + } /* Delete all the family members */ current_member = 0; @@ -1430,9 +1574,9 @@ done: if (temp) H5MM_xfree(temp); - /* Don't close memb_fapl_id - We didn't bump its reference count since we're - * only using it in this call. - */ + /* Only close memb_fapl_id if we created one from the default configuration */ + if (default_fa.memb_fapl_id >= 0 && H5I_dec_ref(default_fa.memb_fapl_id) < 0) + HDONE_ERROR(H5E_VFL, H5E_CANTDEC, FAIL, "can't decrement ref. count on member FAPL ID") FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD__family_delete() */ |