diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5F.c | 2 | ||||
-rw-r--r-- | src/H5FDstdio.c | 2 | ||||
-rw-r--r-- | src/H5Faccum.c | 222 | ||||
-rw-r--r-- | src/H5Fio.c | 8 | ||||
-rw-r--r-- | src/H5Fpkg.h | 3 | ||||
-rw-r--r-- | src/H5Fprivate.h | 6 | ||||
-rw-r--r-- | src/H5Fquery.c | 22 | ||||
-rw-r--r-- | src/H5Ftest.c | 33 | ||||
-rw-r--r-- | src/H5HFcache.c | 170 | ||||
-rw-r--r-- | src/H5HFdblock.c | 40 | ||||
-rw-r--r-- | src/H5HFiblock.c | 32 | ||||
-rw-r--r-- | src/H5MF.c | 75 | ||||
-rw-r--r-- | src/H5MFaggr.c | 30 | ||||
-rw-r--r-- | src/H5MFprivate.h | 3 | ||||
-rw-r--r-- | src/H5T.c | 200 | ||||
-rw-r--r-- | src/H5public.h | 4 | ||||
-rw-r--r-- | src/H5win32defs.h | 2 | ||||
-rw-r--r-- | src/Makefile.in | 2 |
18 files changed, 618 insertions, 238 deletions
@@ -894,7 +894,6 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) f->shared->accum.loc = HADDR_UNDEF; f->shared->lf = lf; f->shared->root_addr = HADDR_UNDEF; - f->shared->next_proxy_addr = HADDR_MAX; /* * Copy the file creation and file access property lists into the @@ -950,6 +949,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) f->shared->maxaddr = H5FD_get_maxaddr(lf); if(!H5F_addr_defined(f->shared->maxaddr)) HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD") + f->shared->tmp_addr = f->shared->maxaddr; if(H5FD_get_feature_flags(lf, &f->shared->feature_flags) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get feature flags from VFD") if(H5FD_get_fs_type_map(lf, f->shared->fs_type_map) < 0) diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 0ae09a6..193c576 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -147,8 +147,10 @@ typedef struct H5FD_stdio_t { #define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ HADDR_UNDEF==(A)+(Z) || (file_offset_t)((A)+(Z))<(file_offset_t)(A)) +#ifndef H5_HAVE_FSEEKO /* Define big file as 2GB */ #define BIG_FILE 0x80000000UL +#endif /* Prototypes */ static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags, diff --git a/src/H5Faccum.c b/src/H5Faccum.c index 05f6910..9529e0c 100644 --- a/src/H5Faccum.c +++ b/src/H5Faccum.c @@ -40,6 +40,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FDprivate.h" /* File drivers */ +#include "H5Vprivate.h" /* Vectors and arrays */ /****************/ @@ -49,12 +50,19 @@ /* Metadata accumulator controls */ #define H5F_ACCUM_THROTTLE 8 #define H5F_ACCUM_THRESHOLD 2048 +#define H5F_ACCUM_MAX_SIZE (1024 *1024) /* Max. accum. buf size (max. I/Os will be 1/2 this size) */ /******************/ /* Local Typedefs */ /******************/ +/* Enumerated type to indicate how data will be added to accumulator */ +typedef enum { + H5F_ACCUM_PREPEND, /* Data will be prepended to accumulator */ + H5F_ACCUM_APPEND /* Data will be appended to accumulator */ +} H5F_accum_adjust_t; + /********************/ /* Package Typedefs */ @@ -112,7 +120,8 @@ H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, HDassert(buf); /* Check if this information is in the metadata accumulator */ - if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW) { + if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW + && size < H5F_ACCUM_MAX_SIZE) { /* Current read overlaps with metadata accumulator */ if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) { unsigned char *read_buf = (unsigned char *)buf; /* Pointer to the buffer being read in */ @@ -195,12 +204,17 @@ H5F_accum_read(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, /* Cache the new piece of metadata */ /* Check if we need to resize the buffer */ if(size > f->shared->accum.alloc_size) { + size_t new_size; /* New size of accumulator */ + + /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ + new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); + /* Grow the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, size))) + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ - f->shared->accum.alloc_size = size; + f->shared->accum.alloc_size = new_size; } /* end if */ else { /* Check if we should shrink the accumulator buffer */ @@ -246,6 +260,111 @@ done: /*------------------------------------------------------------------------- + * Function: H5F_accum_adjust + * + * Purpose: Adjust accumulator size, if necessary + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jun 11 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_accum_adjust(H5F_meta_accum_t *accum, H5FD_t *lf, hid_t dxpl_id, + H5F_accum_adjust_t adjust, size_t size) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_accum_adjust) + + HDassert(accum); + HDassert(lf); + HDassert(size > 0); + HDassert(size <= H5F_ACCUM_MAX_SIZE); + + /* Check if we need more buffer space */ + if((size + accum->size) > accum->alloc_size) { + size_t new_size; /* New size of accumulator */ + + /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ + new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)((size + accum->size) - 1))); + + /* Check for accumulator getting too big */ + if(new_size > H5F_ACCUM_MAX_SIZE) { + size_t shrink_size; /* Amount to shrink accumulator by */ + size_t remnant_size; /* Amount left in accumulator */ + + /* Cap the accumulator's growth, leaving some room */ + + /* Determine the amounts to work with */ + if(size > (H5F_ACCUM_MAX_SIZE / 2)) { + new_size = H5F_ACCUM_MAX_SIZE; + shrink_size = accum->size; + remnant_size = 0; + } /* end if */ + else { + new_size = (H5F_ACCUM_MAX_SIZE / 2); + shrink_size = (H5F_ACCUM_MAX_SIZE / 2); + remnant_size = accum->size - shrink_size; + } /* end else */ + + /* Check if we need to flush accumulator data to file */ + if(accum->dirty) { + /* Check whether to accumulator will be prepended or appended */ + if(H5F_ACCUM_PREPEND == adjust) { + /* Write out upper part of the existing metadata accumulator, with dispatch to driver */ + if(H5FD_write(lf, dxpl_id, H5FD_MEM_DEFAULT, (accum->loc + remnant_size), shrink_size, (accum->buf + remnant_size)) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + } /* end if */ + else { + /* Sanity check */ + HDassert(H5F_ACCUM_APPEND == adjust); + + /* Write out lower part of the existing metadata accumulator, with dispatch to driver */ + if(H5FD_write(lf, dxpl_id, H5FD_MEM_DEFAULT, accum->loc, shrink_size, accum->buf) < 0) + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + + /* Move remnant of accumulator down */ + HDmemmove(accum->buf, (accum->buf + shrink_size), remnant_size); + + /* Adjust accumulator's location */ + accum->loc += shrink_size; + } /* end else */ + + /* Reset accumulator dirty flag (in case of error) */ + accum->dirty = FALSE; + } /* end if */ + + /* Trim the accumulator's use of its buffer */ + accum->size = remnant_size; + } /* end if */ + + /* Check for accumulator needing to be reallocated */ + if(new_size > accum->alloc_size) { + unsigned char *new_buf; /* New buffer to hold the accumulated metadata */ + + /* Reallocate the metadata accumulator buffer */ + if(NULL == (new_buf = H5FL_BLK_REALLOC(meta_accum, accum->buf, new_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") + + /* Update accumulator info */ + accum->buf = new_buf; + accum->alloc_size = new_size; +#ifdef H5_CLEAR_MEMORY +HDmemset(accum->buf + accum->size, 0, (accum->alloc_size - (accum->size + size))); +#endif /* H5_CLEAR_MEMORY */ + } /* end if */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_accum_adjust() */ + + +/*------------------------------------------------------------------------- * Function: H5F_accum_write * * Purpose: Attempts to read some data from the metadata accumulator for @@ -273,23 +392,15 @@ H5F_accum_write(const H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, haddr_t addr, HDassert(buf); /* Check for accumulating metadata */ - if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW) { + if((f->shared->feature_flags & H5FD_FEAT_ACCUMULATE_METADATA) && type != H5FD_MEM_DRAW + && size < H5F_ACCUM_MAX_SIZE) { /* Check if there is already metadata in the accumulator */ if(f->shared->accum.size > 0) { /* Check if the new metadata adjoins the beginning of the current accumulator */ if((addr + size) == f->shared->accum.loc) { - /* Check if we need more buffer space */ - if((size + f->shared->accum.size) > f->shared->accum.alloc_size) { - /* Adjust the buffer size, by doubling it */ - f->shared->accum.alloc_size = MAX(f->shared->accum.alloc_size * 2, size + f->shared->accum.size); - - /* Reallocate the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, f->shared->accum.alloc_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") -#ifdef H5_CLEAR_MEMORY -HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.alloc_size - (f->shared->accum.size + size))); -#endif /* H5_CLEAR_MEMORY */ - } /* end if */ + /* Check if we need to adjust accumulator size */ + if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_PREPEND, size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") /* Move the existing metadata to the proper location */ HDmemmove(f->shared->accum.buf + size, f->shared->accum.buf, f->shared->accum.size); @@ -306,18 +417,9 @@ HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.allo } /* end if */ /* Check if the new metadata adjoins the end of the current accumulator */ else if(addr == (f->shared->accum.loc + f->shared->accum.size)) { - /* Check if we need more buffer space */ - if((size + f->shared->accum.size) > f->shared->accum.alloc_size) { - /* Adjust the buffer size, by doubling it */ - f->shared->accum.alloc_size = MAX(f->shared->accum.alloc_size * 2, size + f->shared->accum.size); - - /* Reallocate the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, f->shared->accum.alloc_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") -#ifdef H5_CLEAR_MEMORY -HDmemset(f->shared->accum.buf + f->shared->accum.size + size, 0, (f->shared->accum.alloc_size - (f->shared->accum.size + size))); -#endif /* H5_CLEAR_MEMORY */ - } /* end if */ + /* Check if we need to adjust accumulator size */ + if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_APPEND, size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") /* Copy the new metadata to the end */ HDmemcpy(f->shared->accum.buf + f->shared->accum.size, buf, size); @@ -330,7 +432,7 @@ HDmemset(f->shared->accum.buf + f->shared->accum.size + size, 0, (f->shared->acc } /* end if */ /* Check if the piece of metadata being written overlaps the metadata accumulator */ else if(H5F_addr_overlap(addr, size, f->shared->accum.loc, f->shared->accum.size)) { - size_t new_size; /* New size of the accumulator buffer */ + size_t add_size; /* New size of the accumulator buffer */ /* Check if the new metadata is entirely within the current accumulator */ if(addr >= f->shared->accum.loc && (addr + size) <= (f->shared->accum.loc + f->shared->accum.size)) { @@ -344,21 +446,12 @@ HDmemset(f->shared->accum.buf + f->shared->accum.size + size, 0, (f->shared->acc else if(addr < f->shared->accum.loc && (addr + size) <= (f->shared->accum.loc + f->shared->accum.size)) { size_t old_offset; /* Offset of old data within the accumulator buffer */ - /* Calculate the new accumulator size, based on the amount of overlap */ - H5_ASSIGN_OVERFLOW(new_size, (f->shared->accum.loc - addr) + f->shared->accum.size, hsize_t, size_t); + /* Calculate the amount we will need to add to the accumulator size, based on the amount of overlap */ + H5_ASSIGN_OVERFLOW(add_size, (f->shared->accum.loc - addr), hsize_t, size_t); - /* Check if we need more buffer space */ - if(new_size > f->shared->accum.alloc_size) { - /* Adjust the buffer size, by doubling it */ - f->shared->accum.alloc_size = MAX(f->shared->accum.alloc_size + 2, new_size); - - /* Reallocate the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, f->shared->accum.alloc_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") -#ifdef H5_CLEAR_MEMORY -HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.alloc_size - f->shared->accum.size)); -#endif /* H5_CLEAR_MEMORY */ - } /* end if */ + /* Check if we need to adjust accumulator size */ + if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_PREPEND, add_size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") /* Calculate the proper offset of the existing metadata */ H5_ASSIGN_OVERFLOW(old_offset, (addr + size) - f->shared->accum.loc, hsize_t, size_t); @@ -371,34 +464,25 @@ HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.allo /* Set the new size & location of the metadata accumulator */ f->shared->accum.loc = addr; - f->shared->accum.size = new_size; + f->shared->accum.size += add_size; /* Mark it as written to */ f->shared->accum.dirty = TRUE; } /* end if */ /* Check if the new metadata overlaps the end of the current accumulator */ else if(addr >= f->shared->accum.loc && (addr + size) > (f->shared->accum.loc + f->shared->accum.size)) { - /* Calculate the new accumulator size, based on the amount of overlap */ - H5_ASSIGN_OVERFLOW(new_size, (addr - f->shared->accum.loc) + size, hsize_t, size_t); - - /* Check if we need more buffer space */ - if(new_size > f->shared->accum.alloc_size) { - /* Adjust the buffer size, by doubling it */ - f->shared->accum.alloc_size = MAX(f->shared->accum.alloc_size * 2, new_size); + /* Calculate the amount we will need to add to the accumulator size, based on the amount of overlap */ + H5_ASSIGN_OVERFLOW(add_size, (addr + size) - (f->shared->accum.loc + f->shared->accum.size), hsize_t, size_t); - /* Reallocate the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, f->shared->accum.alloc_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") -#ifdef H5_CLEAR_MEMORY -HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.alloc_size - f->shared->accum.size)); -#endif /* H5_CLEAR_MEMORY */ - } /* end if */ + /* Check if we need to adjust accumulator size */ + if(H5F_accum_adjust(&f->shared->accum, f->shared->lf, dxpl_id, H5F_ACCUM_APPEND, add_size) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTRESIZE, FAIL, "can't adjust metadata accumulator") /* Copy the new metadata to the end */ HDmemcpy(f->shared->accum.buf + (addr - f->shared->accum.loc), buf, size); - /* Set the new size & location of the metadata accumulator */ - f->shared->accum.size = new_size; + /* Set the new size of the metadata accumulator */ + f->shared->accum.size += add_size; /* Mark it as written to */ f->shared->accum.dirty = TRUE; @@ -421,12 +505,17 @@ HDmemset(f->shared->accum.buf + f->shared->accum.size, 0, (f->shared->accum.allo /* Cache the new piece of metadata */ /* Check if we need to resize the buffer */ if(size > f->shared->accum.alloc_size) { + size_t new_size; /* New size of accumulator */ + + /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ + new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); + /* Grow the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, size))) + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ - f->shared->accum.alloc_size = size; + f->shared->accum.alloc_size = new_size; #ifdef H5_CLEAR_MEMORY { size_t clear_size = MAX(f->shared->accum.size, size); @@ -462,12 +551,17 @@ HDmemset(f->shared->accum.buf + clear_size, 0, (f->shared->accum.alloc_size - cl else { /* Check if we need to reallocate the buffer */ if(size > f->shared->accum.alloc_size) { + size_t new_size; /* New size of accumulator */ + + /* Adjust the buffer size to be a power of 2 that is large enough to hold data */ + new_size = (size_t)1 << (1 + H5V_log2_gen((uint64_t)(size - 1))); + /* Reallocate the metadata accumulator buffer */ - if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, size))) + if(NULL == (f->shared->accum.buf = H5FL_BLK_REALLOC(meta_accum, f->shared->accum.buf, new_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate metadata accumulator buffer") /* Note the new buffer size */ - f->shared->accum.alloc_size = size; + f->shared->accum.alloc_size = new_size; } /* end if */ /* Update the metadata accumulator information */ diff --git a/src/H5Fio.c b/src/H5Fio.c index 1081a27..407f950 100644 --- a/src/H5Fio.c +++ b/src/H5Fio.c @@ -104,6 +104,10 @@ H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, HDassert(f->shared); HDassert(buf); + /* Check for attempting I/O on 'temporary' file address */ + if(H5F_addr_le(f->shared->tmp_addr, (addr + size))) + HGOTO_ERROR(H5E_IO, H5E_BADRANGE, FAIL, "attempting I/O in temporary file space") + /* Check if this I/O can be satisfied by the metadata accumulator */ if((accumulated = H5F_accum_read(f, dxpl_id, type, addr, size, buf)) < 0) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "read from metadata accumulator failed") @@ -150,6 +154,10 @@ HDfprintf(stderr, "%s: write to addr = %a, size = %Zu\n", FUNC, addr, size); HDassert(f->intent & H5F_ACC_RDWR); HDassert(buf); + /* Check for attempting I/O on 'temporary' file address */ + if(H5F_addr_le(f->shared->tmp_addr, (addr + size))) + HGOTO_ERROR(H5E_IO, H5E_BADRANGE, FAIL, "attempting I/O in temporary file space") + /* Check for accumulating metadata */ if((accumulated = H5F_accum_write(f, dxpl_id, type, addr, size, buf)) < 0) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "write to metadata accumulator failed") diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 0f14b46..acc8aaf 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -162,7 +162,7 @@ typedef struct H5F_file_t { 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 */ - haddr_t next_proxy_addr; /* Next address to use for metadata cache proxy entries */ + haddr_t tmp_addr; /* Next address to use for temp. space in the file */ /* File space allocation information */ unsigned fs_aggr_merge[H5FD_MEM_NTYPES]; /* Flags for whether free space can merge with aggregator(s) */ @@ -250,6 +250,7 @@ H5_DLL herr_t H5F_sfile_remove(H5F_file_t *shared); 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); +H5_DLL herr_t H5F_get_maxaddr_test(hid_t file_id, haddr_t *maxaddr); #endif /* H5F_TESTING */ #endif /* _H5Fpkg_H */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 59bdd10..c7b4d25 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -265,7 +265,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags & (FL)) #define H5F_DRIVER_ID(F) ((F)->shared->lf->driver_id) #define H5F_GET_FILENO(F,FILENUM) ((FILENUM) = (F)->shared->lf->fileno) -#define H5F_GET_NEXT_PROXY_ADDR(F) ((F)->shared->next_proxy_addr--) +#define H5F_IS_TMP_ADDR(F, ADDR) (H5F_addr_le((F)->shared->tmp_addr, (ADDR))) #else /* H5F_PACKAGE */ #define H5F_INTENT(F) (H5F_get_intent(F)) #define H5F_FCPL(F) (H5F_get_fcpl(F)) @@ -288,7 +288,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_HAS_FEATURE(F,FL) (H5F_has_feature(F,FL)) #define H5F_DRIVER_ID(F) (H5F_get_driver_id(F)) #define H5F_GET_FILENO(F,FILENUM) (H5F_get_fileno((F), &(FILENUM))) -#define H5F_GET_NEXT_PROXY_ADDR(F) (H5F_get_next_proxy_addr(F)) +#define H5F_IS_TMP_ADDR(F, ADDR) (H5F_is_tmp_addr((F), (ADDR))) #endif /* H5F_PACKAGE */ @@ -474,7 +474,6 @@ H5_DLL char *H5F_get_name(const H5F_t *f); H5_DLL hid_t H5F_get_id(H5F_t *file, hbool_t app_ref); H5_DLL size_t H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref); H5_DLL size_t H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *obj_id_list, hbool_t app_ref); -H5_DLL haddr_t H5F_get_next_proxy_addr(const H5F_t *f); /* Functions than retrieve values set/cached from the superblock/FCPL */ H5_DLL hid_t H5F_get_fcpl(const H5F_t *f); @@ -492,6 +491,7 @@ H5_DLL unsigned H5F_gc_ref(const H5F_t *f); H5_DLL hbool_t H5F_use_latest_format(const H5F_t *f); H5_DLL H5F_close_degree_t H5F_get_fc_degree(const H5F_t *f); H5_DLL hbool_t H5F_store_msg_crt_idx(const H5F_t *f); +H5_DLL hbool_t H5F_is_tmp_addr(const H5F_t *f, haddr_t addr); /* Functions that retrieve values from VFD layer */ H5_DLL hbool_t H5F_has_feature(const H5F_t *f, unsigned feature); diff --git a/src/H5Fquery.c b/src/H5Fquery.c index d070b94..5538d60 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -689,30 +689,30 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_get_next_proxy_addr + * Function: H5F_is_tmp_addr * - * Purpose: Quick and dirty routine to retrieve the next metadata proxy - * address for a file. + * Purpose: Quick and dirty routine to determine if an address is in + * the 'temporary' file space. * (Mainly added to stop non-file routines from poking about in the * H5F_t data structure) * - * Return: Success: Address to use for metadata cache proxy - * Failure: abort (should not happen) + * Return: TRUE/FALSE on success/abort on failure (shouldn't fail) * * Programmer: Quincey Koziol <koziol@hdfgroup.org> - * May 19, 2009 + * June 11, 2009 * *------------------------------------------------------------------------- */ -haddr_t -H5F_get_next_proxy_addr(const H5F_t *f) +hbool_t +H5F_is_tmp_addr(const H5F_t *f, haddr_t addr) { /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_get_next_proxy_addr) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_is_tmp_addr) HDassert(f); HDassert(f->shared); + HDassert(f->shared->lf); - FUNC_LEAVE_NOAPI(f->shared->next_proxy_addr--) -} /* end H5F_get_next_proxy_addr() */ + FUNC_LEAVE_NOAPI(H5F_addr_le(f->shared->tmp_addr, addr)) +} /* end H5F_is_tmp_addr() */ diff --git a/src/H5Ftest.c b/src/H5Ftest.c index 8cbc133..72fee96 100644 --- a/src/H5Ftest.c +++ b/src/H5Ftest.c @@ -153,3 +153,36 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_check_cached_stab_test() */ + +/*------------------------------------------------------------------------- + * Function: H5F_get_maxaddr_test + * + * Purpose: Retrieve the maximum address for a file + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Jun 10, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_maxaddr_test(hid_t file_id, haddr_t *maxaddr) +{ + H5F_t *file; /* File info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_get_maxaddr_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") + + /* Retrieve maxaddr for file */ + *maxaddr = file->shared->maxaddr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_maxaddr_test() */ + diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 0fcca97..6d250d1 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -361,7 +361,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); H5O_pline_t *pline; /* Pipeline information from the header on disk */ /* Compute the offset of the filter info in the header */ - filter_info_off = p - buf; + filter_info_off = (size_t)(p - buf); /* Compute the size of the extra filter information */ filter_info_size = hdr->sizeof_size /* Size of size for filtered root direct block */ @@ -1056,6 +1056,57 @@ HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->f HDassert(max_child == iblock->max_child); #endif /* NDEBUG */ + /* Check for needing to re-allocate indirect block from 'temp.' to 'normal' file space */ + if(H5F_IS_TMP_ADDR(f, addr)) { +#ifdef QAK +HDfprintf(stderr, "%s: Re-allocating indirect block in temporary space - addr = %a\n", FUNC, addr); +#endif /* QAK */ + /* Sanity check */ + HDassert(H5F_addr_eq(iblock->addr, addr)); + + /* Allocate 'normal' space for the new indirect block on disk */ + if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block") + + /* Sanity check */ + HDassert(!H5F_addr_eq(iblock->addr, addr)); + + /* Let the metadata cache know the block moved */ + if(H5AC_rename(f, H5AC_FHEAP_IBLOCK, iblock->addr, addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move indirect block") + + /* Update the internal address for the block */ + iblock->addr = addr; + + /* Check for root indirect block */ + if(NULL == iblock->parent) { + /* Update information about indirect block's location */ + hdr->man_dtable.table_addr = addr; + + /* Mark that heap header was modified */ + if(H5HF_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") + } /* end if */ + else { + H5HF_indirect_t *par_iblock; /* Parent indirect block */ + unsigned par_entry; /* Entry in parent indirect block */ + + /* Get parent information */ + par_iblock = iblock->parent; + par_entry = iblock->par_entry; + + /* Update information about indirect block's location */ + par_iblock->ents[par_entry].addr = addr; + + /* Mark that parent was modified */ + if(H5HF_iblock_dirty(par_iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") + } /* end if */ + } /* end if */ + + /* Indirect block must be in 'normal' file space now */ + HDassert(!H5F_IS_TMP_ADDR(f, addr)); + /* Write the indirect block */ if(H5F_block_write(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap indirect block to disk") @@ -1112,10 +1163,14 @@ HDfprintf(stderr, "%s: Destroying indirect block\n", FUNC); /* Check for freeing file space for indirect block */ if(iblock->cache_info.free_file_space_on_destroy) { - /* Release the space on disk */ - /* (XXX: Nasty usage of internal DXPL value! -QAK) */ - if(H5MF_xfree(f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->cache_info.addr, (hsize_t)iblock->size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block") + /* Check if the indirect block is NOT currently allocated in temp. file space */ + /* (temp. file space does not need to be freed) */ + if(!H5F_IS_TMP_ADDR(f, iblock->cache_info.addr)) { + /* Release the space on disk */ + /* (XXX: Nasty usage of internal DXPL value! -QAK) */ + if(H5MF_xfree(f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->cache_info.addr, (hsize_t)iblock->size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block") + } /* end if */ } /* end if */ /* Set the shared heap header's file context for this operation */ @@ -1130,11 +1185,11 @@ HDfprintf(stderr, "%s: Destroying indirect block\n", FUNC); /* Release entry tables */ if(iblock->ents) - H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents); + (void)H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents); if(iblock->filt_ents) - H5FL_SEQ_FREE(H5HF_indirect_filt_ent_t, iblock->filt_ents); + (void)H5FL_SEQ_FREE(H5HF_indirect_filt_ent_t, iblock->filt_ents); if(iblock->child_iblocks) - H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks); + (void)H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks); /* Free fractal heap indirect block info */ (void)H5FL_FREE(H5HF_indirect_t, iblock); @@ -1436,6 +1491,7 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, if(dblock->cache_info.is_dirty) { H5HF_hdr_t *hdr; /* Shared fractal heap information */ + hbool_t at_tmp_addr = H5F_IS_TMP_ADDR(f, addr); /* Flag to indicate direct block is at temporary address */ void *write_buf; /* Pointer to buffer to write out */ size_t write_size; /* Size of buffer to write out */ uint8_t *p; /* Pointer into raw data buffer */ @@ -1525,13 +1581,17 @@ HDfprintf(stderr, "%s: hdr->man_dtable.table_addr = %a, addr = %a\n", FUNC, hdr- } /* end if */ /* Check if we need to re-size the block on disk */ - if(hdr->pline_root_direct_size != write_size) { + if(hdr->pline_root_direct_size != write_size || at_tmp_addr) { #ifdef QAK HDfprintf(stderr, "%s: Need to re-allocate root direct block!\n", FUNC); #endif /* QAK */ - /* Release direct block's current disk space */ - if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)hdr->pline_root_direct_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block") + /* Check if the direct block is NOT currently allocated in temp. file space */ + /* (temp. file space does not need to be freed) */ + if(!at_tmp_addr) { + /* Release direct block's current disk space */ + if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)hdr->pline_root_direct_size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block") + } /* end if */ /* Allocate space for the compressed direct block */ if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size))) @@ -1579,13 +1639,17 @@ HDfprintf(stderr, "%s: par_iblock->ents[%u].addr = %a, addr = %a\n", FUNC, par_e } /* end if */ /* Check if we need to re-size the block on disk */ - if(par_iblock->filt_ents[par_entry].size != write_size) { + if(par_iblock->filt_ents[par_entry].size != write_size || at_tmp_addr) { #ifdef QAK HDfprintf(stderr, "%s: Need to re-allocate non-root direct block!\n", FUNC); #endif /* QAK */ - /* Release direct block's current disk space */ - if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)par_iblock->filt_ents[par_entry].size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block") + /* Check if the direct block is NOT currently allocated in temp. file space */ + /* (temp. file space does not need to be freed) */ + if(!at_tmp_addr) { + /* Release direct block's current disk space */ + if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, addr, (hsize_t)par_iblock->filt_ents[par_entry].size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block") + } /* end if */ /* Allocate space for the compressed direct block */ if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size))) @@ -1613,8 +1677,70 @@ HDfprintf(stderr, "%s: Need to re-allocate non-root direct block!\n", FUNC); else { write_buf = dblock->blk; write_size = dblock->size; + + /* Check for needing to re-allocate direct block from 'temp.' to 'normal' file space */ + if(at_tmp_addr) { +#ifdef QAK +HDfprintf(stderr, "%s: Re-allocating direct block in temporary space - addr = %a, write_size = %Zu\n", FUNC, addr, write_size); +#endif /* QAK */ + /* Check for root direct block */ + if(NULL == dblock->parent) { + /* Sanity check */ + HDassert(H5F_addr_eq(hdr->man_dtable.table_addr, addr)); + + /* Allocate 'normal' space for the direct block */ + if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block") + + /* Sanity check */ + HDassert(!H5F_addr_eq(hdr->man_dtable.table_addr, addr)); + + /* Let the metadata cache know the block moved */ + if(H5AC_rename(f, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move direct block") + + /* Update information about direct block's location */ + hdr->man_dtable.table_addr = addr; + + /* Mark that heap header was modified */ + if(H5HF_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") + } /* end if */ + else { + H5HF_indirect_t *par_iblock; /* Parent indirect block */ + unsigned par_entry; /* Entry in parent indirect block */ + + /* Get parent information */ + par_iblock = dblock->parent; + par_entry = dblock->par_entry; + + /* Sanity check */ + HDassert(H5F_addr_eq(par_iblock->ents[par_entry].addr, addr)); + + /* Allocate 'normal' space for the direct block */ + if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)write_size))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block") + + /* Sanity check */ + HDassert(!H5F_addr_eq(par_iblock->ents[par_entry].addr, addr)); + + /* Let the metadata cache know the block moved */ + if(H5AC_rename(f, H5AC_FHEAP_DBLOCK, par_iblock->ents[par_entry].addr, addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move direct block") + + /* Update information about direct block's location */ + par_iblock->ents[par_entry].addr = addr; + + /* Mark that parent was modified */ + if(H5HF_iblock_dirty(par_iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") + } /* end else */ + } /* end if */ } /* end else */ + /* Direct block must be in 'normal' file space now */ + HDassert(!H5F_IS_TMP_ADDR(f, addr)); + /* Write the direct block */ #ifdef QAK HDfprintf(stderr, "%s: addr = %a, write_size = %Zu\n", FUNC, addr, write_size); @@ -1674,10 +1800,14 @@ HDfprintf(stderr, "%s: Destroying direct block, dblock = %p\n", FUNC, dblock); /* Sanity check */ HDassert(dblock->file_size > 0); - /* Release the space on disk */ - /* (XXX: Nasty usage of internal DXPL value! -QAK) */ - if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, H5AC_dxpl_id, dblock->cache_info.addr, dblock->file_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block") + /* Check if the direct block is NOT currently allocated in temp. file space */ + /* (temp. file space does not need to be freed) */ + if(!H5F_IS_TMP_ADDR(f, dblock->cache_info.addr)) { + /* Release the space on disk */ + /* (XXX: Nasty usage of internal DXPL value! -QAK) */ + if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, H5AC_dxpl_id, dblock->cache_info.addr, dblock->file_size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block") + } /* end if */ } /* end if */ /* Set the shared heap header's file context for this operation */ diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c index c14249c..7e68533 100644 --- a/src/H5HFdblock.c +++ b/src/H5HFdblock.c @@ -148,8 +148,8 @@ H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblo HDmemset(dblock->blk, 0, dblock->size); #endif /* H5_CLEAR_MEMORY */ - /* Allocate space for the direct block on disk */ - if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)dblock->size))) + /* Allocate [temporary] space for the direct block on disk */ + if(HADDR_UNDEF == (dblock_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)dblock->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block") #ifdef QAK HDfprintf(stderr, "%s: direct block address = %a\n", FUNC, dblock_addr); @@ -695,22 +695,26 @@ HDfprintf(stderr, "%s: Done expunging direct block from cache\n", FUNC); #endif /* QAK */ } /* end if */ - /* Release direct block's disk space */ - /* (XXX: Under the best of circumstances, this block's space in the file - * would be freed in the H5AC_expunge_entry() call above (and the - * H5AC__FREE_FILE_SPACE_FLAG used there), but since the direct - * block structure might have a different size on disk than in - * the heap's 'abstract' address space, we would need to set the - * "file_size" field for the direct block structure. In order to - * do that, we'd have to protect/unprotect the direct block and - * that would add a bunch of unnecessary overhead to the process, - * so we just release the file space here, directly. When the - * revised metadata cache is operating, it will "know" the file - * size of each entry in the cache and we can the the - * H5AC_expunge_entry() method. -QAK) - */ - if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, dblock_addr, dblock_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block") + /* Check if the direct block is NOT currently allocated in temp. file space */ + /* (temp. file space does not need to be freed) */ + if(!H5F_IS_TMP_ADDR(f, dblock_addr)) { + /* Release direct block's disk space */ + /* (XXX: Under the best of circumstances, this block's space in the file + * would be freed in the H5AC_expunge_entry() call above (and the + * H5AC__FREE_FILE_SPACE_FLAG used there), but since the direct + * block structure might have a different size on disk than in + * the heap's 'abstract' address space, we would need to set the + * "file_size" field for the direct block structure. In order to + * do that, we'd have to protect/unprotect the direct block and + * that would add a bunch of unnecessary overhead to the process, + * so we just release the file space here, directly. When the + * revised metadata cache is operating, it will "know" the file + * size of each entry in the cache and we can the the + * H5AC_expunge_entry() method. -QAK) + */ + if(H5MF_xfree(f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, dblock_addr, dblock_size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c index 8f9eb24..3383ef9 100644 --- a/src/H5HFiblock.c +++ b/src/H5HFiblock.c @@ -578,6 +578,9 @@ HDfprintf(stderr, "%s: iblock->nrows = %u, iblock->max_rows = %u\n", FUNC, ibloc HDfprintf(stderr, "%s: new_next_entry = %u\n", FUNC, new_next_entry); #endif /* QAK */ + /* Check if the indirect block is NOT currently allocated in temp. file space */ + /* (temp. file space does not need to be freed) */ + if(!H5F_IS_TMP_ADDR(hdr->f, iblock->addr)) { /* Currently, the old block data is "thrown away" after the space is reallocated, * to avoid data copy in H5MF_realloc() call by just free'ing the space and * allocating new space. @@ -587,16 +590,17 @@ HDfprintf(stderr, "%s: new_next_entry = %u\n", FUNC, new_next_entry); * * QAK - 3/14/2006 */ - /* Free previous indirect block disk space */ - if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space") + /* Free previous indirect block disk space */ + if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space") + } /* end if */ /* Compute size of buffer needed for new indirect block */ iblock->nrows = new_nrows; iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); - /* Allocate space for the new indirect block on disk */ - if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) + /* Allocate [temporary] space for the new indirect block on disk */ + if(HADDR_UNDEF == (new_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size))) HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block") #ifdef QAK HDfprintf(stderr, "%s: Check 1.0 - iblock->addr = %a, new_addr = %a\n", FUNC, iblock->addr, new_addr); @@ -739,6 +743,9 @@ HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows); HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); #endif /* QAK */ + /* Check if the indirect block is NOT currently allocated in temp. file space */ + /* (temp. file space does not need to be freed) */ + if(!H5F_IS_TMP_ADDR(hdr->f, iblock->addr)) { /* Currently, the old block data is "thrown away" after the space is reallocated, * to avoid data copy in H5MF_realloc() call by just free'ing the space and * allocating new space. @@ -748,9 +755,10 @@ HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); * * QAK - 6/12/2006 */ - /* Free previous indirect block disk space */ - if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space") + /* Free previous indirect block disk space */ + if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space") + } /* end if */ /* Compute free space in rows to delete */ acc_dblock_free = 0; @@ -762,8 +770,8 @@ HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); iblock->nrows = new_nrows; iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); - /* Allocate space for the new indirect block on disk */ - if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) + /* Allocate [temporary] space for the new indirect block on disk */ + if(HADDR_UNDEF == (new_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size))) HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block") #ifdef QAK HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr); @@ -1078,8 +1086,8 @@ HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows); else iblock->child_iblocks = NULL; - /* Allocate space for the indirect block on disk */ - if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) + /* Allocate [temporary] space for the indirect block on disk */ + if(HADDR_UNDEF == (*addr_p = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block") iblock->addr = *addr_p; @@ -302,6 +302,8 @@ HDfprintf(stderr, "%s: alloc_type = %u, size = %Hu\n", FUNC, (unsigned)alloc_typ /* check arguments */ HDassert(f); + HDassert(f->shared); + HDassert(f->shared->lf); HDassert(size > 0); /* Get free space type from allocation type */ @@ -374,14 +376,17 @@ HDfprintf(stderr, "%s: Check 2.0\n", FUNC); if(alloc_type != H5FD_MEM_DRAW) { /* Handle metadata differently from "raw" data */ if(HADDR_UNDEF == (ret_value = H5MF_aggr_alloc(f, dxpl_id, &(f->shared->meta_aggr), &(f->shared->sdata_aggr), alloc_type, size))) - HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata") } /* end if */ else { /* Allocate "raw" data */ if(HADDR_UNDEF == (ret_value = H5MF_aggr_alloc(f, dxpl_id, &(f->shared->sdata_aggr), &(f->shared->meta_aggr), alloc_type, size))) - HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data") } /* end else */ + /* Sanity check for overlapping into file's temporary allocation space */ + HDassert(H5F_addr_le((ret_value + size), f->shared->tmp_addr)); + done: #ifdef H5MF_ALLOC_DEBUG HDfprintf(stderr, "%s: Leaving: ret_value = %a, size = %Hu\n", FUNC, ret_value, size); @@ -394,6 +399,66 @@ H5MF_sects_dump(f, dxpl_id, stderr); /*------------------------------------------------------------------------- + * Function: H5MF_alloc_tmp + * + * Purpose: Allocate temporary space in the file + * + * Note: The address returned is non-overlapping with any other address + * in the file and suitable for insertion into the metadata + * cache. + * + * The address is _not_ suitable for actual file I/O and will + * cause an error if it is so used. + * + * The space allocated with this routine should _not_ be freed, + * it should just be abandoned. Calling H5MF_xfree() with space + * from this routine will cause an error. + * + * Return: Success: Temporary file address + * Failure: HADDR_UNDEF + * + * Programmer: Quincey Koziol + * Thursday, June 4, 2009 + * + *------------------------------------------------------------------------- + */ +haddr_t +H5MF_alloc_tmp(H5F_t *f, hsize_t size) +{ + haddr_t eoa; /* End of allocated space in the file */ + haddr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5MF_alloc_tmp, HADDR_UNDEF) +#ifdef H5MF_ALLOC_DEBUG +HDfprintf(stderr, "%s: size = %Hu\n", FUNC, size); +#endif /* H5MF_ALLOC_DEBUG */ + + /* check args */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->lf); + HDassert(size > 0); + + /* Retrieve the 'eoa' for the file */ + if(HADDR_UNDEF == (eoa = H5FD_get_eoa(f->shared->lf, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "driver get_eoa request failed") + + /* Compute value to return */ + ret_value = f->shared->tmp_addr - size; + + /* Check for overlap into the actual allocated space in the file */ + if(H5F_addr_le(ret_value, eoa)) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "driver get_eoa request failed") + + /* Adjust temporary address allocator in the file */ + f->shared->tmp_addr = ret_value; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5MF_alloc_tmp() */ + + +/*------------------------------------------------------------------------- * Function: H5MF_xfree * * Purpose: Frees part of a file, making that part of the file @@ -427,6 +492,10 @@ HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUN HGOTO_DONE(SUCCEED); HDassert(addr != 0); /* Can't deallocate the superblock :-) */ + /* Check for attempting to free space that's a 'temporary' file address */ + if(H5F_addr_le(f->shared->tmp_addr, addr)) + HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, FAIL, "attempting to free temporary file space") + /* Check if the space to free intersects with the file's metadata accumulator */ if(H5F_accum_free(f, dxpl_id, alloc_type, addr, size) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't check free space intersection w/metadata accumulator") @@ -701,6 +770,8 @@ HDfprintf(stderr, "%s: Entering - alloc_type = %u, addr = %a, size = %Hu\n", FUN /* check arguments */ HDassert(f); + HDassert(f->shared); + HDassert(f->shared->lf); HDassert(H5F_addr_defined(addr)); HDassert(size > 0); diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c index f383e23..0f8a374 100644 --- a/src/H5MFaggr.c +++ b/src/H5MFaggr.c @@ -119,6 +119,9 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES); HDassert(size > 0); + if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, type))) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, HADDR_UNDEF, "Unable to get eoa") + /* * If the aggregation feature is enabled for this file, allocate "generic" * space and sub-allocate out of that, if possible. Otherwise just allocate @@ -138,9 +141,6 @@ HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_siz frag_size = alignment - mis_align; } - if (HADDR_UNDEF == (eoa = H5F_get_eoa(f, type))) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "Unable to get eoa") - alloc_type = aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW; other_alloc_type = other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW; @@ -149,9 +149,12 @@ HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_siz /* Check if the block asked for is too large for 'normal' aggregator block */ if(size >= aggr->alloc_size) { - hsize_t ext_size = size + frag_size; + /* Check for overlapping into file's temporary allocation space */ + if(H5F_addr_gt((aggr->addr + aggr->size + ext_size), f->shared->tmp_addr)) + HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space") + if ((aggr->addr > 0) && (extended=H5FD_try_extend(f->shared->lf, alloc_type, aggr->addr + aggr->size, ext_size)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't extending space") else if (extended) { @@ -160,6 +163,10 @@ HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_siz aggr->addr += ext_size; aggr->tot_size += ext_size; } else { + /* Check for overlapping into file's temporary allocation space */ + if(H5F_addr_gt((eoa + size), f->shared->tmp_addr)) + HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space") + if ((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) && ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) { @@ -189,6 +196,10 @@ HDfprintf(stderr, "%s: Allocating block\n", FUNC); if (frag_size > (ext_size - size)) ext_size += (frag_size - (ext_size - size)); + /* Check for overlapping into file's temporary allocation space */ + if(H5F_addr_gt((aggr->addr + aggr->size + ext_size), f->shared->tmp_addr)) + HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space") + if ((aggr->addr > 0) && (extended = H5FD_try_extend(f->shared->lf, alloc_type, aggr->addr + aggr->size, ext_size)) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't extending space") else if (extended) { @@ -196,6 +207,10 @@ HDfprintf(stderr, "%s: Allocating block\n", FUNC); aggr->size += (ext_size - frag_size); aggr->tot_size += ext_size; } else { + /* Check for overlapping into file's temporary allocation space */ + if(H5F_addr_gt((eoa + aggr->alloc_size), f->shared->tmp_addr)) + HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space") + if ((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) && ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) { @@ -250,6 +265,10 @@ HDfprintf(stderr, "%s: Allocating block\n", FUNC); } } /* end if */ else { + /* Check for overlapping into file's temporary allocation space */ + if(H5F_addr_gt((eoa + size), f->shared->tmp_addr)) + HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space") + /* Allocate data from the file */ if(HADDR_UNDEF == (ret_value = H5FD_alloc(f->shared->lf, dxpl_id, type, size, &eoa_frag_addr, &eoa_frag_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate file space") @@ -258,6 +277,9 @@ HDfprintf(stderr, "%s: Allocating block\n", FUNC); HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free eoa fragment") } /* end else */ + /* Sanity check for overlapping into file's temporary allocation space */ + HDassert(H5F_addr_le((ret_value + size), f->shared->tmp_addr)); + done: #ifdef H5MF_AGGR_DEBUG HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value); diff --git a/src/H5MFprivate.h b/src/H5MFprivate.h index 0d1da8a..4508199 100644 --- a/src/H5MFprivate.h +++ b/src/H5MFprivate.h @@ -72,6 +72,9 @@ H5_DLL herr_t H5MF_try_extend(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, H5_DLL htri_t H5MF_try_shrink(H5F_t *f, H5FD_mem_t alloc_type, hid_t dxpl_id, haddr_t addr, hsize_t size); +/* File 'temporary' space allocation routines */ +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); @@ -3161,118 +3161,122 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) break; } /* end switch */ - /* Copy parent information, if we aren't sharing an already opened committed datatype */ - if(NULL == reopened_fo && old_dt->shared->parent) - new_dt->shared->parent = H5T_copy(old_dt->shared->parent, method); + /* Update fields in the new struct, if we aren't sharing an already opened + * committed datatype */ + if(!reopened_fo) { + /* Copy parent information */ + if(old_dt->shared->parent) + new_dt->shared->parent = H5T_copy(old_dt->shared->parent, method); + + switch(new_dt->shared->type) { + case H5T_COMPOUND: + { + int accum_change = 0; /* Amount of change in the offset of the fields */ - switch(new_dt->shared->type) { - case H5T_COMPOUND: - { - int accum_change = 0; /* Amount of change in the offset of the fields */ + /* + * Copy all member fields to new type, then overwrite the + * name and type fields of each new member with copied values. + * That is, H5T_copy() is a deep copy. + */ + /* Only malloc if space has been allocated for members - NAF */ + if(new_dt->shared->u.compnd.nalloc > 0) { + new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc * + sizeof(H5T_cmemb_t)); + if (NULL==new_dt->shared->u.compnd.memb) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb, + new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t)); + } /* end if */ - /* - * Copy all member fields to new type, then overwrite the - * name and type fields of each new member with copied values. - * That is, H5T_copy() is a deep copy. - */ - /* Only malloc if space has been allocated for members - NAF */ - if(new_dt->shared->u.compnd.nalloc > 0) { - new_dt->shared->u.compnd.memb = H5MM_malloc(new_dt->shared->u.compnd.nalloc * - sizeof(H5T_cmemb_t)); - if (NULL==new_dt->shared->u.compnd.memb) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + for(i = 0; i < new_dt->shared->u.compnd.nmembs; i++) { + unsigned j; + int old_match; - HDmemcpy(new_dt->shared->u.compnd.memb, old_dt->shared->u.compnd.memb, - new_dt->shared->u.compnd.nmembs * sizeof(H5T_cmemb_t)); - } /* end if */ + s = new_dt->shared->u.compnd.memb[i].name; + new_dt->shared->u.compnd.memb[i].name = H5MM_xstrdup(s); + tmp = H5T_copy (old_dt->shared->u.compnd.memb[i].type, method); + new_dt->shared->u.compnd.memb[i].type = tmp; + HDassert(tmp != NULL); - for(i = 0; i < new_dt->shared->u.compnd.nmembs; i++) { - unsigned j; - int old_match; + /* Apply the accumulated size change to the offset of the field */ + new_dt->shared->u.compnd.memb[i].offset += accum_change; + + if(old_dt->shared->u.compnd.sorted != H5T_SORT_VALUE) { + for(old_match = -1, j = 0; j < old_dt->shared->u.compnd.nmembs; j++) { + if(!HDstrcmp(new_dt->shared->u.compnd.memb[i].name, old_dt->shared->u.compnd.memb[j].name)) { + old_match = j; + break; + } /* end if */ + } /* end for */ + + /* check if we couldn't find a match */ + if(old_match < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted"); + } /* end if */ + else + old_match = i; - s = new_dt->shared->u.compnd.memb[i].name; - new_dt->shared->u.compnd.memb[i].name = H5MM_xstrdup(s); - tmp = H5T_copy (old_dt->shared->u.compnd.memb[i].type, method); - new_dt->shared->u.compnd.memb[i].type = tmp; - HDassert(tmp != NULL); + /* If the field changed size, add that change to the accumulated size change */ + if(new_dt->shared->u.compnd.memb[i].type->shared->size != old_dt->shared->u.compnd.memb[old_match].type->shared->size) { + /* Adjust the size of the member */ + new_dt->shared->u.compnd.memb[i].size = (old_dt->shared->u.compnd.memb[old_match].size*tmp->shared->size)/old_dt->shared->u.compnd.memb[old_match].type->shared->size; - /* Apply the accumulated size change to the offset of the field */ - new_dt->shared->u.compnd.memb[i].offset += accum_change; + accum_change += (new_dt->shared->u.compnd.memb[i].type->shared->size - old_dt->shared->u.compnd.memb[old_match].type->shared->size); + } /* end if */ + } /* end for */ - if(old_dt->shared->u.compnd.sorted != H5T_SORT_VALUE) { - for(old_match = -1, j = 0; j < old_dt->shared->u.compnd.nmembs; j++) { - if(!HDstrcmp(new_dt->shared->u.compnd.memb[i].name, old_dt->shared->u.compnd.memb[j].name)) { - old_match = j; - break; - } /* end if */ - } /* end for */ + /* Apply the accumulated size change to the size of the compound struct */ + new_dt->shared->size += accum_change; - /* check if we couldn't find a match */ - if(old_match < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "fields in datatype corrupted"); - } /* end if */ - else - old_match = i; + } + break; - /* If the field changed size, add that change to the accumulated size change */ - if(new_dt->shared->u.compnd.memb[i].type->shared->size != old_dt->shared->u.compnd.memb[old_match].type->shared->size) { - /* Adjust the size of the member */ - new_dt->shared->u.compnd.memb[i].size = (old_dt->shared->u.compnd.memb[old_match].size*tmp->shared->size)/old_dt->shared->u.compnd.memb[old_match].type->shared->size; + case H5T_ENUM: + /* + * Copy all member fields to new type, then overwrite the name fields + * of each new member with copied values. That is, H5T_copy() is a + * deep copy. + */ + new_dt->shared->u.enumer.name = H5MM_malloc(new_dt->shared->u.enumer.nalloc * + sizeof(char*)); + new_dt->shared->u.enumer.value = H5MM_malloc(new_dt->shared->u.enumer.nalloc * + new_dt->shared->size); + if(NULL == new_dt->shared->u.enumer.value) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDmemcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value, + new_dt->shared->u.enumer.nmembs * new_dt->shared->size); + for(i = 0; i < new_dt->shared->u.enumer.nmembs; i++) { + s = old_dt->shared->u.enumer.name[i]; + new_dt->shared->u.enumer.name[i] = H5MM_xstrdup(s); + } /* end for */ + break; - accum_change += (new_dt->shared->u.compnd.memb[i].type->shared->size - old_dt->shared->u.compnd.memb[old_match].type->shared->size); + case H5T_VLEN: + case H5T_REFERENCE: + if(method == H5T_COPY_TRANSIENT || method == H5T_COPY_REOPEN) { + /* H5T_copy converts any type into a memory type */ + if(H5T_set_loc(new_dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location"); } /* end if */ - } /* end for */ - - /* Apply the accumulated size change to the size of the compound struct */ - new_dt->shared->size += accum_change; - - } - break; - - case H5T_ENUM: - /* - * Copy all member fields to new type, then overwrite the name fields - * of each new member with copied values. That is, H5T_copy() is a - * deep copy. - */ - new_dt->shared->u.enumer.name = H5MM_malloc(new_dt->shared->u.enumer.nalloc * - sizeof(char*)); - new_dt->shared->u.enumer.value = H5MM_malloc(new_dt->shared->u.enumer.nalloc * - new_dt->shared->size); - if(NULL == new_dt->shared->u.enumer.value) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - HDmemcpy(new_dt->shared->u.enumer.value, old_dt->shared->u.enumer.value, - new_dt->shared->u.enumer.nmembs * new_dt->shared->size); - for(i = 0; i < new_dt->shared->u.enumer.nmembs; i++) { - s = old_dt->shared->u.enumer.name[i]; - new_dt->shared->u.enumer.name[i] = H5MM_xstrdup(s); - } /* end for */ - break; - - case H5T_VLEN: - case H5T_REFERENCE: - if(method == H5T_COPY_TRANSIENT || method == H5T_COPY_REOPEN) { - /* H5T_copy converts any type into a memory type */ - if(H5T_set_loc(new_dt, NULL, H5T_LOC_MEMORY) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location"); - } /* end if */ - break; + break; - case H5T_OPAQUE: - /* - * Copy the tag name. - */ - new_dt->shared->u.opaque.tag = H5MM_xstrdup(new_dt->shared->u.opaque.tag); - break; + case H5T_OPAQUE: + /* + * Copy the tag name. + */ + new_dt->shared->u.opaque.tag = H5MM_xstrdup(new_dt->shared->u.opaque.tag); + break; - case H5T_ARRAY: - /* Re-compute the array's size, in case it's base type changed size */ - new_dt->shared->size=new_dt->shared->u.array.nelem*new_dt->shared->parent->shared->size; - break; + case H5T_ARRAY: + /* Re-compute the array's size, in case it's base type changed size */ + new_dt->shared->size=new_dt->shared->u.array.nelem*new_dt->shared->parent->shared->size; + break; - default: - break; - } /* end switch */ + default: + break; + } /* end switch */ + } /* end if */ /* Set the cached location & name path if the original type was a named * type and the new type is also named. diff --git a/src/H5public.h b/src/H5public.h index f138a16..86cce90 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -71,10 +71,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 41 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 42 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.41" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.42" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/H5win32defs.h b/src/H5win32defs.h index 93695fb..89b41a0 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -47,7 +47,7 @@ typedef __int64 h5_stat_size_t; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - int HDgettimeofday(struct timeval *tv, void *tz); + H5_DLL int HDgettimeofday(struct timeval *tv, void *tz); #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/Makefile.in b/src/Makefile.in index 7fe58fc..914b414 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -409,7 +409,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 31 +LT_VERS_REVISION = 32 LT_VERS_AGE = 0 H5detect_CFLAGS = -g |