2007-12-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Rewritten direct I/O support routine
	* src/SingleFileAllocationIterator.cc
	* src/MultiDiskAdaptor.{h, cc}
	* src/ByteArrayDiskWriter.h
	* src/AbstractSingleDiskAdaptor.h
	* src/AbstractDiskWriter.cc
	* src/DefaultPieceStorage.cc
	* src/DiskWriter.h
	* src/BinaryStream.h
	* src/IteratableChunkChecksumValidator.cc
	* src/IteratableChecksumValidator.cc
	* src/CheckIntegrityEntry.cc
	* src/FileAllocationEntry.cc
pull/1/head
Tatsuhiro Tsujikawa 2007-12-05 17:11:22 +00:00
parent 84e896eb09
commit 2850c16f8a
16 changed files with 98 additions and 40 deletions

View File

@ -1,3 +1,19 @@
2007-12-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Rewritten direct I/O support routine
* src/SingleFileAllocationIterator.cc
* src/MultiDiskAdaptor.{h, cc}
* src/ByteArrayDiskWriter.h
* src/AbstractSingleDiskAdaptor.h
* src/AbstractDiskWriter.cc
* src/DefaultPieceStorage.cc
* src/DiskWriter.h
* src/BinaryStream.h
* src/IteratableChunkChecksumValidator.cc
* src/IteratableChecksumValidator.cc
* src/CheckIntegrityEntry.cc
* src/FileAllocationEntry.cc
2007-12-06 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Fixed typo

View File

@ -47,8 +47,7 @@
AbstractDiskWriter::AbstractDiskWriter():
fd(-1),
logger(LogFactory::getInstance())
{}
logger(LogFactory::getInstance()) {}
AbstractDiskWriter::~AbstractDiskWriter()
{
@ -167,9 +166,11 @@ int64_t AbstractDiskWriter::size() const
void AbstractDiskWriter::enableDirectIO()
{
#ifdef ENABLE_DIRECT_IO
int32_t flg;
while((flg = fcntl(fd, F_GETFL)) == -1 && errno == EINTR);
while(fcntl(fd, F_SETFL, flg|O_DIRECT) == -1 && errno == EINTR);
if(_directIOAllowed) {
int32_t flg;
while((flg = fcntl(fd, F_GETFL)) == -1 && errno == EINTR);
while(fcntl(fd, F_SETFL, flg|O_DIRECT) == -1 && errno == EINTR);
}
#endif // ENABLE_DIRECT_IO
}

View File

@ -77,7 +77,12 @@ public:
virtual void enableDirectIO();
virtual void disableDirectIO();
virtual bool directIOAllowed() const
{
return diskWriter->directIOAllowed();
}
void setDiskWriter(const DiskWriterHandle diskWriter) {
this->diskWriter = diskWriter;
}

View File

@ -47,6 +47,12 @@ public:
virtual int32_t readData(unsigned char* data, int32_t len, int64_t offset) = 0;
virtual void truncate(int64_t length) = 0;
virtual void enableDirectIO() = 0;
virtual void disableDirectIO() = 0;
virtual bool directIOAllowed() const = 0;
};
typedef SharedHandle<BinaryStream> BinaryStreamHandle;

View File

@ -66,7 +66,5 @@ Commands BtCheckIntegrityEntry::onDownloadFinished(DownloadEngine* e)
// are valid, then aira2 goes to seeding mode. Sometimes it is better
// to exit rather than doing seeding. So, it would be good to toggle this
// behavior.
// TODO If FileAllocationEntry is not going to be used, call
// DiskAdaptor::disableDirectIO() manually here.
return onDownloadIncomplete(e);
}

View File

@ -70,6 +70,11 @@ public:
virtual void disableDirectIO() {}
virtual bool directIOAllowed() const
{
return false;
}
void setString(const string& s)
{
buf.str(s);

View File

@ -36,27 +36,14 @@
#include "Command.h"
#include "RequestGroup.h"
#include "IteratableValidator.h"
#include "prefs.h"
#include "PieceStorage.h"
#include "DownloadContext.h"
#include "DiskAdaptor.h"
#include "Option.h"
CheckIntegrityEntry::CheckIntegrityEntry(RequestGroup* requestGroup,
Command* nextCommand):
RequestGroupEntry(requestGroup, nextCommand),
_validator(0)
{
if(_requestGroup->getOption()->getAsBool(PREF_ENABLE_DIRECT_IO) &&
_requestGroup->getDownloadContext()->getFileEntries().size() == 1) {
_requestGroup->getPieceStorage()->getDiskAdaptor()->enableDirectIO();
}
}
{}
CheckIntegrityEntry::~CheckIntegrityEntry()
{
// TODO DiskAdaptor::disableIO() will be called from ~FileAllocationEntry
}
CheckIntegrityEntry::~CheckIntegrityEntry() {}
void CheckIntegrityEntry::validateChunk()
{

View File

@ -434,6 +434,7 @@ void DefaultPieceStorage::initStorage()
if(downloadContext->getFileMode() == DownloadContext::SINGLE) {
logger->debug("Instantiating DirectDiskAdaptor");
DiskWriterHandle writer = _diskWriterFactory->newDiskWriter();
writer->setDirectIOAllowed(option->getAsBool(PREF_ENABLE_DIRECT_IO));
DirectDiskAdaptorHandle directDiskAdaptor = new DirectDiskAdaptor();
directDiskAdaptor->setDiskWriter(writer);
directDiskAdaptor->setTotalLength(downloadContext->getTotalLength());
@ -443,12 +444,14 @@ void DefaultPieceStorage::initStorage()
if(option->get(PREF_DIRECT_FILE_MAPPING) == V_TRUE) {
logger->debug("Instantiating MultiDiskAdaptor");
MultiDiskAdaptorHandle multiDiskAdaptor = new MultiDiskAdaptor();
multiDiskAdaptor->setDirectIOAllowed(option->getAsBool(PREF_ENABLE_DIRECT_IO));
multiDiskAdaptor->setPieceLength(downloadContext->getPieceLength());
multiDiskAdaptor->setTopDir(downloadContext->getName());
this->diskAdaptor = multiDiskAdaptor;
} else {
logger->debug("Instantiating CopyDiskAdaptor");
DiskWriterHandle writer = _diskWriterFactory->newDiskWriter();
writer->setDirectIOAllowed(option->getAsBool(PREF_ENABLE_DIRECT_IO));
CopyDiskAdaptorHandle copyDiskAdaptor = new CopyDiskAdaptor();
copyDiskAdaptor->setDiskWriter(writer);
copyDiskAdaptor->setTempFilename(downloadContext->getName()+".a2tmp");

View File

@ -90,9 +90,9 @@ public:
virtual FileAllocationIteratorHandle fileAllocationIterator() = 0;
virtual void enableDirectIO() {};
virtual void enableDirectIO() {}
virtual void disableDirectIO() {};
virtual void disableDirectIO() {}
};
typedef SharedHandle<DiskAdaptor> DiskAdaptorHandle;

View File

@ -42,7 +42,12 @@
*
*/
class DiskWriter:public BinaryStream {
protected:
bool _directIOAllowed;
public:
DiskWriter():_directIOAllowed(false) {}
virtual ~DiskWriter() {}
/**
* Creates a file output stream to write to the file with the specified name.
@ -75,6 +80,16 @@ public:
virtual void enableDirectIO() = 0;
virtual void disableDirectIO() = 0;
virtual bool directIOAllowed() const
{
return _directIOAllowed;
}
void setDirectIOAllowed(bool f)
{
_directIOAllowed = f;
}
};
typedef SharedHandle<DiskWriter> DiskWriterHandle;

View File

@ -38,24 +38,14 @@
#include "RequestGroup.h"
#include "PieceStorage.h"
#include "DiskAdaptor.h"
#include "prefs.h"
#include "Option.h"
FileAllocationEntry::FileAllocationEntry(RequestGroup* requestGroup, Command* nextCommand):
RequestGroupEntry(requestGroup, nextCommand),
_fileAllocationIterator(requestGroup->getPieceStorage()->getDiskAdaptor()->fileAllocationIterator())
{
if(_requestGroup->getOption()->getAsBool(PREF_ENABLE_DIRECT_IO)) {
_requestGroup->getPieceStorage()->getDiskAdaptor()->enableDirectIO();
}
}
{}
FileAllocationEntry:: ~FileAllocationEntry()
{
if(_requestGroup->getOption()->getAsBool(PREF_ENABLE_DIRECT_IO)) {
_requestGroup->getPieceStorage()->getDiskAdaptor()->disableDirectIO();
}
}
{}
int64_t FileAllocationEntry::getCurrentLength()
{

View File

@ -82,7 +82,12 @@ void IteratableChecksumValidator::validateChunk()
bool IteratableChecksumValidator::finished() const
{
return _currentOffset >= _dctx->getTotalLength();
if(_currentOffset >= _dctx->getTotalLength()) {
_pieceStorage->getDiskAdaptor()->disableDirectIO();
return true;
} else {
return false;
}
}
int64_t IteratableChecksumValidator::getTotalLength() const
@ -97,6 +102,7 @@ void IteratableChecksumValidator::init()
#else
_buffer = new unsigned char[BUFSIZE];
#endif // HAVE_POSIX_MEMALIGN
_pieceStorage->getDiskAdaptor()->enableDirectIO();
_currentOffset = 0;
_ctx = new MessageDigestContext();
_ctx->trySetAlgo(_dctx->getChecksumHashAlgo());

View File

@ -116,6 +116,9 @@ void IteratableChunkChecksumValidator::init()
#else
_buffer = new unsigned char[BUFSIZE];
#endif // HAVE_POSIX_MEMALIGN
if(_dctx->getFileEntries().size() == 1) {
_pieceStorage->getDiskAdaptor()->enableDirectIO();
}
_ctx = new MessageDigestContext();
_ctx->trySetAlgo(_dctx->getPieceHashAlgo());
_ctx->digestInit();
@ -157,7 +160,12 @@ string IteratableChunkChecksumValidator::digest(int64_t offset, int32_t length)
bool IteratableChunkChecksumValidator::finished() const
{
return _currentIndex >= (uint32_t)_dctx->getNumPieces();
if(_currentIndex >= (uint32_t)_dctx->getNumPieces()) {
_pieceStorage->getDiskAdaptor()->disableDirectIO();
return true;
} else {
return false;
}
}
int64_t IteratableChunkChecksumValidator::getCurrentOffset() const

View File

@ -51,6 +51,7 @@ void MultiDiskAdaptor::resetDiskWriterEntries()
} else {
entry->setDiskWriter(new DefaultDiskWriter());
}
entry->getDiskWriter()->setDirectIOAllowed(_directIOAllowed);
diskWriterEntries.push_back(entry);
}
}

View File

@ -116,6 +116,8 @@ private:
int32_t pieceLength;
DiskWriterEntries diskWriterEntries;
bool _directIOAllowed;
void resetDiskWriterEntries();
void mkdir() const;
@ -178,6 +180,16 @@ public:
int32_t getPieceLength() const {
return pieceLength;
}
virtual bool directIOAllowed() const
{
return _directIOAllowed;
}
void setDirectIOAllowed(bool b)
{
_directIOAllowed = b;
}
};
typedef SharedHandle<MultiDiskAdaptor> MultiDiskAdaptorHandle;

View File

@ -40,11 +40,16 @@
#define BUFSIZE (256*1024)
SingleFileAllocationIterator::SingleFileAllocationIterator(BinaryStream* stream, int64_t offset, int64_t totalLength):_stream(stream), _offset(offset), _totalLength(totalLength), _buffer(0)
{}
{
if(_offset%512 == 0) {
_stream->enableDirectIO();
}
}
SingleFileAllocationIterator::~SingleFileAllocationIterator()
{
delete [] _buffer;
_stream->disableDirectIO();
}
void SingleFileAllocationIterator::init()