fix issue of force-recheck or seeding from read-only media, torrents with empty files in them. Previously libtorrent would create empty files up-front unconditionally, now they won't be created if they already exist

This commit is contained in:
arvidn 2017-08-08 14:25:21 +02:00 committed by Arvid Norberg
parent 2b98951ace
commit 378a0e974b
5 changed files with 26 additions and 10 deletions

View File

@ -1,3 +1,4 @@
* don't attempt to create empty files on startup, if they already exist
* fix force-recheck issue (new files would not be picked up)
* fix inconsistency in file_priorities and override_resume_data behavior

View File

@ -543,7 +543,8 @@ namespace libtorrent
// ignore pad files
if (files().pad_file_at(file_index)) continue;
if (m_stat_cache.get_filesize(file_index) == stat_cache::not_in_cache)
boost::int64_t cached_size = m_stat_cache.get_filesize(file_index);
if (cached_size == stat_cache::not_in_cache)
{
file_status s;
std::string file_path = files().file_path(file_index, m_save_path);
@ -551,6 +552,7 @@ namespace libtorrent
if (!ec)
{
m_stat_cache.set_cache(file_index, s.file_size, s.mtime);
cached_size = s.file_size;
}
else if (ec.ec != boost::system::errc::no_such_file_or_directory)
{
@ -559,13 +561,17 @@ namespace libtorrent
ec.operation = storage_error::stat;
break;
}
else
{
cached_size = stat_cache::no_exist;
}
}
// if the file already exists, but is larger than what
// it's supposed to be, truncate it
// if the file is empty, just create it either way.
if ((!ec && m_stat_cache.get_filesize(file_index) > files().file_size(file_index))
|| files().file_size(file_index) == 0)
// if the file is empty and doesn't already exist, create it
if ((!ec && cached_size > files().file_size(file_index))
|| (files().file_size(file_index) == 0 && cached_size == stat_cache::no_exist))
{
std::string file_path = files().file_path(file_index, m_save_path);
std::string dir = parent_path(file_path);

View File

@ -595,7 +595,8 @@ boost::shared_ptr<T> clone_ptr(boost::shared_ptr<T> const& ptr)
unsigned char random_byte()
{ return std::rand() & 0xff; }
void create_random_files(std::string const& path, const int file_sizes[], int num_files)
void create_random_files(std::string const& path, const int file_sizes[], int num_files
, file_storage* fs)
{
error_code ec;
char* random_data = (char*)malloc(300000);
@ -613,6 +614,7 @@ void create_random_files(std::string const& path, const int file_sizes[], int nu
full_path = combine_path(full_path, filename);
int to_write = file_sizes[i];
if (fs) fs->add_file(full_path, to_write);
file f(full_path, file::write_only, ec);
if (ec) fprintf(stderr, "failed to create file \"%s\": (%d) %s\n"
, full_path.c_str(), ec.value(), ec.message().c_str());

View File

@ -41,6 +41,7 @@ namespace libtorrent
{
class alert;
struct add_torrent_params;
class file_storage;
}
EXPORT int print_failures();
@ -83,7 +84,8 @@ EXPORT void wait_for_listen(libtorrent::session& ses, char const* name);
EXPORT void wait_for_downloading(libtorrent::session& ses, char const* name);
EXPORT void test_sleep(int millisec);
EXPORT void create_random_files(std::string const& path, const int file_sizes[], int num_files);
EXPORT void create_random_files(std::string const& path, const int file_sizes[]
, int num_files, libtorrent::file_storage* fs = NULL);
EXPORT boost::shared_ptr<libtorrent::torrent_info> create_torrent(std::ostream* file = 0
, char const* name = "temporary", int piece_size = 16 * 1024, int num_pieces = 13

View File

@ -41,7 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/torrent_status.hpp"
static const int file_sizes[] =
{ 5, 16 - 5, 16000, 17, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
{ 0, 5, 16 - 5, 16000, 17, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
,1,1,1,1,1,1,13,65000,34,75,2,30,400,500,23000,900,43000,400,4300,6, 4};
const int num_files = sizeof(file_sizes)/sizeof(file_sizes[0]);
@ -83,9 +83,8 @@ void test_checking(int flags = read_only_files)
std::srand(10);
int piece_size = 0x4000;
create_random_files("test_torrent_dir", file_sizes, num_files);
create_random_files("test_torrent_dir", file_sizes, num_files, &fs);
add_files(fs, "test_torrent_dir");
lt::create_torrent t(fs, piece_size, 0x4000
, lt::create_torrent::optimize_alignment);
@ -130,7 +129,7 @@ void test_checking(int flags = read_only_files)
// increase the size of some files. When they're read only that forces
// the checker to open them in write-mode to truncate them
static const int file_sizes2[] =
{ 5, 16 - 5, 16001, 30, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
{ 0, 5, 16 - 5, 16001, 30, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
,1,1,1,1,1,1,13,65000,34,75,2,30,400,500,23000,900,43000,400,4300,6, 4};
create_random_files("test_torrent_dir", file_sizes2, num_files);
}
@ -160,6 +159,9 @@ void test_checking(int flags = read_only_files)
if (flags & force_recheck)
{
remove_all("test_torrent_dir_tmp", ec);
if (ec) fprintf(stdout, "ERROR: removing \"test_torrent_dir_tmp\": (%d) %s\n"
, ec.value(), ec.message().c_str());
rename("test_torrent_dir", "test_torrent_dir_tmp", ec);
if (ec) fprintf(stdout, "ERROR: renaming dir \"test_torrent_dir\": (%d) %s\n"
, ec.value(), ec.message().c_str());
@ -196,6 +198,9 @@ void test_checking(int flags = read_only_files)
// now, move back the files and force-recheck. make sure we pick up the
// files this time
remove_all("test_torrent_dir", ec);
if (ec) fprintf(stdout, "ERROR: removing \"test_torrent_dir\": (%d) %s\n"
, ec.value(), ec.message().c_str());
rename("test_torrent_dir_tmp", "test_torrent_dir", ec);
if (ec) fprintf(stdout, "ERROR: renaming dir \"test_torrent_dir_tmp\": (%d) %s\n"
, ec.value(), ec.message().c_str());