lock.writeLock().lock();
try {
//
// Is it already in the create process?
//
ActiveFile activeFile = volumeMap.getOngoingCreates(namespaceId, b);
if (activeFile != null) {
f = activeFile.file;
threads = activeFile.threads;
expectedFileSize = activeFile.getBytesOnDisk();
if (!isRecovery) {
throw new BlockAlreadyExistsException("Block " + b +
" has already been started (though not completed), and thus cannot be created.");
} else {
for (Thread thread:threads) {
thread.interrupt();
}
}
volumeMap.removeOngoingCreates(namespaceId, b);
}
FSVolume v = null;
if (!isRecovery) {
v = volumes.getNextVolume(blockSize);
// create temporary file to hold block in the designated volume
f = createTmpFile(namespaceId, v, b, replicationRequest);
} else if (f != null) {
DataNode.LOG.info("Reopen already-open Block for append " + b);
// create or reuse temporary file to hold block in the designated volume
v = volumeMap.get(namespaceId, b).getVolume();
volumeMap.add(namespaceId, b, new DatanodeBlockInfo(v, f,
DatanodeBlockInfo.UNFINALIZED));
} else {
// reopening block for appending to it.
DataNode.LOG.info("Reopen Block for append " + b);
v = volumeMap.get(namespaceId, b).getVolume();
f = createTmpFile(namespaceId, v, b, replicationRequest);
File blkfile = getBlockFile(namespaceId, b);
File oldmeta = getMetaFile(namespaceId, b);
File newmeta = getMetaFile(f, b);
// rename meta file to tmp directory
DataNode.LOG.debug("Renaming " + oldmeta + " to " + newmeta);
if (!oldmeta.renameTo(newmeta)) {
throw new IOException("Block " + b + " reopen failed. " +
" Unable to move meta file " + oldmeta +
" to tmp dir " + newmeta);
}
// rename block file to tmp directory
DataNode.LOG.debug("Renaming " + blkfile + " to " + f);
if (!blkfile.renameTo(f)) {
if (!f.delete()) {
throw new IOException("Block " + b + " reopen failed. " +
" Unable to remove file " + f);
}
if (!blkfile.renameTo(f)) {
throw new IOException("Block " + b + " reopen failed. " +
" Unable to move block file " + blkfile +
" to tmp dir " + f);
}
}
}
if (f == null) {
DataNode.LOG.warn("Block " + b + " reopen failed " +
" Unable to locate tmp file.");
throw new IOException("Block " + b + " reopen failed " +
" Unable to locate tmp file.");
}
// If this is a replication request, then this is not a permanent
// block yet, it could get removed if the datanode restarts. If this
// is a write or append request, then it is a valid block.
if (replicationRequest) {
volumeMap.add(namespaceId, b, new DatanodeBlockInfo(v));
} else {
volumeMap.add(namespaceId, b, new DatanodeBlockInfo(v, f, -1));
}
volumeMap.addOngoingCreates(namespaceId, b, new ActiveFile(f, threads,
expectedFileSize));
} finally {
lock.writeLock().unlock();
}