From 0398dfe49855e18769161de50f92fe718c692a10 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Fri, 7 Feb 2014 08:58:52 +0000 Subject: [PATCH] merged storage allocation mode fix from RC_0_16 --- ChangeLog | 1 + examples/client_test.cpp | 5 +++-- src/storage.cpp | 4 +++- test/test_transfer.cpp | 18 ++++++++++++++++-- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b0d460aa..8b30820fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -40,6 +40,7 @@ * fix uTP edge case where udp socket buffer fills up * fix nagle implementation in uTP + * fix crash when using full allocation storage mode * improve error_code and error_category support in python bindings * fix python binding for external_ip_alert diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 48a9baf4f..93e06fe52 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -1272,7 +1272,7 @@ int main(int argc, char* argv[]) #endif " -l sets the listen socket queue size\n" "\n DISK OPTIONS\n" - " -a sets the allocation mode. [sparse|full]\n" + " -a sets the allocation mode. [sparse|allocate]\n" " -R number of blocks per read cache line\n" " -C sets the max cache size. Specified in 16kB blocks\n" " -O Disallow disk job reordering\n" @@ -1398,7 +1398,8 @@ int main(int argc, char* argv[]) case 'S': settings.unchoke_slots_limit = atoi(arg); break; case 'a': if (strcmp(arg, "allocate") == 0) allocation_mode = storage_mode_allocate; - if (strcmp(arg, "sparse") == 0) allocation_mode = storage_mode_sparse; + else if (strcmp(arg, "full") == 0) allocation_mode = storage_mode_allocate; + else if (strcmp(arg, "sparse") == 0) allocation_mode = storage_mode_sparse; break; case 's': save_path = arg; break; case 'U': torrent_upload_limit = atoi(arg) * 1000; break; diff --git a/src/storage.cpp b/src/storage.cpp index 2c651bd1c..186c3c00c 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -1223,7 +1223,7 @@ ret: // if the file has priority 0, don't allocate it if (m_allocate_files && (op.mode & file::rw_mask) != file::read_only - && (m_file_priority.size() < file_index || m_file_priority[file_index] > 0)) + && (m_file_priority.size() <= file_index || m_file_priority[file_index] > 0)) { TORRENT_ASSERT(m_file_created.size() == files().num_files()); if (m_file_created[file_index] == false) @@ -2953,6 +2953,8 @@ ret: int piece_manager::slot_for(int piece) const { if (m_storage_mode != internal_storage_mode_compact_deprecated) return piece; + // this happens in seed mode, where we skip checking fastresume + if (m_piece_to_slot.empty()) return piece; TORRENT_ASSERT(piece < int(m_piece_to_slot.size())); TORRENT_ASSERT(piece >= 0); return m_piece_to_slot[piece]; diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 1d222b923..0a1a88111 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -170,7 +170,9 @@ storage_interface* test_storage_constructor(file_storage const& fs return new test_storage(fs, path, fp); } -void test_transfer(int proxy_type, bool test_disk_full = false, bool test_allowed_fast = false) +void test_transfer(int proxy_type, bool test_disk_full = false + , bool test_allowed_fast = false + , storage_mode_t storage_mode = storage_mode_sparse) { static int listen_port = 0; @@ -269,6 +271,9 @@ void test_transfer(int proxy_type, bool test_disk_full = false, bool test_allowe addp.flags &= ~add_torrent_params::flag_paused; addp.flags &= ~add_torrent_params::flag_auto_managed; + add_torrent_params params; + params.storage_mode = storage_mode; + wait_for_listen(ses1, "ses1"); wait_for_listen(ses2, "ses1"); @@ -276,7 +281,7 @@ void test_transfer(int proxy_type, bool test_disk_full = false, bool test_allowe // test using piece sizes smaller than 16kB boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0 - , true, false, true, "_transfer", 8 * 1024, &t, false, test_disk_full?&addp:0); + , true, false, true, "_transfer", 8 * 1024, &t, false, test_disk_full?&addp:¶ms); int num_pieces = tor2.torrent_file()->num_pieces(); std::vector priorities(num_pieces, 1); @@ -380,6 +385,15 @@ int test_main() // test allowed fast test_transfer(0, false, true); + + // test storage_mode_allocate + fprintf(stderr, "full allocation mode\n"); + test_transfer(0, false, false, storage_mode_allocate); + +#ifndef TORRENT_NO_DEPRECATE + fprintf(stderr, "compact mode\n"); + test_transfer(0, false, false, storage_mode_compact); +#endif error_code ec; remove_all("tmp1_transfer", ec);