Skip to content

Commit

Permalink
flush OS write buffers before saving control file
Browse files Browse the repository at this point in the history
This ensures that pieces are physically written to disk before
marking them as finished in the control file.

This should prevent data loss and corruption when resuming downloads
after a system crash.

Signed-off-by: Ali MJ Al-Nasrawy <[email protected]>
  • Loading branch information
aliemjay committed Jun 17, 2020
1 parent 870e2a6 commit 01969fc
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/AbstractDiskWriter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -590,4 +590,16 @@ void AbstractDiskWriter::dropCache(int64_t len, int64_t offset)
#endif // HAVE_POSIX_FADVISE
}

void AbstractDiskWriter::flushOSBuffers()
{
if (fd_ == A2_BAD_FD) {
return;
}
#ifdef __MINGW32__
FlushFileBuffers(fd_);
#else // !__MINGW32__
fsync(fd_);
#endif // __MINGW32__
}

} // namespace aria2
2 changes: 2 additions & 0 deletions src/AbstractDiskWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ class AbstractDiskWriter : public DiskWriter {
virtual void enableMmap() CXX11_OVERRIDE;

virtual void dropCache(int64_t len, int64_t offset) CXX11_OVERRIDE;

virtual void flushOSBuffers() CXX11_OVERRIDE;
};

} // namespace aria2
Expand Down
5 changes: 5 additions & 0 deletions src/AbstractSingleDiskAdaptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
}
}

void AbstractSingleDiskAdaptor::flushOSBuffers()
{
diskWriter_->flushOSBuffers();
}

bool AbstractSingleDiskAdaptor::fileExists()
{
return File(getFilePath()).exists();
Expand Down
2 changes: 2 additions & 0 deletions src/AbstractSingleDiskAdaptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ class AbstractSingleDiskAdaptor : public DiskAdaptor {

virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;

virtual void flushOSBuffers() CXX11_OVERRIDE;

virtual bool fileExists() CXX11_OVERRIDE;

virtual int64_t size() CXX11_OVERRIDE;
Expand Down
3 changes: 3 additions & 0 deletions src/DiskAdaptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ class DiskAdaptor : public BinaryStream {
// Writes cached data to the underlying disk.
virtual void writeCache(const WrDiskCacheEntry* entry) = 0;

// Force physical write of data from OS buffer cache.
virtual void flushOSBuffers() {};

void setFileAllocationMethod(FileAllocationMethod method)
{
fileAllocationMethod_ = method;
Expand Down
3 changes: 3 additions & 0 deletions src/DiskWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ class DiskWriter : public BinaryStream {

// Drops cache in range [offset, offset + len)
virtual void dropCache(int64_t len, int64_t offset) {}

// Force physical write of data from OS buffer cache.
virtual void flushOSBuffers() {}
};

} // namespace aria2
Expand Down
11 changes: 11 additions & 0 deletions src/MultiDiskAdaptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,17 @@ void MultiDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
}
}

void MultiDiskAdaptor::flushOSBuffers()
{
for (auto& dwent : openedDiskWriterEntries_) {
auto& dw = dwent->getDiskWriter();
if (!dw) {
continue;
}
dw->flushOSBuffers();
}
}

bool MultiDiskAdaptor::fileExists()
{
return std::find_if(std::begin(getFileEntries()), std::end(getFileEntries()),
Expand Down
2 changes: 2 additions & 0 deletions src/MultiDiskAdaptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class MultiDiskAdaptor : public DiskAdaptor {

virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;

virtual void flushOSBuffers() CXX11_OVERRIDE;

virtual bool fileExists() CXX11_OVERRIDE;

virtual int64_t size() CXX11_OVERRIDE;
Expand Down
2 changes: 2 additions & 0 deletions src/RequestGroup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ void RequestGroup::closeFile()
{
if (pieceStorage_) {
pieceStorage_->flushWrDiskCacheEntry(true);
pieceStorage_->getDiskAdaptor()->flushOSBuffers();
pieceStorage_->getDiskAdaptor()->closeFile();
}
}
Expand Down Expand Up @@ -1292,6 +1293,7 @@ void RequestGroup::saveControlFile() const
if (saveControlFile_) {
if (pieceStorage_) {
pieceStorage_->flushWrDiskCacheEntry(false);
pieceStorage_->getDiskAdaptor()->flushOSBuffers();
}
progressInfoFile_->save();
}
Expand Down

0 comments on commit 01969fc

Please sign in to comment.