code: @Override
    public int transferTo(ByteBuf buf) throws IOException {
      Preconditions.checkState(!mClosed);
      if (mUnderFileSystemInputStream == null) {
        return -1;
      }
      if (mBlockMeta.getBlockSize() <= mInStreamPos) {
        return -1;
      }
     // Make a copy of the state to keep track of what we have read in this transferTo call.
      ByteBuf bufCopy = null;
      if (mBlockWriter != null) {
        bufCopy = buf.duplicate();
        bufCopy.readerIndex(bufCopy.writerIndex());
      }
      int bytesToRead =
          (int) Math.min(buf.writableBytes(), mBlockMeta.getBlockSize() - mInStreamPos);
      int bytesRead = buf.writeBytes(mUnderFileSystemInputStream, bytesToRead);
      if (bytesRead <= 0) {
        return bytesRead;
      }
  
      mInStreamPos += bytesRead;
  
      if (mBlockWriter != null && bufCopy != null) {
        try {
          bufCopy.writerIndex(buf.writerIndex());
          while (bufCopy.readableBytes() > 0) {
            mLocalBlockStore.requestSpace(mBlockMeta.getSessionId(), mBlockMeta.getBlockId(),
                mInStreamPos - mBlockWriter.getPosition());
            mBlockWriter.append(bufCopy);
          }
        } catch (Exception e) {
          LOG.warn("Failed to cache data read from UFS (on transferTo()): {}", e.getMessage());
          cancelBlockWriter();
        }
      }
  
      return bytesRead;
    }
docs: This interface is supposed to be used for sequence block reads.
  
  @param buf the byte buffer
  @return the number of bytes read, -1 if it reaches EOF and none was read