]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Handle data going missing
authorMatt Joiner <anacrolix@gmail.com>
Wed, 18 Mar 2015 07:35:22 +0000 (18:35 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 18 Mar 2015 07:35:22 +0000 (18:35 +1100)
client.go
data/blob/store.go

index 7ff99428933e2d4ddb1a2d1822be290fe8c98377..d506f5f18bfdfd1111282419afd9875a32b54368 100644 (file)
--- a/client.go
+++ b/client.go
@@ -280,8 +280,20 @@ func (cl *Client) torrentReadAt(t *torrent, off int64, p []byte) (n int, err err
        if len(p) == 0 {
                panic(len(p))
        }
-       cl.prepareRead(t, off)
-       return dataReadAt(t.data, p, off)
+       // TODO: ReadAt should always try to fill the buffer.
+       for {
+               avail := cl.prepareRead(t, off)
+               if avail < int64(len(p)) {
+                       p = p[:avail]
+               }
+               n, err = dataReadAt(t.data, p, off)
+               if n != 0 || err != io.ErrUnexpectedEOF {
+                       break
+               }
+               // If we reach here, the data we thought was ready, isn't. So we
+               // prepare it again, and retry.
+       }
+       return
 }
 
 // Sets priorities to download from the given offset. Returns when the piece
index c69886e7820b90ae024ee2c8e77200bd6819b71a..6bb411e4b433ea6f723147481e01365e1bc05937 100644 (file)
@@ -124,6 +124,10 @@ func (me *store) pieceRead(p metainfo.Piece) (f *os.File) {
        if !os.IsNotExist(err) {
                panic(err)
        }
+       // Ermahgerd, self heal. This occurs when the underlying data goes
+       // missing, likely due to a "cache flush", also known as deleting the
+       // files. TODO: Trigger an asynchronous initCompleted.
+       delete(me.completed, sliceToPieceHashArray(p.Hash()))
        f, err = os.Open(me.path(p, false))
        if err == nil {
                return