|
@@ -267,22 +267,28 @@ public class FSDirectory implements Closeable {
|
|
|
short replication,
|
|
|
long modificationTime,
|
|
|
long atime,
|
|
|
- long preferredBlockSize)
|
|
|
+ long preferredBlockSize,
|
|
|
+ String clientName,
|
|
|
+ String clientMachine)
|
|
|
throws UnresolvedLinkException {
|
|
|
INode newNode;
|
|
|
- long diskspace = UNKNOWN_DISK_SPACE;
|
|
|
assert hasWriteLock();
|
|
|
if (blocks == null)
|
|
|
newNode = new INodeDirectory(permissions, modificationTime);
|
|
|
- else {
|
|
|
+ else if(blocks.length == 0 || blocks[blocks.length-1].getBlockUCState()
|
|
|
+ == BlockUCState.UNDER_CONSTRUCTION) {
|
|
|
+ newNode = new INodeFileUnderConstruction(
|
|
|
+ permissions, blocks.length, replication,
|
|
|
+ preferredBlockSize, modificationTime, clientName,
|
|
|
+ clientMachine, null);
|
|
|
+ } else {
|
|
|
newNode = new INodeFile(permissions, blocks.length, replication,
|
|
|
modificationTime, atime, preferredBlockSize);
|
|
|
- diskspace = ((INodeFile)newNode).diskspaceConsumed(blocks);
|
|
|
}
|
|
|
writeLock();
|
|
|
try {
|
|
|
try {
|
|
|
- newNode = addNode(path, newNode, diskspace);
|
|
|
+ newNode = addNode(path, newNode, UNKNOWN_DISK_SPACE);
|
|
|
if(newNode != null && blocks != null) {
|
|
|
int nrBlocks = blocks.length;
|
|
|
// Add file->block mapping
|
|
@@ -301,6 +307,74 @@ public class FSDirectory implements Closeable {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Update files in-memory data structures with new block information.
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ void updateFile(INodeFile file,
|
|
|
+ String path,
|
|
|
+ PermissionStatus permissions,
|
|
|
+ BlockInfo[] blocks,
|
|
|
+ short replication,
|
|
|
+ long mtime,
|
|
|
+ long atime,
|
|
|
+ long preferredBlockSize) throws IOException {
|
|
|
+
|
|
|
+ // Update the salient file attributes.
|
|
|
+ file.setAccessTime(atime);
|
|
|
+ file.setModificationTimeForce(mtime);
|
|
|
+
|
|
|
+ // Update its block list
|
|
|
+ BlockInfo[] oldBlocks = file.getBlocks();
|
|
|
+
|
|
|
+ // Are we only updating the last block's gen stamp.
|
|
|
+ boolean isGenStampUpdate = oldBlocks.length == blocks.length;
|
|
|
+
|
|
|
+ // First, update blocks in common
|
|
|
+ BlockInfo oldBlock = null;
|
|
|
+ for (int i = 0; i < oldBlocks.length && i < blocks.length; i++) {
|
|
|
+ oldBlock = oldBlocks[i];
|
|
|
+ Block newBlock = blocks[i];
|
|
|
+
|
|
|
+ boolean isLastBlock = i == oldBlocks.length - 1;
|
|
|
+ if (oldBlock.getBlockId() != newBlock.getBlockId() ||
|
|
|
+ (oldBlock.getGenerationStamp() != newBlock.getGenerationStamp() &&
|
|
|
+ !(isGenStampUpdate && isLastBlock))) {
|
|
|
+ throw new IOException("Mismatched block IDs or generation stamps, " +
|
|
|
+ "attempting to replace block " + oldBlock + " with " + newBlock +
|
|
|
+ " as block # " + i + "/" + blocks.length + " of " + path);
|
|
|
+ }
|
|
|
+
|
|
|
+ oldBlock.setNumBytes(newBlock.getNumBytes());
|
|
|
+ oldBlock.setGenerationStamp(newBlock.getGenerationStamp());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (blocks.length < oldBlocks.length) {
|
|
|
+ // We're removing a block from the file, e.g. abandonBlock(...)
|
|
|
+ if (!file.isUnderConstruction()) {
|
|
|
+ throw new IOException("Trying to remove a block from file " +
|
|
|
+ path + " which is not under construction.");
|
|
|
+ }
|
|
|
+ if (blocks.length != oldBlocks.length - 1) {
|
|
|
+ throw new IOException("Trying to remove more than one block from file "
|
|
|
+ + path);
|
|
|
+ }
|
|
|
+ unprotectedRemoveBlock(path,
|
|
|
+ (INodeFileUnderConstruction)file, oldBlocks[oldBlocks.length - 1]);
|
|
|
+ } else if (blocks.length > oldBlocks.length) {
|
|
|
+ // We're adding blocks
|
|
|
+ // First complete last old Block
|
|
|
+ getBlockManager().completeBlock(file, oldBlocks.length-1, true);
|
|
|
+ // Add the new blocks
|
|
|
+ for (int i = oldBlocks.length; i < blocks.length; i++) {
|
|
|
+ // addBlock();
|
|
|
+ BlockInfo newBI = blocks[i];
|
|
|
+ getBlockManager().addINode(newBI, file);
|
|
|
+ file.addBlock(newBI);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
INodeDirectory addToParent(byte[] src, INodeDirectory parentINode,
|
|
|
INode newNode, boolean propagateModTime) throws UnresolvedLinkException {
|
|
|
// NOTE: This does not update space counts for parents
|
|
@@ -422,28 +496,33 @@ public class FSDirectory implements Closeable {
|
|
|
|
|
|
writeLock();
|
|
|
try {
|
|
|
- // modify file-> block and blocksMap
|
|
|
- fileNode.removeLastBlock(block);
|
|
|
- getBlockManager().removeBlockFromMap(block);
|
|
|
-
|
|
|
+ unprotectedRemoveBlock(path, fileNode, block);
|
|
|
// write modified block locations to log
|
|
|
fsImage.getEditLog().logOpenFile(path, fileNode);
|
|
|
- if(NameNode.stateChangeLog.isDebugEnabled()) {
|
|
|
- NameNode.stateChangeLog.debug("DIR* FSDirectory.removeBlock: "
|
|
|
- +path+" with "+block
|
|
|
- +" block is removed from the file system");
|
|
|
- }
|
|
|
-
|
|
|
- // update space consumed
|
|
|
- INode[] pathINodes = getExistingPathINodes(path);
|
|
|
- updateCount(pathINodes, pathINodes.length-1, 0,
|
|
|
- -fileNode.getPreferredBlockSize()*fileNode.getReplication(), true);
|
|
|
} finally {
|
|
|
writeUnlock();
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ void unprotectedRemoveBlock(String path, INodeFileUnderConstruction fileNode,
|
|
|
+ Block block) throws IOException {
|
|
|
+ // modify file-> block and blocksMap
|
|
|
+ fileNode.removeLastBlock(block);
|
|
|
+ getBlockManager().removeBlockFromMap(block);
|
|
|
+
|
|
|
+ if(NameNode.stateChangeLog.isDebugEnabled()) {
|
|
|
+ NameNode.stateChangeLog.debug("DIR* FSDirectory.removeBlock: "
|
|
|
+ +path+" with "+block
|
|
|
+ +" block is removed from the file system");
|
|
|
+ }
|
|
|
+
|
|
|
+ // update space consumed
|
|
|
+ INode[] pathINodes = getExistingPathINodes(path);
|
|
|
+ updateCount(pathINodes, pathINodes.length-1, 0,
|
|
|
+ -fileNode.getPreferredBlockSize()*fileNode.getReplication(), true);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* @see #unprotectedRenameTo(String, String, long)
|
|
|
* @deprecated Use {@link #renameTo(String, String, Rename...)} instead.
|