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
pull/481/head
Tatsuhiro Tsujikawa 2015-11-12 22:42:24 +09:00
parent af98861aff
commit 3974c1223b
3 changed files with 20 additions and 9 deletions

View File

@ -284,12 +284,10 @@ ssize_t AbstractDiskWriter::readDataInternal(unsigned char* data, size_t len,
int64_t offset) int64_t offset)
{ {
if(mapaddr_) { if(mapaddr_) {
ssize_t readlen; if (offset >= maplen_) {
if(offset > maplen_) { return 0;
readlen = 0;
} else {
readlen = std::min(static_cast<size_t>(maplen_ - offset), len);
} }
auto readlen = std::min(maplen_ - offset, static_cast<int64_t>(len));
memcpy(data, mapaddr_ + offset, readlen); memcpy(data, mapaddr_ + offset, readlen);
return readlen; return readlen;
} else { } else {
@ -355,6 +353,14 @@ void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset)
} }
} else { } else {
int64_t filesize = size(); 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; int errNum = 0;
if(static_cast<int64_t>(len + offset) <= filesize) { if(static_cast<int64_t>(len + offset) <= filesize) {
#ifdef __MINGW32__ #ifdef __MINGW32__

View File

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

View File

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