diff --git a/ftk/src/ftk.h b/ftk/src/ftk.h index e3fc976..644660c 100644 --- a/ftk/src/ftk.h +++ b/ftk/src/ftk.h @@ -1586,10 +1586,8 @@ FLMUINT64 ui64WriteOffset, FLMUINT uiBytesToWrite, const void * pvBuffer, - FLMUINT uiBufferSize, IF_IOBuffer * pBufferObj, - FLMUINT * puiBytesWritten = NULL, - FLMBOOL bZeroFill = TRUE) = 0; + FLMUINT * puiBytesWritten = NULL) = 0; virtual RCODE FLMAPI close( void) = 0; diff --git a/ftk/src/ftkerror.cpp b/ftk/src/ftkerror.cpp index 483eff1..37ca5cd 100644 --- a/ftk/src/ftkerror.cpp +++ b/ftk/src/ftkerror.cpp @@ -41,6 +41,8 @@ RCODE FLMAPI f_makeErr( { return( NE_FLM_OK); } + + f_assert( rc != NE_FLM_MEM); #if defined( FLM_DEBUG) if( bAssert) @@ -83,7 +85,7 @@ RCODE FLMAPI f_mapPlatformError( case EINVAL: { - return( RC_SET( NE_FLM_IO_PATH_TOO_LONG)); + return( RC_SET_AND_ASSERT( NE_FLM_IO_PATH_TOO_LONG)); } case EIO: diff --git a/ftk/src/ftkfsys.cpp b/ftk/src/ftkfsys.cpp index 1179351..15d1bfd 100644 --- a/ftk/src/ftkfsys.cpp +++ b/ftk/src/ftkfsys.cpp @@ -1980,7 +1980,7 @@ RCODE FLMAPI F_FileSystem::pathAppend( if (uiStrLen + 2 + f_strlen( pszPathComponent) > F_PATH_MAX_SIZE) { - return RC_SET( NE_FLM_IO_PATH_TOO_LONG); + return RC_SET_AND_ASSERT( NE_FLM_IO_PATH_TOO_LONG); } pszEnd++; @@ -1997,7 +1997,7 @@ RCODE FLMAPI F_FileSystem::pathAppend( if (uiStrLen + 1 + f_strlen( pszPathComponent) > F_PATH_MAX_SIZE) { - return RC_SET( NE_FLM_IO_PATH_TOO_LONG); + return RC_SET_AND_ASSERT( NE_FLM_IO_PATH_TOO_LONG); } } @@ -2089,7 +2089,7 @@ RCODE FLMAPI F_FileSystem::pathToStorageString( if (f_strlen( pszRealPath) >= F_PATH_MAX_SIZE) { - rc = RC_SET( NE_FLM_IO_PATH_TOO_LONG); + rc = RC_SET_AND_ASSERT( NE_FLM_IO_PATH_TOO_LONG); goto Exit; } diff --git a/ftk/src/ftkiobuf.cpp b/ftk/src/ftkiobuf.cpp index c4f16b7..cb4b6c6 100644 --- a/ftk/src/ftkiobuf.cpp +++ b/ftk/src/ftkiobuf.cpp @@ -573,13 +573,40 @@ RCODE F_IOBuffer::waitToComplete( void) #if defined( FLM_LINUX) || defined( FLM_SOLARIS) if( m_aio.aio_fildes != -1) { - const struct aiocb * pAio = &m_aio; + FLMINT iAsyncResult; + const struct aiocb * ppAio[ 1]; - if( aio_suspend( &pAio, 1, NULL) == -1) - { - rc = f_mapPlatformError( errno, NE_FLM_MEM); - } + ppAio[ 0] = &m_aio; + for( ;;) + { + aio_suspend( ppAio, 1, NULL); + iAsyncResult = aio_error( &m_aio); + + if( !iAsyncResult) + { + if( (iAsyncResult = aio_return( &m_aio)) < 0) + { + f_assert( 0); + rc = f_mapPlatformError( errno, NE_FLM_WRITING_FILE); + goto WriteComplete; + } + + break; + } + + if( iAsyncResult == EINTR || iAsyncResult == EINPROGRESS) + { + continue; + } + + f_assert( 0); + rc = f_mapPlatformError( errno, NE_FLM_WRITING_FILE); + goto WriteComplete; + } + +WriteComplete: + notifyComplete( rc); } #endif diff --git a/ftk/src/ftknlm.cpp b/ftk/src/ftknlm.cpp index 4516161..6cd670c 100644 --- a/ftk/src/ftknlm.cpp +++ b/ftk/src/ftknlm.cpp @@ -3188,8 +3188,7 @@ RCODE FLMAPI F_FileHdl::sectorWrite( const void * pvBuffer, FLMUINT uiBufferSize, void * pvBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bZeroFill) + FLMUINT * puiBytesWrittenRV) { RCODE rc = NE_FLM_OK; IF_IOBuffer * pBufferObj = (IF_IOBuffer *)pvBufferObj; @@ -3199,7 +3198,7 @@ RCODE FLMAPI F_FileHdl::sectorWrite( if ( m_bDoDirectIO) { if( RC_BAD( rc = _directIOSectorWrite( (FLMUINT)ui64WriteOffset, - uiBytesToWrite, pvBuffer, pBufferObj, puiBytesWrittenRV, bZeroFill))) + uiBytesToWrite, pvBuffer, pBufferObj, puiBytesWrittenRV))) { goto Exit; } @@ -3235,8 +3234,7 @@ RCODE F_FileHdl::_directIOSectorWrite( FLMUINT uiBytesToWrite, const void * pvBuffer, IF_IOBuffer * pBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bZeroFill) + FLMUINT * puiBytesWrittenRV) { RCODE rc = NE_FLM_OK; LONG lStartSector; @@ -3271,14 +3269,11 @@ RCODE F_FileHdl::_directIOSectorWrite( lSectorCount++; - if (bZeroFill) - { - // Zero out the part of the buffer that was not included in - // uiBytesToWrite - because it will still be written to disk. + // Zero out the part of the buffer that was not included in + // uiBytesToWrite - because it will still be written to disk. - f_memset( &pucBuffer [uiBytesToWrite], 0, - (FLMUINT)(FLM_NLM_SECTOR_SIZE - (uiBytesToWrite % FLM_NLM_SECTOR_SIZE))); - } + f_memset( &pucBuffer [uiBytesToWrite], 0, + (FLMUINT)(FLM_NLM_SECTOR_SIZE - (uiBytesToWrite % FLM_NLM_SECTOR_SIZE))); } if( RC_BAD( rc = writeSectors( (void *)pvBuffer, lStartSector, lSectorCount, diff --git a/ftk/src/ftksys.h b/ftk/src/ftksys.h index 9662bc5..cec844c 100644 --- a/ftk/src/ftksys.h +++ b/ftk/src/ftksys.h @@ -532,7 +532,7 @@ if (m_bDoDirectIO) { return( directRead( ui64ReadOffset, uiBytesToRead, - pvBuffer, TRUE, puiBytesReadRV)); + pvBuffer, puiBytesReadRV)); } else { @@ -545,17 +545,13 @@ FLMUINT64 ui64WriteOffset, FLMUINT uiBytesToWrite, const void * pvBuffer, - FLMUINT uiBufferSize, IF_IOBuffer * pBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bZeroFill = TRUE) + FLMUINT * puiBytesWrittenRV) { - F_UNREFERENCED_PARM( uiBufferSize); - if (m_bDoDirectIO) { return( directWrite( ui64WriteOffset, uiBytesToWrite, - pvBuffer, pBufferObj, TRUE, bZeroFill, puiBytesWrittenRV)); + pvBuffer, pBufferObj, puiBytesWrittenRV)); } else { @@ -631,7 +627,6 @@ FLMUINT64 uiOffset, FLMUINT uiLength, void * pvBuffer, - FLMBOOL bBuffHasFullSectors, FLMUINT * puiBytesRead); RCODE directWrite( @@ -639,8 +634,6 @@ FLMUINT uiLength, const void * pvBuffer, IF_IOBuffer * pBufferObj, - FLMBOOL bBuffHasFullSectors, - FLMBOOL bZeroFill, FLMUINT * puiBytesWritten); FINLINE FLMUINT64 roundToNextSector( @@ -736,17 +729,13 @@ FLMUINT64 ui64WriteOffset, FLMUINT uiBytesToWrite, const void * pvBuffer, - FLMUINT uiBufferSize, IF_IOBuffer * pBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bZeroFill = TRUE) + FLMUINT * puiBytesWrittenRV) { - F_UNREFERENCED_PARM( uiBufferSize); - if( m_bDoDirectIO) { return( directWrite( ui64WriteOffset, uiBytesToWrite, - pvBuffer, pBufferObj, puiBytesWrittenRV, TRUE, bZeroFill)); + pvBuffer, pBufferObj, puiBytesWrittenRV)); } else { @@ -826,7 +815,6 @@ FLMUINT64 ui64ReadOffset, FLMUINT uiBytesToRead, void * pvBuffer, - FLMBOOL bBuffHasFullSectors, FLMUINT * puiBytesRead); RCODE directWrite( @@ -834,9 +822,7 @@ FLMUINT uiBytesToWrite, const void * pvBuffer, IF_IOBuffer * pBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bBuffHasFullSectors, - FLMBOOL bZeroFill); + FLMUINT * puiBytesWrittenRV); RCODE allocAlignedBuffer( void); @@ -911,10 +897,8 @@ FLMUINT64 ui64WriteOffset, FLMUINT uiBytesToWrite, const void * pvBuffer, - FLMUINT uiBufferSize, IF_IOBuffer * pBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bZeroFill = TRUE); + FLMUINT * puiBytesWrittenRV); RCODE FLMAPI close( void); @@ -1020,8 +1004,7 @@ FLMUINT uiBytesToWrite, const void * pvBuffer, IF_IOBuffer * pBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bZeroFill); + FLMUINT * puiBytesWrittenRV); char * m_pszIoPath; FLMBOOL m_bDeleteOnClose; diff --git a/ftk/src/ftkunix.cpp b/ftk/src/ftkunix.cpp index 4741a6b..8fdc9bc 100644 --- a/ftk/src/ftkunix.cpp +++ b/ftk/src/ftkunix.cpp @@ -82,7 +82,6 @@ F_FileHdl::F_FileHdl() m_pszFileName = NULL; m_fd = -1; - m_bDoDirectIO = FALSE; m_uiExtendSize = 0; m_uiBytesPerSector = 0; m_ui64NotOnSectorBoundMask = 0; @@ -129,6 +128,7 @@ RCODE F_FileHdl::openOrCreate( char szSaveFileName[ F_PATH_MAX_SIZE]; int openFlags = O_RDONLY; IF_FileSystem * pFileSystem = f_getFileSysPtr(); + struct stat filestats; #if defined( FLM_LINUX) || defined( FLM_SOLARIS) bDoDirectIO = (uiAccess & FLM_IO_DIRECT) ? TRUE : FALSE; @@ -176,15 +176,6 @@ RCODE F_FileHdl::openOrCreate( if( bDoDirectIO) { - if( RC_BAD( rc = pFileSystem->getSectorSize( - pszFileName, &m_uiBytesPerSector))) - { - goto Exit; - } - - m_ui64NotOnSectorBoundMask = m_uiBytesPerSector - 1; - m_ui64GetSectorBoundMask = ~m_ui64NotOnSectorBoundMask; - // Can't do direct IO if the block size isn't a multiple of // the sector size. @@ -267,6 +258,15 @@ Retry_Create: } #endif + if( fstat( m_fd, &filestats) != 0) + { + rc = f_mapPlatformError( errno, NE_FLM_OPENING_FILE); + goto Exit; + } + + m_uiBytesPerSector = filestats.st_blksize; + m_ui64NotOnSectorBoundMask = m_uiBytesPerSector - 1; + m_ui64GetSectorBoundMask = ~m_ui64NotOnSectorBoundMask; m_bDoDirectIO = bDoDirectIO; Exit: @@ -592,7 +592,6 @@ RCODE F_FileHdl::directRead( FLMUINT64 ui64ReadOffset, FLMUINT uiBytesToRead, void * pvBuffer, - FLMBOOL bBuffHasFullSectors, FLMUINT * puiBytesRead) { RCODE rc = NE_FLM_OK; @@ -626,9 +625,8 @@ RCODE F_FileHdl::directRead( // one (if not already allocated), and use it. if( (ui64ReadOffset & m_ui64NotOnSectorBoundMask) || - (((FLMUINT64)(FLMUINT)pucDestBuffer) & m_ui64NotOnSectorBoundMask) || - ((uiBytesToRead & m_ui64NotOnSectorBoundMask) && - !bBuffHasFullSectors)) + (uiBytesToRead & m_ui64NotOnSectorBoundMask) || + (((FLMUINT64)(FLMUINT)pucDestBuffer) & m_ui64NotOnSectorBoundMask)) { if( !m_pucAlignedBuff) { @@ -755,7 +753,7 @@ RCODE FLMAPI F_FileHdl::read( if( m_bDoDirectIO) { rc = directRead( ui64ReadOffset, uiBytesToRead, - pvBuffer, FALSE, puiBytesRead); + pvBuffer, puiBytesRead); goto Exit; } @@ -802,7 +800,7 @@ RCODE FLMAPI F_FileHdl::sectorRead( if( m_bDoDirectIO) { return( directRead( ui64ReadOffset, uiBytesToRead, - pvBuffer, TRUE, puiBytesRead)); + pvBuffer, puiBytesRead)); } else { @@ -933,10 +931,10 @@ RCODE FLMAPI F_FileHdl::write( f_assert( m_bFileOpened); - if( m_bDoDirectIO) + if( m_bDoDirectIO || m_bOpenedInAsyncMode) { rc = directWrite( ui64WriteOffset, uiBytesToWrite, pvBuffer, - NULL, puiBytesWrittenRV, FALSE, TRUE); + NULL, puiBytesWrittenRV); goto Exit; } @@ -988,6 +986,7 @@ RCODE F_FileHdl::allocAlignedBuffer( void) // boundary if it is not already on one. m_uiAlignedBuffSize = (FLMUINT)roundUpToSectorMultiple( 64 * 1024); + f_assert( m_uiAlignedBuffSize >= m_uiBytesPerSector); #if defined( FLM_SOLARIS) if( (m_pucAlignedBuff = (FLMBYTE *)memalign( @@ -1021,9 +1020,7 @@ RCODE F_FileHdl::directWrite( FLMUINT uiBytesToWrite, const void * pvBuffer, IF_IOBuffer * pBufferObj, - FLMUINT * puiBytesWrittenRV, - FLMBOOL bBuffHasFullSectors, - FLMBOOL bZeroFill) + FLMUINT * puiBytesWrittenRV) { RCODE rc = NE_FLM_OK; FLMUINT uiBytesRead; @@ -1060,12 +1057,9 @@ RCODE F_FileHdl::directWrite( pucSrcBuffer = (FLMBYTE *)pvBuffer; for (;;) { - // See if we are using an aligned buffer. If not, allocate - // one (if not already allocated), and use it. - if( (ui64WriteOffset & m_ui64NotOnSectorBoundMask) || - (((FLMUINT64)(FLMUINT)pucSrcBuffer) & m_ui64NotOnSectorBoundMask) || - ((uiBytesToWrite & m_ui64NotOnSectorBoundMask) && !bBuffHasFullSectors)) + (uiBytesToWrite & m_ui64NotOnSectorBoundMask) || + ((FLMUINT64)(FLMUINT)pucSrcBuffer) & m_ui64NotOnSectorBoundMask) { // Cannot do an async write if we have to use a temporary buffer @@ -1108,7 +1102,7 @@ RCODE F_FileHdl::directWrite( // sector into the buffer. if( (ui64WriteOffset & m_ui64NotOnSectorBoundMask) || - (uiBytesBeingOutput < m_uiBytesPerSector && !bBuffHasFullSectors)) + (uiBytesBeingOutput < m_uiBytesPerSector)) { // Read the first sector that is to be written out. // Read one sector's worth of data - so that we will @@ -1137,15 +1131,9 @@ RCODE F_FileHdl::directWrite( } else { - uiMaxBytesToWrite = (FLMUINT)roundUpToSectorMultiple( uiBytesToWrite); - uiBytesBeingOutput = uiBytesToWrite; pucWriteBuffer = pucSrcBuffer; - - if( bZeroFill && uiMaxBytesToWrite > uiBytesToWrite) - { - f_memset( &pucWriteBuffer[ uiBytesToWrite], 0, - uiMaxBytesToWrite - uiBytesToWrite); - } + uiMaxBytesToWrite = uiBytesToWrite; + uiBytesBeingOutput = uiBytesToWrite; } // Position the file to the nearest sector below the write offset. @@ -1153,7 +1141,7 @@ RCODE F_FileHdl::directWrite( uiLastWriteOffset = (FLMUINT)getSectorStartOffset( ui64WriteOffset); uiLastWriteSize = uiMaxBytesToWrite; - if( bWaitForWrite) + if( !m_bOpenedInAsyncMode) { FLMINT iBytesWritten; @@ -1173,7 +1161,18 @@ RCODE F_FileHdl::directWrite( #ifndef FLM_NLM else { - struct aiocb * pAio = ((F_IOBuffer *)pBufferObj)->getAIOStruct(); + struct aiocb * pAio; + struct aiocb tmpAio; + + if( pBufferObj) + { + pAio = ((F_IOBuffer *)pBufferObj)->getAIOStruct(); + } + else + { + pAio = &tmpAio; + f_assert( bWaitForWrite); + } f_memset( pAio, 0, sizeof( struct aiocb)); pAio->aio_lio_opcode = LIO_WRITE; @@ -1183,13 +1182,63 @@ RCODE F_FileHdl::directWrite( pAio->aio_nbytes = uiMaxBytesToWrite; pAio->aio_buf = pucWriteBuffer; - if( aio_write( pAio) == -1) + if( aio_write( pAio) != 0) { + f_assert( 0); rc = f_mapPlatformError( errno, NE_FLM_WRITING_FILE); goto Exit; } - - pBufferObj->makePending(); + + if( bWaitForWrite) + { + struct aiocb * ppAioList[ 1]; + + ppAioList[ 0] = pAio; + + for( ;;) + { + FLMINT iAsyncResult; + + if( aio_suspend( ppAioList, 1, NULL) != 0) + { + if( errno == EINTR) + { + continue; + } + + f_assert( 0); + rc = f_mapPlatformError( errno, NE_FLM_WRITING_FILE); + goto Exit; + } + + iAsyncResult = aio_error( pAio); + + if( !iAsyncResult) + { + if( (iAsyncResult = aio_return( pAio)) < 0) + { + f_assert( 0); + rc = f_mapPlatformError( errno, NE_FLM_WRITING_FILE); + goto Exit; + } + + break; + } + + if( iAsyncResult == EINTR || iAsyncResult == EINPROGRESS) + { + continue; + } + + f_assert( 0); + rc = f_mapPlatformError( iAsyncResult, NE_FLM_WRITING_FILE); + goto Exit; + } + } + else + { + pBufferObj->makePending(); + } } #endif @@ -1406,7 +1455,7 @@ FLMUINT f_getLinuxMaxFileSize( void) f_assert( gv_uiLinuxMajorVer); - // Is version 2.4 or greater? + // Version 2.4 or greater? if( gv_uiLinuxMajorVer > 2 || (gv_uiLinuxMajorVer == 2 && gv_uiLinuxMinorVer >= 4)) diff --git a/ftk/src/ftkwin.cpp b/ftk/src/ftkwin.cpp index c9e555a..20bf152 100644 --- a/ftk/src/ftkwin.cpp +++ b/ftk/src/ftkwin.cpp @@ -612,7 +612,6 @@ RCODE F_FileHdl::directRead( FLMUINT64 ui64ReadOffset, FLMUINT uiBytesToRead, void * pvBuffer, - FLMBOOL bBuffHasFullSectors, FLMUINT * puiBytesReadRV) { RCODE rc = NE_FLM_OK; @@ -646,8 +645,7 @@ RCODE F_FileHdl::directRead( if ((ui64ReadOffset & m_ui64NotOnSectorBoundMask) || (((FLMUINT64)pucDestBuffer) & m_ui64NotOnSectorBoundMask) || - (((FLMUINT64)uiBytesToRead & m_ui64NotOnSectorBoundMask) && - (!bBuffHasFullSectors))) + (((FLMUINT64)uiBytesToRead & m_ui64NotOnSectorBoundMask))) { if (!m_pucAlignedBuff) { @@ -770,7 +768,7 @@ RCODE FLMAPI F_FileHdl::read( if (m_bDoDirectIO) { rc = directRead( ui64ReadOffset, uiBytesToRead, - pvBuffer, FALSE, puiBytesReadRV); + pvBuffer, puiBytesReadRV); goto Exit; } @@ -1084,27 +1082,25 @@ RCODE F_FileHdl::directWrite( FLMUINT uiBytesToWrite, const void * pvBuffer, IF_IOBuffer * pBufferObj, - FLMBOOL bBuffHasFullSectors, - FLMBOOL bZeroFill, FLMUINT * puiBytesWrittenRV) { - RCODE rc = NE_FLM_OK; - FLMUINT uiBytesRead; - FLMUINT uiBytesWritten; - FLMBYTE * pucWriteBuffer; - FLMBYTE * pucSrcBuffer; - FLMUINT uiMaxBytesToWrite; - FLMUINT64 ui64CurrFileSize; - FLMUINT uiBytesBeingOutput; - OVERLAPPED * pOverlapped; - DWORD udErr; - FLMBOOL bExtendFile = FALSE; - FLMBOOL bWaitForWrite = (pBufferObj == NULL) + RCODE rc = NE_FLM_OK; + FLMUINT uiBytesRead; + FLMUINT uiBytesWritten; + FLMBYTE * pucWriteBuffer; + FLMBYTE * pucSrcBuffer; + FLMUINT uiMaxBytesToWrite; + FLMUINT64 ui64CurrFileSize; + FLMUINT uiBytesBeingOutput; + OVERLAPPED * pOverlapped; + DWORD udErr; + FLMBOOL bExtendFile = FALSE; + FLMBOOL bWaitForWrite = (pBufferObj == NULL) ? TRUE : FALSE; - FLMUINT64 ui64LastWriteOffset; - FLMUINT uiLastWriteSize; - LARGE_INTEGER liTmp; + FLMUINT64 ui64LastWriteOffset; + FLMUINT uiLastWriteSize; + LARGE_INTEGER liTmp; f_assert( m_bFileOpened); @@ -1168,8 +1164,7 @@ RCODE F_FileHdl::directWrite( if ((ui64WriteOffset & m_ui64NotOnSectorBoundMask) || (((FLMUINT)pucSrcBuffer) & m_ui64NotOnSectorBoundMask) || - ((uiBytesToWrite & m_ui64NotOnSectorBoundMask) && - (!bBuffHasFullSectors))) + (uiBytesToWrite & m_ui64NotOnSectorBoundMask)) { // Cannot do an async write if we have to use a temporary buffer @@ -1231,8 +1226,7 @@ RCODE F_FileHdl::directWrite( // we must read in this sector as well. if ((uiMaxBytesToWrite > m_uiBytesPerSector) && - (uiMaxBytesToWrite > uiBytesToWrite) && - (!bBuffHasFullSectors)) + (uiMaxBytesToWrite > uiBytesToWrite)) { // Read the last sector that is to be written out. @@ -1268,14 +1262,9 @@ RCODE F_FileHdl::directWrite( } else { - uiMaxBytesToWrite = roundToNextSector( uiBytesToWrite); - uiBytesBeingOutput = uiBytesToWrite; pucWriteBuffer = pucSrcBuffer; - if( bZeroFill && uiMaxBytesToWrite > uiBytesToWrite) - { - f_memset( &pucWriteBuffer [uiBytesToWrite], 0, - uiMaxBytesToWrite - uiBytesToWrite); - } + uiMaxBytesToWrite = uiBytesToWrite; + uiBytesBeingOutput = uiBytesToWrite; } // Position the file to the nearest sector below the write offset. @@ -1433,7 +1422,7 @@ RCODE FLMAPI F_FileHdl::write( if (m_bDoDirectIO) { rc = directWrite( ui64WriteOffset, uiBytesToWrite, pvBuffer, - NULL, FALSE, FALSE, puiBytesWrittenRV); + NULL, puiBytesWrittenRV); goto Exit; }