From d4788882316354d3e44bd1926faed5f48449974a Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Tue, 9 Apr 2019 12:57:54 +1000 Subject: [PATCH] When failing to read stored data, try updating only the completion state for the failed piece On rare occasions, reads are failing in a loop, exhausting all the available file descriptors. It's not clear why, it could be an error in the filecache storage backend I'm using, or some logic error regarding when it's okay to try to read. --- reader.go | 5 +++-- torrent.go | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/reader.go b/reader.go index 648228be..24403dc1 100644 --- a/reader.go +++ b/reader.go @@ -226,8 +226,9 @@ func (r *reader) readOnceAt(b []byte, pos int64, ctxErr *error) (n int, err erro // prevent thrashing with small caches and file and piece priorities. log.Printf("error reading torrent %s piece %d offset %d, %d bytes: %v", r.t.infoHash.HexString(), pi, po, len(b1), err) - r.t.updateAllPieceCompletions() - r.t.updateAllPiecePriorities() + if !r.t.updatePieceCompletion(pi) { + log.Printf("piece %d completion unchanged", pi) + } r.t.cl.unlock() } } diff --git a/torrent.go b/torrent.go index c9ccaa9f..4a519d34 100644 --- a/torrent.go +++ b/torrent.go @@ -1054,7 +1054,7 @@ func (t *Torrent) putPieceInclination(pi []int) { pieceInclinationsPut.Add(1) } -func (t *Torrent) updatePieceCompletion(piece pieceIndex) { +func (t *Torrent) updatePieceCompletion(piece pieceIndex) bool { pcu := t.pieceCompleteUncached(piece) p := &t.pieces[piece] changed := t.completedPieces.Get(bitmap.BitIndex(piece)) != pcu.Complete || p.storageCompletionOk != pcu.Ok @@ -1067,6 +1067,7 @@ func (t *Torrent) updatePieceCompletion(piece pieceIndex) { if changed { t.pieceCompletionChanged(piece) } + return changed } // Non-blocking read. Client lock is not required. -- 2.48.1