// cached block locations may have been updated by chooseDatNode()
// or fetchBlockAt(). Always get the latest list of locations at the
// start of the loop.
block = getBlockAt(block.getStartOffset(), false, true);
DNAddrPair retval = chooseDataNode(block);
DatanodeInfo chosenNode = retval.info;
InetSocketAddress targetAddr = retval.addr;
ByteBuffer result = null;
BlockReaderLocal localReader = null;
BlockReaderAccelerator remoteReader = null;
try {
if (DFSClient.LOG.isDebugEnabled()) {
DFSClient.LOG.debug("fetchBlockByteRangeScatterGather " +
" localhst " + dfsClient.localHost +
" targetAddr " + targetAddr);
}
// first try reading the block locally.
if (dfsClient.shortCircuitLocalReads &&
NetUtils.isLocalAddressWithCaching(targetAddr.getAddress())) {
localReader = BlockReaderLocal.newBlockReader(dfsClient.conf, src,
namespaceId, block.getBlock(),
chosenNode,
start,
len,
dfsClient.metrics,
verifyChecksum,
this.clearOsBuffer);
localReader.setReadLocal(true);
localReader.setFsStats(dfsClient.stats);
result = localReader.readAll();
} else {
// go to the datanode
dn = dfsClient.socketFactory.createSocket();
NetUtils.connect(dn, targetAddr, dfsClient.socketTimeout,
dfsClient.ipTosValue);
dn.setSoTimeout(dfsClient.socketTimeout);
remoteReader = new BlockReaderAccelerator(dfsClient.conf,
targetAddr,
chosenNode,
dfsClient.getDataTransferProtocolVersion(),
namespaceId, dfsClient.clientName,
dn, src,
block,
start, len,
verifyChecksum, dfsClient.metrics);
result = remoteReader.readAll();
}
if (result.remaining() != len) {
throw new IOException("truncated return from reader.read(): " +
"expected " + len + ", got " +
result.remaining());
}
if (NetUtils.isLocalAddress(targetAddr.getAddress())) {
dfsClient.stats.incrementLocalBytesRead(len);
dfsClient.stats.incrementRackLocalBytesRead(len);
} else if (dfsClient.isInLocalRack(targetAddr.getAddress())) {
dfsClient.stats.incrementRackLocalBytesRead(len);
}
return result;
} catch (ChecksumException e) {
DFSClient.LOG.warn("fetchBlockByteRangeScatterGather(). Got a checksum exception for " +
src + " at " + block.getBlock() + ":" +
e.getPos() + " from " + chosenNode.getName());
dfsClient.reportChecksumFailure(src, block.getBlock(), chosenNode);
} catch (IOException e) {
DFSClient.LOG.warn("Failed to connect to " + targetAddr +
" for file " + src +
" for block " + block.getBlock().getBlockId() + ":" +