diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-03-01 21:26:31 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-03-01 21:26:31 (GMT) |
commit | 2e8b6c0223e6969e3840e2dfefdfa34a223f3e15 (patch) | |
tree | 2b2dae6d7e737de43d23ba0f4fb0a07596a21078 /src/H5Fsuper.c | |
parent | 2618906fee4c3fe20c81c8b2b2d744af4f13e5a7 (diff) | |
download | hdf5-2e8b6c0223e6969e3840e2dfefdfa34a223f3e15.zip hdf5-2e8b6c0223e6969e3840e2dfefdfa34a223f3e15.tar.gz hdf5-2e8b6c0223e6969e3840e2dfefdfa34a223f3e15.tar.bz2 |
[svn-r13440] Description:
Revise latest form of superblock format pretty drastically, to
eliminate unused fields and move rarely used fields into superblock extension.
Finished removing last vestiges of references to (never used) i"shared"
object header message ID.
Added object header messages for non-default v1 B-tree 'K' values
and for driver info.
Updated testfiles to reflect size changes, etc.
Various minor cleanups, etc.
Tested on:
FreeBSD/32 6.2 (duty)
Mac OS X/32 10.4.8 (amazon)
Diffstat (limited to 'src/H5Fsuper.c')
-rw-r--r-- | src/H5Fsuper.c | 717 |
1 files changed, 438 insertions, 279 deletions
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 5a3692a..547502d 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -71,14 +71,13 @@ + H5F_SIZEOF_ADDR(f) /* driver block address */ \ + H5G_SIZEOF_ENTRY(f)) /* root group ptr */ #define H5F_SUPERBLOCK_VARLEN_SIZE_V2(f) \ - ( H5F_SUPERBLOCK_VARLEN_SIZE_COMMON /* Common variable-length info */ \ - + 2 /* indexed B-tree internal k */ \ + ( 2 /* size of address, size of lengths */ \ + + 1 /* consistency flags */ \ + H5F_SIZEOF_ADDR(f) /* base address */ \ + H5F_SIZEOF_ADDR(f) /* superblock extension address */ \ + H5F_SIZEOF_ADDR(f) /* EOF address */ \ - + H5F_SIZEOF_ADDR(f) /* driver block address */ \ - + H5G_SIZEOF_ENTRY(f) /* root group ptr */ \ - + H5F_SIZEOF_CHKSUM) /* superblock + driver info block checksum (keep this last) */ + + H5F_SIZEOF_ADDR(f) /* root group object header address */ \ + + H5F_SIZEOF_CHKSUM) /* superblock checksum (keep this last) */ #define H5F_SUPERBLOCK_VARLEN_SIZE(v, f) ( \ (v == 0 ? H5F_SUPERBLOCK_VARLEN_SIZE_V0(f) : 0) \ + (v == 1 ? H5F_SUPERBLOCK_VARLEN_SIZE_V1(f) : 0) \ @@ -213,7 +212,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_read_superblock + * Function: H5F_super_read * * Purpose: Reads the superblock from the file or from the BUF. If * ADDR is a valid address, then it reads it from the file. @@ -230,25 +229,23 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) +H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) { + uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* Buffer for superblock */ + H5P_genplist_t *c_plist; /* File creation property list */ + H5F_file_t *shared; /* shared part of `file' */ + H5FD_t *lf; /* file driver part of `shared' */ haddr_t stored_eoa; /*relative end-of-addr in file */ haddr_t eof; /*end of file address */ size_t sizeof_addr; /* Size of offsets in the file (in bytes) */ size_t sizeof_size; /* Size of lengths in the file (in bytes) */ const size_t fixed_size = H5F_SUPERBLOCK_FIXED_SIZE; /*fixed sizeof superblock */ - unsigned sym_leaf_k; /* Symbol table leaf node's 'K' value */ size_t variable_size; /*variable sizeof superblock */ - unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree internal node 'K' values */ - H5F_file_t *shared = NULL; /* shared part of `file' */ - H5FD_t *lf = NULL; /* file driver part of `shared' */ uint8_t *p; /* Temporary pointer into encoding buffer */ unsigned super_vers; /* Superblock version */ - uint8_t buf[H5F_MAX_SUPERBLOCK_SIZE + H5F_MAX_DRVINFOBLOCK_SIZE]; /* Buffer for superblock & driver info block */ - H5P_genplist_t *c_plist; /* File creation property list */ herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5F_read_superblock, FAIL) + FUNC_ENTER_NOAPI(H5F_super_read, FAIL) /* Short cuts */ shared = f->shared; @@ -263,7 +260,7 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to find file signature") /* Read fixed-size portion of the superblock */ - p = buf; + p = sbuf; if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, shared->super_addr + fixed_size) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed") if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, shared->super_addr, fixed_size, p) < 0) @@ -280,12 +277,12 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set superblock version") /* Sanity check */ - HDassert(((size_t)(p - buf)) == fixed_size); + HDassert(((size_t)(p - sbuf)) == fixed_size); /* Determine the size of the variable-length part of the superblock */ variable_size = H5F_SUPERBLOCK_VARLEN_SIZE(super_vers, f); HDassert(variable_size > 0); - HDassert(fixed_size + variable_size <= sizeof(buf)); + HDassert(fixed_size + variable_size <= sizeof(sbuf)); /* Read in variable-sized portion of superblock */ if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, shared->super_addr + fixed_size + variable_size) < 0) @@ -293,194 +290,235 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, shared->super_addr + fixed_size, variable_size, p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read superblock") - /* Freespace version */ - if(HDF5_FREESPACE_VERSION != *p++) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad free space version number") - - /* Root group version number */ - if(HDF5_OBJECTDIR_VERSION != *p++) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad object directory version number") - - /* Skip over reserved byte */ - p++; - - /* Shared header version number */ - if(HDF5_SHAREDHEADER_VERSION != *p++) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad shared-header format version number") - - /* Size of file addresses */ - sizeof_addr = *p++; - if(sizeof_addr != 2 && sizeof_addr != 4 && - sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number in an address") - if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME,&sizeof_addr) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number in an address") - shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */ - - /* Size of file sizes */ - sizeof_size = *p++; - if(sizeof_size != 2 && sizeof_size != 4 && - sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number for object size") - if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number for object size") - shared->sizeof_size = sizeof_size; /* Keep a local copy also */ - - /* Skip over reserved byte */ - p++; - - /* Various B-tree sizes */ - UINT16DECODE(p, sym_leaf_k); - if(sym_leaf_k == 0) - HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad symbol table leaf node 1/2 rank") - if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for symbol table leaf nodes") - shared->sym_leaf_k = sym_leaf_k; /* Keep a local copy also */ - - /* Need 'get' call to set other array values */ - if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for btree internal nodes") - UINT16DECODE(p, btree_k[H5B_SNODE_ID]); - if(btree_k[H5B_SNODE_ID] == 0) - HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad 1/2 rank for btree internal nodes") - /* - * Delay setting the value in the property list until we've checked - * for the indexed storage B-tree internal 'K' value later. - */ - - /* File consistency flags. Not really used yet */ - UINT32DECODE(p, shared->consist_flags); - - /* - * If the superblock version # is greater than 0, read in the indexed - * storage B-tree internal 'K' value - */ - if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) { - UINT16DECODE(p, btree_k[H5B_ISTORE_ID]); - /* Reserved bytes are present only in version 1 */ - if(super_vers == HDF5_SUPERBLOCK_VERSION_1) - p += 2; /* reserved */ - } /* end if */ - else - btree_k[H5B_ISTORE_ID] = HDF5_BTREE_ISTORE_IK_DEF; - - /* Set the B-tree internal node values, etc */ - if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for btree internal nodes") - HDmemcpy(shared->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID); /* Keep a local copy also */ - - /* Remainder of "variable-sized" portion of superblock */ - H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/); - H5F_addr_decode(f, (const uint8_t **)&p, &shared->extension_addr/*out*/); - H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/); - H5F_addr_decode(f, (const uint8_t **)&p, &shared->driver_addr/*out*/); - 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") - - /* - * Check if superblock address is different from base address and - * adjust base address and "end of address" address if so. - */ - if(!H5F_addr_eq(shared->super_addr, shared->base_addr)) { - /* Check if the superblock moved earlier in the file */ - if(H5F_addr_lt(shared->super_addr, shared->base_addr)) - stored_eoa -= (shared->base_addr - shared->super_addr); - else - /* The superblock moved later in the file */ - stored_eoa += (shared->super_addr - shared->base_addr); + /* Check for older version of superblock format */ + if(super_vers < HDF5_SUPERBLOCK_VERSION_2) { + uint32_t consist_flags; /* File Consistency Flags */ + unsigned btree_k[H5B_NUM_BTREE_ID]; /* B-tree internal node 'K' values */ + unsigned sym_leaf_k; /* Symbol table leaf node's 'K' value */ + + /* Freespace version (hard-wired) */ + if(HDF5_FREESPACE_VERSION != *p++) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad free space version number") + + /* Root group version number (hard-wired) */ + if(HDF5_OBJECTDIR_VERSION != *p++) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad object directory version number") + + /* Skip over reserved byte */ + p++; + + /* Shared header version number (hard-wired) */ + if(HDF5_SHAREDHEADER_VERSION != *p++) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad shared-header format version number") + + /* Size of file addresses */ + sizeof_addr = *p++; + if(sizeof_addr != 2 && sizeof_addr != 4 && + sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number in an address") + if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number in an address") + shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */ + + /* Size of file sizes */ + sizeof_size = *p++; + if(sizeof_size != 2 && sizeof_size != 4 && + sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number for object size") + if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number for object size") + shared->sizeof_size = sizeof_size; /* Keep a local copy also */ + + /* Skip over reserved byte */ + p++; + + /* Various B-tree sizes */ + UINT16DECODE(p, sym_leaf_k); + if(sym_leaf_k == 0) + HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad symbol table leaf node 1/2 rank") + if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &sym_leaf_k) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for symbol table leaf nodes") + shared->sym_leaf_k = sym_leaf_k; /* Keep a local copy also */ + + /* Need 'get' call to set other array values */ + if(H5P_get(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get rank for btree internal nodes") + UINT16DECODE(p, btree_k[H5B_SNODE_ID]); + if(btree_k[H5B_SNODE_ID] == 0) + HGOTO_ERROR(H5E_FILE, H5E_BADRANGE, FAIL, "bad 1/2 rank for btree internal nodes") + /* + * Delay setting the value in the property list until we've checked + * for the indexed storage B-tree internal 'K' value later. + */ - shared->base_addr = shared->super_addr; - } /* end if */ + /* File consistency flags. (Not really used yet) */ + UINT32DECODE(p, consist_flags); + HDassert(consist_flags <= 255); + shared->consist_flags = consist_flags; - /* 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 the library ignore the family driver information saved - * in the superblock. - */ - if(shared->fam_to_sec2) - shared->driver_addr = HADDR_UNDEF; - - /* Decode the optional driver information block */ - if(H5F_addr_defined(shared->driver_addr)) { - char drv_name[9]; /* Name of driver */ - unsigned drv_vers; /* Version of driver info block */ - haddr_t drv_addr = shared->base_addr + shared->driver_addr; - size_t drv_fixed_size; /* Amount of fixed size driver info to read */ - size_t drv_variable_size; /* Size of variable-length portion of driver info block, in bytes */ - - /* Account for extra data read in for superblock version > 1 */ - /* (extra room is for the trailing checksum on the superblock + driver info block) */ - if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) - drv_fixed_size = (size_t)H5F_DRVINFOBLOCK_HDR_SIZE - H5F_SIZEOF_CHKSUM; + /* + * If the superblock version # is greater than 0, read in the indexed + * storage B-tree internal 'K' value + */ + if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) { + UINT16DECODE(p, btree_k[H5B_ISTORE_ID]); + /* Reserved bytes are present only in version 1 */ + if(super_vers == HDF5_SUPERBLOCK_VERSION_1) + p += 2; /* reserved */ + } /* end if */ else - drv_fixed_size = (size_t)H5F_DRVINFOBLOCK_HDR_SIZE; - - /* Read in fixed-sized portion of driver info block */ - if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed") - if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr, drv_fixed_size, p) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read driver information block") + btree_k[H5B_ISTORE_ID] = HDF5_BTREE_ISTORE_IK_DEF; - /* Version number */ - drv_vers = *p++; - if(drv_vers != HDF5_DRIVERINFO_VERSION_0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad driver information block version number") + /* Set the B-tree internal node values, etc */ + if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btree_k) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for btree internal nodes") + HDmemcpy(shared->btree_k, btree_k, sizeof(unsigned) * (size_t)H5B_NUM_BTREE_ID); /* Keep a local copy also */ - p += 3; /* reserved bytes */ + /* Remainder of "variable-sized" portion of superblock */ + H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/); + H5F_addr_decode(f, (const uint8_t **)&p, &shared->extension_addr/*out*/); + H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/); + H5F_addr_decode(f, (const uint8_t **)&p, &shared->driver_addr/*out*/); + 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") - /* Driver info size */ - UINT32DECODE(p, drv_variable_size); - - /* Account for extra data to read for superblock version > 1 */ - /* (extra room is for the trailing checksum on the superblock + driver info block) */ - if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) - drv_variable_size += H5F_SIZEOF_CHKSUM; - - /* Sanity check */ - HDassert(fixed_size + variable_size + drv_fixed_size + drv_variable_size <= sizeof(buf)); - - /* Driver name and/or version */ - HDstrncpy(drv_name, (const char *)p, (size_t)8); - drv_name[8] = '\0'; - p += 8; /* advance past name/version */ - - /* Read in variable-sized portion of driver info block */ - if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed") - if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE, drv_variable_size, p) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read file driver information") - - /* 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. + /* + * Check if superblock address is different from base address and + * adjust base address and "end of address" address if so. */ - if(!HDstrncmp(drv_name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family")) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "family driver should be used") - if(!HDstrncmp(drv_name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi")) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "multi driver should be used") - - /* Decode the driver-specific driver info block information */ - if(H5FD_sb_decode(lf, drv_name, p) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to decode driver information") + if(!H5F_addr_eq(shared->super_addr, shared->base_addr)) { + /* Check if the superblock moved earlier in the file */ + if(H5F_addr_lt(shared->super_addr, shared->base_addr)) + stored_eoa -= (shared->base_addr - shared->super_addr); + else + /* The superblock moved later in the file */ + stored_eoa += (shared->super_addr - shared->base_addr); + + shared->base_addr = shared->super_addr; + } /* end if */ - /* Advance past variable length portion of driver info block */ - p += drv_variable_size; + /* 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 the library ignore the family driver information saved + * in the superblock. + */ + if(shared->fam_to_sec2) + shared->driver_addr = HADDR_UNDEF; + + /* Decode the optional driver information block */ + if(H5F_addr_defined(shared->driver_addr)) { + uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Buffer for driver info block */ + char drv_name[9]; /* Name of driver */ + unsigned drv_vers; /* Version of driver info block */ + haddr_t drv_addr = shared->base_addr + shared->driver_addr; + size_t drv_variable_size; /* Size of variable-length portion of driver info block, in bytes */ + + /* Read in fixed-sized portion of driver info block */ + p = dbuf; + if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed") + if(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") + + /* Version number */ + drv_vers = *p++; + if(drv_vers != HDF5_DRIVERINFO_VERSION_0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad driver information block version number") + + p += 3; /* reserved bytes */ + + /* Driver info size */ + UINT32DECODE(p, drv_variable_size); + + /* Sanity check */ + HDassert(H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size <= sizeof(dbuf)); + + /* Driver name and/or version */ + HDstrncpy(drv_name, (const char *)p, (size_t)8); + drv_name[8] = '\0'; + p += 8; /* advance past name/version */ + + /* 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(drv_name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family")) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "family driver should be used") + if(!HDstrncmp(drv_name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi")) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "multi driver should be used") + + /* Read in variable-sized portion of driver info block */ + if(H5FD_set_eoa(lf, H5FD_MEM_SUPER, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE + drv_variable_size) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "set end of space allocation request failed") + if(H5FD_read(lf, H5FD_MEM_SUPER, dxpl_id, drv_addr + H5F_DRVINFOBLOCK_HDR_SIZE, drv_variable_size, p) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read file driver information") + + /* Decode driver information */ + if(H5FD_sb_decode(lf, drv_name, p) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to decode driver information") + } /* end if */ } /* end if */ - - /* Compute checksum for superblock versions > 1 */ - if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) { + else { + haddr_t root_addr; /* Address of root group */ uint32_t computed_chksum; /* Computed checksum */ uint32_t read_chksum; /* Checksum read from file */ - /* Compute checksum on superblock + driver info block */ - computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + /* Size of file addresses */ + sizeof_addr = *p++; + if(sizeof_addr != 2 && sizeof_addr != 4 && + sizeof_addr != 8 && sizeof_addr != 16 && sizeof_addr != 32) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number in an address") + if(H5P_set(c_plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &sizeof_addr) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number in an address") + shared->sizeof_addr = sizeof_addr; /* Keep a local copy also */ + + /* Size of file sizes */ + sizeof_size = *p++; + if(sizeof_size != 2 && sizeof_size != 4 && + sizeof_size != 8 && sizeof_size != 16 && sizeof_size != 32) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "bad byte number for object size") + if(H5P_set(c_plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &sizeof_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set byte number for object size") + shared->sizeof_size = sizeof_size; /* Keep a local copy also */ + + /* File consistency flags. (Not really used yet) */ + shared->consist_flags = *p++; + + /* Base, superblock extension, end of file & root group object header addresses */ + H5F_addr_decode(f, (const uint8_t **)&p, &shared->base_addr/*out*/); + H5F_addr_decode(f, (const uint8_t **)&p, &shared->extension_addr/*out*/); + H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/); + H5F_addr_decode(f, (const uint8_t **)&p, &root_addr/*out*/); + + /* Compute checksum for superblock */ + computed_chksum = H5_checksum_metadata(sbuf, (size_t)(p - sbuf), 0); /* Decode checksum */ UINT32DECODE(p, read_chksum); + /* Verify correct checksum */ if(read_chksum != computed_chksum) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad checksum on driver information block") - } /* end if */ + + /* Create root group object location */ + H5O_loc_reset(root_loc->oloc); + root_loc->oloc->file = f; + root_loc->oloc->addr = root_addr; + + /* + * Check if superblock address is different from base address and + * adjust base address and "end of address" address if so. + */ + if(!H5F_addr_eq(shared->super_addr, shared->base_addr)) { + /* Check if the superblock moved earlier in the file */ + if(H5F_addr_lt(shared->super_addr, shared->base_addr)) + stored_eoa -= (shared->base_addr - shared->super_addr); + else + /* The superblock moved later in the file */ + stored_eoa += (shared->super_addr - shared->base_addr); + + shared->base_addr = shared->super_addr; + } /* end if */ + } /* end else */ /* * The user-defined data is the area of the file before the base @@ -508,7 +546,9 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) /* Read the file's superblock extension, if there is one. */ if(H5F_addr_defined(shared->extension_addr)) { - H5O_loc_t ext_loc; /* "Object location" for superblock extension */ + H5O_loc_t ext_loc; /* "Object location" for superblock extension */ + H5O_btreek_t btreek; /* v1 B-tree 'K' value message from superblock extension */ + H5O_drvinfo_t drvinfo; /* Driver info message from superblock extension */ /* Sanity check - superblock extension should only be defined for * superblock version >= 2. @@ -528,6 +568,51 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) if(H5SM_get_info(&ext_loc, c_plist, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read SOHM table information") + /* Read in v1 B-tree 'K' value message, if it exists */ + if(NULL == H5O_msg_read(&ext_loc, H5O_BTREEK_ID, &btreek, dxpl_id)) { + /* Reset error from "failed" message read */ + H5E_clear_stack(NULL); + + /* No non-default v1 B-tree 'K' value info in file, use defaults */ + shared->btree_k[H5B_ISTORE_ID] = HDF5_BTREE_ISTORE_IK_DEF; + shared->btree_k[H5B_SNODE_ID] = HDF5_BTREE_SNODE_IK_DEF; + shared->sym_leaf_k = H5F_CRT_SYM_LEAF_DEF; + } /* end if */ + else { + /* Set non-default v1 B-tree 'K' value info from file */ + shared->btree_k[H5B_ISTORE_ID] = btreek.btree_k[H5B_ISTORE_ID]; + shared->btree_k[H5B_SNODE_ID] = btreek.btree_k[H5B_SNODE_ID]; + shared->sym_leaf_k = btreek.sym_leaf_k; + + /* Set non-default v1 B-tree 'K' values in the property list */ + if(H5P_set(c_plist, H5F_CRT_BTREE_RANK_NAME, btreek.btree_k) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for btree internal nodes") + if(H5P_set(c_plist, H5F_CRT_SYM_LEAF_NAME, &btreek.sym_leaf_k) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set rank for symbol table leaf nodes") + } /* end else */ + + /* Read in driver info message, if it exists */ + if(NULL == H5O_msg_read(&ext_loc, H5O_DRVINFO_ID, &drvinfo, dxpl_id)) { + /* Reset error from "failed" message read */ + H5E_clear_stack(NULL); + } /* end if */ + else { + /* 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(drvinfo.name, "NCSAfami", (size_t)8) && HDstrcmp(lf->cls->name, "family")) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "family driver should be used") + if(!HDstrncmp(drvinfo.name, "NCSAmult", (size_t)8) && HDstrcmp(lf->cls->name, "multi")) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "multi driver should be used") + + /* Decode driver information */ + if(H5FD_sb_decode(lf, drvinfo.name, drvinfo.buf) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to decode driver information") + + /* Reset driver info message */ + H5O_msg_reset(H5O_DRVINFO_ID, &drvinfo); + } /* end else */ + /* Close the extension. Bump the version number to avoid closing the * file (since this will be the only open object). */ @@ -539,15 +624,15 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_read_superblock() */ +} /* end H5F_super_read() */ /*------------------------------------------------------------------------- - * Function: H5F_init_superblock + * Function: H5F_super_init * * Purpose: Allocates the superblock for the file and initializes - * information about the superblock in memory. Does not write - * any superblock information to the file. + * information about the superblock in memory. Writes extension + * messages if any are needed. * * Return: Success: SUCCEED * Failure: FAIL @@ -559,18 +644,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_init_superblock(H5F_t *f, H5O_loc_t *ext_loc, hid_t dxpl_id) +H5F_super_init(H5F_t *f, hid_t dxpl_id) { + H5P_genplist_t *plist; /* File creation property list */ hsize_t userblock_size; /* Size of userblock, in bytes */ size_t superblock_size; /* Size of superblock, in bytes */ size_t driver_size; /* Size of driver info block (bytes) */ + hsize_t alloc_size; /* Size to allocate on disk */ unsigned super_vers; /* Superblock version */ haddr_t super_addr; /* Address of superblock */ - H5P_genplist_t *plist; /* File creation property list */ hbool_t need_ext; /* Whether the superblock extension is needed */ herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5F_init_superblock, FAIL) + FUNC_ENTER_NOAPI(H5F_super_init, FAIL) /* Get the shared file creation property list */ if(NULL == (plist = H5I_object(f->shared->fcpl_id))) @@ -614,8 +700,10 @@ H5F_init_superblock(H5F_t *f, H5O_loc_t *ext_loc, hid_t dxpl_id) * allocation request is required to return memory at format address zero. */ H5_CHECK_OVERFLOW(f->shared->base_addr, haddr_t, hsize_t); - super_addr = H5FD_alloc(f->shared->lf, H5FD_MEM_SUPER, dxpl_id, - ((hsize_t)f->shared->base_addr + superblock_size + driver_size)); + alloc_size = (hsize_t)f->shared->base_addr + superblock_size; + if(super_vers < HDF5_SUPERBLOCK_VERSION_2) + alloc_size += driver_size; + super_addr = H5FD_alloc(f->shared->lf, H5FD_MEM_SUPER, dxpl_id, alloc_size); if(HADDR_UNDEF == super_addr) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file space for userblock and/or superblock") if(0 != super_addr) @@ -651,6 +739,8 @@ H5F_init_superblock(H5F_t *f, H5O_loc_t *ext_loc, hid_t dxpl_id) /* Create the superblock extension for "extra" superblock data, if necessary. */ if(need_ext) { + H5O_loc_t ext_loc; /* Superblock extension object location */ + /* The superblock extension isn't actually a group, but the * default group creation list should work fine. * If we don't supply a size for the object header, HDF5 will @@ -659,27 +749,73 @@ H5F_init_superblock(H5F_t *f, H5O_loc_t *ext_loc, hid_t dxpl_id) * be tuned if more information is added to the superblock * extension. */ - H5O_loc_reset(ext_loc); - if(H5O_create(f, dxpl_id, 0, H5P_GROUP_CREATE_DEFAULT, ext_loc) < 0) + H5O_loc_reset(&ext_loc); + if(H5O_create(f, dxpl_id, 0, H5P_GROUP_CREATE_DEFAULT, &ext_loc) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "unable to create superblock extension") - /* Record this address */ - f->shared->extension_addr = ext_loc->addr; + /* Record the address of the superblock extension */ + f->shared->extension_addr = ext_loc.addr; + + /* Create the Shared Object Header Message table and register it with + * the metadata cache, if this file supports shared messages. + */ + if(f->shared->sohm_nindexes > 0) { + /* Initialize the shared message code & write the SOHM message to the extension */ + if(H5SM_init(f, plist, &ext_loc, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create SOHM table") + } /* end if */ + + /* Check for non-default v1 B-tree 'K' values to store */ + if(f->shared->btree_k[H5B_SNODE_ID] != HDF5_BTREE_SNODE_IK_DEF || + f->shared->btree_k[H5B_ISTORE_ID] != HDF5_BTREE_ISTORE_IK_DEF || + f->shared->sym_leaf_k != H5F_CRT_SYM_LEAF_DEF) { + H5O_btreek_t btreek; /* v1 B-tree 'K' value message for superblock extension */ + + /* Write v1 B-tree 'K' value information to the superblock extension */ + btreek.btree_k[H5B_ISTORE_ID] = f->shared->btree_k[H5B_ISTORE_ID]; + btreek.btree_k[H5B_SNODE_ID] = f->shared->btree_k[H5B_SNODE_ID]; + btreek.sym_leaf_k = f->shared->sym_leaf_k; + if(H5O_msg_create(&ext_loc, H5O_BTREEK_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &btreek, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update v1 B-tree 'K' value header message") + } /* end if */ + + /* Check for driver info to store */ + if(driver_size > 0) { + H5O_drvinfo_t drvinfo; /* Driver info */ + uint8_t dbuf[H5F_MAX_DRVINFOBLOCK_SIZE]; /* Driver info block encoding buffer */ + + /* Sanity check */ + HDassert(driver_size <= H5F_MAX_DRVINFOBLOCK_SIZE); + + /* Encode driver-specific data */ + if(H5FD_sb_encode(f->shared->lf, drvinfo.name, dbuf) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode driver information") + + /* Write driver info information to the superblock extension */ + drvinfo.len = driver_size; + drvinfo.buf = dbuf; + if(H5O_msg_create(&ext_loc, H5O_DRVINFO_ID, H5O_MSG_FLAG_CONSTANT | H5O_MSG_FLAG_DONTSHARE, H5O_UPDATE_TIME, &drvinfo, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update driver info header message") + } /* end if */ + + /* Twiddle the number of open objects to avoid closing the file + * (since this will be the only open object currently). + */ + f->nopen_objs++; + if(H5O_close(&ext_loc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close superblock extension") + f->nopen_objs--; } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_init_superblock() */ +} /* end H5F_super_init() */ /*------------------------------------------------------------------------- - * Function: H5F_write_superblock + * Function: H5F_super_write * - * Purpose: Writes (and optionally allocates) the superblock for the file. - * If BUF is non-NULL, then write the serialized superblock - * information into it. It should be a buffer of size - * H5F_SUPERBLOCK_SIZE + H5F_DRVINFOBLOCK_SIZE - * or larger. + * Purpose: Writes the superblock for the file. * * Return: Success: SUCCEED * Failure: FAIL @@ -691,18 +827,17 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_write_superblock(H5F_t *f, hid_t dxpl_id) +H5F_super_write(H5F_t *f, hid_t dxpl_id) { + H5P_genplist_t *plist; /* File creation property list */ uint8_t buf[H5F_MAX_SUPERBLOCK_SIZE + H5F_MAX_DRVINFOBLOCK_SIZE]; /* Superblock & driver info blockencoding buffer */ - uint8_t *p = NULL; /* Ptr into encoding buffers */ - uint32_t chksum = 0; /* Checksum temporary variable */ - size_t superblock_size; /* Size of superblock, in bytes */ + uint8_t *p; /* Ptr into encoding buffer */ + size_t superblock_size; /* Size of superblock, in bytes */ size_t driver_size; /* Size of driver info block (bytes)*/ unsigned super_vers; /* Superblock version */ - H5P_genplist_t *plist; /* Property list */ herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5F_write_superblock, FAIL) + FUNC_ENTER_NOAPI(H5F_super_write, FAIL) /* Get the shared file creation property list */ if(NULL == (plist = H5I_object(f->shared->fcpl_id))) @@ -712,84 +847,108 @@ H5F_write_superblock(H5F_t *f, hid_t dxpl_id) if(H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get superblock version") - /* Encode the file superblock */ + /* Encode the common portion of the file superblock for all versions */ p = buf; HDmemcpy(p, H5F_SIGNATURE, (size_t)H5F_SIGNATURE_LEN); p += H5F_SIGNATURE_LEN; *p++ = (uint8_t)super_vers; - *p++ = (uint8_t)HDF5_FREESPACE_VERSION; - *p++ = (uint8_t)HDF5_OBJECTDIR_VERSION; - *p++ = 0; /* reserved*/ - *p++ = (uint8_t)HDF5_SHAREDHEADER_VERSION; - HDassert(H5F_SIZEOF_ADDR(f) <= 255); - *p++ = (uint8_t)H5F_SIZEOF_ADDR(f); - HDassert(H5F_SIZEOF_SIZE(f) <= 255); - *p++ = (uint8_t)H5F_SIZEOF_SIZE(f); - *p++ = 0; /* reserved */ + /* Check for older version of superblock format */ + if(super_vers < HDF5_SUPERBLOCK_VERSION_2) { + uint32_t consist_flags; /* File Consistency Flags */ - UINT16ENCODE(p, f->shared->sym_leaf_k); - UINT16ENCODE(p, f->shared->btree_k[H5B_SNODE_ID]); - UINT32ENCODE(p, f->shared->consist_flags); + *p++ = (uint8_t)HDF5_FREESPACE_VERSION; /* (hard-wired) */ + *p++ = (uint8_t)HDF5_OBJECTDIR_VERSION; /* (hard-wired) */ + *p++ = 0; /* reserved*/ - /* - * Versions of the superblock >0 have the indexed storage B-tree - * internal 'K' value stored - */ - if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) { - UINT16ENCODE(p, f->shared->btree_k[H5B_ISTORE_ID]); - if(super_vers < HDF5_SUPERBLOCK_VERSION_2) { + *p++ = (uint8_t)HDF5_SHAREDHEADER_VERSION; /* (hard-wired) */ + HDassert(H5F_SIZEOF_ADDR(f) <= 255); + *p++ = (uint8_t)H5F_SIZEOF_ADDR(f); + HDassert(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]); + consist_flags = f->shared->consist_flags; + UINT32ENCODE(p, consist_flags); + + /* + * Versions of the superblock >0 have the indexed storage B-tree + * internal 'K' value stored + */ + if(super_vers > HDF5_SUPERBLOCK_VERSION_DEF) { + UINT16ENCODE(p, f->shared->btree_k[H5B_ISTORE_ID]); *p++ = 0; /*reserved */ *p++ = 0; /*reserved */ } /* end if */ - } /* end if */ - - H5F_addr_encode(f, &p, f->shared->base_addr); - H5F_addr_encode(f, &p, f->shared->extension_addr); - H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER)); - H5F_addr_encode(f, &p, f->shared->driver_addr); - 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") - /* Compute [possibly partial] superblock checksum */ - if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) + H5F_addr_encode(f, &p, f->shared->base_addr); + H5F_addr_encode(f, &p, f->shared->extension_addr); + H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER)); + H5F_addr_encode(f, &p, f->shared->driver_addr); + 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") + + /* Encode the driver information block. */ + H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t); + if(driver_size > 0) { + char driver_name[9]; /* Name of driver, for driver info block */ + uint8_t *dbuf = p; /* Pointer to beginning of driver info */ + + /* Encode the driver information block */ + *p++ = HDF5_DRIVERINFO_VERSION_0; /* Version */ + *p++ = 0; /* reserved */ + *p++ = 0; /* reserved */ + *p++ = 0; /* reserved */ + + /* Driver info size, excluding header */ + UINT32ENCODE(p, driver_size); + + /* Encode driver-specific data */ + 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") + + /* Store driver name (set in 'H5FD_sb_encode' call above) */ + HDmemcpy(p, driver_name, (size_t)8); + + /* Advance buffer pointer past name & variable-sized portion of driver info */ + /* (for later use in computing the superblock size) */ + p += 8 + driver_size; + } /* end if */ + } /* end if */ + else { + uint32_t chksum; /* Checksum temporary variable */ + H5O_loc_t *root_oloc; /* Pointer to root group's object location */ + + /* Size of file addresses & offsets, and consistency flags */ + HDassert(H5F_SIZEOF_ADDR(f) <= 255); + *p++ = (uint8_t)H5F_SIZEOF_ADDR(f); + HDassert(H5F_SIZEOF_SIZE(f) <= 255); + *p++ = (uint8_t)H5F_SIZEOF_SIZE(f); + *p++ = f->shared->consist_flags; + + /* Base, superblock extension & end of file addresses */ + H5F_addr_encode(f, &p, f->shared->base_addr); + H5F_addr_encode(f, &p, f->shared->extension_addr); + H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER)); + + /* Retrieve information for root group */ + if(NULL == (root_oloc = H5G_oloc(f->shared->root_grp))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to retrieve root group information") + + /* Encode address of root group's object header */ + H5F_addr_encode(f, &p, root_oloc->addr); + + /* Compute superblock checksum */ chksum = H5_checksum_metadata(buf, (H5F_SUPERBLOCK_SIZE(super_vers, f) - H5F_SIZEOF_CHKSUM), 0); - /* Encode the driver information block. */ - H5_ASSIGN_OVERFLOW(driver_size, H5FD_sb_size(f->shared->lf), hsize_t, size_t); - if(driver_size > 0) { - char driver_name[9]; /* Name of driver, for driver info block */ - uint8_t *dbuf = p; /* Pointer to beginning of driver info */ - - /* Encode the driver information block */ - *p++ = HDF5_DRIVERINFO_VERSION_0; /* Version */ - *p++ = 0; /* reserved */ - *p++ = 0; /* reserved */ - *p++ = 0; /* reserved */ - - /* Driver info size, excluding header */ - UINT32ENCODE(p, driver_size); - - /* Encode driver-specific data */ - 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") + /* Superblock checksum */ + UINT32ENCODE(p, chksum); - /* Store driver name (set in 'H5FD_sb_encode' call above) */ - HDmemcpy(dbuf + 8, driver_name, (size_t)8); - - /* Advance buffer pointer past name & variable-sized portion of driver info */ - /* (for later use in storing the checksum) */ - p += 8 + driver_size; - - /* Update superblock checksum with driver info block checksum */ - /* (on superblock versions > 1) */ - if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) - chksum = H5_checksum_metadata(dbuf, driver_size + H5F_DRVINFOBLOCK_HDR_SIZE, chksum); - } /* end if */ - - /* Encode the checksum on the superblock (for versions > 1) */ - if(super_vers >= HDF5_SUPERBLOCK_VERSION_2) - UINT32ENCODE(p, chksum); + /* Sanity check */ + HDassert((size_t)(p - buf) == H5F_SUPERBLOCK_SIZE(super_vers, f)); + } /* end else */ /* Retrieve the total size of the superblock info */ H5_ASSIGN_OVERFLOW(superblock_size, (p - buf), int, size_t); @@ -803,5 +962,5 @@ H5F_write_superblock(H5F_t *f, hid_t dxpl_id) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_write_superblock() */ +} /* end H5F_super_write() */ |