HDFS-4189. Renames the getMutableXxx methods to getXxx4Write and fix a bug that some getExistingPathINodes calls should be getINodesInPath4Write.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/HDFS-2802@1441193 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tsz-wo Sze 2013-01-31 21:13:04 +00:00
parent f352b4ce0c
commit 2372e394dd
8 changed files with 87 additions and 123 deletions

View File

@ -134,5 +134,9 @@ Branch-2802 Snapshot (Unreleased)
HDFS-4131. Add capability to namenode to get snapshot diff. (Jing Zhao via HDFS-4131. Add capability to namenode to get snapshot diff. (Jing Zhao via
suresh) suresh)
HDFS-4447. Refactor INodeDirectoryWithSnapshot for support general INode diff HDFS-4447. Refactor INodeDirectoryWithSnapshot for supporting general INode
lists. (szetszwo) diff lists. (szetszwo)
HDFS-4189. Renames the getMutableXxx methods to getXxx4Write and fix a bug
that some getExistingPathINodes calls should be getINodesInPath4Write.
(szetszwo)

View File

@ -330,12 +330,11 @@ public class FSDirectory implements Closeable {
writeLock(); writeLock();
try { try {
final INode[] inodes = inodesInPath.getINodes();
final INodeFileUnderConstruction fileINode = final INodeFileUnderConstruction fileINode =
INodeFileUnderConstruction.valueOf(inodes[inodes.length-1], path); INodeFileUnderConstruction.valueOf(inodesInPath.getLastINode(), path);
// check quota limits and updated space consumed // check quota limits and updated space consumed
updateCount(inodesInPath, inodes.length-1, 0, updateCount(inodesInPath, 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
@ -426,9 +425,8 @@ public class FSDirectory implements Closeable {
} }
// update space consumed // update space consumed
final INodesInPath inodesInPath = rootDir.getExistingPathINodes(path, true); final INodesInPath iip = rootDir.getINodesInPath4Write(path, true);
final INode[] inodes = inodesInPath.getINodes(); updateCount(iip, 0,
updateCount(inodesInPath, inodes.length-1, 0,
-fileNode.getPreferredBlockSize()*fileNode.getFileReplication(), true); -fileNode.getPreferredBlockSize()*fileNode.getFileReplication(), true);
} }
@ -498,7 +496,7 @@ public class FSDirectory implements Closeable {
throws QuotaExceededException, UnresolvedLinkException, throws QuotaExceededException, UnresolvedLinkException,
FileAlreadyExistsException, SnapshotAccessControlException { FileAlreadyExistsException, SnapshotAccessControlException {
assert hasWriteLock(); assert hasWriteLock();
INodesInPath srcInodesInPath = rootDir.getMutableINodesInPath(src, false); INodesInPath srcInodesInPath = rootDir.getINodesInPath4Write(src, false);
INode[] srcInodes = srcInodesInPath.getINodes(); INode[] srcInodes = srcInodesInPath.getINodes();
INode srcInode = srcInodes[srcInodes.length-1]; INode srcInode = srcInodes[srcInodes.length-1];
@ -629,7 +627,7 @@ public class FSDirectory implements Closeable {
} }
} }
String error = null; String error = null;
final INodesInPath srcInodesInPath = rootDir.getMutableINodesInPath(src, final INodesInPath srcInodesInPath = rootDir.getINodesInPath4Write(src,
false); false);
final INode[] srcInodes = srcInodesInPath.getINodes(); final INode[] srcInodes = srcInodesInPath.getINodes();
final INode srcInode = srcInodes[srcInodes.length - 1]; final INode srcInode = srcInodes[srcInodes.length - 1];
@ -666,9 +664,8 @@ public class FSDirectory implements Closeable {
+ error); + error);
throw new IOException(error); throw new IOException(error);
} }
final byte[][] dstComponents = INode.getPathComponents(dst); final INodesInPath dstInodesInPath = rootDir.getINodesInPath4Write(
final INodesInPath dstInodesInPath = rootDir.getMutableINodesInPath( dst, false);
dstComponents, false);
final INode[] dstInodes = dstInodesInPath.getINodes(); final INode[] dstInodes = dstInodesInPath.getINodes();
INode dstInode = dstInodes[dstInodes.length - 1]; INode dstInode = dstInodes[dstInodes.length - 1];
if (dstInodes.length == 1) { if (dstInodes.length == 1) {
@ -747,7 +744,7 @@ public class FSDirectory implements Closeable {
dstChildName = removedDst.getLocalNameBytes(); dstChildName = removedDst.getLocalNameBytes();
} }
removedSrc.setLocalName(dstComponents[dstInodes.length - 1]); removedSrc.setLocalName(dstInodesInPath.getLastLocalName());
// add src as dst to complete rename // add src as dst to complete rename
if (addLastINodeNoQuotaCheck(dstInodesInPath, removedSrc)) { if (addLastINodeNoQuotaCheck(dstInodesInPath, removedSrc)) {
removedSrc = null; removedSrc = null;
@ -828,7 +825,7 @@ public class FSDirectory implements Closeable {
UnresolvedLinkException, SnapshotAccessControlException { UnresolvedLinkException, SnapshotAccessControlException {
assert hasWriteLock(); assert hasWriteLock();
final INodesInPath inodesInPath = rootDir.getMutableINodesInPath(src, true); final INodesInPath inodesInPath = rootDir.getINodesInPath4Write(src, true);
final INode[] inodes = inodesInPath.getINodes(); final INode[] inodes = inodesInPath.getINodes();
INode inode = inodes[inodes.length - 1]; INode inode = inodes[inodes.length - 1];
if (inode == null || !inode.isFile()) { if (inode == null || !inode.isFile()) {
@ -839,7 +836,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(inodesInPath, inodes.length-1, 0, dsDelta, true); updateCount(inodesInPath, 0, dsDelta, true);
fileNode.setFileReplication(replication, inodesInPath.getLatestSnapshot()); fileNode.setFileReplication(replication, inodesInPath.getLatestSnapshot());
@ -877,23 +874,6 @@ public class FSDirectory implements Closeable {
readUnlock(); readUnlock();
} }
} }
boolean existsMutable(String src) throws UnresolvedLinkException,
SnapshotAccessControlException {
src = normalizePath(src);
readLock();
try {
INode inode = rootDir.getMutableNode(src, false);
if (inode == null) {
return false;
}
return inode.isDirectory() || inode.isSymlink()
? true
: ((INodeFile)inode).getBlocks() != null;
} finally {
readUnlock();
}
}
void setPermission(String src, FsPermission permission) void setPermission(String src, FsPermission permission)
throws FileNotFoundException, UnresolvedLinkException, throws FileNotFoundException, UnresolvedLinkException,
@ -911,7 +891,7 @@ public class FSDirectory implements Closeable {
throws FileNotFoundException, UnresolvedLinkException, throws FileNotFoundException, UnresolvedLinkException,
SnapshotAccessControlException { SnapshotAccessControlException {
assert hasWriteLock(); assert hasWriteLock();
final INodesInPath inodesInPath = rootDir.getMutableINodesInPath(src, true); final INodesInPath inodesInPath = rootDir.getINodesInPath4Write(src, true);
final INode inode = inodesInPath.getLastINode(); final INode inode = inodesInPath.getLastINode();
if (inode == null) { if (inode == null) {
throw new FileNotFoundException("File does not exist: " + src); throw new FileNotFoundException("File does not exist: " + src);
@ -935,7 +915,7 @@ public class FSDirectory implements Closeable {
throws FileNotFoundException, UnresolvedLinkException, throws FileNotFoundException, UnresolvedLinkException,
SnapshotAccessControlException { SnapshotAccessControlException {
assert hasWriteLock(); assert hasWriteLock();
final INodesInPath inodesInPath = rootDir.getMutableINodesInPath(src, true); final INodesInPath inodesInPath = rootDir.getINodesInPath4Write(src, true);
INode inode = inodesInPath.getLastINode(); INode inode = inodesInPath.getLastINode();
if (inode == null) { if (inode == null) {
throw new FileNotFoundException("File does not exist: " + src); throw new FileNotFoundException("File does not exist: " + src);
@ -952,7 +932,7 @@ public class FSDirectory implements Closeable {
* Concat all the blocks from srcs to trg and delete the srcs files * Concat all the blocks from srcs to trg and delete the srcs files
*/ */
public void concat(String target, String [] srcs) public void concat(String target, String [] srcs)
throws UnresolvedLinkException { throws UnresolvedLinkException, SnapshotAccessControlException {
writeLock(); writeLock();
try { try {
// actual move // actual move
@ -976,14 +956,14 @@ public class FSDirectory implements Closeable {
* NOTE: - it does not update quota (not needed for concat) * NOTE: - it does not update quota (not needed for concat)
*/ */
public void unprotectedConcat(String target, String [] srcs, long timestamp) public void unprotectedConcat(String target, String [] srcs, long timestamp)
throws UnresolvedLinkException { throws UnresolvedLinkException, SnapshotAccessControlException {
assert hasWriteLock(); assert hasWriteLock();
if (NameNode.stateChangeLog.isDebugEnabled()) { if (NameNode.stateChangeLog.isDebugEnabled()) {
NameNode.stateChangeLog.debug("DIR* FSNamesystem.concat to "+target); NameNode.stateChangeLog.debug("DIR* FSNamesystem.concat to "+target);
} }
// do the move // do the move
final INodesInPath trgINodesInPath = rootDir.getExistingPathINodes(target, true); final INodesInPath trgINodesInPath = rootDir.getINodesInPath4Write(target, true);
final INode[] trgINodes = trgINodesInPath.getINodes(); 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];
@ -1032,7 +1012,7 @@ public class FSDirectory implements Closeable {
int filesRemoved; int filesRemoved;
writeLock(); writeLock();
try { try {
final INodesInPath inodesInPath = rootDir.getMutableINodesInPath( final INodesInPath inodesInPath = rootDir.getINodesInPath4Write(
normalizePath(src), false); normalizePath(src), false);
final INode[] inodes = inodesInPath.getINodes(); final INode[] inodes = inodesInPath.getINodes();
if (checkPathINodes(inodes, src) == 0) { if (checkPathINodes(inodes, src) == 0) {
@ -1093,7 +1073,7 @@ public class FSDirectory implements Closeable {
boolean isNonEmptyDirectory(String path) throws UnresolvedLinkException { boolean isNonEmptyDirectory(String path) throws UnresolvedLinkException {
readLock(); readLock();
try { try {
final INodesInPath inodesInPath = rootDir.getINodesInPath(path, false); final INodesInPath inodesInPath = rootDir.getLastINodeInPath(path, false);
final INode inode = inodesInPath.getINode(0); final INode inode = inodesInPath.getINode(0);
if (inode == null || !inode.isDirectory()) { if (inode == null || !inode.isDirectory()) {
//not found or not a directory //not found or not a directory
@ -1122,7 +1102,7 @@ public class FSDirectory implements Closeable {
BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo(); BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo();
int filesRemoved = 0; int filesRemoved = 0;
final INodesInPath inodesInPath = rootDir.getMutableINodesInPath( final INodesInPath inodesInPath = rootDir.getINodesInPath4Write(
normalizePath(src), false); normalizePath(src), false);
final INode[] inodes = inodesInPath.getINodes(); final INode[] inodes = inodesInPath.getINodes();
if (checkPathINodes(inodes, src) == 0) { if (checkPathINodes(inodes, src) == 0) {
@ -1255,7 +1235,7 @@ public class FSDirectory implements Closeable {
readLock(); readLock();
try { try {
final INodesInPath inodesInPath = rootDir.getINodesInPath(srcs, true); final INodesInPath inodesInPath = rootDir.getLastINodeInPath(srcs, true);
final Snapshot snapshot = inodesInPath.getPathSnapshot(); final Snapshot snapshot = inodesInPath.getPathSnapshot();
final INode targetNode = inodesInPath.getINode(0); final INode targetNode = inodesInPath.getINode(0);
if (targetNode == null) if (targetNode == null)
@ -1297,7 +1277,7 @@ public class FSDirectory implements Closeable {
String srcs = normalizePath(src); String srcs = normalizePath(src);
readLock(); readLock();
try { try {
final INodesInPath inodesInPath = rootDir.getINodesInPath(srcs, resolveLink); final INodesInPath inodesInPath = rootDir.getLastINodeInPath(srcs, resolveLink);
final INode i = inodesInPath.getINode(0); final INode i = inodesInPath.getINode(0);
return i == null? null: createFileStatus(HdfsFileStatus.EMPTY_NAME, i, return i == null? null: createFileStatus(HdfsFileStatus.EMPTY_NAME, i,
inodesInPath.getPathSnapshot()); inodesInPath.getPathSnapshot());
@ -1324,16 +1304,17 @@ public class FSDirectory implements Closeable {
* Get {@link INode} associated with the file / directory. * Get {@link INode} associated with the file / directory.
*/ */
public INode getINode(String src) throws UnresolvedLinkException { public INode getINode(String src) throws UnresolvedLinkException {
return getINodesInPath(src).getINode(0); return getLastINodeInPath(src).getINode(0);
} }
/** /**
* Get {@link INode} associated with the file / directory. * Get {@link INode} associated with the file / directory.
*/ */
public INodesInPath getINodesInPath(String src) throws UnresolvedLinkException { public INodesInPath getLastINodeInPath(String src)
throws UnresolvedLinkException {
readLock(); readLock();
try { try {
return rootDir.getINodesInPath(src, true); return rootDir.getLastINodeInPath(src, true);
} finally { } finally {
readUnlock(); readUnlock();
} }
@ -1342,11 +1323,11 @@ public class FSDirectory implements Closeable {
/** /**
* Get {@link INode} associated with the file / directory. * Get {@link INode} associated with the file / directory.
*/ */
public INodesInPath getMutableINodesInPath(String src public INodesInPath getINodesInPath4Write(String src
) throws UnresolvedLinkException, SnapshotAccessControlException { ) throws UnresolvedLinkException, SnapshotAccessControlException {
readLock(); readLock();
try { try {
return rootDir.getMutableINodesInPath(src, true); return rootDir.getINodesInPath4Write(src, true);
} finally { } finally {
readUnlock(); readUnlock();
} }
@ -1356,11 +1337,11 @@ public class FSDirectory implements Closeable {
* Get {@link INode} associated with the file / directory. * Get {@link INode} associated with the file / directory.
* @throws SnapshotAccessControlException if path is in RO snapshot * @throws SnapshotAccessControlException if path is in RO snapshot
*/ */
public INode getMutableINode(String src) throws UnresolvedLinkException, public INode getINode4Write(String src) throws UnresolvedLinkException,
SnapshotAccessControlException { SnapshotAccessControlException {
readLock(); readLock();
try { try {
return rootDir.getMutableNode(src, true); return rootDir.getINode4Write(src, true);
} finally { } finally {
readUnlock(); readUnlock();
} }
@ -1376,7 +1357,7 @@ public class FSDirectory implements Closeable {
readLock(); readLock();
try { try {
if (srcs.startsWith("/") && !srcs.endsWith("/") if (srcs.startsWith("/") && !srcs.endsWith("/")
&& rootDir.getMutableNode(srcs, false) == null) { && rootDir.getINode4Write(srcs, false) == null) {
return true; return true;
} else { } else {
return false; return false;
@ -1409,7 +1390,7 @@ public class FSDirectory implements Closeable {
src = normalizePath(src); src = normalizePath(src);
readLock(); readLock();
try { try {
INode node = rootDir.getMutableNode(src, false); INode node = rootDir.getINode4Write(src, false);
return node != null && node.isDirectory(); return node != null && node.isDirectory();
} finally { } finally {
readUnlock(); readUnlock();
@ -1426,21 +1407,25 @@ public class FSDirectory implements Closeable {
* @throws FileNotFoundException if path does not exist. * @throws FileNotFoundException if path does not exist.
*/ */
void updateSpaceConsumed(String path, long nsDelta, long dsDelta) void updateSpaceConsumed(String path, long nsDelta, long dsDelta)
throws QuotaExceededException, FileNotFoundException, UnresolvedLinkException { throws QuotaExceededException, FileNotFoundException,
UnresolvedLinkException, SnapshotAccessControlException {
writeLock(); writeLock();
try { try {
final INodesInPath inodesInPath = rootDir.getExistingPathINodes(path, false); final INodesInPath iip = rootDir.getINodesInPath4Write(path, false);
final INode[] inodes = inodesInPath.getINodes(); if (iip.getLastINode() == null) {
int len = inodes.length;
if (inodes[len - 1] == null) {
throw new FileNotFoundException("Path not found: " + path); throw new FileNotFoundException("Path not found: " + path);
} }
updateCount(inodesInPath, len-1, nsDelta, dsDelta, true); updateCount(iip, nsDelta, dsDelta, true);
} finally { } finally {
writeUnlock(); writeUnlock();
} }
} }
private void updateCount(INodesInPath iip, long nsDelta, long dsDelta,
boolean checkQuota) throws QuotaExceededException {
updateCount(iip, iip.getINodes().length - 1, nsDelta, dsDelta, checkQuota);
}
/** update count of each inode with quota /** update count of each inode with quota
* *
* @param inodes an array of inodes on a path * @param inodes an array of inodes on a path
@ -2011,7 +1996,7 @@ public class FSDirectory implements Closeable {
} }
String srcs = normalizePath(src); String srcs = normalizePath(src);
final INodesInPath iip = rootDir.getMutableINodesInPath(srcs, true); final INodesInPath iip = rootDir.getINodesInPath4Write(srcs, true);
INodeDirectory dirNode = INodeDirectory.valueOf(iip.getLastINode(), srcs); INodeDirectory dirNode = INodeDirectory.valueOf(iip.getLastINode(), srcs);
if (dirNode.isRoot() && nsQuota == HdfsConstants.QUOTA_RESET) { if (dirNode.isRoot() && nsQuota == HdfsConstants.QUOTA_RESET) {
throw new IllegalArgumentException("Cannot clear namespace quota on root."); throw new IllegalArgumentException("Cannot clear namespace quota on root.");
@ -2091,7 +2076,7 @@ public class FSDirectory implements Closeable {
boolean unprotectedSetTimes(String src, long mtime, long atime, boolean force) boolean unprotectedSetTimes(String src, long mtime, long atime, boolean force)
throws UnresolvedLinkException { throws UnresolvedLinkException {
assert hasWriteLock(); assert hasWriteLock();
final INodesInPath i = getINodesInPath(src); final INodesInPath i = getLastINodeInPath(src);
return unprotectedSetTimes(src, i.getLastINode(), mtime, atime, force, return unprotectedSetTimes(src, i.getLastINode(), mtime, atime, force,
i.getLatestSnapshot()); i.getLatestSnapshot());
} }

View File

@ -253,7 +253,7 @@ public class FSEditLogLoader {
// 3. OP_ADD to open file for append // 3. OP_ADD to open file for append
// See if the file already exists (persistBlocks call) // See if the file already exists (persistBlocks call)
final INodesInPath iip = fsDir.getINodesInPath(addCloseOp.path); final INodesInPath iip = fsDir.getLastINodeInPath(addCloseOp.path);
final INodeFile oldFile = toINodeFile(iip.getINode(0), addCloseOp.path); final INodeFile oldFile = toINodeFile(iip.getINode(0), addCloseOp.path);
INodeFile newFile = oldFile; INodeFile newFile = oldFile;
if (oldFile == null) { // this is OP_ADD on a new file (case 1) if (oldFile == null) { // this is OP_ADD on a new file (case 1)
@ -304,7 +304,7 @@ public class FSEditLogLoader {
" clientMachine " + addCloseOp.clientMachine); " clientMachine " + addCloseOp.clientMachine);
} }
final INodesInPath iip = fsDir.getINodesInPath(addCloseOp.path); final INodesInPath iip = fsDir.getLastINodeInPath(addCloseOp.path);
final INodeFile oldFile = toINodeFile(iip.getINode(0), addCloseOp.path); final INodeFile oldFile = toINodeFile(iip.getINode(0), addCloseOp.path);
if (oldFile == null) { if (oldFile == null) {
throw new IOException("Operation trying to close non-existent file " + throw new IOException("Operation trying to close non-existent file " +

View File

@ -638,7 +638,7 @@ public class FSImageFormat {
// verify that file exists in namespace // verify that file exists in namespace
String path = cons.getLocalName(); String path = cons.getLocalName();
final INodesInPath iip = fsDir.getINodesInPath(path); final INodesInPath iip = fsDir.getLastINodeInPath(path);
INodeFile oldnode = INodeFile.valueOf(iip.getINode(0), path); INodeFile oldnode = INodeFile.valueOf(iip.getINode(0), path);
cons.setLocalName(oldnode.getLocalNameBytes()); cons.setLocalName(oldnode.getLocalNameBytes());
if (oldnode instanceof FileWithSnapshot if (oldnode instanceof FileWithSnapshot

View File

@ -1359,7 +1359,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
doAccessTime = false; doAccessTime = false;
} }
final INodesInPath iip = dir.getINodesInPath(src); final INodesInPath iip = dir.getLastINodeInPath(src);
final INodeFile inode = INodeFile.valueOf(iip.getLastINode(), src); final INodeFile inode = INodeFile.valueOf(iip.getLastINode(), src);
if (!iip.isSnapshot() //snapshots are readonly, so don't update atime. if (!iip.isSnapshot() //snapshots are readonly, so don't update atime.
&& doAccessTime && isAccessTimeSupported()) { && doAccessTime && isAccessTimeSupported()) {
@ -1480,7 +1480,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
// replication and blocks sizes should be the same for ALL the blocks // replication and blocks sizes should be the same for ALL the blocks
// check the target // check the target
final INodeFile trgInode = INodeFile.valueOf(dir.getMutableINode(target), final INodeFile trgInode = INodeFile.valueOf(dir.getINode4Write(target),
target); target);
if(trgInode.isUnderConstruction()) { if(trgInode.isUnderConstruction()) {
throw new HadoopIllegalArgumentException("concat: target file " throw new HadoopIllegalArgumentException("concat: target file "
@ -1516,7 +1516,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
if(i==srcs.length-1) if(i==srcs.length-1)
endSrc=true; endSrc=true;
final INodeFile srcInode = INodeFile.valueOf(dir.getMutableINode(src), src); final INodeFile srcInode = INodeFile.valueOf(dir.getINode4Write(src), src);
if(src.isEmpty() if(src.isEmpty()
|| srcInode.isUnderConstruction() || srcInode.isUnderConstruction()
|| srcInode.numBlocks() == 0) { || srcInode.numBlocks() == 0) {
@ -1599,7 +1599,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
if (isPermissionEnabled) { if (isPermissionEnabled) {
checkPathAccess(src, FsAction.WRITE); checkPathAccess(src, FsAction.WRITE);
} }
final INodesInPath iip = dir.getMutableINodesInPath(src); final INodesInPath iip = dir.getINodesInPath4Write(src);
final INode inode = iip.getLastINode(); final INode inode = iip.getLastINode();
if (inode != null) { if (inode != null) {
dir.setTimes(src, inode, mtime, atime, true, iip.getLatestSnapshot()); dir.setTimes(src, inode, mtime, atime, true, iip.getLatestSnapshot());
@ -1882,8 +1882,9 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
} }
// Verify that the destination does not exist as a directory already. // Verify that the destination does not exist as a directory already.
boolean pathExists = dir.existsMutable(src); final INodesInPath iip = dir.getINodesInPath4Write(src);
if (pathExists && dir.isDir(src)) { final INode myFile = iip.getLastINode();
if (myFile != null && myFile.isDirectory()) {
throw new FileAlreadyExistsException("Cannot create file " + src throw new FileAlreadyExistsException("Cannot create file " + src
+ "; already exists as a directory."); + "; already exists as a directory.");
} }
@ -1891,7 +1892,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
boolean overwrite = flag.contains(CreateFlag.OVERWRITE); boolean overwrite = flag.contains(CreateFlag.OVERWRITE);
boolean append = flag.contains(CreateFlag.APPEND); boolean append = flag.contains(CreateFlag.APPEND);
if (isPermissionEnabled) { if (isPermissionEnabled) {
if (append || (overwrite && pathExists)) { if (append || (overwrite && myFile != null)) {
checkPathAccess(src, FsAction.WRITE); checkPathAccess(src, FsAction.WRITE);
} else { } else {
checkAncestorAccess(src, FsAction.WRITE); checkAncestorAccess(src, FsAction.WRITE);
@ -1906,8 +1907,6 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
blockManager.verifyReplication(src, replication, clientMachine); blockManager.verifyReplication(src, replication, clientMachine);
boolean create = flag.contains(CreateFlag.CREATE); boolean create = flag.contains(CreateFlag.CREATE);
final INodesInPath iip = dir.getINodesInPath(src);
final INode myFile = iip.getINode(0);
if (myFile == null) { if (myFile == null) {
if (!create) { if (!create) {
throw new FileNotFoundException("failed to overwrite or append to non-existent file " throw new FileNotFoundException("failed to overwrite or append to non-existent file "
@ -2326,7 +2325,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
throw new SafeModeException("Cannot add block to " + src, safeMode); throw new SafeModeException("Cannot add block to " + src, safeMode);
} }
final INodesInPath iip = dir.rootDir.getExistingPathINodes(src, true); final INodesInPath iip = dir.getINodesInPath4Write(src);
final INodeFileUnderConstruction pendingFile final INodeFileUnderConstruction pendingFile
= checkLease(src, clientName, iip.getLastINode()); = checkLease(src, clientName, iip.getLastINode());
@ -2504,7 +2503,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
throw new SafeModeException("Cannot complete file " + src, safeMode); throw new SafeModeException("Cannot complete file " + src, safeMode);
} }
final INodesInPath iip = dir.getINodesInPath(src); final INodesInPath iip = dir.getLastINodeInPath(src);
final INodeFileUnderConstruction pendingFile; final INodeFileUnderConstruction pendingFile;
try { try {
pendingFile = checkLease(src, holder, iip.getINode(0)); pendingFile = checkLease(src, holder, iip.getINode(0));
@ -3144,7 +3143,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
assert !isInSafeMode(); assert !isInSafeMode();
assert hasWriteLock(); assert hasWriteLock();
final INodesInPath iip = dir.getINodesInPath(src); final INodesInPath iip = dir.getLastINodeInPath(src);
final INodeFileUnderConstruction pendingFile final INodeFileUnderConstruction pendingFile
= INodeFileUnderConstruction.valueOf(iip.getINode(0), src); = INodeFileUnderConstruction.valueOf(iip.getINode(0), src);
int nrBlocks = pendingFile.numBlocks(); int nrBlocks = pendingFile.numBlocks();

View File

@ -122,7 +122,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.
final INodesInPath inodesInPath = root.getExistingPathINodes(path, true); final INodesInPath inodesInPath = root.getINodesInPath(path, true);
final Snapshot snapshot = inodesInPath.getPathSnapshot(); final Snapshot snapshot = inodesInPath.getPathSnapshot();
final INode[] inodes = inodesInPath.getINodes(); final INode[] inodes = inodesInPath.getINodes();
int ancestorIndex = inodes.length - 2; int ancestorIndex = inodes.length - 2;

View File

@ -122,10 +122,6 @@ public class INodeDirectory extends INode {
} }
return i; return i;
} }
protected INode getExistingChild(int i) {
return children.get(i);
}
INode removeChild(INode node) { INode removeChild(INode node) {
assertChildrenNonNull(); assertChildrenNonNull();
@ -266,15 +262,22 @@ public class INodeDirectory extends INode {
} }
/** @return the {@link INodesInPath} containing only the last inode. */ /** @return the {@link INodesInPath} containing only the last inode. */
INodesInPath getINodesInPath(String path, boolean resolveLink INodesInPath getLastINodeInPath(String path, boolean resolveLink
) throws UnresolvedLinkException { ) throws UnresolvedLinkException {
return getExistingPathINodes(getPathComponents(path), 1, resolveLink); return getExistingPathINodes(getPathComponents(path), 1, resolveLink);
} }
/** @return the {@link INodesInPath} containing all inodes in the path. */
INodesInPath getINodesInPath(String path, boolean resolveLink
) throws UnresolvedLinkException {
final byte[][] components = getPathComponents(path);
return getExistingPathINodes(components, components.length, resolveLink);
}
/** @return the last inode in the path. */ /** @return the last inode in the path. */
INode getNode(String path, boolean resolveLink) INode getNode(String path, boolean resolveLink)
throws UnresolvedLinkException { throws UnresolvedLinkException {
return getINodesInPath(path, resolveLink).getINode(0); return getLastINodeInPath(path, resolveLink).getINode(0);
} }
/** /**
@ -283,10 +286,9 @@ public class INodeDirectory extends INode {
* @throws UnresolvedLinkException if symlink can't be resolved * @throws UnresolvedLinkException if symlink can't be resolved
* @throws SnapshotAccessControlException if path is in RO snapshot * @throws SnapshotAccessControlException if path is in RO snapshot
*/ */
INode getMutableNode(String src, boolean resolveLink) INode getINode4Write(String src, boolean resolveLink)
throws UnresolvedLinkException, SnapshotAccessControlException { throws UnresolvedLinkException, SnapshotAccessControlException {
INode[] inodes = getMutableINodesInPath(src, resolveLink).getINodes(); return getINodesInPath4Write(src, resolveLink).getLastINode();
return inodes[inodes.length - 1];
} }
/** /**
@ -294,23 +296,14 @@ public class INodeDirectory extends INode {
* @throws UnresolvedLinkException if symlink can't be resolved * @throws UnresolvedLinkException if symlink can't be resolved
* @throws SnapshotAccessControlException if path is in RO snapshot * @throws SnapshotAccessControlException if path is in RO snapshot
*/ */
INodesInPath getMutableINodesInPath(String src, boolean resolveLink) INodesInPath getINodesInPath4Write(String src, boolean resolveLink)
throws UnresolvedLinkException, SnapshotAccessControlException {
return getMutableINodesInPath(INode.getPathComponents(src), resolveLink);
}
/**
* @return the INodesInPath of the components in src
* @throws UnresolvedLinkException if symlink can't be resolved
* @throws SnapshotAccessControlException if path is in RO snapshot
*/
INodesInPath getMutableINodesInPath(byte[][] components, boolean resolveLink)
throws UnresolvedLinkException, SnapshotAccessControlException { throws UnresolvedLinkException, SnapshotAccessControlException {
final byte[][] components = INode.getPathComponents(src);
INodesInPath inodesInPath = getExistingPathINodes(components, INodesInPath inodesInPath = getExistingPathINodes(components,
components.length, resolveLink); components.length, resolveLink);
if (inodesInPath.isSnapshot()) { if (inodesInPath.isSnapshot()) {
throw new SnapshotAccessControlException( throw new SnapshotAccessControlException(
"Modification on RO snapshot is disallowed"); "Modification on a read-only snapshot is disallowed");
} }
return inodesInPath; return inodesInPath;
} }
@ -447,27 +440,6 @@ public class INodeDirectory extends INode {
return pathComponent == null ? false : HdfsConstants.DOT_SNAPSHOT_DIR return pathComponent == null ? false : HdfsConstants.DOT_SNAPSHOT_DIR
.equalsIgnoreCase(DFSUtil.bytes2String(pathComponent)); .equalsIgnoreCase(DFSUtil.bytes2String(pathComponent));
} }
/**
* Retrieve the existing INodes along the given path. The first INode
* always exist and is this INode.
*
* @param path the path to explore
* @param resolveLink indicates whether UnresolvedLinkException should
* be thrown when the path refers to a symbolic link.
* @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 #getExistingPathINodes(byte[][], int, boolean)
*/
INodesInPath getExistingPathINodes(String path, boolean resolveLink)
throws UnresolvedLinkException {
byte[][] components = getPathComponents(path);
return getExistingPathINodes(components, components.length, resolveLink);
}
/** /**
* Given a child's name, return the index of the next child * Given a child's name, return the index of the next child
@ -728,6 +700,10 @@ public class INodeDirectory extends INode {
public INode getLastINode() { public INode getLastINode() {
return inodes[inodes.length - 1]; return inodes[inodes.length - 1];
} }
byte[] getLastLocalName() {
return path[path.length - 1];
}
/** /**
* @return index of the {@link INodeDirectoryWithSnapshot} in * @return index of the {@link INodeDirectoryWithSnapshot} in

View File

@ -66,7 +66,7 @@ public class SnapshotManager implements SnapshotStats {
* If the path is already a snapshottable directory, update the quota. * If the path is already a snapshottable directory, update the quota.
*/ */
public void setSnapshottable(final String path) throws IOException { public void setSnapshottable(final String path) throws IOException {
final INodesInPath iip = fsdir.getINodesInPath(path); final INodesInPath iip = fsdir.getLastINodeInPath(path);
final INodeDirectory d = INodeDirectory.valueOf(iip.getINode(0), path); final INodeDirectory d = INodeDirectory.valueOf(iip.getINode(0), path);
if (d.isSnapshottable()) { if (d.isSnapshottable()) {
//The directory is already a snapshottable directory. //The directory is already a snapshottable directory.
@ -88,7 +88,7 @@ public class SnapshotManager implements SnapshotStats {
*/ */
public void resetSnapshottable(final String path public void resetSnapshottable(final String path
) throws IOException { ) throws IOException {
final INodesInPath iip = fsdir.getINodesInPath(path); final INodesInPath iip = fsdir.getLastINodeInPath(path);
final INodeDirectorySnapshottable s = INodeDirectorySnapshottable.valueOf( final INodeDirectorySnapshottable s = INodeDirectorySnapshottable.valueOf(
iip.getINode(0), path); iip.getINode(0), path);
if (s.getNumSnapshots() > 0) { if (s.getNumSnapshots() > 0) {
@ -117,7 +117,7 @@ public class SnapshotManager implements SnapshotStats {
public void createSnapshot(final String path, final String snapshotName public void createSnapshot(final String path, final String snapshotName
) throws IOException { ) throws IOException {
// Find the source root directory path where the snapshot is taken. // Find the source root directory path where the snapshot is taken.
final INodesInPath i = fsdir.getMutableINodesInPath(path); final INodesInPath i = fsdir.getINodesInPath4Write(path);
final INodeDirectorySnapshottable srcRoot final INodeDirectorySnapshottable srcRoot
= INodeDirectorySnapshottable.valueOf(i.getLastINode(), path); = INodeDirectorySnapshottable.valueOf(i.getLastINode(), path);
srcRoot.addSnapshot(snapshotCounter, snapshotName); srcRoot.addSnapshot(snapshotCounter, snapshotName);
@ -137,7 +137,7 @@ public class SnapshotManager implements SnapshotStats {
public void deleteSnapshot(final String path, final String snapshotName, public void deleteSnapshot(final String path, final String snapshotName,
BlocksMapUpdateInfo collectedBlocks) throws IOException { BlocksMapUpdateInfo collectedBlocks) throws IOException {
// parse the path, and check if the path is a snapshot path // parse the path, and check if the path is a snapshot path
INodesInPath inodesInPath = fsdir.getMutableINodesInPath(path.toString()); INodesInPath inodesInPath = fsdir.getINodesInPath4Write(path.toString());
// transfer the inode for path to an INodeDirectorySnapshottable. // transfer the inode for path to an INodeDirectorySnapshottable.
// the INodeDirectorySnapshottable#valueOf method will throw Exception // the INodeDirectorySnapshottable#valueOf method will throw Exception
// if the path is not for a snapshottable directory // if the path is not for a snapshottable directory
@ -253,7 +253,7 @@ public class SnapshotManager implements SnapshotStats {
// Find the source root directory path where the snapshots were taken. // Find the source root directory path where the snapshots were taken.
// All the check for path has been included in the valueOf method. // All the check for path has been included in the valueOf method.
INodesInPath inodesInPath = fsdir.getMutableINodesInPath(path.toString()); INodesInPath inodesInPath = fsdir.getINodesInPath4Write(path.toString());
final INodeDirectorySnapshottable snapshotRoot = INodeDirectorySnapshottable final INodeDirectorySnapshottable snapshotRoot = INodeDirectorySnapshottable
.valueOf(inodesInPath.getLastINode(), path); .valueOf(inodesInPath.getLastINode(), path);