code: func (r *bufferingReaderAt) readBlock(offset int64) (data []byte, err error) {
  	// Have it cached already?
  	if b, ok := r.lru.get(offset); ok {
  		data = b.data
  		if b.last {
  			err = io.EOF
  		}
  		return
  	}
  
  	// Kick out the oldest block (if any) to move its buffer to the free buffers
  	// pool and then immediately grab this buffer.
  	r.lru.prepareForAdd()
  	data = r.grabBuf()
  
  	// Read the block from the underlying reader.
  	read, err := r.r.ReadAt(data, offset)
  	data = data[:read]
  
  	// ReadAt promises that it returns nil only if it read the full block. We rely
  	// on this later, so double check.
  	if err == nil && read != r.blockSize {
  		panic(fmt.Sprintf("broken ReaderAt: should have read %d bytes, but read only %d", r.blockSize, read))
  	}
  
  	// Cache fully read blocks and the partially read last block, but skip blocks
  	// that were read partially due to unexpected errors.
  	if err == nil || err == io.EOF {
  		r.lru.add(block{
  			offset: offset,
  			data:   data,
  			last:   err == io.EOF,
  		})
  	} else {
  		// Caller promises not to retain 'data', so we can return it right away.
  		r.recycleBuf(data)
  	}
  
  	return data, err
  }
docs: // readBlock returns the block of the file (of blockSize size) at an offset.
  //
  // Assumes the caller does not retain the returned buffer (just reads from it
  // and forgets it right away, all under the lock).
  //
  // Returns one of:
  //   (full block, nil) on success
  //   (partial or full block, io.EOF) when reading the final block
  //   (partial block, err) on read errors