]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Propagate back piece hashing errors
authorMatt Joiner <anacrolix@gmail.com>
Tue, 7 Jan 2020 08:18:07 +0000 (19:18 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 13 Jan 2020 23:51:09 +0000 (10:51 +1100)
Attempting to solve https://github.com/anacrolix/torrent/issues/364.

issue97_test.go
torrent.go

index 5ccfa62e6a9d00f4a99d3f6a6d2c693115866e12..2091b758df633dd373665c8088456c715090a810 100644 (file)
@@ -5,6 +5,7 @@ import (
        "os"
        "testing"
 
+       "github.com/anacrolix/log"
        "github.com/stretchr/testify/require"
 
        "github.com/anacrolix/torrent/internal/testutil"
@@ -17,6 +18,7 @@ func TestHashPieceAfterStorageClosed(t *testing.T) {
        defer os.RemoveAll(td)
        tt := &Torrent{
                storageOpener: storage.NewClient(storage.NewFile(td)),
+               logger:        log.Default,
        }
        mi := testutil.GreetingMetaInfo()
        info, err := mi.UnmarshalInfo()
index 2937b94ca3b96e194e344851a33a9a6e05f212d3..9b353b44988c6389944eb6fd546abdd55677bc64 100644 (file)
@@ -8,7 +8,6 @@ import (
        "io"
        "math/rand"
        "net/url"
-       "os"
        "sync"
        "text/tabwriter"
        "time"
@@ -744,20 +743,14 @@ func (t *Torrent) pieceLength(piece pieceIndex) pp.Integer {
        return pp.Integer(t.info.PieceLength)
 }
 
-func (t *Torrent) hashPiece(piece pieceIndex) (ret metainfo.Hash) {
+func (t *Torrent) hashPiece(piece pieceIndex) (ret metainfo.Hash, copyErr error) {
        hash := pieceHash.New()
        p := t.piece(piece)
        p.waitNoPendingWrites()
        ip := t.info.Piece(int(piece))
        pl := ip.Length()
-       n, err := io.Copy(hash, io.NewSectionReader(t.pieces[piece].Storage(), 0, pl))
-       if n == pl {
-               missinggo.CopyExact(&ret, hash.Sum(nil))
-               return
-       }
-       if err != io.ErrUnexpectedEOF && !os.IsNotExist(err) {
-               t.logger.Printf("unexpected error hashing piece %d through %T: %s", piece, t.storage.TorrentImpl, err)
-       }
+       _, copyErr = io.CopyN(hash, io.NewSectionReader(t.pieces[piece].Storage(), 0, pl), pl)
+       missinggo.CopyExact(&ret, hash.Sum(nil))
        return
 }
 
@@ -1073,8 +1066,12 @@ func (t *Torrent) updatePieceCompletion(piece pieceIndex) bool {
        uncached := t.pieceCompleteUncached(piece)
        cached := p.completion()
        changed := cached != uncached
+       complete := uncached.Complete
        p.storageCompletionOk = uncached.Ok
-       t.completedPieces.Set(bitmap.BitIndex(piece), uncached.Complete)
+       t.completedPieces.Set(bitmap.BitIndex(piece), complete)
+       if complete && len(p.dirtiers) != 0 {
+               t.logger.Printf("marked piece %v complete but still has dirtiers", piece)
+       }
        if changed {
                log.Fstr("piece %d completion changed: %+v -> %+v", piece, cached, uncached).WithValues(debugLogValue).Log(t.logger)
                t.pieceCompletionChanged(piece)
@@ -1658,13 +1655,17 @@ func (t *Torrent) getPieceToHash() (ret pieceIndex, ok bool) {
 
 func (t *Torrent) pieceHasher(index pieceIndex) {
        p := t.piece(index)
-       sum := t.hashPiece(index)
+       sum, copyErr := t.hashPiece(index)
+       correct := sum == *p.hash
+       if !correct {
+               log.Fmsg("piece %v hash failure copy error: %v", index, copyErr).Log(t.logger)
+       }
        t.storageLock.RUnlock()
        t.cl.lock()
        defer t.cl.unlock()
        p.hashing = false
        t.updatePiecePriority(index)
-       t.pieceHashed(index, sum == *p.hash)
+       t.pieceHashed(index, correct)
        t.publishPieceChange(index)
        t.activePieceHashes--
        t.tryCreateMorePieceHashers()