boolean clearOsBuffer,
boolean positionalReadMode) throws IOException {
LocalDatanodeInfo localDatanodeInfo = getLocalDatanodeInfo(node);
BlockPathInfo pathinfo = localDatanodeInfo.getOrComputePathInfo(namespaceid,
blk, node, conf);
// Another alternative is for datanode to pass whether it is an inline checksum
// file and checksum metadata through BlockPathInfo, which is a cleaner approach.
// However, we need to worry more about protocol compatible issue. We avoid this
// trouble for now. We can always change to the other approach later.
//
boolean isInlineChecksum = Block.isInlineChecksumBlockFilename(new Path(
pathinfo.getBlockPath()).getName());
// check to see if the file exists. It may so happen that the
// HDFS file has been deleted and this block-lookup is occuring
// on behalf of a new HDFS file. This time, the block file could
// be residing in a different portion of the fs.data.dir directory.
// In this case, we remove this entry from the cache. The next
// call to this method will repopulate the cache.
try {
// get a local file system
FileChannel dataFileChannel;
FileDescriptor dataFileDescriptor;
File blkfile = new File(pathinfo.getBlockPath());
FileInputStream fis = new FileInputStream(blkfile);
dataFileChannel = fis.getChannel();
dataFileDescriptor = fis.getFD();
if (LOG.isDebugEnabled()) {
LOG.debug("New BlockReaderLocal for file " +
pathinfo.getBlockPath() + " of size " + blkfile.length() +
" startOffset " + startOffset +
" length " + length);
}
DataChecksum checksum = null;
if (isInlineChecksum) {
GenStampAndChecksum gac = BlockInlineChecksumReader
.getGenStampAndChecksumFromInlineChecksumFile(new Path(pathinfo
.getBlockPath()).getName());
checksum = DataChecksum.newDataChecksum(gac.getChecksumType(),
gac.getBytesPerChecksum());
if (verifyChecksum) {
return new BlockReaderLocalInlineChecksum(conf, file, blk,
startOffset, length, pathinfo, metrics, checksum, verifyChecksum,
dataFileChannel, dataFileDescriptor, clearOsBuffer,
positionalReadMode);
}
else {
return new BlockReaderLocalInlineChecksum(conf, file, blk,
startOffset, length, pathinfo, metrics, checksum,
dataFileChannel, dataFileDescriptor, clearOsBuffer,
positionalReadMode);
}
} else if (verifyChecksum) {
FileChannel checksumInChannel = null;
// get the metadata file
File metafile = new File(pathinfo.getMetaPath());
FileInputStream checksumIn = new FileInputStream(metafile);
checksumInChannel = checksumIn.getChannel();
// read and handle the common header here. For now just a version
BlockMetadataHeader header = BlockMetadataHeader.readHeader(
new DataInputStream(checksumIn), new NativeCrc32());
short version = header.getVersion();
if (version != FSDataset.FORMAT_VERSION_NON_INLINECHECKSUM) {
LOG.warn("Wrong version (" + version + ") for metadata file for "
+ blk + " ignoring ...");
}
checksum = header.getChecksum();
return new BlockReaderLocalWithChecksum(conf, file, blk, startOffset,
length, pathinfo, metrics, checksum, verifyChecksum,
dataFileChannel, dataFileDescriptor, checksumInChannel,
clearOsBuffer, positionalReadMode);
}
else {
return new BlockReaderLocalWithChecksum(conf, file, blk, startOffset,
length, pathinfo, metrics, dataFileChannel, dataFileDescriptor,
clearOsBuffer, positionalReadMode);
}
} catch (FileNotFoundException e) {
localDatanodeInfo.removeBlockLocalPathInfo(namespaceid, blk);
DFSClient.LOG.warn("BlockReaderLoca: Removing " + blk +
" from cache because local file " +
pathinfo.getBlockPath() +
" could not be opened.");
throw e;
}
}