diff --git a/docs/Editing-Configuration-Files.md b/docs/Editing-Configuration-Files.md index 3c484334f..8435e6e29 100644 --- a/docs/Editing-Configuration-Files.md +++ b/docs/Editing-Configuration-Files.md @@ -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. diff --git a/libtransmission/cache.cc b/libtransmission/cache.cc index f9e76374a..f55aff521 100644 --- a/libtransmission/cache.cc +++ b/libtransmission/cache.cc @@ -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) diff --git a/libtransmission/cache.h b/libtransmission/cache.h index 99c845fc9..1161afc74 100644 --- a/libtransmission/cache.h +++ b/libtransmission/cache.h @@ -39,7 +39,6 @@ public: int write_block(tr_torrent_id_t tor, tr_block_index_t block, std::unique_ptr 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); diff --git a/libtransmission/file-posix.cc b/libtransmission/file-posix.cc index 52f2bf5e0..2319385cb 100644 --- a/libtransmission/file-posix.cc +++ b/libtransmission/file-posix.cc @@ -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 diff --git a/libtransmission/file-win32.cc b/libtransmission/file-win32.cc index 0d1be3e93..66397732e 100644 --- a/libtransmission/file-win32.cc +++ b/libtransmission/file-win32.cc @@ -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); diff --git a/libtransmission/file.h b/libtransmission/file.h index 51b662185..3f6a00df6 100644 --- a/libtransmission/file.h +++ b/libtransmission/file.h @@ -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. * diff --git a/libtransmission/inout.cc b/libtransmission/inout.cc index 337e6ec4d..1409d243b 100644 --- a/libtransmission/inout.cc +++ b/libtransmission/inout.cc @@ -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 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(writeme), len, error); + read_or_write_piece(tor, true /*writable*/, loc, const_cast(writeme), len, error); // if IO failed, set torrent's error if not already set if (error && tor.error().error_type() != TR_STAT_LOCAL_ERROR) diff --git a/libtransmission/inout.h b/libtransmission/inout.h index 3febd4708..5aa3c3cad 100644 --- a/libtransmission/inout.h +++ b/libtransmission/inout.h @@ -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. diff --git a/libtransmission/peer-msgs.cc b/libtransmission/peer-msgs.cc index 502bc0201..a7d1f44dc 100644 --- a/libtransmission/peer-msgs.cc +++ b/libtransmission/peer-msgs.cc @@ -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 const io; - struct QueuedPeerRequest : public peer_request - { - explicit QueuedPeerRequest(peer_request in) noexcept - : peer_request{ in } - { - } - - bool prefetched = false; - }; - - std::vector peer_requested_; + std::vector peer_requested_; std::array, NUM_TR_AF_INET_TYPES> pex; @@ -897,15 +884,17 @@ std::optional 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()) { diff --git a/libtransmission/quark.cc b/libtransmission/quark.cc index 43df5dba9..90845fee4 100644 --- a/libtransmission/quark.cc +++ b/libtransmission/quark.cc @@ -19,7 +19,7 @@ using namespace std::literals; namespace { -auto constexpr MyStatic = std::array{ ""sv, +auto constexpr MyStatic = std::array{ ""sv, "activeTorrentCount"sv, "activity-date"sv, "activityDate"sv, @@ -252,7 +252,6 @@ auto constexpr MyStatic = std::array{ ""sv, "port-is-open"sv, "preallocation"sv, "preferred-transport"sv, - "prefetch-enabled"sv, "primary-mime-type"sv, "priorities"sv, "priority"sv, diff --git a/libtransmission/quark.h b/libtransmission/quark.h index 947e2b46f..aefd54a22 100644 --- a/libtransmission/quark.h +++ b/libtransmission/quark.h @@ -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, diff --git a/libtransmission/session-settings.h b/libtransmission/session-settings.h index f9da28358..70b5f7351 100644 --- a/libtransmission/session-settings.h +++ b/libtransmission/session-settings.h @@ -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, "") \ diff --git a/libtransmission/session.h b/libtransmission/session.h index c6f720237..15bb4c376 100644 --- a/libtransmission/session.h +++ b/libtransmission/session.h @@ -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; diff --git a/libtransmission/verify.cc b/libtransmission/verify.cc index 3641a6bc1..0dcfc0570 100644 --- a/libtransmission/verify.cc +++ b/libtransmission/verify.cc @@ -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); } }