diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2009-04-08 21:53:31 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2009-04-08 21:53:31 (GMT) |
commit | c1c58f79a865a1e4bf53949e8819f6612c2cbd93 (patch) | |
tree | 156e27bc731b365284991ea0e3cf53a1cdf5c9d6 | |
parent | 659f3a77ea0f7548ed09a9624de3fe2a183f451c (diff) | |
download | hdf5-c1c58f79a865a1e4bf53949e8819f6612c2cbd93.zip hdf5-c1c58f79a865a1e4bf53949e8819f6612c2cbd93.tar.gz hdf5-c1c58f79a865a1e4bf53949e8819f6612c2cbd93.tar.bz2 |
[svn-r16710] Purpose: Fix bug 1423
Description:
Versions of the library between 1.3.0 and 1.6.3 have a bug which prevents them
from opening any file that does not have the root group's symbol table
information cached in the root group's entry in the superblock. Prior to 1.8
this was not an issue as this information was always cached. However, 1.8.0
stopped writing this information (which is not required by the file format
specification), and these older versions can therefore not read files created or
last written by versions 1.8.0 to 1.8.2. This fix modifies the library to once
again add this information to the superblock (when using the old file format).
Tested: jam, linew, smirom (h5committest)
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | release_docs/RELEASE.txt | 3 | ||||
-rw-r--r-- | src/H5B.c | 2 | ||||
-rw-r--r-- | src/H5Bprivate.h | 2 | ||||
-rw-r--r-- | src/H5F.c | 16 | ||||
-rw-r--r-- | src/H5Fpkg.h | 6 | ||||
-rw-r--r-- | src/H5Fsuper.c | 20 | ||||
-rw-r--r-- | src/H5Ftest.c | 40 | ||||
-rw-r--r-- | src/H5G.c | 165 | ||||
-rw-r--r-- | src/H5Gobj.c | 109 | ||||
-rw-r--r-- | src/H5Gpkg.h | 7 | ||||
-rw-r--r-- | src/H5Gprivate.h | 8 | ||||
-rw-r--r-- | src/H5Groot.c | 344 | ||||
-rw-r--r-- | src/H5Gtest.c | 56 | ||||
-rwxr-xr-x | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Makefile.in | 9 | ||||
-rw-r--r-- | test/family_v16_00000.h5 | bin | 5120 -> 5120 bytes | |||
-rwxr-xr-x | test/objcopy.c | 25 | ||||
-rw-r--r-- | test/tfile.c | 65 |
19 files changed, 552 insertions, 328 deletions
@@ -582,6 +582,7 @@ ./src/H5Gpkg.h ./src/H5Gprivate.h ./src/H5Gpublic.h +./src/H5Groot.c ./src/H5Gstab.c ./src/H5Gtest.c ./src/H5Gtraverse.c diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 2a6d4e6..77f0ae3 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -142,6 +142,9 @@ Bug Fixes since HDF5-1.8.0 release Library ------- + - Modified library to write cached symbol table information to the + superblock, to allow library versions 1.3.0 to 1.6.3 to read files + created by this version. (NAF - 2009/04/08) - Changed skip lists to use a deterministic algorithm. The library should now never call rand() or srand(). (NAF - 2009/04/08 - 503) - Fixed a bug where H5Lcopy and H5Lmove wouldn't create intermediate @@ -2057,7 +2057,6 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B_get_info() */ -#ifndef H5_STRICT_FORMAT_CHECKS /*------------------------------------------------------------------------- * Function: H5B_valid @@ -2099,5 +2098,4 @@ H5B_valid(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5B_valid() */ -#endif /* H5_STRICT_FORMAT_CHECKS */ diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h index 2ec2c22..716b608 100644 --- a/src/H5Bprivate.h +++ b/src/H5Bprivate.h @@ -168,9 +168,7 @@ H5_DLL H5B_shared_t *H5B_shared_new(const H5F_t *f, const H5B_class_t *type, H5_DLL herr_t H5B_shared_free(void *_shared); H5_DLL herr_t H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth, const H5B_class_t *type, void *udata); -#ifndef H5_STRICT_FORMAT_CHECKS H5_DLL htri_t H5B_valid(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr); -#endif /* H5_STRICT_FORMAT_CHECKS */ #endif /* _H5Bprivate_H */ @@ -893,6 +893,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) f->shared->driver_addr = HADDR_UNDEF; f->shared->accum.loc = HADDR_UNDEF; f->shared->lf = lf; + f->shared->root_addr = HADDR_UNDEF; /* * Copy the file creation and file access property lists into the @@ -1369,7 +1370,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d /* (This must be after the space for the superblock is allocated in * the file, since the superblock must be at offset 0) */ - if(H5G_mkroot(file, dxpl_id, NULL) < 0) + if(H5G_mkroot(file, dxpl_id, TRUE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group") /* Write the superblock to the file */ @@ -1379,21 +1380,12 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d if(H5F_super_write(file, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to write file superblock") } else if (1 == shared->nrefs) { - H5G_loc_t root_loc; /*root location */ - H5O_loc_t root_oloc; /*root object location */ - H5G_name_t root_path; /*root group hier. path */ - - /* Set up root location to fill in */ - root_loc.oloc = &root_oloc; - root_loc.path = &root_path; - H5G_loc_reset(&root_loc); - /* Read the superblock if it hasn't been read before. */ - if(H5F_super_read(file, dxpl_id, &root_loc) < 0) + if(H5F_super_read(file, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") /* Open the root group */ - if(H5G_mkroot(file, dxpl_id, &root_loc) < 0) + if(H5G_mkroot(file, dxpl_id, FALSE) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group") } /* end if */ diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 4080705..49af73e 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -158,7 +158,8 @@ typedef struct H5F_file_t { int ncwfs; /* Num entries on cwfs list */ struct H5HG_heap_t **cwfs; /* Global heap cache */ struct H5G_t *root_grp; /* Open root group */ - H5G_entry_t *root_ent; /* Root group symbol table entry */ + H5G_entry_t *root_ent; /* Root group symbol table entry */ + haddr_t root_addr; /* Root group address */ H5FO_t *open_objs; /* Open objects in file */ H5RC_t *grp_btree_shared; /* Ref-counted group B-tree node info */ @@ -225,7 +226,7 @@ H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nop /* Superblock related routines */ H5_DLL herr_t H5F_super_init(H5F_t *f, hid_t dxpl_id); H5_DLL herr_t H5F_super_write(H5F_t *f, hid_t dxpl_id); -H5_DLL herr_t H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc); +H5_DLL herr_t H5F_super_read(H5F_t *f, hid_t dxpl_id); H5_DLL herr_t H5F_super_ext_size(H5F_t *f, hid_t dxpl_id, hsize_t *super_ext_info); /* Metadata accumulator routines */ @@ -247,6 +248,7 @@ H5_DLL herr_t H5F_sfile_remove(H5F_file_t *shared); #ifdef H5F_TESTING H5_DLL herr_t H5F_get_sohm_mesg_count_test(hid_t fid, unsigned type_id, size_t *mesg_count); +H5_DLL herr_t H5F_check_cached_stab_test(hid_t file_id); #endif /* H5F_TESTING */ #endif /* _H5Fpkg_H */ diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c index 8040554..32541ae 100644 --- a/src/H5Fsuper.c +++ b/src/H5Fsuper.c @@ -32,6 +32,7 @@ #include "H5FDprivate.h" /* File drivers */ #include "H5Iprivate.h" /* IDs */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ #include "H5SMprivate.h" /* Shared Object Header Messages */ @@ -230,7 +231,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) +H5F_super_read(H5F_t *f, hid_t dxpl_id) { uint8_t sbuf[H5F_MAX_SUPERBLOCK_SIZE]; /* Buffer for superblock */ H5P_genplist_t *c_plist; /* File creation property list */ @@ -383,8 +384,9 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) 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*/, - &shared->root_ent/*out*/) < 0) + + /* Decode the symbol table entry */ + if(H5G_root_ent_decode(f, (const uint8_t **)&p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root symbol entry") /* @@ -468,7 +470,6 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) } /* end if */ } /* end if */ else { - haddr_t root_addr; /* Address of root group */ uint32_t computed_chksum; /* Computed checksum */ uint32_t read_chksum; /* Checksum read from file */ @@ -499,7 +500,7 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) 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*/); + H5F_addr_decode(f, (const uint8_t **)&p, &shared->root_addr/*out*/); /* Compute checksum for superblock */ computed_chksum = H5_checksum_metadata(sbuf, (size_t)(p - sbuf), 0); @@ -511,11 +512,6 @@ H5F_super_read(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc) if(read_chksum != computed_chksum) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "bad checksum on driver information block") - /* 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. @@ -930,7 +926,9 @@ H5F_super_write(H5F_t *f, hid_t dxpl_id) rel_eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_SUPER); H5F_addr_encode(f, &p, (rel_eoa + f->shared->base_addr)); H5F_addr_encode(f, &p, f->shared->driver_addr); - if(H5G_obj_ent_encode(f, &p, H5G_oloc(f->shared->root_grp)) < 0) + + /* Encode the root group object entry, including the cached stab info */ + if(H5G_root_ent_encode(f, &p) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode root group information") /* Encode the driver information block. */ diff --git a/src/H5Ftest.c b/src/H5Ftest.c index 1d7e514..8cbc133 100644 --- a/src/H5Ftest.c +++ b/src/H5Ftest.c @@ -32,6 +32,8 @@ #define H5F_TESTING /*suppress warning about H5F testing funcs*/ #define H5SM_PACKAGE /*suppress error about including H5SMpkg */ #define H5SM_TESTING /*suppress warning about H5SM testing funcs*/ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ +#define H5G_TESTING /*suppress warning about H5G testing funcs*/ /***********/ @@ -40,6 +42,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ +#include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5SMpkg.h" /* Shared object header messages */ @@ -113,3 +116,40 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_get_sohm_mesg_count_test() */ + +/*------------------------------------------------------------------------- + * Function: H5F_check_cached_stab_test + * + * Purpose: Check that a file's superblock contains a cached symbol + * table entry, that the entry matches that in the root + * group's object header, and check that the addresses are + * valid. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Mar 31, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_check_cached_stab_test(hid_t file_id) +{ + H5F_t *file; /* File info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_check_cached_stab_test) + + /* Check arguments */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + + /* Verify the cached stab info */ + if(H5G_verify_cached_stab_test(H5G_oloc(file->shared->root_grp), file->shared->root_ent) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to verify cached symbol table info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_check_cached_stab_test() */ + @@ -817,141 +817,6 @@ H5G_term_interface(void) /*------------------------------------------------------------------------- - * Function: H5G_mkroot - * - * Purpose: Creates a root group in an empty file and opens it. If a - * root group is already open then this function immediately - * returns. If ENT is non-null then it's the symbol table - * entry for an existing group which will be opened as the root - * group. Otherwise a new root group is created and then - * opened. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 11 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc) -{ - H5O_loc_t new_root_oloc; /* New root object location */ - H5G_name_t new_root_path; /* New root path */ - H5G_loc_t new_root_loc; /* New root location information */ - H5G_loc_t root_loc; /* Root location information */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_mkroot, FAIL) - - /* check args */ - HDassert(f); - - /* Check if the root group is already initialized */ - if(f->shared->root_grp) - HGOTO_DONE(SUCCEED) - - /* Create information needed for group nodes */ - if(H5G_node_init(f) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info") - - /* - * If there is no root object then create one. The root group always starts - * with a hard link count of one since it's pointed to by the superblock. - */ - if(loc == NULL) { - H5P_genplist_t *fc_plist; /* File creation property list */ - H5O_ginfo_t ginfo; /* Group info parameters */ - H5O_linfo_t linfo; /* Link info parameters */ - - /* Get the file creation property list */ - /* (Which is a sub-class of the group creation property class) */ - if(NULL == (fc_plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - /* Get the group info property */ - if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info") - - /* Get the link info property */ - if(H5P_get(fc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") - - /* Set up group location for root group */ - new_root_loc.oloc = &new_root_oloc; - new_root_loc.path = &new_root_path; - H5G_loc_reset(&new_root_loc); - loc = &new_root_loc; - - /* Create root group */ - if(H5G_obj_create(f, dxpl_id, &ginfo, &linfo, f->shared->fcpl_id, loc->oloc/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") - if(1 != H5O_link(loc->oloc, 1, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)") - } /* end if */ - else { - /* - * Open the root object as a group. - */ - if(H5O_open(loc->oloc) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group") - -#ifndef H5_STRICT_FORMAT_CHECKS - /* If symbol table information is cached, check if we should replace the - * symbol table message with the cached symbol table information */ - if((H5F_INTENT(f) & H5F_ACC_RDWR) && f->shared->root_ent - && (f->shared->root_ent->type == H5G_CACHED_STAB)) { - H5O_stab_t cached_stab; - - /* Retrieve the cached symbol table information */ - cached_stab.btree_addr = f->shared->root_ent->cache.stab.btree_addr; - cached_stab.heap_addr = f->shared->root_ent->cache.stab.heap_addr; - - /* Check if the symbol table message is valid, and replace with the - * cached symbol table if necessary */ - if(H5G_stab_valid(loc->oloc, dxpl_id, &cached_stab) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to verify symbol table") - } /* end if */ -#endif /* H5_STRICT_FORMAT_CHECKS */ - } /* end else */ - - /* Create the path names for the root group's entry */ - H5G_name_init(loc->path, "/"); - - /* - * Create the group pointer. Also decrement the open object count so we - * don't count the root group as an open object. The root group will - * never be closed. - */ - if(NULL == (f->shared->root_grp = H5FL_CALLOC(H5G_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - if(NULL == (f->shared->root_grp->shared = H5FL_CALLOC(H5G_shared_t))) { - (void)H5FL_FREE(H5G_t, f->shared->root_grp); - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - } /* end if */ - - /* Shallow copy (take ownership) of the group object info */ - root_loc.oloc = &(f->shared->root_grp->oloc); - root_loc.path = &(f->shared->root_grp->path); - if(H5G_loc_copy(&root_loc, loc, H5_COPY_SHALLOW) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy group object location") - - f->shared->root_grp->shared->fo_count = 1; - /* The only other open object should be the superblock extension, if it - * exists. Don't count either the superblock extension or the root group - * in the number of open objects in the file. - */ - HDassert((1 == f->nopen_objs) || - (2 == f->nopen_objs && HADDR_UNDEF != f->shared->extension_addr)); - f->nopen_objs--; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_mkroot() */ - - -/*------------------------------------------------------------------------- * Function: H5G_create * * Purpose: Creates a new empty group with the specified name. The name @@ -1351,36 +1216,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_rootof - * - * Purpose: Return a pointer to the root group of the file. If the file - * is part of a virtual file then the root group of the virtual - * file is returned. - * - * Return: Success: Ptr to the root group of the file. Do not - * free the pointer -- it points directly into - * the file struct. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Tuesday, October 13, 1998 - * - *------------------------------------------------------------------------- - */ -H5G_t * -H5G_rootof(H5F_t *f) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof) - - while(f->parent) - f = f->parent; - - FUNC_LEAVE_NOAPI(f->shared->root_grp) -} /* end H5G_rootof() */ - - -/*------------------------------------------------------------------------- * Function: H5G_oloc * * Purpose: Returns a pointer to the object location for a group. diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 2eb1924..08a9268 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -221,115 +221,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_obj_ent_decode - * - * Purpose: Decodes a symbol table entry into a object location - * - * Return: Success: Non-negative with *pp pointing to the first byte - * following the symbol table entry. - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Sep 26 2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp, H5O_loc_t *oloc, H5G_entry_t **entp) -{ - const uint8_t *p_ret = *pp; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_obj_ent_decode, FAIL) - - /* check arguments */ - HDassert(f); - HDassert(pp); - HDassert(oloc); - - if(entp) { - /* If entp is not NULL we allocate space for the symbol table entry and - * decode the entire entry. */ - if(!(*entp)) /* Only allocate space if *entp is NULL */ - if(NULL == (*entp = (H5G_entry_t *) H5MM_calloc(sizeof(H5G_entry_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry") - if(H5G_ent_decode_vec(f, pp, *entp, 1) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode symbol table entry") - - /* Set oloc to the correct values */ - oloc->file = (*entp)->file; - oloc->addr = (*entp)->header; - } else { - /* Set file pointer for root object location */ - oloc->file = f; - - /* decode header */ - *pp += H5F_SIZEOF_SIZE(f); /* Skip over local heap address */ - H5F_addr_decode(f, pp, &(oloc->addr)); - *pp += 4; /* Skip over "cache type" */ - *pp += 4; /* Reserved */ - } - - /* Common oloc settings */ - oloc->holding_file = FALSE; - - /* Set decode pointer */ - *pp = p_ret + H5G_SIZEOF_ENTRY(f); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_obj_ent_decode() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_obj_ent_encode - * - * Purpose: Encodes the specified object location into a symbol table - * entry in the buffer pointed to by *pp. - * - * Return: Success: Non-negative, with *pp pointing to the first byte - * after the symbol table entry. - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Sep 26 2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp, const H5O_loc_t *oloc) -{ - uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f); - - FUNC_ENTER_NOAPI_NOFUNC(H5G_obj_ent_encode) - - /* check arguments */ - HDassert(f); - HDassert(pp); - - /* encode header */ - H5F_ENCODE_LENGTH(f, *pp, 0); /* No name for root group */ - if(oloc) - H5F_addr_encode(f, pp, oloc->addr); - else - H5F_addr_encode(f, pp, HADDR_UNDEF); - UINT32ENCODE(*pp, H5G_NOTHING_CACHED); - UINT32ENCODE(*pp, 0); /*reserved*/ - - /* fill with zero */ - while(*pp < p_ret) - *(*pp)++ = 0; - *pp = p_ret; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5G_obj_ent_encode() */ - - -/*------------------------------------------------------------------------- * Function: H5G_obj_get_linfo * * Purpose: Retrieves the "link info" message for an object. Also diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 38c7628..0840ee7 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -340,6 +340,12 @@ H5_DLLVAR const H5B2_class_t H5G_BT2_NAME[1]; /* The v2 B-tree class for indexing 'creation order' field on links */ H5_DLLVAR const H5B2_class_t H5G_BT2_CORDER[1]; +/* Free list for managing H5G_t structs */ +H5FL_EXTERN(H5G_t); + +/* Free list for managing H5G_shared_t structs */ +H5FL_EXTERN(H5G_shared_t); + /******************************/ /* Package Private Prototypes */ /******************************/ @@ -565,6 +571,7 @@ H5_DLL htri_t H5G_is_new_dense_test(hid_t gid); H5_DLL herr_t H5G_new_dense_info_test(hid_t gid, hsize_t *name_count, hsize_t *corder_count); H5_DLL herr_t H5G_lheap_size_test(hid_t gid, size_t *lheap_size); H5_DLL herr_t H5G_user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsigned *user_path_hidden); +H5_DLL herr_t H5G_verify_cached_stab_test(H5O_loc_t *grp_oloc, H5G_entry_t *ent); #endif /* H5G_TESTING */ #endif /* _H5Gpkg_H */ diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index b1db96f..7f001e0 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -151,7 +151,7 @@ typedef struct H5G_entry_t H5G_entry_t; * Library prototypes... These are the ones that other packages routinely * call. */ -H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc); +H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root); H5_DLL struct H5O_loc_t *H5G_oloc(H5G_t *grp); H5_DLL H5G_t *H5G_rootof(H5F_t *f); H5_DLL H5G_name_t * H5G_nameof(H5G_t *grp); @@ -181,10 +181,8 @@ H5_DLL herr_t H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream /* * These functions operate on group object locations. */ -H5_DLL herr_t H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp, - struct H5O_loc_t *oloc, H5G_entry_t **entp); -H5_DLL herr_t H5G_obj_ent_encode(const H5F_t *f, uint8_t **pp, - const struct H5O_loc_t *oloc); +H5_DLL herr_t H5G_root_ent_decode(H5F_t *f, const uint8_t **pp); +H5_DLL herr_t H5G_root_ent_encode(H5F_t *f, uint8_t **pp); /* * These functions operate on group hierarchy names. diff --git a/src/H5Groot.c b/src/H5Groot.c new file mode 100644 index 0000000..4c7c357 --- /dev/null +++ b/src/H5Groot.c @@ -0,0 +1,344 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + /*------------------------------------------------------------------------- + * + * Created: H5Gobj.c + * Apr 8 2009 + * Neil Fortner <nfortne2@hdfgroup.org> + * + * Purpose: Functions for operating on the root group. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5Gpkg.h" /* Groups */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property Lists */ + + + +/*------------------------------------------------------------------------- + * Function: H5G_rootof + * + * Purpose: Return a pointer to the root group of the file. If the file + * is part of a virtual file then the root group of the virtual + * file is returned. + * + * Return: Success: Ptr to the root group of the file. Do not + * free the pointer -- it points directly into + * the file struct. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Tuesday, October 13, 1998 + * + *------------------------------------------------------------------------- + */ +H5G_t * +H5G_rootof(H5F_t *f) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof) + + while(f->parent) + f = f->parent; + + FUNC_LEAVE_NOAPI(f->shared->root_grp) +} /* end H5G_rootof() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_root_ent_decode + * + * Purpose: Decodes the root group symbol table entry into the file + * structure, and updates the root group address in the file + * structure. + * + * Return: Success: Non-negative with *pp pointing to the first byte + * following the symbol table entry. + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 26 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_root_ent_decode(H5F_t *f, const uint8_t **pp) +{ + const uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f); + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_root_ent_decode, FAIL) + + /* check arguments */ + HDassert(f); + HDassert(pp); + + /* Allocate space for the root group symbol table entry */ + HDassert(!f->shared->root_ent); + if(NULL == (f->shared->root_ent = (H5G_entry_t *) H5MM_calloc(sizeof(H5G_entry_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry") + + /* decode the root group symbol table entry */ + if(H5G_ent_decode_vec(f, pp, f->shared->root_ent, 1) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDECODE, FAIL, "can't decode symbol table entry") + + /* Set the root group address to the correct value */ + f->shared->root_addr = f->shared->root_ent->header; + + /* Set decode pointer */ + *pp = p_ret; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_root_ent_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_root_ent_encode + * + * Purpose: Encodes the root group symbol table entry into the buffer + * pointed to by *pp. + * + * Return: Success: Non-negative, with *pp pointing to the first byte + * after the symbol table entry. + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Sep 26 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_root_ent_encode(H5F_t *f, uint8_t **pp) +{ + uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f); + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_root_ent_encode, FAIL) + + /* check arguments */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->root_ent); + HDassert(pp); + + /* Encode entry */ + if(H5G_ent_encode_vec(f, pp, f->shared->root_ent, 1) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't encode symbol table entry") + + /* Set encode pointer */ + *pp = p_ret; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_root_ent_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_mkroot + * + * Purpose: Creates a root group in an empty file and opens it. If a + * root group is already open then this function immediately + * returns. If ENT is non-null then it's the symbol table + * entry for an existing group which will be opened as the root + * group. Otherwise a new root group is created and then + * opened. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 11 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_mkroot(H5F_t *f, hid_t dxpl_id, hbool_t create_root) +{ + H5G_loc_t root_loc; /* Root location information */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_mkroot, FAIL) + + /* check args */ + HDassert(f); + + /* Check if the root group is already initialized */ + if(f->shared->root_grp) + HGOTO_DONE(SUCCEED) + + /* Create information needed for group nodes */ + if(H5G_node_init(f) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info") + + /* + * Create the group pointer + */ + if(NULL == (f->shared->root_grp = H5FL_CALLOC(H5G_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + if(NULL == (f->shared->root_grp->shared = H5FL_CALLOC(H5G_shared_t))) { + (void)H5FL_FREE(H5G_t, f->shared->root_grp); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + } /* end if */ + + /* Initialize the root_loc structure to point to fields in the newly created + * f->shared->root_grp structure */ + root_loc.oloc = &(f->shared->root_grp->oloc); + root_loc.path = &(f->shared->root_grp->path); + H5G_loc_reset(&root_loc); + + /* + * If there is no root object then create one. The root group always starts + * with a hard link count of one since it's pointed to by the superblock. + */ + if(create_root) { + H5P_genplist_t *fc_plist; /* File creation property list */ + H5O_ginfo_t ginfo; /* Group info parameters */ + H5O_linfo_t linfo; /* Link info parameters */ + unsigned super_vers; /* Superblock version */ + + /* Get the file creation property list */ + /* (Which is a sub-class of the group creation property class) */ + if(NULL == (fc_plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Get the group info property */ + if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info") + + /* Get the link info property */ + if(H5P_get(fc_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get link info") + + /* Get the superblock version */ + if(H5P_get(fc_plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get superblock version") + + /* Create root group */ + if(H5G_obj_create(f, dxpl_id, &ginfo, &linfo, f->shared->fcpl_id, root_loc.oloc/*out*/) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") + if(1 != H5O_link(root_loc.oloc, 1, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)") + + /* Create the root group symbol table entry */ + HDassert(!f->shared->root_ent); + if(super_vers < HDF5_SUPERBLOCK_VERSION_2) { + /* Allocate space for the root group symbol table entry */ + if(NULL == (f->shared->root_ent = (H5G_entry_t *) H5MM_calloc(sizeof(H5G_entry_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate space for symbol table entry") + + /* Initialize the root group symbol table entry */ + f->shared->root_ent->dirty = TRUE; + f->shared->root_ent->type = H5G_NOTHING_CACHED; /* We will cache the stab later */ + f->shared->root_ent->name_off = 0; /* No name (yet) */ + f->shared->root_ent->header = root_loc.oloc->addr; + f->shared->root_ent->file = root_loc.oloc->file; + } /* end if */ + } /* end if */ + else { + /* Create root group object location from f */ + root_loc.oloc->addr = f->shared->root_addr; + root_loc.oloc->file = f; + + /* + * Open the root object as a group. + */ + if(H5O_open(root_loc.oloc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group") + +#ifndef H5_STRICT_FORMAT_CHECKS + /* If symbol table information is cached, check if we should replace the + * symbol table message with the cached symbol table information */ + if((H5F_INTENT(f) & H5F_ACC_RDWR) && f->shared->root_ent + && (f->shared->root_ent->type == H5G_CACHED_STAB)) { + H5O_stab_t cached_stab; + + /* Retrieve the cached symbol table information */ + cached_stab.btree_addr = f->shared->root_ent->cache.stab.btree_addr; + cached_stab.heap_addr = f->shared->root_ent->cache.stab.heap_addr; + + /* Check if the symbol table message is valid, and replace with the + * cached symbol table if necessary */ + if(H5G_stab_valid(root_loc.oloc, dxpl_id, &cached_stab) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to verify symbol table") + } /* end if */ +#endif /* H5_STRICT_FORMAT_CHECKS */ + } /* end else */ + + /* Cache the root group's symbol table information in the root group symbol + * table entry. It will have been allocated by now if it needs to be + * present, so we don't need to check the superblock version. We do this if + * we have write access, the root entry has been allocated (i.e. + * super_vers < 2) and the stab info is not already cached. */ + if((H5F_INTENT(f) & H5F_ACC_RDWR) && f->shared->root_ent + && f->shared->root_ent->type != H5G_CACHED_STAB) { + htri_t stab_exists; /* Whether the symbol table exists */ + H5O_stab_t stab; /* Symbol table */ + + /* Check if the stab message exists. It's possible for the root group + * to use the latest version while the superblock is an old version. */ + if((stab_exists = H5O_msg_exists(root_loc.oloc, H5O_STAB_ID, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't check if symbol table message exists") + + if(stab_exists) { + /* Read the root group's symbol table message */ + if(NULL == H5O_msg_read(root_loc.oloc, H5O_STAB_ID, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message") + + /* Update the root group symbol table entry */ + f->shared->root_ent->type = H5G_CACHED_STAB; + f->shared->root_ent->cache.stab.btree_addr = stab.btree_addr; + f->shared->root_ent->cache.stab.heap_addr = stab.heap_addr; + } /* end if */ + } /* end if */ + + /* Create the path names for the root group's entry */ + H5G_name_init(root_loc.path, "/"); + + f->shared->root_grp->shared->fo_count = 1; + /* The only other open object should be the superblock extension, if it + * exists. Don't count either the superblock extension or the root group + * in the number of open objects in the file. + */ + HDassert((1 == f->nopen_objs) || + (2 == f->nopen_objs && HADDR_UNDEF != f->shared->extension_addr)); + f->nopen_objs--; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_mkroot() */ + diff --git a/src/H5Gtest.c b/src/H5Gtest.c index 1f09048..f3508eb 100644 --- a/src/H5Gtest.c +++ b/src/H5Gtest.c @@ -550,3 +550,59 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5G_user_path_test() */ + +/*------------------------------------------------------------------------- + * Function: H5G_verify_cached_stab_test + * + * Purpose: Check that a that the provided group entry contains a + * cached symbol table entry, that the entry matches that in + * the provided group's object header, and check that the + * addresses are valid. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Neil Fortner + * Mar 31, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_verify_cached_stab_test(H5O_loc_t *grp_oloc, H5G_entry_t *ent) +{ + H5O_stab_t stab; /* Symbol table */ + H5HL_t *heap = NULL; /* Pointer to local heap */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_verify_cached_stab_test) + + /* Verify that stab info is cached in ent */ + if(ent->type != H5G_CACHED_STAB) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "symbol table information is not cached") + + /* Read the symbol table message from the group */ + if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, H5AC_ind_dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message") + + /* Verify that the cached symbol table info matches the symbol table message + * in the object header */ + if((ent->cache.stab.btree_addr != stab.btree_addr) + || (ent->cache.stab.heap_addr != stab.heap_addr)) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "cached stab info does not match object header") + + /* Verify that the btree address is valid */ + if(H5B_valid(grp_oloc->file, H5AC_ind_dxpl_id, H5B_SNODE, stab.btree_addr) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "b-tree address is invalid") + + /* Verify that the heap address is valid */ + if(NULL == (heap = H5HL_protect(grp_oloc->file, H5AC_ind_dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "heap address is invalid") + +done: + /* Release resources */ + if(heap && H5HL_unprotect(grp_oloc->file, H5AC_ind_dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_verify_cached_stab_test() */ + diff --git a/src/Makefile.am b/src/Makefile.am index 9ae2252..99a0e72 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,7 +62,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5G.c H5Gbtree2.c H5Gcache.c \ H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \ H5Gint.c H5Glink.c \ - H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c \ + H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Groot.c H5Gstab.c H5Gtest.c \ H5Gtraverse.c \ H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 9dc8180..ecf06c2 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -97,9 +97,9 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5FScache.lo H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo \ H5G.lo H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \ - H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo \ - H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo \ - H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \ + H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Groot.lo H5Gstab.lo \ + H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo \ + H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \ H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \ H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \ H5HGcache.lo H5HGdbg.lo H5HL.lo H5HLcache.lo H5HLdbg.lo \ @@ -446,7 +446,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5G.c H5Gbtree2.c H5Gcache.c \ H5Gcompact.c H5Gdense.c H5Gdeprec.c H5Gent.c \ H5Gint.c H5Glink.c \ - H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c \ + H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c H5Goh.c H5Groot.c H5Gstab.c H5Gtest.c \ H5Gtraverse.c \ H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \ @@ -711,6 +711,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gnode.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gobj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Goh.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Groot.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gstab.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gtest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gtraverse.Plo@am__quote@ diff --git a/test/family_v16_00000.h5 b/test/family_v16_00000.h5 Binary files differindex bf1a711..5b69c93 100644 --- a/test/family_v16_00000.h5 +++ b/test/family_v16_00000.h5 diff --git a/test/objcopy.c b/test/objcopy.c index c2d71c0..4bd4662 100755 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -7451,6 +7451,10 @@ main(void) hid_t fcpl_src; hid_t fcpl_dst; + /* No need to test dense attributes with old format */ + if(!(configuration & CONFIG_NEW_FORMAT) && (configuration & CONFIG_DENSE)) + continue; + /* Test with and without shared messages */ if(configuration & CONFIG_SHARE_SRC) { puts("\nTesting with shared src messages:"); @@ -7473,22 +7477,23 @@ main(void) if(configuration & CONFIG_NEW_FORMAT) { puts("Testing with new group format:"); my_fapl = fapl2; + + /* Test with and without dense attributes */ + if(configuration & CONFIG_DENSE) { + puts("Testing with dense attributes:"); + num_attributes_g = max_compact + 1; + } + else { + puts("Testing without dense attributes:"); + num_attributes_g = MAX(min_dense, 2) - 1; + } } /* end if */ else { puts("Testing with old group format:"); my_fapl = fapl; + num_attributes_g = 4; } /* end else */ - /* Test with and without dense attributes */ - if(configuration & CONFIG_DENSE) { - puts("Testing with dense attributes:"); - num_attributes_g = max_compact + 1; - } - else { - puts("Testing without dense attributes:"); - num_attributes_g = MAX(min_dense, 2) - 1; - } - /* The tests... */ nerrors += test_copy_dataset_simple(fcpl_src, fcpl_dst, my_fapl); nerrors += test_copy_dataset_simple_samefile(fcpl_src, my_fapl); diff --git a/test/tfile.c b/test/tfile.c index 724ad4a..68c7f6b 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -27,6 +27,14 @@ #include "H5Bprivate.h" #include "H5Pprivate.h" +/* + * This file needs to access private information from the H5F package. + * This file also needs to access the file testing code. + */ +#define H5F_PACKAGE +#define H5F_TESTING +#include "H5Fpkg.h" /* File access */ + #define F1_USERBLOCK_SIZE (hsize_t)0 #define F1_OFFSET_SIZE sizeof(haddr_t) #define F1_LENGTH_SIZE sizeof(hsize_t) @@ -1931,9 +1939,9 @@ test_userblock_file_size(void) /* Reopen files */ file1_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Fopen"); + CHECK(file1_id, FAIL, "H5Fopen"); file2_id = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Fopen"); + CHECK(file2_id, FAIL, "H5Fopen"); /* Check file sizes */ ret = H5Fget_filesize(file1_id, &filesize1); @@ -1952,9 +1960,9 @@ test_userblock_file_size(void) /* Reopen files */ file1_id = H5Fopen(FILE1, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Fopen"); + CHECK(file1_id, FAIL, "H5Fopen"); file2_id = H5Fopen(FILE2, H5F_ACC_RDWR, H5P_DEFAULT); - CHECK(ret, FAIL, "H5Fopen"); + CHECK(file2_id, FAIL, "H5Fopen"); /* Verify file sizes did not change */ ret = H5Fget_filesize(file1_id, &filesize); @@ -1973,6 +1981,52 @@ test_userblock_file_size(void) /**************************************************************** ** +** test_cached_stab_info(): low-level file test routine. +** This test checks that new files are created with cached +** symbol table information in the superblock (when using +** the old format). This is necessary to ensure backwards +** compatibility with versions from 1.3.0 to 1.6.3. +** +*****************************************************************/ +static void +test_cached_stab_info(void) +{ + hid_t file_id; + hid_t group_id; + herr_t ret; /* Generic return value */ + + /* Output message about test being performed */ + MESSAGE(5, ("Testing cached symbol table information\n")); + + /* Create file */ + file_id = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(file_id, FAIL, "H5Fcreate"); + + /* Create group */ + group_id = H5Gcreate2(file_id, GROUP1, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + CHECK(group_id, FAIL, "H5Gcreate2"); + + /* Close file and group */ + ret = H5Gclose(group_id); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Fclose(file_id); + CHECK(ret, FAIL, "H5Fclose"); + + /* Reopen file */ + file_id = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK(ret, FAIL, "H5Fopen"); + + /* Verify the cached symbol table information */ + ret = H5F_check_cached_stab_test(file_id); + CHECK(ret, FAIL, "H5F_check_cached_stab_test"); + + /* Close file */ + ret = H5Fclose(file_id); + CHECK(ret, FAIL, "H5Fclose"); +} /* end test_cached_stab_info() */ + +/**************************************************************** +** ** test_file(): Main low-level file I/O test routine. ** ****************************************************************/ @@ -2002,7 +2056,8 @@ test_file(void) test_file_double_dataset_open(); /* Test opening same dataset from two files works properly */ test_file_double_datatype_open(); /* Test opening same named datatype from two files works properly */ #endif /*H5_CANNOT_OPEN_TWICE*/ - test_userblock_file_size(); /* Tests that files created with a userblock have the correct size */ + test_userblock_file_size(); /* Tests that files created with a userblock have the correct size */ + test_cached_stab_info(); /* Tests that files are created with cached stab info in the superblock */ } /* test_file() */ |