diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc index ff4f8856..f21c5261 100644 --- a/src/AbstractDiskWriter.cc +++ b/src/AbstractDiskWriter.cc @@ -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 diff --git a/src/AbstractDiskWriter.h b/src/AbstractDiskWriter.h index 9e5c4799..96518a68 100644 --- a/src/AbstractDiskWriter.h +++ b/src/AbstractDiskWriter.h @@ -100,6 +100,8 @@ public: virtual void enableMmap() CXX11_OVERRIDE; virtual void dropCache(int64_t len, int64_t offset) CXX11_OVERRIDE; + + virtual void flushOSBuffers() CXX11_OVERRIDE; }; } // namespace aria2 diff --git a/src/AbstractSingleDiskAdaptor.cc b/src/AbstractSingleDiskAdaptor.cc index 54ec783e..6e6b70e6 100644 --- a/src/AbstractSingleDiskAdaptor.cc +++ b/src/AbstractSingleDiskAdaptor.cc @@ -103,6 +103,11 @@ void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry) } } +void AbstractSingleDiskAdaptor::flushOSBuffers() +{ + diskWriter_->flushOSBuffers(); +} + bool AbstractSingleDiskAdaptor::fileExists() { return File(getFilePath()).exists(); diff --git a/src/AbstractSingleDiskAdaptor.h b/src/AbstractSingleDiskAdaptor.h index 8d17686c..36899e10 100644 --- a/src/AbstractSingleDiskAdaptor.h +++ b/src/AbstractSingleDiskAdaptor.h @@ -72,6 +72,8 @@ public: virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE; + virtual void flushOSBuffers() CXX11_OVERRIDE; + virtual bool fileExists() CXX11_OVERRIDE; virtual int64_t size() CXX11_OVERRIDE; diff --git a/src/DiskAdaptor.h b/src/DiskAdaptor.h index 2643a65d..9287b3ec 100644 --- a/src/DiskAdaptor.h +++ b/src/DiskAdaptor.h @@ -114,6 +114,9 @@ public: // 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; diff --git a/src/DiskWriter.h b/src/DiskWriter.h index 960e346c..03a4147b 100644 --- a/src/DiskWriter.h +++ b/src/DiskWriter.h @@ -85,6 +85,9 @@ public: // 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 diff --git a/src/MultiDiskAdaptor.cc b/src/MultiDiskAdaptor.cc index d4f419cf..14321aab 100644 --- a/src/MultiDiskAdaptor.cc +++ b/src/MultiDiskAdaptor.cc @@ -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()), diff --git a/src/MultiDiskAdaptor.h b/src/MultiDiskAdaptor.h index 9959888a..7f8ccef4 100644 --- a/src/MultiDiskAdaptor.h +++ b/src/MultiDiskAdaptor.h @@ -135,6 +135,8 @@ public: virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE; + virtual void flushOSBuffers() CXX11_OVERRIDE; + virtual bool fileExists() CXX11_OVERRIDE; virtual int64_t size() CXX11_OVERRIDE; diff --git a/src/RequestGroup.cc b/src/RequestGroup.cc index a008642d..fd6801fc 100644 --- a/src/RequestGroup.cc +++ b/src/RequestGroup.cc @@ -211,6 +211,7 @@ void RequestGroup::closeFile() { if (pieceStorage_) { pieceStorage_->flushWrDiskCacheEntry(true); + pieceStorage_->getDiskAdaptor()->flushOSBuffers(); pieceStorage_->getDiskAdaptor()->closeFile(); } } @@ -1292,6 +1293,7 @@ void RequestGroup::saveControlFile() const if (saveControlFile_) { if (pieceStorage_) { pieceStorage_->flushWrDiskCacheEntry(false); + pieceStorage_->getDiskAdaptor()->flushOSBuffers(); } progressInfoFile_->save(); }