summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Laird <jlaird@hdfgroup.org>2007-01-18 15:27:14 (GMT)
committerJames Laird <jlaird@hdfgroup.org>2007-01-18 15:27:14 (GMT)
commit26fc682d8d54190199c6e04c415eed7d888d6994 (patch)
tree7c4ac9be6dff6019261e6015b5772416a4a4ba03
parent9155785889af8ae809fb5e9cdbb330710a174d72 (diff)
downloadhdf5-26fc682d8d54190199c6e04c415eed7d888d6994.zip
hdf5-26fc682d8d54190199c6e04c415eed7d888d6994.tar.gz
hdf5-26fc682d8d54190199c6e04c415eed7d888d6994.tar.bz2
[svn-r13153] Added checksum to superblock and driver info block (in latest version of
superblock). Tried to standardize sizes and added #defines to H5Fpkg.h so that hopefully the code is a little easier to read. Of course this is a file format change. Tested on Windows, juniper, smirom, kagiso.
-rw-r--r--src/H5Adense.c1
-rw-r--r--src/H5Fpkg.h57
-rw-r--r--src/H5Fsuper.c227
-rw-r--r--src/H5private.h8
4 files changed, 185 insertions, 108 deletions
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 0418427..1259975 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -419,7 +419,6 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, unsigned mesg_flags,
HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
/* Get handle for shared message heap, if attributes are sharable */
- /* JAMES: does this work if only very large attributes are shared? */
if(attr_sharable) {
haddr_t shared_fheap_addr; /* Address of fractal heap to use */
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 957ec0a..1d6cc3f 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -58,9 +58,58 @@
# undef H5F_DEBUG
#endif
-/* Maximum size of super-block buffer */
-#define H5F_SUPERBLOCK_SIZE 130
-#define H5F_DRVINFOBLOCK_SIZE 1024
+/* Superblock sizes for various versions */
+/* Checksum size in the file */
+#define H5F_SIZEOF_CHKSUM 4
+
+/* Fixed-size portion at the beginning of all superblocks */
+#define H5F_SUPERBLOCK_FIXED_SIZE ( H5F_SIGNATURE_LEN \
+ + 3 /* superblock, freespace, and root group versions */ \
+ + 1 /* reserved */ \
+ + 3 /* shared header vers, size of address, size of lengths */ \
+ + 1 /* reserved */ \
+ + 4 /* group leaf k, group internal k */ \
+ + 4) /* consistency flags */
+
+#define H5F_SUPERBLOCK_VARLEN_SIZE_V0(f) \
+ ( H5F_SIZEOF_ADDR(f) /* base address */ \
+ + H5F_SIZEOF_ADDR(f) /* free space address */ \
+ + H5F_SIZEOF_ADDR(f) /* EOF address */ \
+ + H5F_SIZEOF_ADDR(f) /* driver block address */ \
+ + H5G_SIZEOF_ENTRY(f)) /* root group ptr */
+
+#define H5F_SUPERBLOCK_VARLEN_SIZE_V1(f) \
+ ( 2 /* indexed B-tree internal k */ \
+ + 2 /* reserved */ \
+ + H5F_SIZEOF_ADDR(f) /* base address */ \
+ + H5F_SIZEOF_ADDR(f) /* free space address */ \
+ + H5F_SIZEOF_ADDR(f) /* EOF address */ \
+ + H5F_SIZEOF_ADDR(f) /* driver block address */ \
+ + H5G_SIZEOF_ENTRY(f)) /* root group ptr */
+
+#define H5F_SUPERBLOCK_VARLEN_SIZE_V2(f) \
+ ( 2 /* indexed B-tree internal k */ \
+ + H5F_SIZEOF_ADDR(f) /* base address */ \
+ + H5F_SIZEOF_ADDR(f) /* free space address */ \
+ + H5F_SIZEOF_ADDR(f) /* shared message table address */ \
+ + 2 /* shared message version and number of indexes */ \
+ + H5F_SIZEOF_ADDR(f) /* EOF address */ \
+ + H5F_SIZEOF_ADDR(f) /* driver block address */ \
+ + H5G_SIZEOF_ENTRY(f) /* root group ptr */ \
+ + H5F_SIZEOF_CHKSUM)
+
+#define H5F_SUPERBLOCK_SIZE(v, f) ( H5F_SUPERBLOCK_FIXED_SIZE \
+ + (v == 0 ? H5F_SUPERBLOCK_VARLEN_SIZE_V0(f) : 0) \
+ + (v == 1 ? H5F_SUPERBLOCK_VARLEN_SIZE_V1(f) : 0) \
+ + (v == 2 ? H5F_SUPERBLOCK_VARLEN_SIZE_V2(f) : 0))
+
+
+#define H5F_DRVINFOBLOCK_HDR_SIZE 16
+#define H5F_DRVINFO_CHKSUM(v) (v == 0 ? 0 : H5F_SIZEOF_CHKSUM)
+
+/* Maximum size of super-block buffers */
+#define H5F_MAX_SUPERBLOCK_SIZE 134
+#define H5F_MAX_DRVINFOBLOCK_SIZE 1024
/* Define the HDF5 file signature */
#define H5F_SIGNATURE "\211HDF\r\n\032\n"
@@ -98,8 +147,6 @@ typedef struct H5F_file_t {
haddr_t driver_addr; /* File driver information block address*/
hbool_t fam_to_sec2; /* Is h5repart changing driver from family to sec2 */
- unsigned super_chksum; /* Superblock checksum */
- unsigned drvr_chksum; /* Driver info block checksum */
H5AC_t *cache; /* The object cache */
H5AC_cache_config_t
mdc_initCacheCfg; /* initial configuration for the */
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index 62ada4e..3ecdfb4 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -74,10 +74,9 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
{
haddr_t stored_eoa; /*relative end-of-addr in file */
haddr_t eof; /*end of file address */
- uint8_t *q; /*ptr into temp I/O buffer */
size_t sizeof_addr = 0;
size_t sizeof_size = 0;
- const size_t fixed_size = 24; /*fixed sizeof superblock */
+ const size_t fixed_size = H5F_SUPERBLOCK_FIXED_SIZE; /*fixed sizeof superblock */
unsigned sym_leaf_k = 0;
size_t variable_size; /*variable sizeof superblock */
unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree internal node 'K' values */
@@ -85,15 +84,15 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
H5FD_t *lf = NULL; /* file driver part of `shared' */
uint8_t *p; /* Temporary pointer into encoding buffers */
uint8_t *start_p; /* Start of encoding buffers */
- unsigned i; /* Index variable */
- unsigned chksum; /* Checksum temporary variable */
+ uint32_t read_chksum; /* Checksum read from file */
+ uint32_t computed_chksum; /* Computed checksum */
size_t driver_size; /* Size of driver info block, in bytes */
char driver_name[9]; /* Name of driver, for driver info block */
unsigned super_vers; /* Super block version */
unsigned freespace_vers; /* Freespace info version */
unsigned obj_dir_vers; /* Object header info version */
unsigned share_head_vers; /* Shared header info version */
- uint8_t sbuf[H5F_SUPERBLOCK_SIZE]; /* Local buffer */
+ uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* Local buffer */
unsigned nindexes; /* Number of shared message indexes */
H5P_genplist_t *c_plist; /* File creation property list */
herr_t ret_value = SUCCEED;
@@ -206,12 +205,13 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
assert(((size_t)(p - start_p)) == fixed_size);
/* Decode the variable-length part of the superblock... */
- variable_size = (super_vers>0 ? 4 : 0) + /* Potential indexed storage B-tree internal 'K' value */
- H5F_SIZEOF_ADDR(f) + /*base addr*/
- H5F_SIZEOF_ADDR(f) + /*global free list*/
- H5F_SIZEOF_ADDR(f) + /*end-of-address*/
- H5F_SIZEOF_ADDR(f) + /*reserved address*/
- H5G_SIZEOF_ENTRY(f); /*root group ptr*/
+ if(super_vers == HDF5_SUPERBLOCK_VERSION_DEF)
+ variable_size = H5F_SUPERBLOCK_VARLEN_SIZE_V0(f);
+ else if (super_vers == HDF5_SUPERBLOCK_VERSION_1)
+ variable_size = H5F_SUPERBLOCK_VARLEN_SIZE_V1(f);
+ else
+ variable_size = H5F_SUPERBLOCK_VARLEN_SIZE_V2(f);
+
assert(fixed_size + variable_size <= buf_size);
/* The buffer (buf) is either passed in or the "local_buf" variable now */
@@ -226,9 +226,12 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
* If the superblock version # is greater than 0, read in the indexed
* storage B-tree internal 'K' value
*/
- if (super_vers > 0) {
+ if (super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
UINT16DECODE(p, btree_k[H5B_ISTORE_ID]);
- p += 2; /* reserved */
+ /* Reserved bytes are present only in version 1 */
+ if(super_vers == HDF5_SUPERBLOCK_VERSION_1) {
+ p += 2; /* reserved */
+ }
}
else
btree_k[H5B_ISTORE_ID] = HDF5_BTREE_ISTORE_IK_DEF;
@@ -241,7 +244,7 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &shared->freespace_addr/*out*/);
/* If the superblock version is greater than 1, read in the shared OH message table information */
- if(super_vers > 1) {
+ if(super_vers > HDF5_SUPERBLOCK_VERSION_1) {
H5F_addr_decode(f, (const uint8_t **)&p, &shared->sohm_addr/*out*/);
shared->sohm_vers = *p++;
shared->sohm_nindexes = *p++;
@@ -251,6 +254,18 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
if(H5G_obj_ent_decode(f, (const uint8_t **)&p, root_loc->oloc/*out*/) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root symbol entry")
+ /* Compute super block checksum for versions greater than 1 */
+ if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) {
+ computed_chksum = H5_checksum_metadata(sbuf, (p - sbuf), 0);
+ /* Read stored super block checksum */
+ UINT32DECODE(p, read_chksum);
+
+ if(read_chksum != computed_chksum)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad checksum on superblock")
+ }
+
+ HDassert(p - sbuf == H5F_SUPERBLOCK_SIZE(super_vers, f));
+
/*
* Check if superblock address is different from base address and
* adjust base address and "end of address" address if so.
@@ -266,13 +281,6 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
shared->base_addr = shared->super_addr;
} /* end if */
- /* Compute super block checksum */
- assert(sizeof(chksum) == sizeof(shared->super_chksum));
- for (q = (uint8_t *)&chksum, chksum = 0, i = 0; i < fixed_size + variable_size; ++i)
- q[i % sizeof(shared->super_chksum)] ^= start_p[i];
-
- /* Set the super block checksum */
- shared->super_chksum = chksum;
/* This step is for h5repart tool only. If user wants to change file driver from
* family to sec2 while using h5repart, set the driver address to undefined to let
@@ -283,17 +291,19 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
/* Decode the optional driver information block */
if (H5F_addr_defined(shared->driver_addr)) {
+ unsigned drv_vers;
haddr_t drv_addr = shared->base_addr + shared->driver_addr;
- uint8_t dbuf[H5F_DRVINFOBLOCK_SIZE]; /* Local buffer */
+ uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Local buffer */
size_t dbuf_size; /* Size available for driver info */
const uint8_t *driver_p; /* Remember beginning of driver info block */
+
if(!buf) {
driver_p = p = dbuf;
dbuf_size=sizeof(dbuf);
- if (H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + 16) < 0 ||
- H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr, (size_t)16, p) < 0)
+ if (H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0 ||
+ H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr, (size_t)H5F_DRVINFOBLOCK_HDR_SIZE, p) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read driver information block")
} /* end if */
else {
@@ -302,10 +312,11 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
} /* end else */
/* Version number */
- if (HDF5_DRIVERINFO_VERSION != *p++)
+ drv_vers = *p++;
+ if (drv_vers > HDF5_DRIVERINFO_VERSION_MAX)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad driver information block version number")
- p += 3; /* reserved */
+ p += 3; /* reserved bytes */
/* Driver info size */
UINT32DECODE(p, driver_size);
@@ -315,15 +326,18 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
driver_name[8] = '\0';
p += 8; /* advance past name/version */
- /* Read driver information and decode */
- assert((driver_size + 16) <= dbuf_size);
+ HDassert(p - dbuf == H5F_DRVINFOBLOCK_HDR_SIZE);
+
+ /* Read driver information */
+ HDassert((driver_size + H5F_DRVINFOBLOCK_HDR_SIZE + H5F_DRVINFO_CHKSUM(drv_vers)) <= dbuf_size);
if(!buf) {
- if (H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + 16 + driver_size) < 0 ||
- H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr+16, driver_size, p) < 0)
+ if (H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE + driver_size + H5F_DRVINFO_CHKSUM(drv_vers)) < 0 ||
+ H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr+H5F_DRVINFOBLOCK_HDR_SIZE, driver_size, p) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read file driver information")
} /* end if */
+ /* Decode driver information */
/* Check if driver matches driver information saved. Unfortunately, we can't push this
* function to each specific driver because we're checking if the driver is correct.*/
if(!HDstrncmp(driver_name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family"))
@@ -334,13 +348,19 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
if (H5FD_sb_decode(lf, driver_name, p) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "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)] ^= driver_p[i];
+ p += driver_size;
- /* Set the driver info block checksum */
- shared->drvr_chksum = chksum;
+ /* Compute checksum for versions > 0*/
+ if(drv_vers >= HDF5_DRIVERINFO_VERSION_1) {
+ computed_chksum = H5_checksum_metadata(dbuf, (H5F_DRVINFOBLOCK_HDR_SIZE + driver_size), 0);
+ /* Read checksum */
+ UINT32DECODE(p, read_chksum);
+
+ if(read_chksum != computed_chksum)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad checksum on driver information block")
+ }
+
+ HDassert(p - dbuf == driver_size + H5F_DRVINFOBLOCK_HDR_SIZE + H5F_DRVINFO_CHKSUM(drv_vers));
} /* end if */
/*
@@ -368,6 +388,7 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr,
if (H5FD_set_eoa(lf, H5FD_MEM_SUPER, stored_eoa) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to set end-of-address marker for file")
+
/* Decode shared object header message information and store it in the
* fcpl */
if(shared->sohm_addr != HADDR_UNDEF)
@@ -460,17 +481,26 @@ H5F_init_superblock(const H5F_t *f, hid_t dxpl_id)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, UFAIL, "unable to get super block version")
/* Compute the size of the superblock */
- superblock_size=H5F_SIGNATURE_LEN /* Signature length (8 bytes) */
- + 16 /* Length of required fixed-size portion */
- + ((super_vers>0) ? 4 : 0) /* Version specific fixed-size portion */
- + 4 * H5F_sizeof_addr(f) /* Variable-sized addresses */
- + (super_vers>1 ? H5F_sizeof_addr(f) + 2: 0) + /*SOHM table info*/
- + H5G_SIZEOF_ENTRY(f); /* Size of root group symbol table entry */
-
- /* Compute the size of the driver information block. */
+ superblock_size=H5F_SUPERBLOCK_FIXED_SIZE;
+
+ if(super_vers==HDF5_SUPERBLOCK_VERSION_DEF)
+ superblock_size += H5F_SUPERBLOCK_VARLEN_SIZE_V0(f);
+ else if (super_vers == HDF5_SUPERBLOCK_VERSION_1)
+ superblock_size += H5F_SUPERBLOCK_VARLEN_SIZE_V1(f);
+ else if (super_vers == HDF5_SUPERBLOCK_VERSION_2)
+ superblock_size += H5F_SUPERBLOCK_VARLEN_SIZE_V2(f);
+
+ /* Compute the size of the driver information block. Use driver block
+ * version 1 if the superblock is at least version 2 */
H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t);
if (driver_size > 0)
- driver_size += 16; /* Driver block header */
+ {
+ driver_size += H5F_DRVINFOBLOCK_HDR_SIZE;
+ if(super_vers > HDF5_SUPERBLOCK_VERSION_1)
+ driver_size += H5F_DRVINFO_CHKSUM(1);
+ else
+ driver_size += H5F_DRVINFO_CHKSUM(0);
+ }
/*
* Allocate space for the userblock, superblock, driver info
@@ -529,11 +559,10 @@ done:
herr_t
H5F_write_superblock(H5F_t *f, hid_t dxpl_id)
{
- uint8_t sbuf[H5F_SUPERBLOCK_SIZE]; /* Superblock encoding buffer */
- uint8_t dbuf[H5F_DRVINFOBLOCK_SIZE];/* Driver info block encoding buffer*/
+ uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* Superblock encoding buffer */
+ uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE];/* Driver info block encoding buffer*/
uint8_t *p = NULL; /* Ptr into encoding buffers */
- unsigned i; /* Index variable */
- unsigned chksum; /* Checksum temporary variable */
+ uint32_t chksum; /* Checksum temporary variable */
size_t superblock_size; /* Size of superblock, in bytes */
size_t driver_size; /* Size of driver info block (bytes)*/
char driver_name[9]; /* Name of driver, for driver info block */
@@ -568,12 +597,14 @@ H5F_write_superblock(H5F_t *f, hid_t dxpl_id)
*p++ = (uint8_t)freespace_vers;
*p++ = (uint8_t)obj_dir_vers;
*p++ = 0; /* reserved*/
+
*p++ = (uint8_t)share_head_vers;
assert (H5F_SIZEOF_ADDR(f) <= 255);
*p++ = (uint8_t)H5F_SIZEOF_ADDR(f);
assert (H5F_SIZEOF_SIZE(f) <= 255);
*p++ = (uint8_t)H5F_SIZEOF_SIZE(f);
*p++ = 0; /* reserved */
+
UINT16ENCODE(p, f->shared->sym_leaf_k);
UINT16ENCODE(p, f->shared->btree_k[H5B_SNODE_ID]);
UINT32ENCODE(p, f->shared->consist_flags);
@@ -582,15 +613,17 @@ H5F_write_superblock(H5F_t *f, hid_t dxpl_id)
* Versions of the superblock >0 have the indexed storage B-tree
* internal 'K' value stored
*/
- if (super_vers > 0) {
+ if (super_vers > HDF5_SUPERBLOCK_VERSION_DEF) {
UINT16ENCODE(p, f->shared->btree_k[H5B_ISTORE_ID]);
- *p++ = 0; /*reserved */
- *p++ = 0; /*reserved */
+ if (super_vers < HDF5_SUPERBLOCK_VERSION_2) {
+ *p++ = 0; /*reserved */
+ *p++ = 0; /*reserved */
+ }
}
H5F_addr_encode(f, &p, f->shared->base_addr);
H5F_addr_encode(f, &p, f->shared->freespace_addr);
- if(super_vers > 1) {
+ if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) {
H5F_addr_encode(f, &p, f->shared->sohm_addr);
*p++ = f->shared->sohm_vers;
*p++ = f->shared->sohm_nindexes;
@@ -600,76 +633,72 @@ H5F_write_superblock(H5F_t *f, hid_t dxpl_id)
if(H5G_obj_ent_encode(f, &p, H5G_oloc(f->shared->root_grp))<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode root group information")
- H5_ASSIGN_OVERFLOW(superblock_size, p - sbuf, int, size_t);
+ /* Compute super block checksum */
+ if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) {
+ chksum = H5_checksum_metadata(sbuf, H5F_SUPERBLOCK_SIZE(super_vers, f) - H5F_SIZEOF_CHKSUM, 0);
+ UINT32ENCODE(p, chksum);
+ }
/* Double check we didn't overrun the block (unlikely) */
- assert(superblock_size <= sizeof(sbuf));
+ H5_ASSIGN_OVERFLOW(superblock_size, p - sbuf, int, size_t);
+ HDassert(superblock_size <= sizeof(sbuf));
+
+ /* Double check that the superblock is the right size */
+ HDassert(superblock_size == (H5F_SUPERBLOCK_SIZE(super_vers, f)));
+
+ /* Write superblock */
+ if (H5FD_write(f->shared->lf, H5FD_MEM_SUPER, dxpl_id,
+ f->shared->super_addr, superblock_size, sbuf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write superblock")
+
/* Encode the driver information block. */
H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t);
if (driver_size > 0) {
- driver_size += 16; /* Driver block header */
+ unsigned driver_vers;
+
+ /* Use driver info block version 1 on superblock version >= 2 */
+ if(super_vers > HDF5_SUPERBLOCK_VERSION_1) {
+ driver_vers = HDF5_DRIVERINFO_VERSION_1;
+ } else {
+ driver_vers = HDF5_DRIVERINFO_VERSION_0;
+ }
+
+ driver_size += H5F_DRVINFOBLOCK_HDR_SIZE + H5F_DRVINFO_CHKSUM(driver_vers);
/* Double check we didn't overrun the block (unlikely) */
- assert(driver_size <= sizeof(dbuf));
+ HDassert(driver_size <= sizeof(dbuf));
/* Encode the driver information block */
p = dbuf;
- *p++ = HDF5_DRIVERINFO_VERSION; /* Version */
- *p++ = 0; /* reserved */
- *p++ = 0; /* reserved */
- *p++ = 0; /* reserved */
+ *p++ = driver_vers; /* Version */
+ *p++ = 0; /* reserved */
+ *p++ = 0; /* reserved */
+ *p++ = 0; /* reserved */
- /* Driver info size, excluding header */
- UINT32ENCODE(p, driver_size - 16);
+ /* Driver info size, excluding header and checksum */
+ UINT32ENCODE(p, driver_size - H5F_DRVINFOBLOCK_HDR_SIZE - H5F_DRVINFO_CHKSUM(driver_vers));
/* Encode driver-specific data */
- if (H5FD_sb_encode(f->shared->lf, driver_name, dbuf + 16) < 0)
+ if (H5FD_sb_encode(f->shared->lf, driver_name, dbuf + H5F_DRVINFOBLOCK_HDR_SIZE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information")
/* Driver name */
HDmemcpy(dbuf + 8, driver_name, (size_t)8);
- } /* end if */
- /* Compute super block checksum */
- assert(sizeof(chksum) == sizeof(f->shared->super_chksum));
+ /* Compute driver info block checksum on versions > 0 */
+ if(driver_vers > HDF5_DRIVERINFO_VERSION_0) {
+ chksum = H5_checksum_metadata(dbuf, (driver_size - H5F_SIZEOF_CHKSUM), 0);
+ UINT32ENCODE(p, chksum);
+ }
- for (p = (uint8_t *)&chksum, chksum = 0, i = 0; i < superblock_size; ++i)
- p[i % sizeof(f->shared->super_chksum)] ^= sbuf[i];
-
- /* Compare with current checksums */
- if (chksum != f->shared->super_chksum) {
- /* Write superblock */
+ /* Write driver information block */
if (H5FD_write(f->shared->lf, H5FD_MEM_SUPER, dxpl_id,
- f->shared->super_addr, superblock_size, sbuf) < 0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write superblock")
-
- /* Update checksum information if different */
- f->shared->super_chksum = chksum;
+ f->shared->base_addr + f->shared->driver_addr, driver_size, dbuf) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write driver information block")
} /* end if */
-
- /* Check for driver info block */
- if (HADDR_UNDEF != f->shared->driver_addr) {
- /* 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->drvr_chksum) {
- /* Write driver information block */
- if (H5FD_write(f->shared->lf, H5FD_MEM_SUPER, dxpl_id,
- f->shared->base_addr + f->shared->driver_addr, driver_size, dbuf) < 0)
- HGOTO_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 */
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_write_superblock() */
diff --git a/src/H5private.h b/src/H5private.h
index 2d5cbdb..ada1e0d 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -266,12 +266,14 @@
/* Version #'s of the major components of the file format */
#define HDF5_SUPERBLOCK_VERSION_DEF 0 /* The default super block format */
#define HDF5_SUPERBLOCK_VERSION_1 1 /* Version with non-default B-tree 'K' value */
-#define HDF5_SUPERBLOCK_VERSION_2 2 /* Version with implicit shared OH messages */
-#define HDF5_SUPERBLOCK_VERSION_MAX HDF5_SUPERBLOCK_VERSION_2 /* The maximum super block format */
+#define HDF5_SUPERBLOCK_VERSION_2 2 /* Version with implicit shared OH messages and checksum */
+#define HDF5_SUPERBLOCK_VERSION_MAX HDF5_SUPERBLOCK_VERSION_2 /* The maximum super block format */
#define HDF5_FREESPACE_VERSION 0 /* of the Free-Space Info */
#define HDF5_OBJECTDIR_VERSION 0 /* of the Object Directory format */
#define HDF5_SHAREDHEADER_VERSION 0 /* of the Shared-Header Info */
-#define HDF5_DRIVERINFO_VERSION 0 /* of the Driver Information Block*/
+#define HDF5_DRIVERINFO_VERSION_0 0 /* of the Driver Information Block*/
+#define HDF5_DRIVERINFO_VERSION_1 1 /* Driver Information Block with checksum */
+#define HDF5_DRIVERINFO_VERSION_MAX HDF5_DRIVERINFO_VERSION_1 /* Maximum driver info block format */
/* B-tree internal 'K' values */
#define HDF5_BTREE_SNODE_IK_DEF 16