From ea5f97cf8f38e5832656c2c44507cce3e548058f Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 20 Aug 2009 15:30:35 -0500 Subject: [svn-r17398] Description: First set of changes to move VFD 'truncate' call out of H5F_flush and defer it until the file is closed. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.8 (amazon) in debug mode Mac OS X/32 10.5.8 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode --- src/H5F.c | 29 +++++++++++++++------- src/H5FD.c | 20 +++------------ src/H5MF.c | 68 --------------------------------------------------- src/H5MFaggr.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/H5MFprivate.h | 2 +- 5 files changed, 95 insertions(+), 97 deletions(-) diff --git a/src/H5F.c b/src/H5F.c index 0f37c86..c8c062a 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -1083,10 +1083,18 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) /* Push error, but keep going*/ HDONE_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't close property list") - /* Close low-level file */ + /* Only truncate the file on an orderly close, with write-access */ + if(f->closing && (H5F_ACC_RDWR & f->shared->flags)) { + /* Truncate the file to the current allocated size */ + if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed") + } /* end if */ + + /* Close the file */ if(H5FD_close(f->shared->lf) < 0) /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") /* Free mount table */ f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child); @@ -1674,13 +1682,16 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags) if(H5MF_close(f, dxpl_id) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") } /* end if */ - - /* Truncate the file to the current allocated size */ - /* (needs to happen before superblock write, since the 'eoa' value is - * written in superblock -QAK) - */ - if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)((flags & H5F_FLUSH_CLOSING) > 0)) < 0) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level truncate failed") + else { + /* Release any space allocated to space aggregators, so that the eoa value + * corresponds to the end of the space written to in the file. + */ + /* (needs to happen before superblock write, since the 'eoa' value is + * written in superblock -QAK) + */ + if(H5MF_free_aggrs(f, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") + } /* end else */ /* Flush (and invalidate, if requested) the entire metadata cache */ H5AC_flags = 0; diff --git a/src/H5FD.c b/src/H5FD.c index 967017f..8de2a1a 100644 --- a/src/H5FD.c +++ b/src/H5FD.c @@ -1126,14 +1126,11 @@ done: * the `open' callback. * * Return: Success: Non-negative - * * Failure: Negative * * Programmer: Robb Matzke * Tuesday, July 27, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -1148,11 +1145,11 @@ H5FDclose(H5FD_t *file) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file pointer") if(H5FD_close(file) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "unable to close file") + HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close file") done: FUNC_LEAVE_API(ret_value) -} +} /* end H5FDclose() */ /*------------------------------------------------------------------------- @@ -1161,22 +1158,11 @@ done: * Purpose: Private version of H5FDclose() * * Return: Success: Non-negative - * * Failure: Negative * * Programmer: Robb Matzke * Wednesday, August 4, 1999 * - * Modifications: - * Robb Matzke, 2000-11-10 - * Removed a call to set *file to all zero because the struct - * has already been freed by the close method. This fixes a write - * to freed memory. - * - * Bill Wendling, 2003-02-17 - * Split out the freeing of the freelist from this function - * so that the Flexible PHDF5 stuff can call it without - * having to call H5FD_close(). *------------------------------------------------------------------------- */ herr_t @@ -1201,7 +1187,7 @@ H5FD_close(H5FD_t *file) */ HDassert(driver->close); if((driver->close)(file) < 0) - HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "close failed") + HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "close failed") done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5MF.c b/src/H5MF.c index 03e614f..b59af88 100644 --- a/src/H5MF.c +++ b/src/H5MF.c @@ -938,74 +938,6 @@ HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value); /*------------------------------------------------------------------------- - * Function: H5MF_free_aggrs - * - * Purpose: Reset a block aggregator, returning any space back to file - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Vailin Choi - * July 1st, 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id) -{ - H5F_blk_aggr_t *first_aggr; /* First aggregator to reset */ - H5F_blk_aggr_t *second_aggr; /* Second aggregator to reset */ - haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */ - hsize_t ma_size = 0; /* Size of "metadata aggregator" */ - haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */ - hsize_t sda_size = 0; /* Size of "small data aggregator" */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5MF_free_aggrs, FAIL) - - /* Check args */ - HDassert(f); - HDassert(f->shared); - HDassert(f->shared->lf); - - /* Retrieve metadata aggregator info, if available */ - if(H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query metadata aggregator stats") - - /* Retrieve 'small data' aggregator info, if available */ - if(H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query small data aggregator stats") - - /* Make certain we release the aggregator that's later in the file first */ - /* (so the file shrinks properly) */ - if(H5F_addr_defined(ma_addr) && H5F_addr_defined(sda_addr)) { - if(H5F_addr_lt(ma_addr, sda_addr)) { - first_aggr = &(f->shared->sdata_aggr); - second_aggr = &(f->shared->meta_aggr); - } /* end if */ - else { - first_aggr = &(f->shared->meta_aggr); - second_aggr = &(f->shared->sdata_aggr); - } /* end else */ - } /* end if */ - else { - first_aggr = &(f->shared->meta_aggr); - second_aggr = &(f->shared->sdata_aggr); - } /* end else */ - - /* Release the unused portion of the metadata and "small data" blocks back - * to the free lists in the file. - */ - if(H5MF_aggr_reset(f, dxpl_id, first_aggr) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset metadata block") - if(H5MF_aggr_reset(f, dxpl_id, second_aggr) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset 'small data' block") -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5MF_free_aggrs() */ - - -/*------------------------------------------------------------------------- * Function: H5MF_close * * Purpose: Close the free space tracker(s) for a file diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c index 89412cd..1435d18 100644 --- a/src/H5MFaggr.c +++ b/src/H5MFaggr.c @@ -605,13 +605,13 @@ H5MF_aggr_query(const H5F_t *f, const H5F_blk_aggr_t *aggr, haddr_t *addr, * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5MF_aggr_reset(H5F_t *f, hid_t dxpl_id, H5F_blk_aggr_t *aggr) { H5FD_mem_t alloc_type; /* Type of file memory to work with */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5MF_aggr_reset, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5MF_aggr_reset) /* Check args */ HDassert(f); @@ -648,3 +648,72 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5MF_aggr_reset() */ + +/*------------------------------------------------------------------------- + * Function: H5MF_free_aggrs + * + * Purpose: Reset a metadata & small block aggregators, returning any space + * back to file + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi + * July 1st, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id) +{ + H5F_blk_aggr_t *first_aggr; /* First aggregator to reset */ + H5F_blk_aggr_t *second_aggr; /* Second aggregator to reset */ + haddr_t ma_addr = HADDR_UNDEF; /* Base "metadata aggregator" address */ + hsize_t ma_size = 0; /* Size of "metadata aggregator" */ + haddr_t sda_addr = HADDR_UNDEF; /* Base "small data aggregator" address */ + hsize_t sda_size = 0; /* Size of "small data aggregator" */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5MF_free_aggrs, FAIL) + + /* Check args */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->lf); + + /* Retrieve metadata aggregator info, if available */ + if(H5MF_aggr_query(f, &(f->shared->meta_aggr), &ma_addr, &ma_size) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query metadata aggregator stats") + + /* Retrieve 'small data' aggregator info, if available */ + if(H5MF_aggr_query(f, &(f->shared->sdata_aggr), &sda_addr, &sda_size) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query small data aggregator stats") + + /* Make certain we release the aggregator that's later in the file first */ + /* (so the file shrinks properly) */ + if(H5F_addr_defined(ma_addr) && H5F_addr_defined(sda_addr)) { + if(H5F_addr_lt(ma_addr, sda_addr)) { + first_aggr = &(f->shared->sdata_aggr); + second_aggr = &(f->shared->meta_aggr); + } /* end if */ + else { + first_aggr = &(f->shared->meta_aggr); + second_aggr = &(f->shared->sdata_aggr); + } /* end else */ + } /* end if */ + else { + first_aggr = &(f->shared->meta_aggr); + second_aggr = &(f->shared->sdata_aggr); + } /* end else */ + + /* Release the unused portion of the metadata and "small data" blocks back + * to the free lists in the file. + */ + if(H5MF_aggr_reset(f, dxpl_id, first_aggr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset metadata block") + if(H5MF_aggr_reset(f, dxpl_id, second_aggr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't reset 'small data' block") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MF_free_aggrs() */ + diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 515fed8..3f2a427 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -78,7 +78,7 @@ H5_DLL htri_t H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id, H5_DLL haddr_t H5MF_alloc_tmp(H5F_t *f, hsize_t size); /* 'block aggregator' routines */ -H5_DLL herr_t H5MF_aggr_reset(H5F_t *file, hid_t dxpl_id, H5F_blk_aggr_t *aggr); +H5_DLL herr_t H5MF_free_aggrs(H5F_t *f, hid_t dxpl_id); /* Debugging routines */ #ifdef H5MF_DEBUGGING -- cgit v0.12