svn merge -c 1406006 from trunk for HDFS-4151. Change the methods in FSDirectory to pass INodesInPath instead of INode[] as a parameter.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-2802@1406014 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
b3bc2fb76e
commit
34413c2000
|
@ -146,11 +146,14 @@ Trunk (Unreleased)
|
||||||
HDFS-4110. Refine a log printed in JNStorage. (Liang Xie via suresh)
|
HDFS-4110. Refine a log printed in JNStorage. (Liang Xie via suresh)
|
||||||
|
|
||||||
HDFS-4124. Refactor INodeDirectory#getExistingPathINodes() to enable
|
HDFS-4124. Refactor INodeDirectory#getExistingPathINodes() to enable
|
||||||
returningmore than INode array. (Jing Zhao via suresh)
|
returning more than INode array. (Jing Zhao via suresh)
|
||||||
|
|
||||||
HDFS-4129. Add utility methods to dump NameNode in memory tree for
|
HDFS-4129. Add utility methods to dump NameNode in memory tree for
|
||||||
testing. (szetszwo via suresh)
|
testing. (szetszwo via suresh)
|
||||||
|
|
||||||
|
HDFS-4151. Change the methods in FSDirectory to pass INodesInPath instead
|
||||||
|
of INode[] as a parameter. (szetszwo)
|
||||||
|
|
||||||
OPTIMIZATIONS
|
OPTIMIZATIONS
|
||||||
|
|
||||||
BUG FIXES
|
BUG FIXES
|
||||||
|
|
|
@ -331,22 +331,18 @@ public class FSDirectory implements Closeable {
|
||||||
/**
|
/**
|
||||||
* Add a block to the file. Returns a reference to the added block.
|
* Add a block to the file. Returns a reference to the added block.
|
||||||
*/
|
*/
|
||||||
BlockInfo addBlock(String path,
|
BlockInfo addBlock(String path, INodesInPath inodesInPath, Block block,
|
||||||
INode[] inodes,
|
DatanodeDescriptor targets[]) throws IOException {
|
||||||
Block block,
|
|
||||||
DatanodeDescriptor targets[]
|
|
||||||
) throws QuotaExceededException {
|
|
||||||
waitForReady();
|
waitForReady();
|
||||||
|
|
||||||
writeLock();
|
writeLock();
|
||||||
try {
|
try {
|
||||||
assert inodes[inodes.length-1].isUnderConstruction() :
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
"INode should correspond to a file under construction";
|
final INodeFileUnderConstruction fileINode =
|
||||||
INodeFileUnderConstruction fileINode =
|
INodeFileUnderConstruction.valueOf(inodes[inodes.length-1], path);
|
||||||
(INodeFileUnderConstruction)inodes[inodes.length-1];
|
|
||||||
|
|
||||||
// check quota limits and updated space consumed
|
// check quota limits and updated space consumed
|
||||||
updateCount(inodes, inodes.length-1, 0,
|
updateCount(inodesInPath, inodes.length-1, 0,
|
||||||
fileINode.getPreferredBlockSize()*fileINode.getFileReplication(), true);
|
fileINode.getPreferredBlockSize()*fileINode.getFileReplication(), true);
|
||||||
|
|
||||||
// associate new last block for the file
|
// associate new last block for the file
|
||||||
|
@ -442,8 +438,9 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update space consumed
|
// update space consumed
|
||||||
INode[] pathINodes = getExistingPathINodes(path);
|
final INodesInPath inodesInPath = rootDir.getExistingPathINodes(path, true);
|
||||||
updateCount(pathINodes, pathINodes.length-1, 0,
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
|
updateCount(inodesInPath, inodes.length-1, 0,
|
||||||
-fileNode.getPreferredBlockSize()*fileNode.getFileReplication(), true);
|
-fileNode.getPreferredBlockSize()*fileNode.getFileReplication(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +508,8 @@ public class FSDirectory implements Closeable {
|
||||||
throws QuotaExceededException, UnresolvedLinkException,
|
throws QuotaExceededException, UnresolvedLinkException,
|
||||||
FileAlreadyExistsException {
|
FileAlreadyExistsException {
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
INode[] srcInodes = rootDir.getExistingPathINodes(src, false);
|
INodesInPath srcInodesInPath = rootDir.getExistingPathINodes(src, false);
|
||||||
|
INode[] srcInodes = srcInodesInPath.getINodes();
|
||||||
INode srcInode = srcInodes[srcInodes.length-1];
|
INode srcInode = srcInodes[srcInodes.length-1];
|
||||||
|
|
||||||
// check the validation of the source
|
// check the validation of the source
|
||||||
|
@ -574,7 +572,7 @@ public class FSDirectory implements Closeable {
|
||||||
String srcChildName = null;
|
String srcChildName = null;
|
||||||
try {
|
try {
|
||||||
// remove src
|
// remove src
|
||||||
srcChild = removeChild(srcInodes, srcInodes.length-1);
|
srcChild = removeChild(srcInodesInPath, srcInodes.length-1);
|
||||||
if (srcChild == null) {
|
if (srcChild == null) {
|
||||||
NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
|
NameNode.stateChangeLog.warn("DIR* FSDirectory.unprotectedRenameTo: "
|
||||||
+ "failed to rename " + src + " to " + dst
|
+ "failed to rename " + src + " to " + dst
|
||||||
|
@ -585,7 +583,7 @@ public class FSDirectory implements Closeable {
|
||||||
srcChild.setLocalName(dstComponents[dstInodes.length-1]);
|
srcChild.setLocalName(dstComponents[dstInodes.length-1]);
|
||||||
|
|
||||||
// add src to the destination
|
// add src to the destination
|
||||||
dstChild = addChildNoQuotaCheck(dstInodes, dstInodes.length - 1,
|
dstChild = addChildNoQuotaCheck(dstInodesInPath, dstInodes.length-1,
|
||||||
srcChild, UNKNOWN_DISK_SPACE);
|
srcChild, UNKNOWN_DISK_SPACE);
|
||||||
if (dstChild != null) {
|
if (dstChild != null) {
|
||||||
srcChild = null;
|
srcChild = null;
|
||||||
|
@ -602,7 +600,7 @@ public class FSDirectory implements Closeable {
|
||||||
if (dstChild == null && srcChild != null) {
|
if (dstChild == null && srcChild != null) {
|
||||||
// put it back
|
// put it back
|
||||||
srcChild.setLocalName(srcChildName);
|
srcChild.setLocalName(srcChildName);
|
||||||
addChildNoQuotaCheck(srcInodes, srcInodes.length - 1, srcChild,
|
addChildNoQuotaCheck(srcInodesInPath, srcInodes.length - 1, srcChild,
|
||||||
UNKNOWN_DISK_SPACE);
|
UNKNOWN_DISK_SPACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -635,7 +633,8 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String error = null;
|
String error = null;
|
||||||
final INode[] srcInodes = rootDir.getExistingPathINodes(src, false);
|
final INodesInPath srcInodesInPath = rootDir.getExistingPathINodes(src, false);
|
||||||
|
final INode[] srcInodes = srcInodesInPath.getINodes();
|
||||||
final INode srcInode = srcInodes[srcInodes.length - 1];
|
final INode srcInode = srcInodes[srcInodes.length - 1];
|
||||||
// validate source
|
// validate source
|
||||||
if (srcInode == null) {
|
if (srcInode == null) {
|
||||||
|
@ -721,7 +720,7 @@ public class FSDirectory implements Closeable {
|
||||||
|
|
||||||
// Ensure dst has quota to accommodate rename
|
// Ensure dst has quota to accommodate rename
|
||||||
verifyQuotaForRename(srcInodes, dstInodes);
|
verifyQuotaForRename(srcInodes, dstInodes);
|
||||||
INode removedSrc = removeChild(srcInodes, srcInodes.length - 1);
|
INode removedSrc = removeChild(srcInodesInPath, srcInodes.length - 1);
|
||||||
if (removedSrc == null) {
|
if (removedSrc == null) {
|
||||||
error = "Failed to rename " + src + " to " + dst
|
error = "Failed to rename " + src + " to " + dst
|
||||||
+ " because the source can not be removed";
|
+ " because the source can not be removed";
|
||||||
|
@ -734,14 +733,14 @@ public class FSDirectory implements Closeable {
|
||||||
INode removedDst = null;
|
INode removedDst = null;
|
||||||
try {
|
try {
|
||||||
if (dstInode != null) { // dst exists remove it
|
if (dstInode != null) { // dst exists remove it
|
||||||
removedDst = removeChild(dstInodes, dstInodes.length - 1);
|
removedDst = removeChild(dstInodesInPath, dstInodes.length - 1);
|
||||||
dstChildName = removedDst.getLocalName();
|
dstChildName = removedDst.getLocalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
INode dstChild = null;
|
INode dstChild = null;
|
||||||
removedSrc.setLocalName(dstComponents[dstInodes.length - 1]);
|
removedSrc.setLocalName(dstComponents[dstInodes.length - 1]);
|
||||||
// add src as dst to complete rename
|
// add src as dst to complete rename
|
||||||
dstChild = addChildNoQuotaCheck(dstInodes, dstInodes.length - 1,
|
dstChild = addChildNoQuotaCheck(dstInodesInPath, dstInodes.length - 1,
|
||||||
removedSrc, UNKNOWN_DISK_SPACE);
|
removedSrc, UNKNOWN_DISK_SPACE);
|
||||||
|
|
||||||
int filesDeleted = 0;
|
int filesDeleted = 0;
|
||||||
|
@ -769,13 +768,13 @@ public class FSDirectory implements Closeable {
|
||||||
if (removedSrc != null) {
|
if (removedSrc != null) {
|
||||||
// Rename failed - restore src
|
// Rename failed - restore src
|
||||||
removedSrc.setLocalName(srcChildName);
|
removedSrc.setLocalName(srcChildName);
|
||||||
addChildNoQuotaCheck(srcInodes, srcInodes.length - 1, removedSrc,
|
addChildNoQuotaCheck(srcInodesInPath, srcInodes.length - 1, removedSrc,
|
||||||
UNKNOWN_DISK_SPACE);
|
UNKNOWN_DISK_SPACE);
|
||||||
}
|
}
|
||||||
if (removedDst != null) {
|
if (removedDst != null) {
|
||||||
// Rename failed - restore dst
|
// Rename failed - restore dst
|
||||||
removedDst.setLocalName(dstChildName);
|
removedDst.setLocalName(dstChildName);
|
||||||
addChildNoQuotaCheck(dstInodes, dstInodes.length - 1, removedDst,
|
addChildNoQuotaCheck(dstInodesInPath, dstInodes.length - 1, removedDst,
|
||||||
UNKNOWN_DISK_SPACE);
|
UNKNOWN_DISK_SPACE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -815,7 +814,8 @@ public class FSDirectory implements Closeable {
|
||||||
UnresolvedLinkException {
|
UnresolvedLinkException {
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
|
|
||||||
INode[] inodes = rootDir.getExistingPathINodes(src, true);
|
final INodesInPath inodesInPath = rootDir.getExistingPathINodes(src, true);
|
||||||
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
INode inode = inodes[inodes.length - 1];
|
INode inode = inodes[inodes.length - 1];
|
||||||
if (inode == null) {
|
if (inode == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -829,7 +829,7 @@ public class FSDirectory implements Closeable {
|
||||||
|
|
||||||
// check disk quota
|
// check disk quota
|
||||||
long dsDelta = (replication - oldRepl) * (fileNode.diskspaceConsumed()/oldRepl);
|
long dsDelta = (replication - oldRepl) * (fileNode.diskspaceConsumed()/oldRepl);
|
||||||
updateCount(inodes, inodes.length-1, 0, dsDelta, true);
|
updateCount(inodesInPath, inodes.length-1, 0, dsDelta, true);
|
||||||
|
|
||||||
fileNode.setFileReplication(replication);
|
fileNode.setFileReplication(replication);
|
||||||
|
|
||||||
|
@ -959,7 +959,8 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
// do the move
|
// do the move
|
||||||
|
|
||||||
INode [] trgINodes = getExistingPathINodes(target);
|
final INodesInPath trgINodesInPath = rootDir.getExistingPathINodes(target, true);
|
||||||
|
final INode[] trgINodes = trgINodesInPath.getINodes();
|
||||||
INodeFile trgInode = (INodeFile) trgINodes[trgINodes.length-1];
|
INodeFile trgInode = (INodeFile) trgINodes[trgINodes.length-1];
|
||||||
INodeDirectory trgParent = (INodeDirectory)trgINodes[trgINodes.length-2];
|
INodeDirectory trgParent = (INodeDirectory)trgINodes[trgINodes.length-2];
|
||||||
|
|
||||||
|
@ -986,7 +987,7 @@ public class FSDirectory implements Closeable {
|
||||||
trgInode.setModificationTimeForce(timestamp);
|
trgInode.setModificationTimeForce(timestamp);
|
||||||
trgParent.setModificationTime(timestamp);
|
trgParent.setModificationTime(timestamp);
|
||||||
// update quota on the parent directory ('count' files removed, 0 space)
|
// update quota on the parent directory ('count' files removed, 0 space)
|
||||||
unprotectedUpdateCount(trgINodes, trgINodes.length-1, - count, 0);
|
unprotectedUpdateCount(trgINodesInPath, trgINodes.length-1, -count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1006,7 +1007,9 @@ public class FSDirectory implements Closeable {
|
||||||
int filesRemoved;
|
int filesRemoved;
|
||||||
writeLock();
|
writeLock();
|
||||||
try {
|
try {
|
||||||
INode[] inodes = rootDir.getExistingPathINodes(normalizePath(src), false);
|
final INodesInPath inodesInPath = rootDir.getExistingPathINodes(
|
||||||
|
normalizePath(src), false);
|
||||||
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
if (checkPathINodes(inodes, src) == 0) {
|
if (checkPathINodes(inodes, src) == 0) {
|
||||||
filesRemoved = 0;
|
filesRemoved = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1020,7 +1023,7 @@ public class FSDirectory implements Closeable {
|
||||||
+ " cannot be deleted since " + snapshotNode.getFullPathName()
|
+ " cannot be deleted since " + snapshotNode.getFullPathName()
|
||||||
+ " is snapshottable and already has snapshots");
|
+ " is snapshottable and already has snapshots");
|
||||||
}
|
}
|
||||||
filesRemoved = unprotectedDelete(inodes, collectedBlocks, now);
|
filesRemoved = unprotectedDelete(inodesInPath, collectedBlocks, now);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
writeUnlock();
|
writeUnlock();
|
||||||
|
@ -1084,11 +1087,13 @@ public class FSDirectory implements Closeable {
|
||||||
List<Block> collectedBlocks = new ArrayList<Block>();
|
List<Block> collectedBlocks = new ArrayList<Block>();
|
||||||
int filesRemoved = 0;
|
int filesRemoved = 0;
|
||||||
|
|
||||||
INode[] inodes = rootDir.getExistingPathINodes(normalizePath(src), false);
|
final INodesInPath inodesInPath = rootDir.getExistingPathINodes(
|
||||||
|
normalizePath(src), false);
|
||||||
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
if (checkPathINodes(inodes, src) == 0) {
|
if (checkPathINodes(inodes, src) == 0) {
|
||||||
filesRemoved = 0;
|
filesRemoved = 0;
|
||||||
} else {
|
} else {
|
||||||
filesRemoved = unprotectedDelete(inodes, collectedBlocks, mtime);
|
filesRemoved = unprotectedDelete(inodesInPath, collectedBlocks, mtime);
|
||||||
}
|
}
|
||||||
if (filesRemoved > 0) {
|
if (filesRemoved > 0) {
|
||||||
getFSNamesystem().removePathAndBlocks(src, collectedBlocks);
|
getFSNamesystem().removePathAndBlocks(src, collectedBlocks);
|
||||||
|
@ -1103,14 +1108,15 @@ public class FSDirectory implements Closeable {
|
||||||
* @param mtime the time the inode is removed
|
* @param mtime the time the inode is removed
|
||||||
* @return the number of inodes deleted; 0 if no inodes are deleted.
|
* @return the number of inodes deleted; 0 if no inodes are deleted.
|
||||||
*/
|
*/
|
||||||
int unprotectedDelete(INode[] inodes, List<Block> collectedBlocks,
|
int unprotectedDelete(INodesInPath inodesInPath, List<Block> collectedBlocks,
|
||||||
long mtime) {
|
long mtime) {
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
|
|
||||||
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
INode targetNode = inodes[inodes.length-1];
|
INode targetNode = inodes[inodes.length-1];
|
||||||
int pos = inodes.length - 1;
|
int pos = inodes.length - 1;
|
||||||
// Remove the node from the namespace
|
// Remove the node from the namespace
|
||||||
targetNode = removeChild(inodes, pos);
|
targetNode = removeChild(inodesInPath, pos);
|
||||||
if (targetNode == null) {
|
if (targetNode == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1300,28 +1306,6 @@ public class FSDirectory implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the existing INodes along the given path.
|
|
||||||
*
|
|
||||||
* @param path the path to explore
|
|
||||||
* @return INodes array containing the existing INodes in the order they
|
|
||||||
* appear when following the path from the root INode to the
|
|
||||||
* deepest INodes. The array size will be the number of expected
|
|
||||||
* components in the path, and non existing components will be
|
|
||||||
* filled with null
|
|
||||||
*
|
|
||||||
* @see INodeDirectory#getExistingPathINodes(byte[][], INode[])
|
|
||||||
*/
|
|
||||||
INode[] getExistingPathINodes(String path)
|
|
||||||
throws UnresolvedLinkException {
|
|
||||||
readLock();
|
|
||||||
try {
|
|
||||||
return rootDir.getExistingPathINodes(path, true);
|
|
||||||
} finally {
|
|
||||||
readUnlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the parent node of path.
|
* Get the parent node of path.
|
||||||
*
|
*
|
||||||
|
@ -1386,13 +1370,14 @@ public class FSDirectory implements Closeable {
|
||||||
UnresolvedLinkException {
|
UnresolvedLinkException {
|
||||||
writeLock();
|
writeLock();
|
||||||
try {
|
try {
|
||||||
INode[] inodes = rootDir.getExistingPathINodes(path, false);
|
final INodesInPath inodesInPath = rootDir.getExistingPathINodes(path, false);
|
||||||
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
int len = inodes.length;
|
int len = inodes.length;
|
||||||
if (inodes[len - 1] == null) {
|
if (inodes[len - 1] == null) {
|
||||||
throw new FileNotFoundException(path +
|
throw new FileNotFoundException(path +
|
||||||
" does not exist under rootDir.");
|
" does not exist under rootDir.");
|
||||||
}
|
}
|
||||||
updateCount(inodes, len-1, nsDelta, dsDelta, true);
|
updateCount(inodesInPath, len-1, nsDelta, dsDelta, true);
|
||||||
} finally {
|
} finally {
|
||||||
writeUnlock();
|
writeUnlock();
|
||||||
}
|
}
|
||||||
|
@ -1407,7 +1392,7 @@ public class FSDirectory implements Closeable {
|
||||||
* @param checkQuota if true then check if quota is exceeded
|
* @param checkQuota if true then check if quota is exceeded
|
||||||
* @throws QuotaExceededException if the new count violates any quota limit
|
* @throws QuotaExceededException if the new count violates any quota limit
|
||||||
*/
|
*/
|
||||||
private void updateCount(INode[] inodes, int numOfINodes,
|
private void updateCount(INodesInPath inodesInPath, int numOfINodes,
|
||||||
long nsDelta, long dsDelta, boolean checkQuota)
|
long nsDelta, long dsDelta, boolean checkQuota)
|
||||||
throws QuotaExceededException {
|
throws QuotaExceededException {
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
|
@ -1415,29 +1400,25 @@ public class FSDirectory implements Closeable {
|
||||||
//still initializing. do not check or update quotas.
|
//still initializing. do not check or update quotas.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (numOfINodes>inodes.length) {
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
|
if (numOfINodes > inodes.length) {
|
||||||
numOfINodes = inodes.length;
|
numOfINodes = inodes.length;
|
||||||
}
|
}
|
||||||
if (checkQuota) {
|
if (checkQuota) {
|
||||||
verifyQuota(inodes, numOfINodes, nsDelta, dsDelta, null);
|
verifyQuota(inodes, numOfINodes, nsDelta, dsDelta, null);
|
||||||
}
|
}
|
||||||
for(int i = 0; i < numOfINodes; i++) {
|
unprotectedUpdateCount(inodesInPath, numOfINodes, nsDelta, dsDelta);
|
||||||
if (inodes[i].isQuotaSet()) { // a directory with quota
|
|
||||||
INodeDirectoryWithQuota node =(INodeDirectoryWithQuota)inodes[i];
|
|
||||||
node.updateNumItemsInTree(nsDelta, dsDelta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* update quota of each inode and check to see if quota is exceeded.
|
* update quota of each inode and check to see if quota is exceeded.
|
||||||
* See {@link #updateCount(INode[], int, long, long, boolean)}
|
* See {@link #updateCount(INode[], int, long, long, boolean)}
|
||||||
*/
|
*/
|
||||||
private void updateCountNoQuotaCheck(INode[] inodes, int numOfINodes,
|
private void updateCountNoQuotaCheck(INodesInPath inodesInPath,
|
||||||
long nsDelta, long dsDelta) {
|
int numOfINodes, long nsDelta, long dsDelta) {
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
try {
|
try {
|
||||||
updateCount(inodes, numOfINodes, nsDelta, dsDelta, false);
|
updateCount(inodesInPath, numOfINodes, nsDelta, dsDelta, false);
|
||||||
} catch (QuotaExceededException e) {
|
} catch (QuotaExceededException e) {
|
||||||
NameNode.LOG.warn("FSDirectory.updateCountNoQuotaCheck - unexpected ", e);
|
NameNode.LOG.warn("FSDirectory.updateCountNoQuotaCheck - unexpected ", e);
|
||||||
}
|
}
|
||||||
|
@ -1451,9 +1432,10 @@ public class FSDirectory implements Closeable {
|
||||||
* @param nsDelta
|
* @param nsDelta
|
||||||
* @param dsDelta
|
* @param dsDelta
|
||||||
*/
|
*/
|
||||||
void unprotectedUpdateCount(INode[] inodes, int numOfINodes,
|
private void unprotectedUpdateCount(INodesInPath inodesInPath,
|
||||||
long nsDelta, long dsDelta) {
|
int numOfINodes, long nsDelta, long dsDelta) {
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
for(int i=0; i < numOfINodes; i++) {
|
for(int i=0; i < numOfINodes; i++) {
|
||||||
if (inodes[i].isQuotaSet()) { // a directory with quota
|
if (inodes[i].isQuotaSet()) { // a directory with quota
|
||||||
INodeDirectoryWithQuota node =(INodeDirectoryWithQuota)inodes[i];
|
INodeDirectoryWithQuota node =(INodeDirectoryWithQuota)inodes[i];
|
||||||
|
@ -1530,7 +1512,7 @@ public class FSDirectory implements Closeable {
|
||||||
StringBuilder pathbuilder = new StringBuilder();
|
StringBuilder pathbuilder = new StringBuilder();
|
||||||
int i = 1;
|
int i = 1;
|
||||||
for(; i < inodes.length && inodes[i] != null; i++) {
|
for(; i < inodes.length && inodes[i] != null; i++) {
|
||||||
pathbuilder.append(Path.SEPARATOR + names[i]);
|
pathbuilder.append(Path.SEPARATOR).append(names[i]);
|
||||||
if (!inodes[i].isDirectory()) {
|
if (!inodes[i].isDirectory()) {
|
||||||
throw new FileAlreadyExistsException("Parent path is not a directory: "
|
throw new FileAlreadyExistsException("Parent path is not a directory: "
|
||||||
+ pathbuilder+ " "+inodes[i].getLocalName());
|
+ pathbuilder+ " "+inodes[i].getLocalName());
|
||||||
|
@ -1572,8 +1554,7 @@ public class FSDirectory implements Closeable {
|
||||||
// create directories beginning from the first null index
|
// create directories beginning from the first null index
|
||||||
for(; i < inodes.length; i++) {
|
for(; i < inodes.length; i++) {
|
||||||
pathbuilder.append(Path.SEPARATOR + names[i]);
|
pathbuilder.append(Path.SEPARATOR + names[i]);
|
||||||
String cur = pathbuilder.toString();
|
unprotectedMkdir(inodesInPath, i, components[i],
|
||||||
unprotectedMkdir(inodes, i, components[i],
|
|
||||||
(i < lastInodeIndex) ? parentPermissions : permissions, now);
|
(i < lastInodeIndex) ? parentPermissions : permissions, now);
|
||||||
if (inodes[i] == null) {
|
if (inodes[i] == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1582,6 +1563,8 @@ public class FSDirectory implements Closeable {
|
||||||
// to match count of FilesDeleted metric.
|
// to match count of FilesDeleted metric.
|
||||||
if (getFSNamesystem() != null)
|
if (getFSNamesystem() != null)
|
||||||
NameNode.getNameNodeMetrics().incrFilesCreated();
|
NameNode.getNameNodeMetrics().incrFilesCreated();
|
||||||
|
|
||||||
|
final String cur = pathbuilder.toString();
|
||||||
fsImage.getEditLog().logMkDir(cur, inodes[i]);
|
fsImage.getEditLog().logMkDir(cur, inodes[i]);
|
||||||
if(NameNode.stateChangeLog.isDebugEnabled()) {
|
if(NameNode.stateChangeLog.isDebugEnabled()) {
|
||||||
NameNode.stateChangeLog.debug(
|
NameNode.stateChangeLog.debug(
|
||||||
|
@ -1602,30 +1585,30 @@ public class FSDirectory implements Closeable {
|
||||||
INodesInPath inodesInPath = rootDir.getExistingPathINodes(components,
|
INodesInPath inodesInPath = rootDir.getExistingPathINodes(components,
|
||||||
components.length, false);
|
components.length, false);
|
||||||
INode[] inodes = inodesInPath.getINodes();
|
INode[] inodes = inodesInPath.getINodes();
|
||||||
unprotectedMkdir(inodes, inodes.length-1, components[inodes.length-1],
|
final int pos = inodes.length - 1;
|
||||||
permissions, timestamp);
|
unprotectedMkdir(inodesInPath, pos, components[pos], permissions, timestamp);
|
||||||
return inodes[inodes.length-1];
|
return inodes[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** create a directory at index pos.
|
/** create a directory at index pos.
|
||||||
* The parent path to the directory is at [0, pos-1].
|
* The parent path to the directory is at [0, pos-1].
|
||||||
* All ancestors exist. Newly created one stored at index pos.
|
* All ancestors exist. Newly created one stored at index pos.
|
||||||
*/
|
*/
|
||||||
private void unprotectedMkdir(INode[] inodes, int pos,
|
private void unprotectedMkdir(INodesInPath inodesInPath, int pos,
|
||||||
byte[] name, PermissionStatus permission,
|
byte[] name, PermissionStatus permission,
|
||||||
long timestamp) throws QuotaExceededException {
|
long timestamp) throws QuotaExceededException {
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
inodes[pos] = addChild(inodes, pos,
|
final INodeDirectory dir = new INodeDirectory(name, permission, timestamp);
|
||||||
new INodeDirectory(name, permission, timestamp),
|
final INode inode = addChild(inodesInPath, pos, dir, -1, true);
|
||||||
-1);
|
inodesInPath.setINode(pos, inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add a node child to the namespace. The full path name of the node is src.
|
/** Add a node child to the namespace. The full path name of the node is src.
|
||||||
* childDiskspace should be -1, if unknown.
|
* childDiskspace should be -1, if unknown.
|
||||||
* QuotaExceededException is thrown if it violates quota limit */
|
* @throw QuotaExceededException is thrown if it violates quota limit
|
||||||
private <T extends INode> T addNode(String src, T child,
|
*/
|
||||||
long childDiskspace)
|
private <T extends INode> T addNode(String src, T child, long childDiskspace
|
||||||
throws QuotaExceededException, UnresolvedLinkException {
|
) throws QuotaExceededException, UnresolvedLinkException {
|
||||||
byte[][] components = INode.getPathComponents(src);
|
byte[][] components = INode.getPathComponents(src);
|
||||||
byte[] path = components[components.length-1];
|
byte[] path = components[components.length-1];
|
||||||
child.setLocalName(path);
|
child.setLocalName(path);
|
||||||
|
@ -1634,8 +1617,8 @@ public class FSDirectory implements Closeable {
|
||||||
try {
|
try {
|
||||||
INodesInPath inodesInPath = rootDir.getExistingPathINodes(components,
|
INodesInPath inodesInPath = rootDir.getExistingPathINodes(components,
|
||||||
components.length, false);
|
components.length, false);
|
||||||
INode[] inodes = inodesInPath.getINodes();
|
return addChild(inodesInPath, inodesInPath.getINodes().length-1, child,
|
||||||
return addChild(inodes, inodes.length-1, child, childDiskspace);
|
childDiskspace, true);
|
||||||
} finally {
|
} finally {
|
||||||
writeUnlock();
|
writeUnlock();
|
||||||
}
|
}
|
||||||
|
@ -1761,18 +1744,21 @@ public class FSDirectory implements Closeable {
|
||||||
|
|
||||||
/** Add a node child to the inodes at index pos.
|
/** Add a node child to the inodes at index pos.
|
||||||
* Its ancestors are stored at [0, pos-1].
|
* Its ancestors are stored at [0, pos-1].
|
||||||
* QuotaExceededException is thrown if it violates quota limit */
|
* @return the added node.
|
||||||
private <T extends INode> T addChild(INode[] pathComponents, int pos,
|
* @throw QuotaExceededException is thrown if it violates quota limit
|
||||||
|
*/
|
||||||
|
private <T extends INode> T addChild(INodesInPath inodesInPath, int pos,
|
||||||
T child, long childDiskspace,
|
T child, long childDiskspace,
|
||||||
boolean checkQuota) throws QuotaExceededException {
|
boolean checkQuota) throws QuotaExceededException {
|
||||||
// The filesystem limits are not really quotas, so this check may appear
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
// odd. It's because a rename operation deletes the src, tries to add
|
// The filesystem limits are not really quotas, so this check may appear
|
||||||
// to the dest, if that fails, re-adds the src from whence it came.
|
// odd. It's because a rename operation deletes the src, tries to add
|
||||||
// The rename code disables the quota when it's restoring to the
|
// to the dest, if that fails, re-adds the src from whence it came.
|
||||||
// original location becase a quota violation would cause the the item
|
// The rename code disables the quota when it's restoring to the
|
||||||
// to go "poof". The fs limits must be bypassed for the same reason.
|
// original location becase a quota violation would cause the the item
|
||||||
|
// to go "poof". The fs limits must be bypassed for the same reason.
|
||||||
if (checkQuota) {
|
if (checkQuota) {
|
||||||
verifyFsLimits(pathComponents, pos, child);
|
verifyFsLimits(inodes, pos, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
INode.DirCounts counts = new INode.DirCounts();
|
INode.DirCounts counts = new INode.DirCounts();
|
||||||
|
@ -1780,31 +1766,22 @@ public class FSDirectory implements Closeable {
|
||||||
if (childDiskspace < 0) {
|
if (childDiskspace < 0) {
|
||||||
childDiskspace = counts.getDsCount();
|
childDiskspace = counts.getDsCount();
|
||||||
}
|
}
|
||||||
updateCount(pathComponents, pos, counts.getNsCount(), childDiskspace,
|
updateCount(inodesInPath, pos, counts.getNsCount(), childDiskspace, checkQuota);
|
||||||
checkQuota);
|
if (inodes[pos-1] == null) {
|
||||||
if (pathComponents[pos-1] == null) {
|
|
||||||
throw new NullPointerException("Panic: parent does not exist");
|
throw new NullPointerException("Panic: parent does not exist");
|
||||||
}
|
}
|
||||||
T addedNode = ((INodeDirectory)pathComponents[pos-1]).addChild(
|
final T addedNode = ((INodeDirectory)inodes[pos-1]).addChild(child, true);
|
||||||
child, true);
|
|
||||||
if (addedNode == null) {
|
if (addedNode == null) {
|
||||||
updateCount(pathComponents, pos, -counts.getNsCount(),
|
updateCount(inodesInPath, pos, -counts.getNsCount(), -childDiskspace, true);
|
||||||
-childDiskspace, true);
|
|
||||||
}
|
}
|
||||||
return addedNode;
|
return addedNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends INode> T addChild(INode[] pathComponents, int pos,
|
private <T extends INode> T addChildNoQuotaCheck(INodesInPath inodesInPath,
|
||||||
T child, long childDiskspace)
|
|
||||||
throws QuotaExceededException {
|
|
||||||
return addChild(pathComponents, pos, child, childDiskspace, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T extends INode> T addChildNoQuotaCheck(INode[] pathComponents,
|
|
||||||
int pos, T child, long childDiskspace) {
|
int pos, T child, long childDiskspace) {
|
||||||
T inode = null;
|
T inode = null;
|
||||||
try {
|
try {
|
||||||
inode = addChild(pathComponents, pos, child, childDiskspace, false);
|
inode = addChild(inodesInPath, pos, child, childDiskspace, false);
|
||||||
} catch (QuotaExceededException e) {
|
} catch (QuotaExceededException e) {
|
||||||
NameNode.LOG.warn("FSDirectory.addChildNoQuotaCheck - unexpected", e);
|
NameNode.LOG.warn("FSDirectory.addChildNoQuotaCheck - unexpected", e);
|
||||||
}
|
}
|
||||||
|
@ -1816,13 +1793,13 @@ public class FSDirectory implements Closeable {
|
||||||
* Count of each ancestor with quota is also updated.
|
* Count of each ancestor with quota is also updated.
|
||||||
* Return the removed node; null if the removal fails.
|
* Return the removed node; null if the removal fails.
|
||||||
*/
|
*/
|
||||||
private INode removeChild(INode[] pathComponents, int pos) {
|
private INode removeChild(final INodesInPath inodesInPath, int pos) {
|
||||||
INode removedNode =
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
((INodeDirectory)pathComponents[pos-1]).removeChild(pathComponents[pos]);
|
INode removedNode = ((INodeDirectory)inodes[pos-1]).removeChild(inodes[pos]);
|
||||||
if (removedNode != null) {
|
if (removedNode != null) {
|
||||||
INode.DirCounts counts = new INode.DirCounts();
|
INode.DirCounts counts = new INode.DirCounts();
|
||||||
removedNode.spaceConsumedInTree(counts);
|
removedNode.spaceConsumedInTree(counts);
|
||||||
updateCountNoQuotaCheck(pathComponents, pos,
|
updateCountNoQuotaCheck(inodesInPath, pos,
|
||||||
-counts.getNsCount(), -counts.getDsCount());
|
-counts.getNsCount(), -counts.getDsCount());
|
||||||
}
|
}
|
||||||
return removedNode;
|
return removedNode;
|
||||||
|
@ -1957,7 +1934,8 @@ public class FSDirectory implements Closeable {
|
||||||
|
|
||||||
String srcs = normalizePath(src);
|
String srcs = normalizePath(src);
|
||||||
|
|
||||||
INode[] inodes = rootDir.getExistingPathINodes(src, true);
|
final INodesInPath inodesInPath = rootDir.getExistingPathINodes(src, true);
|
||||||
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
INode targetNode = inodes[inodes.length-1];
|
INode targetNode = inodes[inodes.length-1];
|
||||||
if (targetNode == null) {
|
if (targetNode == null) {
|
||||||
throw new FileNotFoundException("Directory does not exist: " + srcs);
|
throw new FileNotFoundException("Directory does not exist: " + srcs);
|
||||||
|
|
|
@ -159,6 +159,7 @@ import org.apache.hadoop.hdfs.server.common.Storage;
|
||||||
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirType;
|
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirType;
|
||||||
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory;
|
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory;
|
||||||
import org.apache.hadoop.hdfs.server.common.Util;
|
import org.apache.hadoop.hdfs.server.common.Util;
|
||||||
|
import org.apache.hadoop.hdfs.server.namenode.INodeDirectory.INodesInPath;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease;
|
import org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.NameNode.OperationCategory;
|
import org.apache.hadoop.hdfs.server.namenode.NameNode.OperationCategory;
|
||||||
import org.apache.hadoop.hdfs.server.namenode.ha.ActiveState;
|
import org.apache.hadoop.hdfs.server.namenode.ha.ActiveState;
|
||||||
|
@ -1674,7 +1675,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Verify that parent directory of src exists.
|
* Verify that parent directory of src exists.
|
||||||
*/
|
*/
|
||||||
private void verifyParentDir(String src) throws FileNotFoundException,
|
private void verifyParentDir(String src) throws FileNotFoundException,
|
||||||
|
@ -1682,14 +1683,13 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
assert hasReadOrWriteLock();
|
assert hasReadOrWriteLock();
|
||||||
Path parent = new Path(src).getParent();
|
Path parent = new Path(src).getParent();
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
INode[] pathINodes = dir.getExistingPathINodes(parent.toString());
|
final INode parentNode = dir.getINode(parent.toString());
|
||||||
INode parentNode = pathINodes[pathINodes.length - 1];
|
|
||||||
if (parentNode == null) {
|
if (parentNode == null) {
|
||||||
throw new FileNotFoundException("Parent directory doesn't exist: "
|
throw new FileNotFoundException("Parent directory doesn't exist: "
|
||||||
+ parent.toString());
|
+ parent);
|
||||||
} else if (!parentNode.isDirectory() && !parentNode.isSymlink()) {
|
} else if (!parentNode.isDirectory() && !parentNode.isSymlink()) {
|
||||||
throw new ParentNotDirectoryException("Parent path is not a directory: "
|
throw new ParentNotDirectoryException("Parent path is not a directory: "
|
||||||
+ parent.toString());
|
+ parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2209,18 +2209,18 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
if (isInSafeMode()) {
|
if (isInSafeMode()) {
|
||||||
throw new SafeModeException("Cannot add block to " + src, safeMode);
|
throw new SafeModeException("Cannot add block to " + src, safeMode);
|
||||||
}
|
}
|
||||||
INode[] pathINodes = dir.getExistingPathINodes(src);
|
|
||||||
int inodesLen = pathINodes.length;
|
final INodesInPath inodesInPath = dir.rootDir.getExistingPathINodes(src, true);
|
||||||
checkLease(src, clientName, pathINodes[inodesLen-1]);
|
final INode[] inodes = inodesInPath.getINodes();
|
||||||
INodeFileUnderConstruction pendingFile = (INodeFileUnderConstruction)
|
final INodeFileUnderConstruction pendingFile
|
||||||
pathINodes[inodesLen - 1];
|
= checkLease(src, clientName, inodes[inodes.length - 1]);
|
||||||
|
|
||||||
if (!checkFileProgress(pendingFile, false)) {
|
if (!checkFileProgress(pendingFile, false)) {
|
||||||
throw new NotReplicatedYetException("Not replicated yet:" + src);
|
throw new NotReplicatedYetException("Not replicated yet:" + src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate new block record block locations in INode.
|
// allocate new block record block locations in INode.
|
||||||
newBlock = allocateBlock(src, pathINodes, targets);
|
newBlock = allocateBlock(src, inodesInPath, targets);
|
||||||
|
|
||||||
for (DatanodeDescriptor dn : targets) {
|
for (DatanodeDescriptor dn : targets) {
|
||||||
dn.incBlocksScheduled();
|
dn.incBlocksScheduled();
|
||||||
|
@ -2431,14 +2431,12 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
* Allocate a block at the given pending filename
|
* Allocate a block at the given pending filename
|
||||||
*
|
*
|
||||||
* @param src path to the file
|
* @param src path to the file
|
||||||
* @param inodes INode representing each of the components of src.
|
* @param inodesInPath representing each of the components of src.
|
||||||
* <code>inodes[inodes.length-1]</code> is the INode for the file.
|
* The last INode is the INode for the file.
|
||||||
*
|
|
||||||
* @throws QuotaExceededException If addition of block exceeds space quota
|
* @throws QuotaExceededException If addition of block exceeds space quota
|
||||||
*/
|
*/
|
||||||
private Block allocateBlock(String src, INode[] inodes,
|
private Block allocateBlock(String src, INodesInPath inodesInPath,
|
||||||
DatanodeDescriptor targets[]) throws QuotaExceededException,
|
DatanodeDescriptor targets[]) throws IOException {
|
||||||
SafeModeException {
|
|
||||||
assert hasWriteLock();
|
assert hasWriteLock();
|
||||||
Block b = new Block(DFSUtil.getRandom().nextLong(), 0, 0);
|
Block b = new Block(DFSUtil.getRandom().nextLong(), 0, 0);
|
||||||
while(isValidBlock(b)) {
|
while(isValidBlock(b)) {
|
||||||
|
@ -2447,7 +2445,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
||||||
// Increment the generation stamp for every new block.
|
// Increment the generation stamp for every new block.
|
||||||
nextGenerationStamp();
|
nextGenerationStamp();
|
||||||
b.setGenerationStamp(getGenerationStamp());
|
b.setGenerationStamp(getGenerationStamp());
|
||||||
b = dir.addBlock(src, inodes, b, targets);
|
b = dir.addBlock(src, inodesInPath, b, targets);
|
||||||
NameNode.stateChangeLog.info("BLOCK* allocateBlock: " + src + ". "
|
NameNode.stateChangeLog.info("BLOCK* allocateBlock: " + src + ". "
|
||||||
+ blockPoolId + " " + b);
|
+ blockPoolId + " " + b);
|
||||||
return b;
|
return b;
|
||||||
|
|
|
@ -121,7 +121,7 @@ class FSPermissionChecker {
|
||||||
}
|
}
|
||||||
// check if (parentAccess != null) && file exists, then check sb
|
// check if (parentAccess != null) && file exists, then check sb
|
||||||
// Resolve symlinks, the check is performed on the link target.
|
// Resolve symlinks, the check is performed on the link target.
|
||||||
INode[] inodes = root.getExistingPathINodes(path, true);
|
final INode[] inodes = root.getExistingPathINodes(path, true).getINodes();
|
||||||
int ancestorIndex = inodes.length - 2;
|
int ancestorIndex = inodes.length - 2;
|
||||||
for(; ancestorIndex >= 0 && inodes[ancestorIndex] == null;
|
for(; ancestorIndex >= 0 && inodes[ancestorIndex] == null;
|
||||||
ancestorIndex--);
|
ancestorIndex--);
|
||||||
|
|
|
@ -284,14 +284,12 @@ public class INodeDirectory extends INode {
|
||||||
* components in the path, and non existing components will be
|
* components in the path, and non existing components will be
|
||||||
* filled with null
|
* filled with null
|
||||||
*
|
*
|
||||||
* @see #getExistingPathINodes(byte[][], INode[])
|
* @see #getExistingPathINodes(byte[][], int, boolean)
|
||||||
*/
|
*/
|
||||||
INode[] getExistingPathINodes(String path, boolean resolveLink)
|
INodesInPath getExistingPathINodes(String path, boolean resolveLink)
|
||||||
throws UnresolvedLinkException {
|
throws UnresolvedLinkException {
|
||||||
byte[][] components = getPathComponents(path);
|
byte[][] components = getPathComponents(path);
|
||||||
INodesInPath inodes = this.getExistingPathINodes(components,
|
return getExistingPathINodes(components, components.length, resolveLink);
|
||||||
components.length, resolveLink);
|
|
||||||
return inodes.inodes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -563,6 +561,10 @@ public class INodeDirectory extends INode {
|
||||||
inodes[size++] = node;
|
inodes[size++] = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setINode(int i, INode inode) {
|
||||||
|
inodes[i] = inode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The number of non-null elements
|
* @return The number of non-null elements
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue