1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-21 23:32:35 +00:00

refactor: remove prefetch (#6332)

This commit is contained in:
Charles Kerr 2023-12-04 11:45:37 -06:00 committed by GitHub
parent 0c51eb36d7
commit 3cd66899fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 15 additions and 184 deletions

View file

@ -81,7 +81,6 @@ Here is a sample of the three basic types: respectively Boolean, Number and Stri
* **message-level:** Number (0 = None, 1 = Critical, 2 = Error, 3 = Warn, 4 = Info, 5 = Debug, 6 = Trace; default = 2) Set verbosity of Transmission's log messages.
* **pex-enabled:** Boolean (default = true) Enable [Peer Exchange (PEX)](https://en.wikipedia.org/wiki/Peer_exchange).
* **pidfile:** String Path to file in which daemon PID will be stored (transmission-daemon only)
* **prefetch-enabled:** Boolean (default = true). When enabled, Transmission will hint to the OS which piece data it's about to read from disk in order to satisfy requests from peers. On Linux, this is done by passing `POSIX_FADV_WILLNEED` to [posix_fadvise()](https://www.kernel.org/doc/man-pages/online/pages/man2/posix_fadvise.2.html). On macOS, this is done by passing `F_RDADVISE` to [fcntl()](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html).
* **scrape-paused-torrents-enabled:** Boolean (default = true)
* **script-torrent-added-enabled:** Boolean (default = false) Run a script when a torrent is added to Transmission. Environmental variables are passed in as detailed on the [Scripts](./Scripts.md) page
* **script-torrent-added-filename:** String (default = "") Path to script.

View file

@ -185,16 +185,6 @@ int Cache::read_block(tr_torrent const& tor, tr_block_info::Location const& loc,
return tr_ioRead(tor, loc, len, setme);
}
int Cache::prefetch_block(tr_torrent const& tor, tr_block_info::Location const& loc, size_t len)
{
if (auto const iter = get_block(tor, loc); iter != std::end(blocks_))
{
return {}; // already have it
}
return tr_ioPrefetch(tor, loc, len);
}
// ---
int Cache::flush_span(CIter const begin, CIter const end)

View file

@ -39,7 +39,6 @@ public:
int write_block(tr_torrent_id_t tor, tr_block_index_t block, std::unique_ptr<BlockData> writeme);
int read_block(tr_torrent const& tor, tr_block_info::Location const& loc, size_t len, uint8_t* setme);
int prefetch_block(tr_torrent const& tor, tr_block_info::Location const& loc, size_t len);
int flush_torrent(tr_torrent_id_t tor_id);
int flush_file(tr_torrent const& tor, tr_file_index_t file);

View file

@ -842,58 +842,6 @@ bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error* error)
return ret;
}
bool tr_sys_file_advise(
[[maybe_unused]] tr_sys_file_t handle,
[[maybe_unused]] uint64_t offset,
[[maybe_unused]] uint64_t size,
[[maybe_unused]] tr_sys_file_advice_t advice,
[[maybe_unused]] tr_error* error)
{
TR_ASSERT(handle != TR_BAD_SYS_FILE);
TR_ASSERT(size > 0);
TR_ASSERT(advice == TR_SYS_FILE_ADVICE_WILL_NEED || advice == TR_SYS_FILE_ADVICE_DONT_NEED);
bool ret = true;
#if defined(HAVE_POSIX_FADVISE)
int const native_advice = advice == TR_SYS_FILE_ADVICE_WILL_NEED ?
POSIX_FADV_WILLNEED :
(advice == TR_SYS_FILE_ADVICE_DONT_NEED ? POSIX_FADV_DONTNEED : POSIX_FADV_NORMAL);
TR_ASSERT(native_advice != POSIX_FADV_NORMAL);
if (int const code = posix_fadvise(handle, offset, size, native_advice); code != 0)
{
if (error != nullptr)
{
error->set_from_errno(errno);
}
ret = false;
}
#elif defined(__APPLE__)
if (advice == TR_SYS_FILE_ADVICE_WILL_NEED)
{
auto radv = radvisory{};
radv.ra_offset = offset;
radv.ra_count = size;
ret = fcntl(handle, F_RDADVISE, &radv) != -1;
if (error != nullptr && !ret)
{
error->set_from_errno(errno);
}
}
#endif
return ret;
}
namespace
{
namespace preallocate_helpers

View file

@ -1127,24 +1127,6 @@ bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error* error)
return ret;
}
bool tr_sys_file_advise(
[[maybe_unused]] tr_sys_file_t handle,
uint64_t /*offset*/,
[[maybe_unused]] uint64_t size,
[[maybe_unused]] tr_sys_file_advice_t advice,
tr_error* /*error*/)
{
TR_ASSERT(handle != TR_BAD_SYS_FILE);
TR_ASSERT(size > 0);
TR_ASSERT(advice == TR_SYS_FILE_ADVICE_WILL_NEED || advice == TR_SYS_FILE_ADVICE_DONT_NEED);
bool ret = true;
/* ??? */
return ret;
}
bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_error* error)
{
TR_ASSERT(handle != TR_BAD_SYS_FILE);

View file

@ -75,12 +75,6 @@ enum tr_sys_path_get_info_flags_t
TR_SYS_PATH_NO_FOLLOW = (1 << 0)
};
enum tr_sys_file_advice_t
{
TR_SYS_FILE_ADVICE_WILL_NEED,
TR_SYS_FILE_ADVICE_DONT_NEED
};
enum tr_sys_file_preallocate_flags_t
{
TR_SYS_FILE_PREALLOC_SPARSE = (1 << 0)
@ -469,24 +463,6 @@ bool tr_sys_file_flush_possible(tr_sys_file_t handle, tr_error* error = nullptr)
*/
bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error* error = nullptr);
/**
* @brief Tell system to prefetch or discard some part of file which is [not] to be read soon.
*
* @param[in] handle Valid file descriptor.
* @param[in] offset Offset in file to prefetch from.
* @param[in] size Number of bytes to prefetch.
* @param[out] error Pointer to error object. Optional, pass `nullptr` if you
* are not interested in error details.
*
* @return `True` on success, `false` otherwise (with `error` set accordingly).
*/
bool tr_sys_file_advise(
tr_sys_file_t handle,
uint64_t offset,
uint64_t size,
tr_sys_file_advice_t advice,
tr_error* error = nullptr);
/**
* @brief Preallocate file to specified size in full or sparse mode.
*

View file

@ -123,18 +123,11 @@ bool write_entire_buf(tr_sys_file_t const fd, uint64_t file_offset, uint8_t cons
return {};
}
enum class IoMode
{
Read,
Prefetch,
Write
};
void read_or_write_bytes(
tr_session& session,
tr_open_files& open_files,
tr_torrent const& tor,
IoMode const io_mode,
bool const writable,
tr_file_index_t const file_index,
uint64_t const file_offset,
uint8_t* const buf,
@ -150,7 +143,6 @@ void read_or_write_bytes(
return;
}
auto const writable = io_mode == IoMode::Write;
auto const fd = get_fd(session, open_files, tor, writable, file_index, error);
if (!fd || error)
{
@ -158,21 +150,15 @@ void read_or_write_bytes(
}
auto fmtstr = ""sv;
switch (io_mode)
if (writable)
{
case IoMode::Prefetch:
tr_sys_file_advise(*fd, file_offset, buflen, TR_SYS_FILE_ADVICE_WILL_NEED);
break;
case IoMode::Write:
fmtstr = _("Couldn't save '{path}': {error} ({error_code})");
write_entire_buf(*fd, file_offset, buf, buflen, error);
break;
case IoMode::Read:
}
else
{
fmtstr = _("Couldn't read '{path}': {error} ({error_code})");
read_entire_buf(*fd, file_offset, buf, buflen, error);
break;
}
if (error)
@ -189,7 +175,7 @@ void read_or_write_bytes(
void read_or_write_piece(
tr_torrent const& tor,
IoMode const io_mode,
bool const writable,
tr_block_info::Location const loc,
uint8_t* buf,
uint64_t buflen,
@ -207,7 +193,7 @@ void read_or_write_piece(
while (buflen != 0U && !error)
{
auto const bytes_this_pass = std::min(buflen, tor.file_size(file_index) - file_offset);
read_or_write_bytes(session, open_files, tor, io_mode, file_index, file_offset, buf, bytes_this_pass, error);
read_or_write_bytes(session, open_files, tor, writable, file_index, file_offset, buf, bytes_this_pass, error);
if (buf != nullptr)
{
buf += bytes_this_pass;
@ -264,21 +250,14 @@ std::optional<tr_sha1_digest_t> recalculate_hash(tr_torrent const& tor, tr_piece
int tr_ioRead(tr_torrent const& tor, tr_block_info::Location const& loc, size_t const len, uint8_t* const setme)
{
auto error = tr_error{};
read_or_write_piece(tor, IoMode::Read, loc, setme, len, error);
return error.code();
}
int tr_ioPrefetch(tr_torrent const& tor, tr_block_info::Location const& loc, size_t const len)
{
auto error = tr_error{};
read_or_write_piece(tor, IoMode::Prefetch, loc, nullptr, len, error);
read_or_write_piece(tor, false /*writable*/, loc, setme, len, error);
return error.code();
}
int tr_ioWrite(tr_torrent& tor, tr_block_info::Location const& loc, size_t const len, uint8_t const* const writeme)
{
auto error = tr_error{};
read_or_write_piece(tor, IoMode::Write, loc, const_cast<uint8_t*>(writeme), len, error);
read_or_write_piece(tor, true /*writable*/, loc, const_cast<uint8_t*>(writeme), len, error);
// if IO failed, set torrent's error if not already set
if (error && tor.error().error_type() != TR_STAT_LOCAL_ERROR)

View file

@ -29,8 +29,6 @@ struct tr_torrent;
*/
[[nodiscard]] int tr_ioRead(tr_torrent const& tor, tr_block_info::Location const& loc, size_t len, uint8_t* setme);
int tr_ioPrefetch(tr_torrent const& tor, tr_block_info::Location const& loc, size_t len);
/**
* Writes the block specified by the piece index, offset, and length.
* @return 0 on success, or an errno value on failure.

View file

@ -183,9 +183,6 @@ auto constexpr ReqQ = int{ 512 };
// used in lowering the outMessages queue period
// how many blocks to keep prefetched per peer
auto constexpr PrefetchMax = size_t{ 18 };
// when we're making requests from another peer,
// batch them together to send enough requests to
// meet our bandwidth goals for the next N seconds
@ -635,17 +632,7 @@ public:
std::shared_ptr<tr_peerIo> const io;
struct QueuedPeerRequest : public peer_request
{
explicit QueuedPeerRequest(peer_request in) noexcept
: peer_request{ in }
{
}
bool prefetched = false;
};
std::vector<QueuedPeerRequest> peer_requested_;
std::vector<peer_request> peer_requested_;
std::array<std::vector<tr_pex>, NUM_TR_AF_INET_TYPES> pex;
@ -897,15 +884,17 @@ std::optional<int> popNextMetadataRequest(tr_peerMsgsImpl* msgs)
void cancelAllRequestsToClient(tr_peerMsgsImpl* msgs)
{
auto& queue = msgs->peer_requested_;
if (auto const must_send_rej = msgs->io->supports_fext(); must_send_rej)
{
for (auto const& req : msgs->peer_requested_)
for (auto const& req : queue)
{
protocolSendReject(msgs, &req);
}
}
msgs->peer_requested_.clear();
queue.clear();
}
// ---
@ -1257,25 +1246,6 @@ void parseLtep(tr_peerMsgsImpl* msgs, MessageReader& payload)
ReadResult process_peer_message(tr_peerMsgsImpl* msgs, uint8_t id, MessageReader& payload);
void prefetchPieces(tr_peerMsgsImpl* msgs)
{
if (!msgs->session->allowsPrefetch())
{
return;
}
// ensure that the first `PrefetchMax` items in `msgs->peer_requested_` are prefetched.
auto& requests = msgs->peer_requested_;
for (size_t i = 0, n = std::min(PrefetchMax, std::size(requests)); i < n; ++i)
{
if (auto& req = requests[i]; !req.prefetched)
{
msgs->session->cache->prefetch_block(*msgs->torrent, msgs->torrent->piece_loc(req.index, req.offset), req.length);
req.prefetched = true;
}
}
}
[[nodiscard]] bool canAddRequestFromPeer(tr_peerMsgsImpl const* const msgs, struct peer_request const& req)
{
if (msgs->peer_is_choked())
@ -1310,7 +1280,6 @@ void peerMadeRequest(tr_peerMsgsImpl* msgs, struct peer_request const* req)
if (canAddRequestFromPeer(msgs, *req))
{
msgs->peer_requested_.emplace_back(*req);
prefetchPieces(msgs);
}
else if (msgs->io->supports_fext())
{

View file

@ -19,7 +19,7 @@ using namespace std::literals;
namespace
{
auto constexpr MyStatic = std::array<std::string_view, 406>{ ""sv,
auto constexpr MyStatic = std::array<std::string_view, 405>{ ""sv,
"activeTorrentCount"sv,
"activity-date"sv,
"activityDate"sv,
@ -252,7 +252,6 @@ auto constexpr MyStatic = std::array<std::string_view, 406>{ ""sv,
"port-is-open"sv,
"preallocation"sv,
"preferred-transport"sv,
"prefetch-enabled"sv,
"primary-mime-type"sv,
"priorities"sv,
"priority"sv,

View file

@ -254,7 +254,6 @@ enum
TR_KEY_port_is_open,
TR_KEY_preallocation,
TR_KEY_preferred_transport,
TR_KEY_prefetch_enabled,
TR_KEY_primary_mime_type,
TR_KEY_priorities,
TR_KEY_priority,

View file

@ -53,7 +53,6 @@ struct tr_variant;
V(TR_KEY_pex_enabled, pex_enabled, bool, true, "") \
V(TR_KEY_port_forwarding_enabled, port_forwarding_enabled, bool, true, "") \
V(TR_KEY_preallocation, preallocation_mode, tr_open_files::Preallocation, tr_open_files::Preallocation::Sparse, "") \
V(TR_KEY_prefetch_enabled, is_prefetch_enabled, bool, true, "") \
V(TR_KEY_queue_stalled_enabled, queue_stalled_enabled, bool, true, "") \
V(TR_KEY_queue_stalled_minutes, queue_stalled_minutes, size_t, 30U, "") \
V(TR_KEY_ratio_limit, ratio_limit, double, 2.0, "") \

View file

@ -786,11 +786,6 @@ public:
return settings_.preferred_transport;
}
[[nodiscard]] constexpr auto allowsPrefetch() const noexcept
{
return settings_.is_prefetch_enabled;
}
[[nodiscard]] constexpr auto isIdleLimited() const noexcept
{
return settings_.idle_seeding_limit_enabled;

View file

@ -75,7 +75,6 @@ void tr_verify_worker::verify_torrent(Mediator& verify_mediator, bool const abor
{
bytes_this_pass = num_read;
sha->add(std::data(buffer), bytes_this_pass);
tr_sys_file_advise(fd, file_pos, bytes_this_pass, TR_SYS_FILE_ADVICE_DONT_NEED);
}
}