summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2015-11-12 22:42:24 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2015-11-12 22:42:24 +0900
commit3974c1223b19a8647d7e361fa130d0fa78a41026 (patch)
tree4cd9f9585cb2939ecef37a3d215ab59f4df6f751
parentaf98861aff50737f87d9c251ee9a68280bba3e64 (diff)
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
-rw-r--r--src/AbstractDiskWriter.cc16
-rw-r--r--src/BtFileAllocationEntry.cc8
-rw-r--r--src/StreamFileAllocationEntry.cc5
3 files changed, 20 insertions, 9 deletions
diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc
index 0944194c..0d1e014a 100644
--- a/src/AbstractDiskWriter.cc
+++ b/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__
diff --git a/src/BtFileAllocationEntry.cc b/src/BtFileAllocationEntry.cc
index 44553354..89a4c7c4 100644
--- a/src/BtFileAllocationEntry.cc
+++ b/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()) {
diff --git a/src/StreamFileAllocationEntry.cc b/src/StreamFileAllocationEntry.cc
index dfe1f679..de851da6 100644
--- a/src/StreamFileAllocationEntry.cc
+++ b/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()) {