mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-01-18 15:15:56 +08:00
[svn-r7473] Purpose:
Code cleanup & optimization Description: Split superblock initialization and space allocation out from writing the superblock information to disk, which makes the code much cleaner and easier to understand and also allows FPHDF5 to have a fully completed superblock to Bcast to other (non-caption) processes. Platforms tested: FreeBSD 4.9 (sleipnir) too minor to require h5committest
This commit is contained in:
parent
fb44f88bc6
commit
26ebe5876b
189
src/H5F.c
189
src/H5F.c
@ -81,8 +81,9 @@ static herr_t H5F_flush_all(hbool_t invalidate);
|
||||
static int H5F_flush_all_cb(void *f, hid_t fid, void *_invalidate);
|
||||
#endif /* NOT_YET */
|
||||
|
||||
static herr_t H5F_init_superblock(H5F_t *f, hid_t dxpl_id);
|
||||
static herr_t H5F_write_superblock(H5F_t *f, hid_t dxpl_id, uint8_t *buf);
|
||||
static herr_t H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_entry_t *root_ent, haddr_t addr, uint8_t *buf);
|
||||
static herr_t H5F_write_superblock(H5F_t *f, hid_t dxpl_id, unsigned alloc, uint8_t *buf);
|
||||
|
||||
static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id);
|
||||
static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id);
|
||||
@ -1792,8 +1793,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
|
||||
unsigned tent_flags; /*tentative flags */
|
||||
H5FD_class_t *drvr; /*file driver class info */
|
||||
hbool_t driver_has_cmp; /*`cmp' callback defined? */
|
||||
hsize_t userblock_size = 0;
|
||||
H5P_genplist_t *c_plist; /*file creation property list */
|
||||
H5P_genplist_t *a_plist; /*file access property list */
|
||||
H5F_close_degree_t fc_degree; /*file close degree */
|
||||
H5F_t *ret_value = NULL; /*actual return value */
|
||||
@ -1914,10 +1913,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
|
||||
file->intent = flags;
|
||||
file->name = H5MM_xstrdup(name);
|
||||
|
||||
/* Get the shared file creation property list */
|
||||
if(NULL == (c_plist = H5I_object(shared->fcpl_id)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get property list")
|
||||
|
||||
/*
|
||||
* Read or write the file superblock, depending on whether the file is
|
||||
* empty or not.
|
||||
@ -1925,32 +1920,41 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
|
||||
if (0==H5FD_get_eof(lf) && (flags & H5F_ACC_RDWR)) {
|
||||
/*
|
||||
* We've just opened a fresh new file (or truncated one). We need
|
||||
* to write the superblock.
|
||||
*
|
||||
* The superblock starts immediately after the user-defined
|
||||
* header, which we have already insured is a proper size. The
|
||||
* base address is set to the same thing as the superblock for
|
||||
* now.
|
||||
*/
|
||||
if(H5P_get(c_plist, H5F_CRT_USER_BLOCK_NAME, &userblock_size) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get user block size")
|
||||
shared->super_addr = userblock_size;
|
||||
shared->base_addr = shared->super_addr;
|
||||
shared->consist_flags = 0x03;
|
||||
|
||||
* to create & write the superblock.
|
||||
*/
|
||||
#ifdef H5_HAVE_FPHDF5
|
||||
/* Non-captn procs get bcast from capt. Call read_superblock with
|
||||
* that buffer. Then call mkroot with root_ent pointer. Capt does
|
||||
* just the mkroot call with NULL. Capt should do the mkroot
|
||||
* first. Then bcast, then the rest can call it. */
|
||||
/*
|
||||
* Psuedo-code for FPHDF5 should be something like this:
|
||||
* if(captn) {
|
||||
* H5F_init_superblock(...)
|
||||
* H5G_mkroot(...,NULL)
|
||||
* H5F_write_superblock(...,buf)
|
||||
* }
|
||||
* MPI_Bcast(...,captn,buf,...)
|
||||
* if(!captn) {
|
||||
* H5F_read_superblock(...,HADDR_UNDEF,buf)
|
||||
* H5G_mkroot(...,&root_ret)
|
||||
* }
|
||||
*/
|
||||
#endif /* H5_HAVE_FPHDF5 */
|
||||
|
||||
if (H5F_write_superblock(file, dxpl_id, TRUE, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to write file superblock")
|
||||
/* Initialize information about the superblock and allocate space for it */
|
||||
if (H5F_init_superblock(file, dxpl_id) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to allocate file superblock")
|
||||
|
||||
/* Create and open the root group */
|
||||
/* (This must be after the space for the superblock is allocated in
|
||||
* the file)
|
||||
*/
|
||||
if (H5G_mkroot(file, dxpl_id, NULL)<0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group")
|
||||
|
||||
/* Write the superblock to the file */
|
||||
/* (This must be after the root group is created, since the root
|
||||
* group's symbol table entry is part of the superblock)
|
||||
*/
|
||||
if (H5F_write_superblock(file, dxpl_id, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to write file superblock")
|
||||
} else if (1 == shared->nrefs) {
|
||||
/* Read the superblock if it hasn't been read before. */
|
||||
if (HADDR_UNDEF == (shared->super_addr = H5F_locate_signature(lf,dxpl_id)))
|
||||
@ -2581,12 +2585,107 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_init_superblock
|
||||
*
|
||||
* Purpose: Allocates the superblock for the file and initializes
|
||||
* information about the superblock in memory. Does not write
|
||||
* any superblock information to the file.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@ncsa.uiuc.edu
|
||||
* Sept 15, 2003
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_init_superblock(H5F_t *f, hid_t dxpl_id)
|
||||
{
|
||||
hsize_t userblock_size = 0; /* Size of userblock, in bytes */
|
||||
size_t superblock_size; /* Size of superblock, in bytes */
|
||||
size_t driver_size; /* Size of driver info block (bytes)*/
|
||||
unsigned super_vers; /* Super block version */
|
||||
haddr_t addr; /* Address of superblock */
|
||||
H5P_genplist_t *plist; /* Property list */
|
||||
herr_t ret_value = SUCCEED;
|
||||
|
||||
/* Encoding */
|
||||
FUNC_ENTER_NOAPI(H5F_init_superblock, FAIL)
|
||||
|
||||
/* Get the shared file creation property list */
|
||||
if (NULL == (plist = H5I_object(f->shared->fcpl_id)))
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
|
||||
|
||||
/*
|
||||
* The superblock starts immediately after the user-defined
|
||||
* header, which we have already insured is a proper size. The
|
||||
* base address is set to the same thing as the superblock for
|
||||
* now.
|
||||
*/
|
||||
if(H5P_get(plist, H5F_CRT_USER_BLOCK_NAME, &userblock_size) < 0)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to get user block size")
|
||||
f->shared->super_addr = userblock_size;
|
||||
f->shared->base_addr = f->shared->super_addr;
|
||||
f->shared->consist_flags = 0x03;
|
||||
|
||||
/* Grab superblock version from property list */
|
||||
if (H5P_get(plist, H5F_CRT_SUPER_VERS_NAME, &super_vers) < 0)
|
||||
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "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 */
|
||||
+ H5G_SIZEOF_ENTRY(f); /* Size of root group symbol table entry */
|
||||
|
||||
/* Compute the size of 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 */
|
||||
|
||||
/*
|
||||
* Allocate space for the userblock, superblock, and driver info
|
||||
* block. We do it with one allocation request because the
|
||||
* userblock and superblock need to be at the beginning of the
|
||||
* file and only the first allocation request is required to
|
||||
* return memory at format address zero.
|
||||
*/
|
||||
|
||||
H5_CHECK_OVERFLOW(f->shared->base_addr, haddr_t, hsize_t);
|
||||
addr = H5FD_alloc(f->shared->lf, H5FD_MEM_SUPER, dxpl_id,
|
||||
((hsize_t)f->shared->base_addr + superblock_size + driver_size));
|
||||
|
||||
if (HADDR_UNDEF == addr)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL,
|
||||
"unable to allocate file space for userblock and/or superblock")
|
||||
|
||||
if (0 != addr)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL,
|
||||
"file driver failed to allocate userblock and/or superblock at address zero")
|
||||
|
||||
/*
|
||||
* The file driver information block begins immediately after the
|
||||
* superblock.
|
||||
*/
|
||||
if (driver_size > 0)
|
||||
f->shared->driver_addr = superblock_size;
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5F_init_superblock() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_write_superblock
|
||||
*
|
||||
* Purpose: Writes (and optionally allocates) the superblock for the
|
||||
* file. If ALLOC is TRUE, then it allocates the superblock.
|
||||
* 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.
|
||||
@ -2603,7 +2702,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_write_superblock(H5F_t *f, hid_t dxpl_id, unsigned alloc, uint8_t *buf)
|
||||
H5F_write_superblock(H5F_t *f, hid_t dxpl_id, uint8_t *buf)
|
||||
{
|
||||
uint8_t sbuf[H5F_SUPERBLOCK_SIZE]; /* Superblock encoding buffer */
|
||||
uint8_t dbuf[H5F_DRVINFOBLOCK_SIZE];/* Driver info block encoding buffer*/
|
||||
@ -2706,36 +2805,6 @@ H5F_write_superblock(H5F_t *f, hid_t dxpl_id, unsigned alloc, uint8_t *buf)
|
||||
HDmemcpy(dbuf + 8, driver_name, 8);
|
||||
} /* end if */
|
||||
|
||||
if (alloc) {
|
||||
/*
|
||||
* Allocate space for the userblock, superblock, and driver info
|
||||
* block. We do it with one allocation request because the
|
||||
* userblock and superblock need to be at the beginning of the
|
||||
* file and only the first allocation request is required to
|
||||
* return memory at format address zero.
|
||||
*/
|
||||
haddr_t addr;
|
||||
|
||||
H5_CHECK_OVERFLOW(f->shared->base_addr, haddr_t, hsize_t);
|
||||
addr = H5FD_alloc(f->shared->lf, H5FD_MEM_SUPER, dxpl_id,
|
||||
((hsize_t)f->shared->base_addr + superblock_size + driver_size));
|
||||
|
||||
if (HADDR_UNDEF == addr)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL,
|
||||
"unable to allocate file space for userblock and/or superblock")
|
||||
|
||||
if (0 != addr)
|
||||
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL,
|
||||
"file driver failed to allocate userblock and/or superblock at address zero")
|
||||
|
||||
/*
|
||||
* The file driver information block begins immediately after the
|
||||
* superblock.
|
||||
*/
|
||||
if (driver_size > 0)
|
||||
f->shared->driver_addr = superblock_size;
|
||||
}
|
||||
|
||||
/* Compute super block checksum */
|
||||
assert(sizeof(chksum) == sizeof(f->shared->super_chksum));
|
||||
|
||||
@ -2958,7 +3027,7 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush meta data cache")
|
||||
|
||||
/* Write the superblock to disk */
|
||||
if (H5F_write_superblock(f, dxpl_id, FALSE, NULL) != SUCCEED)
|
||||
if (H5F_write_superblock(f, dxpl_id, NULL) != SUCCEED)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_WRITEERROR, FAIL, "unable to superblock to file")
|
||||
|
||||
/* Flush file buffers to disk. */
|
||||
|
Loading…
Reference in New Issue
Block a user