From 786952e4cd4633991f9699bd8abdeabda12b3093 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Wed, 9 Apr 2014 01:15:39 +1000 Subject: [PATCH] Add error handling to PrioritizeDataRegion as it's public facing API --- client.go | 22 ++++++++++++++-------- fs/torrentfs.go | 5 ++++- torrent.go | 12 ++++++++++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/client.go b/client.go index 9b9a6d38..6858f953 100644 --- a/client.go +++ b/client.go @@ -33,27 +33,32 @@ func (cl *Client) queuePieceCheck(t *Torrent, pieceIndex peer_protocol.Integer) go cl.verifyPiece(t, pieceIndex) } -func (cl *Client) PrioritizeDataRegion(ih InfoHash, off, len_ int64) { +func (cl *Client) PrioritizeDataRegion(ih InfoHash, off, len_ int64) error { cl.mu.Lock() defer cl.mu.Unlock() t := cl.torrent(ih) - newPriorities := make([]Request, 0, (len_+2*(chunkSize-1))/chunkSize) + if t == nil { + return errors.New("no such active torrent") + } + newPriorities := make([]Request, 0, (len_+chunkSize-1)/chunkSize) for len_ > 0 { - // TODO: Write a function to return the Request for a given offset. req, ok := t.offsetRequest(off) if !ok { - break + return errors.New("bad offset") } - off += int64(req.Length) + reqOff := t.requestOffset(req) + // Gain the alignment adjustment. + len_ += off - reqOff + // Lose the length of this block. len_ -= int64(req.Length) - // TODO(anacrolix): Determine if this check is satisfactory. - if _, ok = t.Pieces[req.Index].PendingChunkSpecs[req.ChunkSpec]; !ok { + off = reqOff + int64(req.Length) + if !t.wantPiece(int(req.Index)) { continue } newPriorities = append(newPriorities, req) } if len(newPriorities) == 0 { - return + return nil } if t.Priorities == nil { t.Priorities = list.New() @@ -65,6 +70,7 @@ func (cl *Client) PrioritizeDataRegion(ih InfoHash, off, len_ int64) { for _, cn := range t.Conns { cl.replenishConnRequests(t, cn) } + return nil } type DataSpec struct { diff --git a/fs/torrentfs.go b/fs/torrentfs.go index 1c9567f0..fba0e09e 100644 --- a/fs/torrentfs.go +++ b/fs/torrentfs.go @@ -65,7 +65,9 @@ func (fn fileNode) Read(req *fuse.ReadRequest, resp *fuse.ReadResponse, intr fus infoHash := torrent.BytesInfoHash(fn.metaInfo.InfoHash) torrentOff := fn.TorrentOffset + req.Offset log.Print(torrentOff, len(data), fn.TorrentOffset) - fn.FS.Client.PrioritizeDataRegion(infoHash, torrentOff, int64(len(data))) + if err := fn.FS.Client.PrioritizeDataRegion(infoHash, torrentOff, int64(len(data))); err != nil { + panic(err) + } for { dataWaiter := fn.FS.Client.DataWaiter() n, err := fn.FS.Client.TorrentReadAt(infoHash, torrentOff, data) @@ -217,6 +219,7 @@ func (rootNode) Attr() fuse.Attr { } } +// TODO(anacrolix): Why should rootNode implement this? func (rootNode) Forget() { } diff --git a/torrent.go b/torrent.go index 5445eb97..d6279f2d 100644 --- a/torrent.go +++ b/torrent.go @@ -92,6 +92,18 @@ func torrentOffsetRequest(torrentLength, pieceSize, chunkSize, offset int64) ( return } +func torrentRequestOffset(torrentLength, pieceSize int64, r Request) (off int64) { + off = int64(r.Index)*pieceSize + int64(r.Begin) + if off < 0 || off >= torrentLength { + panic("invalid request") + } + return +} + +func (t *Torrent) requestOffset(r Request) int64 { + return torrentRequestOffset(t.Length(), t.MetaInfo.PieceLength, r) +} + // Return the request that would include the given offset into the torrent data. func (t *Torrent) offsetRequest(off int64) (req Request, ok bool) { return torrentOffsetRequest(t.Length(), t.MetaInfo.PieceLength, chunkSize, off) -- 2.48.1