From 1cdfe266307b7790be17322366f39702c830952e Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 17 Mar 2009 09:31:30 +0000 Subject: [PATCH] Fixed bug when moving storage with files renamed to end up outside of the rood directory. Fixes Deluge bug http://dev.deluge-torrent.org/ticket/839 --- ChangeLog | 2 ++ src/storage.cpp | 67 ++++++++++++++++++++++++++----------------- test/test_storage.cpp | 50 ++++++++++++++++++-------------- 3 files changed, 72 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9cc268cea..8cb7ef10f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -43,6 +43,8 @@ release 0.14.3 * fixed a replace_trackers bug * fixed bug where the DHT port mapping would not be removed when changing DHT port + * fixed move_storage bug when files were renamed to be moved out + of the root directory release 0.14.2 diff --git a/src/storage.cpp b/src/storage.cpp index 6002e4218..aa1400fe0 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -931,40 +931,55 @@ namespace libtorrent m_pool.release(this); + bool ret = true; + std::set to_move; + file_storage const& f = files(); + + for (file_storage::iterator i = f.begin() + , end(f.end()); i != end; ++i) + { + to_move.insert(to_move.begin(), *i->path.begin()); + } + + for (std::set::const_iterator i = to_move.begin() + , end(to_move.end()); i != end; ++i) + { + #if TORRENT_USE_WPATH - old_path = convert_to_wstring((m_save_path / files().name()).string()); - new_path = convert_to_wstring((save_path / files().name()).string()); + old_path = convert_to_wstring((m_save_path / *i).string()); + new_path = convert_to_wstring((save_path / *i).string()); #elif TORRENT_USE_LOCALE_FILENAMES - old_path = convert_to_native((m_save_path / files().name()).string()); - new_path = convert_to_native((save_path / files().name().string())); + old_path = convert_to_native((m_save_path / *i).string()); + new_path = convert_to_native((save_path / *i).string()); #else - old_path = m_save_path / files().name(); - new_path = save_path / files().name(); + old_path = m_save_path / *i; + new_path = save_path / *i; #endif #ifndef BOOST_NO_EXCEPTIONS - try - { -#endif - rename(old_path, new_path); - m_save_path = save_path; - return true; -#ifndef BOOST_NO_EXCEPTIONS - } - catch (std::exception& e) - { - error_code ec; - recursive_copy(old_path, new_path, ec); - if (ec) + try { - set_error(m_save_path / files().name(), ec); - return true; - } - m_save_path = save_path; - recursive_remove(old_path); - } #endif - return false; + rename(old_path, new_path); +#ifndef BOOST_NO_EXCEPTIONS + } + catch (std::exception& e) + { + error_code ec; + recursive_copy(old_path, new_path, ec); + if (ec) + { + set_error(m_save_path / files().name(), ec); + ret = false; + } + recursive_remove(old_path); + } +#endif + } + + if (ret) m_save_path = save_path; + + return ret; } #ifdef TORRENT_DEBUG diff --git a/test/test_storage.cpp b/test/test_storage.cpp index 899856662..2c6fa8dd9 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -199,30 +199,11 @@ void run_storage_tests(boost::intrusive_ptr info ios.reset(); ios.poll(ec); - // test move_storage - boost::function none; - TEST_CHECK(exists(test_path / "temp_storage")); - pm->async_move_storage(test_path / "temp_storage2", bind(on_move_storage, _1, _2, (test_path / "temp_storage2").string())); - - test_sleep(2000); - ios.reset(); - ios.poll(ec); - - TEST_CHECK(!exists(test_path / "temp_storage")); - TEST_CHECK(exists(test_path / "temp_storage2/temp_storage")); - pm->async_move_storage(test_path, bind(on_move_storage, _1, _2, test_path.string())); - - test_sleep(1000); - ios.reset(); - ios.poll(ec); - - TEST_CHECK(!exists(test_path / "temp_storage2/temp_storage")); - remove_all(test_path / "temp_storage2"); - // test rename_file remove(test_path / "part0"); TEST_CHECK(exists(test_path / "temp_storage/test1.tmp")); TEST_CHECK(!exists(test_path / "part0")); + boost::function none; pm->async_rename_file(0, "part0", none); test_sleep(1000); @@ -232,6 +213,31 @@ void run_storage_tests(boost::intrusive_ptr info TEST_CHECK(!exists(test_path / "temp_storage/test1.tmp")); TEST_CHECK(exists(test_path / "part0")); + // test move_storage with two files in the root directory + TEST_CHECK(exists(test_path / "temp_storage")); + pm->async_move_storage(test_path / "temp_storage2", bind(on_move_storage, _1, _2, (test_path / "temp_storage2").string())); + + test_sleep(2000); + ios.reset(); + ios.poll(ec); + + if (fs.num_files() > 1) + { + TEST_CHECK(!exists(test_path / "temp_storage")); + TEST_CHECK(exists(test_path / "temp_storage2/temp_storage")); + } + TEST_CHECK(exists(test_path / "temp_storage2/part0")); + + pm->async_move_storage(test_path, bind(on_move_storage, _1, _2, test_path.string())); + + test_sleep(2000); + ios.reset(); + ios.poll(ec); + + TEST_CHECK(exists(test_path / "part0")); + TEST_CHECK(!exists(test_path / "temp_storage2/temp_storage")); + TEST_CHECK(!exists(test_path / "temp_storage2/part0")); + peer_request r; r.piece = 0; r.start = 0; @@ -244,7 +250,7 @@ void run_storage_tests(boost::intrusive_ptr info pm->async_release_files(none); pm->async_rename_file(0, "temp_storage/test1.tmp", none); - test_sleep(1000); + test_sleep(2000); ios.reset(); ios.poll(ec); @@ -254,6 +260,8 @@ void run_storage_tests(boost::intrusive_ptr info ios.run(ec); io.join(); + remove_all(test_path / "temp_storage2"); + remove_all(test_path / "part0"); } page_aligned_allocator::free(piece); }