include the piece index that failed in disk errors

This commit is contained in:
Arvid Norberg 2009-05-31 19:44:56 +00:00
parent 75d06a7a64
commit b2c5d8a563
4 changed files with 26 additions and 2 deletions

View File

@ -120,6 +120,9 @@ namespace libtorrent
// the error code from the file operation // the error code from the file operation
error_code error; error_code error;
// the piece the error occurred on
int error_piece;
// this is called when operation completes // this is called when operation completes
boost::function<void(int, disk_io_job const&)> callback; boost::function<void(int, disk_io_job const&)> callback;
}; };

View File

@ -289,6 +289,7 @@ namespace libtorrent
error_code const& error() const { return m_storage->error(); } error_code const& error() const { return m_storage->error(); }
std::string const& error_file() const { return m_storage->error_file(); } 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(); } void clear_error() { m_storage->clear_error(); }
int slot_for(int piece) const; int slot_for(int piece) const;
@ -418,14 +419,17 @@ namespace libtorrent
disk_buffer_holder m_scratch_buffer2; disk_buffer_holder m_scratch_buffer2;
// the piece that is in the scratch buffer // the piece that is in the scratch buffer
int m_scratch_piece; 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 // this is saved in case we need to instantiate a new
// storage (osed when remapping files) // storage (osed when remapping files)
storage_constructor_type m_storage_constructor; storage_constructor_type m_storage_constructor;
// this maps a piece hash to piece index. It will be // this maps a piece hash to piece index. It will be
// build the first time it is used (to save time if it // build the first time it is used (to save time if it
// isn't needed) // isn't needed)
std::multimap<sha1_hash, int> m_hash_to_piece; std::multimap<sha1_hash, int> m_hash_to_piece;
// this map contains partial hashes for downloading // this map contains partial hashes for downloading

View File

@ -1248,6 +1248,7 @@ namespace libtorrent
j.str = ec.message(); j.str = ec.message();
j.error = ec; j.error = ec;
j.error_file = j.storage->error_file(); j.error_file = j.storage->error_file();
j.error_piece = j.storage->last_piece();
j.storage->clear_error(); j.storage->clear_error();
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
std::cout << "ERROR: '" << j.str << "' " << j.error_file << std::endl; std::cout << "ERROR: '" << j.str << "' " << j.error_file << std::endl;
@ -1421,6 +1422,7 @@ namespace libtorrent
{ {
ret = -1; ret = -1;
j.error = error_code(ENOMEM, get_posix_category()); j.error = error_code(ENOMEM, get_posix_category());
j.error_piece = -1;
j.str = j.error.message(); j.str = j.error.message();
break; break;
} }
@ -1447,6 +1449,7 @@ namespace libtorrent
j.storage->mark_failed(j.piece); j.storage->mark_failed(j.piece);
j.error = error_code(errors::failed_hash_check, libtorrent_category); j.error = error_code(errors::failed_hash_check, libtorrent_category);
j.str = j.error.message(); j.str = j.error.message();
j.error_piece = j.storage->last_piece();
j.buffer = 0; j.buffer = 0;
break; break;
} }
@ -1473,6 +1476,7 @@ namespace libtorrent
{ {
ret = -1; ret = -1;
j.error = error_code(ENOMEM, get_posix_category()); j.error = error_code(ENOMEM, get_posix_category());
j.error_piece = -1;
j.str = j.error.message(); j.str = j.error.message();
break; break;
} }
@ -1505,6 +1509,7 @@ namespace libtorrent
j.error = error_code(errors::file_too_short, libtorrent_category); j.error = error_code(errors::file_too_short, libtorrent_category);
j.error_file.clear(); j.error_file.clear();
j.str = j.error.message(); j.str = j.error.message();
j.error_piece = j.storage->last_piece();
ret = -1; ret = -1;
break; break;
} }

View File

@ -1484,6 +1484,7 @@ ret:
, m_scratch_buffer(io, 0) , m_scratch_buffer(io, 0)
, m_scratch_buffer2(io, 0) , m_scratch_buffer2(io, 0)
, m_scratch_piece(-1) , m_scratch_piece(-1)
, m_last_piece(-1)
, m_storage_constructor(sc) , m_storage_constructor(sc)
, m_io_thread(io) , m_io_thread(io)
, m_torrent(torrent) , m_torrent(torrent)
@ -1745,6 +1746,7 @@ ret:
TORRENT_ASSERT(bufs); TORRENT_ASSERT(bufs);
TORRENT_ASSERT(offset >= 0); TORRENT_ASSERT(offset >= 0);
TORRENT_ASSERT(num_bufs > 0); TORRENT_ASSERT(num_bufs > 0);
m_last_piece = piece_index;
int slot = slot_for(piece_index); int slot = slot_for(piece_index);
return m_storage->readv(bufs, slot, offset, num_bufs); 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); file::iovec_t* iov = TORRENT_ALLOCA(file::iovec_t, num_bufs);
std::copy(bufs, bufs + num_bufs, iov); std::copy(bufs, bufs + num_bufs, iov);
m_last_piece = piece_index;
int slot = allocate_slot_for_piece(piece_index); int slot = allocate_slot_for_piece(piece_index);
int ret = m_storage->writev(bufs, slot, offset, num_bufs); int ret = m_storage->writev(bufs, slot, offset, num_bufs);
// only save the partial hash if the write succeeds // only save the partial hash if the write succeeds
@ -2336,7 +2339,10 @@ ret:
// the slot where this piece belongs is // the slot where this piece belongs is
// free. Just move the piece there. // free. Just move the piece there.
m_last_piece = piece;
m_storage->move_slot(m_current_slot, piece); m_storage->move_slot(m_current_slot, piece);
if (m_storage->error()) return -1;
m_piece_to_slot[piece] = piece; m_piece_to_slot[piece] = piece;
m_slot_to_piece[m_current_slot] = unassigned; m_slot_to_piece[m_current_slot] = unassigned;
m_slot_to_piece[piece] = piece; m_slot_to_piece[piece] = piece;
@ -2560,6 +2566,7 @@ ret:
} }
bool ret = false; bool ret = false;
m_last_piece = piece_index;
if (other_piece >= 0) if (other_piece >= 0)
ret |= m_storage->swap_slots(other_slot, m_current_slot); ret |= m_storage->swap_slots(other_slot, m_current_slot);
else else
@ -2598,6 +2605,7 @@ ret:
ret |= m_storage->move_slot(other_slot, m_current_slot); ret |= m_storage->move_slot(other_slot, m_current_slot);
} }
m_last_piece = other_piece;
if (ret) return skip_file(); if (ret) return skip_file();
TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned
@ -2636,6 +2644,7 @@ ret:
TORRENT_ASSERT(piece1 == m_current_slot); TORRENT_ASSERT(piece1 == m_current_slot);
TORRENT_ASSERT(piece_index == slot1); TORRENT_ASSERT(piece_index == slot1);
m_last_piece = piece_index;
m_storage->swap_slots(m_current_slot, slot1); m_storage->swap_slots(m_current_slot, slot1);
TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned
@ -2682,6 +2691,7 @@ ret:
ret |= m_storage->move_slot(slot2, m_current_slot); ret |= m_storage->move_slot(slot2, m_current_slot);
} }
m_last_piece = piece_index;
if (ret) return skip_file(); if (ret) return skip_file();
TORRENT_ASSERT(m_slot_to_piece[m_current_slot] == unassigned 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_index]
, m_piece_to_slot[piece_at_our_slot]); , m_piece_to_slot[piece_at_our_slot]);
m_last_piece = piece_index;
m_storage->move_slot(piece_index, slot_index); m_storage->move_slot(piece_index, slot_index);
TORRENT_ASSERT(m_slot_to_piece[piece_index] == piece_index); TORRENT_ASSERT(m_slot_to_piece[piece_index] == piece_index);
@ -2870,6 +2881,7 @@ ret:
int new_free_slot = pos; int new_free_slot = pos;
if (m_piece_to_slot[pos] != has_no_slot) if (m_piece_to_slot[pos] != has_no_slot)
{ {
m_last_piece = pos;
new_free_slot = m_piece_to_slot[pos]; new_free_slot = m_piece_to_slot[pos];
m_storage->move_slot(new_free_slot, pos); m_storage->move_slot(new_free_slot, pos);
m_slot_to_piece[pos] = pos; m_slot_to_piece[pos] = pos;