diff -Nurp ktorrent-641523/configure.in.in ktorrent-642237/configure.in.in --- ktorrent-641523/configure.in.in 2007-03-08 21:07:02.000000000 +0200 +++ ktorrent-642237/configure.in.in 2007-03-13 20:36:48.000000000 +0200 @@ -11,6 +11,8 @@ AC_CHECK_FUNCS(fstat64, ktorrent_cv_func AC_CHECK_FUNCS(stat64, ktorrent_cv_func_stat64=yes, ktorrent_cv_func_stat64=no) AC_CHECK_FUNCS(ftruncate64, ktorrent_cv_func_ftruncate64=yes, ktorrent_cv_func_ftruncate64=no) AC_CHECK_FUNCS(lseek64, ktorrent_cv_func_lseek64=yes, ktorrent_cv_func_lseek64=no) +AC_CHECK_FUNCS(mmap64, ktorrent_cv_func_mmap64=yes, ktorrent_cv_func_mmap64=no) +AC_CHECK_FUNCS(munmap64, ktorrent_cv_func_munmap64=yes, ktorrent_cv_func_munmap64=no) if test "$ktorrent_cv_func_fseek64" = yes -a "$ktorrent_cv_func_ftell64" = yes; then AC_DEFINE(HAVE_FSEEKO64, 1) @@ -36,6 +38,18 @@ else AC_DEFINE(HAVE_LSEEK64,0) fi +if test "$ktorrent_cv_func_mmap64" = yes ; then + AC_DEFINE(HAVE_MMAP64, 1) +else + AC_DEFINE(HAVE_MMAP64, 0) +fi + +if test "$ktorrent_cv_func_munmap64" = yes ; then + AC_DEFINE(HAVE_MUNMAP64, 1) +else + AC_DEFINE(HAVE_MUNMAP64, 0) +fi + KDE_CHECK_LIB(gmp, __gmpz_init, [have_gmp=yes], [ have_gmp=no diff -Nurp ktorrent-641523/libktorrent/torrent/cachefile.cpp ktorrent-642237/libktorrent/torrent/cachefile.cpp --- ktorrent-641523/libktorrent/torrent/cachefile.cpp 2006-12-13 21:03:30.000000000 +0200 +++ ktorrent-642237/libktorrent/torrent/cachefile.cpp 2007-03-13 20:36:48.000000000 +0200 @@ -65,7 +65,7 @@ namespace bt CacheFile::~CacheFile() { if (fd != -1) - close(false); + close(); } void CacheFile::changePath(const QString & npath) @@ -83,20 +83,6 @@ namespace bt } file_size = FileSize(fd); - - // Out() << QString("CacheFile %1 = %2").arg(path).arg(file_size) << endl; - - // re do all mappings if there are any - QMap<void*,Entry>::iterator i = mappings.begin(); - while (i != mappings.end()) - { - CacheFile::Entry e = i.data(); - i++; - mappings.erase(e.ptr); - e.ptr = map(e.thing,e.offset,e.size - e.diff,e.mode); - if (e.ptr) - e.thing->remapped(e.ptr); - } } void CacheFile::open(const QString & path,Uint64 size) @@ -105,9 +91,6 @@ namespace bt // only set the path and the max size, we only open the file when it is needed this->path = path; max_size = size; - // if there are mappings we must reopen the file and restore them - if (mappings.count() > 0) - openFile(); } void* CacheFile::map(MMappeable* thing,Uint64 off,Uint32 size,Mode mode) @@ -156,7 +139,11 @@ namespace bt Uint32 diff = (off % page_size); Uint64 noff = off - diff; // Out() << "Offsetted mmap : " << diff << endl; +#if HAVE_MMAP64 + char* ptr = (char*)mmap64(0, size + diff, mmap_flag, MAP_SHARED, fd, noff); +#else char* ptr = (char*)mmap(0, size + diff, mmap_flag, MAP_SHARED, fd, noff); +#endif if (ptr == MAP_FAILED) { Out() << "mmap failed : " << QString(strerror(errno)) << endl; @@ -177,7 +164,11 @@ namespace bt } else { +#if HAVE_MMAP64 + void* ptr = mmap64(0, size, mmap_flag, MAP_SHARED, fd, off); +#else void* ptr = mmap(0, size, mmap_flag, MAP_SHARED, fd, off); +#endif if (ptr == MAP_FAILED) { Out() << "mmap failed : " << QString(strerror(errno)) << endl; @@ -256,11 +247,17 @@ namespace bt if (mappings.contains(ptr)) { CacheFile::Entry & e = mappings[ptr]; +#if HAVE_MUNMAP64 + if (e.diff > 0) + ret = munmap64((char*)ptr - e.diff,e.size); + else + ret = munmap64(ptr,e.size); +#else if (e.diff > 0) ret = munmap((char*)ptr - e.diff,e.size); else ret = munmap(ptr,e.size); - +#endif mappings.erase(ptr); // no mappings, close temporary if (mappings.count() == 0) @@ -268,7 +265,11 @@ namespace bt } else { +#if HAVE_MUNMAP64 + ret = munmap64(ptr,size); +#else ret = munmap(ptr,size); +#endif } if (ret < 0) @@ -277,7 +278,7 @@ namespace bt } } - void CacheFile::close(bool to_be_reopened) + void CacheFile::close() { QMutexLocker lock(&mutex); @@ -289,23 +290,22 @@ namespace bt { int ret = 0; CacheFile::Entry & e = i.data(); +#if HAVE_MUNMAP64 + if (e.diff > 0) + ret = munmap64((char*)e.ptr - e.diff,e.size); + else + ret = munmap64(e.ptr,e.size); +#else if (e.diff > 0) ret = munmap((char*)e.ptr - e.diff,e.size); else ret = munmap(e.ptr,e.size); - e.thing->unmapped(to_be_reopened); - // if it will be reopenend, we will not remove all mappings - // so that they will be redone on reopening - if (to_be_reopened) - { - i++; - } - else - { - i++; - mappings.erase(e.ptr); - } +#endif + e.thing->unmapped(); + i++; + mappings.erase(e.ptr); + if (ret < 0) { Out(SYS_DIO|LOG_IMPORTANT) << QString("Munmap failed with error %1 : %2").arg(errno).arg(strerror(errno)) << endl; @@ -318,12 +318,14 @@ namespace bt void CacheFile::read(Uint8* buf,Uint32 size,Uint64 off) { QMutexLocker lock(&mutex); + bool close_again = false; // reopen the file if necessary if (fd == -1) { // Out() << "Reopening " << path << endl; openFile(); + close_again = true; } if (off >= file_size || off >= max_size) @@ -334,18 +336,28 @@ namespace bt // jump to right position SeekFile(fd,off,SEEK_SET); if ((Uint32)::read(fd,buf,size) != size) + { + if (close_again) + closeTemporary(); + throw Error(i18n("Error reading from %1").arg(path)); + } + + if (close_again) + closeTemporary(); } void CacheFile::write(const Uint8* buf,Uint32 size,Uint64 off) { QMutexLocker lock(&mutex); + bool close_again = false; // reopen the file if necessary if (fd == -1) { // Out() << "Reopening " << path << endl; openFile(); + close_again = true; } if (off + size > max_size) @@ -363,6 +375,9 @@ namespace bt // jump to right position SeekFile(fd,off,SEEK_SET); int ret = ::write(fd,buf,size); + if (close_again) + closeTemporary(); + if (ret == -1) throw Error(i18n("Error writing to %1 : %2").arg(path).arg(strerror(errno))); else if ((Uint32)ret != size) @@ -380,9 +395,8 @@ namespace bt if (fd == -1 || mappings.count() > 0) return; - close(fd); + ::close(fd); fd = -1; - //Out() << "Temporarely closed " << path << endl; } diff -Nurp ktorrent-641523/libktorrent/torrent/cachefile.h ktorrent-642237/libktorrent/torrent/cachefile.h --- ktorrent-641523/libktorrent/torrent/cachefile.h 2006-12-27 16:14:04.000000000 +0200 +++ ktorrent-642237/libktorrent/torrent/cachefile.h 2007-03-13 20:36:48.000000000 +0200 @@ -41,16 +41,8 @@ namespace bt /** * When a CacheFile is closed, this will be called on all existing mappings. - * @param remap_intended A remap will happen */ - virtual void unmapped(bool remap_intended) = 0; - - /** - * When a previously unmapped thing is remapped again. This happens - * if the CacheFile is moved on disk. - * @param ptr The new pointer to the mapping - */ - virtual void remapped(void* ptr) = 0; + virtual void unmapped() = 0; }; /** @@ -103,7 +95,7 @@ namespace bt * Close the file, everything will be unmapped. * @param to_be_reopened Indicates if the close is temporarely (i.e. it will be reopened) */ - void close(bool to_be_reopened); + void close(); /** * Read from the file. diff -Nurp ktorrent-641523/libktorrent/torrent/chunk.cpp ktorrent-642237/libktorrent/torrent/chunk.cpp --- ktorrent-641523/libktorrent/torrent/chunk.cpp 2006-12-27 16:14:04.000000000 +0200 +++ ktorrent-642237/libktorrent/torrent/chunk.cpp 2007-03-13 20:36:48.000000000 +0200 @@ -61,16 +61,11 @@ namespace bt } } - void Chunk::unmapped(bool remap_intended) + void Chunk::unmapped() { - setData(0,remap_intended ? Chunk::MMAPPED : Chunk::ON_DISK); + setData(0,Chunk::ON_DISK); } - void Chunk::remapped(void* ptr) - { - setData((Uint8*)ptr,Chunk::MMAPPED); - } - bool Chunk::checkHash(const SHA1Hash & h) const { if (status != BUFFERED && status != MMAPPED) diff -Nurp ktorrent-641523/libktorrent/torrent/chunk.h ktorrent-642237/libktorrent/torrent/chunk.h --- ktorrent-641523/libktorrent/torrent/chunk.h 2006-12-27 16:14:04.000000000 +0200 +++ ktorrent-642237/libktorrent/torrent/chunk.h 2007-03-13 20:36:48.000000000 +0200 @@ -114,8 +114,7 @@ namespace bt */ bool checkHash(const SHA1Hash & h) const; - virtual void unmapped(bool remap_intended); - virtual void remapped(void* ptr); + virtual void unmapped(); private: Status status; diff -Nurp ktorrent-641523/libktorrent/torrent/singlefilecache.cpp ktorrent-642237/libktorrent/torrent/singlefilecache.cpp --- ktorrent-641523/libktorrent/torrent/singlefilecache.cpp 2006-12-13 21:03:30.000000000 +0200 +++ ktorrent-642237/libktorrent/torrent/singlefilecache.cpp 2007-03-13 20:36:48.000000000 +0200 @@ -124,7 +124,7 @@ namespace bt { if (fd) { - fd->close(false); + fd->close(); delete fd; fd = 0; } @@ -142,7 +142,7 @@ namespace bt } catch (...) { - fd->close(false); + fd->close(); delete fd; fd = 0; throw; diff -Nurp ktorrent-641523/libktorrent/util/mmapfile.cpp ktorrent-642237/libktorrent/util/mmapfile.cpp --- ktorrent-641523/libktorrent/util/mmapfile.cpp 2006-09-23 11:34:33.000000000 +0300 +++ ktorrent-642237/libktorrent/util/mmapfile.cpp 2007-03-13 20:36:48.000000000 +0200 @@ -116,7 +116,11 @@ namespace bt filename = file; // mmap the file +#if HAVE_MMAP64 + data = (Uint8*)mmap64(0, size, mmap_flag, MAP_SHARED, fd, 0); +#else data = (Uint8*)mmap(0, size, mmap_flag, MAP_SHARED, fd, 0); +#endif if (data == MAP_FAILED) { ::close(fd); @@ -133,7 +137,11 @@ namespace bt { if (fd > 0) { +#if HAVE_MUNMAP64 + munmap64(data,size); +#else munmap(data,size); +#endif ::close(fd); ptr = size = 0; data = 0;