diff --git a/include/libtorrent/disk_io_thread.hpp b/include/libtorrent/disk_io_thread.hpp index 1d5af07d3..c7f475f9c 100644 --- a/include/libtorrent/disk_io_thread.hpp +++ b/include/libtorrent/disk_io_thread.hpp @@ -97,7 +97,7 @@ namespace libtorrent bool need_readback; }; - + // this struct holds a number of statistics counters // relevant for the disk io thread and disk cache. struct TORRENT_EXPORT cache_status @@ -461,7 +461,7 @@ namespace libtorrent // writes out the blocks [start, end) (releases the lock // during the file operation) int flush_range(cached_piece_entry* p, int start, int end - , int flags, tailqueue& completed_jobs, mutex::scoped_lock& l); + , tailqueue& completed_jobs, mutex::scoped_lock& l); // low level flush operations, used by flush_range int build_iovec(cached_piece_entry* pe, int start, int end diff --git a/include/libtorrent/part_file.hpp b/include/libtorrent/part_file.hpp index db8c74e0c..772744413 100644 --- a/include/libtorrent/part_file.hpp +++ b/include/libtorrent/part_file.hpp @@ -52,13 +52,13 @@ namespace libtorrent // each piece being 'piece_size' number of bytes part_file(std::string const& path, std::string const& name, int num_pieces, int piece_size); ~part_file(); - + int writev(file::iovec_t const* bufs, int num_bufs, int piece, int offset, error_code& ec); int readv(file::iovec_t const* bufs, int num_bufs, int piece, int offset, error_code& ec); // free the slot the given piece is stored in. We no longer need to store this // piece in the part file - void free_piece(int piece, error_code& ec); + void free_piece(int piece); void move_partfile(std::string const& path, error_code& ec); diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 98e09df18..cf2c91f85 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -346,7 +346,7 @@ namespace libtorrent DLOG("try_flush_hashed: (%d) blocks_in_piece: %d end: %d\n" , int(p->piece), int(p->blocks_in_piece), end); - return flush_range(p, 0, end, 0, completed_jobs, l); + return flush_range(p, 0, end, completed_jobs, l); } // piece range @@ -713,7 +713,7 @@ namespace libtorrent // issues write operations for blocks in the given // range on the given piece. int disk_io_thread::flush_range(cached_piece_entry* pe, int start, int end - , int flags, tailqueue& completed_jobs, mutex::scoped_lock& l) + , tailqueue& completed_jobs, mutex::scoped_lock& l) { TORRENT_ASSERT(l.locked()); INVARIANT_CHECK; @@ -722,7 +722,7 @@ namespace libtorrent , int(pe->piece), start, end); TORRENT_PIECE_ASSERT(start >= 0, pe); TORRENT_PIECE_ASSERT(start < end, pe); - + file::iovec_t* iov = TORRENT_ALLOCA(file::iovec_t, pe->blocks_in_piece); int* flushing = TORRENT_ALLOCA(int, pe->blocks_in_piece); int iov_len = build_iovec(pe, start, end, iov, flushing, 0); @@ -791,7 +791,7 @@ namespace libtorrent else if ((flags & flush_write_cache) && pe->num_dirty > 0) { // issue write commands - flush_range(pe, 0, INT_MAX, 0, completed_jobs, l); + flush_range(pe, 0, INT_MAX, completed_jobs, l); // if we're also flushing the read cache, this piece // should be removed as soon as all write jobs finishes @@ -943,7 +943,7 @@ namespace libtorrent #endif ++pe->piece_refcount; - num -= flush_range(pe, 0, INT_MAX, 0, completed_jobs, l); + num -= flush_range(pe, 0, INT_MAX, completed_jobs, l); --pe->piece_refcount; m_disk_cache.maybe_free_piece(pe); @@ -991,7 +991,7 @@ namespace libtorrent for (int i = 0; i < num_flush; ++i) { - flush_range(to_flush[i], 0, INT_MAX, 0, completed_jobs, l); + flush_range(to_flush[i], 0, INT_MAX, completed_jobs, l); TORRENT_ASSERT(to_flush[i]->piece_refcount > 0); --to_flush[i]->piece_refcount; m_disk_cache.maybe_free_piece(to_flush[i]); diff --git a/src/part_file.cpp b/src/part_file.cpp index ad7abef9c..5050d66d5 100644 --- a/src/part_file.cpp +++ b/src/part_file.cpp @@ -102,20 +102,20 @@ namespace libtorrent file::iovec_t b = {header.get(), size_t(m_header_size) }; int n = m_file.readv(0, &b, 1, ec); if (ec) return; - + // we don't have a full header. consider the file empty if (n < m_header_size) return; using namespace libtorrent::detail; - + char* ptr = (char*)header.get(); // we have a header. Parse it int num_pieces_ = read_uint32(ptr); int piece_size_ = read_uint32(ptr); - + // if there is a mismatch in number of pieces or piece size // consider the file empty and overwrite anything in there if (num_pieces != num_pieces_ || m_piece_size != piece_size_) return; - + // this is used to determine which slots are free, and how many // slots are allocated std::vector free_slots; @@ -125,14 +125,14 @@ namespace libtorrent { int slot = read_uint32(ptr); if (slot == 0xffffffff) continue; - + // invalid part-file TORRENT_ASSERT(slot < num_pieces); if (slot >= num_pieces) continue; - + if (slot >= m_num_allocated) m_num_allocated = slot + 1; - + free_slots[slot] = false; m_piece_map[i] = slot; } @@ -152,7 +152,7 @@ namespace libtorrent error_code ec; flush_metadata_impl(ec); } - + int part_file::allocate_slot(int piece) { // the mutex is assumed to be held here, since this is a private function @@ -242,7 +242,7 @@ namespace libtorrent } } - void part_file::free_piece(int piece, error_code& ec) + void part_file::free_piece(int piece) { mutex::scoped_lock l(m_mutex); @@ -316,16 +316,19 @@ namespace libtorrent { open_file(file::read_only, ec); if (ec) return; - + if (!buf) buf.reset(new char[m_piece_size]); boost::int64_t slot_offset = boost::int64_t(m_header_size) + boost::int64_t(i->second) * m_piece_size; file::iovec_t v = { buf.get(), size_t(block_to_copy) }; int ret = m_file.readv(slot_offset + piece_offset, &v, 1, ec); - if (ec) return; + TORRENT_ASSERT(ec || ret == block_to_copy); + if (ec || ret != block_to_copy) return; + ret = f.writev(file_offset, &v, 1, ec); - if (ec) return; + TORRENT_ASSERT(ec || ret == block_to_copy); + if (ec || ret != block_to_copy) return; if (block_to_copy == m_piece_size) { diff --git a/src/storage.cpp b/src/storage.cpp index 618a2be93..032a431f7 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -190,7 +190,7 @@ namespace libtorrent size += i->iov_len; return size; } - + TORRENT_EXTRA_EXPORT void clear_bufs(file::iovec_t const* bufs, int num_bufs) { for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) diff --git a/test/test_part_file.cpp b/test/test_part_file.cpp index 93e516c16..3b6d7d7c9 100644 --- a/test/test_part_file.cpp +++ b/test/test_part_file.cpp @@ -118,8 +118,7 @@ int test_main() pf.export_file(output, 10 * piece_size, 1024, ec); if (ec) fprintf(stderr, "export_file: %s\n", ec.message().c_str()); - pf.free_piece(10, ec); - if (ec) fprintf(stderr, "free_piece: %s\n", ec.message().c_str()); + pf.free_piece(10); pf.flush_metadata(ec); if (ec) fprintf(stderr, "flush_metadata: %s\n", ec.message().c_str());