From 431efc615767f0e4b45c6676407b46d7d87c1612 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 3 Mar 2013 04:47:19 +0000 Subject: [PATCH] merge storage fix from RC_0_16 --- ChangeLog | 1 + include/libtorrent/storage.hpp | 12 ++++++------ src/disk_io_thread.cpp | 2 +- src/storage.cpp | 36 ++++++++++++++++++---------------- test/test_transfer.cpp | 8 ++++---- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96d50dff1..9bed3b5d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ * fix uTP edge case where udp socket buffer fills up * fix nagle implementation in uTP + * distinguish file open mode when checking files and downloading/seeding with bittorrent. updates storage interface * improve file_storage::map_file when dealing with invalid input * improve handling of invalid utf-8 sequences in strings in torrent files * handle more cases of broken .torrent files diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 225151f2c..b7bc6f9de 100644 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -111,8 +111,8 @@ namespace libtorrent virtual bool has_any_file() = 0; - virtual int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs); - virtual int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs); + virtual int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); + virtual int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); virtual void hint_read(int, int, int) {} // negative return value indicates an error @@ -202,8 +202,8 @@ namespace libtorrent int write(char const* buf, int slot, int offset, int size); int sparse_end(int start) const; void hint_read(int slot, int offset, int len); - int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs); - int writev(file::iovec_t const* buf, int slot, int offset, int num_bufs); + int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); + int writev(file::iovec_t const* buf, int slot, int offset, int num_bufs, int flags = file::random_access); size_type physical_offset(int slot, int offset); bool move_slot(int src_slot, int dst_slot); bool swap_slots(int slot1, int slot2); @@ -275,8 +275,8 @@ namespace libtorrent int read(char*, int, int, int size) { return size; } int write(char const*, int, int, int size) { return size; } size_type physical_offset(int, int) { return 0; } - int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs); - int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs); + int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); + int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags = file::random_access); bool move_slot(int, int) { return false; } bool swap_slots(int, int) { return false; } bool swap_slots3(int, int, int) { return false; } diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index f7e2d6a9d..86dbd0383 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -1411,7 +1411,7 @@ namespace libtorrent , 0 // release_files , 0 // delete_files , 0 // check_fastresume - , read_operation + cancel_on_abort // check_files + , cancel_on_abort // check_files , 0 // save_resume_data , 0 // rename_file , 0 // abort_thread diff --git a/src/storage.cpp b/src/storage.cpp index 7cfbddfaf..0871dc5a3 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -203,7 +203,7 @@ namespace libtorrent // writev implementations be implemented in terms of the // old read and write int storage_interface::readv(file::iovec_t const* bufs - , int slot, int offset, int num_bufs) + , int slot, int offset, int num_bufs, int flags) { int ret = 0; for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) @@ -217,7 +217,7 @@ namespace libtorrent } int storage_interface::writev(file::iovec_t const* bufs, int slot - , int offset, int num_bufs) + , int offset, int num_bufs, int flags) { int ret = 0; for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) @@ -321,7 +321,8 @@ namespace libtorrent bufs[i].iov_len = (std::min)(block_size, size); size -= bufs[i].iov_len; } - num_read = m_storage->readv(bufs, slot, ph.offset, num_blocks); + // deliberately pass in 0 as flags, to disable random_access + num_read = m_storage->readv(bufs, slot, ph.offset, num_blocks, 0); // TODO: if the read fails, set error and exit immediately for (int i = 0; i < num_blocks; ++i) @@ -353,7 +354,8 @@ namespace libtorrent for (int i = 0; i < num_blocks; ++i) { buf.iov_len = (std::min)(block_size, size); - int ret = m_storage->readv(&buf, slot, ph.offset, 1); + // deliberately pass in 0 as flags, to disable random_access + int ret = m_storage->readv(&buf, slot, ph.offset, 1, 0); if (ret > 0) num_read += ret; // TODO: if the read fails, set error and exit immediately @@ -448,7 +450,7 @@ namespace libtorrent } ec.clear(); - boost::intrusive_ptr f = open_file(file_iter, file::read_write, ec); + boost::intrusive_ptr f = open_file(file_iter, file::read_write | file::random_access, ec); if (ec) set_error(file_path, ec); else if (f) { @@ -920,7 +922,7 @@ ret: } int default_storage::writev(file::iovec_t const* bufs, int slot, int offset - , int num_bufs) + , int num_bufs, int flags) { #ifdef TORRENT_DISK_STATS disk_buffer_pool* pool = disk_pool(); @@ -931,7 +933,7 @@ ret: } #endif fileop op = { &file::writev, &default_storage::write_unaligned - , m_settings ? settings().disk_io_write_mode : 0, file::read_write }; + , m_settings ? settings().disk_io_write_mode : 0, file::read_write | flags }; #ifdef TORRENT_DISK_STATS int ret = readwritev(bufs, slot, offset, num_bufs, op); if (pool) @@ -971,7 +973,7 @@ ret: // open the file read only to avoid re-opening // it in case it's already opened in read-only mode error_code ec; - boost::intrusive_ptr f = open_file(file_iter, file::read_only, ec); + boost::intrusive_ptr f = open_file(file_iter, file::read_only | file::random_access, ec); size_type ret = 0; if (f && !ec) ret = f->phys_offset(file_offset); @@ -1019,7 +1021,7 @@ ret: if (file_iter->pad_file) continue; error_code ec; - file_handle = open_file(file_iter, file::read_only, ec); + file_handle = open_file(file_iter, file::read_only | file::random_access, ec); // failing to hint that we want to read is not a big deal // just swollow the error and keep going @@ -1031,7 +1033,7 @@ ret: } int default_storage::readv(file::iovec_t const* bufs, int slot, int offset - , int num_bufs) + , int num_bufs, int flags) { #ifdef TORRENT_DISK_STATS disk_buffer_pool* pool = disk_pool(); @@ -1042,7 +1044,7 @@ ret: } #endif fileop op = { &file::readv, &default_storage::read_unaligned - , m_settings ? settings().disk_io_read_mode : 0, file::read_only }; + , m_settings ? settings().disk_io_read_mode : 0, file::read_only | flags }; #ifdef TORRENT_SIMULATE_SLOW_READ boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(1000)); @@ -1138,7 +1140,7 @@ ret: if (file_iter->pad_file) { - if (op.mode == file::read_only) + if ((op.mode & file::rw_mask) == file::read_only) { int num_tmp_bufs = copy_bufs(current_buf, file_bytes_left, tmp_bufs); TORRENT_ASSERT(count_bufs(tmp_bufs, file_bytes_left) == num_tmp_bufs); @@ -1153,7 +1155,7 @@ ret: error_code ec; file_handle = open_file(file_iter, op.mode, ec); - if ((op.mode == file::read_write) && ec == boost::system::errc::no_such_file_or_directory) + if (((op.mode & file::rw_mask) == file::read_write) && ec == boost::system::errc::no_such_file_or_directory) { // this means the directory the file is in doesn't exist. // so create it @@ -1188,7 +1190,7 @@ ret: { bytes_transferred = (int)(this->*op.unaligned_op)(file_handle, adjusted_offset , tmp_bufs, num_tmp_bufs, ec); - if (op.mode == file::read_write + if ((op.mode & file::rw_mask) == file::read_write && adjusted_offset + bytes_transferred >= file_iter->size && (file_handle->pos_alignment() > 0 || file_handle->size_alignment() > 0)) { @@ -1332,7 +1334,7 @@ ret: , int size) { file::iovec_t b = { (file::iovec_base_t)buf, size_t(size) }; - return writev(&b, slot, offset, 1); + return writev(&b, slot, offset, 1, 0); } int default_storage::read( @@ -1368,7 +1370,7 @@ ret: return new default_storage(fs, mapped, path, fp, file_prio); } - int disabled_storage::readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs) + int disabled_storage::readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags) { #ifdef TORRENT_DISK_STATS disk_buffer_pool* pool = disk_pool(); @@ -1391,7 +1393,7 @@ ret: return ret; } - int disabled_storage::writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs) + int disabled_storage::writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags) { #ifdef TORRENT_DISK_STATS disk_buffer_pool* pool = disk_pool(); diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 7fb85acf4..8eec9796a 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -135,12 +135,12 @@ struct test_storage : storage_interface virtual bool has_any_file() { return m_lower_layer->has_any_file(); } - virtual int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs) - { return m_lower_layer->readv(bufs, slot, offset, num_bufs); } + virtual int readv(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags) + { return m_lower_layer->readv(bufs, slot, offset, num_bufs, flags); } - virtual int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs) + virtual int writev(file::iovec_t const* bufs, int slot, int offset, int num_bufs, int flags) { - int ret = m_lower_layer->writev(bufs, slot, offset, num_bufs); + int ret = m_lower_layer->writev(bufs, slot, offset, num_bufs, flags); if (ret > 0) m_written += ret; if (m_written > m_limit) {