summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5FDcore.c63
-rw-r--r--test/vfd.c135
2 files changed, 189 insertions, 9 deletions
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index cbbda53..b27949b 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -49,6 +49,7 @@ typedef struct H5FD_core_t {
haddr_t eoa; /*end of allocated region */
haddr_t eof; /*current allocated size */
size_t increment; /*multiples for mem allocation */
+ hbool_t backing_store; /*write to file name on flush */
int fd; /*backing store file descriptor */
hbool_t dirty; /*changes not saved? */
} H5FD_core_t;
@@ -368,23 +369,29 @@ done:
* Modifications:
* Robb Matzke, 1999-10-19
* The backing store file is created and opened if specified.
+ *
+ * Raymond Lu, 2006-11-30
+ * Enabled the driver to read an existing file depending on
+ * the setting of the backing_store and file open flags.
*-------------------------------------------------------------------------
*/
static H5FD_t *
-H5FD_core_open(const char *name, unsigned UNUSED flags, hid_t fapl_id,
+H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id,
haddr_t maxaddr)
{
+ int o_flags;
H5FD_core_t *file=NULL;
H5FD_core_fapl_t *fa=NULL;
H5P_genplist_t *plist; /* Property list pointer */
+ h5_stat_t sb;
int fd=-1;
H5FD_t *ret_value;
FUNC_ENTER_NOAPI(H5FD_core_open, NULL)
/* Check arguments */
- if (!(H5F_ACC_CREAT & flags))
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, NULL, "must create core files, not open them")
+ if (!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
if (0==maxaddr || HADDR_UNDEF==maxaddr)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
if (ADDR_OVERFLOW(maxaddr))
@@ -395,10 +402,18 @@ H5FD_core_open(const char *name, unsigned UNUSED flags, hid_t fapl_id,
fa = H5P_get_driver_info(plist);
} /* end if */
- /* Open backing store */
- if (fa && fa->backing_store && name &&
- (fd=HDopen(name, (O_CREAT|O_TRUNC|O_RDWR), 0666))<0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open backing store")
+ /* Build the open flags */
+ o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY;
+ if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC;
+ if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT;
+ if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL;
+
+ /* Open backing store. The only case that backing store is off is when
+ * the backing_store flag is off and H5F_ACC_CREAT is on. */
+ if(fa->backing_store || !(H5F_ACC_CREAT & flags)) {
+ if (fa && (fd=HDopen(name, o_flags, 0666))<0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file")
+ }
/* Create the new file struct */
if (NULL==(file=H5MM_calloc(sizeof(H5FD_core_t))))
@@ -414,6 +429,34 @@ H5FD_core_open(const char *name, unsigned UNUSED flags, hid_t fapl_id,
*/
file->increment = (fa && fa->increment>0) ? fa->increment : H5FD_CORE_INCREMENT;
+ /* If save data in backing store. */
+ file->backing_store = fa->backing_store;
+
+ /* If an existing file is opened, load the whole file into memory. */
+ if(!(H5F_ACC_CREAT & flags)) {
+ unsigned char *x;
+ size_t size;
+
+ if (HDfstat(file->fd, &sb)<0)
+ HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file")
+
+ size = (size_t)sb.st_size;
+
+ if(size) {
+ if (NULL==file->mem)
+ x = (unsigned char*)H5MM_malloc(size);
+
+ if (!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory block")
+
+ file->mem = x;
+ file->eof = size;
+
+ if(HDread(file->fd, file->mem, size)<0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file")
+ }
+ }
+
/* Set return value */
ret_value=(H5FD_t *)file;
@@ -808,7 +851,9 @@ done:
* Friday, October 15, 1999
*
* Modifications:
- *
+ * Raymond Lu, 2006-11-30
+ * Added a condition check for backing store flag, for an
+ * existing file can be opened for read and write now.
*-------------------------------------------------------------------------
*/
/* ARGSUSED */
@@ -821,7 +866,7 @@ H5FD_core_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
FUNC_ENTER_NOAPI(H5FD_core_flush, FAIL)
/* Write to backing store */
- if (file->dirty && file->fd>=0) {
+ if (file->dirty && file->fd>=0 && file->backing_store) {
haddr_t size = file->eof;
unsigned char *ptr = file->mem;
diff --git a/test/vfd.c b/test/vfd.c
index c8b67f7..21d022c 100644
--- a/test/vfd.c
+++ b/test/vfd.c
@@ -365,6 +365,10 @@ test_core(void)
char filename[1024];
void *fhandle=NULL;
hsize_t file_size;
+ int *points, *check, *p1, *p2;
+ hid_t dset1=-1, space1=-1;
+ hsize_t dims1[2];
+ int i, j, n;
TESTING("CORE file driver");
@@ -405,7 +409,138 @@ test_core(void)
if(H5Fclose(file)<0)
TEST_ERROR;
+
+
+ /* Open the file with backing store off for read and write.
+ * Changes won't be saved in file. */
+ if(H5Pset_fapl_core(fapl, CORE_INCREMENT, FALSE)<0)
+ TEST_ERROR;
+
+ if((file=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0)
+ TEST_ERROR;
+
+ /* Allocate memory for data set. */
+ points=(int*)malloc(DSET1_DIM1*DSET1_DIM2*sizeof(int));
+ check=(int*)malloc(DSET1_DIM1*DSET1_DIM2*sizeof(int));
+
+ /* Initialize the dset1 */
+ p1 = points;
+ for (i = n = 0; i < DSET1_DIM1; i++)
+ for (j = 0; j < DSET1_DIM2; j++)
+ *p1++ = n++;
+
+ /* Create the data space1 */
+ dims1[0] = DSET1_DIM1;
+ dims1[1] = DSET1_DIM2;
+ if ((space1 = H5Screate_simple(2, dims1, NULL))<0)
+ TEST_ERROR;
+
+ /* Create the dset1 */
+ if ((dset1 = H5Dcreate(file, DSET1_NAME, H5T_NATIVE_INT, space1, H5P_DEFAULT))<0)
+ TEST_ERROR;
+
+ /* Write the data to the dset1 */
+ if (H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, points)<0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset1)<0)
+ TEST_ERROR;
+
+ if((dset1=H5Dopen(file, DSET1_NAME))<0)
+ TEST_ERROR;
+
+ /* Read the data back from dset1 */
+ if (H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, check)<0)
+ TEST_ERROR;
+
+ /* Check that the values read are the same as the values written */
+ p1 = points;
+ p2 = check;
+ for (i = 0; i < DSET1_DIM1; i++) {
+ for (j = 0; j < DSET1_DIM2; j++) {
+ if (*p1++ != *p2++) {
+ H5_FAILED();
+ printf(" Read different values than written in data set 1.\n");
+ printf(" At index %d,%d\n", i, j);
+ TEST_ERROR;
+ }
+ }
+ }
+
+ if(H5Dclose(dset1)<0)
+ TEST_ERROR;
+
+ if(H5Fclose(file)<0)
+ TEST_ERROR;
+
+ /* Open the file with backing store on for read and write.
+ * Changes will be saved in file. */
+ if(H5Pset_fapl_core(fapl, CORE_INCREMENT, TRUE)<0)
+ TEST_ERROR;
+
+ if((file=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0)
+ TEST_ERROR;
+
+ /* Create the dset1 */
+ if ((dset1 = H5Dcreate(file, DSET1_NAME, H5T_NATIVE_INT, space1, H5P_DEFAULT))<0)
+ TEST_ERROR;
+
+ /* Write the data to the dset1 */
+ if (H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, points)<0)
+ TEST_ERROR;
+
+ if(H5Dclose(dset1)<0)
+ TEST_ERROR;
+
+ if((dset1=H5Dopen(file, DSET1_NAME))<0)
+ TEST_ERROR;
+
+ /* Reallocate memory for reading buffer. */
+ if(check)
+ free(check);
+
+ check=(int*)malloc(DSET1_DIM1*DSET1_DIM2*sizeof(int));
+
+ /* Read the data back from dset1 */
+ if (H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, check)<0)
+ TEST_ERROR;
+
+ /* Check that the values read are the same as the values written */
+ p1 = points;
+ p2 = check;
+ for (i = 0; i < DSET1_DIM1; i++) {
+ for (j = 0; j < DSET1_DIM2; j++) {
+ if (*p1++ != *p2++) {
+ H5_FAILED();
+ printf(" Read different values than written in data set 1.\n");
+ printf(" At index %d,%d\n", i, j);
+ TEST_ERROR;
+ }
+ }
+ }
+
+ /* Check file size API */
+ if(H5Fget_filesize(file, &file_size) < 0)
+ TEST_ERROR;
+
+ /* There is no garantee the size of metadata in file is constant.
+ * Just try to check if it's reasonable. */
+ if(file_size<64*KB || file_size>256*KB)
+ TEST_ERROR;
+
+ if(H5Sclose(space1)<0)
+ TEST_ERROR;
+ if(H5Dclose(dset1)<0)
+ TEST_ERROR;
+ if(H5Fclose(file)<0)
+ TEST_ERROR;
+ if(points)
+ free(points);
+ if(check)
+ free(check);
+
h5_cleanup(FILENAME, fapl);
+
PASSED();
return 0;