From b2c5d8a5635ce29d09c8439911e5d8e616198fe1 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 31 May 2009 19:44:56 +0000 Subject: [PATCH] include the piece index that failed in disk errors --- include/libtorrent/disk_io_thread.hpp | 3 +++ include/libtorrent/storage.hpp | 8 ++++++-- src/disk_io_thread.cpp | 5 +++++ src/storage.cpp | 12 ++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/libtorrent/disk_io_thread.hpp b/include/libtorrent/disk_io_thread.hpp index b9f5ac1c0..ec93e2f25 100644 --- a/include/libtorrent/disk_io_thread.hpp +++ b/include/libtorrent/disk_io_thread.hpp @@ -120,6 +120,9 @@ namespace libtorrent // the error code from the file operation error_code error; + // the piece the error occurred on + int error_piece; + // this is called when operation completes boost::function callback; }; diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 9cc1dfeb9..ef4f7c255 100644 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -289,6 +289,7 @@ namespace libtorrent error_code const& error() const { return m_storage->error(); } std::string const& error_file() const { return m_storage->error_file(); } + int last_piece() const { return m_last_piece; } void clear_error() { m_storage->clear_error(); } int slot_for(int piece) const; @@ -418,14 +419,17 @@ namespace libtorrent disk_buffer_holder m_scratch_buffer2; // the piece that is in the scratch buffer int m_scratch_piece; - + + // the last piece we wrote to or read from + int m_last_piece; + // this is saved in case we need to instantiate a new // storage (osed when remapping files) storage_constructor_type m_storage_constructor; // this maps a piece hash to piece index. It will be // build the first time it is used (to save time if it - // isn't needed) + // isn't needed) std::multimap m_hash_to_piece; // this map contains partial hashes for downloading diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 5269507e1..ddc08a22d 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -1248,6 +1248,7 @@ namespace libtorrent j.str = ec.message(); j.error = ec; j.error_file = j.storage->error_file(); + j.error_piece = j.storage->last_piece(); j.storage->clear_error(); #ifdef TORRENT_DEBUG std::cout << "ERROR: '" << j.str << "' " << j.error_file << std::endl; @@ -1421,6 +1422,7 @@ namespace libtorrent { ret = -1; j.error = error_code(ENOMEM, get_posix_category()); + j.error_piece = -1; j.str = j.error.message(); break; } @@ -1447,6 +1449,7 @@ namespace libtorrent j.storage->mark_failed(j.piece); j.error = error_code(errors::failed_hash_check, libtorrent_category); j.str = j.error.message(); + j.error_piece = j.storage->last_piece(); j.buffer = 0; break; } @@ -1473,6 +1476,7 @@ namespace libtorrent { ret = -1; j.error = error_code(ENOMEM, get_posix_category()); + j.error_piece = -1; j.str = j.error.message(); break; } @@ -1505,6 +1509,7 @@ namespace libtorrent j.error = error_code(errors::file_too_short, libtorrent_category); j.error_file.clear(); j.str = j.error.message(); + j.error_piece = j.storage->last_piece(); ret = -1; break; } diff --git a/src/storage.cpp b/src/storage.cpp index b74daacf2..58281757e 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -1484,6 +1484,7 @@ ret: , m_scratch_buffer(io, 0) , m_scratch_buffer2(io, 0) , m_scratch_piece(-1) + , m_last_piece(-1) , m_storage_constructor(sc) , m_io_thread(io) , m_torrent(torrent) @@ -1745,6 +1746,7 @@ ret: TORRENT_ASSERT(bufs); TORRENT_ASSERT(offset >= 0); TORRENT_ASSERT(num_bufs > 0); + m_last_piece = piece_index; int slot = slot_for(piece_index); return m_storage->readv(bufs, slot, offset, num_bufs); } @@ -1764,6 +1766,7 @@ ret: file::iovec_t* iov = TORRENT_ALLOCA(file::iovec_t, num_bufs); std::copy(bufs, bufs + num_bufs, iov); + m_last_piece = piece_index; int slot = allocate_slot_for_piece(piece_index); int ret = m_storage->writev(bufs, slot, offset, num_bufs); // only save the partial hash if the write succeeds @@ -2336,7 +2339,10 @@ ret: // the slot where this piece belongs is // free. Just move the piece there. + m_last_piece = piece; m_storage->move_slot(m_current_slot, piece); + if (m_storage->error()) return -1; + m_piece_to_slot[piece] = piece; m_slot_to_piece[m_current_slot] = unassigned; m_slot_to_piece[piece] = piece; @@ -2560,6 +2566,7 @@ ret: } bool ret = false; + m_last_piece = piece_index; if (other_piece >= 0) ret |= m_storage->swap_slots(other_slot, m_current_slot); else @@ -2598,6 +2605,7 @@ ret: ret |= m_storage->move_slot(other_slot, m_current_slot); } + m_last_piece = other_piece; if (ret) return skip_file(); TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned @@ -2636,6 +2644,7 @@ ret: TORRENT_ASSERT(piece1 == m_current_slot); TORRENT_ASSERT(piece_index == slot1); + m_last_piece = piece_index; m_storage->swap_slots(m_current_slot, slot1); TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned @@ -2682,6 +2691,7 @@ ret: ret |= m_storage->move_slot(slot2, m_current_slot); } + m_last_piece = piece_index; if (ret) return skip_file(); TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned @@ -2827,6 +2837,7 @@ ret: m_piece_to_slot[piece_index] , m_piece_to_slot[piece_at_our_slot]); + m_last_piece = piece_index; m_storage->move_slot(piece_index, slot_index); TORRENT_ASSERT(m_slot_to_piece[piece_index] == piece_index); @@ -2870,6 +2881,7 @@ ret: int new_free_slot = pos; if (m_piece_to_slot[pos] != has_no_slot) { + m_last_piece = pos; new_free_slot = m_piece_to_slot[pos]; m_storage->move_slot(new_free_slot, pos); m_slot_to_piece[pos] = pos;