--- a/src/command_download.cc 2017-04-30 21:40:38.853044300 +0100 +++ a/src/command_download.cc 2017-04-30 22:48:43.094251399 +0100 @@ -64,6 +64,7 @@ #include "core/download_store.h" #include "core/manager.h" #include "rpc/parse.h" +#include "rpc/parse_commands.h" #include "globals.h" #include "control.h" @@ -571,6 +572,13 @@ d_list_remove(core::Download* download, return torrent::Object(); } +torrent::Object +apply_d_update_priorities(core::Download* download) { + int fallocate = rpc::call_command_value("system.file.allocate") ? torrent::Download::open_enable_fallocate : 0; + + download->update_priorities(fallocate); +} + #define CMD2_ON_INFO(func) std::bind(&torrent::DownloadInfo::func, std::bind(&core::Download::info, std::placeholders::_1)) #define CMD2_ON_DATA(func) std::bind(&torrent::download_data::func, std::bind(&core::Download::data, std::placeholders::_1)) #define CMD2_ON_DL(func) std::bind(&torrent::Download::func, std::bind(&core::Download::download, std::placeholders::_1)) @@ -687,7 +695,7 @@ initialize_command_download() { CMD2_DL ("d.save_resume", std::bind(&core::DownloadStore::save_resume, control->core()->download_store(), std::placeholders::_1)); CMD2_DL ("d.save_full_session", std::bind(&core::DownloadStore::save_full, control->core()->download_store(), std::placeholders::_1)); - CMD2_DL_V ("d.update_priorities", CMD2_ON_DL(update_priorities)); + CMD2_DL_V ("d.update_priorities", std::bind(&apply_d_update_priorities, std::placeholders::_1)); CMD2_DL_STRING_V("add_peer", std::bind(&apply_d_add_peer, std::placeholders::_1, std::placeholders::_2)); @@ -792,14 +799,16 @@ initialize_command_download() { CMD2_DL ("d.throttle_name", std::bind(&download_get_variable, std::placeholders::_1, "rtorrent", "throttle_name")); CMD2_DL_STRING_V("d.throttle_name.set", std::bind(&core::Download::set_throttle_name, std::placeholders::_1, std::placeholders::_2)); - CMD2_DL ("d.bytes_done", CMD2_ON_DL(bytes_done)); - CMD2_DL ("d.ratio", std::bind(&retrieve_d_ratio, std::placeholders::_1)); - CMD2_DL ("d.chunks_hashed", CMD2_ON_DL(chunks_hashed)); - CMD2_DL ("d.free_diskspace", CMD2_ON_FL(free_diskspace)); + CMD2_DL ("d.bytes_done", CMD2_ON_DL(bytes_done)); + CMD2_DL ("d.ratio", std::bind(&retrieve_d_ratio, std::placeholders::_1)); + CMD2_DL ("d.chunks_hashed", CMD2_ON_DL(chunks_hashed)); + CMD2_DL ("d.free_diskspace", CMD2_ON_FL(free_diskspace)); + CMD2_DL ("d.is_enough_diskspace", CMD2_ON_FL(is_enough_diskspace)); CMD2_DL ("d.size_files", CMD2_ON_FL(size_files)); CMD2_DL ("d.selected_size_bytes", CMD2_ON_FL(selected_size_bytes)); CMD2_DL ("d.size_bytes", CMD2_ON_FL(size_bytes)); + CMD2_DL ("d.allocatable_size_bytes", CMD2_ON_FL(allocatable_size_bytes)); CMD2_DL ("d.size_chunks", CMD2_ON_FL(size_chunks)); CMD2_DL ("d.chunk_size", CMD2_ON_FL(chunk_size)); CMD2_DL ("d.size_pex", CMD2_ON_DL(size_pex)); --- a/src/command_file.cc 2016-10-23 05:33:00.000000000 +0100 +++ a/src/command_file.cc 2017-04-30 22:42:23.000000000 +0100 @@ -105,11 +105,15 @@ initialize_command_file() { CMD2_FILE("f.is_create_queued", std::bind(&torrent::File::is_create_queued, std::placeholders::_1)); CMD2_FILE("f.is_resize_queued", std::bind(&torrent::File::is_resize_queued, std::placeholders::_1)); + CMD2_FILE("f.is_fallocatable", std::bind(&torrent::File::is_fallocatable, std::placeholders::_1)); + CMD2_FILE("f.is_fallocatable_file", std::bind(&torrent::File::is_fallocatable_file, std::placeholders::_1)); CMD2_FILE_VALUE_V("f.set_create_queued", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_create_queued)); CMD2_FILE_VALUE_V("f.set_resize_queued", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_resize_queued)); + CMD2_FILE_VALUE_V("f.set_fallocate", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_fallocate)); CMD2_FILE_VALUE_V("f.unset_create_queued", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_create_queued)); CMD2_FILE_VALUE_V("f.unset_resize_queued", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_resize_queued)); + CMD2_FILE_VALUE_V("f.unset_fallocate", std::bind(&torrent::File::unset_flags, std::placeholders::_1, torrent::File::flag_fallocate)); CMD2_FILE ("f.prioritize_first", std::bind(&torrent::File::has_flags, std::placeholders::_1, torrent::File::flag_prioritize_first)); CMD2_FILE_V("f.prioritize_first.enable", std::bind(&torrent::File::set_flags, std::placeholders::_1, torrent::File::flag_prioritize_first)); --- a/src/core/download.h 2017-04-30 21:35:27.000000000 +0100 +++ a/src/core/download.h 2017-04-30 22:42:23.000000000 +0100 @@ -119,6 +119,8 @@ public: uint32_t priority(); void set_priority(uint32_t p); + void update_priorities(int flags = 0) { m_download.update_priorities(flags); }; + uint32_t resume_flags() { return m_resumeFlags; } void set_resume_flags(uint32_t flags) { m_resumeFlags = flags; } --- a/src/core/download_list.cc 2017-04-30 21:35:27.000000000 +0100 +++ a/src/core/download_list.cc 2017-05-14 21:24:57.199934736 +0100 @@ -120,9 +120,10 @@ DownloadList::find_hex_ptr(const char* h Download* DownloadList::create(torrent::Object* obj, bool printLog) { torrent::Download download; + int fallocate = rpc::call_command_value("system.file.allocate") ? torrent::Download::open_enable_fallocate : 0; try { - download = torrent::download_add(obj); + download = torrent::download_add(obj, fallocate); } catch (torrent::local_error& e) { delete obj; @@ -157,7 +158,9 @@ DownloadList::create(std::istream* str, return NULL; } - download = torrent::download_add(object); + int fallocate = rpc::call_command_value("system.file.allocate") ? torrent::Download::open_enable_fallocate : 0; + + download = torrent::download_add(object, fallocate); } catch (torrent::local_error& e) { delete object; @@ -341,8 +344,6 @@ DownloadList::resume(Download* download, if (download->download()->info()->is_active()) return; - rpc::parse_command_single(rpc::make_target(download), "view.set_visible=active"); - // We need to make sure the flags aren't reset if someone decideds // to call resume() while it is hashing, etc. if (download->resume_flags() == ~uint32_t()) @@ -369,9 +370,6 @@ DownloadList::resume(Download* download, // This will never actually do anything due to the above hash check. // open_throw(download); - rpc::call_command("d.state_changed.set", cachedTime.seconds(), rpc::make_target(download)); - rpc::call_command("d.state_counter.set", rpc::call_command_value("d.state_counter", rpc::make_target(download)) + 1, rpc::make_target(download)); - if (download->is_partially_done()) { rpc::call_command("d.group.set", "default_seed", rpc::make_target(download)); @@ -401,12 +399,32 @@ DownloadList::resume(Download* download, // Update the priority to ensure it has the correct // seeding/unfinished modifiers. download->set_priority(download->priority()); - download->download()->start(download->resume_flags()); - download->set_resume_flags(~uint32_t()); + int openFlags = download->resume_flags(); - DL_TRIGGER_EVENT(download, "event.download.resumed"); + if (rpc::call_command_value("system.file.allocate")) + openFlags |= torrent::Download::open_enable_fallocate; + try { + download->download()->start(openFlags); + + rpc::parse_command_single(rpc::make_target(download), "view.set_visible=active"); + rpc::call_command("d.state_changed.set", cachedTime.seconds(), rpc::make_target(download)); + rpc::call_command("d.state_counter.set", rpc::call_command_value("d.state_counter", rpc::make_target(download)) + 1, rpc::make_target(download)); + + download->set_resume_flags(~uint32_t()); + + DL_TRIGGER_EVENT(download, "event.download.resumed"); + } catch (torrent::internal_error& e) { + std::string errmsg = e.what(); + + if (errmsg == "Tried to start an already started download.") { + download->set_resume_flags(~uint32_t()); + } else if (errmsg == "Tried to start a download with not enough disk space for it.") { + rpc::call_command("d.stop", torrent::Object(), rpc::make_target(download)); + control->core()->push_log_std("Not enough disk space to start download " + download->download()->info()->name()); + } + } } catch (torrent::local_error& e) { lt_log_print(torrent::LOG_TORRENT_ERROR, "Could not resume download: %s", e.what()); } --- a/src/ui/element_file_list.cc 2016-10-23 05:33:00.000000000 +0100 +++ a/src/ui/element_file_list.cc 2017-04-30 22:42:23.000000000 +0100 @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -47,6 +48,8 @@ #include "display/window_file_list.h" #include "input/manager.h" +#include "rpc/parse_commands.h" + #include "control.h" #include "element_file_list.h" #include "element_text.h" @@ -278,7 +281,8 @@ ElementFileList::receive_priority() { first++; } - m_download->download()->update_priorities(); + int flags = rpc::call_command_value("system.file.allocate") ? torrent::Download::open_enable_fallocate : 0; + m_download->download()->update_priorities(flags); update_itr(); } @@ -293,7 +297,8 @@ ElementFileList::receive_change_all() { for (torrent::FileList::iterator itr = fl->begin(), last = fl->end(); itr != last; ++itr) (*itr)->set_priority(priority); - m_download->download()->update_priorities(); + int flags = rpc::call_command_value("system.file.allocate") ? torrent::Download::open_enable_fallocate : 0; + m_download->download()->update_priorities(flags); update_itr(); }