From 747c70a58eae329b1f109a6728d100196ed834ef Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Mon, 9 Apr 2018 05:55:04 +0300 Subject: [PATCH] Avoid data corruption when rechecking paused torrents Libtorrent can recheck only unpaused torrents. We get around this by unpausing the torrent, issuing the recheck and pausing again after we get alerted by libtorrent that the recheck has finished. This alert is asyncronous. There is a small time frame where the program might start downloading and writing data to the file before we pause it. This can lead to data corruption if the file on disk is totally different that the one expected by the torrent AND the file on disk is a valid file on its own. OR in case the user points the new torrent to the wrong directory by mistake. To get around this the torrent is placed in upload_mode and out of automanagement. --- src/base/bittorrent/torrenthandle.cpp | 9 +++++++-- src/base/bittorrent/torrenthandle.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 9ec78b8dd..4f49f5c88 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -1277,7 +1277,7 @@ void TorrentHandle::forceRecheck() if (isPaused()) { m_pauseAfterRecheck = true; - resume(); + resume_impl(true, true); } m_nativeHandle.force_recheck(); @@ -1345,12 +1345,17 @@ void TorrentHandle::pause() } void TorrentHandle::resume(bool forced) +{ + resume_impl(forced, false); +} + +void TorrentHandle::resume_impl(bool forced, bool uploadMode) { if (hasError()) m_nativeHandle.clear_error(); m_hasMissingFiles = false; - m_nativeHandle.set_upload_mode(false); m_nativeHandle.auto_managed(!forced); + m_nativeHandle.set_upload_mode(uploadMode); m_nativeHandle.resume(); } diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index b67eeec3d..6639385f1 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -406,6 +406,7 @@ namespace BitTorrent void handleMetadataReceivedAlert(libtorrent::metadata_received_alert *p); void handleStatsAlert(libtorrent::stats_alert *p); + void resume_impl(bool forced, bool uploadMode); bool isMoveInProgress() const; QString nativeActualSavePath() const;