summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-05-03 11:00:39 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2009-05-03 11:00:39 +0000
commiteeece05063212ccf5b4f86cb7004739e2c3d5a94 (patch)
treec0b66275fa1a7e59b13feb19673f632d6791ffbc
parentee229c6f00a0a01b99e37d91c14060a29d41a3a6 (diff)
2009-05-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed the bug that read-only file with wrong file size will cause error because it cannot be truncated to the correct size. Now if file size is different than the expected one, re-open file in writable mode. * src/AbstractSingleDiskAdaptor.cc * src/AbstractSingleDiskAdaptor.h * src/BtCheckIntegrityEntry.cc * src/DiskAdaptor.h * src/MultiDiskAdaptor.h * src/RequestGroup.cc
-rw-r--r--ChangeLog13
-rw-r--r--src/AbstractSingleDiskAdaptor.cc5
-rw-r--r--src/AbstractSingleDiskAdaptor.h3
-rw-r--r--src/BtCheckIntegrityEntry.cc13
-rw-r--r--src/DiskAdaptor.h2
-rw-r--r--src/MultiDiskAdaptor.h2
-rw-r--r--src/RequestGroup.cc17
7 files changed, 47 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 934e8d8b..72c56334 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
2009-05-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
+ Fixed the bug that read-only file with wrong file size will cause
+ error because it cannot be truncated to the correct size. Now if
+ file size is different than the expected one, re-open file in
+ writable mode.
+ * src/AbstractSingleDiskAdaptor.cc
+ * src/AbstractSingleDiskAdaptor.h
+ * src/BtCheckIntegrityEntry.cc
+ * src/DiskAdaptor.h
+ * src/MultiDiskAdaptor.h
+ * src/RequestGroup.cc
+
+2009-05-03 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
+
Fixed the bug that with --check-integrity option aria2 reports
downloaded file size is 0 even if some parts of file is correctly
downloaded. This bug is reproducible for the download that a file
diff --git a/src/AbstractSingleDiskAdaptor.cc b/src/AbstractSingleDiskAdaptor.cc
index f1c71493..695eab7c 100644
--- a/src/AbstractSingleDiskAdaptor.cc
+++ b/src/AbstractSingleDiskAdaptor.cc
@@ -42,7 +42,8 @@
namespace aria2 {
-AbstractSingleDiskAdaptor::AbstractSingleDiskAdaptor():totalLength(0) {}
+AbstractSingleDiskAdaptor::AbstractSingleDiskAdaptor():
+ totalLength(0), _readOnly(false) {}
AbstractSingleDiskAdaptor::~AbstractSingleDiskAdaptor() {}
@@ -126,11 +127,13 @@ bool AbstractSingleDiskAdaptor::directIOAllowed() const
void AbstractSingleDiskAdaptor::enableReadOnly()
{
diskWriter->enableReadOnly();
+ _readOnly = true;
}
void AbstractSingleDiskAdaptor::disableReadOnly()
{
diskWriter->disableReadOnly();
+ _readOnly = false;
}
void AbstractSingleDiskAdaptor::cutTrailingGarbage()
diff --git a/src/AbstractSingleDiskAdaptor.h b/src/AbstractSingleDiskAdaptor.h
index b01f29a2..f8c9e3a1 100644
--- a/src/AbstractSingleDiskAdaptor.h
+++ b/src/AbstractSingleDiskAdaptor.h
@@ -46,6 +46,7 @@ class AbstractSingleDiskAdaptor : public DiskAdaptor {
protected:
SharedHandle<DiskWriter> diskWriter;
uint64_t totalLength;
+ bool _readOnly;
public:
AbstractSingleDiskAdaptor();
@@ -84,6 +85,8 @@ public:
// Make sure that DiskWriter is set before calling this function.
virtual void disableReadOnly();
+ virtual bool isReadOnlyEnabled() const { return _readOnly; }
+
virtual void cutTrailingGarbage();
virtual std::string getFilePath() = 0;
diff --git a/src/BtCheckIntegrityEntry.cc b/src/BtCheckIntegrityEntry.cc
index 1be5e251..211467c2 100644
--- a/src/BtCheckIntegrityEntry.cc
+++ b/src/BtCheckIntegrityEntry.cc
@@ -51,11 +51,14 @@ BtCheckIntegrityEntry::~BtCheckIntegrityEntry() {}
void BtCheckIntegrityEntry::onDownloadIncomplete(std::deque<Command*>& commands,
DownloadEngine* e)
{
- // Now reopen DiskAdaptor with read only disabled.
- _requestGroup->getPieceStorage()->getDiskAdaptor()->closeFile();
- _requestGroup->getPieceStorage()->getDiskAdaptor()->disableReadOnly();
- _requestGroup->getPieceStorage()->getDiskAdaptor()->openFile();
-
+ const SharedHandle<DiskAdaptor>& diskAdaptor =
+ _requestGroup->getPieceStorage()->getDiskAdaptor();
+ if(diskAdaptor->isReadOnlyEnabled()) {
+ // Now reopen DiskAdaptor with read only disabled.
+ diskAdaptor->closeFile();
+ diskAdaptor->disableReadOnly();
+ diskAdaptor->openFile();
+ }
SharedHandle<BtFileAllocationEntry> entry
(new BtFileAllocationEntry(_requestGroup));
proceedFileAllocation(commands, entry, e);
diff --git a/src/DiskAdaptor.h b/src/DiskAdaptor.h
index a07d42e0..959f430b 100644
--- a/src/DiskAdaptor.h
+++ b/src/DiskAdaptor.h
@@ -100,6 +100,8 @@ public:
virtual void disableReadOnly() {}
+ virtual bool isReadOnlyEnabled() const { return false; }
+
// Assumed each file length is stored in fileEntries or DiskAdaptor knows it.
// If each actual file's length is larger than that, truncate file to that
// length.
diff --git a/src/MultiDiskAdaptor.h b/src/MultiDiskAdaptor.h
index ae9695e7..21fa60a6 100644
--- a/src/MultiDiskAdaptor.h
+++ b/src/MultiDiskAdaptor.h
@@ -155,6 +155,8 @@ public:
virtual void disableReadOnly();
+ virtual bool isReadOnlyEnabled() const { return _readOnly; }
+
void setPieceLength(size_t pieceLength) {
this->pieceLength = pieceLength;
}
diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc
index a33d179c..d65a687d 100644
--- a/src/RequestGroup.cc
+++ b/src/RequestGroup.cc
@@ -311,7 +311,20 @@ void RequestGroup::createInitialCommand(std::deque<Command*>& commands,
}
}
_progressInfoFile = progressInfoFile;
-
+ {
+ uint64_t actualFileSize = _pieceStorage->getDiskAdaptor()->size();
+ if(actualFileSize != btContext->getTotalLength()) {
+ // Re-open file in writable mode to allow the program
+ // truncate the file to the specified length
+ _logger->debug("File size not match. Re-open file in writable mode."
+ " Expected:%s Actual:%s",
+ Util::uitos(btContext->getTotalLength()).c_str(),
+ Util::uitos(actualFileSize).c_str());
+ _pieceStorage->getDiskAdaptor()->closeFile();
+ _pieceStorage->getDiskAdaptor()->disableReadOnly();
+ _pieceStorage->getDiskAdaptor()->openFile();
+ }
+ }
if(!btContext->isPrivate() && _option->getAsBool(PREF_ENABLE_DHT)) {
std::deque<Command*> commands;
DHTSetup().setup(commands, e, _option);
@@ -371,7 +384,7 @@ void RequestGroup::processCheckIntegrityEntry(std::deque<Command*>& commands,
if(e->option->getAsBool(PREF_CHECK_INTEGRITY) &&
entry->isValidationReady()) {
entry->initValidator();
- entry->cutTrailingGarbage();
+ entry->cutTrailingGarbage();
e->_checkIntegrityMan->pushEntry(entry);
} else
#endif // ENABLE_MESSAGE_DIGEST