1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include <ndb_global.h>
19
#include "AsyncFile.hpp"
20
#include "Filename.hpp"
22
#include <signaldata/FsOpenReq.hpp>
23
#include <signaldata/FsCloseReq.hpp>
24
#include <signaldata/FsReadWriteReq.hpp>
25
#include <signaldata/FsAppendReq.hpp>
26
#include <signaldata/FsRemoveReq.hpp>
27
#include <signaldata/FsConf.hpp>
28
#include <signaldata/FsRef.hpp>
29
#include <signaldata/NdbfsContinueB.hpp>
30
#include <signaldata/DumpStateOrd.hpp>
32
#include <RefConvert.hpp>
35
#include <Configuration.hpp>
37
#define DEBUG(x) { ndbout << "FS::" << x << endl; }
40
int pageSize( const NewVARIABLE* baseAddrRef )
43
int log_qsize = baseAddrRef->bits.q;
44
int log_vsize = baseAddrRef->bits.v;
47
log_psize = log_qsize + log_vsize - 3;
48
return (1 << log_psize);
52
Ndbfs::Ndbfs(Block_context& ctx) :
53
SimulatedBlock(NDBFS, ctx),
54
scanningInProgress(false),
59
BLOCK_CONSTRUCTOR(Ndbfs);
61
// Set received signals
62
addRecSignal(GSN_READ_CONFIG_REQ, &Ndbfs::execREAD_CONFIG_REQ);
63
addRecSignal(GSN_DUMP_STATE_ORD, &Ndbfs::execDUMP_STATE_ORD);
64
addRecSignal(GSN_STTOR, &Ndbfs::execSTTOR);
65
addRecSignal(GSN_FSOPENREQ, &Ndbfs::execFSOPENREQ);
66
addRecSignal(GSN_FSCLOSEREQ, &Ndbfs::execFSCLOSEREQ);
67
addRecSignal(GSN_FSWRITEREQ, &Ndbfs::execFSWRITEREQ);
68
addRecSignal(GSN_FSREADREQ, &Ndbfs::execFSREADREQ);
69
addRecSignal(GSN_FSSYNCREQ, &Ndbfs::execFSSYNCREQ);
70
addRecSignal(GSN_CONTINUEB, &Ndbfs::execCONTINUEB);
71
addRecSignal(GSN_FSAPPENDREQ, &Ndbfs::execFSAPPENDREQ);
72
addRecSignal(GSN_FSREMOVEREQ, &Ndbfs::execFSREMOVEREQ);
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];
88
delete theRequestPool;
92
Ndbfs::execREAD_CONFIG_REQ(Signal* signal)
94
const ReadConfigReq * req = (ReadConfigReq*)signal->getDataPtr();
96
Uint32 ref = req->senderRef;
97
Uint32 senderData = req->senderData;
99
const ndb_mgm_configuration_iterator * p =
100
m_ctx.m_config.getOwnConfigIterator();
102
theFileSystemPath.assfmt("%sndb_%u_fs%s", m_ctx.m_config.fileSystemPath(),
103
getOwnNodeId(), DIR_SEPARATOR);
104
theBackupFilePath.assign(m_ctx.m_config.backupFilePath());
106
theRequestPool = new Pool<Request>;
109
ndb_mgm_get_int_parameter(p, CFG_DB_MAX_OPEN_FILES, &m_maxFiles);
110
Uint32 noIdleFiles = 27;
111
ndb_mgm_get_int_parameter(p, CFG_DB_INITIAL_OPEN_FILES, &noIdleFiles);
112
if (noIdleFiles > m_maxFiles && m_maxFiles != 0)
113
m_maxFiles = noIdleFiles;
114
// Create idle AsyncFiles
115
for (Uint32 i = 0; i < noIdleFiles; i++){
116
theIdleFiles.push_back(createAsyncFile());
119
ReadConfigConf * conf = (ReadConfigConf*)signal->getDataPtrSend();
120
conf->senderRef = reference();
121
conf->senderData = senderData;
122
sendSignal(ref, GSN_READ_CONFIG_CONF, signal,
123
ReadConfigConf::SignalLength, JBB);
126
/* Received a restart signal.
127
* Answer it like any other block
137
Ndbfs::execSTTOR(Signal* signal)
141
if(signal->theData[1] == 0){ // StartPhase 0
146
CreateDirectory(theFileSystemPath.c_str(), 0);
148
mkdir(theFileSystemPath.c_str(),
149
S_IRUSR | S_IWUSR | S_IXUSR | S_IXGRP | S_IRGRP);
154
// close all open files
155
ndbrequire(theOpenFiles.size() == 0);
157
scanningInProgress = false;
159
signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY;
160
sendSignalWithDelay(cownref, GSN_CONTINUEB, signal, 10, 1);
162
signal->theData[3] = 255;
163
sendSignal(NDBCNTR_REF, GSN_STTORRY, signal,4, JBB);
170
Ndbfs::forward( AsyncFile * file, Request* request)
173
file->execute(request);
178
Ndbfs::execFSOPENREQ(Signal* signal)
181
const FsOpenReq * const fsOpenReq = (FsOpenReq *)&signal->theData[0];
182
const BlockReference userRef = fsOpenReq->userReference;
183
AsyncFile* file = getIdleFile();
184
ndbrequire(file != NULL);
185
Filename::NameSpec spec(theFileSystemPath, theBackupFilePath);
187
Uint32 userPointer = fsOpenReq->userPointer;
189
if(fsOpenReq->fileFlags & FsOpenReq::OM_INIT)
191
Ptr<GlobalPage> page_ptr;
192
if(m_global_page_pool.seize(page_ptr) == false)
194
FsRef * const fsRef = (FsRef *)&signal->theData[0];
195
fsRef->userPointer = userPointer;
196
fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrOutOfMemory);
197
fsRef->osErrorCode = ~0; // Indicate local error
198
sendSignal(userRef, GSN_FSOPENREF, signal, 3, JBB);
201
file->m_page_ptr = page_ptr;
205
ndbassert(file->m_page_ptr.isNull());
206
file->m_page_ptr.setNull();
209
if(signal->getNoOfSections() == 0){
211
file->theFileName.set(spec, userRef, fsOpenReq->fileNumber);
214
SegmentedSectionPtr ptr;
215
signal->getSection(ptr, FsOpenReq::FILENAME);
216
file->theFileName.set(spec, ptr, g_sectionSegmentPool);
217
releaseSections(signal);
219
file->reportTo(&theFromThreads);
220
if (getenv("NDB_TRACE_OPEN"))
221
ndbout_c("open(%s)", file->theFileName.c_str());
223
Request* request = theRequestPool->get();
224
request->action = Request::open;
226
request->set(userRef, userPointer, newId() );
227
request->file = file;
228
request->theTrace = signal->getTrace();
229
request->par.open.flags = fsOpenReq->fileFlags;
230
request->par.open.page_size = fsOpenReq->page_size;
231
request->par.open.file_size = fsOpenReq->file_size_hi;
232
request->par.open.file_size <<= 32;
233
request->par.open.file_size |= fsOpenReq->file_size_lo;
234
request->par.open.auto_sync_size = fsOpenReq->auto_sync_size;
236
ndbrequire(forward(file, request));
240
Ndbfs::execFSREMOVEREQ(Signal* signal)
243
const FsRemoveReq * const req = (FsRemoveReq *)signal->getDataPtr();
244
const BlockReference userRef = req->userReference;
245
AsyncFile* file = getIdleFile();
246
ndbrequire(file != NULL);
248
Filename::NameSpec spec(theFileSystemPath, theBackupFilePath);
249
file->theFileName.set(spec, userRef, req->fileNumber, req->directory);
250
file->reportTo(&theFromThreads);
252
Request* request = theRequestPool->get();
253
request->action = Request::rmrf;
254
request->par.rmrf.directory = req->directory;
255
request->par.rmrf.own_directory = req->ownDirectory;
257
request->set(userRef, req->userPointer, newId() );
258
request->file = file;
259
request->theTrace = signal->getTrace();
261
ndbrequire(forward(file, request));
265
* PR0: File Pointer DR0: User reference DR1: User Pointer DR2: Flag bit 0= 1
269
Ndbfs::execFSCLOSEREQ(Signal * signal)
272
const FsCloseReq * const fsCloseReq = (FsCloseReq *)&signal->theData[0];
273
const BlockReference userRef = fsCloseReq->userReference;
274
const Uint16 filePointer = (Uint16)fsCloseReq->filePointer;
275
const UintR userPointer = fsCloseReq->userPointer;
277
AsyncFile* openFile = theOpenFiles.find(filePointer);
278
if (openFile == NULL) {
279
// The file was not open, send error back to sender
281
// Initialise FsRef signal
282
FsRef * const fsRef = (FsRef *)&signal->theData[0];
283
fsRef->userPointer = userPointer;
284
fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrFileDoesNotExist);
285
fsRef->osErrorCode = ~0; // Indicate local error
286
sendSignal(userRef, GSN_FSCLOSEREF, signal, 3, JBB);
290
Request *request = theRequestPool->get();
291
if( fsCloseReq->getRemoveFileFlag(fsCloseReq->fileFlag) == true ) {
293
request->action = Request::closeRemove;
296
request->action = Request::close;
298
request->set(userRef, fsCloseReq->userPointer, filePointer);
299
request->file = openFile;
301
request->theTrace = signal->getTrace();
303
ndbrequire(forward(openFile, request));
307
Ndbfs::readWriteRequest(int action, Signal * signal)
309
const FsReadWriteReq * const fsRWReq = (FsReadWriteReq *)&signal->theData[0];
310
Uint16 filePointer = (Uint16)fsRWReq->filePointer;
311
const UintR userPointer = fsRWReq->userPointer;
312
const BlockReference userRef = fsRWReq->userReference;
313
const BlockNumber blockNumber = refToBlock(userRef);
315
AsyncFile* openFile = theOpenFiles.find(filePointer);
317
const NewVARIABLE *myBaseAddrRef = &getBat(blockNumber)[fsRWReq->varIndex];
319
UintPtr tClusterSize;
323
FsRef::NdbfsErrorCodeType errorCode;
325
Request *request = theRequestPool->get();
327
request->set(userRef, userPointer, filePointer);
328
request->file = openFile;
329
request->action = (Request::Action) action;
330
request->theTrace = signal->getTrace();
332
Uint32 format = fsRWReq->getFormatFlag(fsRWReq->operationFlag);
334
if (fsRWReq->numberOfPages == 0) { //Zero pages not allowed
336
errorCode = FsRef::fsErrInvalidParameters;
340
if(format != FsReadWriteReq::fsFormatGlobalPage &&
341
format != FsReadWriteReq::fsFormatSharedPage)
343
if (fsRWReq->varIndex >= getBatSize(blockNumber)) {
344
jam();// Ensure that a valid variable is used
345
errorCode = FsRef::fsErrInvalidParameters;
348
if (myBaseAddrRef == NULL) {
349
jam(); // Ensure that a valid variable is used
350
errorCode = FsRef::fsErrInvalidParameters;
353
if (openFile == NULL) {
354
jam(); //file not open
355
errorCode = FsRef::fsErrFileDoesNotExist;
358
tPageSize = pageSize(myBaseAddrRef);
359
tClusterSize = myBaseAddrRef->ClusterSize;
360
tNRR = myBaseAddrRef->nrr;
361
tWA = (char*)myBaseAddrRef->WA;
365
// List of memory and file pages pairs
366
case FsReadWriteReq::fsFormatListOfPairs: {
368
for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) {
370
const UintPtr varIndex = fsRWReq->data.listOfPair[i].varIndex;
371
const UintPtr fileOffset = fsRWReq->data.listOfPair[i].fileOffset;
372
if (varIndex >= tNRR) {
374
errorCode = FsRef::fsErrInvalidParameters;
377
request->par.readWrite.pages[i].buf = &tWA[varIndex * tClusterSize];
378
request->par.readWrite.pages[i].size = tPageSize;
379
request->par.readWrite.pages[i].offset = fileOffset * tPageSize;
381
request->par.readWrite.numberOfPages = fsRWReq->numberOfPages;
385
// Range of memory page with one file page
386
case FsReadWriteReq::fsFormatArrayOfPages: {
387
if ((fsRWReq->numberOfPages + fsRWReq->data.arrayOfPages.varIndex) > tNRR) {
389
errorCode = FsRef::fsErrInvalidParameters;
392
const UintPtr varIndex = fsRWReq->data.arrayOfPages.varIndex;
393
const UintPtr fileOffset = fsRWReq->data.arrayOfPages.fileOffset;
395
request->par.readWrite.pages[0].offset = fileOffset * tPageSize;
396
request->par.readWrite.pages[0].size = tPageSize * fsRWReq->numberOfPages;
397
request->par.readWrite.numberOfPages = 1;
398
request->par.readWrite.pages[0].buf = &tWA[varIndex * tPageSize];
402
// List of memory pages followed by one file page
403
case FsReadWriteReq::fsFormatListOfMemPages: {
405
tPageOffset = fsRWReq->data.listOfMemPages.varIndex[fsRWReq->numberOfPages];
406
tPageOffset *= tPageSize;
408
for (unsigned int i = 0; i < fsRWReq->numberOfPages; i++) {
410
UintPtr varIndex = fsRWReq->data.listOfMemPages.varIndex[i];
412
if (varIndex >= tNRR) {
414
errorCode = FsRef::fsErrInvalidParameters;
417
request->par.readWrite.pages[i].buf = &tWA[varIndex * tClusterSize];
418
request->par.readWrite.pages[i].size = tPageSize;
419
request->par.readWrite.pages[i].offset = tPageOffset + (i*tPageSize);
421
request->par.readWrite.numberOfPages = fsRWReq->numberOfPages;
423
// make it a writev or readv
428
errorCode = FsRef::fsErrInvalidParameters;
433
else if (format == FsReadWriteReq::fsFormatGlobalPage)
436
m_global_page_pool.getPtr(ptr, fsRWReq->data.pageData[0]);
437
request->par.readWrite.pages[0].buf = (char*)ptr.p;
438
request->par.readWrite.pages[0].size = ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->numberOfPages;
439
request->par.readWrite.pages[0].offset= ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->varIndex;
440
request->par.readWrite.numberOfPages = 1;
444
ndbrequire(format == FsReadWriteReq::fsFormatSharedPage);
446
m_shared_page_pool.getPtr(ptr, fsRWReq->data.pageData[0]);
447
request->par.readWrite.pages[0].buf = (char*)ptr.p;
448
request->par.readWrite.pages[0].size = ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->numberOfPages;
449
request->par.readWrite.pages[0].offset= ((UintPtr)GLOBAL_PAGE_SIZE)*fsRWReq->varIndex;
450
request->par.readWrite.numberOfPages = 1;
453
ndbrequire(forward(openFile, request));
457
theRequestPool->put(request);
458
FsRef * const fsRef = (FsRef *)&signal->theData[0];
459
fsRef->userPointer = userPointer;
460
fsRef->setErrorCode(fsRef->errorCode, errorCode);
461
fsRef->osErrorCode = ~0; // Indicate local error
463
case Request:: write:
464
case Request:: writeSync: {
466
sendSignal(userRef, GSN_FSWRITEREF, signal, 3, JBB);
469
case Request:: readPartial:
470
case Request:: read: {
472
sendSignal(userRef, GSN_FSREADREF, signal, 3, JBB);
479
PR0: File Pointer , theData[0]
480
DR0: User reference, theData[1]
481
DR1: User Pointer, etc.
485
DR5->: Memory Page id and File page id according to Flag
488
Ndbfs::execFSWRITEREQ(Signal* signal)
491
const FsReadWriteReq * const fsWriteReq = (FsReadWriteReq *)&signal->theData[0];
493
if (fsWriteReq->getSyncFlag(fsWriteReq->operationFlag) == true){
495
readWriteRequest( Request::writeSync, signal );
498
readWriteRequest( Request::write, signal );
509
DR5->: Memory Page id and File page id according to Flag
512
Ndbfs::execFSREADREQ(Signal* signal)
515
FsReadWriteReq * req = (FsReadWriteReq *)signal->getDataPtr();
516
if (FsReadWriteReq::getPartialReadFlag(req->operationFlag))
517
readWriteRequest( Request::readPartial, signal );
519
readWriteRequest( Request::read, signal );
523
* PR0: File Pointer DR0: User reference DR1: User Pointer
526
Ndbfs::execFSSYNCREQ(Signal * signal)
529
Uint16 filePointer = (Uint16)signal->theData[0];
530
BlockReference userRef = signal->theData[1];
531
const UintR userPointer = signal->theData[2];
532
AsyncFile* openFile = theOpenFiles.find(filePointer);
534
if (openFile == NULL) {
535
jam(); //file not open
536
FsRef * const fsRef = (FsRef *)&signal->theData[0];
537
fsRef->userPointer = userPointer;
538
fsRef->setErrorCode(fsRef->errorCode, FsRef::fsErrFileDoesNotExist);
539
fsRef->osErrorCode = ~0; // Indicate local error
540
sendSignal(userRef, GSN_FSSYNCREF, signal, 3, JBB);
544
Request *request = theRequestPool->get();
546
request->action = Request::sync;
547
request->set(userRef, userPointer, filePointer);
548
request->file = openFile;
549
request->theTrace = signal->getTrace();
551
ndbrequire(forward(openFile,request));
555
Ndbfs::execFSAPPENDREQ(Signal * signal)
557
const FsAppendReq * const fsReq = (FsAppendReq *)&signal->theData[0];
558
const Uint16 filePointer = (Uint16)fsReq->filePointer;
559
const UintR userPointer = fsReq->userPointer;
560
const BlockReference userRef = fsReq->userReference;
561
const BlockNumber blockNumber = refToBlock(userRef);
563
FsRef::NdbfsErrorCodeType errorCode;
565
AsyncFile* openFile = theOpenFiles.find(filePointer);
566
const NewVARIABLE *myBaseAddrRef = &getBat(blockNumber)[fsReq->varIndex];
568
const Uint32* tWA = (const Uint32*)myBaseAddrRef->WA;
569
const Uint32 tSz = myBaseAddrRef->nrr;
570
const Uint32 offset = fsReq->offset;
571
const Uint32 size = fsReq->size;
572
const Uint32 synch_flag = fsReq->synch_flag;
573
Request *request = theRequestPool->get();
575
if (openFile == NULL) {
577
errorCode = FsRef::fsErrFileDoesNotExist;
581
if (myBaseAddrRef == NULL) {
582
jam(); // Ensure that a valid variable is used
583
errorCode = FsRef::fsErrInvalidParameters;
587
if (fsReq->varIndex >= getBatSize(blockNumber)) {
588
jam();// Ensure that a valid variable is used
589
errorCode = FsRef::fsErrInvalidParameters;
593
if(offset + size > tSz){
594
jam(); // Ensure that a valid variable is used
595
errorCode = FsRef::fsErrInvalidParameters;
600
request->set(userRef, userPointer, filePointer);
601
request->file = openFile;
602
request->theTrace = signal->getTrace();
604
request->par.append.buf = (const char *)(tWA + offset);
605
request->par.append.size = size << 2;
608
request->action = Request::append;
610
request->action = Request::append_synch;
611
ndbrequire(forward(openFile, request));
616
theRequestPool->put(request);
617
FsRef * const fsRef = (FsRef *)&signal->theData[0];
618
fsRef->userPointer = userPointer;
619
fsRef->setErrorCode(fsRef->errorCode, errorCode);
620
fsRef->osErrorCode = ~0; // Indicate local error
623
sendSignal(userRef, GSN_FSAPPENDREF, signal, 3, JBB);
630
// finds a new key, eg a new filepointer
631
for (int i = 1; i < SHRT_MAX; i++)
633
if (theLastId == SHRT_MAX) {
641
if(theOpenFiles.find(theLastId) == NULL) {
647
// The program will not reach this point
652
Ndbfs::createAsyncFile(){
654
// Check limit of open files
655
if (m_maxFiles !=0 && theFiles.size() == m_maxFiles) {
656
// Print info about all open files
657
for (unsigned i = 0; i < theFiles.size(); i++){
658
AsyncFile* file = theFiles[i];
659
ndbout_c("%2d (0x%lx): %s", i, (long) file, file->isOpen()?"OPEN":"CLOSED");
661
ERROR_SET(fatal, NDBD_EXIT_AFS_MAXOPEN,""," Ndbfs::createAsyncFile");
664
AsyncFile* file = new AsyncFile(* this);
667
// Put the file in list of all files
668
theFiles.push_back(file);
671
infoEvent("NDBFS: Created new file thread %d", theFiles.size());
678
Ndbfs::getIdleFile(){
680
if (theIdleFiles.size() > 0){
681
file = theIdleFiles[0];
682
theIdleFiles.erase(0);
684
file = createAsyncFile();
692
Ndbfs::report(Request * request, Signal* signal)
694
const Uint32 orgTrace = signal->getTrace();
695
signal->setTrace(request->theTrace);
696
const BlockReference ref = request->theUserReference;
698
if(!request->file->m_page_ptr.isNull())
700
m_global_page_pool.release(request->file->m_page_ptr);
701
request->file->m_page_ptr.setNull();
704
if (request->error) {
706
// Initialise FsRef signal
707
FsRef * const fsRef = (FsRef *)&signal->theData[0];
708
fsRef->userPointer = request->theUserPointer;
709
if(request->error & FsRef::FS_ERR_BIT)
711
fsRef->errorCode = request->error;
712
fsRef->osErrorCode = 0;
716
fsRef->setErrorCode(fsRef->errorCode, translateErrno(request->error));
717
fsRef->osErrorCode = request->error;
719
switch (request->action) {
720
case Request:: open: {
722
// Put the file back in idle files list
723
theIdleFiles.push_back(request->file);
724
sendSignal(ref, GSN_FSOPENREF, signal, FsRef::SignalLength, JBB);
727
case Request:: closeRemove:
728
case Request:: close: {
730
sendSignal(ref, GSN_FSCLOSEREF, signal, FsRef::SignalLength, JBB);
733
case Request:: writeSync:
734
case Request:: writevSync:
735
case Request:: write:
736
case Request:: writev: {
738
sendSignal(ref, GSN_FSWRITEREF, signal, FsRef::SignalLength, JBB);
742
case Request:: readPartial:
743
case Request:: readv: {
745
sendSignal(ref, GSN_FSREADREF, signal, FsRef::SignalLength, JBB);
748
case Request:: sync: {
750
sendSignal(ref, GSN_FSSYNCREF, signal, FsRef::SignalLength, JBB);
753
case Request::append:
754
case Request::append_synch:
757
sendSignal(ref, GSN_FSAPPENDREF, signal, FsRef::SignalLength, JBB);
760
case Request::rmrf: {
762
// Put the file back in idle files list
763
theIdleFiles.push_back(request->file);
764
sendSignal(ref, GSN_FSREMOVEREF, signal, FsRef::SignalLength, JBB);
768
case Request:: end: {
775
FsConf * const fsConf = (FsConf *)&signal->theData[0];
776
fsConf->userPointer = request->theUserPointer;
777
switch (request->action) {
778
case Request:: open: {
780
theOpenFiles.insert(request->file, request->theFilePointer);
782
// Keep track on max number of opened files
783
if (theOpenFiles.size() > m_maxOpenedFiles)
784
m_maxOpenedFiles = theOpenFiles.size();
786
fsConf->filePointer = request->theFilePointer;
787
sendSignal(ref, GSN_FSOPENCONF, signal, 3, JBB);
790
case Request:: closeRemove:
791
case Request:: close: {
793
// removes the file from OpenFiles list
794
theOpenFiles.erase(request->theFilePointer);
795
// Put the file in idle files list
796
theIdleFiles.push_back(request->file);
797
sendSignal(ref, GSN_FSCLOSECONF, signal, 1, JBB);
800
case Request:: writeSync:
801
case Request:: writevSync:
802
case Request:: write:
803
case Request:: writev: {
805
sendSignal(ref, GSN_FSWRITECONF, signal, 1, JBB);
809
case Request:: readv: {
811
sendSignal(ref, GSN_FSREADCONF, signal, 1, JBB);
814
case Request:: readPartial: {
816
fsConf->bytes_read = request->par.readWrite.pages[0].size;
817
sendSignal(ref, GSN_FSREADCONF, signal, 2, JBB);
820
case Request:: sync: {
822
sendSignal(ref, GSN_FSSYNCCONF, signal, 1, JBB);
825
case Request::append:
826
case Request::append_synch:
829
signal->theData[1] = request->par.append.size;
830
sendSignal(ref, GSN_FSAPPENDCONF, signal, 2, JBB);
833
case Request::rmrf: {
835
// Put the file in idle files list
836
theIdleFiles.push_back(request->file);
837
sendSignal(ref, GSN_FSREMOVECONF, signal, 1, JBB);
840
case Request:: end: {
846
signal->setTrace(orgTrace);
851
Ndbfs::scanIPC(Signal* signal)
853
Request* request = theFromThreads.tryReadChannel();
857
report(request, signal);
858
theRequestPool->put(request);
864
#if defined NDB_WIN32
865
Uint32 Ndbfs::translateErrno(int aErrno)
870
case ERROR_ACCESS_DENIED:
872
return FsRef::fsErrPermissionDenied;
873
//temporary not accessible
874
case ERROR_PATH_BUSY:
875
case ERROR_NO_MORE_SEARCH_HANDLES:
877
return FsRef::fsErrTemporaryNotAccessible;
878
//no space left on device
879
case ERROR_HANDLE_DISK_FULL:
880
case ERROR_DISK_FULL:
882
return FsRef::fsErrNoSpaceLeftOnDevice;
883
//none valid parameters
884
case ERROR_INVALID_HANDLE:
885
case ERROR_INVALID_DRIVE:
886
case ERROR_INVALID_ACCESS:
887
case ERROR_HANDLE_EOF:
888
case ERROR_BUFFER_OVERFLOW:
890
return FsRef::fsErrInvalidParameters;
893
case ERROR_ARENA_TRASHED:
894
case ERROR_BAD_ENVIRONMENT:
895
case ERROR_INVALID_BLOCK:
896
case ERROR_WRITE_FAULT:
897
case ERROR_READ_FAULT:
898
case ERROR_OPEN_FAILED:
900
return FsRef::fsErrEnvironmentError;
902
//no more process resources
903
case ERROR_TOO_MANY_OPEN_FILES:
904
case ERROR_NOT_ENOUGH_MEMORY:
905
case ERROR_OUTOFMEMORY:
906
return FsRef::fsErrNoMoreResources;
908
case ERROR_FILE_NOT_FOUND:
909
return FsRef::fsErrFileDoesNotExist;
911
case ERR_ReadUnderflow:
912
return FsRef::fsErrReadUnderflow;
915
return FsRef::fsErrUnknown;
919
Uint32 Ndbfs::translateErrno(int aErrno)
927
return FsRef::fsErrPermissionDenied;
928
//temporary not accessible
934
return FsRef::fsErrTemporaryNotAccessible;
935
//no space left on device
943
return FsRef::fsErrNoSpaceLeftOnDevice;
944
//none valid parameters
953
return FsRef::fsErrInvalidParameters;
969
return FsRef::fsErrEnvironmentError;
971
//no more process resources
974
return FsRef::fsErrNoMoreResources;
977
return FsRef::fsErrFileDoesNotExist;
979
case ERR_ReadUnderflow:
980
return FsRef::fsErrReadUnderflow;
983
return FsRef::fsErrUnknown;
991
Ndbfs::execCONTINUEB(Signal* signal)
994
if (signal->theData[0] == NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY) {
997
// Also send CONTINUEB to ourself in order to scan for
998
// incoming answers from AsyncFile on MemoryChannel theFromThreads
999
signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_10MS_DELAY;
1000
sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 10, 1);
1001
if (scanningInProgress == true) {
1006
if (scanIPC(signal)) {
1008
scanningInProgress = true;
1009
signal->theData[0] = NdbfsContinueB::ZSCAN_MEMORYCHANNEL_NO_DELAY;
1010
sendSignal(reference(), GSN_CONTINUEB, signal, 1, JBB);
1013
scanningInProgress = false;
1019
Ndbfs::execDUMP_STATE_ORD(Signal* signal)
1021
if(signal->theData[0] == 19){
1024
if(signal->theData[0] == DumpStateOrd::NdbfsDumpFileStat){
1025
infoEvent("NDBFS: Files: %d Open files: %d",
1027
theOpenFiles.size());
1028
infoEvent(" Idle files: %d Max opened files: %d",
1029
theIdleFiles.size(),
1031
infoEvent(" Max files: %d",
1033
infoEvent(" Requests: %d",
1034
theRequestPool->size());
1038
if(signal->theData[0] == DumpStateOrd::NdbfsDumpOpenFiles){
1039
infoEvent("NDBFS: Dump open files: %d", theOpenFiles.size());
1041
for (unsigned i = 0; i < theOpenFiles.size(); i++){
1042
AsyncFile* file = theOpenFiles.getFile(i);
1043
infoEvent("%2d (0x%x): %s", i,file, file->theFileName.c_str());
1047
if(signal->theData[0] == DumpStateOrd::NdbfsDumpAllFiles){
1048
infoEvent("NDBFS: Dump all files: %d", theFiles.size());
1050
for (unsigned i = 0; i < theFiles.size(); i++){
1051
AsyncFile* file = theFiles[i];
1052
infoEvent("%2d (0x%x): %s", i,file, file->isOpen()?"OPEN":"CLOSED");
1056
if(signal->theData[0] == DumpStateOrd::NdbfsDumpIdleFiles){
1057
infoEvent("NDBFS: Dump idle files: %d", theIdleFiles.size());
1059
for (unsigned i = 0; i < theIdleFiles.size(); i++){
1060
AsyncFile* file = theIdleFiles[i];
1061
infoEvent("%2d (0x%x): %s", i,file, file->isOpen()?"OPEN":"CLOSED");
1066
if(signal->theData[0] == 404)
1068
ndbrequire(signal->getLength() == 2);
1069
Uint32 file= signal->theData[1];
1070
AsyncFile* openFile = theOpenFiles.find(file);
1071
ndbrequire(openFile != 0);
1072
ndbout_c("File: %s %p", openFile->theFileName.c_str(), openFile);
1073
Request* curr = openFile->m_current_request;
1074
Request* last = openFile->m_last_request;
1076
ndbout << "Current request: " << *curr << endl;
1078
ndbout << "Last request: " << *last << endl;
1080
ndbout << "theReportTo " << *openFile->theReportTo << endl;
1081
ndbout << "theMemoryChannelPtr" << *openFile->theMemoryChannelPtr << endl;
1083
ndbout << "All files: " << endl;
1084
for (unsigned i = 0; i < theFiles.size(); i++){
1085
AsyncFile* file = theFiles[i];
1086
ndbout_c("%2d (0x%lx): %s", i, (long) file, file->isOpen()?"OPEN":"CLOSED");
1089
}//Ndbfs::execDUMP_STATE_ORD()
1092
Ndbfs::get_filename(Uint32 fd) const
1095
const AsyncFile* openFile = theOpenFiles.find(fd);
1097
return openFile->theFileName.get_base_name();
1102
BLOCK_FUNCTIONS(Ndbfs)
1104
template class Vector<AsyncFile*>;
1105
template class Vector<OpenFiles::OpenFileItem>;
1106
template class MemoryChannel<Request>;
1107
template class Pool<Request>;
1108
template NdbOut& operator<<(NdbOut&, const MemoryChannel<Request>&);