long startOffset = header.getStartOffset();
long length = header.getLen();
String clientName = header.getClientName();
reuseConnection = header.getReuseConnection();
boolean shouldProfile = header.getShouldProfile();
FSDataNodeReadProfilingData dnData = shouldProfile ?
new FSDataNodeReadProfilingData() : null;
if (shouldProfile) {
dnData.readVersionAndOpCodeTime = (startNanoTime - receiverStartTime) ;
dnData.readBlockHeaderTime = (System.nanoTime() - startNanoTime);
dnData.startProfiling();
}
// send the block
OutputStream baseStream = NetUtils.getOutputStream(s,
datanode.socketWriteTimeout);
DataOutputStream out = new DataOutputStream(
new BufferedOutputStream(baseStream, SMALL_BUFFER_SIZE));
BlockSender blockSender = null;
String clientTraceFmt = null;
if (ClientTraceLog.isInfoEnabled()) {
if (remoteAddress == null) {
getAddresses();
}
clientTraceFmt = clientName.length() > 0 ? String.format(
DN_CLIENTTRACE_FORMAT, localAddress, remoteAddress, "%d",
"HDFS_READ", clientName, "%d",
datanode.getDNRegistrationForNS(namespaceId).getStorageID(), block,
"%d")
:
datanode.getDNRegistrationForNS(namespaceId)
+ " Served block " + block + " to " + s.getInetAddress();
}
updateCurrentThreadName("sending block " + block);
InjectionHandler.processEvent(InjectionEvent.DATANODE_READ_BLOCK);
try {
try {
blockSender = new BlockSender(namespaceId, block, startOffset, length,
datanode.ignoreChecksumWhenRead, true, true, false,
versionAndOpcode.getDataTransferVersion() >=
DataTransferProtocol.PACKET_INCLUDE_VERSION_VERSION,
false, datanode, clientTraceFmt);
if (shouldProfile) {
blockSender.enableReadProfiling(dnData);
}
} catch(IOException e) {
sendResponse(s, (short) DataTransferProtocol.OP_STATUS_ERROR,
datanode.socketWriteTimeout);
throw e;
}
if (ClientTraceLog.isInfoEnabled()) {
ClientTraceLog.info("Sending blocks. namespaceId: "
+ namespaceId + " block: " + block + " to " + remoteAddress);
}
out.writeShort(DataTransferProtocol.OP_STATUS_SUCCESS); // send op status
if (shouldProfile) {
dnData.startSendBlock();
}
long read = blockSender.sendBlock(out, baseStream, null); // send data
if (shouldProfile) {
dnData.endSendBlock();
}
// report finalization information and block length.
ReplicaToRead replicaRead = blockSender.getReplicaToRead();
if (replicaRead == null) {
replicaRead = datanode.data.getReplicaToRead(namespaceId, block);
}
if (replicaRead == null) {
throw new IOException("Can't find block " + block + " in volumeMap");
}
int fadvise = header.getReadOptions().getFadvise();
if (fadvise != 0) {
blockSender.fadviseStream(fadvise, startOffset, length);
}
boolean isBlockFinalized = replicaRead.isFinalized();
long blockLength = replicaRead.getBytesVisible();
out.writeBoolean(isBlockFinalized);
out.writeLong(blockLength);
if (shouldProfile) {
dnData.write(out);
}
out.flush();
if (blockSender.didSendEntireByteRange()) {
// See if client verification succeeded.