factor creating of directories into default_storage::open_file to make that functionality more robust and fix a bug where moving files out of the part-file would fail because the directories hadn't been created yet

This commit is contained in:
Arvid Norberg 2015-01-03 16:57:21 +00:00
parent b897a6ce29
commit f839b8c9b4
2 changed files with 51 additions and 57 deletions

View File

@ -468,8 +468,8 @@ namespace libtorrent
mutable stat_cache m_stat_cache; mutable stat_cache m_stat_cache;
// helper function to open a file in the file pool with the right mode // helper function to open a file in the file pool with the right mode
file_handle open_file(int file, int mode file_handle open_file(int file, int mode, storage_error& ec) const;
, error_code& ec) const; file_handle open_file_impl(int file, int mode, error_code& ec) const;
std::vector<boost::uint8_t> m_file_priority; std::vector<boost::uint8_t> m_file_priority;
std::string m_save_path; std::string m_save_path;

View File

@ -256,13 +256,8 @@ namespace libtorrent
if (old_prio == 0 && new_prio != 0) if (old_prio == 0 && new_prio != 0)
{ {
// move stuff out of the part file // move stuff out of the part file
file_handle f = open_file(i, file::read_write | file::random_access, ec.ec); file_handle f = open_file(i, file::read_write, ec);
if (ec || !f) if (ec) return;
{
ec.file = i;
ec.operation = storage_error::open;
return;
}
need_partfile(); need_partfile();
@ -284,15 +279,11 @@ namespace libtorrent
if (exists(fp)) if (exists(fp))
new_prio = 1; new_prio = 1;
/* /*
file_handle f = open_file(i, file::read_only | file::random_access, ec.ec); file_handle f = open_file(i, file::read_only, ec);
if (ec.ec != boost::system::errc::no_such_file_or_directory) if (ec.ec != boost::system::errc::no_such_file_or_directory)
{ {
if (ec || !f) if (ec) return;
{
ec.file = i;
ec.operation = storage_error::open;
return;
}
need_partfile(); need_partfile();
m_part_file->import_file(*f, fs.file_offset(i), fs.file_size(i), ec.ec); m_part_file->import_file(*f, fs.file_offset(i), fs.file_size(i), ec.ec);
@ -394,13 +385,10 @@ namespace libtorrent
} }
} }
ec.ec.clear(); ec.ec.clear();
file_handle f = open_file(file_index, file::read_write | file::random_access, ec.ec); file_handle f = open_file(file_index, file::read_write
if (ec || !f) | file::random_access, ec);
{ if (ec) return;
ec.file = file_index;
ec.operation = storage_error::open;
return;
}
f->set_size(files().file_size(file_index), ec.ec); f->set_size(files().file_size(file_index), ec.ec);
if (ec) if (ec)
{ {
@ -719,8 +707,8 @@ namespace libtorrent
} }
error_code ec; error_code ec;
file_handle handle = open_file(file_index, file::read_only, ec); file_handle handle = open_file_impl(file_index, file::read_only, ec);
if (!handle || ec) return slot; if (ec) return slot;
boost::int64_t data_start = handle->sparse_end(file_offset); boost::int64_t data_start = handle->sparse_end(file_offset);
return int((data_start + files().piece_length() - 1) / files().piece_length()); return int((data_start + files().piece_length() - 1) / files().piece_length());
@ -1183,36 +1171,8 @@ namespace libtorrent
} }
else else
{ {
handle = open_file(file_index, op.mode, e); handle = open_file(file_index, op.mode, ec);
if (((op.mode & file::rw_mask) != file::read_only) if (ec) return -1;
&& e == boost::system::errc::no_such_file_or_directory)
{
// this means the directory the file is in doesn't exist.
// so create it
e.clear();
std::string path = files().file_path(file_index, m_save_path);
create_directories(parent_path(path), e);
if (e)
{
ec.ec = e;
ec.file = file_index;
ec.operation = storage_error::mkdir;
return -1;
}
// if the directory creation failed, don't try to open the file again
// but actually just fail
handle = open_file(file_index, op.mode, e);
}
if (!handle || e)
{
ec.ec = e;
ec.file = file_index;
ec.operation = storage_error::open;
return -1;
}
if (m_allocate_files && (op.mode & file::rw_mask) != file::read_only) if (m_allocate_files && (op.mode & file::rw_mask) != file::read_only)
{ {
@ -1280,8 +1240,41 @@ namespace libtorrent
return size; return size;
} }
file_handle default_storage::open_file(int file, int mode file_handle default_storage::open_file(int file, int mode
, storage_error& ec) const
{
file_handle h = open_file_impl(file, mode, ec.ec);
if (((mode & file::rw_mask) != file::read_only)
&& ec.ec == boost::system::errc::no_such_file_or_directory)
{
// this means the directory the file is in doesn't exist.
// so create it
ec.ec.clear();
std::string path = files().file_path(file, m_save_path);
create_directories(parent_path(path), ec.ec);
if (ec.ec)
{
ec.file = file;
ec.operation = storage_error::mkdir;
return file_handle();
}
// if the directory creation failed, don't try to open the file again
// but actually just fail
h = open_file_impl(file, mode, ec.ec);
}
if (ec.ec)
{
ec.file = file;
ec.operation = storage_error::open;
return file_handle();
}
TORRENT_ASSERT(h);
return h;
}
file_handle default_storage::open_file_impl(int file, int mode
, error_code& ec) const , error_code& ec) const
{ {
bool lock_files = m_settings ? settings().get_bool(settings_pack::lock_files) : false; bool lock_files = m_settings ? settings().get_bool(settings_pack::lock_files) : false;
@ -1302,7 +1295,8 @@ namespace libtorrent
mode |= file::no_cache; mode |= file::no_cache;
} }
return m_pool.open_file(const_cast<default_storage*>(this), m_save_path, file, files(), mode, ec); return m_pool.open_file(const_cast<default_storage*>(this), m_save_path
, file, files(), mode, ec);
} }
bool default_storage::tick() bool default_storage::tick()