Caching behavior
What is the issue?
In 4.1.3, normally, cached data are written to disk only when cached size exceeds limit (and "special cases" like stop/exit/file done/etc of cource)
On the other hand, the resume file is written to disk on a schedule
void tr_session::on_save_timer()
{
for (auto* const tor : torrents())
{
tor->save_resume_file();
}
stats().save_if_dirty();
torrent_queue().to_file();
}So it seems possible that when a piece is done, piece data writes may happen AFTER resume file (piece check status) writes. I'm not very sure, but if it is the case, there seems to be a small chance that the piece data become corrupt if the app is teminated or crashes after resume file write and before data write, and we'll never know it except for a manual re-verify (piece status from resume file is right, and mtime may also be right since mtime may have been updated by writes of some other piece).
In 3.0, data (of complete pieces) are forced flushed to disk BEFORE resume file write:
static void onSaveTimer(evutil_socket_t foo UNUSED, short bar UNUSED, void* vsession)
{
tr_torrent* tor = NULL;
tr_session* session = vsession;
if (tr_cacheFlushDone(session->cache) != 0)
{
tr_logAddError("Error while flushing completed pieces from cache");
}
while ((tor = tr_torrentNext(session, tor)) != NULL)
{
tr_torrentSave(tor);
}
tr_statsSaveDirty(session);
tr_timerAdd(session->saveTimer, SAVE_INTERVAL_SECS, 0);
}The 3.0 behavior guarantees piece data be valid when the resume file says so. The 4.x behavior extends cache usage. Cached data are invalidated (written to file) only when cache is full, while in 3.0 cached data (of complete pieces) are invalidated on a the timer, even if the cache is not full. However that brings the posibility of corrupted data.
If that is a promplem, I think maybe:
- When saving the resume file, only status of flushed data are written (maybe by adding a separate "flushed" flag in addition to the checked flag)
- Is it possible that we further extend the cache usege: cache becomes not only for write. Cache may still be kept even after flushed to file (when cache space is suficiente of course). And read data may also be kept in cache (useful in seeding scenario). This extension seems not to be very complicated: adding an extra status flag to cache items and extending the cache trim algorithm (longest + simple LRU)
Which application of Transmission?
transmission-daemon
Which version of Transmission?
4.1.3
Source: transmission/transmission