diff --git a/src/data/socket_file.cc b/src/data/socket_file.cc index b359ef8e2..f7d3d50e9 100644 --- a/src/data/socket_file.cc +++ b/src/data/socket_file.cc @@ -1,43 +1,8 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include "socket_file.h" #include "torrent/exceptions.h" +#include "torrent/utils/log.h" #include #include @@ -48,10 +13,15 @@ #include #ifdef HAVE_FALLOCATE +#ifndef _GNU_SOURCE #define _GNU_SOURCE +#endif #include #endif +#define LT_LOG_ERROR(log_fmt, ...) \ + lt_log_print(LOG_STORAGE, "socket_file->%i: " log_fmt, m_fd, __VA_ARGS__); + namespace torrent { bool @@ -73,7 +43,7 @@ SocketFile::open(const std::string& path, int prot, int flags, mode_t mode) { #else fd_type fd = ::open(path.c_str(), flags, mode); #endif - + if (fd == invalid_fd) return false; @@ -99,26 +69,42 @@ SocketFile::size() const { rak::file_stat fs; return fs.update(m_fd) ? fs.size() : 0; -} +} bool -SocketFile::set_size(uint64_t size, int flags) const { +SocketFile::set_size(uint64_t size) const { if (!is_open()) throw internal_error("SocketFile::set_size() called on a closed file"); -#ifdef HAVE_FALLOCATE - if (flags & flag_fallocate && fallocate(m_fd, 0, 0, size) == 0) - return true; -#endif + if (ftruncate(m_fd, size) == -1) { + return false; + } -#ifdef USE_POSIX_FALLOCATE - if (flags & flag_fallocate && - flags & flag_fallocate_blocking && - posix_fallocate(m_fd, 0, size) == 0) - return true; -#endif + return true; +} -#ifdef SYS_DARWIN +bool +SocketFile::allocate(uint64_t size, int flags) const { + if (!is_open()) + throw internal_error("SocketFile::allocate() called on a closed file"); + +#if defined(HAVE_FALLOCATE) + if (flags & flag_fallocate) { + if (fallocate(m_fd, 0, 0, size) == -1) { + LT_LOG_ERROR("fallocate failed : %s", strerror(errno)); + return false; + } + } + +#elif defined(USE_POSIX_FALLOCATE) + if (flags & flag_fallocate && flags & flag_fallocate_blocking) { + if (posix_fallocate(m_fd, 0, size) == -1) { + LT_LOG_INFO("posix_fallocate failed : %s", strerror(errno)); + return false; + } + } + +#elif defined(SYS_DARWIN) if (flags & flag_fallocate) { fstore_t fstore; fstore.fst_flags = F_ALLOCATECONTIG; @@ -127,29 +113,21 @@ SocketFile::set_size(uint64_t size, int flags) const { fstore.fst_length = size; fstore.fst_bytesalloc = 0; - // Hmm... this shouldn't really be something we fail the set_size - // on... + // This shouldn't really be something we fail the set_size + // on. // - // Yet is somehow fails with ENOSPC... + // Yet is somehow fails with ENOSPC. // if (fcntl(m_fd, F_PREALLOCATE, &fstore) == -1) // throw internal_error("hack: fcntl failed" + std::string(strerror(errno))); - fcntl(m_fd, F_PREALLOCATE, &fstore); // Ignore result for now... - } -#endif + if (fcntl(m_fd, F_PREALLOCATE, &fstore) == -1) + LT_LOG_INFO("fcntl(,F_PREALLOCATE,) failed : %s", strerror(errno)); - if (ftruncate(m_fd, size) == 0) - return true; - - // Use workaround to resize files on vfat. It causes the whole - // client to block while it is resizing the files, this really - // should be in a seperate thread. - if (size != 0 && - lseek(m_fd, size - 1, SEEK_SET) == (off_t)(size - 1) && - write(m_fd, &size, 1) == 1) return true; + } +#endif - return false; + return true; } MemoryChunk @@ -165,7 +143,7 @@ SocketFile::create_chunk(uint64_t offset, uint32_t length, int prot, int flags) uint64_t align = offset % MemoryChunk::page_size(); char* ptr = (char*)mmap(NULL, length + align, prot, flags, m_fd, offset - align); - + if (ptr == MAP_FAILED) return MemoryChunk(); diff --git a/src/data/socket_file.h b/src/data/socket_file.h index d25c4a446..ca34c461e 100644 --- a/src/data/socket_file.h +++ b/src/data/socket_file.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_SOCKET_FILE_H #define LIBTORRENT_SOCKET_FILE_H @@ -68,12 +32,14 @@ class SocketFile { bool open(const std::string& path, int prot, int flags, mode_t mode = 0666); void close(); - + uint64_t size() const; - bool set_size(uint64_t s, int flags = 0) const; + bool set_size(uint64_t size) const; + + bool allocate(uint64_t size, int flags = 0) const; MemoryChunk create_chunk(uint64_t offset, uint32_t length, int prot, int flags) const; - + fd_type fd() const { return m_fd; } private: diff --git a/src/torrent/data/file.cc b/src/torrent/data/file.cc index 0dfe6ea8a..0f44754a8 100644 --- a/src/torrent/data/file.cc +++ b/src/torrent/data/file.cc @@ -1,41 +1,6 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" +#include #include #include @@ -76,8 +41,7 @@ File::File() : } File::~File() { - if (is_open()) - throw internal_error("File::~File() called on an open file."); + assert(!is_open() && "File::~File() called on an open file."); } bool @@ -177,16 +141,16 @@ File::resize_file() { if (m_size == SocketFile(m_fd).size()) return true; - int flags = 0; + if (!SocketFile(m_fd).set_size(m_size)) + return false; - // Set FS supported non-blocking allocation flag and potentially - // blocking allocation flag if fallocate flag is set. if (m_flags & flag_fallocate) { - flags |= SocketFile::flag_fallocate; - flags |= SocketFile::flag_fallocate_blocking; + // Only do non-blocking fallocate. + if (!SocketFile(m_fd).allocate(m_size, SocketFile::flag_fallocate)) + return false; } - return SocketFile(m_fd).set_size(m_size, flags); + return true; } } diff --git a/src/torrent/data/file.h b/src/torrent/data/file.h index 4c58994bd..e4b471f2e 100644 --- a/src/torrent/data/file.h +++ b/src/torrent/data/file.h @@ -142,7 +142,7 @@ class LIBTORRENT_EXPORT lt_cacheline_aligned File { int m_fd; int m_protection; int m_flags; - + Path m_path; std::string m_frozenPath; diff --git a/src/torrent/data/file_list.cc b/src/torrent/data/file_list.cc index 2e334fa89..a6ad80e35 100644 --- a/src/torrent/data/file_list.cc +++ b/src/torrent/data/file_list.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -92,7 +56,7 @@ FileList::~FileList() { // Can we skip close()? close(); - std::for_each(begin(), end(), rak::call_delete()); + std::for_each(begin(), end(), [](File* file) { delete file; }); base_type::clear(); m_torrentSize = 0; @@ -213,7 +177,7 @@ FileList::iterator_range FileList::split(iterator position, split_type* first, split_type* last) { if (is_open()) throw internal_error("FileList::split(...) is_open().", data()->hash()); - + if (first == last || position == end()) throw internal_error("FileList::split(...) invalid arguments.", data()->hash()); @@ -355,7 +319,7 @@ FileList::make_all_paths() { rak::error_number::clear_global(); make_directory(entry->path()->begin(), entry->path()->end(), firstMismatch); - + lastPath = entry->path(); } @@ -415,7 +379,7 @@ FileList::open(int flags) { try { if (!(flags & open_no_create) && !make_root_path()) throw storage_error("Could not create directory '" + m_rootDir + "': " + std::strerror(errno)); - + for (itr = begin(); itr != end(); ++itr) { File* entry = *itr; @@ -427,7 +391,7 @@ FileList::open(int flags) { // we can keep the previously opened file. if (entry->is_open()) continue; - + // Update the path during open so that any changes to root dir // and file paths are properly handled. if (entry->path()->back().empty()) @@ -602,10 +566,11 @@ FileList::create_chunk(uint64_t offset, uint32_t length, int prot) { if (offset + length > m_torrentSize) throw internal_error("Tried to access chunk out of range in FileList", data()->hash()); - std::auto_ptr chunk(new Chunk); + std::unique_ptr chunk(new Chunk); - for (iterator itr = std::find_if(begin(), end(), std::bind2nd(std::mem_fun(&File::is_valid_position), offset)); length != 0; ++itr) { + auto itr = std::find_if(begin(), end(), [offset](File* file) { return file->is_valid_position(offset); }); + for (; length != 0; ++itr) { if (itr == end()) throw internal_error("FileList could not find a valid file for chunk", data()->hash()); @@ -667,15 +632,15 @@ FileList::mark_completed(uint32_t index) { if (m_data.normal_priority()->has(index) || m_data.high_priority()->has(index)) { if (m_data.wanted_chunks() == 0) throw internal_error("FileList::mark_completed(...) m_data.wanted_chunks() == 0.", data()->hash()); - + m_data.set_wanted_chunks(m_data.wanted_chunks() - 1); } } FileList::iterator FileList::inc_completed(iterator firstItr, uint32_t index) { - firstItr = std::find_if(firstItr, end(), rak::less(index, std::mem_fun(&File::range_second))); - iterator lastItr = std::find_if(firstItr, end(), rak::less(index + 1, std::mem_fun(&File::range_second))); + firstItr = std::find_if(firstItr, end(), [index](File* file) { return index < file->range_second(); }); + auto lastItr = std::find_if(firstItr, end(), [index](File* file) { return index+1 < file->range_second(); }); if (firstItr == end()) throw internal_error("FileList::inc_completed() first == m_entryList->end().", data()->hash()); @@ -683,7 +648,7 @@ FileList::inc_completed(iterator firstItr, uint32_t index) { // TODO: Check if this works right for zero-length files. std::for_each(firstItr, lastItr == end() ? end() : (lastItr + 1), - std::mem_fun(&File::inc_completed_protected)); + [](File* file) { file->inc_completed_protected(); }); return lastItr; } diff --git a/src/torrent/data/file_list.h b/src/torrent/data/file_list.h index 2cb64f669..9ced1ed7e 100644 --- a/src/torrent/data/file_list.h +++ b/src/torrent/data/file_list.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_FILE_LIST_H #define LIBTORRENT_FILE_LIST_H @@ -199,7 +163,9 @@ class LIBTORRENT_EXPORT FileList : private std::vector { inline FileList::iterator file_list_contains_position(FileList* file_list, uint64_t pos) { - return std::find_if(file_list->begin(), file_list->end(), std::bind2nd(std::mem_fun(&File::is_valid_position), pos)); + return std::find_if(file_list->begin(), file_list->end(), [pos] (File* file) { + return file->is_valid_position(pos); + }); } } diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h index fe6127d62..fb23c883b 100644 --- a/src/torrent/utils/log.h +++ b/src/torrent/utils/log.h @@ -106,6 +106,7 @@ enum { LOG_RPC_EVENTS, LOG_RPC_DUMP, + LOG_STORAGE, LOG_SYSTEM, LOG_UI_EVENTS, diff --git a/src/torrent/utils/option_strings.cc b/src/torrent/utils/option_strings.cc index 101e2688d..fb3521bbe 100644 --- a/src/torrent/utils/option_strings.cc +++ b/src/torrent/utils/option_strings.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -41,14 +5,13 @@ #include #include "torrent/connection_manager.h" +#include "torrent/download.h" +#include "torrent/exceptions.h" #include "torrent/object.h" #include "torrent/download/choke_group.h" #include "torrent/download/choke_queue.h" - -#include "exceptions.h" -#include "download.h" -#include "log.h" -#include "option_strings.h" +#include "torrent/utils/log.h" +#include "torrent/utils/option_strings.h" namespace torrent { @@ -144,21 +107,21 @@ const char* option_list_log_group[] = { "notice", "info", "debug", - + "dht_critical", "dht_error", "dht_warn", "dht_notice", "dht_info", "dht_debug", - + "peer_critical", "peer_error", "peer_warn", "peer_notice", "peer_info", "peer_debug", - + "socket_critical", "socket_error", "socket_warn", @@ -179,14 +142,14 @@ const char* option_list_log_group[] = { "thread_notice", "thread_info", "thread_debug", - + "tracker_critical", "tracker_error", "tracker_warn", "tracker_notice", "tracker_info", "tracker_debug", - + "torrent_critical", "torrent_error", "torrent_warn", @@ -230,6 +193,7 @@ const char* option_list_log_group[] = { "rpc_events", "rpc_dump", + "storage", "system", "ui_events",