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

This commit is contained in:
Arvid Norberg 2009-03-17 09:31:30 +00:00
parent 4ae27edb89
commit 1cdfe26630
3 changed files with 72 additions and 47 deletions

View File

@ -43,6 +43,8 @@ release 0.14.3
* fixed a replace_trackers bug * fixed a replace_trackers bug
* fixed bug where the DHT port mapping would not be removed when * fixed bug where the DHT port mapping would not be removed when
changing DHT port changing DHT port
* fixed move_storage bug when files were renamed to be moved out
of the root directory
release 0.14.2 release 0.14.2

View File

@ -931,40 +931,55 @@ namespace libtorrent
m_pool.release(this); m_pool.release(this);
bool ret = true;
std::set<std::string> 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<std::string>::const_iterator i = to_move.begin()
, end(to_move.end()); i != end; ++i)
{
#if TORRENT_USE_WPATH #if TORRENT_USE_WPATH
old_path = convert_to_wstring((m_save_path / files().name()).string()); old_path = convert_to_wstring((m_save_path / *i).string());
new_path = convert_to_wstring((save_path / files().name()).string()); new_path = convert_to_wstring((save_path / *i).string());
#elif TORRENT_USE_LOCALE_FILENAMES #elif TORRENT_USE_LOCALE_FILENAMES
old_path = convert_to_native((m_save_path / files().name()).string()); old_path = convert_to_native((m_save_path / *i).string());
new_path = convert_to_native((save_path / files().name().string())); new_path = convert_to_native((save_path / *i).string());
#else #else
old_path = m_save_path / files().name(); old_path = m_save_path / *i;
new_path = save_path / files().name(); new_path = save_path / *i;
#endif #endif
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
try 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)
{ {
set_error(m_save_path / files().name(), ec);
return true;
}
m_save_path = save_path;
recursive_remove(old_path);
}
#endif #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 #ifdef TORRENT_DEBUG

View File

@ -199,30 +199,11 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
ios.reset(); ios.reset();
ios.poll(ec); ios.poll(ec);
// test move_storage
boost::function<void(int, disk_io_job const&)> 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 // test rename_file
remove(test_path / "part0"); remove(test_path / "part0");
TEST_CHECK(exists(test_path / "temp_storage/test1.tmp")); TEST_CHECK(exists(test_path / "temp_storage/test1.tmp"));
TEST_CHECK(!exists(test_path / "part0")); TEST_CHECK(!exists(test_path / "part0"));
boost::function<void(int, disk_io_job const&)> none;
pm->async_rename_file(0, "part0", none); pm->async_rename_file(0, "part0", none);
test_sleep(1000); test_sleep(1000);
@ -232,6 +213,31 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
TEST_CHECK(!exists(test_path / "temp_storage/test1.tmp")); TEST_CHECK(!exists(test_path / "temp_storage/test1.tmp"));
TEST_CHECK(exists(test_path / "part0")); 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; peer_request r;
r.piece = 0; r.piece = 0;
r.start = 0; r.start = 0;
@ -244,7 +250,7 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
pm->async_release_files(none); pm->async_release_files(none);
pm->async_rename_file(0, "temp_storage/test1.tmp", none); pm->async_rename_file(0, "temp_storage/test1.tmp", none);
test_sleep(1000); test_sleep(2000);
ios.reset(); ios.reset();
ios.poll(ec); ios.poll(ec);
@ -254,6 +260,8 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
ios.run(ec); ios.run(ec);
io.join(); io.join();
remove_all(test_path / "temp_storage2");
remove_all(test_path / "part0");
} }
page_aligned_allocator::free(piece); page_aligned_allocator::free(piece);
} }