فهرست منبع

Don't enable mmap if file allocation is disabled

Without file allocation, we cannot map file because file length could
be zero.

This could fix bug reported at GH-478
Tatsuhiro Tsujikawa 10 سال پیش
والد
کامیت
3974c1223b
3فایلهای تغییر یافته به همراه20 افزوده شده و 9 حذف شده
  1. 11 5
      src/AbstractDiskWriter.cc
  2. 5 3
      src/BtFileAllocationEntry.cc
  3. 4 1
      src/StreamFileAllocationEntry.cc

+ 11 - 5
src/AbstractDiskWriter.cc

@@ -284,12 +284,10 @@ ssize_t AbstractDiskWriter::readDataInternal(unsigned char* data, size_t len,
                                              int64_t offset)
 {
   if(mapaddr_) {
-    ssize_t readlen;
-    if(offset > maplen_) {
-      readlen = 0;
-    } else {
-      readlen = std::min(static_cast<size_t>(maplen_ - offset), len);
+    if (offset >= maplen_) {
+      return 0;
     }
+    auto readlen = std::min(maplen_ - offset, static_cast<int64_t>(len));
     memcpy(data, mapaddr_ + offset, readlen);
     return readlen;
   } else {
@@ -355,6 +353,14 @@ void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset)
       }
     } else {
       int64_t filesize = size();
+
+      if (filesize == 0) {
+        // mapping 0 length file is useless.  Also munmap with size ==
+        // 0 will fail with EINVAL.
+        enableMmap_ = false;
+        return;
+      }
+
       int errNum = 0;
       if(static_cast<int64_t>(len + offset) <= filesize) {
 #ifdef __MINGW32__

+ 5 - 3
src/BtFileAllocationEntry.cc

@@ -58,9 +58,11 @@ BtFileAllocationEntry::~BtFileAllocationEntry() {}
 void BtFileAllocationEntry::prepareForNextAction
 (std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
 {
-  BtSetup().setup(commands, getRequestGroup(), e,
-                  getRequestGroup()->getOption().get());
-  if(getRequestGroup()->getOption()->getAsBool(PREF_ENABLE_MMAP)) {
+  auto &option = getRequestGroup()->getOption();
+
+  BtSetup().setup(commands, getRequestGroup(), e, option.get());
+  if(option->getAsBool(PREF_ENABLE_MMAP) &&
+     option->get(PREF_FILE_ALLOCATION) != V_NONE) {
     getRequestGroup()->getPieceStorage()->getDiskAdaptor()->enableMmap();
   }
   if(!getRequestGroup()->downloadFinished()) {

+ 4 - 1
src/StreamFileAllocationEntry.cc

@@ -60,10 +60,13 @@ void StreamFileAllocationEntry::prepareForNextAction
 (std::vector<std::unique_ptr<Command>>& commands,
  DownloadEngine* e)
 {
+  auto &option = getRequestGroup()->getOption();
+
   // For DownloadContext::resetDownloadStartTime(), see also
   // RequestGroup::createInitialCommand()
   getRequestGroup()->getDownloadContext()->resetDownloadStartTime();
-  if(getRequestGroup()->getOption()->getAsBool(PREF_ENABLE_MMAP)) {
+  if(option->getAsBool(PREF_ENABLE_MMAP) &&
+     option->get(PREF_FILE_ALLOCATION) != V_NONE) {
     getRequestGroup()->getPieceStorage()->getDiskAdaptor()->enableMmap();
   }
   if(getNextCommand()) {