diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5FDdirect.c | 86 | ||||
-rw-r--r-- | src/H5config.h.in | 3 |
2 files changed, 84 insertions, 5 deletions
diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index 8a6a27a..89bf099 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -861,6 +861,8 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha { H5FD_direct_t *file = (H5FD_direct_t*)_file; ssize_t nbytes; + herr_t ret_value=SUCCEED; /* Return value */ +#ifdef H5_HAVE_DIRECT_ALIGN size_t alloc_size; void *copy_buf, *p2, *p3; size_t _boundary; @@ -868,7 +870,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha size_t _cbsize; haddr_t copy_addr = addr; size_t copy_size = size; - herr_t ret_value=SUCCEED; /* Return value */ +#endif /*H5_HAVE_DIRECT_ALIGN*/ FUNC_ENTER_NOAPI(H5FD_direct_read, FAIL) @@ -883,6 +885,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha if (addr+size>file->eoa) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") +#ifdef H5_HAVE_DIRECT_ALIGN /* If the system requires data to be aligned */ /* Get the memory boundary for alignment, file system block size, and maximal * copy buffer size. */ @@ -928,7 +931,7 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha else alloc_size = _cbsize; if (HDposix_memalign(©_buf, _boundary, alloc_size) != 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "posix_memalign failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "HDposix_memalign failed") /* look for the aligned position for reading the data */ if(file_seek(file->fd, (file_offset_t)(copy_addr - copy_addr % _fbsize), SEEK_SET) < 0) @@ -985,6 +988,42 @@ H5FD_direct_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, ha HDfree(copy_buf); } +#else /*H5_HAVE_DIRECT_ALIGN*/ + /* If the system doesn't require data to be aligned, read the data in + * the same way as sec2 driver. + */ + + /* Seek to the correct location */ + if ((addr!=file->pos || OP_READ!=file->op) && + file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + + /* + * Read data, being careful of interrupted system calls, partial results, + * and the end of the file. + */ + while (size>0) { + do { + nbytes = HDread(file->fd, buf, size); + } while (-1==nbytes && EINTR==errno); + if (-1==nbytes) /* error */ + HSYS_GOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") + if (0==nbytes) { + /* end of file but not end of format address space */ + HDmemset(buf, 0, size); + break; + } + assert(nbytes>=0); + assert((size_t)nbytes<=size); + H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t); + size -= (size_t)nbytes; + H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t); + addr += (haddr_t)nbytes; + buf = (char*)buf + nbytes; + } + +#endif /*H5_HAVE_DIRECT_ALIGN*/ + /* Update current position */ file->pos = addr; file->op = OP_READ; @@ -1024,6 +1063,8 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h { H5FD_direct_t *file = (H5FD_direct_t*)_file; ssize_t nbytes; + herr_t ret_value=SUCCEED; /* Return value */ +#ifdef H5_HAVE_DIRECT_ALIGN size_t alloc_size; void *copy_buf, *p1, *p3; size_t _boundary; @@ -1031,7 +1072,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h size_t _cbsize; haddr_t copy_addr = addr; size_t copy_size = size; - herr_t ret_value=SUCCEED; /* Return value */ +#endif /*H5_HAVE_DIRECT_ALIGN*/ FUNC_ENTER_NOAPI(H5FD_direct_write, FAIL) @@ -1046,6 +1087,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h if (addr+size>file->eoa) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") +#ifdef H5_HAVE_DIRECT_ALIGN /* If the system requires data to be aligned */ /* Get the memory boundary for alignment, file system block size, and maximal * copy buffer size. */ @@ -1088,7 +1130,7 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h alloc_size = _cbsize; if (HDposix_memalign(©_buf, _boundary, alloc_size) != 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "posix_memalign failed") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "HDposix_memalign failed") /* look for the right position for reading the data */ if(file_seek(file->fd, (file_offset_t)(copy_addr - copy_addr % _fbsize), SEEK_SET) < 0) @@ -1162,6 +1204,37 @@ H5FD_direct_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, h HDfree(copy_buf); } +#else /*H5_HAVE_DIRECT_ALIGN*/ + /* If the system doesn't require data to be aligned, write the data in + * the same way as sec2 driver. + */ + + /* Seek to the correct location */ + if ((addr!=file->pos || OP_WRITE!=file->op) && + file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + + /* + * Write the data, being careful of interrupted system calls and partial + * results + */ + while (size>0) { + do { + nbytes = HDwrite(file->fd, buf, size); + } while (-1==nbytes && EINTR==errno); + if (-1==nbytes) /* error */ + HSYS_GOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + assert(nbytes>0); + assert((size_t)nbytes<=size); + H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t); + size -= (size_t)nbytes; + H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t); + addr += (haddr_t)nbytes; + buf = (const char*)buf + nbytes; + } + +#endif /*H5_HAVE_DIRECT_ALIGN*/ + /* Update current position and eof */ file->pos = addr; file->op = OP_WRITE; @@ -1232,13 +1305,16 @@ H5FD_direct_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing) /* Reset last file I/O information */ file->pos = HADDR_UNDEF; file->op = OP_UNKNOWN; - } else { + } +#ifdef H5_HAVE_DIRECT_ALIGN + else { /*Even though eof is equal to eoa, file is still truncated because Direct I/O *write introduces some extra data for alignment. */ if (-1==file_truncate(file->fd, (file_offset_t)file->eof)) HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") } +#endif /*H5_HAVE_DIRECT_ALIGN*/ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5config.h.in b/src/H5config.h.in index 0853964..998a616 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -57,6 +57,9 @@ /* Define if the direct I/O virtual file driver should be compiled */ #undef HAVE_DIRECT +/* Define if the direct I/O VFD requires alignment */ +#undef HAVE_DIRECT_ALIGN + /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H |