merge storage fix from RC_0_16

This commit is contained in:
Arvid Norberg 2013-03-03 04:47:19 +00:00
parent b07e7d8fe9
commit 431efc6157
5 changed files with 31 additions and 28 deletions

View File

@ -15,6 +15,7 @@
* fix uTP edge case where udp socket buffer fills up * fix uTP edge case where udp socket buffer fills up
* fix nagle implementation in uTP * 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 file_storage::map_file when dealing with invalid input
* improve handling of invalid utf-8 sequences in strings in torrent files * improve handling of invalid utf-8 sequences in strings in torrent files
* handle more cases of broken .torrent files * handle more cases of broken .torrent files

View File

@ -111,8 +111,8 @@ namespace libtorrent
virtual bool has_any_file() = 0; virtual bool has_any_file() = 0;
virtual int readv(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); 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) {} virtual void hint_read(int, int, int) {}
// negative return value indicates an error // negative return value indicates an error
@ -202,8 +202,8 @@ namespace libtorrent
int write(char const* buf, int slot, int offset, int size); int write(char const* buf, int slot, int offset, int size);
int sparse_end(int start) const; int sparse_end(int start) const;
void hint_read(int slot, int offset, int len); void hint_read(int slot, int offset, int len);
int readv(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* buf, int slot, int offset, int num_bufs); 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); size_type physical_offset(int slot, int offset);
bool move_slot(int src_slot, int dst_slot); bool move_slot(int src_slot, int dst_slot);
bool swap_slots(int slot1, int slot2); bool swap_slots(int slot1, int slot2);
@ -275,8 +275,8 @@ namespace libtorrent
int read(char*, int, int, int size) { return size; } int read(char*, int, int, int size) { return size; }
int write(char const*, int, int, int size) { return size; } int write(char const*, int, int, int size) { return size; }
size_type physical_offset(int, int) { return 0; } size_type physical_offset(int, int) { return 0; }
int readv(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 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 move_slot(int, int) { return false; }
bool swap_slots(int, int) { return false; } bool swap_slots(int, int) { return false; }
bool swap_slots3(int, int, int) { return false; } bool swap_slots3(int, int, int) { return false; }

View File

@ -1411,7 +1411,7 @@ namespace libtorrent
, 0 // release_files , 0 // release_files
, 0 // delete_files , 0 // delete_files
, 0 // check_fastresume , 0 // check_fastresume
, read_operation + cancel_on_abort // check_files , cancel_on_abort // check_files
, 0 // save_resume_data , 0 // save_resume_data
, 0 // rename_file , 0 // rename_file
, 0 // abort_thread , 0 // abort_thread

View File

@ -203,7 +203,7 @@ namespace libtorrent
// writev implementations be implemented in terms of the // writev implementations be implemented in terms of the
// old read and write // old read and write
int storage_interface::readv(file::iovec_t const* bufs 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; int ret = 0;
for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) 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 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; int ret = 0;
for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i) 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); bufs[i].iov_len = (std::min)(block_size, size);
size -= bufs[i].iov_len; 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 // TODO: if the read fails, set error and exit immediately
for (int i = 0; i < num_blocks; ++i) for (int i = 0; i < num_blocks; ++i)
@ -353,7 +354,8 @@ namespace libtorrent
for (int i = 0; i < num_blocks; ++i) for (int i = 0; i < num_blocks; ++i)
{ {
buf.iov_len = (std::min)(block_size, size); 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; if (ret > 0) num_read += ret;
// TODO: if the read fails, set error and exit immediately // TODO: if the read fails, set error and exit immediately
@ -448,7 +450,7 @@ namespace libtorrent
} }
ec.clear(); ec.clear();
boost::intrusive_ptr<file> f = open_file(file_iter, file::read_write, ec); boost::intrusive_ptr<file> f = open_file(file_iter, file::read_write | file::random_access, ec);
if (ec) set_error(file_path, ec); if (ec) set_error(file_path, ec);
else if (f) else if (f)
{ {
@ -920,7 +922,7 @@ ret:
} }
int default_storage::writev(file::iovec_t const* bufs, int slot, int offset 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 #ifdef TORRENT_DISK_STATS
disk_buffer_pool* pool = disk_pool(); disk_buffer_pool* pool = disk_pool();
@ -931,7 +933,7 @@ ret:
} }
#endif #endif
fileop op = { &file::writev, &default_storage::write_unaligned 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 #ifdef TORRENT_DISK_STATS
int ret = readwritev(bufs, slot, offset, num_bufs, op); int ret = readwritev(bufs, slot, offset, num_bufs, op);
if (pool) if (pool)
@ -971,7 +973,7 @@ ret:
// open the file read only to avoid re-opening // open the file read only to avoid re-opening
// it in case it's already opened in read-only mode // it in case it's already opened in read-only mode
error_code ec; error_code ec;
boost::intrusive_ptr<file> f = open_file(file_iter, file::read_only, ec); boost::intrusive_ptr<file> f = open_file(file_iter, file::read_only | file::random_access, ec);
size_type ret = 0; size_type ret = 0;
if (f && !ec) ret = f->phys_offset(file_offset); if (f && !ec) ret = f->phys_offset(file_offset);
@ -1019,7 +1021,7 @@ ret:
if (file_iter->pad_file) continue; if (file_iter->pad_file) continue;
error_code ec; 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 // failing to hint that we want to read is not a big deal
// just swollow the error and keep going // 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 default_storage::readv(file::iovec_t const* bufs, int slot, int offset
, int num_bufs) , int num_bufs, int flags)
{ {
#ifdef TORRENT_DISK_STATS #ifdef TORRENT_DISK_STATS
disk_buffer_pool* pool = disk_pool(); disk_buffer_pool* pool = disk_pool();
@ -1042,7 +1044,7 @@ ret:
} }
#endif #endif
fileop op = { &file::readv, &default_storage::read_unaligned 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 #ifdef TORRENT_SIMULATE_SLOW_READ
boost::thread::sleep(boost::get_system_time() boost::thread::sleep(boost::get_system_time()
+ boost::posix_time::milliseconds(1000)); + boost::posix_time::milliseconds(1000));
@ -1138,7 +1140,7 @@ ret:
if (file_iter->pad_file) 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); 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); TORRENT_ASSERT(count_bufs(tmp_bufs, file_bytes_left) == num_tmp_bufs);
@ -1153,7 +1155,7 @@ ret:
error_code ec; error_code ec;
file_handle = open_file(file_iter, op.mode, 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. // this means the directory the file is in doesn't exist.
// so create it // so create it
@ -1188,7 +1190,7 @@ ret:
{ {
bytes_transferred = (int)(this->*op.unaligned_op)(file_handle, adjusted_offset bytes_transferred = (int)(this->*op.unaligned_op)(file_handle, adjusted_offset
, tmp_bufs, num_tmp_bufs, ec); , 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 && adjusted_offset + bytes_transferred >= file_iter->size
&& (file_handle->pos_alignment() > 0 || file_handle->size_alignment() > 0)) && (file_handle->pos_alignment() > 0 || file_handle->size_alignment() > 0))
{ {
@ -1332,7 +1334,7 @@ ret:
, int size) , int size)
{ {
file::iovec_t b = { (file::iovec_base_t)buf, size_t(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( int default_storage::read(
@ -1368,7 +1370,7 @@ ret:
return new default_storage(fs, mapped, path, fp, file_prio); 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 #ifdef TORRENT_DISK_STATS
disk_buffer_pool* pool = disk_pool(); disk_buffer_pool* pool = disk_pool();
@ -1391,7 +1393,7 @@ ret:
return 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 #ifdef TORRENT_DISK_STATS
disk_buffer_pool* pool = disk_pool(); disk_buffer_pool* pool = disk_pool();

View File

@ -135,12 +135,12 @@ struct test_storage : storage_interface
virtual bool has_any_file() virtual bool has_any_file()
{ return m_lower_layer->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) 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); } { 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 (ret > 0) m_written += ret;
if (m_written > m_limit) if (m_written > m_limit)
{ {