code: func (r *reader) readOnceAt(b []byte, pos int64, ctxErr *error) (n int, err error) {
  	if pos >= r.length {
  		err = io.EOF
  		return
  	}
  	for {
  		avail := r.waitAvailable(pos, int64(len(b)), ctxErr)
  		if avail == 0 {
  			if r.t.closed.IsSet() {
  				err = errors.New("torrent closed")
  				return
  			}
  			if *ctxErr != nil {
  				err = *ctxErr
  				return
  			}
  		}
  		pi := pieceIndex(r.torrentOffset(pos) / r.t.info.PieceLength)
  		ip := r.t.info.Piece(pi)
  		po := r.torrentOffset(pos) % r.t.info.PieceLength
  		b1 := missinggo.LimitLen(b, ip.Length()-po, avail)
  		n, err = r.t.readAt(b1, r.torrentOffset(pos))
  		if n != 0 {
  			err = nil
  			return
  		}
  		r.t.cl.lock()
  		// TODO: Just reset pieces in the readahead window. This might help
  		// 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)
  		if !r.t.updatePieceCompletion(pi) {
  			log.Printf("piece %d completion unchanged", pi)
  		}
  		r.t.cl.unlock()
  	}
  }
docs: // Performs at most one successful read to torrent storage.