mirror of https://github.com/aria2/aria2
flush OS write buffers before saving control file
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 <alimjalnasrawy@gmail.com>pull/1644/head
parent
870e2a6014
commit
01969fc530
|
@ -590,4 +590,16 @@ void AbstractDiskWriter::dropCache(int64_t len, int64_t offset)
|
||||||
#endif // HAVE_POSIX_FADVISE
|
#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
|
} // namespace aria2
|
||||||
|
|
|
@ -100,6 +100,8 @@ public:
|
||||||
virtual void enableMmap() CXX11_OVERRIDE;
|
virtual void enableMmap() CXX11_OVERRIDE;
|
||||||
|
|
||||||
virtual void dropCache(int64_t len, int64_t offset) CXX11_OVERRIDE;
|
virtual void dropCache(int64_t len, int64_t offset) CXX11_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void flushOSBuffers() CXX11_OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -103,6 +103,11 @@ void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractSingleDiskAdaptor::flushOSBuffers()
|
||||||
|
{
|
||||||
|
diskWriter_->flushOSBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
bool AbstractSingleDiskAdaptor::fileExists()
|
bool AbstractSingleDiskAdaptor::fileExists()
|
||||||
{
|
{
|
||||||
return File(getFilePath()).exists();
|
return File(getFilePath()).exists();
|
||||||
|
|
|
@ -72,6 +72,8 @@ public:
|
||||||
|
|
||||||
virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;
|
virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void flushOSBuffers() CXX11_OVERRIDE;
|
||||||
|
|
||||||
virtual bool fileExists() CXX11_OVERRIDE;
|
virtual bool fileExists() CXX11_OVERRIDE;
|
||||||
|
|
||||||
virtual int64_t size() CXX11_OVERRIDE;
|
virtual int64_t size() CXX11_OVERRIDE;
|
||||||
|
|
|
@ -114,6 +114,9 @@ public:
|
||||||
// Writes cached data to the underlying disk.
|
// Writes cached data to the underlying disk.
|
||||||
virtual void writeCache(const WrDiskCacheEntry* entry) = 0;
|
virtual void writeCache(const WrDiskCacheEntry* entry) = 0;
|
||||||
|
|
||||||
|
// Force physical write of data from OS buffer cache.
|
||||||
|
virtual void flushOSBuffers() {};
|
||||||
|
|
||||||
void setFileAllocationMethod(FileAllocationMethod method)
|
void setFileAllocationMethod(FileAllocationMethod method)
|
||||||
{
|
{
|
||||||
fileAllocationMethod_ = method;
|
fileAllocationMethod_ = method;
|
||||||
|
|
|
@ -85,6 +85,9 @@ public:
|
||||||
|
|
||||||
// Drops cache in range [offset, offset + len)
|
// Drops cache in range [offset, offset + len)
|
||||||
virtual void dropCache(int64_t len, int64_t offset) {}
|
virtual void dropCache(int64_t len, int64_t offset) {}
|
||||||
|
|
||||||
|
// Force physical write of data from OS buffer cache.
|
||||||
|
virtual void flushOSBuffers() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace aria2
|
} // namespace aria2
|
||||||
|
|
|
@ -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()
|
bool MultiDiskAdaptor::fileExists()
|
||||||
{
|
{
|
||||||
return std::find_if(std::begin(getFileEntries()), std::end(getFileEntries()),
|
return std::find_if(std::begin(getFileEntries()), std::end(getFileEntries()),
|
||||||
|
|
|
@ -135,6 +135,8 @@ public:
|
||||||
|
|
||||||
virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;
|
virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;
|
||||||
|
|
||||||
|
virtual void flushOSBuffers() CXX11_OVERRIDE;
|
||||||
|
|
||||||
virtual bool fileExists() CXX11_OVERRIDE;
|
virtual bool fileExists() CXX11_OVERRIDE;
|
||||||
|
|
||||||
virtual int64_t size() CXX11_OVERRIDE;
|
virtual int64_t size() CXX11_OVERRIDE;
|
||||||
|
|
|
@ -211,6 +211,7 @@ void RequestGroup::closeFile()
|
||||||
{
|
{
|
||||||
if (pieceStorage_) {
|
if (pieceStorage_) {
|
||||||
pieceStorage_->flushWrDiskCacheEntry(true);
|
pieceStorage_->flushWrDiskCacheEntry(true);
|
||||||
|
pieceStorage_->getDiskAdaptor()->flushOSBuffers();
|
||||||
pieceStorage_->getDiskAdaptor()->closeFile();
|
pieceStorage_->getDiskAdaptor()->closeFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1292,6 +1293,7 @@ void RequestGroup::saveControlFile() const
|
||||||
if (saveControlFile_) {
|
if (saveControlFile_) {
|
||||||
if (pieceStorage_) {
|
if (pieceStorage_) {
|
||||||
pieceStorage_->flushWrDiskCacheEntry(false);
|
pieceStorage_->flushWrDiskCacheEntry(false);
|
||||||
|
pieceStorage_->getDiskAdaptor()->flushOSBuffers();
|
||||||
}
|
}
|
||||||
progressInfoFile_->save();
|
progressInfoFile_->save();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue