diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2007-04-04 19:59:00 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2007-04-04 19:59:00 (GMT) |
commit | 3431f74c438b25e7aeba9062ed1e948899457b46 (patch) | |
tree | ed7a1aa1282e74a0a4646762ce82f29b1749dbec /src | |
parent | ea63d5fb19e8b260178e6f76e8ed0504ded148a3 (diff) | |
download | hdf5-3431f74c438b25e7aeba9062ed1e948899457b46.zip hdf5-3431f74c438b25e7aeba9062ed1e948899457b46.tar.gz hdf5-3431f74c438b25e7aeba9062ed1e948899457b46.tar.bz2 |
[svn-r13588] A support of files bigger than 2GB for STDIO driver. Configure will
check if fseeko is available. Using it instead of fseek can support
big files because the offset is of type off_t not long int. Also
added the test for STDIO in big.c.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5FD.c | 26 | ||||
-rw-r--r-- | src/H5FDstdio.c | 102 | ||||
-rw-r--r-- | src/H5L.c | 1 | ||||
-rw-r--r-- | src/H5config.h.in | 6 |
4 files changed, 112 insertions, 23 deletions
@@ -1535,11 +1535,11 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); if(type != H5FD_MEM_DRAW) { /* Handle metadata differently from "raw" data */ if((ret_value = H5FD_alloc_metadata(file, type, dxpl_id, size)) == HADDR_UNDEF) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't allocate for metadata") + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate for metadata") } else { /* Allocate "raw" data */ if((ret_value = H5FD_alloc_raw(file, type, dxpl_id, size)) == HADDR_UNDEF) - HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't allocate for raw data") + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate for raw data") } done: @@ -1857,7 +1857,8 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); */ if(size >= file->def_meta_block_size) { /* Allocate more room for this new block the regular way */ - new_meta = H5FD_real_alloc(file, type, dxpl_id, size); + if(HADDR_UNDEF==(new_meta = H5FD_real_alloc(file, type, dxpl_id, size))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block") /* * Check if the new metadata is at the end of the current @@ -1879,8 +1880,9 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); } } else { /* Allocate another metadata block */ - new_meta = H5FD_real_alloc(file, H5FD_MEM_DEFAULT, dxpl_id, - file->def_meta_block_size); + if(HADDR_UNDEF==(new_meta = H5FD_real_alloc(file, H5FD_MEM_DEFAULT, dxpl_id, + file->def_meta_block_size))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block") /* * Check if the new metadata is at the end of the current @@ -1916,7 +1918,8 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); } } else { /* Allocate data the regular way */ - ret_value = H5FD_real_alloc(file, type, dxpl_id, size); + if(HADDR_UNDEF==(ret_value = H5FD_real_alloc(file, type, dxpl_id, size))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block") } done: @@ -1970,7 +1973,8 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); /* Check if the block asked for is too large for the "small data" block */ if(size >= file->def_sdata_block_size) { /* Allocate more room for this new block the regular way */ - new_data = H5FD_real_alloc(file, type, dxpl_id, size); + if(HADDR_UNDEF==(new_data = H5FD_real_alloc(file, type, dxpl_id, size))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block") /* * Check if the new raw data is at the end of the current @@ -1992,8 +1996,9 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); } } else { /* Allocate another "small data" block */ - new_data = H5FD_real_alloc(file, type, dxpl_id, - file->def_sdata_block_size); + if(HADDR_UNDEF==(new_data = H5FD_real_alloc(file, type, dxpl_id, + file->def_sdata_block_size))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block") /* * Check if the new raw data is at the end of the current @@ -2032,7 +2037,8 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size); } } else { /* Allocate data the regular way */ - ret_value = H5FD_real_alloc(file, type, dxpl_id, size); + if(HADDR_UNDEF==(ret_value = H5FD_real_alloc(file, type, dxpl_id, size))) + HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block") } done: diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index e299311..87eb1dd 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -28,6 +28,7 @@ #include <stdlib.h> #include <string.h> #include <sys/stat.h> +#include <errno.h> /* Disable certain warnings in PC-Lint: */ /*lint --emacro( {534, 830}, H5P_FILE_ACCESS) */ @@ -113,6 +114,18 @@ typedef struct H5FD_stdio_t { #endif } H5FD_stdio_t; +#ifdef H5_HAVE_LSEEK64 +# define file_offset_t off64_t +# define file_truncate ftruncate64 +#elif defined (WIN32) && !defined(__MWERKS__) +# /*MSVC*/ +# define file_offset_t __int64 +# define file_truncate _chsize +#else +# define file_offset_t off_t +# define file_truncate ftruncate +#endif + /* * These macros check for overflow of various quantities. These macros * assume that file_offset_t is signed and haddr_t and size_t are unsigned. @@ -135,17 +148,8 @@ 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)) -#ifdef H5_HAVE_LSEEK64 -# define file_offset_t off64_t -# define file_truncate ftruncate64 -#elif defined (WIN32) && !defined(__MWERKS__) -# /*MSVC*/ -# define file_offset_t __int64 -# define file_truncate _chsize -#else -# define file_offset_t off_t -# define file_truncate ftruncate -#endif +/* Define big file as 2GB */ +#define BIG_FILE 0x80000000UL /* Prototypes */ static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags, @@ -153,6 +157,7 @@ static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags, static herr_t H5FD_stdio_close(H5FD_t *lf); static int H5FD_stdio_cmp(const H5FD_t *_f1, const H5FD_t *_f2); static herr_t H5FD_stdio_query(const H5FD_t *_f1, unsigned long *flags); +static haddr_t H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size); static haddr_t H5FD_stdio_get_eoa(const H5FD_t *_file, H5FD_mem_t type); static herr_t H5FD_stdio_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); static haddr_t H5FD_stdio_get_eof(const H5FD_t *_file); @@ -181,7 +186,7 @@ static const H5FD_class_t H5FD_stdio_g = { H5FD_stdio_close, /*close */ H5FD_stdio_cmp, /*cmp */ H5FD_stdio_query, /*query */ - NULL, /*alloc */ + H5FD_stdio_alloc, /*alloc */ NULL, /*free */ H5FD_stdio_get_eoa, /*get_eoa */ H5FD_stdio_set_eoa, /*set_eoa */ @@ -372,10 +377,18 @@ H5FD_stdio_open( const char *name, unsigned flags, hid_t fapl_id, file->op = H5FD_STDIO_OP_SEEK; file->pos = HADDR_UNDEF; file->write_access=write_access; /* Note the write_access for later */ - if(fseek(file->fp, (long)0, SEEK_END) < 0) { +#ifdef H5_HAVE_FSEEKO + if(fseeko(file->fp, (off_t)0, SEEK_END) < 0) { +#else + if(fseek(file->fp, (long)0L, SEEK_END) < 0) { +#endif file->op = H5FD_STDIO_OP_UNKNOWN; } else { +#ifdef H5_HAVE_FTELLO + off_t x = ftello (file->fp); +#else long x = ftell (file->fp); +#endif assert (x>=0); file->eof = (haddr_t)x; } @@ -525,6 +538,61 @@ H5FD_stdio_query(const H5FD_t *_f, unsigned long *flags /* out */) /*------------------------------------------------------------------------- + * Function: H5FD_stdio_alloc + * + * Purpose: Allocates file memory. If fseeko isn't available, makes + * sure the file size isn't bigger than 2GB because the + * parameter OFFSET of fseek is of the type LONG INT, limiting + * the file size to 2GB. + * + * Return: Success: Address of new memory + * + * Failure: HADDR_UNDEF + * + * Programmer: Raymond Lu + * 30 March 2007 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxpl_id, hsize_t size) +{ + H5FD_stdio_t *file = (H5FD_stdio_t*)_file; + haddr_t addr; + static const char *func="H5FD_stdio_alloc"; /* Function Name for error reporting */ + haddr_t ret_value; /* Return value */ + + /* Clear the error stack */ + H5Eclear_stack(H5E_DEFAULT); + + /* Compute the address for the block to allocate */ + addr = file->eoa; + + /* Check if we need to align this block */ + if(size>=file->pub.threshold) { + /* Check for an already aligned block */ + if(addr%file->pub.alignment!=0) + addr=((addr/file->pub.alignment)+1)*file->pub.alignment; + } /* end if */ + +#ifndef H5_HAVE_FSEEKO + /* If fseeko isn't available, big files (>2GB) won't be supported. */ + if(addr+size>BIG_FILE) + H5Epush_ret (func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "can't write file bigger than 2GB because fseek isn't available", -1) +#endif + + file->eoa = addr+size; + + /* Set return value */ + ret_value=addr; + + return(ret_value); +} /* H5FD_stdio_alloc() */ + + +/*------------------------------------------------------------------------- * Function: H5FD_stdio_get_eoa * * Purpose: Gets the end-of-address marker for the file. The EOA marker @@ -727,7 +795,11 @@ H5FD_stdio_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, siz */ if (!(file->op == H5FD_STDIO_OP_READ || file->op==H5FD_STDIO_OP_SEEK) || file->pos != addr) { +#ifdef H5_HAVE_FSEEKO + if (fseeko(file->fp, (off_t)addr, SEEK_SET) < 0) { +#else if (fseek(file->fp, (long)addr, SEEK_SET) < 0) { +#endif file->op = H5FD_STDIO_OP_UNKNOWN; file->pos = HADDR_UNDEF; H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1) @@ -817,7 +889,11 @@ H5FD_stdio_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, */ if ((file->op != H5FD_STDIO_OP_WRITE && file->op != H5FD_STDIO_OP_SEEK) || file->pos != addr) { +#ifdef H5_HAVE_FSEEKO + if (fseeko(file->fp, (off_t)addr, SEEK_SET) < 0) { +#else if (fseek(file->fp, (long)addr, SEEK_SET) < 0) { +#endif file->op = H5FD_STDIO_OP_UNKNOWN; file->pos = HADDR_UNDEF; H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "fseek failed", -1) @@ -855,6 +855,7 @@ H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id) herr_t ret_value = SUCCEED; FUNC_ENTER_API(H5Lexists, FAIL) + H5TRACE3("e", "i*si", loc_id, name, lapl_id); /* Check arguments */ if(H5G_loc(loc_id, &loc)) diff --git a/src/H5config.h.in b/src/H5config.h.in index 2804109..96c6520 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -100,9 +100,15 @@ /* Define to 1 if you have the `fseek64' function. */ #undef HAVE_FSEEK64 +/* Define to 1 if you have the `fseeko' function. */ +#undef HAVE_FSEEKO + /* Define to 1 if you have the `fstat64' function. */ #undef HAVE_FSTAT64 +/* Define to 1 if you have the `ftello' function. */ +#undef HAVE_FTELLO + /* Define if the compiler understand the __FUNCTION__ keyword */ #undef HAVE_FUNCTION |