summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5F.c140
-rw-r--r--src/H5Fpkg.h2
2 files changed, 101 insertions, 41 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 463f46e..961a8e9 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -1620,6 +1620,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
H5FD_t *lf=NULL; /*file driver part of `shared' */
uint8_t buf[256]; /*temporary I/O buffer */
const uint8_t *p; /*ptr into temp I/O buffer */
+ uint8_t *q; /*ptr into temp I/O buffer */
size_t fixed_size=24; /*fixed sizeof superblock */
size_t variable_size; /*variable sizeof superblock */
size_t driver_size; /*size of driver info block */
@@ -1641,6 +1642,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
H5P_genplist_t *c_plist;
H5P_genplist_t *a_plist; /* Property list */
H5F_close_degree_t fc_degree;
+ unsigned chksum; /* Checksum temporary variable */
+ unsigned i; /* Index variable */
FUNC_ENTER_NOAPI(H5F_open, NULL);
@@ -1860,9 +1863,8 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
H5G_SIZEOF_ENTRY(file); /*root group ptr*/
assert(variable_size<=sizeof(buf));
if (H5FD_set_eoa(lf, shared->boot_addr+fixed_size+variable_size)<0 ||
- H5FD_read(lf, H5FD_MEM_SUPER, H5P_DATASET_XFER_DEFAULT, shared->boot_addr+fixed_size, variable_size, buf)<0)
+ H5FD_read(lf, H5FD_MEM_SUPER, H5P_DATASET_XFER_DEFAULT, shared->boot_addr+fixed_size, variable_size, &buf[fixed_size])<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read superblock");
- p = buf;
H5F_addr_decode(file, &p, &(shared->base_addr)/*out*/);
H5F_addr_decode(file, &p, &(shared->freespace_addr)/*out*/);
H5F_addr_decode(file, &p, &stored_eoa/*out*/);
@@ -1870,6 +1872,14 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
if (H5G_ent_decode(file, &p, &root_ent/*out*/)<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root symbol entry");
+ /* Compute boot block checksum */
+ assert(sizeof(chksum)==sizeof(shared->boot_chksum));
+ for(q=(uint8_t *)&chksum, chksum=0, i=0; i<(fixed_size+variable_size); i++)
+ q[i%sizeof(shared->boot_chksum)] ^= buf[i];
+
+ /* Set the boot block checksum */
+ shared->boot_chksum=chksum;
+
/* Decode the optional driver information block */
if (H5F_addr_defined(shared->driver_addr)) {
haddr_t drv_addr = shared->base_addr + shared->driver_addr;
@@ -1894,10 +1904,19 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Read driver information and decode */
if (H5FD_set_eoa(lf, drv_addr+16+driver_size)<0 ||
- H5FD_read(lf, H5FD_MEM_SUPER, H5P_DATASET_XFER_DEFAULT, drv_addr+16, driver_size, buf)<0)
+ H5FD_read(lf, H5FD_MEM_SUPER, H5P_DATASET_XFER_DEFAULT, drv_addr+16, driver_size, &buf[16])<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file driver information");
- if (H5FD_sb_decode(lf, driver_name, buf)<0)
+ if (H5FD_sb_decode(lf, driver_name, &buf[16])<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to decode driver information");
+
+ /* Compute driver info block checksum */
+ assert(sizeof(chksum)==sizeof(shared->drvr_chksum));
+ for(q=(uint8_t *)&chksum, chksum=0, i=0; i<(driver_size+16); i++)
+ q[i%sizeof(shared->drvr_chksum)] ^= buf[i];
+
+ /* Set the driver info block checksum */
+ shared->drvr_chksum=chksum;
+
} /* end if */
/* Make sure we can open the root group */
@@ -2288,20 +2307,31 @@ H5Fflush(hid_t object_id, H5F_scope_t scope)
* Quincey Koziol, 2002-05-20
* Added 'closing' parameter
*
+ * Quincey Koziol, 2002-06-05
+ * Added boot block & driver info block checksumming, to avoid
+ * writing them out when they haven't changed.
+ *
*-------------------------------------------------------------------------
*/
static herr_t
H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
hbool_t alloc_only, hbool_t closing)
{
- uint8_t sbuf[2048], dbuf[2048], *p=NULL;
- unsigned nerrors=0, i;
- size_t superblock_size, driver_size;
- char driver_name[9];
- int boot_vers, freespace_vers,
- obj_dir_vers, share_head_vers,
- btree_k[H5B_NUM_BTREE_ID];
- unsigned sym_leaf_k;
+ uint8_t sbuf[1024]; /* Superblock encoding buffer */
+ uint8_t dbuf[1024]; /* Driver info block encoding buffer */
+ uint8_t *p=NULL; /* Temporary pointer into encoding buffers */
+ unsigned nerrors=0; /* Errors from nested flushes */
+ unsigned i; /* Index variable */
+ unsigned chksum; /* Checksum temporary variable */
+ size_t superblock_size;/* Size of superblock, in bytes */
+ size_t driver_size; /* Size of driver info block, in bytes */
+ char driver_name[9]; /* Name of driver, for driver info block */
+ int boot_vers; /* Boot block version */
+ int freespace_vers; /* Freespace info version */
+ int obj_dir_vers; /* Object header info version */
+ int share_head_vers;/* Shared header info version */
+ int btree_k[H5B_NUM_BTREE_ID]; /* B-tree size info */
+ unsigned sym_leaf_k; /* Number of symbols in B-tree leafs */
H5P_genplist_t *plist; /* Property list */
FUNC_ENTER_NOINIT(H5F_flush);
@@ -2328,24 +2358,27 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
}
}
- /* flush the data sieve buffer, if we have a dirty one */
- if(!alloc_only && f->shared->sieve_buf && f->shared->sieve_dirty) {
- /* Write dirty data sieve buffer to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, H5P_DATASET_XFER_DEFAULT, f->shared->sieve_buf)<0)
- HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
+ /* Avoid flushing buffers & caches when alloc_only set */
+ if(!alloc_only) {
+ /* flush the data sieve buffer, if we have a dirty one */
+ if(f->shared->sieve_buf && f->shared->sieve_dirty) {
+ /* Write dirty data sieve buffer to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, H5P_DATASET_XFER_DEFAULT, f->shared->sieve_buf)<0)
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end if */
+
+ /* flush the entire raw data cache */
+ if (H5F_istore_flush (f, invalidate)<0)
+ HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush raw data cache");
+
+ /* flush (and invalidate) the entire meta data cache */
+ if (H5AC_flush(f, NULL, HADDR_UNDEF, invalidate)<0)
+ HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush meta data cache");
} /* end if */
- /* flush the entire raw data cache */
- if (!alloc_only && H5F_istore_flush (f, invalidate)<0)
- HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush raw data cache");
-
- /* flush (and invalidate) the entire meta data cache */
- if (!alloc_only && H5AC_flush(f, NULL, HADDR_UNDEF, invalidate)<0)
- HRETURN_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush meta data cache");
-
/* Get the shared file creation property list */
if(NULL == (plist = H5I_object(f->shared->fcpl_id)))
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list");
@@ -2387,6 +2420,9 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
H5G_ent_encode(f, &p, H5G_entof(f->shared->root_grp));
superblock_size = p-sbuf;
+ /* Double check we didn't overrun the block (unlikely) */
+ assert(superblock_size<=sizeof(sbuf));
+
/*
* Encode the driver information block.
*/
@@ -2411,6 +2447,9 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
/* Driver name */
HDmemcpy(dbuf+8, driver_name, 8);
+
+ /* Double check we didn't overrun the block (unlikely) */
+ assert(driver_size<=sizeof(dbuf));
} /* end if */
if (alloc_only) {
@@ -2438,15 +2477,37 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
f->shared->driver_addr = superblock_size;
} else {
- /* Write superblock */
- if (H5FD_write(f->shared->lf, H5FD_MEM_SUPER, H5P_DATASET_XFER_DEFAULT, f->shared->boot_addr, superblock_size, sbuf)<0)
- HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write superblock");
-
- /* Write driver information block */
+ /* Compute boot block checksum */
+ assert(sizeof(chksum)==sizeof(f->shared->boot_chksum));
+ for(p=(uint8_t *)&chksum, chksum=0, i=0; i<superblock_size; i++)
+ p[i%sizeof(f->shared->boot_chksum)] ^= sbuf[i];
+
+ /* Compare with current checksums */
+ if(chksum!=f->shared->boot_chksum) {
+ /* Write superblock */
+ if (H5FD_write(f->shared->lf, H5FD_MEM_SUPER, H5P_DATASET_XFER_DEFAULT, f->shared->boot_addr, superblock_size, sbuf)<0)
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write superblock");
+
+ /* Update checksum information if different */
+ f->shared->boot_chksum=chksum;
+ } /* end if */
+
+ /* Check for driver info block */
if (HADDR_UNDEF!=f->shared->driver_addr) {
- if (H5FD_write(f->shared->lf, H5FD_MEM_SUPER, H5P_DATASET_XFER_DEFAULT,
- f->shared->base_addr+superblock_size, driver_size, dbuf)<0)
- HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write driver information block");
+ /* Compute driver info block checksum */
+ assert(sizeof(chksum)==sizeof(f->shared->drvr_chksum));
+ for(p=(uint8_t *)&chksum, chksum=0, i=0; i<driver_size; i++)
+ p[i%sizeof(f->shared->drvr_chksum)] ^= dbuf[i];
+
+ /* Compare with current checksums */
+ if(chksum!=f->shared->boot_chksum) {
+ /* Write driver information block */
+ if (H5FD_write(f->shared->lf, H5FD_MEM_SUPER, H5P_DATASET_XFER_DEFAULT, f->shared->base_addr+superblock_size, driver_size, dbuf)<0)
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write driver information block");
+
+ /* Update checksum information if different */
+ f->shared->drvr_chksum=chksum;
+ } /* end if */
} /* end if */
} /* end else */
@@ -2455,11 +2516,8 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate,
HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed");
/* Check flush errors for children - errors are already on the stack */
- if (nerrors)
- HRETURN(FAIL);
-
- FUNC_LEAVE(SUCCEED);
-}
+ FUNC_LEAVE(nerrors ? FAIL : SUCCEED);
+} /* end H5F_flush() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 30439b4..6f034b6 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -98,6 +98,8 @@ typedef struct H5F_file_t {
haddr_t base_addr; /* Absolute base address for rel.addrs. */
haddr_t freespace_addr; /* Relative address of free-space info */
haddr_t driver_addr; /* File driver information block address*/
+ unsigned boot_chksum; /* Boot block checksum */
+ unsigned drvr_chksum; /* Driver info block checksum */
struct H5AC_t *cache; /* The object cache */
hid_t fcpl_id; /* File creation property list ID */
int mdc_nelmts; /* Size of meta data cache (elements) */