From 19ce53e69f4b46f9b94dd557ba58aac3fcc44c93 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Thu, 27 Feb 2020 16:45:57 +1100 Subject: [PATCH] Make io.EOF an expected error from storage.Piece.ReadAt Fixes #381. --- storage/bolt_piece.go | 6 ++++-- storage/file.go | 4 ---- storage/file_test.go | 6 +++++- storage/wrappers.go | 10 ++-------- test/transfer_test.go | 1 - torrent.go | 4 +++- 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/storage/bolt_piece.go b/storage/bolt_piece.go index 179fe3bd..c54a25e9 100644 --- a/storage/bolt_piece.go +++ b/storage/bolt_piece.go @@ -2,6 +2,7 @@ package storage import ( "encoding/binary" + "io" "github.com/anacrolix/missinggo/x" bolt "github.com/etcd-io/bbolt" @@ -46,15 +47,16 @@ func (me *boltDBPiece) ReadAt(b []byte, off int64) (n int, err error) { err = me.db.View(func(tx *bolt.Tx) error { db := tx.Bucket(dataBucketKey) if db == nil { - return nil + return io.EOF } ci := off / chunkSize off %= chunkSize for len(b) != 0 { ck := me.chunkKey(int(ci)) _b := db.Get(ck[:]) + // If the chunk is the wrong size, assume it's missing as we can't rely on the data. if len(_b) != chunkSize { - break + return io.EOF } n1 := copy(b, _b[off:]) off = 0 diff --git a/storage/file.go b/storage/file.go index 415ac5df..013351d7 100644 --- a/storage/file.go +++ b/storage/file.go @@ -169,10 +169,6 @@ func (fst fileTorrentImplIO) ReadAt(b []byte, off int64) (n int, err error) { continue } err = err1 - if err == io.EOF { - // Lies. - err = io.ErrUnexpectedEOF - } return } off -= fi.Length diff --git a/storage/file_test.go b/storage/file_test.go index 1a5e1b60..daa28acc 100644 --- a/storage/file_test.go +++ b/storage/file_test.go @@ -36,5 +36,9 @@ func TestShortFile(t *testing.T) { p := info.Piece(0) n, err := io.Copy(&buf, io.NewSectionReader(ts.Piece(p), 0, p.Length())) assert.EqualValues(t, 1, n) - assert.Equal(t, io.ErrUnexpectedEOF, err) + switch err { + case nil, io.EOF: + default: + t.Errorf("expected nil or EOF error from truncated piece, got %v", err) + } } diff --git a/storage/wrappers.go b/storage/wrappers.go index 4fc0e10d..da52c89f 100644 --- a/storage/wrappers.go +++ b/storage/wrappers.go @@ -69,16 +69,10 @@ func (p Piece) ReadAt(b []byte, off int64) (n int, err error) { if n > len(b) { panic(n) } - off += int64(n) - if err == io.EOF && off < p.mip.Length() { - err = io.ErrUnexpectedEOF - } - if err == nil && off >= p.mip.Length() { - err = io.EOF - } if n == 0 && err == nil { - err = io.ErrUnexpectedEOF + panic("io.Copy will get stuck") } + off += int64(n) if off < p.mip.Length() && err != nil { p.MarkNotComplete() } diff --git a/test/transfer_test.go b/test/transfer_test.go index 32b9ed15..4fe9d562 100644 --- a/test/transfer_test.go +++ b/test/transfer_test.go @@ -93,7 +93,6 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) { cfg.DownloadRateLimiter = ps.LeecherDownloadRateLimiter } cfg.Seed = false - //cfg.Debug = true if ps.ConfigureLeecher.Config != nil { ps.ConfigureLeecher.Config(cfg) } diff --git a/torrent.go b/torrent.go index f6627b2f..42f5636e 100644 --- a/torrent.go +++ b/torrent.go @@ -1682,7 +1682,9 @@ func (t *Torrent) pieceHasher(index pieceIndex) { p := t.piece(index) sum, copyErr := t.hashPiece(index) correct := sum == *p.hash - if !correct { + switch copyErr { + case nil, io.EOF: + default: log.Fmsg("piece %v (%s) hash failure copy error: %v", p, p.hash.HexString(), copyErr).Log(t.logger) } t.storageLock.RUnlock()