Преглед изворни кода

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()) {