Ndbfs.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:27k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include "Ndbfs.hpp"
  15. #include "AsyncFile.hpp"
  16. #include "Filename.hpp"
  17. #include "Error.hpp"
  18. #include <signaldata/FsOpenReq.hpp>
  19. #include <signaldata/FsCloseReq.hpp>
  20. #include <signaldata/FsReadWriteReq.hpp>
  21. #include <signaldata/FsAppendReq.hpp>
  22. #include <signaldata/FsRemoveReq.hpp>
  23. #include <signaldata/FsConf.hpp>
  24. #include <signaldata/FsRef.hpp>
  25. #include <signaldata/NdbfsContinueB.hpp>
  26. #include <signaldata/DumpStateOrd.hpp>
  27. #include <RefConvert.hpp>
  28. #include <NdbSleep.h>
  29. #include <NdbOut.hpp>
  30. #include <Configuration.hpp>
  31. #define DEBUG(x) { ndbout << "FS::" << x << endl; }
  32. inline
  33. int pageSize( const NewVARIABLE* baseAddrRef )
  34. {
  35.    int log_psize;
  36.    int log_qsize = baseAddrRef->bits.q;
  37.    int log_vsize = baseAddrRef->bits.v;
  38.    if (log_vsize < 3)
  39.       log_vsize = 3;
  40.    log_psize = log_qsize + log_vsize - 3;
  41.    return (1 << log_psize);
  42. }
  43. Ndbfs::Ndbfs(const Configuration & conf) :
  44.   SimulatedBlock(NDBFS, conf),
  45.   scanningInProgress(false),
  46.   theLastId(0),
  47.   m_maxOpenedFiles(0)
  48. {
  49.   theFileSystemPath = conf.fileSystemPath();
  50.   theBackupFilePath = conf.backupFilePath();
  51.   theRequestPool = new Pool<Request>;
  52.   const ndb_mgm_configuration_iterator * p = conf.getOwnConfigIterator();
  53.   ndbrequire(p != 0);
  54.   m_maxFiles = 40;
  55.   ndb_mgm_get_int_parameter(p, CFG_DB_MAX_OPEN_FILES, &m_maxFiles);
  56.   
  57.   // Create idle AsyncFiles
  58.   Uint32 noIdleFiles = m_maxFiles > 27  ? 27 : m_maxFiles ;
  59.   for (Uint32 i = 0; i < noIdleFiles; i++){
  60.     theIdleFiles.push_back(createAsyncFile());
  61.   }
  62.   BLOCK_CONSTRUCTOR(Ndbfs);
  63.   // Set received signals
  64.   addRecSignal(GSN_DUMP_STATE_ORD,  &Ndbfs::execDUMP_STATE_ORD);
  65.   addRecSignal(GSN_STTOR,  &Ndbfs::execSTTOR);
  66.   addRecSignal(GSN_FSOPENREQ, &Ndbfs::execFSOPENREQ);
  67.   addRecSignal(GSN_FSCLOSEREQ, &Ndbfs::execFSCLOSEREQ);
  68.   addRecSignal(GSN_FSWRITEREQ, &Ndbfs::execFSWRITEREQ);
  69.   addRecSignal(GSN_FSREADREQ, &Ndbfs::execFSREADREQ);
  70.   addRecSignal(GSN_FSSYNCREQ, &Ndbfs::execFSSYNCREQ);
  71.   addRecSignal(GSN_CONTINUEB, &Ndbfs::execCONTINUEB);
  72.   addRecSignal(GSN_FSAPPENDREQ, &Ndbfs::execFSAPPENDREQ);
  73.   addRecSignal(GSN_FSREMOVEREQ, &Ndbfs::execFSREMOVEREQ);
  74.    // Set send signals
  75. }
  76. Ndbfs::~Ndbfs()
  77. {
  78.   // Delete all files
  79.   // AsyncFile destuctor will take care of deleting
  80.   // the thread it has created
  81.   for (unsigned i = 0; i < theFiles.size(); i++){
  82.     AsyncFile* file = theFiles[i];
  83.     delete file; 
  84.     theFiles[i] = NULL;
  85.   }//for
  86.   theFiles.clear();
  87.   delete theRequestPool;
  88. }
  89. /* Received a restart signal.
  90.  * Answer it like any other block
  91.  * PR0  : StartCase
  92.  * DR0  : StartPhase
  93.  * DR1  : ?
  94.  * DR2  : ?
  95.  * DR3  : ?
  96.  * DR4  : ?
  97.  * DR5  : SignalKey
  98.  */
  99. void
  100. Ndbfs::execSTTOR(Signal* signal)
  101. {
  102.   jamEntry();
  103.   
  104.   if(signal->theData[1] == 0){ // StartPhase 0
  105.     jam();
  106.     cownref = NDBFS_REF;
  107.     // close all open files
  108.     ndbrequire(theOpenFiles.size() == 0);
  109.     
  110.     scanningInProgress = false;
  111.     
  112.     signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY;
  113.     sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 1);
  114.     signal->theData[3] = 255;
  115.     sendSignal(NDBCNTR_REF, GSN_STTORRY, signal,4, JBB);
  116.     return;
  117.   }
  118.   ndbrequire(0);
  119. }
  120. int 
  121. Ndbfs::forward( AsyncFile * file, Request* request)
  122. {
  123.   jam();
  124.   file->execute(request);
  125.   return 1;
  126. }
  127. void 
  128. Ndbfs::execFSOPENREQ(Signal* signal)
  129. {
  130.   jamEntry();
  131.   const FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
  132.   const BlockReference userRef = fsOpenReq->userReference;
  133.   AsyncFile* file = getIdleFile();
  134.   ndbrequire(file != NULL);
  135.   ndbrequire(signal->getLength() == FsOpenReq::SignalLength)
  136.   file->theFileName.set( userRef, fsOpenReq->fileNumber);
  137.   file->reportTo(&theFromThreads);
  138.   
  139.   Request* request = theRequestPool->get();
  140.   request->action = Request::open;
  141.   request->error = 0;
  142.   request->par.open.flags = fsOpenReq->fileFlags;
  143.   request->set(userRef, fsOpenReq->userPointer, newId() );
  144.   request->file = file;
  145.   request->theTrace = signal->getTrace();
  146.   
  147.   ndbrequire(forward(file, request));
  148. }
  149. void 
  150. Ndbfs::execFSREMOVEREQ(Signal* signal)
  151. {
  152.   jamEntry();
  153.   const FsRemoveReq * const req = (FsRemoveReq *)signal->getDataPtr();
  154.   const BlockReference userRef = req->userReference;
  155.   AsyncFile* file = getIdleFile();
  156.   ndbrequire(file != NULL);
  157.   file->theFileName.set( userRef, req->fileNumber, req->directory);
  158.   file->reportTo(&theFromThreads);
  159.   
  160.   Request* request = theRequestPool->get();
  161.   request->action = Request::rmrf;
  162.   request->par.rmrf.directory = req->directory;
  163.   request->par.rmrf.own_directory = req->ownDirectory;
  164.   request->error = 0;
  165.   request->set(userRef, req->userPointer, newId() );
  166.   request->file = file;
  167.   request->theTrace = signal->getTrace();
  168.   
  169.   ndbrequire(forward(file, request));
  170. }
  171. /*
  172.  * PR0: File Pointer DR0: User reference DR1: User Pointer DR2: Flag bit 0= 1
  173.  * remove file
  174.  */
  175. void 
  176. Ndbfs::execFSCLOSEREQ(Signal * signal)
  177. {
  178.   jamEntry();
  179.   const FsCloseReq * const fsCloseReq = (FsCloseReq *)&signal->theData[0];
  180.   const BlockReference userRef = fsCloseReq->userReference;
  181.   const Uint16 filePointer = (Uint16)fsCloseReq->filePointer;
  182.   const UintR userPointer = fsCloseReq->userPointer; 
  183.   AsyncFile* openFile = theOpenFiles.find(filePointer);
  184.   if (openFile == NULL) {
  185.     // The file was not open, send error back to sender
  186.     jam();    
  187.     // Initialise FsRef signal
  188.     FsRef * const fsRef = (FsRef *)&signal->theData[0];
  189.     fsRef->userPointer  = userPointer; 
  190.     fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrFileDoesNotExist);
  191.     fsRef->osErrorCode  = ~0; // Indicate local error
  192.     sendSignal(userRef, GSN_FSCLOSEREF, signal, 3, JBB);
  193.     return;
  194.   }
  195.   Request *request = theRequestPool->get();
  196.   if( fsCloseReq->getRemoveFileFlag(fsCloseReq->fileFlag) == true ) {
  197.      jam();
  198.      request->action = Request::closeRemove;
  199.   } else {
  200.      jam();
  201.      request->action = Request::close;
  202.   }
  203.   request->set(userRef, fsCloseReq->userPointer, filePointer);
  204.   request->file = openFile;
  205.   request->error = 0;
  206.   request->theTrace = signal->getTrace();
  207.   ndbrequire(forward(openFile, request));
  208. }
  209. void 
  210. Ndbfs::readWriteRequest(int action, Signal * signal)
  211. {
  212.   const FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
  213.   Uint16 filePointer =  (Uint16)fsRWReq->filePointer;
  214.   const UintR userPointer = fsRWReq->userPointer; 
  215.   const BlockReference userRef = fsRWReq->userReference;
  216.   const BlockNumber blockNumber = refToBlock(userRef);
  217.   AsyncFile* openFile = theOpenFiles.find(filePointer);
  218.   const NewVARIABLE *myBaseAddrRef = &getBat(blockNumber)[fsRWReq->varIndex];
  219.   UintPtr tPageSize;
  220.   UintPtr tClusterSize;
  221.   UintPtr tNRR;
  222.   UintPtr tPageOffset;
  223.   char*        tWA;
  224.   FsRef::NdbfsErrorCodeType errorCode;
  225.   Request *request = theRequestPool->get();
  226.   request->error = 0;
  227.   request->set(userRef, userPointer, filePointer);
  228.   request->file = openFile;
  229.   request->action = (Request::Action) action;
  230.   request->theTrace = signal->getTrace();
  231.   if (fsRWReq->numberOfPages == 0) { //Zero pages not allowed
  232.     jam();
  233.     errorCode = FsRef::fsErrInvalidParameters;
  234.     goto error;
  235.   }
  236.   if (fsRWReq->varIndex >= getBatSize(blockNumber)) {
  237.     jam();// Ensure that a valid variable is used    
  238.     errorCode = FsRef::fsErrInvalidParameters;
  239.     goto error;
  240.   }
  241.   if (myBaseAddrRef == NULL) {
  242.     jam(); // Ensure that a valid variable is used
  243.     errorCode = FsRef::fsErrInvalidParameters;
  244.     goto error;
  245.   }
  246.   if (openFile == NULL) {
  247.     jam(); //file not open
  248.     errorCode = FsRef::fsErrFileDoesNotExist;
  249.     goto error;
  250.   }
  251.   tPageSize = pageSize(myBaseAddrRef);
  252.   tClusterSize = myBaseAddrRef->ClusterSize;
  253.   tNRR = myBaseAddrRef->nrr;
  254.   tWA = (char*)myBaseAddrRef->WA;
  255.  
  256.   switch (fsRWReq->getFormatFlag(fsRWReq->operationFlag)) {
  257.   // List of memory and file pages pairs
  258.   case FsReadWriteReq::fsFormatListOfPairs: { 
  259.     jam();
  260.     for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) {
  261.       jam();
  262.       const UintPtr varIndex = fsRWReq->data.listOfPair[i].varIndex;
  263.       const UintPtr fileOffset = fsRWReq->data.listOfPair[i].fileOffset;
  264.       if (varIndex >= tNRR) {
  265.         jam();
  266.         errorCode = FsRef::fsErrInvalidParameters;
  267.         goto error;
  268.       }//if
  269.       request->par.readWrite.pages[i].buf = &tWA[varIndex * tClusterSize];
  270.       request->par.readWrite.pages[i].size = tPageSize;
  271.       request->par.readWrite.pages[i].offset = fileOffset * tPageSize;
  272.     }//for
  273.     request->par.readWrite.numberOfPages = fsRWReq->numberOfPages;
  274.     break;
  275.   }//case
  276.   // Range of memory page with one file page
  277.   case FsReadWriteReq::fsFormatArrayOfPages: { 
  278.     if ((fsRWReq->numberOfPages + fsRWReq->data.arrayOfPages.varIndex) > tNRR) {
  279.       jam();
  280.       errorCode = FsRef::fsErrInvalidParameters;
  281.       goto error;
  282.     }//if
  283.     const UintPtr varIndex = fsRWReq->data.arrayOfPages.varIndex;
  284.     const UintPtr fileOffset = fsRWReq->data.arrayOfPages.fileOffset;
  285.     
  286.     request->par.readWrite.pages[0].offset = fileOffset * tPageSize;
  287.     request->par.readWrite.pages[0].size = tPageSize * fsRWReq->numberOfPages;
  288.     request->par.readWrite.numberOfPages = 1;
  289.     request->par.readWrite.pages[0].buf = &tWA[varIndex * tPageSize];
  290.     break;
  291.   }//case
  292.   // List of memory pages followed by one file page
  293.   case FsReadWriteReq::fsFormatListOfMemPages: { 
  294.     tPageOffset = fsRWReq->data.listOfMemPages.varIndex[fsRWReq->numberOfPages];
  295.     tPageOffset *= tPageSize;
  296.     
  297.     for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) {
  298.       jam();
  299.       UintPtr varIndex = fsRWReq->data.listOfMemPages.varIndex[i];
  300.       if (varIndex >= tNRR) {
  301.         jam();
  302.         errorCode = FsRef::fsErrInvalidParameters;
  303.         goto error;
  304.       }//if
  305.       request->par.readWrite.pages[i].buf = &tWA[varIndex * tClusterSize];
  306.       request->par.readWrite.pages[i].size = tPageSize;
  307.       request->par.readWrite.pages[i].offset = tPageOffset + (i*tPageSize);
  308.     }//for
  309.     request->par.readWrite.numberOfPages = fsRWReq->numberOfPages;
  310.     break;
  311.     // make it a writev or readv
  312.   }//case
  313.   
  314.   default: {
  315.     jam();
  316.     errorCode = FsRef::fsErrInvalidParameters;
  317.     goto error;
  318.   }//default
  319.   
  320.   }//switch
  321.   
  322.   ndbrequire(forward(openFile, request));
  323.   return;
  324. error:
  325.   theRequestPool->put(request);
  326.   FsRef * const fsRef = (FsRef *)&signal->theData[0];
  327.   fsRef->userPointer = userPointer;
  328.   fsRef->setErrorCode(fsRef->errorCode, errorCode);
  329.   fsRef->osErrorCode = ~0; // Indicate local error
  330.   switch (action) {
  331.   case Request:: write:
  332.   case Request:: writeSync: {
  333.     jam();
  334.     sendSignal(userRef, GSN_FSWRITEREF, signal, 3, JBB);
  335.     break;
  336.   }//case
  337.   case Request:: read: {
  338.     jam();
  339.     sendSignal(userRef, GSN_FSREADREF, signal, 3, JBB);
  340.   }//case
  341.   }//switch
  342.   return;
  343. }
  344. /*
  345.     PR0: File Pointer , theData[0]
  346.     DR0: User reference, theData[1]
  347.     DR1: User Pointer,   etc.
  348.     DR2: Flag
  349.     DR3: Var number
  350.     DR4: amount of pages
  351.     DR5->: Memory Page id and File page id according to Flag
  352. */
  353. void 
  354. Ndbfs::execFSWRITEREQ(Signal* signal)
  355. {
  356.   jamEntry();
  357.   const FsReadWriteReq * const fsWriteReq = (FsReadWriteReq *)&signal->theData[0];
  358.   
  359.   if (fsWriteReq->getSyncFlag(fsWriteReq->operationFlag) == true){
  360.     jam();
  361.     readWriteRequest( Request::writeSync, signal );
  362.   } else {
  363.     jam();
  364.     readWriteRequest( Request::write, signal );
  365.   }
  366. }
  367. /*
  368.     PR0: File Pointer
  369.     DR0: User reference
  370.     DR1: User Pointer
  371.     DR2: Flag
  372.     DR3: Var number
  373.     DR4: amount of pages
  374.     DR5->: Memory Page id and File page id according to Flag
  375. */
  376. void 
  377. Ndbfs::execFSREADREQ(Signal* signal)
  378. {
  379.    jamEntry();
  380.    readWriteRequest( Request::read, signal );
  381. }
  382. /*
  383.  * PR0: File Pointer DR0: User reference DR1: User Pointer
  384.  */
  385. void
  386. Ndbfs::execFSSYNCREQ(Signal * signal)
  387. {
  388.   jamEntry();
  389.   Uint16 filePointer =  (Uint16)signal->theData[0];
  390.   BlockReference userRef = signal->theData[1];
  391.   const UintR userPointer = signal->theData[2]; 
  392.   AsyncFile* openFile = theOpenFiles.find(filePointer);
  393.   if (openFile == NULL) {
  394.      jam(); //file not open
  395.      FsRef * const fsRef = (FsRef *)&signal->theData[0];
  396.      fsRef->userPointer = userPointer;
  397.      fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrFileDoesNotExist);
  398.      fsRef->osErrorCode = ~0; // Indicate local error
  399.      sendSignal(userRef, GSN_FSSYNCREF, signal, 3, JBB);
  400.      return;
  401.   }
  402.   
  403.   Request *request = theRequestPool->get();
  404.   request->error = 0;
  405.   request->action = Request::sync;
  406.   request->set(userRef, userPointer, filePointer);
  407.   request->file = openFile;
  408.   request->theTrace = signal->getTrace();
  409.   
  410.   ndbrequire(forward(openFile,request));
  411. }
  412. void 
  413. Ndbfs::execFSAPPENDREQ(Signal * signal)
  414. {
  415.   const FsAppendReq * const fsReq = (FsAppendReq *)&signal->theData[0];
  416.   const Uint16 filePointer =  (Uint16)fsReq->filePointer;
  417.   const UintR userPointer = fsReq->userPointer; 
  418.   const BlockReference userRef = fsReq->userReference;
  419.   const BlockNumber blockNumber = refToBlock(userRef);
  420.   FsRef::NdbfsErrorCodeType errorCode;
  421.   AsyncFile* openFile = theOpenFiles.find(filePointer);
  422.   const NewVARIABLE *myBaseAddrRef = &getBat(blockNumber)[fsReq->varIndex];
  423.   const Uint32* tWA   = (const Uint32*)myBaseAddrRef->WA;
  424.   const Uint32  tSz   = myBaseAddrRef->nrr;
  425.   const Uint32 offset = fsReq->offset;
  426.   const Uint32 size   = fsReq->size;
  427.   Request *request = theRequestPool->get();
  428.   if (openFile == NULL) {
  429.     jam();
  430.     errorCode = FsRef::fsErrFileDoesNotExist;
  431.     goto error;
  432.   }
  433.   if (myBaseAddrRef == NULL) {
  434.     jam(); // Ensure that a valid variable is used
  435.     errorCode = FsRef::fsErrInvalidParameters;
  436.     goto error;
  437.   }
  438.   
  439.   if (fsReq->varIndex >= getBatSize(blockNumber)) {
  440.     jam();// Ensure that a valid variable is used    
  441.     errorCode = FsRef::fsErrInvalidParameters;
  442.     goto error;
  443.   }
  444.   
  445.   if(offset + size > tSz){
  446.     jam(); // Ensure that a valid variable is used
  447.     errorCode = FsRef::fsErrInvalidParameters;
  448.     goto error;
  449.   }
  450.   request->error = 0;
  451.   request->set(userRef, userPointer, filePointer);
  452.   request->file = openFile;
  453.   request->action = Request::append;
  454.   request->theTrace = signal->getTrace();
  455.   
  456.   request->par.append.buf = (const char *)(tWA + offset);
  457.   request->par.append.size = size << 2;
  458.   
  459.   ndbrequire(forward(openFile, request));
  460.   return;
  461.   
  462. error:
  463.   jam();
  464.   theRequestPool->put(request);
  465.   FsRef * const fsRef = (FsRef *)&signal->theData[0];
  466.   fsRef->userPointer = userPointer;
  467.   fsRef->setErrorCode(fsRef->errorCode, errorCode);
  468.   fsRef->osErrorCode = ~0; // Indicate local error
  469.   jam();
  470.   sendSignal(userRef, GSN_FSAPPENDREF, signal, 3, JBB);
  471.   return;
  472. }
  473. Uint16
  474. Ndbfs::newId()
  475. {
  476.   // finds a new key, eg a new filepointer
  477.   for (int i = 1; i < SHRT_MAX; i++) 
  478.   {
  479.     if (theLastId == SHRT_MAX) {
  480.       jam();
  481.       theLastId = 1;
  482.     } else {
  483.       jam();
  484.       theLastId++;
  485.     }
  486.       
  487.     if(theOpenFiles.find(theLastId) == NULL) {
  488.       jam();
  489.       return theLastId;
  490.     }
  491.   }  
  492.   ndbrequire(1 == 0);
  493.   // The program will not reach this point
  494.   return 0;
  495. }
  496. AsyncFile*
  497. Ndbfs::createAsyncFile(){
  498.   // Check limit of open files
  499.   if (theFiles.size()+1 ==  m_maxFiles) {
  500.     // Print info about all open files
  501.     for (unsigned i = 0; i < theFiles.size(); i++){
  502.       AsyncFile* file = theFiles[i];
  503.       ndbout_c("%2d (0x%x): %s", i, file, file->isOpen()?"OPEN":"CLOSED");
  504.     }
  505.     ERROR_SET(fatal, AFS_ERROR_MAXOPEN,""," Ndbfs::createAsyncFile");
  506.   }
  507.   AsyncFile* file = new AsyncFile;
  508.   file->doStart(getOwnNodeId(), theFileSystemPath, theBackupFilePath);
  509.   // Put the file in list of all files
  510.   theFiles.push_back(file);
  511. #ifdef VM_TRACE
  512.   infoEvent("NDBFS: Created new file thread %d", theFiles.size());
  513. #endif
  514.   
  515.   return file;
  516. }
  517. AsyncFile*
  518. Ndbfs::getIdleFile(){
  519.   AsyncFile* file;
  520.   if (theIdleFiles.size() > 0){
  521.     file = theIdleFiles[0];
  522.     theIdleFiles.erase(0);
  523.   } else {
  524.     file = createAsyncFile();
  525.   } 
  526.   return file;
  527. }
  528. void
  529. Ndbfs::report(Request * request, Signal* signal)
  530. {
  531.   const Uint32 orgTrace = signal->getTrace();
  532.   signal->setTrace(request->theTrace);
  533.   const BlockReference ref = request->theUserReference;
  534.   if (request->error) {
  535.     jam();
  536.     // Initialise FsRef signal
  537.     FsRef * const fsRef = (FsRef *)&signal->theData[0];
  538.     fsRef->userPointer = request->theUserPointer;
  539.     fsRef->setErrorCode(fsRef->errorCode, translateErrno(request->error));
  540.     fsRef->osErrorCode = request->error; 
  541.     switch (request->action) {
  542.     case Request:: open: {
  543.       jam();
  544.       // Put the file back in idle files list
  545.       theIdleFiles.push_back(request->file);  
  546.       sendSignal(ref, GSN_FSOPENREF, signal, FsRef::SignalLength, JBB);
  547.       break;
  548.     }
  549.     case Request:: closeRemove:
  550.     case Request:: close: {
  551.       jam();
  552.       sendSignal(ref, GSN_FSCLOSEREF, signal, FsRef::SignalLength, JBB);
  553.       break;
  554.     }
  555.     case Request:: writeSync:
  556.     case Request:: writevSync:
  557.     case Request:: write:
  558.     case Request:: writev: {
  559.       jam();
  560.       sendSignal(ref, GSN_FSWRITEREF, signal, FsRef::SignalLength, JBB);
  561.       break;
  562.     }
  563.     case Request:: read:
  564.     case Request:: readv: {
  565.       jam();
  566.       sendSignal(ref, GSN_FSREADREF, signal, FsRef::SignalLength, JBB);
  567.       break;
  568.     }
  569.     case Request:: sync: {
  570.       jam();
  571.       sendSignal(ref, GSN_FSSYNCREF, signal, FsRef::SignalLength, JBB);
  572.       break;
  573.     }
  574.     case Request::append: {
  575.       jam();
  576.       sendSignal(ref, GSN_FSAPPENDREF, signal, FsRef::SignalLength, JBB);
  577.       break;
  578.     }
  579.     case Request::rmrf: {
  580.       jam();
  581.       // Put the file back in idle files list
  582.       theIdleFiles.push_back(request->file);  
  583.       sendSignal(ref, GSN_FSREMOVEREF, signal, FsRef::SignalLength, JBB);
  584.       break;
  585.     }
  586.     
  587.     case Request:: end: {
  588.       // Report nothing
  589.       break;
  590.     }
  591.     }//switch
  592.   } else {
  593.     jam();
  594.     FsConf * const fsConf = (FsConf *)&signal->theData[0];
  595.     fsConf->userPointer = request->theUserPointer;
  596.     switch (request->action) {
  597.     case Request:: open: {
  598.       jam();
  599.       theOpenFiles.insert(request->file, request->theFilePointer);
  600.       // Keep track on max number of opened files
  601.       if (theOpenFiles.size() > m_maxOpenedFiles)
  602. m_maxOpenedFiles = theOpenFiles.size();
  603.       fsConf->filePointer = request->theFilePointer;
  604.       sendSignal(ref, GSN_FSOPENCONF, signal, 3, JBB);
  605.       break;
  606.     }
  607.     case Request:: closeRemove:
  608.     case Request:: close: {
  609.       jam();
  610.       // removes the file from OpenFiles list
  611.       theOpenFiles.erase(request->theFilePointer); 
  612.       // Put the file in idle files list
  613.       theIdleFiles.push_back(request->file); 
  614.       sendSignal(ref, GSN_FSCLOSECONF, signal, 1, JBB);
  615.       break;
  616.     }
  617.     case Request:: writeSync:
  618.     case Request:: writevSync:
  619.     case Request:: write:
  620.     case Request:: writev: {
  621.       jam();
  622.       sendSignal(ref, GSN_FSWRITECONF, signal, 1, JBB);
  623.       break;
  624.     }
  625.     case Request:: read:
  626.     case Request:: readv: {
  627.       jam();
  628.       sendSignal(ref, GSN_FSREADCONF, signal, 1, JBB);
  629.       break;
  630.     }
  631.     case Request:: sync: {
  632.       jam();
  633.       sendSignal(ref, GSN_FSSYNCCONF, signal, 1, JBB);
  634.       break;
  635.     }//case
  636.     case Request::append: {
  637.       jam();
  638.       signal->theData[1] = request->par.append.size;
  639.       sendSignal(ref, GSN_FSAPPENDCONF, signal, 2, JBB);
  640.       break;
  641.     }
  642.     case Request::rmrf: {
  643.       jam();
  644.       // Put the file in idle files list
  645.       theIdleFiles.push_back(request->file);            
  646.       sendSignal(ref, GSN_FSREMOVECONF, signal, 1, JBB);
  647.       break;
  648.     }
  649.     case Request:: end: {
  650.       // Report nothing
  651.       break;
  652.     }
  653.     }    
  654.   }//if
  655.   signal->setTrace(orgTrace);
  656. }
  657. bool
  658. Ndbfs::scanIPC(Signal* signal)
  659. {
  660.    Request* request = theFromThreads.tryReadChannel();
  661.    jam();
  662.    if (request) {
  663.       jam();
  664.       report(request, signal);
  665.       theRequestPool->put(request);
  666.       return true;
  667.    }
  668.    return false;
  669. }
  670. #if defined NDB_WIN32
  671. int Ndbfs::translateErrno(int aErrno)
  672. {
  673.   switch (aErrno)
  674.     {
  675.       //permission denied
  676.     case ERROR_ACCESS_DENIED:
  677.       return FsRef::fsErrPermissionDenied;
  678.       //temporary not accessible
  679.     case ERROR_PATH_BUSY:
  680.     case ERROR_NO_MORE_SEARCH_HANDLES:
  681.       return FsRef::fsErrTemporaryNotAccessible;
  682.       //no space left on device
  683.     case ERROR_HANDLE_DISK_FULL:
  684.     case ERROR_DISK_FULL:
  685.       return FsRef::fsErrNoSpaceLeftOnDevice;
  686.       //none valid parameters
  687.     case ERROR_INVALID_HANDLE:
  688.     case ERROR_INVALID_DRIVE:
  689.     case ERROR_INVALID_ACCESS:
  690.     case ERROR_HANDLE_EOF:
  691.     case ERROR_BUFFER_OVERFLOW:
  692.       return FsRef::fsErrInvalidParameters;
  693.       //environment error
  694.     case ERROR_CRC:
  695.     case ERROR_ARENA_TRASHED:
  696.     case ERROR_BAD_ENVIRONMENT:
  697.     case ERROR_INVALID_BLOCK:
  698.     case ERROR_WRITE_FAULT:
  699.     case ERROR_READ_FAULT:
  700.     case ERROR_OPEN_FAILED:
  701.       return FsRef::fsErrEnvironmentError;
  702.       //no more process resources
  703.     case ERROR_TOO_MANY_OPEN_FILES:
  704.     case ERROR_NOT_ENOUGH_MEMORY:
  705.     case ERROR_OUTOFMEMORY:
  706.       return FsRef::fsErrNoMoreResources;
  707.       //no file
  708.     case ERROR_FILE_NOT_FOUND:
  709.       return FsRef::fsErrFileDoesNotExist;
  710.     case ERR_ReadUnderflow:
  711.       return FsRef::fsErrReadUnderflow;
  712.     default:
  713.       return FsRef::fsErrUnknown;
  714.     }
  715. }
  716. #elif defined NDB_OSE || defined NDB_SOFTOSE
  717. int Ndbfs::translateErrno(int aErrno)
  718. {
  719.   switch (aErrno)
  720.     {
  721.       //permission denied
  722.     case EACCES:
  723.     case EROFS:
  724.     case ENXIO:
  725.       return FsRef::fsErrPermissionDenied;
  726.       //temporary not accessible
  727.     case EAGAIN:
  728.     case ETIMEDOUT:
  729.     case ENOLCK:
  730.       return FsRef::fsErrTemporaryNotAccessible;
  731.       //no space left on device
  732.     case ENFILE:
  733.     case EDQUOT:
  734.     case ENOSPC:
  735.       return FsRef::fsErrNoSpaceLeftOnDevice;
  736.       //none valid parameters
  737.     case EINVAL:
  738.     case EFBIG:
  739.     case EBADF:
  740.     case ENAMETOOLONG:
  741.     case EFAULT:
  742.     case EISDIR:
  743.       return FsRef::fsErrInvalidParameters;
  744.       //environment error
  745.     case EMLINK:
  746.     case ELOOP:
  747.       return FsRef::fsErrEnvironmentError;
  748.       //no more process resources
  749.     case EMFILE:
  750.     case ENOMEM:
  751.       return FsRef::fsErrNoMoreResources;
  752.       //no file
  753.     case ENOENT:
  754.       return FsRef::fsErrFileDoesNotExist;
  755.     case ERR_ReadUnderflow:
  756.       return FsRef::fsErrReadUnderflow;
  757.     default:
  758.       return FsRef::fsErrUnknown;
  759.     }
  760. }
  761. #else
  762. int Ndbfs::translateErrno(int aErrno)
  763. {
  764.   switch (aErrno)
  765.     {
  766.       //permission denied
  767.     case EACCES:
  768.     case EROFS:
  769.     case ENXIO:
  770.       return FsRef::fsErrPermissionDenied;
  771.       //temporary not accessible
  772.     case EAGAIN:
  773.     case ETIMEDOUT:
  774.     case ENOLCK:
  775.     case EINTR:
  776.     case EIO:
  777.       return FsRef::fsErrTemporaryNotAccessible;
  778.       //no space left on device
  779.     case ENFILE:
  780.     case EDQUOT:
  781. #ifdef ENOSR
  782.     case ENOSR:
  783. #endif
  784.     case ENOSPC:
  785.     case EFBIG:
  786.       return FsRef::fsErrNoSpaceLeftOnDevice;
  787.       //none valid parameters
  788.     case EINVAL:
  789.     case EBADF:
  790.     case ENAMETOOLONG:
  791.     case EFAULT:
  792.     case EISDIR:
  793.     case ENOTDIR:
  794.     case EEXIST:
  795.     case ETXTBSY:
  796.       return FsRef::fsErrInvalidParameters;
  797.       //environment error
  798.     case ELOOP:
  799. #ifdef ENOLINK
  800.     case ENOLINK:
  801. #endif
  802. #ifdef EMULTIHOP
  803.     case EMULTIHOP:
  804. #endif
  805. #ifdef EOPNOTSUPP
  806.     case EOPNOTSUPP:
  807. #endif
  808. #ifdef ESPIPE
  809.     case ESPIPE:
  810. #endif
  811.     case EPIPE:
  812.       return FsRef::fsErrEnvironmentError;
  813.       //no more process resources
  814.     case EMFILE:
  815.     case ENOMEM:
  816.       return FsRef::fsErrNoMoreResources;
  817.       //no file
  818.     case ENOENT:
  819.       return FsRef::fsErrFileDoesNotExist;
  820.     case ERR_ReadUnderflow:
  821.       return FsRef::fsErrReadUnderflow;
  822.       
  823.     default:
  824.       return FsRef::fsErrUnknown;
  825.     }
  826. }
  827. #endif
  828. void 
  829. Ndbfs::execCONTINUEB(Signal* signal)
  830. {
  831.   jamEntry();
  832.   if (signal->theData[0] == NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY) {
  833.     jam();
  834.     // Also send CONTINUEB to ourself in order to scan for 
  835.     // incoming answers from AsyncFile on MemoryChannel theFromThreads
  836.     signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY;
  837.     sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 1);
  838.     if (scanningInProgress == true) {
  839.       jam();
  840.       return;
  841.     }
  842.   }
  843.   if (scanIPC(signal)) {
  844.     jam();
  845.     scanningInProgress = true;
  846.     signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_NO_DELAY;    
  847.     sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
  848.    } else {
  849.     jam();
  850.     scanningInProgress = false;
  851.    }
  852.    return;
  853. }
  854. bool Global_useO_SYNC = false;
  855. bool Global_useO_DIRECT = false;
  856. bool Global_unlinkO_CREAT = false;
  857. Uint32 Global_syncFreq = 1024 * 1024;
  858. void
  859. Ndbfs::execDUMP_STATE_ORD(Signal* signal)
  860. {
  861.   if(signal->theData[0] == 19){
  862.     if(signal->length() > 1){
  863.       Global_useO_SYNC = signal->theData[1];
  864.     }
  865.     if(signal->length() > 2){
  866.       Global_syncFreq = signal->theData[2] * 1024 * 1024;
  867.     }
  868.     if(signal->length() > 3){
  869.       Global_unlinkO_CREAT = signal->theData[3];
  870.     }
  871.     if(signal->length() > 4){
  872.       Global_useO_DIRECT = signal->theData[4];
  873.     }
  874.     ndbout_c("useO_SYNC = %d syncFreq = %d unlinkO_CREATE = %d O_DIRECT = %d",
  875.      Global_useO_SYNC,
  876.      Global_syncFreq,
  877.      Global_unlinkO_CREAT,
  878.      Global_useO_DIRECT);
  879.     return;
  880.   }
  881.   if(signal->theData[0] == DumpStateOrd::NdbfsDumpFileStat){
  882.     infoEvent("NDBFS: Files: %d Open files: %d",
  883.       theFiles.size(),
  884.       theOpenFiles.size());
  885.     infoEvent(" Idle files: %d Max opened files: %d",
  886.        theIdleFiles.size(),
  887.        m_maxOpenedFiles);
  888.     infoEvent(" Max files: %d",
  889.       m_maxFiles);
  890.     infoEvent(" Requests: %d",
  891.       theRequestPool->size());
  892.     return;
  893.   }
  894.   if(signal->theData[0] == DumpStateOrd::NdbfsDumpOpenFiles){
  895.     infoEvent("NDBFS: Dump open files: %d", theOpenFiles.size());
  896.     
  897.     for (unsigned i = 0; i < theOpenFiles.size(); i++){
  898.       AsyncFile* file = theOpenFiles.getFile(i);
  899.       infoEvent("%2d (0x%x): %s", i,file, file->theFileName.c_str());
  900.     }
  901.     return;
  902.   }
  903.   if(signal->theData[0] == DumpStateOrd::NdbfsDumpAllFiles){
  904.     infoEvent("NDBFS: Dump all files: %d", theFiles.size());
  905.     
  906.     for (unsigned i = 0; i < theFiles.size(); i++){
  907.       AsyncFile* file = theFiles[i];
  908.       infoEvent("%2d (0x%x): %s", i,file, file->isOpen()?"OPEN":"CLOSED");
  909.     }
  910.     return;
  911.   }
  912.   if(signal->theData[0] == DumpStateOrd::NdbfsDumpIdleFiles){
  913.     infoEvent("NDBFS: Dump idle files: %d", theIdleFiles.size());
  914.     
  915.     for (unsigned i = 0; i < theIdleFiles.size(); i++){
  916.       AsyncFile* file = theIdleFiles[i];
  917.       infoEvent("%2d (0x%x): %s", i,file, file->isOpen()?"OPEN":"CLOSED");
  918.     }
  919.     return;
  920.   }
  921. }//Ndbfs::execDUMP_STATE_ORD()
  922. BLOCK_FUNCTIONS(Ndbfs)
  923. template class Vector<AsyncFile*>;
  924. template class Vector<OpenFiles::OpenFileItem>;
  925. template class MemoryChannel<Request>;
  926. template class Pool<Request>;