AsyncFile.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:24k
- /* Copyright (C) 2003 MySQL AB
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
- #include <ndb_global.h>
- #include <my_sys.h>
- #include <my_pthread.h>
- #include <Error.hpp>
- #include "AsyncFile.hpp"
- #include <ErrorHandlingMacros.hpp>
- #include <kernel_types.h>
- #include <NdbMem.h>
- #include <NdbThread.h>
- #include <signaldata/FsOpenReq.hpp>
- // use this to test broken pread code
- //#define HAVE_BROKEN_PREAD
- #ifdef HAVE_BROKEN_PREAD
- #undef HAVE_PWRITE
- #undef HAVE_PREAD
- #endif
- #if defined NDB_WIN32 || defined NDB_OSE || defined NDB_SOFTOSE
- #else
- // For readv and writev
- #include <sys/uio.h>
- #endif
- #ifndef NDB_WIN32
- #include <dirent.h>
- #endif
- // Use this define if you want printouts from AsyncFile class
- //#define DEBUG_ASYNCFILE
- #ifdef DEBUG_ASYNCFILE
- #include <NdbOut.hpp>
- #define DEBUG(x) x
- #define PRINT_ERRORANDFLAGS(f) printErrorAndFlags(f)
- void printErrorAndFlags(Uint32 used_flags);
- #else
- #define DEBUG(x)
- #define PRINT_ERRORANDFLAGS(f)
- #endif
- // Define the size of the write buffer (for each thread)
- #if defined NDB_SOFTOSE || defined NDB_OSE
- #define WRITEBUFFERSIZE 65536
- #else
- #define WRITEBUFFERSIZE 262144
- #endif
- const char *actionName[] = {
- "open",
- "close",
- "closeRemove",
- "read",
- "readv",
- "write",
- "writev",
- "writeSync",
- "writevSync",
- "sync",
- "end" };
- static int numAsyncFiles = 0;
- extern "C" void * runAsyncFile(void* arg)
- {
- ((AsyncFile*)arg)->run();
- return (NULL);
- }
- AsyncFile::AsyncFile() :
- theFileName(),
- #ifdef NDB_WIN32
- hFile(INVALID_HANDLE_VALUE),
- #else
- theFd(-1),
- #endif
- theReportTo(0),
- theMemoryChannelPtr(NULL)
- {
- }
- void
- AsyncFile::doStart(Uint32 nodeId,
- const char * filesystemPath,
- const char * backup_path) {
- theFileName.init(nodeId, filesystemPath, backup_path);
- // Stacksize for filesystem threads
- // An 8k stack should be enough
- const NDB_THREAD_STACKSIZE stackSize = 8192;
- char buf[16];
- numAsyncFiles++;
- BaseString::snprintf(buf, sizeof(buf), "AsyncFile%d", numAsyncFiles);
- theStartMutexPtr = NdbMutex_Create();
- theStartConditionPtr = NdbCondition_Create();
- NdbMutex_Lock(theStartMutexPtr);
- theStartFlag = false;
- theThreadPtr = NdbThread_Create(runAsyncFile,
- (void**)this,
- stackSize,
- (char*)&buf,
- NDB_THREAD_PRIO_MEAN);
- NdbCondition_Wait(theStartConditionPtr,
- theStartMutexPtr);
- NdbMutex_Unlock(theStartMutexPtr);
- NdbMutex_Destroy(theStartMutexPtr);
- NdbCondition_Destroy(theStartConditionPtr);
- }
- AsyncFile::~AsyncFile()
- {
- void *status;
- Request request;
- request.action = Request::end;
- theMemoryChannelPtr->writeChannel( &request );
- NdbThread_WaitFor(theThreadPtr, &status);
- NdbThread_Destroy(&theThreadPtr);
- delete theMemoryChannelPtr;
- }
- void
- AsyncFile::reportTo( MemoryChannel<Request> *reportTo )
- {
- theReportTo = reportTo;
- }
- void AsyncFile::execute(Request* request)
- {
- theMemoryChannelPtr->writeChannel( request );
- }
- void
- AsyncFile::run()
- {
- Request *request;
- // Create theMemoryChannel in the thread that will wait for it
- NdbMutex_Lock(theStartMutexPtr);
- theMemoryChannelPtr = new MemoryChannel<Request>();
- theStartFlag = true;
- // Create write buffer for bigger writes
- theWriteBufferSize = WRITEBUFFERSIZE;
- theWriteBuffer = (char *) NdbMem_Allocate(theWriteBufferSize);
- NdbMutex_Unlock(theStartMutexPtr);
- NdbCondition_Signal(theStartConditionPtr);
-
- if (!theWriteBuffer) {
- DEBUG(ndbout_c("AsyncFile::writeReq, Failed allocating write buffer"));
- return;
- }//if
- while (1) {
- request = theMemoryChannelPtr->readChannel();
- if (!request) {
- DEBUG(ndbout_c("Nothing read from Memory Channel in AsyncFile"));
- endReq();
- return;
- }//if
- switch (request->action) {
- case Request:: open:
- openReq(request);
- break;
- case Request:: close:
- closeReq(request);
- break;
- case Request:: closeRemove:
- closeReq(request);
- removeReq(request);
- break;
- case Request:: read:
- readReq(request);
- break;
- case Request:: readv:
- readvReq(request);
- break;
- case Request:: write:
- writeReq(request);
- break;
- case Request:: writev:
- writevReq(request);
- break;
- case Request:: writeSync:
- writeReq(request);
- syncReq(request);
- break;
- case Request:: writevSync:
- writevReq(request);
- syncReq(request);
- break;
- case Request:: sync:
- syncReq(request);
- break;
- case Request:: append:
- appendReq(request);
- break;
- case Request::rmrf:
- rmrfReq(request, (char*)theFileName.c_str(), request->par.rmrf.own_directory);
- break;
- case Request:: end:
- if (theFd > 0)
- closeReq(request);
- endReq();
- return;
- default:
- abort();
- break;
- }//switch
-
- // No need to signal as ndbfs only uses tryRead
- theReportTo->writeChannelNoSignal(request);
- }//while
- }//AsyncFile::run()
- extern bool Global_useO_SYNC;
- extern bool Global_useO_DIRECT;
- extern bool Global_unlinkO_CREAT;
- extern Uint32 Global_syncFreq;
- void AsyncFile::openReq(Request* request)
- {
- m_openedWithSync = false;
- m_syncFrequency = 0;
- m_syncCount= 0;
- // for open.flags, see signal FSOPENREQ
- #ifdef NDB_WIN32
- DWORD dwCreationDisposition;
- DWORD dwDesiredAccess = 0;
- DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
- DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS | FILE_FLAG_NO_BUFFERING;
- const Uint32 flags = request->par.open.flags;
-
- // Convert file open flags from Solaris to Windows
- if ((flags & FsOpenReq::OM_CREATE) && (flags & FsOpenReq::OM_TRUNCATE)){
- dwCreationDisposition = CREATE_ALWAYS;
- } else if (flags & FsOpenReq::OM_TRUNCATE){
- dwCreationDisposition = TRUNCATE_EXISTING;
- } else if (flags & FsOpenReq::OM_CREATE){
- dwCreationDisposition = CREATE_NEW;
- } else {
- dwCreationDisposition = OPEN_EXISTING;
- }
-
- switch(flags & 3){
- case FsOpenReq::OM_READONLY:
- dwDesiredAccess = GENERIC_READ;
- break;
- case FsOpenReq::OM_WRITEONLY:
- dwDesiredAccess = GENERIC_WRITE;
- break;
- case FsOpenReq::OM_READWRITE:
- dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
- break;
- default:
- request->error = 1000;
- break;
- return;
- }
- hFile = CreateFile(theFileName.c_str(), dwDesiredAccess, dwShareMode,
- 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
-
- if(INVALID_HANDLE_VALUE == hFile) {
- request->error = GetLastError();
- if(((ERROR_PATH_NOT_FOUND == request->error) || (ERROR_INVALID_NAME == request->error))
- && (flags & FsOpenReq::OM_CREATE)) {
- createDirectories();
- hFile = CreateFile(theFileName.c_str(), dwDesiredAccess, dwShareMode,
- 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
-
- if(INVALID_HANDLE_VALUE == hFile)
- request->error = GetLastError();
- else
- request->error = 0;
-
- return;
- }
- }
- else {
- request->error = 0;
- return;
- }
- #else
- const Uint32 flags = request->par.open.flags;
- Uint32 new_flags = 0;
- // Convert file open flags from Solaris to Liux
- if(flags & FsOpenReq::OM_CREATE){
- new_flags |= O_CREAT;
- }
- if(flags & FsOpenReq::OM_TRUNCATE){
- #if 0
- if(Global_unlinkO_CREAT){
- unlink(theFileName.c_str());
- } else
- #endif
- new_flags |= O_TRUNC;
- }
- if(flags & FsOpenReq::OM_APPEND){
- new_flags |= O_APPEND;
- }
- if(flags & FsOpenReq::OM_SYNC){
- #if 0
- if(Global_useO_SYNC){
- new_flags |= O_SYNC;
- m_openedWithSync = true;
- m_syncFrequency = 0;
- } else {
- #endif
- m_openedWithSync = false;
- m_syncFrequency = Global_syncFreq;
- #if 0
- }
- #endif
- } else {
- m_openedWithSync = false;
- m_syncFrequency = 0;
- }
- #if 0
- //#if NDB_LINUX
- if(Global_useO_DIRECT){
- new_flags |= O_DIRECT;
- }
- #endif
- switch(flags & 0x3){
- case FsOpenReq::OM_READONLY:
- new_flags |= O_RDONLY;
- break;
- case FsOpenReq::OM_WRITEONLY:
- new_flags |= O_WRONLY;
- break;
- case FsOpenReq::OM_READWRITE:
- new_flags |= O_RDWR;
- break;
- default:
- request->error = 1000;
- break;
- return;
- }
- const int mode = S_IRUSR | S_IWUSR | S_IRGRP;
-
- if (-1 == (theFd = ::open(theFileName.c_str(), new_flags, mode))) {
- PRINT_ERRORANDFLAGS(new_flags);
- if( (errno == ENOENT ) && (new_flags & O_CREAT ) ) {
- createDirectories();
- if (-1 == (theFd = ::open(theFileName.c_str(), new_flags, mode))) {
- PRINT_ERRORANDFLAGS(new_flags);
- request->error = errno;
- }
- } else {
- request->error = errno;
- }
- }
- #endif
- }
- int
- AsyncFile::readBuffer(char * buf, size_t size, off_t offset){
- int return_value;
-
- #ifdef NDB_WIN32
- DWORD dwSFP = SetFilePointer(hFile, offset, 0, FILE_BEGIN);
- if(dwSFP != offset) {
- return GetLastError();
- }
- #elif ! defined(HAVE_PREAD)
- off_t seek_val;
- while((seek_val= lseek(theFd, offset, SEEK_SET)) == (off_t)-1
- && errno == EINTR);
- if(seek_val == (off_t)-1)
- {
- return errno;
- }
- #endif
-
- while (size > 0) {
- size_t bytes_read = 0;
-
- #ifdef NDB_WIN32
- DWORD dwBytesRead;
- BOOL bRead = ReadFile(hFile,
- buf,
- size,
- &dwBytesRead,
- 0);
- if(!bRead){
- return GetLastError();
- }
- bytes_read = dwBytesRead;
- #elif ! defined(HAVE_PREAD)
- return_value = ::read(theFd, buf, size);
- #else // UNIX
- return_value = ::pread(theFd, buf, size, offset);
- #endif
- #ifndef NDB_WIN32
- if (return_value == -1 && errno == EINTR) {
- DEBUG(ndbout_c("EINTR in read"));
- continue;
- } else if (return_value == -1){
- return errno;
- } else {
- bytes_read = return_value;
- }
- #endif
- if(bytes_read == 0){
- DEBUG(ndbout_c("Read underflow %d %dn %xn%d %d",
- size, offset, buf, bytes_read, return_value));
- return ERR_ReadUnderflow;
- }
-
- if(bytes_read != size){
- DEBUG(ndbout_c("Warning partial read %d != %d",
- bytes_read, size));
- }
- buf += bytes_read;
- size -= bytes_read;
- offset += bytes_read;
- }
- return 0;
- }
- void
- AsyncFile::readReq( Request * request)
- {
- for(int i = 0; i < request->par.readWrite.numberOfPages ; i++) {
- off_t offset = request->par.readWrite.pages[i].offset;
- size_t size = request->par.readWrite.pages[i].size;
- char * buf = request->par.readWrite.pages[i].buf;
-
- int err = readBuffer(buf, size, offset);
- if(err != 0){
- request->error = err;
- return;
- }
- }
- }
- void
- AsyncFile::readvReq( Request * request)
- {
- #if ! defined(HAVE_PREAD)
- readReq(request);
- return;
- #elif defined NDB_WIN32
- // ReadFileScatter?
- readReq(request);
- return;
- #else
- int return_value;
- int length = 0;
- struct iovec iov[20]; // the parameter in the signal restricts this to 20 deep
- for(int i=0; i < request->par.readWrite.numberOfPages ; i++) {
- iov[i].iov_base= request->par.readWrite.pages[i].buf;
- iov[i].iov_len= request->par.readWrite.pages[i].size;
- length = length + iov[i].iov_len;
- }
- lseek( theFd, request->par.readWrite.pages[0].offset, SEEK_SET );
- return_value = ::readv(theFd, iov, request->par.readWrite.numberOfPages);
- if (return_value == -1) {
- request->error = errno;
- return;
- } else if (return_value != length) {
- request->error = 1011;
- return;
- }
- #endif
- }
- int
- AsyncFile::extendfile(Request* request) {
- #if ! defined(HAVE_PWRITE)
- // Find max size of this file in this request
- int maxOffset = 0;
- int maxSize = 0;
- for(int i=0; i < request->par.readWrite.numberOfPages ; i++) {
- if (request->par.readWrite.pages[i].offset > maxOffset) {
- maxOffset = request->par.readWrite.pages[i].offset;
- maxSize = request->par.readWrite.pages[i].size;
- }
- }
- DEBUG(ndbout_c("extendfile: maxOffset=%d, size=%d", maxOffset, maxSize));
- // Allocate a buffer and fill it with zeros
- void* pbuf = NdbMem_Allocate(maxSize);
- memset(pbuf, 0, maxSize);
- for (int p = 0; p <= maxOffset; p = p + maxSize) {
- int return_value;
- return_value = lseek(theFd,
- p,
- SEEK_SET);
- if((return_value == -1 ) || (return_value != p)) {
- return -1;
- }
- return_value = ::write(theFd,
- pbuf,
- maxSize);
- if ((return_value == -1) || (return_value != maxSize)) {
- return -1;
- }
- }
- free(pbuf);
-
- DEBUG(ndbout_c("extendfile: "%s" OK!", theFileName.c_str()));
- return 0;
- #else
- request = request;
- abort();
- return -1;
- #endif
- }
- void
- AsyncFile::writeReq( Request * request)
- {
- int page_num = 0;
- bool write_not_complete = true;
- while(write_not_complete) {
- int totsize = 0;
- off_t offset = request->par.readWrite.pages[page_num].offset;
- char* bufptr = theWriteBuffer;
-
- write_not_complete = false;
- if (request->par.readWrite.numberOfPages > 1) {
- off_t page_offset = offset;
- // Multiple page write, copy to buffer for one write
- for(int i=page_num; i < request->par.readWrite.numberOfPages; i++) {
- memcpy(bufptr,
- request->par.readWrite.pages[i].buf,
- request->par.readWrite.pages[i].size);
- bufptr += request->par.readWrite.pages[i].size;
- totsize += request->par.readWrite.pages[i].size;
- if (((i + 1) < request->par.readWrite.numberOfPages)) {
- // There are more pages to write
- // Check that offsets are consequtive
- off_t tmp = page_offset + request->par.readWrite.pages[i].size;
- if (tmp != request->par.readWrite.pages[i+1].offset) {
- // Next page is not aligned with previous, not allowed
- DEBUG(ndbout_c("Page offsets are not aligned"));
- request->error = EINVAL;
- return;
- }
- if ((unsigned)(totsize + request->par.readWrite.pages[i+1].size) > (unsigned)theWriteBufferSize) {
- // We are not finished and the buffer is full
- write_not_complete = true;
- // Start again with next page
- page_num = i + 1;
- break;
- }
- }
- page_offset += request->par.readWrite.pages[i].size;
- }
- bufptr = theWriteBuffer;
- } else {
- // One page write, write page directly
- bufptr = request->par.readWrite.pages[0].buf;
- totsize = request->par.readWrite.pages[0].size;
- }
- int err = writeBuffer(bufptr, totsize, offset);
- if(err != 0){
- request->error = err;
- return;
- }
- } // while(write_not_complete)
- }
- int
- AsyncFile::writeBuffer(const char * buf, size_t size, off_t offset,
- size_t chunk_size)
- {
- size_t bytes_to_write = chunk_size;
- int return_value;
- #ifdef NDB_WIN32
- DWORD dwSFP = SetFilePointer(hFile, offset, 0, FILE_BEGIN);
- if(dwSFP != offset) {
- return GetLastError();
- }
- #elif ! defined(HAVE_PWRITE)
- off_t seek_val;
- while((seek_val= lseek(theFd, offset, SEEK_SET)) == (off_t)-1
- && errno == EINTR);
- if(seek_val == (off_t)-1)
- {
- return errno;
- }
- #endif
-
- while (size > 0) {
- if (size < bytes_to_write){
- // We are at the last chunk
- bytes_to_write = size;
- }
- size_t bytes_written = 0;
-
- #ifdef NDB_WIN32
- DWORD dwWritten;
- BOOL bWrite = WriteFile(hFile, buf, bytes_to_write, &dwWritten, 0);
- if(!bWrite) {
- return GetLastError();
- }
- bytes_written = dwWritten;
- if (bytes_written != bytes_to_write) {
- DEBUG(ndbout_c("Warning partial write %d != %d", bytes_written, bytes_to_write));
- }
-
- #elif ! defined(HAVE_PWRITE)
- return_value = ::write(theFd, buf, bytes_to_write);
- #else // UNIX
- return_value = ::pwrite(theFd, buf, bytes_to_write, offset);
- #endif
- #ifndef NDB_WIN32
- if (return_value == -1 && errno == EINTR) {
- bytes_written = 0;
- DEBUG(ndbout_c("EINTR in write"));
- } else if (return_value == -1){
- return errno;
- } else {
- bytes_written = return_value;
- if(bytes_written == 0){
- abort();
- }
-
- if(bytes_written != bytes_to_write){
- DEBUG(ndbout_c("Warning partial write %d != %d",
- bytes_written, bytes_to_write));
- }
- }
- #endif
-
- m_syncCount+= bytes_written;
- buf += bytes_written;
- size -= bytes_written;
- offset += bytes_written;
- }
- return 0;
- }
- void
- AsyncFile::writevReq( Request * request)
- {
- // WriteFileGather on WIN32?
- writeReq(request);
- }
- void
- AsyncFile::closeReq(Request * request)
- {
- syncReq(request);
- #ifdef NDB_WIN32
- if(!CloseHandle(hFile)) {
- request->error = GetLastError();
- }
- hFile = INVALID_HANDLE_VALUE;
- #else
- if (-1 == ::close(theFd)) {
- #ifndef DBUG_OFF
- if (theFd == -1)
- abort();
- #endif
- request->error = errno;
- }
- theFd = -1;
- #endif
- }
- bool AsyncFile::isOpen(){
- #ifdef NDB_WIN32
- return (hFile != INVALID_HANDLE_VALUE);
- #else
- return (theFd != -1);
- #endif
- }
- void
- AsyncFile::syncReq(Request * request)
- {
- if(m_openedWithSync ||
- m_syncCount == 0){
- return;
- }
- #ifdef NDB_WIN32
- if(!FlushFileBuffers(hFile)) {
- request->error = GetLastError();
- return;
- }
- #else
- if (-1 == ::fsync(theFd)){
- request->error = errno;
- return;
- }
- #endif
- m_syncCount = 0;
- }
- void
- AsyncFile::appendReq(Request * request){
-
- const char * buf = request->par.append.buf;
- Uint32 size = request->par.append.size;
- m_syncCount += size;
- #ifdef NDB_WIN32
- DWORD dwWritten = 0;
- while(size > 0){
- if(!WriteFile(hFile, buf, size, &dwWritten, 0)){
- request->error = GetLastError();
- return ;
- }
-
- buf += dwWritten;
- size -= dwWritten;
- }
- #else
- while(size > 0){
- const int n = write(theFd, buf, size);
- if(n == -1 && errno == EINTR){
- continue;
- }
- if(n == -1){
- request->error = errno;
- return;
- }
- if(n == 0){
- abort();
- }
- size -= n;
- buf += n;
- }
- #endif
- if(m_syncFrequency != 0 && m_syncCount > m_syncFrequency){
- syncReq(request);
- }
- }
- void
- AsyncFile::removeReq(Request * request)
- {
- #ifdef NDB_WIN32
- if(!DeleteFile(theFileName.c_str())) {
- request->error = GetLastError();
- }
- #else
- if (-1 == ::remove(theFileName.c_str())) {
- request->error = errno;
- }
- #endif
- }
- void
- AsyncFile::rmrfReq(Request * request, char * path, bool removePath){
- Uint32 path_len = strlen(path);
- Uint32 path_max_copy = PATH_MAX - path_len;
- char* path_add = &path[path_len];
- #ifndef NDB_WIN32
- if(!request->par.rmrf.directory){
- // Remove file
- if(unlink((const char *)path) != 0 && errno != ENOENT)
- request->error = errno;
- return;
- }
- // Remove directory
- DIR* dirp = opendir((const char *)path);
- if(dirp == 0){
- if(errno != ENOENT)
- request->error = errno;
- return;
- }
- struct dirent * dp;
- while ((dp = readdir(dirp)) != NULL){
- if ((strcmp(".", dp->d_name) != 0) && (strcmp("..", dp->d_name) != 0)) {
- BaseString::snprintf(path_add, (size_t)path_max_copy, "%s%s",
- DIR_SEPARATOR, dp->d_name);
- if(remove((const char*)path) == 0){
- path[path_len] = 0;
- continue;
- }
-
- rmrfReq(request, path, true);
- path[path_len] = 0;
- if(request->error != 0){
- closedir(dirp);
- return;
- }
- }
- }
- closedir(dirp);
- if(removePath && rmdir((const char *)path) != 0){
- request->error = errno;
- }
- return;
- #else
- if(!request->par.rmrf.directory){
- // Remove file
- if(!DeleteFile(path)){
- DWORD dwError = GetLastError();
- if(dwError!=ERROR_FILE_NOT_FOUND)
- request->error = dwError;
- }
- return;
- }
-
- strcat(path, "\*");
- WIN32_FIND_DATA ffd;
- HANDLE hFindFile = FindFirstFile(path, &ffd);
- path[path_len] = 0;
- if(INVALID_HANDLE_VALUE==hFindFile){
- DWORD dwError = GetLastError();
- if(dwError!=ERROR_PATH_NOT_FOUND)
- request->error = dwError;
- return;
- }
-
- do {
- if(0!=strcmp(".", ffd.cFileName) && 0!=strcmp("..", ffd.cFileName)){
- strcat(path, "\");
- strcat(path, ffd.cFileName);
- if(DeleteFile(path)) {
- path[path_len] = 0;
- continue;
- }//if
-
- rmrfReq(request, path, true);
- path[path_len] = 0;
- if(request->error != 0){
- FindClose(hFindFile);
- return;
- }
- }
- } while(FindNextFile(hFindFile, &ffd));
-
- FindClose(hFindFile);
-
- if(removePath && !RemoveDirectory(path))
- request->error = GetLastError();
-
- #endif
- }
- void AsyncFile::endReq()
- {
- // Thread is ended with return
- if (theWriteBuffer) NdbMem_Free(theWriteBuffer);
- }
- void AsyncFile::createDirectories()
- {
- for (int i = 0; i < theFileName.levels(); i++) {
- #ifdef NDB_WIN32
- CreateDirectory(theFileName.directory(i), 0);
- #else
- //printf("AsyncFile::createDirectories : "%s"n", theFileName.directory(i));
- mkdir(theFileName.directory(i), S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IRGRP);
- #endif
- }
- }
- #ifdef DEBUG_ASYNCFILE
- void printErrorAndFlags(Uint32 used_flags) {
- char buf[255];
- sprintf(buf, "PEAF: errno=%d "", errno);
- switch(errno) {
- case EACCES:
- strcat(buf, "EACCES");
- break;
- case EDQUOT:
- strcat(buf, "EDQUOT");
- break;
- case EEXIST :
- strcat(buf, "EEXIST");
- break;
- case EINTR :
- strcat(buf, "EINTR");
- break;
- case EFAULT :
- strcat(buf, "EFAULT");
- break;
- case EIO :
- strcat(buf, "EIO");
- break;
- case EISDIR :
- strcat(buf, "EISDIR");
- break;
- case ELOOP :
- strcat(buf, "ELOOP");
- break;
- case EMFILE :
- strcat(buf, "EMFILE");
- break;
- case ENFILE :
- strcat(buf, "ENFILE");
- break;
- case ENOENT :
- strcat(buf, "ENOENT ");
- break;
- case ENOSPC :
- strcat(buf, "ENOSPC");
- break;
- case ENOTDIR :
- strcat(buf, "ENOTDIR");
- break;
- case ENXIO :
- strcat(buf, "ENXIO");
- break;
- case EOPNOTSUPP:
- strcat(buf, "EOPNOTSUPP");
- break;
- #if !defined NDB_OSE && !defined NDB_SOFTOSE
- case EMULTIHOP :
- strcat(buf, "EMULTIHOP");
- break;
- case ENOLINK :
- strcat(buf, "ENOLINK");
- break;
- case ENOSR :
- strcat(buf, "ENOSR");
- break;
- case EOVERFLOW :
- strcat(buf, "EOVERFLOW");
- break;
- #endif
- case EROFS :
- strcat(buf, "EROFS");
- break;
- case EAGAIN :
- strcat(buf, "EAGAIN");
- break;
- case EINVAL :
- strcat(buf, "EINVAL");
- break;
- case ENOMEM :
- strcat(buf, "ENOMEM");
- break;
- case ETXTBSY :
- strcat(buf, "ETXTBSY");
- break;
- case ENAMETOOLONG:
- strcat(buf, "ENAMETOOLONG");
- break;
- case EBADF:
- strcat(buf, "EBADF");
- break;
- case ESPIPE:
- strcat(buf, "ESPIPE");
- break;
- case ESTALE:
- strcat(buf, "ESTALE");
- break;
- default:
- strcat(buf, "EOTHER");
- break;
- }
- strcat(buf, "" ");
- #if defined NDB_OSE
- strcat(buf, strerror(errno) << " ");
- #endif
- strcat(buf, " flags: ");
- switch(used_flags & 3){
- case O_RDONLY:
- strcat(buf, "O_RDONLY, ");
- break;
- case O_WRONLY:
- strcat(buf, "O_WRONLY, ");
- break;
- case O_RDWR:
- strcat(buf, "O_RDWR, ");
- break;
- default:
- strcat(buf, "Unknown!!, ");
- }
- if((used_flags & O_APPEND)==O_APPEND)
- strcat(buf, "O_APPEND, ");
- if((used_flags & O_CREAT)==O_CREAT)
- strcat(buf, "O_CREAT, ");
- if((used_flags & O_EXCL)==O_EXCL)
- strcat(buf, "O_EXCL, ");
- if((used_flags & O_NOCTTY) == O_NOCTTY)
- strcat(buf, "O_NOCTTY, ");
- if((used_flags & O_NONBLOCK)==O_NONBLOCK)
- strcat(buf, "O_NONBLOCK, ");
- if((used_flags & O_TRUNC)==O_TRUNC)
- strcat(buf, "O_TRUNC, ");
- #if !defined NDB_OSE && !defined NDB_SOFTOSE
- if((used_flags & O_DSYNC)==O_DSYNC)
- strcat(buf, "O_DSYNC, ");
- if((used_flags & O_NDELAY)==O_NDELAY)
- strcat(buf, "O_NDELAY, ");
- if((used_flags & O_RSYNC)==O_RSYNC)
- strcat(buf, "O_RSYNC, ");
- if((used_flags & O_SYNC)==O_SYNC)
- strcat(buf, "O_SYNC, ");
- DEBUG(ndbout_c(buf));
- #endif
- }
- #endif