From 22a72b911eda2f413691eed0ef2862025827a858 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Tue, 16 Nov 2004 11:38:28 -0500 Subject: [PATCH] [svn-r9531] Purpose: Bug fix(#213) Description: H5Pset_fapl_family sets family member size only for creating new file. The file doesn't keep this size information. When the file is re-opened, the size of first member file is used as the member size. Solution: Assume user knows the original member size and sets it through H5Pset_fapl_family. That will be the member size. User can pass in value 0 as member size if he doesn't know the original member size. Library will choose the size of current first member size as the member file size. Platforms tested: h5committest and fuss. --- src/H5F.c | 1 + src/H5FDfamily.c | 25 ++++++++++++++++--------- test/file_handle.c | 37 ++++++++++++++++++++++++++++++------- tools/lib/h5tools.c | 3 +++ 4 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/H5F.c b/src/H5F.c index 798a28e7a2..7db2f3f8c5 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -1,4 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * Copyright by the Board of Trustees of the University of Illinois. * * All rights reserved. * * * diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index 7d35b4116a..d22bc279d7 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -580,7 +580,7 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id, hsize_t eof; unsigned t_flags = flags & ~H5F_ACC_CREAT; H5P_genplist_t *plist; /* Property list pointer */ - + FUNC_ENTER_NOAPI(H5FD_family_open, NULL) /* Check arguments */ @@ -621,6 +621,7 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id, /* Check that names are unique */ sprintf(memb_name, name, 0); sprintf(temp, name, 1); + if (!strcmp(memb_name, temp)) HGOTO_ERROR(H5E_FILE, H5E_FILEEXISTS, NULL, "file names not unique") @@ -656,14 +657,18 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id, } file->nmembs++; } - - /* - * The size of the first member determines the size of all the members, - * but if the size of the first member is zero then use the member size - * from the file access property list. + + /* + * Check if user sets member size smaller than existing first member file size. + * Return failure if so. If the member size coming from access property list is + * 0, then set the member size to be the current first member file size. */ - if ((eof=H5FDget_eof(file->memb[0]))) + if(HADDR_UNDEF==(eof = H5FD_get_eof(file->memb[0]))) + HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, NULL, "file get eof request failed") + if(file->memb_size==0 && eof) file->memb_size = eof; + if(eof && file->memb_sizenmembs; u++) if (file->memb[u]) - if (H5FDclose(file->memb[u])<0) + if (H5FD_close(file->memb[u])<0) nerrors++; if (nerrors) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "unable to close member files") @@ -812,7 +817,9 @@ H5FD_family_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) if(flags) { *flags=0; *flags|=H5FD_FEAT_AGGREGATE_METADATA; /* OK to aggregate metadata allocations */ - *flags|=H5FD_FEAT_ACCUMULATE_METADATA; /* OK to accumulate metadata for faster writes */ + /**flags|=H5FD_FEAT_ACCUMULATE_METADATA;*/ /* OK to accumulate metadata for faster writes. + * - Turn it off temporarily because there's a bug + * when trying to flush metadata during closing. */ *flags|=H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */ *flags|=H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ } diff --git a/test/file_handle.c b/test/file_handle.c index d090fce4f7..c50a749cbf 100644 --- a/test/file_handle.c +++ b/test/file_handle.c @@ -23,7 +23,7 @@ #define KB 1024 #define FAMILY_NUMBER 4 -#define FAMILY_SIZE 128 +#define FAMILY_SIZE 1024 #define MULTI_SIZE 128 #define CORE_INCREMENT 4096 @@ -226,6 +226,7 @@ test_family(void) int buf[FAMILY_NUMBER][FAMILY_SIZE]; hsize_t dims[2]={FAMILY_NUMBER, FAMILY_SIZE}; hsize_t file_size; + herr_t ret; TESTING("FAMILY file driver"); @@ -238,12 +239,29 @@ test_family(void) if((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) goto error; + if((ret=H5Fclose(file))<0) + goto error; + + /* Tries to reopen the file with member file size smaller than + * actual 1st member file size(976 bytes). Supposed to fail. */ + if(H5Pset_fapl_family(fapl, (hsize_t)512, H5P_DEFAULT)<0) + goto error; + H5E_BEGIN_TRY { + H5Fopen(filename, H5F_ACC_RDWR, fapl); + } H5E_END_TRY; + + /* Reopen the file with original member file size */ + if(H5Pset_fapl_family(fapl, (hsize_t)FAMILY_SIZE, H5P_DEFAULT)<0) + goto error; + if((file=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0) + goto error; + /* Check file size API */ if(H5Fget_filesize(file, &file_size) < 0) goto error; - /* The file size is supposed to be 2KB right now. */ - if(file_size<1*KB || file_size>4*KB) + /* The file size is supposed to be 976 bytes right now. */ + if(file_size4*KB) goto error; /* Create and write dataset */ @@ -289,10 +307,15 @@ test_family(void) if(H5Fget_filesize(file, &file_size) < 0) goto error; - /* Some data has been written. The file size should be bigger(4KB) now. */ - if(file_size<2*KB || file_size>6*KB) - goto error; - + /* Some data has been written. The file size should be bigger(18KB+976 bytes if int size is 4 bytes) now. */ + if(sizeof(int)<=4) { + if(file_size<18*KB || file_size>20*KB) + goto error; + } else if(sizeof(int)>=8) { + if(file_size<32*KB || file_size>40*KB) + goto error; + } + if(H5Sclose(space)<0) goto error; if(H5Dclose(dset)<0) diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c index fef34df3cf..801f83c726 100644 --- a/tools/lib/h5tools.c +++ b/tools/lib/h5tools.c @@ -180,6 +180,9 @@ h5tools_get_fapl(const char *driver, unsigned *drivernum, int argc, const char * } else if (!strcmp(driver, drivernames[FAMILY_IDX])) { /* FAMILY Driver */ if((fapl = H5Pcreate(H5P_FILE_ACCESS))>=0) { + /* Set member size to be 0 to indicate the current first member size + * is the member size. + */ H5Pset_fapl_family(fapl, (hsize_t)0, H5P_DEFAULT); if(drivernum)